ID:2096356
 
(See the best response by Lummox JR.)
Code:
var/list/MartialPassives=list()

mob
proc
ListPassives(var/ClassType="")
src << output(null,"Passive.Passive2")//clears it
if(ClassType=="Martial Artist")
if(!locate(/obj/Passives/Martial_Artist/Full_Force) in MartialPassives)
var/obj/Passives/Martial_Artist/Full_Force/A=new
MartialPassives+=A
if(!locate(/obj/Passives/Martial_Artist/Full_Force2) in MartialPassives)
var/obj/Passives/Martial_Artist/Full_Force2/D=new
MartialPassives+=D
if(!locate(/obj/Passives/BuySkills/MartialArtist/Heavy_Strike) in MartialPassives)
var/obj/Passives/BuySkills/MartialArtist/Heavy_Strike/B=new
MartialPassives+=B
for(var/obj/C in MartialPassives)
usr << "[C.name] (\ref[C])"
usr << output(C,"Passive.Passive2")


Problem description:

The issue is, it's building the list just fine, but it only displays the final item in that list on my grid element(passive.passive2). I think it's a problem with my grid? The settings have it set as a flexible list of entries, starting cell is 1,1.. Not sure what could be the issue. Any help would really be appreciated!

Best response
usr has no place in a proc. Change that to src, which is the correct choice here.

Here's the reason you're only seeing one item: You don't specify a grid cell. You need to choose a cell number for the item to go in. Since this grid is in list format, the cell is just one number instead of two.

var/idx = 0
for(var/obj/C in MartialPassives)
src << output(C,"Passive.Passive2:[++idx]")

The locate/new code above all that is kind of disturbing, though. Seems like you could save yourself a crapload of time this way:

if(ClassType=="Martial Artist")
var/list/skills = typesof(/obj/Passives/Martial_Artist) - /obj/Passives/Martial_Artist
skills += typesof(/obj/Passives/BuySkills/Martial_Artist) - /obj/Passives/BuySkills/Martial_Artist
MartialPassives = newlist(skills)

You can probably do even better by having a quick way to get those two type paths (the regular and buyable passives) from the string without a lot of if/else checks. For instance, if your class naming scheme is consistent where the name always stays the same and spaces are replaced by underscores:

// replacetext() is in 510, but you can also do this other ways
var/ct = replacetext(ClassType, " ", "_")
var/innate = text2path("/obj/Passives/[ct]")
var/buyable = text2path("/obj/Passives/BuySkills/[ct]")
passives[ClassType] = newlist((typesof(innate) - innate) + (typesof(buyable) - buyable))
var/idx = 0
for(var/obj/C in passives[ClassType])
src << output(C,"Passive.Passive2:[++idx]")
Thank you! It's working well enough, though I did try to use that second dm quote to make it simpler, so I don't have to manually add every object to the list, but it had a runtime error, and couldn't generate the objects of that list?

mob
proc
ListPassives(var/ClassType="")
src << output(null,"Passive.Passive2")//clears it
if(ClassType=="Martial Artist")
var/list/skills=typesof(/obj/Passives/Martial_Artist) - /obj/Passives/Martial_Artist
skills+=typesof(/obj/Passives/BuySkills/Martial_Artist) - /obj/Passives/BuySkills/Martial_Artist
MartialPassives=newlist(skills)
var/gridcount=0
for(var/obj/C in MartialPassives)
src << "[C.name] (\ref[C])"
src << output(C,"Passive.Passive2:[++gridcount]")


runtime error: Cannot create objects of type /list.
proc name: ListPassives (/mob/proc/ListPassives)
usr: (src)
src: Tempestous Heart (/mob/player)
src.loc: the gridlines (15,1,1) (/turf/gridlines)
call stack:
Tempestous Heart (/mob/player): ListPassives("Martial Artist")
Martial Artist (/obj/Classes/Martial_Artist): Click("1", "Passive.Passive1", "icon-x=150;icon-y=6;left=1;dra...")
Hrm, so apparently newlist() can't take a list as an argument. That's not so good; I think that should be changed.

But, you can go about it this way:

MartialPassives = list()
for(var/tp in skills) MartialPassives += new tp()


[edit]
Okay, looks like changing newlist() to accept a list isn't that simple. It's effectively a macro for list(new/item1, new/item2, ...) rather than its own instruction. Not something that can be easily altered in the runtime code. Guess that's going on the back burner.
Whoah whoah whoah. Macros with variadic argument lengths?

does DM support the C99 preprocessor structure?
In response to Ter13
Ter13 wrote:
Whoah whoah whoah. Macros with variadic argument lengths?

does DM support the C99 preprocessor structure?

Sadly no. What's happening is that newlist() is interpreted specially by the compiler, and it converts the children (the list arguments) into new() instructions, then appends a list() instruction.

So my idea of using newlist() on a runtime-generated list won't work. It gets changed to list(new/theruntimelist).

[edit]
Come to think of it, even variadic macros couldn't work this way. It'd have to perform an operation on each argument.
Although it's not relevant to this issue, I think variadic macros look much more doable than they once did, so I've put them on my list.