ID:2289151
 
(See the best response by Unwanted4Murder.)
I want to avoid having a bunch of messy/unnecessary code and of course save myself the time where I can. I'm newish still and this is a fairly ambitious game for a DMer of my caliber but I'm determined.

So I have a LOT of different classes in the works. I'm just gonna give an example of my class plan.

Scout - at level 5 you choose between Archer and Gunman. You choose Archer. Then at level 10, you have another 2 subclasses to choose from - Longrange archer or Shortrange archer. Same goes for the gunner tree obviously.

With Scout being one of the base classes, I've got 4 more base classes I definitely want to add. Hoping to go even more, maybe double that. So all these base classes are gonna have to have their own respective attack procs I'm guessing, since they wield different weapons, use different icon states, maybe some different macros, and I want all their stat progressions to be different too, so pretty much separate everything for each base class, is the only way I can see this happening. Or is there a much easier way that I'm missing. ? I'm even wondering if I should make separate base icons for each base class just to possibly save myself some confusion down the road. Or would it be better to leave everything same same, code it all under for instance one attack proc and just have a ton of conditions in the proc?
Best response
Easiest way would probably be to make each base class its own type of mob and then children of that base mob. That way they could all inherit the parts of procedures you want them to, but still function differently. So from your example, it would be something like...

mob/Scout
var tmp/attacking
proc/Attack()
// this is where attack stuff that is generic to all Scouts goes
if(attacking) return // stop the proc if attacking is true
else attacking = TRUE // otherwise set it to true

mob/Scout/Archer // the Archer is a child of mob/Scout, so it will inherit its base procedures and variables
Attack()
..() // this calls the parent proc
// then you would put the stuff specific to Archers here

mob/Scout/Gunman // again, the Gunman is a child of mob/Scout so it inherits its variables and procedures -- but nothing defined under mob/Scout/Archer will be inherited here
Attack()
..() // call the parent proc
// stuff that is specific to attacking with a Gunman would go here
To add onto Unwanted4Murder's response, what you're needing is a ubiquitous, fundamental utility of object oriented programming: polymorphism and inheritance. It's useful to know what they're called in case you want to do more research on them, but they're pretty simple topics.

I would take Unwanted's example one step further by using a universal base class which all classes stem from. So the type tree might look something like /mob/Class/Scout/Spy. Class would be where you define all of the variables and procs that are universal to all child class types.

While I always try to steer newer programmers away from using a ton of if-else-if blocks, the most important thing for a new programmer to do is write code that's easily readable from a glance. My advice is to write code that's self-commented, without the need for // or /**/.
Do you want your classes to be flexible? If so, I would advise saving their attributes as data and loading that up when the world loads.