ID:2647955
 
I'm having an issue with a perk shop I made. Essentially, the perkss(which are objects) are stored in an archive object/savefile. When the player opens the shop, it outputs the contents on a grid. At that point, they click on something they want and it sets a tmp variable to a reference of that object and outputs anything needed to the shop interface(descriptions and such).

    Click()
if(src in perk_archive.contents)
var/p = ""
usr.databaseperk=src
for(var/req in src.prerequisites)
p += "[req]"
if(req != src.prerequisites[src.prerequisites.len])
p += ", "
if(p == "") p = "None"
winset(usr,"perk_shop.perk_reqs","text=\"[p]\"")
var/DESC = "<font color=white><small>Tier [src.tier] Perk<br>[src.description]</small>"
usr << browse("\ <body bgcolor=black><font color=white>[DESC]","window=perk_shop.perk_desc")


At this point, everything is working fine. The player then clicks the Purchase button and an alert asks if they're sure they want to purchase (insert name here). They hit purchase, and:

        switch(input("Are you sure you wish to buy [usr.databaseperk.name]?","Confirmation") in list("No","Yes"))
if("No")
return
if("Yes")
var/PR = locate(usr.databaseperk) in usr.contents
if(PR)
alert(usr,"You already have that perk.")
return
var/reqs = check_reqs(usr.databaseperk)
if(reqs != "Pass")
alert(usr,reqs)
return
else if(reqs == "Pass")
if(usr.databaseperk.RPPCost > 0 && usr.RPP >= usr.databaseperk.RPPCost)
usr.RPP -= usr.databaseperk.RPPCost
alert(usr, "You have purchased [usr.databaseperk] for [usr.databaseperk.RPPCost] RPP.")
Copy_Object(usr.databaseperk)



It first checks if they already have the perk. If they don't, it proceeds to check the reqs before copying the object to them. The check_reqs proc takes the referenced object's prerequisites(stored in a list) and compares it to what the user has. It returns "Pass" if they have everything.

mob
proc/check_reqs(obj/Perk/perk)

var/list/listed_requirements = perk.prerequisites.Copy()

for(var/obj/Perk/P in src)
if(P.name in listed_requirements)
listed_requirements -= P.name

if(listed_requirements.len)
var/text = "You don't meet the requirements for [perk] ( "
for(var/t in listed_requirements)
text += "[t])"
return text
return "Pass"





Assuming they both confirm their purchase and meet the requirements, it copies the object to them, excluding specific variables:

proc
Copy_Object(obj/O)
if(!O) return
var/obj/copy_o = new O.type (usr)
copy_o.name = O.name
var/list/denyvar = list("client","key","loc","x","y","z","type")
for(var/V in O.vars)
if(V in denyvar)
continue
else
copy_o.vars[V] = O.vars[V]
return



The problem seems to happen after saying "Yes" but before copying the object, as according to all reports I've gotten everything is normal until then - but all that happens during that time is checking if they already have that object, and checking the reqs. Neither of those two things influence their current choice(specifically, the databaseperk variable)

Often times a player will purchase a perk and be given a completely different one. I haven't personally experienced this, but the people I've spoken with who have had this happen(some of which are admins) tell me that up until they say "Yes" to purchasing, everything is correct - it tells them the name of the perk they want, etc. It's only after hitting "Yes" that it suddenly tells them they purchased something else. As an aside, while it's possible to click another object before confirming the purchase, all the reqs are checked at the time they press yes. Occasionally someone will obtain a perk they don't actually meet the reqs for, so I don't think that has anything to do with it.

I can't seem to find the cause for this. There seems to be no constant way to trigger it and I haven't been able to recreate it. Can anyone glean anything from my shop code or give any insight on why this would happen?
Jen Aside wrote:
It's only after hitting "Yes" that it suddenly tells them they purchased something else. As an aside, while it's possible to click another object before confirming the purchase, all the reqs are checked at the time they press yes.

This is your issue. If the usr is clicking another obj, it's databaseperk var is changed before he clicks Yes. Inputs and alerts suspends the code until an option is chosen. So he will get the last perk he clicked, not the one in the confirmation. You need to store that information elsewhere, before the input, and use it afterwards.

Regarding the requirements, I don't see anything that can explain the behavior you're describing.
NSBR wrote:
This is your issue. If the usr is clicking another obj, it's databaseperk var is changed before he clicks Yes. Inputs and alerts suspends the code until an option is chosen. So he will get the last perk he clicked, not the one in the confirmation. You need to store that information elsewhere, before the input, and use it afterwards.

Regarding the requirements, I don't see anything that can explain the behavior you're describing.

Ah, yeah - that makes sense. I fixed it(or at least have had no new reports all day) by "locking in" their choice to another tmp variable when hitting purchase, but I have yet to figure out how the requirements bug was happening.

Thanks!