简体   繁体   中英

Searching for child class properties in a list

Right now I'm creating a Quest Requirement Checker in order to find if a player is able to accomplish a mission. The type of mission that I'm working with right now is the "Have An Item In Inventory" which, as you can see, will get done if the player has one or more specified items inside his/her inventory.

Now, what is my exact problem? Well, the... items.

First of all. Item is a class with the next structure:

public int ID { get; set; }
public string Name { get; set; }
public double Price { get; set; }

public Item(int id, string name, double price)
{
    ID = id;
    Name = name;
    Price = price;
}

And there is a class named Tool which extends the Item class:

public string Material { get; set; }
public string Classification { get; set; }

public Tool
    (
        int id,
        string name,
        double price,
        string material,
        string classification
    ) : base(id, name, price)
{
    Material = material;
    Classification = classification;
}

Now, this is how I create every Tool:

Items.Tool tool = new Items.Tool(1, "Shovel", 100, "Wood", "Poor");

My player object has and List of items like this one:

public List<Items.Item> InventoryItems { get; set; }

And it works as its inventory. Also, to add a new item to the list, I use this function:

player.AddItem(tool, 1);

public void AddItem(Items.Item item, int quantity)
{
    for(int i = 0; i < quantity; i++)
    {
        InventoryItems.Add(item);
    }
}

On the other hand, my current quest type "Has Items In Inventory" has a property that is, at the same time, a list of items:

public List<Items.Item> RequiredItems { get; set; }

And this is how I add items to this list:

quest.AddRequiredItem(tool, 1);

public void AddRequiredItem(Items.Item item, int quantity)
{
    for(int i = 0; i < quantity; i++)
    {
        RequiredItems.Add(item);
    }
}

In order to fulfill this quest, the player must have the same amount (or more) of items that the RequiredItems list have. So, if this quest ask the player to look around for 3 Poor Wooden Shovels, it should have at least 3 Poor Wooden Shovels on its InventoryItems list.

My quest, which is a class named HaveItemsInInventory implements the next function in order to evaluate that condition:

override public bool Accomplish()
{
    bool questAccomplished = true;
    foreach (var group in RequiredItems.GroupBy(x => x))
    {
        if (Application._player.InventoryItems.Count
            (
                x =>
                (
                    x.Name == group.Key.Name && 
                    x.Material == group.Key.Material &&
                    x.Classification == group.Key.Classification
                )
            ) < group.Count())
        {
            questAccomplished = false;
            break;
        }
    }

    return questAccomplished;
}

And this where all my problems appear. This two lines or code are wrong:

x.Material == group.Key.Material &&
x.Classification == group.Key.Classification

Because there's no such thing as a Material or Classification in a Item .

What i want to do is to implement different types of evaluations.

  • If an quest ask for a Glass of Water, I should look for properties living inside my Beberage class.

  • If the quest ask for just a Sword. I should look for a item with the Name "Sword" in its inventory.

  • If the quest ask for a Diamond Legendary Sword, well... You get my point.

Is there a way to look for these extended classes properties within my system? I can't find a way to do so.

PD: Sorry for my bad english, not a native speaker.

EDIT: I've edited my answer to address the idea of a generic task method.

If you want the task to be generic across multiple different types, you probably want to implement an IsSame or IsEquivalent method on Items.Item , and then inherit that method. You could even override the Object.Equals method (and that might be a more appropriate way).

class Item
{
    public virtual bool IsSame(Item comp){ return comp.Name == Name; }
}

class Tool: Item
{
    public override bool IsSame(Item comp)
    {
        return base.IsSame(comp) && (comp is Tool) && ((Tool)comp).Material == Material && ((Tool)comp).Classification == Classification;
    }
}

Then in your accomplish iteration:

override public bool Accomplish()
{
    bool questAccomplished = true;
    foreach (var group in RequiredItems.GroupBy(x => x))
    {
        if (Application._player.InventoryItems.Count
            (
                x =>
                (
                   x.IsSame(group.Key)
                )
            ) < group.Count())
        {
            questAccomplished = false;
            break;
        }
    }

    return questAccomplished;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM