ID:1180701
 
Keywords: skills, tech, techniques
(See the best response by Fushimi.)

Problem description: How do I go about creating a skill method that would apply to all skills?

//I was thinking along the lines of
proc/Skills(var/Lev, var/skillPow/dmg, var/cooldown)

//OR
Skills
var/cooldown
var/pow
var/lev

Phantom_Flame
cooldown =30
lev=1
pow = 300


If the techniques all use the same variables, then datums (2nd method) would be the way to go.

Also, if the techniques are all used in the same way, such as firing a spell, then my Modular Spells demo may be of some use to you.
In response to Danny Roe
I see where you're tryna get at but the thing is I don't want to use so many variables naw mean? You know how every player has distinct health variable, well I want it to be like that.

For example lets say I have the skills Phantom_Flame, Heavy_storm, Thunder, Final_Blow, and Revive. I want them to have a cooldown variable called "cooldown." Another variable called "pow" which indicates the skill's damage, and finally "lev" which indicates the skill's rank.

i.e.
Thunder.pow=500+usr.pow
sleep(Thunder.cooldown-(Thunder.lev*10))

Final_Blow.pow=1500+usr.pow
sleep(Final_Blow.cooldown-(Final_Blow.lev*10))

for(var/mob/player/ M in oview(1))
if(M.ko)
M.ko=0
M.wounds=-50
sleep(Revive.cooldown-(Revive.lev*10))


~Regards~
Best response
Deffinitively handlid Techniques or Skills with datums seems to be the most efficient and flexible approach;

Skill
parent_type = /obj
var
Power
Cooldown
cooling_down = FALSE
Level


What we do here is create a new Skill obj, as defined by parent_type, and assign it three default and non-initialized variables, with the exception of cooling_down, which is a boolean (Can only be TRUE[1] or FALSE[0]).
All objects defined under this new "class" will share those variables (as I assume you already know this), as will do with the procs you define under this one.

Skill
proc
Use(mob/mob)
IsUsable(mob/mob)
Perform(mob/mob)
if(!cooling_down && IsUsable(mob))
Use(mob)
Cooldown()
else mob << "Skill cannot be used at the time being."
Cooldown()
cooling_down = TRUE
spawn(Cooldown) cooling_down = FALSE


What we do her now, is define four new procedures that will be also shared by all sub-classes, which goes as follos:

Use(mob/mob)
This procedure is meant to be overwritten and to be different for each skill (Anyhow you can define a preset action if it is needed), this proc is called by the Perform() proc, and is the atual effect of our technique

IsUsable(mob/mob)
This procedure is meant to be overwritten with special behavior to determine wether or not a technique can be used.
For example, if we didn't use Sunny Day before, we cannot use Solar Beam.


Cooldown()
Simply turns the boolean cooling_down on (TRUE or 1) and, after spawning the amount of ticks set in the Cooldown variable, and then turns it back off (FALSE or 0)

Perform(mob/mob)
This procedure initially checks if the skill is cooling down with a conventional if conditional, if it is false then the proc calls Use() and Cooldown() by the stated order, otherwise it throws an output.

This can be extended with as much variables as you need, you don't really need more procs than that, some useful one would be to handle drainds.

EDIT: Forgot to add some actual examples:

Skill/Sunny_Day
Cooldown = 1200 //2 Minutes
//Since this won't do any damage at all, we do not need to even initialize the Power variable.
Level = 1

Use(mob/mob)
mob.current_effects["SunnyDay"] = TRUE //Assuming we have a list defined under mob with the name current_effects, this won't compile for you as is, but is a good example.

Skill/SolarBeam
Cooldown = 2400
Power = 120
Level = 56
IsUsable(mob/mob)
if(mob.current_effects["SunnyDay"]) return 1
else return 0

Use(mob/mob)
mob.current_effects["SunnyDay"] = FALSE
var/mob/_target = locate() in hearers() //Selects a random mob from hearers, which retrieves a list of mobs within view
if(_target)_target.HP -= (2*(Power + Level)) - (Power-Level+1)
hearers() << "[mob] casts [src]"
In response to Fushimi
I really like this thank you very much. Anyways though, the function of Level only lowers the cooldown and increase the power. The way Power is calculate, it's going to be a fixed value plus the user's power.

i.e.
Skill/SolarBeam
Cooldown = 2400-Solarbeam.level*10
Power = 120+Solarbeam.level*10+usr.power
Level = 1// the level can be further upgraded by the user
Of course you can calculate things as you like, The calculations I did in those fomulas are pretty much radom operations I did on the fly, haha.

Also remember you cannot assing those values to Power and Cooldown on compile time that way, just in-case.
In response to Fushimi
Oh okay you've been a great help thank you :) do you mind If come to you when I encounter future problems?
Of course I wouldn't mind.
My apologies but how do you call those skills and how do I go about adding the icons?

src.Perform(powerBlast)

Technique
powerBlast
Cooldown= 300
Damage = 400
Rank=1
name="Power Blast"
icon='powerBlast.dmi'

Use(mob/mob)
var/mob/_target = locate() in hearers() //Selects a random mob from hearers, which retrieves a list of mobs within view
if(_target)_target.hp -= (Damage+Rank*10)+usr.pow+rand(-1,1)
hearers() << "[mob] casts [src]"


~Regards~
You are using usr.pow where you meant to use mob.pow.
To use these techniques overwrite the Click() proc.
Technique
Click()
..()
Perform(usr)


Then in order to have them accessible to a mob, you need to give them the actual object, and display it.
proc/give_skill(mob/mob, path)
if(mob && ispath(path))
return new path(mob)
return 0
mob/Stat()
statpanel("Techniques")
for(var/Technique/T in contents)
stat(T)
In response to Fushimi
Thanks so much :) can I get your email if that's possible?