diff options
author | ultramage <ultramage@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2009-03-08 12:32:45 +0000 |
---|---|---|
committer | ultramage <ultramage@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2009-03-08 12:32:45 +0000 |
commit | 61f8a2a0670998c502684bb8ecf88e0fb4d256ab (patch) | |
tree | 349f27fa3dc5483055d331a5a330f1621b0d0449 /src/map | |
parent | 951ab9d41f399b436e1221d894d1e7c43ea8267e (diff) | |
download | hercules-61f8a2a0670998c502684bb8ecf88e0fb4d256ab.tar.gz hercules-61f8a2a0670998c502684bb8ecf88e0fb4d256ab.tar.bz2 hercules-61f8a2a0670998c502684bb8ecf88e0fb4d256ab.tar.xz hercules-61f8a2a0670998c502684bb8ecf88e0fb4d256ab.zip |
* Fixed a couple bugs with marionette control
- Reduces caster max hp by 1000.
- Job and Equipment bonuses counts toward the 99 limit.
- Fixed stat overflow on baby targets with stats over 80 (bugreport:2232).
- Fixed clowns being able to cast it on another bard/clown (same for gypsy/dancer) (bugreport:166).
- Caster is no longer blocked from using items.
git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@13572 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src/map')
-rw-r--r-- | src/map/pc.c | 1 | ||||
-rw-r--r-- | src/map/skill.c | 37 | ||||
-rw-r--r-- | src/map/status.c | 164 |
3 files changed, 59 insertions, 143 deletions
diff --git a/src/map/pc.c b/src/map/pc.c index 4fab50112..afbbdf8bb 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -3365,7 +3365,6 @@ int pc_useitem(struct map_session_data *sd,int n) if (sd->sc.count && ( sd->sc.data[SC_BERSERK] || - sd->sc.data[SC_MARIONETTE] || (sd->sc.data[SC_GRAVITATION] && sd->sc.data[SC_GRAVITATION]->val3 == BCT_SELF) || sd->sc.data[SC_TRICKDEAD] || sd->sc.data[SC_HIDING] || diff --git a/src/map/skill.c b/src/map/skill.c index 54f8495f8..78d29cb40 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -3267,22 +3267,35 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in case CG_MARIONETTE: { - struct status_change *sc= status_get_sc(src); - enum sc_type type2 = SC_MARIONETTE2; + struct status_change* sc = status_get_sc(src); - if(sc && tsc){ - if (!sc->data[type] && !tsc->data[type2]) { - sc_start(src,type,100,bl->id,skill_get_time(skillid,skilllv)); - sc_start(bl,type2,100,src->id,skill_get_time(skillid,skilllv)); + if( sd && dstsd && (dstsd->class_&MAPID_UPPERMASK) == MAPID_BARDDANCER && dstsd->status.sex == sd->status.sex ) + {// Cannot cast on another bard/dancer-type class of the same gender as caster + clif_skill_fail(sd,skillid,0,0); + map_freeblock_unlock(); + return 1; + } + + if( sc && tsc ) + { + if( !sc->data[SC_MARIONETTE] && !tsc->data[SC_MARIONETTE2] ) + { + sc_start(src,SC_MARIONETTE,100,bl->id,skill_get_time(skillid,skilllv)); + sc_start(bl,SC_MARIONETTE2,100,src->id,skill_get_time(skillid,skilllv)); clif_skill_nodamage(src,bl,skillid,skilllv,1); } - else if (sc->data[type] && tsc->data[type2] && - sc->data[type]->val1 == bl->id && tsc->data[type2]->val1 == src->id) { - status_change_end(src, type, -1); - status_change_end(bl, type2, -1); + else + if( sc->data[SC_MARIONETTE ] && sc->data[SC_MARIONETTE ]->val1 == bl->id && + tsc->data[SC_MARIONETTE2] && tsc->data[SC_MARIONETTE2]->val1 == src->id ) + { + status_change_end(src, SC_MARIONETTE, -1); + status_change_end(bl, SC_MARIONETTE2, -1); } - else { - if (sd) clif_skill_fail(sd,skillid,0,0); + else + { + if( sd ) + clif_skill_fail(sd,skillid,0,0); + map_freeblock_unlock(); return 1; } diff --git a/src/map/status.c b/src/map/status.c index 9acc9da02..10eb77053 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -1101,8 +1101,8 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, int ) { //Skills blocked through status changes... if (!flag && ( //Blocked only from using the skill (stuff like autospell may still go through sc->data[SC_SILENCE] || - (sc->data[SC_MARIONETTE] && skill_num != CG_MARIONETTE) || - (sc->data[SC_MARIONETTE2] && skill_num == CG_MARIONETTE) || + (sc->data[SC_MARIONETTE] && skill_num != CG_MARIONETTE) || //Only skill you can use is marionette again to cancel it + (sc->data[SC_MARIONETTE2] && skill_num == CG_MARIONETTE) || //Cannot use marionette if you are being buffed by another sc->data[SC_STEELBODY] || sc->data[SC_BERSERK] )) @@ -4055,6 +4055,9 @@ static unsigned int status_calc_maxhp(struct block_list *bl, struct status_chang maxhp += maxhp * sc->data[SC_DELUGE]->val2/100; if(sc->data[SC_BERSERK]) maxhp += maxhp * 2; + if(sc->data[SC_MARIONETTE]) + maxhp -= 1000; + if(sc->data[SC_MERC_HPUP]) maxhp += maxhp * sc->data[SC_MERC_HPUP]->val2/100; @@ -5603,143 +5606,44 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val break; case SC_MARIONETTE: - if (sd) { - val3 = 0; - val2 = sd->status.str>>1; - if (val2 > 0xFF) val2 = 0xFF; - val3|=val2<<16; - - val2 = sd->status.agi>>1; - if (val2 > 0xFF) val2 = 0xFF; - val3|=val2<<8; - - val2 = sd->status.vit>>1; - if (val2 > 0xFF) val2 = 0xFF; - val3|=val2; - - val4 = 0; - val2 = sd->status.int_>>1; - if (val2 > 0xFF) val2 = 0xFF; - val4|=val2<<16; - - val2 = sd->status.dex>>1; - if (val2 > 0xFF) val2 = 0xFF; - val4|=val2<<8; - - val2 = sd->status.luk>>1; - if (val2 > 0xFF) val2 = 0xFF; - val4|=val2; - } else { - struct status_data *b_status = status_get_base_status(bl); - if (!b_status) - return 0; - - val3 = 0; - val2 = b_status->str>>1; - if (val2 > 0xFF) val2 = 0xFF; - val3|=val2<<16; - - val2 = b_status->agi>>1; - if (val2 > 0xFF) val2 = 0xFF; - val3|=val2<<8; - - val2 = b_status->vit>>1; - if (val2 > 0xFF) val2 = 0xFF; - val3|=val2; - - val4 = 0; - val2 = b_status->int_>>1; - if (val2 > 0xFF) val2 = 0xFF; - val4|=val2<<16; - - val2 = b_status->dex>>1; - if (val2 > 0xFF) val2 = 0xFF; - val4|=val2<<8; - - val2 = b_status->luk>>1; - if (val2 > 0xFF) val2 = 0xFF; - val4|=val2; - } - val2 = tick/1000; + { + int stat; + + val2 = tick / 1000; + val3 = 0; + val4 = 0; + stat = ( sd ? sd->status.str : status_get_base_status(bl)->str ) / 2; if (stat > 0xFF) stat = 0xFF; val3 |= stat<<16; + stat = ( sd ? sd->status.agi : status_get_base_status(bl)->agi ) / 2; if (stat > 0xFF) stat = 0xFF; val3 |= stat<<8; + stat = ( sd ? sd->status.vit : status_get_base_status(bl)->vit ) / 2; if (stat > 0xFF) stat = 0xFF; val3 |= stat; + stat = ( sd ? sd->status.int_: status_get_base_status(bl)->int_) / 2; if (stat > 0xFF) stat = 0xFF; val4 |= stat<<16; + stat = ( sd ? sd->status.dex : status_get_base_status(bl)->dex ) / 2; if (stat > 0xFF) stat = 0xFF; val4 |= stat<<8; + stat = ( sd ? sd->status.luk : status_get_base_status(bl)->luk ) / 2; if (stat > 0xFF) stat = 0xFF; val4 |= stat; tick = 1000; break; + } case SC_MARIONETTE2: { + int stat,max; + // fetch caster information struct block_list *pbl = map_id2bl(val1); struct status_change *psc = pbl?status_get_sc(pbl):NULL; struct status_change_entry *psce = psc?psc->data[SC_MARIONETTE]:NULL; - int stat,max; + // fetch target's stats + struct status_data* status = status_get_status_data(bl); // battle status + if (!psce) return 0; - val2 = tick /1000; - val3 = val4 = 0; - if (sd) { - max = pc_maxparameter(sd); //Cap to max parameter. [Skotlex] - //Str - stat = (psce->val3>>16)&0xFF; - if (sd->status.str+stat > max) - stat =max-sd->status.str; - val3 |= stat<<16; - //Agi - stat = (psce->val3>>8)&0xFF; - if (sd->status.agi+stat > max) - stat =max-sd->status.agi; - val3 |= stat<<8; - //Vit - stat = psce->val3&0xFF; - if (sd->status.vit+stat > max) - stat =max-sd->status.vit; - val3 |= stat; - //Int - stat = (psce->val4>>16)&0xFF; - if (sd->status.int_+stat > max) - stat =max-sd->status.int_; - val4 |= stat<<16; - //Dex - stat = (psce->val4>>8)&0xFF; - if (sd->status.dex+stat > max) - stat =max-sd->status.dex; - val4 |= stat<<8; - //Luk - stat = psce->val4&0xFF; - if (sd->status.luk+stat > max) - stat =max-sd->status.luk; - val4 |= stat; - } else { - struct status_data *b_status = status_get_base_status(bl); - if (!b_status) return 0; - max = 0xFF; //Assume a 256 max parameter - //Str - stat = (psce->val3>>16)&0xFF; - if (b_status->str+stat > max) - stat = max - b_status->str; - val3 |= stat<<16; - //Agi - stat = (psce->val3>>8)&0xFF; - if (b_status->agi+stat > max) - stat = max - b_status->agi; - val3 |= stat<<8; - //Vit - stat = psce->val3&0xFF; - if (b_status->vit+stat > max) - stat = max - b_status->vit; - val3 |= stat; - //Int - stat = (psce->val4>>16)&0xFF; - if (b_status->int_+stat > max) - stat = max - b_status->int_; - val4 |= stat<<16; - //Dex - stat = (psce->val4>>8)&0xFF; - if (b_status->dex+stat > max) - stat = max - b_status->dex; - val4 |= stat<<8; - //Luk - stat = psce->val4&0xFF; - if (b_status->luk+stat > max) - stat = max - b_status->luk; - val4 |= stat; - } + + val2 = tick / 1000; + val3 = 0; + val4 = 0; + max = battle_config.max_parameter; //Cap to 99 (default) + stat = (psce->val3 >>16)&0xFF; stat = cap_value(status->str + stat, INT_MIN, max) - cap_value(status->str, INT_MIN, max); if (stat > 0xFF) stat = 0xFF; val3 |= stat<<16; + stat = (psce->val3 >> 8)&0xFF; stat = cap_value(status->agi + stat, INT_MIN, max) - cap_value(status->agi, INT_MIN, max); if (stat > 0xFF) stat = 0xFF; val3 |= stat<<8; + stat = (psce->val3 >> 0)&0xFF; stat = cap_value(status->vit + stat, INT_MIN, max) - cap_value(status->vit, INT_MIN, max); if (stat > 0xFF) stat = 0xFF; val3 |= stat; + stat = (psce->val4 >>16)&0xFF; stat = cap_value(status->int_+ stat, INT_MIN, max) - cap_value(status->int_,INT_MIN, max); if (stat > 0xFF) stat = 0xFF; val4 |= stat<<16; + stat = (psce->val4 >> 8)&0xFF; stat = cap_value(status->dex + stat, INT_MIN, max) - cap_value(status->dex, INT_MIN, max); if (stat > 0xFF) stat = 0xFF; val4 |= stat<<8; + stat = (psce->val4 >> 0)&0xFF; stat = cap_value(status->luk + stat, INT_MIN, max) - cap_value(status->luk, INT_MIN, max); if (stat > 0xFF) stat = 0xFF; val4 |= stat; tick = 1000; break; } |