ID:178462
 
This has been giving me so much trouble. I want a vebr that will let you select from a list of objects (which already works) and creates that object depending on the objects difficulty var. Unfortuneately, the list has to be limited to objects that have a certain difficulty var compared to a skill var on the client. Here's the code. I think you can tell what I want, the problem is in bold.

Wood
icon = 'Wood.dmi'
var
Quality = 0
verb
Get()
set src in oview(1)
Move(usr)
Examine()
set src in view(3)
usr << "This woood's quality is [src.Quality]."
Craft(C in usr.Woodcrafts)
if(usr.Woodworking + rand(0,100) >= C.difficulty)
new C (usr)
usr << "You made a [C]!"
else
usr << "You failed to make a [C]."
del(src)
FishingPole
icon = 'Fishing Rod.dmi'
var
difficulty = 75

The problem is, C.difficulty is an undefined var. How can I set this up so it works? If it's not clear how I want it to work, I'll clarify for you.
Garthor wrote:
Craft(C in usr.Woodcrafts)
if(usr.Woodworking + rand(0,100) >= C.difficulty)
new C (usr)
usr << "You made a [C]!"
else
usr << "You failed to make a [C]."
del(src)
FishingPole
icon = 'Fishing Rod.dmi'
var
difficulty = 75

The problem is, C.difficulty is an undefined var. How can I set this up so it works? If it's not clear how I want it to work, I'll clarify for you.

Basically the problem stems from trying to use an object's vars before the object even exists. In theory what you're trying to do sounds fine because the vars you want describe all objects of their type, and you don't really need the difficulty var from a specific fishing pole--just from the type.

Your quickest way to get around this would be to set up some kind of associative list, like this:
mob
Woodcrafts = list( /obj/Wood/FishingPole=75,
/obj/Wood/UselessTrinket=20)

However, if you want to access other vars, that quickly becomes difficult.
What I would recommend instead may sound a little more bizarre: You should instantiate (create) one object of each type you want to examine, and store each object in a global cache of some kind.
var/list/_objcache=list()

proc/GetObjFromCache(objtype)
var/O=_objcache[objtype]
if(!O)
O=new objtype() // this obj has loc=null
_objcache[objtype]=O
return O

Now, you can make your list a list of types, like /obj/Wood/FishingPole and so on--or just use typesof(), which is quicker:
  ...
for(var/C in typesof(/obj/Wood))
var/obj/Wood/O = GetObjFromCache(C)
if(usr.Woodworking + rand(0,100) >= O.difficulty)
O=new C(usr)
usr << "You made \a [O]!"
else
usr << "You failed to make \a [O]."
del(src)

Well, that loop is a little funky but otherwise that should put you on the right track. The idea is that instead of creating a list of objs you'll never use and then delete them again, you have one obj of each type that you keep on hand as a guide; you can access its vars as needed, and then forget about it.

The beauty of this cache system is that you can clear the cache as often as you want with _objcache.Cut(), which will delete the objs from the cache; they can be created again when needed.

Lummox JR
In response to Lummox JR (#1)
mob
> Woodcrafts = list( /obj/Wood/FishingPole=75,
> /obj/Wood/UselessTrinket=20)

I decided to go with this. Instead of assigning the difficulty var to the object, I'll just put it in with the list. The object will always be created, and a proc will be run so that if the object's quality is less than 0, it's destroyed. The one question I have, is how to access the numbers in the list.

            Craft(C in usr.Woodcrafts)
new C (usr, Quality = usr.Woodworking + rand(0,100) - <b>usr.Woodcrafts/C</b>)
usr << "You made /a [C]!"
del(src)


I need to know what you put in the part that's bold in order to subtract the value I assigned in the list.
In response to Garthor (#2)
Garthor wrote:
mob
> > Woodcrafts = list( /obj/Wood/FishingPole=75,
> > /obj/Wood/UselessTrinket=20)

I decided to go with this. Instead of assigning the difficulty var to the object, I'll just put it in with the list. The object will always be created, and a proc will be run so that if the object's quality is less than 0, it's destroyed. The one question I have, is how to access the numbers in the list.

Craft(C in usr.Woodcrafts)
var/obj/O = new C (usr, Quality = usr.Woodworking + rand(0,100) - usr.Woodcrafts[C])
// if the quality<=0, O is destroyed in New() with del(src)
if(O) usr << "You made \a [O]!"
del(src)

I've left that out of the <DM> tags so you can see the parts I highlighted. Saying "You made a [C]" won't work because it will say "You made a /obj/Wood/FishingPole" instead of the object's name. For accessing the numbers in an associative list, just use C as your index.

BTW, this list scheme won't work in an older version of BYOND. Associative lists using type paths were buggy until about 324 or 325, so you should make sure you have a new version before compiling.

Lummox JR