If I want in general that using inventory1-on-inventory2 always gives the same result as using inv2-on-inv1... Is there a better way to achieve that other than just writing everything twice? I'm aware of the possiblilty to put code in a function and call that twice, but I'm hoping it can be generalized more.
thanks
Quote from: HandsFree on Sat 05/10/2013 10:05:43put code in a function and call that twice
is exactly what you need to do.
I don't see how making it even shorter would be possible, you have to establish that using x on y causes z and using y on x causes z.
OK, that's the way then. :)
thanks
I tend to write a function like this:
void Combine(this InventoryItem*, InventoryItem *other)
{
if (other == null) return;
if (this.ID > other.ID)
{
// make sure that this.ID is the lower ID
other.Combine(this);
return;
}
if (this == iCarrot)
{
if (other == iGrater)
{
player.LoseInventory(iCarrot);
player.AddInventory(iGratedCarrots);
}
}
}
This function prevents you from having to duplicate the interaction code. You can call it with the inventory items in either order and it will sort it so your interactions can be defined in ascending order (based on item ID).
Interesting, I'll give that a try. :cool:
thanks
I'm a bit confused by this actually.
First of all, if your game doesn't have a huge amount of combinations like that, what I would do is this:
function iCarrot_Useinv {
if (player.ActiveInventory == iGrater) grate_carrot();
else Unhandled(); // custom unhandled function or similar
}
The same for the the grater obviously, then a function called grate_carrot() further up.
Monkey:
I can see this Combine function being useful, but only if it is called directly inside on_mouse_click, as in
else if (button == eMouseLeftInv) {
if (player.ActiveInventory != null) player.ActiveInventory.Combine(inventory[game.inv_activated]);
...
}
Otherwise I don't see how you're avoiding duplicate interaction code. Is this how you intended it to be used?
Well, arguably, even if you had separate event handlers, the only duplicate code would be a single function call with no logic, which is pretty typical for methods that avoid code duplication. Calling it directly from on_mouse_click would of course make it even simpler, but either way it would still be simpler to do that than to do:
function iCarrot_Useinv()
{
if (player.ActiveInventory == iGrater) grate_carrot();
else Unhandled(); // custom unhandled function or similar
}
function iGrater_Useinv()
{
if (player.ActiveInventory == iCarrot) grate_carrot();
else Unhandled(); // custom unhandled function or similar
}
This actually involves duplication of logic, whereas either usage of the function (calling it from on_mouse_click or from the event handlers) I provided prevents duplicating the logic.
You all probably know this, but I just wanted to emphasize that you can link the same function to different events :
(http://image.noelshack.com/fichiers/2013/41/1381259041-iposter.png)(http://image.noelshack.com/fichiers/2013/41/1381259036-ikey.png)
function iPoster_UseInv()
{
//some code here.
}
It may be not the more ortodox way to avoid duplicate code, but IMO it is one of the advantages of the events-code linking system.
The problem with that route is that you then have no idea which item was used on the other.
The event handler would then have to be something like this to avoid code duplication:
function iPoster_UseInv()
{
InventoryItem *a = inventory[game.inv_activated];
InventoryItem *b = player.ActiveInventory;
if (((a.ID > b.ID) && !((a == iPoster) && (b == iKey))) || ((a == iKey) && (b == iPoster)))
{
a = player.ActiveInventory;
b = inventory[game.inv_activated];
}
if (a == iPoster)
{
if (b == iKey)
{
// interactions here
}
}
}
That's a rather horrible way of preventing code duplication.
Yes, you're right. It's useless for inventory item on inventory item usage. It is mostly useful when dealing with hotspots / objects.