Pārlūkot izejas kodu

- Modified the Storm Gust freeze counter code. It now takes into consideration the ID of the skill before increasing the counter, which should effectively yield the closest aproximation to official (even though the counter will reset if you step out of a SG and into another one, we do not know yet what should happen in such a case).
- Added @homshuffle. It recalculates the homunculus stats, as if the homunc was sent back to level 1, and then releveled. This command is mean to help fix those previously created Homunculus that are much stronger than they should be.


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

skotlex 18 gadi atpakaļ
vecāks
revīzija
ae58a47909

+ 9 - 0
Changelog-Trunk.txt

@@ -4,6 +4,15 @@ 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.
 
 2007/01/18
+	* Modified the Storm Gust freeze counter code. It now takes into
+	  consideration the ID of the skill before increasing the counter, which
+	  should effectively yield the closest aproximation to official (even though
+	  the counter will reset if you step out of a SG and into another one, we do
+	  not know yet what should happen in such a case).
+	* Added @homshuffle. It recalculates the homunculus stats, as if the homunc
+	  was sent back to level 1, and then releveled. This command is mean to help
+	  fix those previously created Homunculus that are much stronger than they
+	  should be.
 	* Fixed overflow on the mob delay adjustment setting.
 	* Fixed characters being unable to trade again if you attempt a trade on
 	  someone who is on storage/npc when you accept the trade. [Skotlex]

+ 3 - 0
conf-tmpl/atcommand_athena.conf

@@ -618,6 +618,9 @@ makehomun: 60
 homfriendly: 60
 homhungry: 60
 
+//Re-calculates stats, as if the homun was sent back to level 1 and re-leveled
+homshuffle: 60
+
 //----------------------
 // 80: GM Chief commands
 

+ 52 - 0
src/map/atcommand.c

@@ -312,6 +312,7 @@ ACMD_FUNC(homhungry);	//[orn]
 ACMD_FUNC(homtalk);	//[orn]
 ACMD_FUNC(hominfo);	//[Toms]
 ACMD_FUNC(homstats);	//[Skotlex]
+ACMD_FUNC(homshuffle);	//[Skotlex]
 ACMD_FUNC(showmobs); //KarLaeda
 
 /*==========================================
@@ -644,6 +645,7 @@ static AtCommandInfo atcommand_info[] = {
 	{ AtCommand_HomTalk,			"@homtalk",		10, atcommand_homtalk },
 	{ AtCommand_HomInfo,			"@hominfo",		1, atcommand_hominfo },
 	{ AtCommand_HomStats,			"@homstats",		1, atcommand_homstats },
+	{ AtCommand_HomShuffle,			"@homshuffle",		60, atcommand_homshuffle },
 	{ AtCommand_ShowMobs,			"@showmobs",		10, atcommand_showmobs },  //KarLaeda
 // add new commands before this line
 	{ AtCommand_Unknown,			NULL,				 1, NULL }
@@ -10005,6 +10007,56 @@ int atcommand_homstats(
 	return 0;
 }
 
+int atcommand_homshuffle(
+	const int fd, struct map_session_data* sd,
+	const char* command, const char* message)
+{
+	struct homun_data *hd;
+	int lv, i;
+	TBL_PC* tsd = sd;
+
+	nullpo_retr(-1, sd);
+
+	if ((!message || !*message) && !sd->hd)
+	{
+		clif_displaymessage(fd, "usage: @homshuffle <Alchemist's name>");
+		clif_displaymessage(fd, "Use this to recalculate your (or someone else's) homunculus growth data");
+		return -1;
+	}
+	if (message && *message) {
+		tsd = map_nick2sd((char*)message);
+		if (!tsd) {
+			clif_displaymessage(fd, msg_txt(3)); // Character not found.
+			return -1;
+		}
+		if (pc_isGM(tsd) > pc_isGM(sd)) {
+			clif_displaymessage(fd, msg_txt(81)); // Your GM level don't authorise you to do this action on this player.
+			return -1;
+		}
+	}
+
+	hd = tsd->hd;
+	if(!merc_is_hom_active(hd))
+		return -1;
+	
+	lv = hd->homunculus.level;
+	//Reset values to level 1.
+	merc_reset_stats(hd);
+	//Level it back up
+	for (i = 1; i < lv && hd->exp_next; i++){
+		hd->homunculus.exp += hd->exp_next;
+		merc_hom_levelup(hd);
+	}
+	status_calc_homunculus(hd,0);
+	status_percent_heal(&hd->bl, 100, 100);
+	clif_misceffect2(&hd->bl,568);
+	clif_displaymessage(fd, "Homunculus stats altered");
+	//Print out the new stats
+	//This will send the commands to the invoker since they all use this fd regardless of sd value.
+	atcommand_homstats(fd, tsd, command, message);
+	return 0;
+}
+
 /*==========================================
  * Show Items DB Info   v 1.0
  * originally by [Lupus] eAthena

+ 1 - 0
src/map/atcommand.h

@@ -283,6 +283,7 @@ enum AtCommandType {
 	AtCommand_HomTalk, //[orn]
 	AtCommand_HomInfo, //[Toms]
 	AtCommand_HomStats, //[Skotlex]
+	AtCommand_HomShuffle, //[Skotlex]
 	AtCommand_ShowMobs, //KarLaeda
 	// end <- Ahem, guys, don't place AtCommands after AtCommand_Unknown! [Skotlex]
 	AtCommand_Unknown,

+ 20 - 0
src/map/mercenary.c

@@ -730,6 +730,26 @@ void merc_hom_revive(struct homun_data *hd, unsigned int hp, unsigned int sp)
 	clif_homskillinfoblock(sd);
 }
 
+void merc_reset_stats(struct homun_data *hd)
+{	//Resets a homunc stats back to zero (but doesn't touches hunger or intimacy)
+	struct homunculus_db *db;
+	struct s_homunculus *hom;
+	hom = &hd->homunculus;
+	db = hd->homunculusDB;
+	hom->level = 1;
+	hom->hp = 10;
+	hom->max_hp = db->basemaxHP;
+	hom->max_sp = db->basemaxSP;
+	hom->str = db->baseSTR*10;
+	hom->agi = db->baseAGI*10;
+	hom->vit = db->baseVIT*10;
+	hom->int_= db->baseINT*10;
+	hom->dex = db->baseDEX*10;
+	hom->luk = db->baseLUK*10;
+	hom->exp = 0;
+	hd->exp_next = hexptbl[0];
+}
+
 int read_homunculusdb(void)
 {
 	FILE *fp;

+ 1 - 0
src/map/mercenary.h

@@ -62,6 +62,7 @@ void merc_hom_heal(struct homun_data *hd,int hp,int sp);
 int merc_hom_vaporize(struct map_session_data *sd, int flag);
 int merc_resurrect_homunculus(struct map_session_data *sd, unsigned char per, short x, short y);
 void merc_hom_revive(struct homun_data *hd, unsigned int hp, unsigned int sp);
+void merc_reset_stats(struct homun_data *hd);
 void merc_save(struct homun_data *hd);
 int merc_call_homunculus(struct map_session_data *sd);
 int merc_create_homunculus_request(struct map_session_data *sd, int class_);

+ 13 - 2
src/map/skill.c

@@ -1117,7 +1117,6 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int
 		break;
 
 	case WZ_STORMGUST:
-		tsc->data[SC_FREEZE].val3++;
 		if(tsc->data[SC_FREEZE].val3 >= 3) //Tharis pointed out that this is normal freeze chance with a base of 300%
 			sc_start(bl,SC_FREEZE,300,skilllv,skill_get_time2(skillid,skilllv));
 		break;
@@ -7121,7 +7120,19 @@ int skill_unit_onplace_timer (struct skill_unit *src, struct block_list *bl, uns
 						//Otherwise, Knockback attack.
 						skill_attack(BF_WEAPON,ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0);
 				break;
-
+				case WZ_STORMGUST:
+					if (tsc)
+					{	//This should be safe as skill_additional_effect 
+						//won't be triggered if the attack is absorbed. [Skotlex]
+						//And if the target is already frozen,
+						//the counter is reset when it ends.
+						if (tsc->data[SC_FREEZE].val4 == sg->group_id)
+							tsc->data[SC_FREEZE].val3++; //SG hit counter.
+						else { //New SG
+							tsc->data[SC_FREEZE].val4 = sg->group_id;
+							tsc->data[SC_FREEZE].val3 = 1;
+						}
+					}
 				default:
 					skill_attack(skill_get_type(sg->skill_id),ss,&src->bl,bl,sg->skill_id,sg->skill_lv,tick,0);			
 			}

+ 1 - 7
src/map/status.c

@@ -5957,13 +5957,7 @@ int status_change_clear(struct block_list *bl,int type)
 
 	sc = status_get_sc(bl);
 
-	if (!sc)
-		return 0;
-
-	if (sc->data[SC_FREEZE].val3)
-		sc->data[SC_FREEZE].val3 = 0; //Reset freeze counter.
-	
-  	if (!sc->count)
+	if (!sc || !sc->count)
 		return 0;
 
 	if(sc->data[SC_DANCING].timer != -1)