mob
verb
FireBall()
usr.Do_FireBall_Stuff()
That is often a better example than most cases.
Many times people do the whole skill process via their verbs. Why do that, or even do an extremely long procedure, when you could use a datum and simplify everything? In this post, I will show you how to do a simple skill system using a datum.
Creating the datum
Here is the start, the simplest part. Create the datum.
skill
Simple as that. Now, let's do some defining. But wait; you need to plan out how you want things to work before you make them, to reduce changes later. In this case, we want a simple system that will activate and deactivate skills, and do a few checks in there too.
Making Variables
skill
var
using=FALSE
cooldown=0
default_cooldown=0
tmp/mob/owner
There we go. Now we can see if the skill is being used, and what it's cool down is, what it's default cool down is(we will set the cool down to this when they use the skill) and we can also see whose skill this is later.
Default Procedures
skill
var
using=FALSE
cooldown=0
default_cooldown=0
tmp/mob/owner
New(mob/_owner,_cooldown)
owner=_owner
default_cooldown=_cooldown
proc
Use(mob/target)
Activate(mob/target)
DeActivate(mob/target)
Using()
if(using)
return 1
return 0
Default_Cooldown()
return default_cooldown
Cooldown()
return cooldown
Start_CD(mob/_owner)
while(_owner&&_owner.loc&&cooldown)
--cooldown
sleep(1)
if(cooldown<0) cooldown=0
Ok, there is a lot here. So I will go step by step.
These are just default procedures, that each skill will define. Or, you can have a subclass of skills(For example, transformations) that define these procedures, then the skills under the transformations class will call those procedures.(Quick Note: If you do that, and also change the procedure in the subclass from transformations, you need to call ..() so it will do the previous definition.)
Using() will return 1 if the skill is being used. You can use this to see if the skill is being used, obviously. Cooldown() returns the current cool down of the skill. Default_Cooldown() returns the default cool down of the skill.
Start_CD() makes the cool down start going down. Call this after the skill is used.
Activate() is to be called before Use(). It does the checks, and Use() does the actions.
We also used New() in here, but I added arguments to it. I added mob/_owner and _cooldown. I used underscores so I could use a variable similar to the variables being assigned values to avoid confusion later down the road. mob/ requires the owner to only be a mob, to avoid errors.
Your First Skill
skill
var
using=FALSE
cooldown=0
default_cooldown=0
tmp/mob/owner
New(mob/_owner,_cooldown)
owner=_owner
default_cooldown=_cooldown
proc
Use(mob/target)
Activate(mob/target)
DeActivate(mob/target)
Using()
if(using)
return 1
return 0
Default_Cooldown()
return default_cooldown
Cooldown()
return cooldown
Start_CD(mob/_owner)
while(_owner&&_owner.loc&&cooldown)
--cooldown
sleep(1)
if(cooldown<0) cooldown=0
Transform
Activate(mob/target)
if(using) DeActivate(target)
//In here, just check for things that will make the user NOT be able to use the skill.
else Use(target)
Use(mob/target)
view(target)<<"[target] yells: Raaaaagh!"
sleep(15)
target.icon='Transformed_Icon.dmi'
view(target)<<"[target] transformed!"
using=TRUE
DeActivate(mob/target)
view(target)<<"[target] starts reverting..."
sleep(15)
target.icon = 'Normal_Icon.dmi'
view(target)<<"[target] reverted to his original form."
using=FALSE
cooldown=default_cooldown
Start_CD(target)
Alright. We defined a Transform subclass, and defined the Use(), Activate(), and DeActivate() procedures.
As said in the code, Activate() is used to check for limitations. In this example, it just checks if it is already being used, if so then DeActivate() it, preventing them from stacking. The Use() and DeActivate() procedures just do a simple process. It tells people around them a message, sleeps for a second and a half, then tells them another message, changes the icon, sets the using to FALSE, and (in the case of DeActivate()) sets and starts the cool down.
Now all we have to do is make the datum usable by people. This is quite easy. In the next example, I will be making a verb that uses the skill, and making the mob receive the verb upon login.
Making Your Skill Usable
skill
var
using=FALSE
cooldown=0
default_cooldown=0
tmp/mob/owner
New(mob/_owner,_cooldown)
owner=_owner
default_cooldown=_cooldown
proc
Use(mob/target)
Activate(mob/target)
DeActivate(mob/target)
Using()
if(using)
return 1
return 0
Default_Cooldown()
return default_cooldown
Cooldown()
return cooldown
Start_CD(mob/_owner)
while(_owner&&_owner.loc&&cooldown)
--cooldown
sleep(1)
if(cooldown<0) cooldown=0
Transform
Activate(mob/target)
if(using) DeActivate(target)
//In here, just check for things that will make the user NOT be able to use the skill.
else Use(target)
Use(mob/target)
view(target)<<"[target] yells: Raaaaagh!"
sleep(15)
target.icon='Transformed_Icon.dmi'
view(target)<<"[target] transformed!"
using=TRUE
DeActivate(mob/target)
view(target)<<"[target] starts reverting..."
sleep(15)
target.icon = 'Normal_Icon.dmi'
view(target)<<"[target] reverted to his original form."
using=FALSE
cooldown=default_cooldown
Start_CD(target)
mob
var
skill
Super_Saiyan
Saiyan/verb
Super_Saiyan()
usr.Super_Saiyan.Activate(usr)
Login()
. = ..()
src.Super_Saiyan=new/skill/Transform
src.verbs+=/mob/Saiyan/verb/Super_Saiyan
Here, we just gave the mob a variable named Super_Saiyan. You have to define it under skill/, or it won't call Activate() when you use the skill. Then I made a verb that calls the user's Super_Saiyan variable's Activate() procedure. I then gave the mob this verb upon login and made the mob's variable be assigned to a new skill datum. And that is all there is to it.
-----------------------------------------------
I hope you learned from this, any questions, comments, or concerns are welcome in the comments. The more helpful comments I get, the better the next article I can make next time! Also check out my topic in the forums if you have any suggestions for next week!
[Edit:]
Skill datums can be handy ways to keep your skills sorted out or portable so you can distribute them to other mob types. However, the old fashioned way of putting them directly on the player mob has advantages to simplicity. It depends on what you plan to do.