Okay, so let's start. Item needs to be a descendant of TNode, as the player. I guess the structure should be:
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:
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:
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 :
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:
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:
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 :).