ID:141253
 
Code: Skill Panel Problems
    statpanel("Inventory")
stat("",contents)
..()
statpanel("Skills")
if(statpanel("Skills"))
stat("[src]'s Skills")
for(var/Skill/S in contents)
stat("",S)


Problem description: Well, the problem is, i have a coded in a Skill Tree, and i want the Skills to show up in the Skills panel, and it shows up there, but it also shows up in the Inventory Panel, and i don't want that. Any ideas how to fix this? *If i need to post any other code, please tell me to do so.

Some stuff about proper usage that are somewhat off in your code:

  •         statpanel("Inventory")
    stat("",contents)
    ..()

    I hope you do realize this will be your "problem" as it just displays everything inside contents, which includes the Skills in it.
    This can be condensed to just statpanel("Inventory",src.contents), removing the stat() call.
    Also, BTW, everywhere you're using the empty string here (""), it is pretty redundant. More importantly, for future work, don't use it too often like some people tend to, it isn't a global value indicating 'empty' or 'nothing', and it can even cause problems if you're using it where strings aren't supported/expected. null is the 'value of nothing', and will be implicitly assigned whenever you just put 'nothing' anyway, so you don't have to always even write it out manually.
    For example:
    var/MyVar
    //is the same as
    var/MyVar = null
    stat(,contents)
    //is the same as
    stat(null,contents)

    Lastly - generally, ..() shouldn't be called in the middle of the proc when you don't have a specific reason to do that, so if you don't, put it in the beginning or end depending on what is preferred. When ..() actually calls another Stat() override/parent, this can easily interfere if done in the middle.

  • >       statpanel("Skills")
    > if(statpanel("Skills"))

    This code is doing double work - calling statpanel() twice. The only difference is that the first time you're not using the return value (essentially ignoring it), but the proc is still run twice. You can just remove the first one.

  • >               stat("",S)
    

    Nothing important wrong here, but like I said above, this can be just stat(,S) or in this case even just stat(S).


but it also shows up in the Inventory Panel, and i don't want that. Any ideas how to fix this?

As said above, skills show up in the Inventory panel because it displays everything in contents, and skills are in contents. The solution should be pretty obvious:
A) Don't put Skills inside contents. Put them in a separate list - e.g., src.skills, then just display that list. Then, in total you've got 2 stapanel() calls, each displaying a different list.
B) When you're displaying Inventory, just like what you're doing with Skills objects now, specifically use a for() loop to display non-Skill objs. This will look a little differently depending on your game and the wanted result. For example, if you've got a specific subtype for items in your game (recommended anyway), like /obj/item, you may choose to simply only ever display those, with a simple for(var/obj/item/Item in src.contents) stat(Item) line.

The first (A) method is quite preferred, because of 2 advantages:
1) It leads into a more efficient Stat(). This is, after all, is a proc that gets run for every player every few ticks. So having it run faster (even if not by big amounts) is a nice plus.
2) Storing skill objects in a normal list instead of contents allows a good, resource-efficient design change: it allows you to re-use objects between different players (if a reader is familiar with this, this is rather the same principle as reusing screen objects used with multiple players). Making every player get his own, unique, new skill objects is a waste, as most often these objects are identical (and sometimes even if they aren't you can easily make them). For example, let's say you have a generic Attack skill, which is the same with every player. Instead of creating a new Attack obj per player, you can create 1 global one, and display that one for all the players. So when, with the less efficient method, you'd have 20 objs created with 20 players online, if you re-use objs you'll have just 1, even if you have 100 players online. This saves memory, processing time (required to create new objs), and objs, of course (which in turn saves obj slots, although the limit is much higher nowadays).
In response to Kaioken
A) Don't put Skills inside contents. Put them in a separate list - e.g., src.skills, then just display that list. Then, in total you've got 2 stapanel() calls, each displaying a different list.

I'm new to BYOND so i'm just learning how to code, and how do i make a list to let me Skills show up in that certain list?
In response to Mitzzz
If you're new and you don't know how to work with lists, learn about them first:
DM Ref (also see 'see also' ;P) http://www.byond.com/docs/ref/info.html#/list
DM Guide http://www.byond.com/docs/guide/chap10.html

What you want here is to declare a variable on mob [combatants] and set it to a list. Then whenever you used to add a newly-learned skill to a player's contents, you just add it to your own list instead.
In response to Kaioken
    statpanel("Inventory",src.contents)
if(statpanel("Skills"))
stat("[src]'s Skills")
for(var/Skill/L in world.contents)
stat(,L)

mob
var/list/L // list reference
L = world.contents // assign to existing list
L = new/list() // make a new list
L = new() // make a new list (implicit type)


Compile errors: BS.dm:604:error:world.contents:expected a constant expression

I'm not really understanding on how to make the Skills appear in a separate list.
In response to Mitzzz
No, looking strictly at examples and directly copying code from them will definitely not help. You can't copy random code into your project and expect it to work for what you wanted. Examples are given so they help you understand the principles, which you're supposed to then used to make your own code applicable for the situation. Read the pages I've linked to in my previous post.