浏览代码

* 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://svn.code.sf.net/p/rathena/svn/trunk@13572 54d463be-8e91-2dee-dedb-b68131a5f0ec

ultramage 16 年之前
父节点
当前提交
4d5e91c6f6
共有 4 个文件被更改,包括 65 次插入143 次删除
  1. 6 0
      Changelog-Trunk.txt
  2. 0 1
      src/map/pc.c
  3. 25 12
      src/map/skill.c
  4. 34 130
      src/map/status.c

+ 6 - 0
Changelog-Trunk.txt

@@ -4,6 +4,12 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK.  ALL UNTESTED BUGFIXES/FEATURES GO
 IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
 
 2009/03/08
+	* Fixed a couple bugs with marionette control [Brainstorm]
+	- 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.
 	* Added several mail id checks to prevent a map server crash (bugreport:2837)
 2009/03/02
 	* Blade Stop status no longer prevents item use and equip changing.

+ 0 - 1
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] ||

+ 25 - 12
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;
 				}

+ 34 - 130
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;
 		}