ID:2553869
 
(See the best response by Ter13.)
Code:
world
New()
for (var/Atype in typesof(/area))
var/area/A = new Atype
A.tag = A.name
..()

mob
Login()
Move(locate("staggerinn"))
..()

Move(area/A)
..()
src << "<b>[A.title]</b>"
src << "[A.desc]"
src << "[A.features] \..."

area/var
title
area/var/list
features

area
staggerinn
title = "The Stagger Inn"
desc = "A homely litte inn and tavern catering to a simpler folk."
features = list("chairsandtables","liquorcollection")

obj
chairsandtables
desc = "An assortment of salvaged chairs and tables for patrons to use."
liquorcollection
desc = "A neatly organized collection of wines, liquors, beers, and ciders sits on the shelf."


Problem description:

Hi, I am brand new to programming and have been following ZBT3 text MUD tutorial but want to do something different with how the description of the room is displayed. Instead of a static text description, I want to use lists to make room features interactive.

In the above code I believe I have created and defined a list variable called "features". That list variable should contain the objects "chairsandtables" and "liquor collection" when the player is in the "staggerinn" area.

I want the Move() proc to send that list to the player with the
Code:
src << "[A.features] \..."

line but obviously that isn't how to do it. Next question will be how to send the "desc" variable of those objects to the player instead of just the names.

I've tried reading up on lists but it's all still kind of overwhelming at this point. Help?
Best response
I would recommend that you don't use lists, but instead use objs IN rooms' contents to make them interactive.
That is what I intend to do but I want to separate those objects based on type and display them differently. Simply listing the contents of the rooms doesn't seem to give me options to treat types of objects differently.

For example if I have a shield, a door, and a sword in a room I would have the user interact with them all as objects but instead of having them jumbled together in the same output message to the user when they "look", I expect I can use a list to categorize them based on a variable tied to the object.

So the output message to the User would look like:
The Stagger Inn
A homely little inn and tavern catering to a simpler folk.
Exits: door
Items: shield, sword

instead of:
The Stagger Inn
A homely little inn and tavern catering to a simpler folk.
shield
door
sword

I can do the latter example no problem with:
for (var/obj/O in A)
src << "[O] \..."
This may not be the best advice but this is akin to the way I would accomplish this goal.

There is one glaring issue is that I see no way to reference objects via the strings you have listed as features. They could be tagged as well as the areas, but I think the approach I would take is having features refer to actual instantiated objects to simplify my code.

The way I would do that is through the area.New() override you have going on.

Another thing I would do is subclass /obj to create exits, or doors. This could be accomplished simply through variables and depending on your infrastructure, variable flags have some merit, but my first instinct is to subclass /obj to introduce new behavior. Then we can use istype(obj, /obj/door) to sort through data later.

Finally, you can use those loops you have to build strings to represent data. Much in the way you loop through objects in the area to display them, you can loop through object data in the same manner using a loop.

Relevant changes might look something like this.

area
staggerinn
title = "The Stagger Inn"
desc = "A homely litte inn and tavern catering to a simpler folk."
features = list(/obj/chairsandtables,/obj/liquorcollection, /obj/exits/door1) // obj types

obj/exits
var/target_area // where the user might go when walking through
door1
name = "door"
target_area = ...
door2
name = "door to alaska"
target_area = ...

area/New()
..()
// the goal is to replace features with a list of instantiated objects, we need to check that features isn't null and not empty
if(src.features && src.features.len)
var/list/nf = new
for(var/i in src.features)
nf += new i
src.features = nf

mob
Move(area/A)
..()
// this is where the magic happens.
src << "<b>[A.title]</b>"
src << "[A.desc]"

// we'll use a string-building approach
var/exits = ""
var/items = ""
for(var/obj/o in A.features)
if(istype(o, /obj/exits/))
exits = "[exits], "
else
items = "[items], "
if(lentext(exits) > 0)
src << "Exits: [exits]"
if(lentext(items) > 0)
src << "Items: [items]"


You could just as easily leave features alone and instantiate objects only when necessary but it is unnecessarily complex behavior for first beginnings. In fact, there are many ways to accomplish tasks in programming and figuring out which approach to take is usually the most difficult task.

If you wanted to ever make this faster, you might build the different strings you want to display to your users only at times when changes that might change those strings occur and cache them. For example, when a door goes away or an item gets picked up--that way, you don't have loops in your Move() code. For now, however, this will suffice.