[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Adonthell-devel] Item action thoughts

From: Kai Sterker
Subject: [Adonthell-devel] Item action thoughts
Date: Tue, 28 Jan 2003 18:42:10 +0100

To get on with the item code, I want to take down a few thoughts about
item actions, to see what needs to be implemented.

Charging an item (i.e. a lamp)

Guess the lamp would have a "combine" action that works as follows:

    def combine (self, item):
        fuel = item.get_instance ()
        if not fuel.is_a ("Lampoil"): return
        fuel_needed = self.MaxCharge - self.Charge:
        if fuel.Charge > fuel_needed:
            fuel.Charge = fuel.Charge - fuel_needed
            self.Charge = self.MaxCharge
            self.Charge = self.Charge + fuel.Charge
            del item

So what happens here? We get some C++ item and aquire it's python
instance. Next we check whether it'll fuel the lamp. If it does, we
calculate how much fuel will fit into the lamp. If the item provides
more fuel, we take away as much as fits and refill the lamp. But if the
item provides less fuel than fits into the lamp, we'll fill the lamp as
much as we can and destroy the item. This implies that the item will
remove itself from the inventory it is in. (All items should do that!)

It would work similarly for other items which can be recharged. The
question is, will we ever have the case where the player wants (or
needs) to control the amount of charge to put into an item? Like, "I
only want to put half of my lampoil into that lamp".

Should it become neccessary for a special item, I guess that item's
combine method could open a window where the player can select a number
between 0 and min (item.Charge, self.MaxCharge - self.Charge).

The rest would be analog. Which would cover charging an item.

Transforming an item (i.e. stick to arrow)

Again, our stick would have a "combine" method:

    def combine (self, item):
        knife = item.get_instance ()
        if not knife.is_a ("Knife"): return

        self.load ("wooden_arrow.item")

After checking whether the stick is combined with a knife, it's
transformed into a simple arrow. Voila.

Since we could have a stack of sticks, combine should always use a
corresponding method of the inventory, so that the whole stack is
converted to arrows. Something like (in pseudocode)

    void inventory::combine (slot1, slot2)
        foreach item in slot1:
            if slot2 not empty:
                item.combine (slot2.item);

The next example will show why we need to check whether slot2 still
contains an item. A knife will not vanish, but a bottle of poison might
get used up, for example.

Poisoning an arrow

Again, we'd use the combine method for that.

    def combine (self, item):
        poison = item.get_instance ()
        if not poison.is_a ("Poison"): return
        if self.is_a ("Poisoned Weapon"): return

        poison.Charge = poison.Charge - 1
        self.Name = "%s (poisoned)" % self.Name
        self.Damage = self.Damage + poison.Damage 
        self.add_category ("Poisoned Weapon")

        if poison.Charge == 0: del item

The code here is a bit more vague, as I do not know yet which attributes
an arrow would have. (Nils, Ben, that's your job, ain't it?)

Anyway, we check whether we have poison and whether the arrow isn't
poisoned already. (If weapons had a "poisoned" flag, this would be a bit
easier.) Next we apply some poison to the arrow, and remove it from the
bottle of poison. If the bottle is empty, it is deleted.

Now imagine a bottle of poison with 20 charges is applied to a stack of
40 arrows. That would poison half of the arrows but no more. It would
also leave us with a mixed stack of arrows, which isn't good. So the
inventory code needs some additions:

First of all, combine should return the result of the combination. 

    void inventory::combine (slot1, slot2)
        foreach item in slot1:
            if slot2 not empty:
                item.combine (slot2.item)
                move item to slot2

This works, because we know that slot2 is empty. That means we either
end up with one stack of equally transformed items in slot1 (and
possibly some items left in slot2 as well). Or we have some transformed
items in slot1, and a number of original items in slot2.

A slight improvement of the else part would be:

    slot1.remove (item)
    inventory::add (item)

That is, we do not move items to slot2 at once, but will re-add them to
the inventory. This assumes that inventory::add will first search for a
stack new items can be added to. Only if that does not exist, it would
add them to an empty slot. As we know that we have at least one empty
slot, there won't be any problem.

Hm, this pretty much covers the combine action, doesn't it? Anything
else that could be done with it? If you have further ideas, I'd be
happy to give them a thought, as long as they require a different
approach than those I dealt with so far. So fire away!

Anyway, it seems that combine (and other actions) require an inventory
to properly implement them. So first of all I'll have some thoughts
about inventories. Expect a mail about that soon. Until then feel free
to comment on the examples above.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]