simple crafting system

Started by
21 comments, last by imontheverge7 9 years, 6 months ago

Look at 3 & 4 again...


//C#, compare by type, e.g. Rock == Rock, but Rock != Twig
typeof(slot.Item) == typeof(item.Item)

and like I said, the look logic is wrong as well.

Id suggest making an "int Inventory.GetCountOf(Item item)" to get how many of a given item is in the inventory, test that, once you are sure that works, use it to implement CheckForItemsNeeded with a single loop.

Advertisement

SyncViews has mentioned many of the design flaws already. Here re some more:

1.) public bool ItemRecipe.CanCraft

a) ... should not be publicly writeable because there is no sense in setting it from outside the class, BUT ...

b) ... is not meaningful at all because for every change in the inventory the CanCraft may become obsolete

2.) public bool ItemRecipe.CheckForItemsNeeded(Player player)

a) ... needs an Inventory object but gets a Player object; that restricts flexibility and burdens with unneeded knowledge of what Player is

b) ... doesn't compute what you want (SyncView has mentioned it).

3.) public class HammerRecipe : ItemRecipe

a) Seconding SyncViews: Do this in a data driven way, not by inheritance! Even better: Do this in a data driven way, NOT by inheritance!! ;)


Be sure not to "overcode" things. You don't always need an elaborate class or several functions to handle something that could, technically, be stored in a handful of variables.

While this is true in principle ... Don't mix the representation with the data model and/or the mechanics. It is not over-engineering if data model, logic, and presentation are separated.

Can you explaon what is.meant be data drivem and how it os better than inheritance in this case? From what i understand, youre saying instead of inherting, whenever i create a new instance of my Recipe class I populate the recipeitems list at the time of initialization. When i get off work ill make some more changes and post them


Can you explaon what is.meant be data drivem and how it os better than inheritance in this case? From what i understand, youre saying instead of inherting, whenever i create a new instance of my Recipe class I populate the recipeitems list at the time of initialization.

Data driven means that there is no concrete, specialized sub-class for everything but the parametrization makes the difference.

You shall ask "how does an instance of HammerReceipe differ from an instance of, say, ScrewdriverRecipe? You'll notice that it is not really different. They may differ in the amount of distinguishable items needed, but that is given with List<ReceiptItem>.length() already. They may differ in the kinds of items and/or their amounts, but that is encoded in the ReceiptItem stored within the List<ReceiptItem> already. If you implement ItemReceipt as an object factory, then they differ from the type of crafted items, but that can easily be defined by using cloning an ItemReceipt.resultingItem template. They may differ in some kind of representations like a name or an icon, but those need to be attached anyway. So in fact, HammerReceipe and ScrewdriverRecipe and any XyzReceipe do not differ from each other except in their data! Using inheritance in such a case does nothing more than cluttering your code with many (many!) more classes, making it less maintainable.

Imagine a file that defines the game content. Let there be an entry that enumerates the items and their respective amount, and a routine that is able to process this. This routine can create all of the recipes without knowing any specialization of the basic ItemRecipe class, because the basic class is all what is needed.

Ok I got rid of the inherited class and am just updating the recipe list when the CraftingSystem is created. But I still have no idea what I'm doing wrong in my CheckForItemsNeeded method. I'm looping through each InventorySlot and Item in RecipeItems and using item.Equals to compare them, and still I have nothing returning true. I'm lost tongue.png

While this is true in principle ... Don't mix the representation with the data model and/or the mechanics. It is not over-engineering if data model, logic, and presentation are separated

I rewrote my comment for clarity, I think I got myself misunderstood a little, here. Also, I wasn't implying that anyone was overcoding, I was just giving general advice.

Ok I got rid of the inherited class and am just updating the recipe list when the CraftingSystem is created. But I still have no idea what I'm doing wrong in my CheckForItemsNeeded method. I'm looping through each InventorySlot and Item in RecipeItems and using item.Equals to compare them, and still I have nothing returning true. I'm lost tongue.png

Show us the implementation of item.Equals.

One of the surprising things I discovered when attempting to implement a crafting system in my current project is just how complicated a "simple" crafting system can be. I think the level of discussion and the number of responses here illustrates that quite well.

On my inventory screen I have 5 crafting slots into which you can drop items. Every time something is dropped in a slot (or taken away), I quickly check all the known recipes and see if the items in the slots match any recipe. If so, I add a virtual item into the output slot that matches the output of the recipe. The player can then mouse over that item and find out what it is etc.

To that end, you may want to consider having the output also include a quantity rather than always imply a single item, as you can chop a log of wood into multiple pieces of firewood for example.

One thing that does bother me is the issue that Waterlimon raised which I'll dub "wiki syndrome" - where you have to consult the wiki to know the recipes or play the trial and error game. In my opinion, once you "know" a recipe, you should be able to activate it quickly if you have the required materials. That said, I haven't yet figured out a neat solution for that in my game, though it is on my todo list.

[size="2"]Currently working on an open world survival RPG - For info check out my Development blog:[size="2"] ByteWrangler

If your relying on the players to put inputs into some sort of slots, I think your basically stuck with a wiki or in game browser. Personally I have always gone with having the crafting system work by just displaying the list of known recipes (possibly grouped) with an indication (e.g. highlighting) of what is currently possible. The user simply clicks on the things in this list to craft them (there is some more complexity with crafting stations that are not instant, but I still display the list on the ui screen).

Hi.

What I like doing is a bit more work but I create a class that I define all the Objects Types in like, PLANT_TYPE has all things to do with plants.

class ObjTypePlant

{

static std::vector<UINT> PlantType;

static std::vector<std::string> TypeName;

public:

static DefinePlantType(UINT baseindx)//the startting range you want for plants to start at

{

//here you define your plants

PlantType.push_back(baseindex);//first plant type

TypeName.push_back("Tree1");

//when you want to define a new plant type add it to the list

baseindex++;//next type

PlantType.push_back(baseindex);

TypePlant.push_back("TheBushThatGiveLife");

baseindex++;//next type

}//end

//then setters and getters

static UINT GetType(UINT type)

{ UINT rt = -1;//sets it to max value a uint can hold

//find type in list or return -1

}

static UINT GetType(std::string type)

{

//same but find the string name or return -1 for error

}

};

use like

#define PLANT_START_RANGE 3000

#define UNIT_START_RANGE 4000//

//called at init time

ObjectTypePlant::DefinePlantType(PLANT_START_RANGE);

there static so you can have them through out the code base

This topic is closed to new replies.

Advertisement