ID:1860955
 
(See the best response by Nadrew.)
Ello. I was just wondering the the difference between absolute paths and relative paths in regards to the / path operator. Here's an example the F1 Help macro gives:
mob
var
corpse = /obj/corpse
Die()
new corpse(src.loc) //create the corpse here
del src

spider
corpse = /obj/corpse/spider
frog
corpse = /obj/corpse/frog


What would be different if in the code, it were "corpse = obj/corpse" instead of "corpse = /obj/corpse"?

Reason I ask this is because I have an istype error where it returns if the src isn't istype(/obj/Perk). Even when I placed a / path operator before the obj where my big obj/Perk object tree is, it still returned where
if(!istype(P, /obj/Perk)) return //P is true though, so no need to pay attention to that as far as I know


The difference is one is a type-path, and the other is really nothing without the 'new' keyword.

The problem you're having is that istype() takes an object reference as its first argument, not a string. The ispath() proc is what you're after.

var/somevar = /obj/sometype

if(istype(somevar,/obj/sometype)) // Incorrect

if(ispath(somevar,/obj/sometype)) // Correct


But in cases when you're setting a variable to a type-path, you rarely need to actually check it directly, the usage is usually something along the lines of what the reference entry shows where you're creating something of that type.

var/obj/sometype/somevar = new()

if(istype(somevar,/obj/sometype)) // true
if(istype(somevar,/obj/someothertype)) // false


You'd really have to show what you're doing with your 'P' variable to know what the issue is you're having. Is it an object or a type?
P is an var/object. Here's what I'm doing with P.

                else
if(isnull(PerkDatabase))
src<<"Perk Database file was not found!"
return
if(!PerkDatabase.len)
src<<"There are currently no perks saved in the Perk Database!"
return
var/obj/Perk/P=input("Which perk will you give [src]?","Database") in PerkDatabase
if(!P)
usr << "Error: Line 86: !P"
return
if(!istype(P,/obj/Perk))
usr << "Error: Line 90 Perks-Skills: !istype(P,/obj/Perk)"
return
var/obj/Perk/O=copyatom(P)
M.contents+=O
Is the PerkDatabase list a list of actual /obj/Perk objects? If the istype() check is failing it's probably because the item in the list isn't a /obj/Perk. You can add [P.type] to the output and it'll show some more info.

Also, for those messages, you can use the "__LINE__" macro to show the line number in the file and "__FILE__" to show the code file.

src << "Error in [__FILE__] on line [__LINE__], universe imploded!"
Ah I never knew those macros existed. Thanks for that tidbit.

The PerkDatabase list is a list of /obj/Perk objects:
proc/Perks2Database()
PerkDatabase += typesof(/obj/Perk)
DudeSaveTheDatabase()

The name of that proc refers to the perk objs names and desc's that I coded in that I want saved in the runtime-accessible database (PerkDatabase).

Not sure what you mean by adding [P.type] though.
You're not actually creating a list of objects, but a list of type-paths. typesof() doesn't return objects, just paths.

for(var/P in typesof(/obj/Perk)-/obj/Perk)
PerkDatabase += new P
DudeSaveTheDatabase()
I changed my Perk2Database() proc to what you just provided, but it doesn't look like my list of objects (which is really a list of type-paths) gets saved into the PerkDatabase list.

The error happens here:
                    var/obj/Perk/P=input("Which perk will you give [src]?","Database") in PerkDatabase
if(!P)
usr << "Error: File [__FILE__], Line: [__LINE__]"
return
A list of objects and a list of type-paths are vastly different things, you can't interchange their usage. I'm not even sure why you're saving the data if you're just generating it from a typesof() call, you can literally just generate that list once when you start the world and use it over and over.
var/list/PerkDatabase

proc/GeneratePerks()
PerkDatabase = list()
for(var/P in typesof(/obj/Perk)-/obj/Perk)
PerkDatabase += new P

mob/verb/GetPerk()
var/obj/Perk/P = input("Blah blah blah","Blah")in PerkDatabase
if(!P)
usr << "Well, that didn't work."
return
usr.perks += new P.type


You COULD do this with a list of types, but you said above you wanted to access the variables belonging to the perk, so it's better to do it with a list of objects.

// [... some of the stuff above here]
usr << "You picked [P.name] ([P.description])"


You don't really need the usage of your copyatom() proc unless you're altering the variables of the perks in PerkDatabase from their initial values set in the code, just creating a new object of that type will handle setting them to those values otherwise.
The PerksDatabase list is a file admins will be able to draw from to give players perks. It contains (or is supposed to contain) a long list of perks with their names and what the user is able to do with them (RP game). The perks aren't accessible by admins if I don't add them into the PerkDatabase.

But okay, the problem is much bigger than I thought. I need to have obj's, and I don't. Here's a picture of what my "object" tree looks like.. I (wrongfully) thought they were actual objs:

These aren't objects?
In response to Oleic
It's good to learn the proper language.

No, those aren't objects, they're object prototypes. Like recipes in cooking.

Objects are instances of those prototypes. Like the food itself. They are created using the "new" operator.

Furthermore, in DM, there's obj, which describes objects that inherit from the /obj type. What you have there are type definitions for descendants of obj.
Those are prototypes, but you don't seem to quite understand the difference between a reference to an actual object or a type-path.

The type-path (/obj/Perk/...) is just the pointer to that object definition in the code, it doesn't actually exist as an object until it's created using 'new'. Type-paths on their own don't contain variables or anything of that nature.

Since you're adding/removing to the list, it's definitely worth saving, it's better to save a list of types than a list of objects, but both work. So you'd have something like this:

var/list/PerkDatabase

proc
SavePerkDatabase()
if(!PerkDatabase) return
var/savefile/perk_save = new("perks.sav")
perk_save["perks"] << PerkDatabase
LoadPerkDatabase()
var/savefile/perk_save = new("perks.sav")
if(perk_save["perks"]) perk_save["perks"] >> PerkDatabase
else PerkDatabase = list()

world
New()
..()
spawn(1) LoadPerkDatabase()


mob
admin/verb
GivePerk(mob/M as mob in world)
if(!M) return
var/obj/Perk/selected = input("Pick a perk")as null|anything in PerkDatabase
if(isnull(selected)) return
// ... Do your stuff here

super_admin/verb
AddPerk()
var/perk_type = input("Which perk do you want to add to the database?")as null|anything in typesof(/obj/Perk)-/obj/Perk
if(isnull(perk_type)) return
if(locate(perk_type) in PerkDatabase)
usr << "Already in the database."
return
PerkDatabase += new perk_type
usr << "Added."
SavePerkDatabase()


Written off the top of my head, you could probably keep a list of types (and save/load that) while generating a list of objects so you can access the variables, but it's not really needed. Since you're not altering any of the object variables, they'll be saved in their most simplistic form so it's not a major storage hit like saving modified objects.
In response to Kaiochao
Kaiochao wrote:
It's good to learn the proper language.

No, those aren't objects, they're object prototypes. Like recipes in cooking.

Objects are instances of those prototypes. Like the food itself. They are created using the "new" operator.

Furthermore, in DM, there's obj, which describes objects that inherit from the /obj type. What you have there are type definitions for descendants of obj.

._. Shit stressful. So there's not easy way out of making objects other than "obj/blahblah" for each of my type-paths?
In response to Kaiochao
@Nadrew Damn. Thanks for that. It's almost time for me to hit the sack, plus my girlfriend just came over B) So I'll definitely try your code when I wake up later today!
In response to Oleic
If you want to be a messy programmer, you can exploit the parent_type variable to shorten your type paths.
corpse
parent_type = /obj

spider
parent_type = /mob
corpse = /corpse/spider

// e.g.
var spider/charlotte = new (loc)
sleep 10
new charlotte.corpse (charlotte.loc)
del charlotte
In response to Kaiochao
@Kaiochao Well, I don't want to be a messy programmer. What do you suggest I do to make this work normally, or how would you do it?

@Nadrew I tried your GivePerk() code but it still didn't place a perk in my mob's contents. I suppose it's best to do this the more common way and rewrite these type-paths to be actual objects so they're more usable and editable after they're given to a player. Thanks for the work you've done so far in helping me.

So if I rewrite all these type-paths to be actual objects will I still have to individually put a Click() proc for each of them and give them an icon and icon_state? Or can I do that once in some parent object above them? Like as what's posted in my previous screenshot (Blacksmith having an icon for the specific kinds of blacksmiths under it).
I can't really help you if you don't know the basics of the language first. I suggest you go back and re-read the guide and tutorials.
In response to Nadrew
Nadrew wrote:
I can't really help you if you don't know the basics of the language first. I suggest you go back and re-read the guide and tutorials.

Lol I know the basics. Just not all of them perfectly. Even with the chapter's I've read fully and looked up through F1 in the environment, I still have trouble with things. Such as the Topic() proc for example. But anyway.. You can help me. I'm helpable. :| I just want to know how I can place a proc under a parent object that will be adopted by all its child objects if those child objects have their own name and icon var. Because writing 70 Click() procs that do the same thing seems a bit ridiculous to me.
Best response
obj
Perk
Click()
usr << "You activated [src.name]!"

PerkOne
name = "Perk One"

PerkTwo
name = "Perk Two"
Sorry for the late response, got busy with army stuff. I'll probably just end up doing exactly that, Nadrew. One last question: what if I wanted to make those PerkOne, PerkTwo, etc objects one step lower in that object tree; would it be one a type-path at that point? For example, if in your code you put NovicePerks a couple lines under that Click() proc, then another line under and indented you added the PerkOne, PerkTwo, etc objects?

The purpose of that question is to see if the PerkOne, PerkTwo, etc objects would be able to adopt some declared vars of the newly created 'NovicePerks'.
Page: 1 2