summaryrefslogtreecommitdiff
path: root/src/map
diff options
context:
space:
mode:
authorultramage <ultramage@54d463be-8e91-2dee-dedb-b68131a5f0ec>2009-03-08 12:32:45 +0000
committerultramage <ultramage@54d463be-8e91-2dee-dedb-b68131a5f0ec>2009-03-08 12:32:45 +0000
commit61f8a2a0670998c502684bb8ecf88e0fb4d256ab (patch)
tree349f27fa3dc5483055d331a5a330f1621b0d0449 /src/map
parent951ab9d41f399b436e1221d894d1e7c43ea8267e (diff)
downloadhercules-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.c1
-rw-r--r--src/map/skill.c37
-rw-r--r--src/map/status.c164
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;
}