Decoded: Rogue (1980) by Toy, Arnold, Wichman
DOS version (1983) by Mel Sibony and Jon Lane
Source file: PACK.C
Beginner friendly, line-by-line code walkthrough by MaiZure

PACK.C provides inventory management functions

Original code:
https://britzl.github.io/roguearchive/

Original code with line numbers
http://www.maizure.org/projects/decoded-rogue/PACK_linenum.txt



1     Include game header
2     Include the console management header
3     BLANK
4     COMMENT
5     COMMENT
6     COMMENT
7     COMMENT
8     COMMENT
9     BLANK

GET INVENTORY ITEM BY LETTER

10    pack_obj returns a pointer to an object
11    Defines pack_obj with two arguments
12    Arguments 1 is an input object index and Argument 2 is the offset 
13    BLOCK START - pack_obj, returns object and updates backpack pointer
14    Declares a pointer to an object
15    Declares a character to match
16    BLANK
17    Loop through each item in the inventory
18    If the input character matches an item's index character
19    Return the object
20    Set the input pointer to the character
21    Return NULL
22    BLOCK END - pack_obj
23    BLANK
24    COMMENT
25    COMMENT
26    COMMENT
27    COMMENT
28    COMMENT
29    COMMENT

ADD ITEM TO INVENTORY

30    Defines add_pack with two arguments
31    Argument 1 is a pointer to an object
32    Argument 2 is a flag to report the pick up to the player
33    BLOCK START - add_pack, adds an item to inventory
34    Delcares two pointers to inventory objects to iterate over
35    Declares flags for picked up items and for exact matches
36    Declares a byte for the floor value/type
37    BLANK
38    If the input object isn't specified
39    BLOCK START - Check floor for object
40    Set from_floor flag
41    If there is no object on the floor
42    Return fail
43    BLOCK END - Check floor for object
44    Otherwise...
45    Object was input, not from floor
46    COMMENT
47    COMMENT
48    COMMENT
49    COMMENT
50    COMMENT
51    COMMENT
52    COMMENT
53    COMMENT
54    COMMENT
55    Get the floor type, either passage or floor based on room type
56    If the object is part of a group...
57    BLOCK START - Has inventory group
58    Loop through all items in a pack
59    BLOCK START - Check pack
60    If the object has a matching group..
61    BLOCK START - Add object to inventory stack
62    COMMENT
63    COMMENT
64    COMMENT
65    Add to the inventory count
66    If the item came from the floor
67    BLOCK START - Item from floor
68    Remove item from the level
69    Add the proper floor character to the screen
70    Add the floor character to the map data
71    BLOCK END - Item from floor
72    Free the object from memory
73    Report object pointer to the backpack slot
74    Jump to line 178 to handle post-pickup effects (skip other pickup types)
75    BLOCK END - Add object to inventory pack
76    BLOCK END - Check pack
77    BLOCK END - Has inventory group
78    COMMENT
79    COMMENT
80    COMMENT
81    If the player's inventory is full
82    BLOCK START - Inventory full
83    Print inventory full message
84    Return failure
85    BLOCK END - Inventory full
86    COMMENT
87    COMMENT
88    COMMENT
89    If the object is a scare monster scroll...
90    And the player has found the object already...
91    BLOCK START - Moving scare monster scroll
92    Remove the scroll from the level
93    Add a floor character to the floor
94    Add a floor character to the map data
95    Send message that the scroll is destory
96    Return failure to pick up
97    BLOCK END - Moving scare monster scroll
98    Otherwise...
99    Set object to found
100   BLANK
101   Add to the inventory counter
102   If the object came from the floor
103   BLOCK START - Floor pickup
104   Remove the object from the level 
105   Add the floor square to the position
106   Add the floor square to the map data
107   BLOCK END - Floor pickup
108   COMMENT
109   COMMENT
110   COMMENT
111   Assume object is new, doesn't match anything the character already has
112   Loop through the inventory
113   If we find a matching object
114   Break at this point to save the pointer position
115   If no matching object type was found...
116   BLOCK START - New object type in backpack
117   COMMENT
118   COMMENT
119   COMMENT
120   Loop through the backpack
121   BLOCK START - Find new position in backpack
122   If the object isn't of type food
123   Break at this position
124   Track the last pointer
125   BLOCK END - Find new position in backpack
126   BLOCK END - New object type in backpack
127   Otherwise we found a matching object
128   BLOCK START - Found a potential match in inventory
129   COMMENT
130   COMMENT
131   COMMENT
132   Loop to find matching object sub-types
133   BLOCK START - Matching object subtypes
134   If the subtypes match
135   BLOCK START - Found type/subtype match
136   Set exact flag to true
137   Break from loop with these pointers set
138   BLOCK END - Found type/subtype match
139   Set last pointer to this position
140   If this is the last item
141   Break from outer loop
142   BLOCK END - Matching object subtypes
143   BLOCK END - Found a potential match in inventory
144   If matching objects were found..
145   BLOCK START - No match, insert object at the end
146   COMMENT
147   COMMENT
148   COMMENT
149   If the monster has no inventory at all...
150   This is the first object
151   Otherwise
152   BLOCK START - Add object to the end
153   Change the last valid object's next to the new object
154   Set the new object's last pointer to the previous
155   This is the last object, no next
156   BLOCK END - Add object to the end
157   BLOCK END - No match, insert object at the end
158   Otherwise, we've found an exactly match
159   BLOCK START - Verify inventory stack
160   COMMENT
161   COMMENT
162   COMMENT
163   COMMENT
164   If there is an exactly match and this is a stackable object...
165   BLOCK START - Add to stack
166   Add to inventory counter
167   Remove the object picked up
168   Point to the inventory position
169   Jump to picked up subroutine
170   BLOCK END - Add to stack
171   Set the previous object's pointer and check if it exists...
172   If so, set the previous object to the current object we're inserting
173   Otherwise this object is at the head of the inventory
174   The inventory points to this object
175   Set this object's next pointer
176   Set the next object to this object
177   BLOCK END - Verify inventory stack
178   Label for after pickup effects
179   COMMENT
180   COMMENT
181   COMMENT
182   COMMENT
183   Loop through all the monsters on the level
184   COMMENT
185   COMMENT
186   COMMENT
187   COMMENT
188   COMMENT
189   COMMENT
190   COMMENT
191   COMMENT
192   COMMENT
193   COMMENT
194   If the monster was trying to reach the object the player picked up...
195   The monster will now chase the player
196   BLANK
197   If the player just picked up the amulet of Yendor...
198   BLOCK START - Got amulet of Yendor
199   Set global flag that player has the amulet
200   Set global flag that player saw the amulet
201   BLOCK END - Got amulet of Yendor
202   COMMENT
203   COMMENT
204   COMMENT
205   If the silent flag isn't set
206   Send a message that he player picked up the object...
207   Include the inventory position
208   BLOCK END - add_pack
209   BLANK
210   COMMENT
211   COMMENT
212   COMMENT
213   COMMENT

SHOW INVENTORY

214   Define inventory with three arguments
215   Argument 1 is a pointer to the first item in the list
216   Argument 2 is the type to filter for
217   Argument 3 is the substring to search for
218   BLOCK START - inventory, lists out the items in inventory
219   Declare the inventory index character
220   Declare a counter for number of objects
221   Declare a buffer
222   BLANK
223   Initialize the number of objects to zero
224   Loop throuh all of the items in inventory
225   BLOCK START - Inventory loop
226   COMMENT
227   COMMENT
228   COMMENT
229   COMMENT
230   COMMENT
231   COMMENT
232   If type is set and the object matches the type...
233   If it's not a callable scroll, or potion...
234   or ring or wand...
235   ...and it's not zappable...
236   ...or with a vorpal effect
237   Skip this item
238   Increment the number of object
239   Print the inventory item to the temporary buffer
240   Add the line from the temporary buffer to the output string
241   BLOCK END - Inventory loop
242   If no objects were added...
243   BLOCK START - No inventory
244   If no type was input...print empty handed or..
245   Print no type available
246   Return no list
247   BLOCK END - No inventory
248   Return the inventory list after removing the final endline character
249   BLOCK END - inventory
250   BLANK
251   COMMENT
252   COMMENT
253   COMMENT
254   COMMENT

PICK UP ITEM

255   Define pick_up with one argument
256   Argument 1 is the item to pick up
257   BLOCK START - pick_up, pick up an item
258   Declare a pointer to an object
259   BLANK
260   Switch on the type of object
261   BLOCK START - Switch on the type of object to pick up
262   CASE gold
263   If there is no object under the player..
264   Return, nothing to do
265   Add the money in the stack
266   Remove the money from the map
267   Free the money object memory
268   Remove the gold value from the room
269   Break from picking up
270   CASE any type (fallthrough)
271   CASE armor (fallthrough)
272   CASE potion (fallthrough)
273   CASE food (fallthrough)
274   CASE weapon (fallthrough)
275   CASE scroll (fallthrough)
276   CASE amulet (fallthrough)
277   CASE ring (fallthrough)
278   CASE stick
279   Add the object to the pack
280   End check for object type
281   BLOCK END - Switch on the type of object to pick up
282   BLOCK END - pick_up
283   BLANK
284   COMMENT
285   COMMENT
286   COMMENT
287   COMMENT

USE ITEM FROM PACK

288   get_item returns a pointer to an item
289   Defines get_item with two arguments
290   Argument one is a string describing the purpose of the item
291   Argument 2 is the type of item
292   BLOCK START - get_item, uses and item from inventory
293   Declare a pointer to an object
294   Declare a character used to hold user input
295   Declare a character used for inventory index
296   Declare yet another character
297   Declare a pointer to hold a previous object
298   Declare a character to match the repeat global state
299   Declare a flag for repeating
300   BLANK
301   If the purpose is to select or eat...
302   ...or drop, or wear
303   Only do this once
304   BLANK
305   Match the repeat state from the global
306   If there is nothing in inventory...
307   Print out empty inventory
308   Otherwise, search inventory
309   Match the last character (not init)
310   Loop until items are uses up
311   COMMENT
312   COMMENT
313   COMMENT
314   COMMENT
315   COMMENT
316   If we're getting multiple items but we still have one buffered...
317   Jump to line 329 to skip item selection
318   If we're only doing this one time...
319   Set character to the character that shows action list
320   Jump to line 329 to skip item selection
321   End of shortcut checks
322   We're not in terse mode...
323   Query the player to select an item...
324   And to choose a purpose
325   COMMENT
326   COMMENT
327   COMMENT
328   Get user input for purpose
329   Label for skipping input
330   Reset the message buffer
331   Clear the repeat input state
332   Clear the once flag
333   If we chose to look at the list of actions
334   If the user doesn't select an item...
335   Clear the repeat flag
336   Return nothing
337   End of check for nothing
338   If the player input a space
339   Skip this round
340   Otherwise, save the input for a possible repeat
341   End of check for listing options
342   COMMENT
343   COMMENT
344   COMMENT
345   Check if the player tried to escape out of the selection
346   Reset the repeat flag  
347   Clear the message buffer
348   Return nothing
349   End of check for early escape
350   If the player chose an invalid option
351   Print the retry message
352   Skip this round
353   Otherwise...
354   COMMENT
355   COMMENT
356   COMMENT
357   COMMENT
358   COMMENT
359   COMMENT
360   If the input purpose is to identify
361   Save the input character
362   Save the repeated object
363   End check for identify
364   Return the object
365   End check for selected object
366   Repeat loop until object or nothing returns
367   End check inventory
368   Nothing was found, return nothing
369   BLOCK END - get_item
370   BLANK
371   COMMENT
372   COMMENT
373   COMMENT
374   COMMENT

GET PACK INDEX

375   Defines pack_char with one argument
376   Argument one is a pointer to an object
377   BLOCK START - pack_char, gets the inventory index
378   Declare a pointer to an object
379   Declare the return character
380   BLANK
381   Set the character to the initial item
382   Loop through the pack
383   If the item matches input
384   Return the character
385   Otherwise...
386   Try the next character
387   Return unknown
388   BLOCK END - pack_char
389   BLANK
390   COMMENT
391   COMMENT
392   COMMENT
393   COMMENT

GIVE MONEY TO INVENTORY

394   Define money with one argument
395   Argument 1 is a gold value
396   BLOCK START - money, add or take away gold
397   Declare a floor space byte
398   BLANK
399   Get the floor space, either passage or floor
400   Add the value to the purse (Could be negative)
401   Print the character to the screen
402   Add the character to the level data
403   If the input value is positive
404   BLOCK START - positive gold find
405   Print about gold find
406   BLOCK END - positive gold find
407   BLOCK END - money
408   EOF