open-dm / api

A Laravel-based API for managing all things D&D
MIT License
3 stars 0 forks source link

Monster skills #5

Closed G-Bro closed 4 years ago

G-Bro commented 4 years ago

The skills are:

Strength

Dexterity

Intelligence

Wisdom

Charisma

For monsters the skill bonus is: relevant ability modifier +skill bonus

As an example: Orcs have Charisma of 10 (+0) and an intimidation skill of +2 for a total intimidation score of +2 Orc war chiefs have Charisma of 16 (+3) and an intimidation skill of +5 for a total intimidation score of +8

How best to handle this relation? The values are almost computed, but also not.

I think we need a skills table

id name base_ability_id
int varchar int

And a monster_skill pivot table

monster_id skill_id bonus
int int int

if no join to skill then skill = base_ability modifier?

G-Bro commented 4 years ago

@DanEvans485 @Newobc can I get your thoughts on this? In summary the logic for calculating these would be something like...

function getAthleticsScoreAttribute() {
    $score = $this->strength_modifier;

    $skill = $this->skills()->where('name', '=', 'athletics')->first();
    if ($skill) {
        $score += $skill->pivot('bonus');
    }
}

But thats fairly nasty and I would have to do it 18 times, once per skill. Either of you got any nicer ideas of how to handle this?

ghost commented 4 years ago

You could easily abstract the:

$skill = $this->skills()->where('name', '=', 'athletics')->first();

if ($skill) {
    $score += $skill->pivot('bonus');
}

to a method that accepts the skill code/name.

I don't really see an issue with duplicating it however, as there are a finite number of skills that a Monster can have right?

If you absolutely insisted on no writing it over and over, you could use __get to dynamically figure out the property from a lookup table and the property name, but it would be hard to test and not worth it imo.

G-Bro commented 4 years ago

I'm not that bothered about duplicating it, its more that I don't like its half computed, half from the database.

value = other value + (if in database then take value from database else 0)

that just seems ugly to me, but I think its also the most elegant solution as opposed to putting it all in the database