ID:2619625
 
Code:
(The buy Verb)
mob
verb
Buy(var/obj/passive/A)
set hidden=1
var/cost=A.PCost
var/Choice=alert(usr,"Would you like to buy [A.name]: [A.desc]: [cost]","",text) in list("Yes","No")
switch(Choice)
if("Yes")
if(usr.passivep>=cost)
alert(usr,"You have purchased [A.name]")
(Click Proc)
client
Click(A,B,C)
if(C=="Passive.grid")
if(istype(A,/obj/passive/))
usr.Buy(A)
..()

(What makes the list)
mob/verb
MakeList()
set hidden=1
if(src.client)
var/list/A=list()
var/row= 1, col=0, max_col=3
for(var/V in typesof(/obj/passive))
var/obj/passive/F = new V
if(F.name=="passive") break
if(findtext("[F.name]",,1,0) in A) break
A+=F
col ++
if(col>max_col)
row ++
col=1
src<<output(F,"grid:[col],[row]")


Problem description:
So I can generate the list fine. It appears on the interface properly and so on. However when I click on it attempting to buy the passive it does northing, I see no alert pop up on my screen or anything. Been messing around with it sometime and figured I should ask the community. Thank you for any help in advance!
Figured out the problem. It was being collected by the garbage collector and it had no reference. Creating a list that saves to the player and referencing the list on the Click() proc seems to do the trick. Posting this here for anyone that runs into the same problem.
I would have thought that appearing in a grid control would be reference enough to avoid garbage collection. If you can see the object, there's no reason to believe it was deleted amirite? Can we see your new code? Having something that works, but you don't know why, is a recipe for delayed disaster...

In the meantime, allow me to nitpick the code you posted:
(The buy Verb)        //doing "comments" this way is bad form and won't compile anyway.
(Click Proc) // Use double slashes like this.
(What makes the list)

//they can be on their own line if you want

mob/verb
MakeList() //why is this a verb? initializing an interface should be handled in procs
set hidden=1
if(src.client)
var/list/A=list() //what's the point of this list? from the code it appears to be unused
var/row= 1, col=0, max_col=3
for(var/V in typesof(/obj/passive)) //instead of testing for F.name, instead you could do
var/obj/passive/F = new V //for(var/V in typesof(/obj/passive) - /obj/passive)


Also, this line makes no sense at all:

if(findtext("[F.name]",,1,0) in A) break


Remember, the "in" operator returns TRUE if the left hand value is found in the right hand list. The findtext() proc returns the first position of the "needle" (the second argument) if it is found in the "haystack" (the first argument". If not found, it returns 0. So for example, this:

findtext("Searching this text", "ching")


...will return the number 5. That's because "ching" is first found starting at the 5th character in the original string.

So, the way you have written it, you're searching the string F.name for the value NULL. This always returns 1, because you're searching for an empty string, "" (different from searching for the space character, " ") Then, you are asking if that value, 1, appears in the list A, which is a list of /obj/passive's. Therefore, this line will always evaluate to false.
So magic sofa very very late to this. Nearly a month, after figuring it out I stopped logging into the forms. Now.

These weren't apart of my code at all just played to separate my code blocks so yall could tell the different of each function

(The buy Verb) //doing "comments" this way is bad form and won't compile anyway.
(Click Proc) // Use double slashes like this.
(What makes the list)

But honestly I should of just broke the code blocks into 3 different code blocks.

The reason for if(findtext("[F.name]",,1,0) in A) break is to search for the name of the object that already exists in the list. I tried it without it and even though it generated my list it also generated multiple of the same thing. This however, may it be runtime error or w.e stopped it from generating more then just one.

This is used. var/list/A=list() //what's the point of this list? from the code it appears to be unused
Ill show where buddy.
if(findtext("[F.name]",,1,0) in A) break
A+=F
On why they are verbs. Prototyping is the answer. This is bad practice for code and I am aware but using verb allows me to be usr heavy if need be for the prototyping Q.Q don't yell at me plox.

But for the new code this is what I did.

mob/verb
MakeList()
set hidden=1
if(src.client)
src.A=new
var/row= 1, col=0, max_col=3
for(var/V in typesof(/obj/feats))
var/obj/feats/Martial/F = new V

if(findtext("[F.name]",,1,0) in A) break
A+=F
col ++
if(col>max_col)
row ++
col=1
src<<output(F,"grid:[col],[row]")

The above code is basically the same from my original entry.
client
Click(A,B,C)
if(C=="Passive.grid")
for(var/obj/feats/D in usr.Buying)
if(D==A)
usr.Buy(D)
..()
mob
var/tmp/list/Buying //The temp list to be used as reference since garbage collection

The var being added is one of the main differences. It also checks the players list and make sure it matches the item that was pressed.
mob
verb
Buy(var/obj/feats/A)
set hidden=1
var/Buy=input("Do you want to buy this feat? [A.name]:[A.desc]:[A.FPCost]") in list("Yes","No")
switch(Buy)
if("Yes")
if(usr.Featp>A.FPCost)
usr.contents+=A
usr.Featp-=A.FPCost

else
usr<<"You do not have enough points to buy this!"