Jump to content
Tero

Release: Homunculus Storage

Recommended Posts

This is not tested under renewal.  I think it should still work, but test it with a GM character first.

 

The default implementation of Homunculi is kind of obnoxious.  When you create one, you get one of the homunculi at random, and in order to get another one, you have to completely delete them from existence.  Wouldn't it be nice if you could keep the other homunculi to use later?  Well, now you can!

 

EmbyroMod.png.e55978e9e9d6e87afd4d0252a4dfeba1.png

 

What it does:

- When you use rest, the Homunculus returns to its Embyro.

- You can use Call Homunculus to call it back out, just as it was when you rested it.

- You can store the Homunculus for later use, allowing you to raise a different Homunculus, which is not normally possible.

- Only you can call the Homunculus back out.  If another alchemist tries to call it, it doesn't let them.

- You can still delete the Homunculi as normal to remove them from existence completely.

 

How it works from a technical perspective:

- When you rest the homunculus, it is technically "removed" from you, similar to deleting it, but it returns an embyro with the Homunculus id set to its card[1] slot.

- When you call out a Homunculus from an Embyro, if the embyro has a value in its card[1] slot, it restores that Homunculus instead of creating a new one.

 

Some minor limitations:

- It's not possible to distinguish embryos from each other, and call homunculus will always try to call the first one it finds in your inventory.  You'll need to store the ones you don't want to raise right now, and it may take some trial and error to hatch the right one if you have a bunch.

- The name display of the embryo doesn't work with the client I have (it seems like the client will only display the name if the card[1] slot is 0, which it's not if a homunculus is in there).  This makes it hard to tell who owns a homunculus embyro.

 

How to implement:

Make the following code changes:

 

In homunculus.cpp:

Find the method "hom_vaporize":

First, add the following variable declarations to the top, under the existing ones:

	int itemflag;
	struct item tmp_item;

Next, comment out the following line:

hd->homunculus.vaporize = flag ? flag : HOM_ST_REST;

Then, insert the following at the end of the method, just before the return statement.

if (hd->homunculus.intimacy > 0) {	

		memset(&tmp_item, 0, sizeof(tmp_item));
		tmp_item.nameid = 7142;
		tmp_item.amount = 1;
		tmp_item.identify = 1;
		tmp_item.card[0] = CARD0_CREATE;
		tmp_item.card[1] = hd->homunculus.hom_id;
		tmp_item.card[2] = GetWord(sd->status.char_id, 0); // CharId
		tmp_item.card[3] = GetWord(sd->status.char_id, 1);

		if ((itemflag = pc_additem(sd, &tmp_item, tmp_item.amount, LOG_TYPE_PRODUCE))) {
			clif_additem(sd, 0, 0, itemflag);
			if (battle_config.skill_drop_items_full) {
				map_addflooritem(&tmp_item, tmp_item.amount, sd->bl.m, sd->bl.x, sd->bl.y, 0, 0, 0, 0, 0);
			}
		}

		unit_remove_map(&hd->bl, CLR_OUTSIGHT);
		sd->status.hom_id = 0;
		unit_free(&hd->bl, CLR_OUTSIGHT);
		sd->hd = 0;
		return 1;
	}

 

Next, find the method "hom_call":

Find this code:

if (!sd->status.hom_id) //Create a new homun.
		return hom_create_request(sd, HM_CLASS_BASE + rnd_value(0, 7)) ;

Replace it with this:

	struct item ed;
	int n;

	// find the embryo
	if (!sd->status.hom_id) { //Create or revive a homun.
		if ((n = pc_search_inventory(sd, 7142)) >= 0) {
			ed = sd->inventory.u.items_inventory[n];
		}
		else {
			return false; // no embryo
		}

		if (ed.card[1] != 0) {
			// is it ours?
			if (sd->status.char_id == MakeDWord(ed.card[2], ed.card[3])) {
				// revive the homun

				// delete the embryo
				pc_delitem(sd, n, 1, 0, 0, LOG_TYPE_CONSUME);
				clif_delitem(sd, n, 1, 3);

				sd->status.hom_id = ed.card[1];
				// proceed with rest of function
			}
			else {
				// Cannot revive someone else's homunculus
				return false;
			}			
		}
		else {
			// create a new homun

			// delete the embryo
			pc_delitem(sd, n, 1, 0, 0, LOG_TYPE_CONSUME);
			clif_delitem(sd, n, 1, 3);
			return hom_create_request(sd, HM_CLASS_BASE + rnd_value(0, 7));
		}
	}

 

Almost done, just one small change to make in skill.cpp.

 

Find this line:

	if (sd->status.hom_id) //Don't delete items when hom is already out.

And comment it out (we never want this method to delete the embyros, since the call method now handles it).

 

Now just recompile your server and you should have the new homunculus behaviour.

  • Love 1
  • Like 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use and Privacy Policy.