Chaosforge Forum

  • March 28, 2024, 06:38
  • Welcome, Guest
Please login or register.



Login with username, password and session length
Pages: [1]

Author Topic: Inventory  (Read 7572 times)

Igor Savin

  • Elder Chaos Guard
  • Second Lieutenant
  • *
  • *
  • Offline Offline
  • Posts: 180
    • View Profile
Inventory
« on: December 01, 2006, 11:46 »

(OK, this might better suit the "DiabloRL" forum, but I'll just pretend "Valkyrie" one is created for programming stuff... and it's pretty empty here anyway, so it isn't that much of littering)

Looks like I'm getting spoiled with all the goodies I found in Valkyrie, and ideology of "make games not engines" overcomes me more and more... There's lots of things to, *ahem*, "borrow" from BerserkRL (I guess the appropriate credit for everything I make would be "All the hard stuff: K. K. Anubis; All the fun stuff: *me*"), but there's one important thing missing: yep, you guessed right. Inventory&equipment. Hell, I feel confident enough with TNodes already to implement class-using inventory, but I don't know if it'd be worth reinventing the wheel (and it would be inferior one anyway)... The system you coded for DiabloRL works fine for me, and you mentioned that it's *possible* you will open-source it one day.

So yeah, generally it's a plea to release sources sooner rather than later; I'll make a good use of them *foxish grin*

Is everything *that* unoptimized, anyway?
« Last Edit: December 01, 2006, 11:48 by Igor Savin »
Logged

Kornel Kisielewicz

  • God Hand
  • Apostle
  • *
  • *
  • Offline Offline
  • Posts: 4562
    • View Profile
    • http://chaosforge.org/
Re: Inventory
« Reply #1 on: December 02, 2006, 05:16 »

Well, the DiabloRL inventory system IS complicated and unoptimized, mainly because of:
1) the "funny" way it presents equipment
2) the "slots" system it uses (object "volume")

I'll write something on inventories ASAP, stay tuned.

Before that you need to make some decisions tough:
1) fixed inv size (Angband, DoomRL) or open (DiabloRL/ADoM)
2) monster inventories?
3) equipment handling?
4) containers?

Testing code highliting (will be usefull in the future)...

Code: (delphi) [Select]
procedure TPlayer.PrepareItemList(const ItemContainer : TGameObject;
                                  const Filter : TFlags);
var Scan  : TGameObject;
    Count : Word;
    Count2: Word;
    Skip  : Boolean;
begin
  Count := 0;
  Scan := TGameObject(ItemContainer.Child);
  while Scan <> nil do
  begin
    if (Scan.ClassType = TItem) then
      if (Filter = AllFlags) or (Filter*Scan.Flags <> []) then
      begin
        Skip := False;
        if ItemContainer = Self then
          for Count2 := 0 to EqSize-1 do
            if Eq[Count2] = Scan then begin Skip := True; break; end;
        if not Skip then
        begin
          ItemList[Count] := TItem(Scan);
          Inc(Count);
        end;
      end;
    Scan := TGameObject(Scan.Next);
  end;
  ItemList[Count] := nil;
  ItemListSize := Count;
end;
« Last Edit: December 02, 2006, 05:51 by Kornel Kisielewicz »
Logged
at your service,
Kornel Kisielewicz

Igor Savin

  • Elder Chaos Guard
  • Second Lieutenant
  • *
  • *
  • Offline Offline
  • Posts: 180
    • View Profile
Re: Inventory
« Reply #2 on: December 02, 2006, 05:51 »

\1) fixed inv size (Angband, DoomRL) or open (DiabloRL/ADoM)\

Open.

\2) monster inventories?\

Yep. (since TPlayer is TBeing too, one can simply move all inventory-related functions to the TBeing, if inventory is implemented for TPlyaer only, right? And write appropriate interface for TPlayer and AI for TBeing)

\3) equipment handling?\

What are possible options here? I think ADoM's system is rather good (yet I don't see how much it is different from GearHead... or DiabloRL in that matter))...

(BTW, DiabloRL quickslots ARE something that really should be reuused somewhere else - too convenient)


\4) containers?\

What's with them?

As I see them, they should be able to
1) Hold different items (>1 item stack)
2) Have locks&traps (unrelated to inventory)
3) Possess limited capacity.
4) Both give and take items.

Is there something I missed?


Why won't you create class Inventory? I think it would have sense to define "PrepareItemList" for it, and then reuse it for everything, starting with chests and monsters, and ending with shops and PC...
Or is ItemContainer actually something like that? (since ItemContainer might be "= self")
Logged

Kornel Kisielewicz

  • God Hand
  • Apostle
  • *
  • *
  • Offline Offline
  • Posts: 4562
    • View Profile
    • http://chaosforge.org/
Re: Inventory
« Reply #3 on: December 02, 2006, 06:02 »

\3) equipment handling?\

What are possible options here? I think ADoM's system is rather good (yet I don't see how much it is different from GearHead... or DiabloRL in that matter))...

There's a difference in the internals between the DiabloRL/DoomRL way and for example Carceri. In Carceri equipment items are kept as children of TBeing, and just flagged as Equipment and added to a static array of Equipment pointers. In DiabloRL/DoomRL they are moved to that separate array and are no longer a Child of TBeing. Both methods have their advantages/disadvantages. The Carceri way is more proper in the OO sense, and allows easier handling of all items at the same time. But the DRL way is easier to implement, handle maintain.

\4) containers?\

What's with them?
If you want items within items this is going to be a pain to code and maintain ;-)


Why won't you create class Inventory? I think it would have sense to define "PrepareItemList" for it, and then reuse it for everything, starting with chests and monsters, and ending with shops and PC...
Or is ItemContainer actually something like that? (since ItemContainer might be "= self")
No, this function prepares a global item list for any container given (it may be TPlayer if browsing own inventory, or TBeing if stealing... etc). As for a TItemContainer class, I used that approach for GenRogue and it prooved to be messy unfortunately :(. The point was that we had to keep a initialized TItemContainer for every map cell... anyway... do you want multiple items on a single map square? If so, you will need to do a TItemContainer class anyway...
Logged
at your service,
Kornel Kisielewicz

Igor Savin

  • Elder Chaos Guard
  • Second Lieutenant
  • *
  • *
  • Offline Offline
  • Posts: 180
    • View Profile
Re: Inventory
« Reply #4 on: December 02, 2006, 06:12 »

Hmmm... I guess that DoomRL approach will be more appropriate for now.


\If you want items within items this is going to be a pain to code and maintain ;-)\

It's pain merely to think about it ;). Strict "no".

\do you want multiple items on a single map square? If so, you will need to do a TItemContainer class anyway...\

It was nice in ADoM... yet I don't see it as a "must". For the sake of organization (and economy of memory) I'll stick to "one stack (ex. arrows) per tile" approach.
It worked for DoomRL.
Logged

Kornel Kisielewicz

  • God Hand
  • Apostle
  • *
  • *
  • Offline Offline
  • Posts: 4562
    • View Profile
    • http://chaosforge.org/
Re: Inventory
« Reply #5 on: December 02, 2006, 06:15 »

Okay, so:
1) one item (or stack) per mapsquare
2) inventory handled seperately
3) monster inventory and equipment
4) open size inventory

Yes?
Logged
at your service,
Kornel Kisielewicz

Igor Savin

  • Elder Chaos Guard
  • Second Lieutenant
  • *
  • *
  • Offline Offline
  • Posts: 180
    • View Profile
Re: Inventory
« Reply #6 on: December 02, 2006, 06:31 »

Yes.
Logged

Kornel Kisielewicz

  • God Hand
  • Apostle
  • *
  • *
  • Offline Offline
  • Posts: 4562
    • View Profile
    • http://chaosforge.org/
Re: Inventory
« Reply #7 on: December 02, 2006, 07:27 »

Okay, so let's start. Item needs to be a descendant of TNode, as the player. I guess the structure should be:

Code: [Select]
TNode -> TThing -> TNPC  -> TPlayer
                -> TItem

You can also put something like TGameObject between TNode and TThing, I use it so all game objects have a base class.

First, item handling by TLevel. Make TItems children of TLevel. Assign proper x,y coords. And have the "TMapCell" like this:

Code: (delphi) [Select]
type TMapCell = record
  NPC : TNPC;
  Item : TItem;
  Cell : Byte; // a reference to a cell array;
end;

You may ask why is it a record and not an object? Because you will have LOTS of those, and the Allocation and disposing of them would be a hell both speed-wise and memory-fragmentation-wise.

When adding an object to the level you'd use something like this:

Code: (delphi) [Select]
procedure TLevel.AddItem(x,y : Word; Item : TItem);
begin
  // just safety measures, these should be checked
  // before, for proper fail handling
  if Item           = nil then Exit;
  if Map[x,y].Item <> nil then Exit;

  Map[x,y].Item := Item; // Register the item to the map
  Add(Item);             // Add it to Self's (TLevel) children
end;


Then item pickup is simple :

Code: (delphi) [Select]
  Level.Map[x,y].Item.Move(Player);
  Level.Map[x,y].Item := nil;

The Move method detaches the item from the level, and attaches it to the Player. Droping would be similar:

Code: (delphi) [Select]
procedure TPlayer.DropItem(Item : TItem);
begin
  // just safety measures, these should be checked
  // before, for proper fail handling
  if Item           = nil then Exit;
  if Map[x,y].Item <> nil then Exit;

  Item.Move(Level);
  Map[x,y].Item := Item;
end;

Here's a code to list the inventory items:

Code: (delphi) [Select]
procedure TPlayer.ListItems(Item : TItem);
var Scan : TNode;
begin
  Scan := Child;
  repeat
    if Scan.inheritsFrom(TItem) then
      Writeln(TItem(Scan).Name);
    Scan := Scan.Next;
  until Scan = Child;
end;

Yes, you shouldn't use Writeln :-P. But there's a problem here -- you chose unlimited inventory. The UI for unlimited inventory will be hard to code. My advice is to set a limit for inventory now, and then once you feel comfortable with it, redesign it without the limit -- it will be easy, cause engine-wise the limit will be fictional.

The way to handle UI anyway is to put all the items in an array of Items, sort/filter them while doing so, then allow a choice from the filtered list. You have an example in the test code I posted above :).
Logged
at your service,
Kornel Kisielewicz

Kornel Kisielewicz

  • God Hand
  • Apostle
  • *
  • *
  • Offline Offline
  • Posts: 4562
    • View Profile
    • http://chaosforge.org/
Re: Inventory
« Reply #8 on: December 02, 2006, 07:29 »

Uh wait -- that scan is broken, for it uses the single linked list approach of an older valkyrie :-P
Logged
at your service,
Kornel Kisielewicz

Igor Savin

  • Elder Chaos Guard
  • Second Lieutenant
  • *
  • *
  • Offline Offline
  • Posts: 180
    • View Profile
Re: Inventory
« Reply #9 on: December 06, 2006, 07:30 »

Aha... thanks. As soon as I deal with the Latin that arised suddenly, I'll integrate this code into my ouevre...
Logged
Pages: [1]