X-Git-Url: https://plomlompom.com/repos/?a=blobdiff_plain;f=src%2Fserver%2Fai.c;h=b8850a8155c6772b6d7e0ae279430e88b432fe31;hb=eff209c8fe5a74ba54efae4fbc58875dc6fabbf1;hp=0fd43ad2abffc6dc17189d699de3c0904b4bb551;hpb=3cb6ed6453b22eba62f7c9186790813b0abebeb9;p=plomrogue diff --git a/src/server/ai.c b/src/server/ai.c index 0fd43ad..b8850a8 100644 --- a/src/server/ai.c +++ b/src/server/ai.c @@ -2,13 +2,13 @@ #include "ai.h" #include /* NULL */ -#include /* uint8_t, uint16_t, uint32_t, UINT16_MAX */ +#include /* uint8_t, uint16_t, uint32_t, int16_t, UINT16_MAX */ #include /* free() */ #include "../common/try_malloc.h" /* try_malloc() */ #include "hardcoded_strings.h" /* s */ #include "thing_actions.h" /* get_thing_action_id_by_name() */ -#include "things.h" /* struct Thing */ -#include "world.h" /* global world */ +#include "things.h" /* Thing, ThingType */ +#include "world.h" /* world */ @@ -39,6 +39,15 @@ static void dijkstra_map(uint16_t * score_map, uint16_t max_score); */ static char get_dir_to_nearest_enemy(struct Thing * thing_origin); +/* Return 1 if any animate thing not "t_origin" is in its FOV, else 0. */ +static uint8_t seeing_enemies(struct Thing * t_origin); + +/* Return slot ID of strongest consumable in "t_owner"'s inventory, else -1. */ +static int16_t get_inventory_slot_to_consume(struct Thing * t_owner); + +/* Return 1 if "t_standing" is standing on a consumable, else 0. */ +static uint8_t standing_on_consumable(struct Thing * t_standing); + static void get_neighbor_scores(uint16_t * score_map, uint16_t pos_i, @@ -173,13 +182,85 @@ static char get_dir_to_nearest_enemy(struct Thing * t_origin) +static uint8_t seeing_enemies(struct Thing * t_origin) +{ + struct Thing * t = world.things; + for (; t != NULL; t = t->next) + { + if ( t->lifepoints + && t != t_origin + && 'v' == t_origin->fov_map[t->pos.y * world.map.length + t->pos.x]) + { + return 1; + } + } + return 0; +} + + + +static int16_t get_inventory_slot_to_consume(struct Thing * t_owner) +{ + uint8_t compare_consumability = 0; + int16_t selection = -1; + struct Thing * t = t_owner->owns;; + uint8_t i; + for (i = 0; t != NULL; t = t->next, i++) + { + struct ThingType * tt = get_thing_type(t->type); + if (tt->consumable > compare_consumability) + { + compare_consumability = tt->consumable; + selection = i; + } + } + return selection; +} + + + +static uint8_t standing_on_consumable(struct Thing * t_standing) +{ + struct Thing * t = world.things; + for (; t != NULL; t = t->next) + { + if (t->pos.y == t_standing->pos.y && t->pos.x && t_standing->pos.x) + { + struct ThingType * tt = get_thing_type(t->type); + if (tt->consumable) + { + return 1; + } + } + } + return 0; +} + + + extern void ai(struct Thing * t) { t->command = get_thing_action_id_by_name(s[S_CMD_WAIT]); - char sel = t->fov_map ? get_dir_to_nearest_enemy(t) : 0;/* t->fov_map may */ - if (0 != sel) /* be absent due */ - { /* to god command.*/ - t->command = get_thing_action_id_by_name(s[S_CMD_MOVE]); - t->arg = sel; + if (seeing_enemies(t)) + { + char sel = t->fov_map ? get_dir_to_nearest_enemy(t) : 0; + if (0 != sel) + { + t->command = get_thing_action_id_by_name(s[S_CMD_MOVE]); + t->arg = sel; + } + } + else + { + int16_t sel = get_inventory_slot_to_consume(t); + if (-1 != sel) + { + t->command = get_thing_action_id_by_name(s[S_CMD_USE]); + t->arg = (uint8_t) sel; + } + else if (standing_on_consumable(t)) + { + t->command = get_thing_action_id_by_name(s[S_CMD_PICKUP]); + } } }