ID:882031
 
In my game, many AI will utilize the same attacks (with little changes to them).

I'm wondering how it would be best to define these different kinds of attacks. If I should be defining a ton of procs under my base Enemy mob, or be utilizing datums to create custom attacks for each person...

I could do this
mob/enemy
proc/strike(power,critrate)

mob/enemy/bear
while(src)
//do whatever
strike(strength,1.1)


or I could hold each proc call in a list, being associative, since I want my attacks to be chosen by probability if there are enemies in view (the thing is, sometimes, I'll want to have my enemy be making the smarter-decision attack instead of one chosen at random)

mob/enemy
list/attacks = list(70 = strike(strength,4.4), 30 = strike(strength, 1.1))


I'm also thinking I could maybe use datums to solve this situation?...just an idea...

_attack
var
name
base_damage
max_damage
crit_multiplier
crit_probability


So basically, I need some help with the design of this feature. I want my enemy to select an attack either by

1) Randomness or
2) Intelligence

Some enemies will be utilizing the same attacks, such as a basic "strike" attack that will hit mobs in view. May I get some advice on how I should be going about this? Thanks!

tl;dr features:
-Random selected attacks
-Attacks selected by analyzing the situation
-Some enemies will utilize the same attacks
-Code needs to be efficient and organized
It's very simple. Use a datum, like you mentioned, to handle the actual attack execution, and then you have to arbitrarily decide what is "intelligence."

"What *is* an intelligent attack?"

Do your characters have... 'types'? Like, Fire, Water, Ice?
Then you could simple check the enemy's 'type' and pick an attack with the counter-type attack.

Or if it's simply by distance, then calculate the distance from the enemy, and pick the attack that deals the most damage at that distance.

In response to Gooseheaded (#1)
So do you think this would be the best way to do things:

_attack
var
name
base_damage
max_damage
crit_multiplier
crit_probability

mob/enemy
var/_attack
smash
project
defend


And say all enemies will utilize the same datums, I can just define the datums like I've done above (under the general "enemy" mob), and upon the creation of the enemy, use new to manually place in the values like so

mob/enemy/seal
New()
new smash("Smash",100,150,1.1,8)


or do you think there would be a better way to go about doing this?

Using datums can be helpful if there's are multiple procs or pieces of information associated with an attack. For example, if this is your attack datum you might as well use procs:

attack
proc
use(mob/m)

smash
use(mob/m)
m.damage(10)

// you might as well just do this:
mob
proc
smash(mob/m)
m.damage(10)

But if you have multiple procs associated with the attack (ex: one to check if you can use it, one to select a target, one to tell AI how to use it, and one to perform its effect) and multiple properties that may vary (damage, cooldown, etc.) it'd be easier to store all of that in a datum.

Using objects also lets you make use of inheritance. You can do something like this:

attack
smash
var
damage = 10

use(mob/m)
m.damage(damage)
m.dazed(5)

weak_smash
damage = 5

strong_smash
damage = 20

That way the weak_smash and strong_smash abilities have the same behavior and you just have to change their vars to define what's different about them.

For creating AI that uses abilities it really depends on how different the abilities are. If every attack is just something that deals a certain amount of damage to a single target you can create a proc on the mob that figures out what ability it should use. If the abilities are very different you can give each attack object a proc that'll determine how beneficial it'd be to use that ability in the current situation. For example:


attack
proc
ai_value()

punch
ai_value()
return 5

kick
ai_value()
return 10

revive_ally
ai_value()
if(there is a dead ally nearby)
return 10
else
return 0

To decide what action to perform it calls ai_value() for each ability it has. If a mob only has punch and kick, since kick's value is twice punch's value the mob will be twice as likely to kick than punch (it'll have a 66.67% chance to kick and a 33.33% chance to punch). The revive ability only has value if there's a nearby mob that can be revived, otherwise its value is zero and it won't be used.
In response to Forum_account (#3)
Thanks for that lengthy reply!