Forráskód Böngészése

- Now when you set the guardian's HP, if the guardian is spawned, it's HP will be updated accordingly (and if you set it to 0, the guardian is killed)
- Added functions status_set_hp/status_set_sp to set hp/sp to a given value. Applied usage of these on the Berserk and Soul Change code.


git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@7922 54d463be-8e91-2dee-dedb-b68131a5f0ec

skotlex 19 éve
szülő
commit
932107f772
5 módosított fájl, 67 hozzáadás és 8 törlés
  1. 6 0
      Changelog-Trunk.txt
  2. 16 1
      src/map/script.c
  3. 2 3
      src/map/skill.c
  4. 40 4
      src/map/status.c
  5. 3 0
      src/map/status.h

+ 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.
 IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
 
 
 2006/07/27
 2006/07/27
+	* Now when you set the guardian's HP, if the guardian is spawned, it's HP
+	  will be updated accordingly (and if you set it to 0, the guardian is
+	  killed) [Skotlex]
+	* Added functions status_set_hp/status_set_sp to set hp/sp to a given
+	  value. Applied usage of these on the Berserk and Soul Change code.
+	  [Skotlex]
 	* Added config setting "party_hp_mode" (battle/party.conf) which determines
 	* Added config setting "party_hp_mode" (battle/party.conf) which determines
 	  method to use to update party-mate hp bars. Aegis style is to update HP
 	  method to use to update party-mate hp bars. Aegis style is to update HP
 	  bars whenever HP changes, while eAthena style is to update it together with
 	  bars whenever HP changes, while eAthena style is to update it together with

+ 16 - 1
src/map/script.c

@@ -7553,7 +7553,22 @@ int buildin_setcastledata(struct script_state *st)
 				case 23:
 				case 23:
 				case 24:
 				case 24:
 				case 25:
 				case 25:
-					gc->guardian[index-18].hp = value; break;
+					gc->guardian[index-18].hp = value;
+					if (gc->guardian[index-18].id)
+				  	{	//Update this mob's HP.
+						struct block_list *bl = map_id2bl(gc->guardian[index-18].id);
+						if (!bl)
+					  	{	//Wrong target?
+							gc->guardian[index-18].id = 0;
+							break;
+						}
+						if (value < 1) {
+							status_kill(bl);
+							break;
+						}
+						status_set_hp(bl, value, 0);
+					}
+					break;
 				default: return 0;
 				default: return 0;
 				}
 				}
 				guild_castledatasave(gc->castle_id,index,value);
 				guild_castledatasave(gc->castle_id,index,value);

+ 2 - 3
src/map/skill.c

@@ -5200,9 +5200,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
 			}
 			}
 			sp1 = sstatus->sp;
 			sp1 = sstatus->sp;
 			sp2 = tstatus->sp;
 			sp2 = tstatus->sp;
-			//TODO: Will this work correctly once sp1/sp2 go above INT_MAX?
-			status_heal(src, 0, (signed int)(sp2-sp1), 3);
-			status_heal(bl, 0, (signed int)(sp1-sp2), 3);
+			status_set_sp(src, sp2, 3);
+			status_set_sp(bl, sp1, 3);
 			clif_skill_nodamage(src,bl,skillid,skilllv,1);
 			clif_skill_nodamage(src,bl,skillid,skilllv,1);
 		}
 		}
 		break;
 		break;

+ 40 - 4
src/map/status.c

@@ -495,6 +495,42 @@ int status_getrefinebonus(int lv,int type)
 	return 0;
 	return 0;
 }
 }
 
 
+//Sets HP to given value. Flag is the flag passed to status_heal in case
+//final value is higher than current (use 2 to make a healing effect display 
+//on players) It will always succeed (overrides Berserk block), but it can't kill.
+int status_set_hp(struct block_list *bl, unsigned int hp, int flag)
+{
+	struct status_data *status;
+	if (hp < 1) return 0;
+	status = status_get_status_data(bl);
+	if (status == &dummy_status)
+		return 0;
+
+	if (hp > status->max_hp) hp = status->max_hp;
+	if (hp == status->hp) return 0;
+	if (hp > status->hp)
+		return status_heal(bl, hp - status->hp, 0, 1|flag);
+	return status_zap(bl, status->hp - hp, 0);
+}
+
+//Sets SP to given value. Flag is the flag passed to status_heal in case
+//final value is higher than current (use 2 to make a healing effect display 
+//on players)
+int status_set_sp(struct block_list *bl, unsigned int sp, int flag)
+{
+	struct status_data *status;
+	
+	status = status_get_status_data(bl);
+	if (status == &dummy_status)
+		return 0;
+
+	if (sp > status->max_sp) sp = status->max_sp;
+	if (sp == status->sp) return 0;
+	if (sp > status->sp)
+		return status_heal(bl, 0, sp - status->sp, 1|flag);
+	return status_zap(bl, 0, status->sp - sp);
+}
+
 //Inflicts damage on the target with the according walkdelay.
 //Inflicts damage on the target with the according walkdelay.
 //If flag&1, damage is passive and does not triggers cancelling status changes.
 //If flag&1, damage is passive and does not triggers cancelling status changes.
 //If flag&2, fail if target does not has enough to substract.
 //If flag&2, fail if target does not has enough to substract.
@@ -504,8 +540,8 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s
 	struct status_data *status;
 	struct status_data *status;
 	struct status_change *sc;
 	struct status_change *sc;
 
 
-	if(sp && target->type != BL_PC && target->type != BL_HOMUNCULUS)	//[orn]
-		sp = 0; //Only players and Homunculus get SP damage.
+	if(sp && !(target->type&BL_CONSUME))
+		sp = 0; //Not a valid SP target.
 	
 	
 	if (hp < 0) { //Assume absorbed damage.
 	if (hp < 0) { //Assume absorbed damage.
 		status_heal(target, -hp, 0, 1);
 		status_heal(target, -hp, 0, 1);
@@ -5548,7 +5584,7 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val
 	if (type==SC_BERSERK) {
 	if (type==SC_BERSERK) {
 		sc->data[type].val2 = 5*status->max_hp/100;
 		sc->data[type].val2 = 5*status->max_hp/100;
 		status_heal(bl, status->max_hp, 0, 1); //Do not use percent_heal as this healing must override BERSERK's block.
 		status_heal(bl, status->max_hp, 0, 1); //Do not use percent_heal as this healing must override BERSERK's block.
-		status_percent_damage(NULL, bl, 0, 100); //Damage all SP
+		status_set_sp(bl, 0, 0); //Damage all SP
 	}
 	}
 
 
 	if (type==SC_RUN) {
 	if (type==SC_RUN) {
@@ -5822,7 +5858,7 @@ int status_change_end( struct block_list* bl , int type,int tid )
 		case SC_BERSERK:
 		case SC_BERSERK:
 			//If val2 is removed, no HP penalty (dispelled?) [Skotlex]
 			//If val2 is removed, no HP penalty (dispelled?) [Skotlex]
 			if(status->hp > 100 && sc->data[type].val2)
 			if(status->hp > 100 && sc->data[type].val2)
-				status_zap(bl, status->hp-100, 0); 
+				status_set_hp(bl, 100, 0); 
 			if(sc->data[SC_ENDURE].timer != -1)
 			if(sc->data[SC_ENDURE].timer != -1)
 				status_change_end(bl, SC_ENDURE, -1);
 				status_change_end(bl, SC_ENDURE, -1);
 			break;
 			break;

+ 3 - 0
src/map/status.h

@@ -532,6 +532,9 @@ int status_percent_change(struct block_list *src,struct block_list *target,signe
 //Instant kill with no drops/exp/etc
 //Instant kill with no drops/exp/etc
 //
 //
 #define status_kill(bl) status_percent_damage(NULL, bl, 100, 0)
 #define status_kill(bl) status_percent_damage(NULL, bl, 100, 0)
+//Used to set the hp/sp of an object to an absolute value (can't kill)
+int status_set_hp(struct block_list *bl, unsigned int hp, int flag);
+int status_set_sp(struct block_list *bl, unsigned int sp, int flag);
 int status_heal(struct block_list *bl,int hp,int sp, int flag);
 int status_heal(struct block_list *bl,int hp,int sp, int flag);
 int status_revive(struct block_list *bl, unsigned char per_hp, unsigned char per_sp);
 int status_revive(struct block_list *bl, unsigned char per_hp, unsigned char per_sp);