home · contact · privacy
Server: Internally, rename "map object" stuff to "thing" stuff.
authorChristian Heller <c.heller@plomlompom.de>
Fri, 20 Jun 2014 01:23:27 +0000 (03:23 +0200)
committerChristian Heller <c.heller@plomlompom.de>
Fri, 20 Jun 2014 01:23:27 +0000 (03:23 +0200)
25 files changed:
README
TODO
confserver/world
src/server/ai.c
src/server/ai.h
src/server/cleanup.c
src/server/cleanup.h
src/server/configfile.c
src/server/configfile.h
src/server/field_of_view.c
src/server/field_of_view.h
src/server/init.c
src/server/init.h
src/server/io.c
src/server/map.h
src/server/map_object_actions.c [deleted file]
src/server/map_object_actions.h [deleted file]
src/server/map_objects.c [deleted file]
src/server/map_objects.h [deleted file]
src/server/run.c
src/server/thing_actions.c [new file with mode: 0644]
src/server/thing_actions.h [new file with mode: 0644]
src/server/things.c [new file with mode: 0644]
src/server/things.h [new file with mode: 0644]
src/server/world.h

diff --git a/README b/README
index 5ec2f4ae7b059650e3b247ba10f3f7d7f37d4668..8b79cf28fda8dcc6fd898fb7894e46b9751dd550 100644 (file)
--- a/README
+++ b/README
@@ -77,10 +77,9 @@ option (like "-s100") to start the recording at the respective turn number.
 Hacking / server internals and configuration
 --------------------------------------------
 
-The ./confserver/world file defines the map object types, actions available to
-them, the map geometry and the map object type (species) of the player. Each
-definition consists of a single- or multi-line block wherein each line sets one
-attribute.
+The ./confserver/world file defines the thing types, actions available to them,
+the map geometry and the thing type (species) of the player. Each definition
+consists of a single- or multi-line block wherein each line sets one attribute.
 
 Here's a typical action definition block:
 
@@ -96,9 +95,9 @@ it. The string after "NAME" names the action. Furthermore, if it is one of
 these strings to this action. All other names (including "wait") currently are
 matched to a do-nothing wait function.
 
-Here's a typical map object type definition block: 
+Here's a typical thing type definition block: 
 
-OBJECT 2
+THINGTYPE 2
 NAME ZOMBIE
 SYMBOL z
 LIFEPOINTS 3
@@ -106,18 +105,18 @@ CORPSE_ID 5
 CONSUMABLE 0
 START_NUMBER 9
 
-A line of "OBJECT" followed by a number starts it, and the number sets the
-object type's internal id. The number after "CONSUMABLE" defines the object
-as consumable (and to so many hitpoints gain). The character after "SYMBOL" is
-the one shown on the map to represent to object type. "LIFEPOINTS" is the start
-hitpoints value for this object type and defines it as animate if it is
-non-zero. The string after "NAME" sets the object type's name. "CORPSE_ID" sets
-the id of the object type that objects of this type degrade to if their
-hitpoints drop to zero if they start out as inanimate (what is not implemented
-yet: or if they are inanimate, but are otherwise crushed). Note that the
-"CORPSE_ID" must match the id of an object type defined in the file (before or
-after, it may even be the same). "START_NUMBER" sets the number of objects that
-are to appear of the given type on the map on game start.
+A line of "THINGTYPE" followed by a number starts it, and the number sets the
+thing type's internal id. The number after "CONSUMABLE" defines the thing as
+consumable (and to so many hitpoints gain). The character after "SYMBOL" is the
+one shown on the map to represent to thing type. "LIFEPOINTS" is the start
+hitpoints value for this thing type and defines it as animate if it is non-zero.
+The string after "NAME" sets the thing type's name. "CORPSE_ID" sets the id of
+the thing type that things of this type degrade to if their hitpoints drop to
+zero if they start out as inanimate (what is not implemented yet: or if they are
+inanimate, but are otherwise crushed). Note that the "CORPSE_ID" must match the
+id of a thing type defined in the file (before or after, it may even be the
+same). "START_NUMBER" sets the number of things that are to appear of the
+given type on the map on game start.
 
 The map is defined by a single-line block. Its number value sets the map
 square's edge length. It must be >= 1 and <= 256:
@@ -125,15 +124,15 @@ square's edge length. It must be >= 1 and <= 256:
 MAP_LENGTH 64
 
 The player type / species is also defined by a single line block. Its number
-value sets the player's creature's map object type by its id:
+value sets the player's creature's thing type by its id:
 
 PLAYER_TYPE 0
 
 All these definition block members must be present within their respective
-blocks, but only "ACTION" and "OBJECT" must be positioned at their respective
+blocks, but only "ACTION" and "THINGTYPE" must be positioned at their respective
 blocks' first line; the others may appear in whatever order and even multiple
-times. If an object or action definition block is finished, however, it cannot
-be re-defined by starting a new block with the same object type or action id.
+times. If a thing or action definition block is finished, however, it cannot
+be re-defined by starting a new block with the same thing type or action id.
 
 Tokens in this config file are separated by whitespace. Single quotes can be
 put around string values that are to include whitespace by themslves. Note that
diff --git a/TODO b/TODO
index b1148e100fc64f96719ee2230e8c4c737ac34af4..c6623da4ddf03a19c52db310a12cb1e684a275a2 100644 (file)
--- a/TODO
+++ b/TODO
@@ -18,8 +18,6 @@ SERVER:
 - for game continuation, replace re-playing of whole record files with loading
   game state snapshots / save files
 
-- rename MapObject to Thing, MapObjectDef to ThingType etc.
-
 CLIENT:
 
 - enable toggling of window borders
index a44535c1f21d03b9033bbc1706ab8293f9b9e8b3..1bbb10c06fc588c6b8aea412451685be0170cf5f 100644 (file)
@@ -21,7 +21,7 @@ ACTION 5
 NAME use
 EFFORT 45
 
-OBJECT 0
+THINGTYPE 0
 NAME HUMAN
 SYMBOL @
 LIFEPOINTS 5
@@ -29,7 +29,7 @@ CORPSE_ID 5
 CONSUMABLE 0
 START_NUMBER 1
 
-OBJECT 1
+THINGTYPE 1
 NAME ANT
 SYMBOL a
 LIFEPOINTS 1
@@ -37,7 +37,7 @@ CORPSE_ID 4
 CONSUMABLE 0
 START_NUMBER 27
 
-OBJECT 2
+THINGTYPE 2
 NAME ZOMBIE
 SYMBOL z
 LIFEPOINTS 3
@@ -45,7 +45,7 @@ CORPSE_ID 5
 CONSUMABLE 0
 START_NUMBER 9
 
-OBJECT 3
+THINGTYPE 3
 NAME SHOGGOTH
 SYMBOL S
 LIFEPOINTS 9
@@ -53,7 +53,7 @@ CORPSE_ID 6
 CONSUMABLE 0
 START_NUMBER 3
 
-OBJECT 4
+THINGTYPE 4
 NAME DIRT
 SYMBOL #
 LIFEPOINTS 0
@@ -61,7 +61,7 @@ CORPSE_ID 4
 CONSUMABLE 0
 START_NUMBER 9
 
-OBJECT 5
+THINGTYPE 5
 NAME SKELETON
 SYMBOL %
 LIFEPOINTS 0
@@ -69,7 +69,7 @@ CORPSE_ID 4
 CONSUMABLE 0
 START_NUMBER 9
 
-OBJECT 6
+THINGTYPE 6
 NAME 'MAGIC MEAT'
 SYMBOL m
 LIFEPOINTS 0
index ea77dd48e740e79bf4dd67a9a0a4d629368bb4d7..54db84babcf99dc2cebf60f8dd66c0ff152c877d 100644 (file)
@@ -6,8 +6,8 @@
 #include <stdlib.h> /* free() */
 #include "../common/try_malloc.h" /* try_malloc() */
 #include "field_of_view.h" /* VISIBLE */
-#include "map_object_actions.h" /* get_moa_id_by_name() */
-#include "map_objects.h" /* struct MapObj */
+#include "thing_actions.h" /* get_thing_action_id_by_name() */
+#include "things.h" /* struct Thing */
 #include "world.h" /* global world */
 
 
@@ -37,9 +37,9 @@ static void get_neighbor_scores(uint16_t * score_map, uint16_t pos_i,
 static void dijkstra_map(uint16_t * score_map, uint16_t max_score);
 
 /* Return numpad char of direction ("8", "6", "2", "4" etc.) of enemy with the
- * shortest path visible to "mo_origin". If no enemy is around, return 0.
+ * shortest path visible to "t_origin". If no enemy is around, return 0.
  */
-static char get_dir_to_nearest_enemy(struct MapObj * mo_origin);
+static char get_dir_to_nearest_enemy(struct Thing * thing_origin);
 
 
 
@@ -118,12 +118,12 @@ static void dijkstra_map(uint16_t * score_map, uint16_t max_score)
 
 
 
-static char get_dir_to_nearest_enemy(struct MapObj * mo_origin)
+static char get_dir_to_nearest_enemy(struct Thing * t_origin)
 {
     char * f_name = "get_dir_to_nearest_enemy()";
 
     /* Calculate for each cell the distance to the visibly nearest map actor not
-     * "mo_origin", with movement only possible in the directions of "dir".
+     * "t_origin", with movement only possible in the directions of "dir".
      * (Actors' own cells start with a distance of 0 towards themselves.)
      */
     uint32_t map_size = world.map.length * world.map.length;
@@ -132,22 +132,22 @@ static char get_dir_to_nearest_enemy(struct MapObj * mo_origin)
     uint32_t i;
     for (i = 0; i < map_size; i++)
     {
-        score_map[i] = mo_origin->fov_map[i] & VISIBLE ? max_score : UINT16_MAX;
+        score_map[i] = t_origin->fov_map[i] & VISIBLE ? max_score : UINT16_MAX;
     }
-    struct MapObj * mo = world.map_objs;
-    for (; mo != NULL; mo = mo->next)
+    struct Thing * t = world.things;
+    for (; t != NULL; t = t->next)
     {
-        if (!mo->lifepoints || mo == mo_origin)
+        if (!t->lifepoints || t == t_origin)
         {
             continue;
         }
-        score_map[(mo->pos.y * world.map.length) + mo->pos.x] = 0;
+        score_map[(t->pos.y * world.map.length) + t->pos.x] = 0;
     }
     dijkstra_map(score_map, max_score);
 
-    /* Return direction of "mo_origin"'s lowest-scored neighbor cell. */
+    /* Return direction of "t_origin"'s lowest-scored neighbor cell. */
     uint16_t neighbors[N_DIRS];
-    uint16_t pos_i = (mo_origin->pos.y * world.map.length) + mo_origin->pos.x;
+    uint16_t pos_i = (t_origin->pos.y * world.map.length) + t_origin->pos.x;
     get_neighbor_scores(score_map, pos_i, max_score, neighbors);
     free(score_map);
     char dir_to_nearest_enemy = 0;
@@ -166,13 +166,13 @@ static char get_dir_to_nearest_enemy(struct MapObj * mo_origin)
 
 
 
-extern void ai(struct MapObj * mo)
+extern void ai(struct Thing * t)
 {
-    mo->command = get_moa_id_by_name("wait");
-    char sel = get_dir_to_nearest_enemy(mo);
+    t->command = get_thing_action_id_by_name("wait");
+    char sel = get_dir_to_nearest_enemy(t);
     if (0 != sel)
     {
-        mo->command = get_moa_id_by_name("move");
-        mo->arg = sel;
+        t->command = get_thing_action_id_by_name("move");
+        t->arg = sel;
     }
 }
index 4b9b776c9dfa1b8465d96b6ccddc8965a7e4c36b..9a50a3a86dfb298422888475f5912852e2e7b76f 100644 (file)
@@ -6,7 +6,7 @@
 #ifndef AI_H
 #define AI_H
 
-struct MapObj;
+struct Thing;
 
 
 
@@ -14,7 +14,7 @@ struct MapObj;
  * pretty dumb so far. Actors will try to move towards their path-wise nearest
  * neighbor. If no one else is found in the neighborhood, they will simply wait.
  */
-extern void ai(struct MapObj * mo);
+extern void ai(struct Thing * t);
 
 
 
index 08e3bb6057027637850b348380f2ad21fa99091b..1959c1c831aedf979bd777b999a0bf09b5cff015 100644 (file)
@@ -5,8 +5,8 @@
 #include <stdlib.h> /* free() */
 #include <unistd.h> /* unlink() */
 #include "../common/readwrite.h" /* try_fclose() */
-#include "map_object_actions.h" /* free_map_object_actions() */
-#include "map_objects.h" /* free_map_objects(), free_map_object_defs() */
+#include "thing_actions.h" /* free_thing_actions() */
+#include "things.h" /* free_things(), free_thing_types() */
 #include "world.h" /* global world */
 
 
@@ -27,17 +27,17 @@ extern void cleanup()
     {
         unlink(world.path_worldstate);
     }
-    if (cleanup_flags & CLEANUP_MAP_OBJECTS)
+    if (cleanup_flags & CLEANUP_THINGS)
     {
-        free_map_objects(world.map_objs);
+        free_things(world.things);
     }
-    if (cleanup_flags & CLEANUP_MAP_OBJECT_DEFS)
+    if (cleanup_flags & CLEANUP_THING_TYPES)
     {
-        free_map_object_defs(world.map_obj_defs);
+        free_thing_types(world.thing_types);
     }
-    if (cleanup_flags & CLEANUP_MAP_OBJECT_ACTS)
+    if (cleanup_flags & CLEANUP_THING_ACTIONS)
     {
-        free_map_object_actions(world.map_obj_acts);
+        free_thing_actions(world.thing_actions);
     }
     if (cleanup_flags & CLEANUP_IN)
     {
index 16529414f90e6faafe7ee5d1871ddac5b8c853e7..12e76807344b78e08dee3fae7de4ee3eabdda392 100644 (file)
  */
 enum cleanup_flag
 {
-    CLEANUP_FIFO            = 0x0001,
-    CLEANUP_WORLDSTATE      = 0x0002,
-    CLEANUP_MAP_OBJECT_DEFS = 0x0004,
-    CLEANUP_MAP_OBJECTS     = 0x0008,
-    CLEANUP_MAP_OBJECT_ACTS = 0x0010,
-    CLEANUP_IN              = 0x0020,
-    CLEANUP_OUT             = 0x0040
+    CLEANUP_FIFO          = 0x0001,
+    CLEANUP_WORLDSTATE    = 0x0002,
+    CLEANUP_THING_TYPES   = 0x0004,
+    CLEANUP_THINGS        = 0x0008,
+    CLEANUP_THING_ACTIONS = 0x0010,
+    CLEANUP_IN            = 0x0020,
+    CLEANUP_OUT           = 0x0040
 };
 
 /* In addition, unset_cleanup_flag() may be used to unset flags. */
index 8bbf4ef7a6251e61984b023ab22648f00c885f69..b53b85e197b5ff9a4e49f88bb4f945bfa71b5f81 100644 (file)
                                    */
 #include "../common/rexit.h" /* exit_err(), exit_trouble() */
 #include "../common/try_malloc.h" /* try_malloc() */
-#include "cleanup.h" /* set_cleanup_flag(), CLEANUP_MAP_OBJ_DEFS,
-                      * CLEANUP_MAP_OBJ_ACTS
+#include "cleanup.h" /* set_cleanup_flag(), CLEANUP_THING_TYPES,
+                      * CLEANUP_THING_ACTIONS
                       */
-#include "map_object_actions.h" /* MapObjAct */
-#include "map_objects.h" /* MapObj, MapObjDef, struct MapObjDef */
+#include "thing_actions.h" /* ThingAction */
+#include "things.h" /* Thing, ThingType */
 #include "world.h" /* world global */
 
 
 
-/* Flags defining state of object and action entry reading ((un-)finished /
+/* Flags defining state of thing type and action entry reading ((un-)finished /
  * ready for starting the reading of a new definition etc.)
  */
 enum flag
@@ -35,15 +35,15 @@ enum flag
     LIFEPOINTS_SET = 0x10,
     CONSUMABLE_SET = 0x20,
     START_N_SET    = 0x40,
-    READY_ACT = NAME_SET | EFFORT_SET,
-    READY_OBJ = NAME_SET | CORPSE_ID_SET | SYMBOL_SET | LIFEPOINTS_SET
-                | CONSUMABLE_SET | START_N_SET
+    READY_ACTION   = NAME_SET | EFFORT_SET,
+    READY_THING    = NAME_SET | CORPSE_ID_SET | SYMBOL_SET | LIFEPOINTS_SET
+                     | CONSUMABLE_SET | START_N_SET
 };
 
 
 
-/* What MapObjDef and MapObjAct structs have in common at their top. Use this to
- * allow same functions run over structs of both types.
+/* What ThingType and ThingAction structs have in common at their top. Use this
+ * to allow same functions run over structs of both types.
  */
 struct EntryHead
 {
@@ -53,13 +53,13 @@ struct EntryHead
 
 
 
-/* Interpret "token0" and "token1" as data to write into the MapObjAct /
- * MapObjDef DB.
+/* Interpret "token0" and "token1" as data to write into the ThingAction /
+ * ThingType DB.
  *
- * Individual MapObjDef / MapObjAct DB entries are put together line by line
+ * Individual ThingType / ThingAction DB entries are put together line by line
  * before being written. Writing only happens after all necessary members of an
  * entry have been assembled, and when additionally a) a new entry is started by
- * a "token0" of "ACTION" or "OBJECT"; or b) "token0" is NULL.
+ * a "token0" of "ACTION" or "THINGTYPE"; or b) "token0" is NULL.
  *
  * Also check against the line parse_file() read tokens from having more tokens.
  */
@@ -79,8 +79,8 @@ static uint8_t start_entry(char * token0, char * token1, char * comparand,
 static void write_if_entry(struct EntryHead ** entry,
                            struct EntryHead *** entry_p_p_p);
 
-/* Ensure that all .corpse_id members in the MapObjDef DB fit .id members of
- * MapObjDef DB entries.
+/* Ensure that all .corpse_id members in the ThingType DB fit .id members of
+ * ThingType DB entries.
  */
 static void test_corpse_ids();
 
@@ -91,62 +91,62 @@ static uint8_t set_player_type(char * token0, char * comparand, char * token1);
 static uint8_t set_map_length(char * token0, char * comparand, char * token1);
 
 /* Try to read tokens as members for the definition currently edited, which may
- * be "mod" or "moa". What member of which of the two is set depends on which of
+ * be "tt" or "ta". What member of which of the two is set depends on which of
  * the flags has EDIT_STARTED set and on the key name in "token0". Return 1 if
  * interpretation succeeds, else 0.
  *
- * Note that MapObjAct entries' .name also determines their .func.
+ * Note that ThingAction entries' .name also determines their .func.
  */
 static uint8_t set_members(char * token0, char * token1,
-                           uint8_t * object_flags, uint8_t * action_flags,
-                           struct MapObjDef * mod, struct MapObjAct * moa);
+                           uint8_t * thing_flags, uint8_t * action_flags,
+                           struct ThingType * tt, struct ThingAction * ta);
 
-/* If "name" fits "moa"->name, set "moa"->func to "func". (Derives MapObjAct
+/* If "name" fits "ta"->name, set "ta"->func to "func". (Derives ThingAction
  * .func from .name for set_members().
  */
-static uint8_t try_func_name(struct MapObjAct * moa,
-                             char * name, void (* func) (struct MapObj *));
+static uint8_t try_func_name(struct ThingAction * ta,
+                             char * name, void (* func) (struct Thing *));
 
 
 
 static void tokens_into_entries(char * token0, char * token1)
 {
-    char * str_act = "ACTION";
-    char * str_obj = "OBJECT";
+    char * str_action = "ACTION";
+    char * str_thing = "THINGTYPE";
     char * str_player = "PLAYER_TYPE";
     char * str_map_length = "MAP_LENGTH";
-    static struct MapObjAct ** moa_p_p = &world.map_obj_acts;
-    static struct MapObjDef ** mod_p_p = &world.map_obj_defs;
-    static uint8_t action_flags = READY_ACT;
-    static uint8_t object_flags = READY_OBJ;
-    static struct EntryHead * moa = NULL;
-    static struct EntryHead * mod = NULL;
-    if (!token0 || !strcmp(token0, str_act) || !strcmp(token0, str_obj)
+    static struct ThingAction ** ta_p_p = &world.thing_actions;
+    static struct ThingType ** tt_p_p = &world.thing_types;
+    static uint8_t action_flags = READY_ACTION;
+    static uint8_t thing_flags = READY_THING;
+    static struct EntryHead * ta = NULL;
+    static struct EntryHead * tt = NULL;
+    if (!token0 || !strcmp(token0, str_action) || !strcmp(token0, str_thing)
                 || !strcmp(token0, str_player))
     {
-        parse_and_reduce_to_readyflag(&action_flags, READY_ACT);
-        parse_and_reduce_to_readyflag(&object_flags, READY_OBJ);
-        write_if_entry(&moa, (struct EntryHead ***) &moa_p_p);
-        write_if_entry(&mod, (struct EntryHead ***) &mod_p_p);
+        parse_and_reduce_to_readyflag(&action_flags, READY_ACTION);
+        parse_and_reduce_to_readyflag(&thing_flags, READY_THING);
+        write_if_entry(&ta, (struct EntryHead ***) &ta_p_p);
+        write_if_entry(&tt, (struct EntryHead ***) &tt_p_p);
     }
     if (token0)
     {
         parsetest_too_many_values();
-        if (start_entry(token0, token1, str_act, &action_flags,
-                        sizeof(struct MapObjAct), (struct EntryHead**) &moa,
-                        (struct EntryHead *) world.map_obj_acts))
+        if (start_entry(token0, token1, str_action, &action_flags,
+                        sizeof(struct ThingAction), (struct EntryHead**) &ta,
+                        (struct EntryHead *) world.thing_actions))
         {
             err_line(0 == atoi(token1), "Value must not be 0.");
         }
-        else if (!(   start_entry(token0, token1, str_obj, &object_flags,
-                                  sizeof(struct MapObjDef),
-                                  (struct EntryHead**) &mod,
-                                  (struct EntryHead *) world.map_obj_defs)
+        else if (!(   start_entry(token0, token1, str_thing, &thing_flags,
+                                  sizeof(struct ThingType),
+                                  (struct EntryHead**) &tt,
+                                  (struct EntryHead *) world.thing_types)
                    || set_player_type(token0, str_player, token1)
                    || set_map_length(token0, str_map_length, token1)
-                   || set_members(token0, token1, &object_flags, &action_flags,
-                                  (struct MapObjDef *)mod,
-                                  (struct MapObjAct *) moa)))
+                   || set_members(token0, token1, &thing_flags, &action_flags,
+                                  (struct ThingType *) tt,
+                                  (struct ThingAction *) ta)))
         {
             parse_unknown_arg();
         }
@@ -193,16 +193,16 @@ static void write_if_entry(struct EntryHead ** entry,
 static void test_corpse_ids()
 {
     char * f_name = "test_corpse_ids()";
-    char * prefix = "In the object definitions DB, one object corpse ID does "
-                    "not reference any known object in the DB. ID of "
-                    "responsible object: ";
+    char * prefix = "In the thing types DB, one thing corpse ID does not "
+                    "reference any known thing type in the DB. ID of "
+                    "responsible thing type: ";
     size_t size = strlen(prefix) + 3 + 1; /* 3: uint8_t representation strlen */
     char * err_corpse = try_malloc(size, f_name);
-    struct MapObjDef * test_entry_0 = world.map_obj_defs;
+    struct ThingType * test_entry_0 = world.thing_types;
     for (; test_entry_0; test_entry_0 = test_entry_0->next)
     {
         uint8_t corpse_id_found = 0;
-        struct MapObjDef * test_entry_1 = world.map_obj_defs;
+        struct ThingType * test_entry_1 = world.thing_types;
         for (; test_entry_1; test_entry_1 = test_entry_1->next)
         {
             if (test_entry_0->corpse_id == test_entry_1->id)
@@ -247,38 +247,38 @@ static uint8_t set_map_length(char * token0, char * comparand, char * token1)
 
 
 
-static uint8_t set_members(char * token0, char * token1, uint8_t * object_flags,
+static uint8_t set_members(char * token0, char * token1, uint8_t * thing_flags,
                            uint8_t * action_flags,
-                           struct MapObjDef * mod, struct MapObjAct * moa)
+                           struct ThingType * tt, struct ThingAction * ta)
 {
     if (   *action_flags & EDIT_STARTED
         && parse_val(token0, token1, "NAME", action_flags,
-                     NAME_SET, 's', (char *) &moa->name))
+                     NAME_SET, 's', (char *) &ta->name))
     {
-        if (!(   try_func_name(moa, "move", actor_move)
-              || try_func_name(moa, "pick_up", actor_pick)
-              || try_func_name(moa, "drop", actor_drop)
-              || try_func_name(moa, "use", actor_use)))
+        if (!(   try_func_name(ta, "move", actor_move)
+              || try_func_name(ta, "pick_up", actor_pick)
+              || try_func_name(ta, "drop", actor_drop)
+              || try_func_name(ta, "use", actor_use)))
         {
-            moa->func = actor_wait;
+            ta->func = actor_wait;
         }
         *action_flags = *action_flags | NAME_SET;
         return 1;
     }
-    else if (   parse_val(token0, token1, "NAME", object_flags,
-                          NAME_SET, 's', (char *) &mod->name)
-             || parse_val(token0, token1, "SYMBOL", object_flags,
-                          SYMBOL_SET, 'c', (char *) &mod->char_on_map)
+    else if (   parse_val(token0, token1, "NAME", thing_flags,
+                          NAME_SET, 's', (char *) &tt->name)
+             || parse_val(token0, token1, "SYMBOL", thing_flags,
+                          SYMBOL_SET, 'c', (char *) &tt->char_on_map)
              || parse_val(token0, token1, "EFFORT", action_flags,
-                          EFFORT_SET, '8', (char *) &moa->effort)
-             || parse_val(token0, token1, "START_NUMBER", object_flags,
-                          START_N_SET, '8', (char *) &mod->start_n)
-             || parse_val(token0, token1, "LIFEPOINTS", object_flags,
-                          LIFEPOINTS_SET, '8', (char *) &mod->lifepoints)
-             || parse_val(token0, token1, "CONSUMABLE", object_flags,
-                          CONSUMABLE_SET, '8', (char *) &mod->consumable)
-             || parse_val(token0, token1, "CORPSE_ID", object_flags,
-                          CORPSE_ID_SET, '8', (char *) &mod->corpse_id))
+                          EFFORT_SET, '8', (char *) &ta->effort)
+             || parse_val(token0, token1, "START_NUMBER", thing_flags,
+                          START_N_SET, '8', (char *) &tt->start_n)
+             || parse_val(token0, token1, "LIFEPOINTS", thing_flags,
+                          LIFEPOINTS_SET, '8', (char *) &tt->lifepoints)
+             || parse_val(token0, token1, "CONSUMABLE", thing_flags,
+                          CONSUMABLE_SET, '8', (char *) &tt->consumable)
+             || parse_val(token0, token1, "CORPSE_ID", thing_flags,
+                          CORPSE_ID_SET, '8', (char *) &tt->corpse_id))
     {
         return 1;
     }
@@ -287,12 +287,12 @@ static uint8_t set_members(char * token0, char * token1, uint8_t * object_flags,
 
 
 
-static uint8_t try_func_name(struct MapObjAct * moa, char * name,
-                             void (* func) (struct MapObj *))
+static uint8_t try_func_name(struct ThingAction * ta, char * name,
+                             void (* func) (struct Thing *))
 {
-    if (0 == strcmp(moa->name, name))
+    if (0 == strcmp(ta->name, name))
     {
-        moa->func = func;
+        ta->func = func;
         return 1;
     }
     return 0;
@@ -305,16 +305,16 @@ extern void read_config_file()
     parse_file(world.path_config, tokens_into_entries);
     exit_err(!world.map.length, "Map size not defined in config file.");
     uint8_t player_type_is_valid = 0;
-    struct MapObjDef * mod;
-    for (mod = world.map_obj_defs; NULL != mod; mod = mod->next)
+    struct ThingType * tt;
+    for (tt = world.thing_types; NULL != tt; tt = tt->next)
     {
-        if (world.player_type == mod->id)
+        if (world.player_type == tt->id)
         {
             player_type_is_valid = 1;
             break;
         }
     }
-    exit_err(!player_type_is_valid, "No valid map object type set for player.");
-    set_cleanup_flag(CLEANUP_MAP_OBJECT_ACTS | CLEANUP_MAP_OBJECT_DEFS);
+    exit_err(!player_type_is_valid, "No valid thing type set for player.");
+    set_cleanup_flag(CLEANUP_THING_ACTIONS | CLEANUP_THING_TYPES);
     test_corpse_ids();
 }
index 5fc2a0d8c6cb971e782dac5583a585ce600e9321..901834af96cc87c8cac982ad327dcd8fa66003c9 100644 (file)
@@ -1,6 +1,6 @@
 /* src/server/configfile.h
  *
- * Reading in the config file of map object and map object action definitions.
+ * Reading in the config file of thing types and thing actions.
  */
 
 #ifndef CONFIGFILE_H
@@ -8,8 +8,8 @@
 
 
 
-/* Parse file at world.path_config into map object and map object action
- * definitions at world.map_obj_defs and world.map_obj_acts.
+/* Parse file at world.path_config into thing type and thing action definitions
+ * at world.thing_types and world.thing_actions.
  */
 extern void read_config_file();
 
index ad58a191c3194664c0eed365dc29e6cca6a52222..95b26d49bcd5ca5555894eabf32c13a489552476 100644 (file)
@@ -8,7 +8,7 @@
 #include "../common/rexit.h" /* exit_trouble() */
 #include "../common/try_malloc.h" /* try_malloc() */
 #include "map.h" /* yx_to_map_pos() */
-#include "map_objects.h" /* MapObj */
+#include "things.h" /* Thing */
 #include "yx_uint8.h" /* yx_uint8 */
 #include "world.h" /* global world  */
 
@@ -557,7 +557,7 @@ static void set_view_of_cell_and_shadows(struct yx_uint8 * yx_cell,
 
 
 
-extern uint8_t * build_fov_map(struct MapObj * eye)
+extern uint8_t * build_fov_map(struct Thing * eye)
 {
     char * f_name = "build_fov_map()";
     uint8_t radius = 2 * world.map.length;
index ee337eb1d69636d4d95e764c685a94cc02d5e99b..d7d7d00795297c7be561968ac5e0c290b5f8d9dc 100644 (file)
@@ -9,7 +9,7 @@
 #define FIELD_OF_VIEW_H
 
 #include <stdint.h> /* uint8_t */
-struct MapObj;
+struct Thing;
 
 
 
@@ -39,7 +39,7 @@ enum fov_cell_states {
  * shadows, therefore might be ignored if HIDDEN and not cast shadows on their
  * own that may slightly extend beyond the pre-established shadows they border.
  */
-extern uint8_t * build_fov_map(struct MapObj * eye);
+extern uint8_t * build_fov_map(struct Thing * eye);
 
 
 
index d8ae94f753a1fc66ddbd733c99875a12453254a5..a3c1589b6992c1af654e327f9b193e464329d62e 100644 (file)
@@ -20,9 +20,9 @@
 #include "cleanup.h" /* set_cleanup_flag() */
 #include "field_of_view.h" /* build_fov_map() */
 #include "map.h" /* init_map() */
-#include "map_objects.h" /* MapObj, MapObjDef, free_map_objects(),
-                          * add_map_objects(), get_player()
-                          */
+#include "things.h" /* Thing, ThingType, free_things(), add_things(),
+                     * get_player()
+                     */
 #include "run.h" /* obey_msg(), io_loop() */
 #include "world.h" /* global world */
 
@@ -82,34 +82,34 @@ extern void remake_world(uint32_t seed)
 {
     char * f_name = "remake_world()";
     free(world.log);
-    world.log = NULL;  /* map_object_action.c's update_log() checks for this. */
+    world.log = NULL;  /* thing_actions.c's update_log() checks for this. */
     world.seed = seed;
-    world.map_obj_count = 0;
+    world.thing_count = 0;
     free(world.map.cells);
-    free_map_objects(world.map_objs);
+    free_things(world.things);
     world.last_update_turn = 0;
     init_map();
-    struct MapObjDef * mod;
-    for (mod = world.map_obj_defs; NULL != mod; mod = mod->next)
+    struct ThingType * tt;
+    for (tt = world.thing_types; NULL != tt; tt = tt->next)
     {
-        if (world.player_type == mod->id)
+        if (world.player_type == tt->id)
         {
-            add_map_objects(mod->id, mod->start_n);
+            add_things(tt->id, tt->start_n);
             break;
         }
     }
-    for (mod = world.map_obj_defs; NULL != mod; mod = mod->next)
+    for (tt = world.thing_types; NULL != tt; tt = tt->next)
     {
-        if (world.player_type != mod->id)
+        if (world.player_type != tt->id)
         {
-            add_map_objects(mod->id, mod->start_n);
+            add_things(tt->id, tt->start_n);
         }
     }
-    set_cleanup_flag(CLEANUP_MAP_OBJECTS);
-    struct MapObj * mo;
-    for (mo = world.map_objs; NULL != mo; mo = mo->next)
+    set_cleanup_flag(CLEANUP_THINGS);
+    struct Thing * t;
+    for (t = world.things; NULL != t; t = t->next)
     {
-        mo->fov_map = mo->lifepoints ? build_fov_map(mo) : NULL;
+        t->fov_map = t->lifepoints ? build_fov_map(t) : NULL;
     }
     if (world.turn)
     {
index f99126c88aaadc5c06f73673dd568d1a5f0ea852..0fbc79b51c20c42b2f17b5497dda33ea8e34bf01 100644 (file)
@@ -20,7 +20,7 @@ extern void setup_server_io();
  * Unlinks a pre-existing file at world.path_record if called on a world.turn>0,
  * i.e. if called after iterating through an already established game world.
  *
- * Map object (action) definitions read in from server config directory are not
+ * Thing (action) definitions read in from server config directory are not
  * affected. The map is populated accordingly. world.last_update_turn is set to
  * 0 and world.turn to 1, so that io_round()'s criteria for updating the output
  * file are triggered even when this function is called during a round 1.
index 488f92bd34ac8a2923b1a500f2c3d8f1c9d94a98..8b09ec0f8bdf4c8b898d1e7f15947d8390442f13 100644 (file)
@@ -18,9 +18,7 @@
 #include "cleanup.h" /* set_cleanup_flag() */
 #include "field_of_view.h" /* VISIBLE */
 #include "map.h" /* yx_to_map_pos() */
-#include "map_objects.h" /* structs MapObj, MapObjDef, get_map_obj_def(),
-                          * get_player()
-                          */
+#include "things.h" /* Thing, ThingType, get_thing_type(), get_player() */
 #include "world.h" /* global world  */
 
 
@@ -46,17 +44,17 @@ static void update_worldstate_file();
 static void write_value_as_line(uint32_t value, FILE * file);
 
 /* Write to "file" player's inventory, one item name per line. End in "%\n". */
-static void write_inventory(struct MapObj * player, FILE * file);
+static void write_inventory(struct Thing * player, FILE * file);
 
 /* Return map cells sequence as visible to the "player", with invisible cells as
- * whitespace. Super-impose over visible map cells map objects positioned there.
+ * whitespace. Super-impose over visible map cells things positioned there.
  */
-static char * build_visible_map(struct MapObj * player);
+static char * build_visible_map(struct Thing * player);
 
 /* Write to "file" game map as visible to "player", build_visible_map()-drawn.
  * Write one row per \n-delimited line.
  */
-static void write_map(struct MapObj * player, FILE * file);
+static void write_map(struct Thing * player, FILE * file);
 
 
 
@@ -138,7 +136,7 @@ static void update_worldstate_file()
     char path_tmp[strlen(world.path_worldstate) + strlen(world.tmp_suffix) + 1];
     sprintf(path_tmp, "%s%s", world.path_worldstate, world.tmp_suffix);
     FILE * file = try_fopen(path_tmp, "w", f_name);
-    struct MapObj * player = get_player();
+    struct Thing * player = get_player();
     write_value_as_line(world.turn, file);
     write_value_as_line(player->lifepoints, file);
     write_inventory(player, file);
@@ -169,10 +167,10 @@ static void write_value_as_line(uint32_t value, FILE * file)
 
 
 
-static void write_inventory(struct MapObj * player, FILE * file)
+static void write_inventory(struct Thing * player, FILE * file)
 {
     char * f_name = "write_inventory()";
-    struct MapObj * owned = player->owns;
+    struct Thing * owned = player->owns;
     if (NULL == owned)
     {
         char * empty = "(none)\n";
@@ -183,8 +181,8 @@ static void write_inventory(struct MapObj * player, FILE * file)
         uint8_t q;
         for (q = 0; NULL != owned; q++)
         {
-            struct MapObjDef * mod = get_map_object_def(owned->type);
-            try_fwrite(mod->name, strlen(mod->name), 1, file, f_name);
+            struct ThingType * tt = get_thing_type(owned->type);
+            try_fwrite(tt->name, strlen(tt->name), 1, file, f_name);
             try_fputc('\n', file, f_name);
             owned = owned->next;
         }
@@ -195,7 +193,7 @@ static void write_inventory(struct MapObj * player, FILE * file)
 
 
 
-static char * build_visible_map(struct MapObj * player)
+static char * build_visible_map(struct Thing * player)
 {
     char * f_name = "build_visible_map()";
     uint32_t map_size = world.map.length * world.map.length;
@@ -209,21 +207,21 @@ static char * build_visible_map(struct MapObj * player)
             visible_map[pos_i] = world.map.cells[pos_i];
         }
     }
-    struct MapObj * o;
-    struct MapObjDef * d;
+    struct Thing * t;
+    struct ThingType * tt;
     char c;
     uint8_t i;
     for (i = 0; i < 2; i++)
     {
-        for (o = world.map_objs; o != 0; o = o->next)
+        for (t = world.things; t != 0; t = t->next)
         {
-            if (   player->fov_map[yx_to_map_pos(&o->pos)] & VISIBLE
-                && (   (0 == i && 0 == o->lifepoints)
-                    || (1 == i && 0 < o->lifepoints)))
+            if (   player->fov_map[yx_to_map_pos(&t->pos)] & VISIBLE
+                && (   (0 == i && 0 == t->lifepoints)
+                    || (1 == i && 0 < t->lifepoints)))
             {
-                d = get_map_object_def(o->type);
-                c = d->char_on_map;
-                visible_map[yx_to_map_pos(&o->pos)] = c;
+                tt = get_thing_type(t->type);
+                c = tt->char_on_map;
+                visible_map[yx_to_map_pos(&t->pos)] = c;
             }
         }
     }
@@ -232,7 +230,7 @@ static char * build_visible_map(struct MapObj * player)
 
 
 
-static void write_map(struct MapObj * player, FILE * file)
+static void write_map(struct Thing * player, FILE * file)
 {
     char * f_name = "write_map()";
     char * visible_map = build_visible_map(player);
index 74bb71ea5dfeb2660bfa126f1c428ad91df564de..f74d85df18bd7b6305b1733949df74e52ca7a60d 100644 (file)
@@ -20,8 +20,8 @@
  */
 extern void init_map();
 
-/* Check if coordinate "pos" on (or beyond) world.map is accessible to map
- * object movement.
+/* Check if coordinate "pos" on (or beyond) world.map is accessible to thing
+ * movement.
  */
 extern uint8_t is_passable(struct yx_uint8 pos);
 
diff --git a/src/server/map_object_actions.c b/src/server/map_object_actions.c
deleted file mode 100644 (file)
index 6c92d07..0000000
+++ /dev/null
@@ -1,354 +0,0 @@
-/* src/server/map_object_actions.c */
-
-#include "map_object_actions.h"
-#include <stddef.h> /* NULL */
-#include <stdint.h> /* uint8_t, uint16_t */
-#include <stdio.h> /* sprintf() */
-#include <stdlib.h> /* free() */
-#include <string.h> /* strlen(), strcmp(), memcpy(), strncmp() */
-#include "../common/rexit.h" /* exit_err() */
-#include "../common/try_malloc.h" /* try_malloc() */
-#include "../common/yx_uint8.h" /* struct yx_uint8 */
-#include "field_of_view.h" /* build_fov_map() */
-#include "map_objects.h" /* structs MapObj, MapObjDef, get_player(),
-                          * set_object_position(), own_map_object(),
-                          * get_map_object_def()
-                          */
-#include "map.h" /* is_passable() */
-#include "yx_uint8.h" /* mv_yx_in_dir(), yx_uint8_cmp() */
-#include "world.h" /* global world */
-
-
-
-/* Append "text" to game log, or a "." if "text" is the same as the last one. */
-static void update_log(char * text);
-
-/* One actor "wounds" another actor, decrementing his lifepoints and, if they
- * reach zero in the process, killing it. Generates appropriate log message.
- */
-static void actor_hits_actor(struct MapObj * hitter, struct MapObj * hitted);
-
-/* Bonus stuff to actor_*() to happen if actor==player. Mostly writing of log
- * messages; _pick and _drop also decrement world.inventory_sel by 1 if >0.
- * (match_dir() is just a little helper to playerbonus_move().)
- */
-static void playerbonus_wait();
-static uint8_t match_dir(char d, char ** dsc_d, char match, char * dsc_match);
-static void playerbonus_move(char d, uint8_t passable);
-static void playerbonus_drop(uint8_t owns_none);
-static void playerbonus_pick(uint8_t picked);
-static void playerbonus_use(uint8_t no_object, uint8_t wrong_object);
-
-
-
-static void update_log(char * text)
-{
-    char * f_name = "update_log()";
-    uint16_t len_new = strlen(text);
-    uint16_t len_old = 0;
-    if (world.log)
-    {
-        len_old = strlen(world.log);
-        uint16_t last_nl = len_old - 1;
-        while (last_nl != 0)
-        {
-            if ('\n' == world.log[last_nl])
-            {
-                break;
-            }
-            last_nl--;
-        }
-        uint16_t last_stop = len_old - 1;
-        while (last_stop != 0)
-        {
-            if ('.' == world.log[last_stop] && '.' != world.log[last_stop - 1])
-            {
-                break;
-            }
-            last_stop--;
-        }
-        if (   (last_stop + 1) - last_nl == (uint16_t) strlen(text)
-            && 0 == strncmp(world.log + last_nl, text, strlen(text)))
-        {
-            text = ".";
-        }
-    }
-    uint16_t len_whole = len_old + len_new + 1;
-    char * new_text = try_malloc(len_whole, f_name);
-    memcpy(new_text, world.log, len_old);
-    sprintf(new_text + len_old, "%s", text);
-    free(world.log);
-    world.log = new_text;
-}
-
-
-
-static void actor_hits_actor(struct MapObj * hitter, struct MapObj * hitted)
-{
-    struct MapObjDef * mod_hitter = get_map_object_def(hitter->type);
-    struct MapObjDef * mod_hitted = get_map_object_def(hitted->type);
-    struct MapObj * player = get_player();
-    char * msg1 = "You";
-    char * msg2 = "wound";
-    char * msg3 = "you";
-    if      (player != hitter)
-    {
-        msg1 = mod_hitter->name;
-        msg2 = "wounds";
-    }
-    if (player != hitted)
-    {
-        msg3 = mod_hitted->name;
-    }
-    uint8_t len = 1 + strlen(msg1) + 1 + strlen(msg2) + 1 + strlen(msg3) + 2;
-    char msg[len];
-    sprintf(msg, "\n%s %s %s.", msg1, msg2, msg3);
-    update_log(msg);
-    hitted->lifepoints--;
-    if (0 == hitted->lifepoints)
-    {
-        hitted->type = mod_hitted->corpse_id;
-        if (player == hitted)
-        {
-            update_log(" You die.");
-            return;
-        }
-        update_log(" It dies.");
-    }
-}
-
-
-
-static void playerbonus_wait()
-{
-        update_log("\nYou wait.");
-}
-
-
-
-static uint8_t match_dir(char d, char ** dsc_d, char match, char * dsc_match)
-{
-    if (d == match)
-    {
-        * dsc_d = dsc_match;
-        return 1;
-    }
-    return 0;
-}
-
-
-
-static void playerbonus_move(char d, uint8_t passable)
-{
-    char * dsc_dir = "north-east";
-    if (   match_dir(d, &dsc_dir, 'd', "east")
-        || match_dir(d, &dsc_dir, 'c', "south-east")
-        || match_dir(d, &dsc_dir, 'x', "south-west")
-        || match_dir(d, &dsc_dir, 's', "west")
-        || match_dir(d, &dsc_dir, 'w', "north-west"))
-    {
-        ;
-    }
-    char * dsc_move = "You move ";
-    if (0 == passable)
-    {
-        dsc_move = "You fail to move ";
-    }
-    char msg[strlen(dsc_move) + strlen (dsc_dir) + 3];
-    sprintf(msg, "\n%s%s.", dsc_move, dsc_dir);
-    update_log(msg);
-}
-
-
-
-static void playerbonus_drop(uint8_t owns_none)
-{
-    if (0 != owns_none)
-    {
-        update_log("\nYou try to drop an object, but you own none.");
-        return;
-    }
-    update_log("\nYou drop an object.");
-}
-
-
-
-static void playerbonus_pick(uint8_t picked)
-{
-    if (picked)
-    {
-        update_log("\nYou pick up an object.");
-        return;
-    }
-    update_log("\nYou try to pick up an object, but there is none.");
-}
-
-
-
-static void playerbonus_use(uint8_t no_object, uint8_t wrong_object)
-{
-    if      (no_object)
-    {
-        update_log("\nYou try to use an object, but you own none.");
-        return;
-    }
-    else if (wrong_object)
-    {
-        update_log("\nYou try to use this object, but fail.");
-        return;
-    }
-    update_log("\nYou consume MAGIC MEAT.");
-}
-
-
-
-extern void free_map_object_actions(struct MapObjAct * moa)
-{
-    if (NULL == moa)
-    {
-        return;
-    }
-    free(moa->name);
-    free_map_object_actions(moa->next);
-    free(moa);
-}
-
-
-
-extern uint8_t get_moa_id_by_name(char * name)
-{
-    struct MapObjAct * moa = world.map_obj_acts;
-    while (NULL != moa)
-    {
-        if (0 == strcmp(moa->name, name))
-        {
-            break;
-        }
-        moa = moa->next;
-    }
-    exit_err(NULL==moa, "get_moa_id_by_name() did not find map object action.");
-    return moa->id;
-}
-
-
-
-extern void actor_wait(struct MapObj * mo)
-{
-    if (mo == get_player())
-    {
-        playerbonus_wait();
-    }
-}
-
-
-
-extern void actor_move(struct MapObj * mo)
-{
-    char d = mo->arg;
-    struct yx_uint8 target = mv_yx_in_dir(d, mo->pos);
-    struct MapObj * other_mo;
-    for (other_mo = world.map_objs; other_mo != 0; other_mo = other_mo->next)
-    {
-        if (0 == other_mo->lifepoints || other_mo == mo)
-        {
-            continue;
-        }
-        if (yx_uint8_cmp(&target, &other_mo->pos))
-        {
-            actor_hits_actor(mo, other_mo);
-            return;
-        }
-    }
-    uint8_t passable = is_passable(target);
-    if (passable)
-    {
-        set_object_position(mo, target);
-        free(mo->fov_map);
-        mo->fov_map = build_fov_map(mo);
-    }
-    if (mo == get_player())
-    {
-        playerbonus_move(d, passable);
-    }
-}
-
-
-
-extern void actor_drop(struct MapObj * mo)
-{
-    uint8_t owns_none = (NULL == mo->owns);
-    if (!owns_none)
-    {
-        uint8_t select = mo->arg;
-        struct MapObj * owned = mo->owns;
-        uint8_t i = 0;
-        for (; i != select; i++, owned = owned->next);
-        own_map_object(&world.map_objs, &mo->owns, owned->id);
-    }
-    if (mo == get_player())
-    {
-        playerbonus_drop(owns_none);
-    }
-}
-
-
-
-extern void actor_pick(struct MapObj * mo)
-{
-    struct MapObj * picked = NULL;
-    struct MapObj * mo_i;
-    for (mo_i = world.map_objs; NULL != mo_i; mo_i = mo_i->next)
-    {
-        if (mo_i != mo && yx_uint8_cmp(&mo_i->pos, &mo->pos))
-        {
-            picked = mo_i;
-        }
-    }
-    if (NULL != picked)
-    {
-        own_map_object(&mo->owns, &world.map_objs, picked->id);
-        set_object_position(picked, mo->pos);
-    }
-    if (mo == get_player())
-    {
-        playerbonus_pick(NULL != picked);
-    }
-}
-
-
-
-extern void actor_use(struct MapObj * mo)
-{
-    uint8_t wrong_object = 1;
-    uint8_t no_object = (NULL == mo->owns);
-    if (!no_object)
-    {
-        uint8_t select = mo->arg;
-        uint8_t i = 0;
-        struct MapObj * selected = mo->owns;
-        for (; i != select; i++, selected = selected->next);
-        struct MapObjDef * mod = get_map_object_def(selected->type);
-        if (mod->consumable)
-        {
-            wrong_object = 0;
-            struct MapObj * next = selected->next;
-            free(selected);
-            if (0 < select)
-            {
-                select--;
-                selected = mo->owns;
-                for (i = 0; i != select; i++, selected = selected->next);
-                selected->next = next;
-            }
-            else
-            {
-                mo->owns = next;
-            }
-            mo->lifepoints = mo->lifepoints + mod->consumable;
-        }
-    }
-    if (mo == get_player())
-    {
-        playerbonus_use(no_object, wrong_object);
-    }
-}
diff --git a/src/server/map_object_actions.h b/src/server/map_object_actions.h
deleted file mode 100644 (file)
index 7192cb4..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/* src/server/map_object_actions.h
- *
- * Actions that can be performed my map objects / "actors". Note that apart
- * from the consequences described below, each action may also trigger log
- * messages and other minor stuff if the actor is equal to the player.
- */
-
-#ifndef MAP_OBJECT_ACTIONS_H
-#define MAP_OBJECT_ACTIONS_H
-
-#include <stdint.h> /* uint8_t */
-struct MapObj;
-
-
-
-struct MapObjAct
-{
-    uint8_t id; /* identifies action in MapObj.command; therefore must be >0 */
-    struct MapObjAct * next;
-    void (* func) (struct MapObj *); /* function called after .effort turns */
-    char * name; /* human-readable identifier */
-    uint8_t effort; /* how many turns the action takes */
-};
-
-
-
-/* Free MapObjAct * chain starting at "moa". */
-extern void free_map_object_actions(struct MapObjAct * moa);
-
-/* Return world.map_obj_acts MapObjAct.id for "name". */
-extern uint8_t get_moa_id_by_name(char * name);
-
-/* Actor "mo" does nothing. */
-extern void actor_wait(struct MapObj * mo);
-
-/* Actor "mo" tries to move one step in direction described by char mo->arg
- * (where noth-east is 'e', east 'd' etc.) Move either succeeds, or another
- * actor is encountered and hit (which leads ot its lifepoint decreasing by one
- * and eventually death), or the move fails due to an impassable target square.
- * On success, update object's field of view map.
- */
-extern void actor_move(struct MapObj * mo);
-
-/* Actor "mo" tries to drop from inventory object indexed by number mo->args. */
-extern void actor_drop(struct MapObj * mo);
-
-/* Actor "mo" tries to pick up topmost object from ground into its inventory. */
-extern void actor_pick(struct MapObj * mo);
-
-/* Actor "mo" tries to use inventory object indexed by number mo->args.
- * (Currently the only valid use is consuming items defined as consumable.)
- */
-extern void actor_use(struct MapObj * mo);
-
-
-
-#endif
diff --git a/src/server/map_objects.c b/src/server/map_objects.c
deleted file mode 100644 (file)
index fa20c17..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
-/* src/server/map_objects.c */
-
-#include "map_objects.h"
-#include <stddef.h> /* NULL */
-#include <stdint.h> /* uint8_t, uint16_t, UINT16_MAX */
-#include <stdlib.h> /* free() */
-#include <string.h> /* memset(), strlen() */
-#include "../common/rexit.h" /* exit_err() */
-#include "../common/try_malloc.h" /* try_malloc() */
-#include "../common/yx_uint8.h" /* yx_uint8 struct */
-#include "map.h" /* is_passable() */
-#include "rrand.h" /* rrand() */
-#include "world.h" /* global world */
-#include "yx_uint8.h" /* yx_uint8_cmp() */
-
-
-
-/* Return pointer to map object of "id" in chain starting at "ptr". */
-static struct MapObj * get_map_object(struct MapObj * ptr, uint8_t id);
-
-/* Add object of "type" to map on passable position. Don't put actor on actor.*/
-static void add_map_object(uint8_t type);
-
-
-
-static struct MapObj * get_map_object(struct MapObj * ptr, uint8_t id)
-{
-    while (1)
-    {
-        if (NULL == ptr || id == ptr->id)
-        {
-            return ptr;
-        }
-        struct MapObj * owned_object = get_map_object(ptr->owns, id);
-        if (NULL != owned_object)
-        {
-            return ptr;
-        }
-        ptr = ptr->next;
-    }
-}
-
-
-
-static void add_map_object(uint8_t type)
-{
-    char * f_name = "add_map_object()";
-    struct MapObjDef * mod = get_map_object_def(type);
-    struct MapObj *    mo  = try_malloc(sizeof(struct MapObj), f_name);
-    memset(mo, 0, sizeof(struct MapObj));
-    mo->id         = world.map_obj_count++;
-    mo->type       = mod->id;
-    mo->lifepoints = mod->lifepoints;
-    char * err = "Space to put map object on too hard to find. Map too small?";
-    uint16_t i = 0;
-    while (1)
-    {
-        struct yx_uint8 pos;
-        for (pos.y = pos.x = 0; 0 == is_passable(pos); i++)
-        {
-            exit_err(UINT16_MAX == i, err);
-            pos.y = rrand() % world.map.length;
-            pos.x = rrand() % world.map.length;
-        }
-        struct MapObj * mo_ptr;
-        uint8_t clear = 1;
-        for (mo_ptr = world.map_objs; mo_ptr != NULL; mo_ptr = mo_ptr->next)
-        {
-            if (yx_uint8_cmp(&pos, &mo_ptr->pos) && 0 != mo_ptr->lifepoints)
-            {
-                clear = 0;
-                break;
-            }
-        }
-        if (1 == clear)
-        {
-            mo->pos = pos;
-            break;
-        }
-    }
-    struct MapObj ** mo_ptr_ptr = &world.map_objs;
-    for (; NULL != * mo_ptr_ptr; mo_ptr_ptr = &(*mo_ptr_ptr)->next);
-    * mo_ptr_ptr = mo;
-}
-
-
-
-extern void free_map_object_defs(struct MapObjDef * mod_start)
-{
-    if (NULL == mod_start)
-    {
-        return;
-    }
-    free_map_object_defs(mod_start->next);
-    free(mod_start->name);
-    free(mod_start);
-}
-
-
-
-extern void add_map_objects(uint8_t type, uint8_t n)
-{
-    uint8_t i;
-    for (i = 0; i < n; i++)
-    {
-        add_map_object(type);
-    }
-}
-
-
-
-extern void free_map_objects(struct MapObj * mo_start)
-{
-    if (NULL == mo_start)
-    {
-        return;
-    }
-    free_map_objects(mo_start->owns);
-    free_map_objects(mo_start->next);
-    free(mo_start->fov_map);
-    free(mo_start);
-    if (mo_start == world.map_objs)  /* So add_map_objects()' NULL-delimited  */
-    {                                /* map object iteration loop does not    */
-        world.map_objs = NULL;       /* iterate over freed memory when called */
-    }                                /* the 1st time after world re-seeding.  */
-}
-
-
-
-extern void own_map_object(struct MapObj ** target, struct MapObj ** source,
-                           uint8_t id)
-{
-    struct MapObj * mo;
-    if (id == (*source)->id)
-    {
-        mo = * source;
-        * source = mo->next;
-    }
-    else
-    {
-        struct MapObj * penult = * source;
-        while (1)
-        {
-            if (id == penult->next->id)
-            {
-                break;
-            }
-            penult = penult->next;
-        }
-        mo = penult->next;
-        penult->next = mo->next;
-    }
-    struct MapObj ** mo_ptr_ptr = target;
-    for (; NULL != * mo_ptr_ptr; mo_ptr_ptr = &(*mo_ptr_ptr)->next);
-    * mo_ptr_ptr = mo;
-    mo->next = NULL;
-}
-
-
-
-extern struct MapObj * get_player()
-{
-    return get_map_object(world.map_objs, 0);
-}
-
-
-
-extern struct MapObjDef * get_map_object_def(uint8_t id)
-{
-    struct MapObjDef * mod = world.map_obj_defs;
-    for (; NULL != mod && id != mod->id; mod = mod->next);
-    char * err_intro = "Requested map object definition of unused ID ";
-    char err[strlen(err_intro) + 3 + 1 + 1];
-    sprintf(err, "%s%d.", err_intro, id);
-    exit_err(NULL == mod, err);
-    return mod;
-}
-
-
-
-extern void set_object_position(struct MapObj * mo, struct yx_uint8 pos)
-{
-    mo->pos = pos;
-    struct MapObj * owned = mo->owns;
-    for (; owned != NULL; set_object_position(owned, pos), owned = owned->next);
-}
diff --git a/src/server/map_objects.h b/src/server/map_objects.h
deleted file mode 100644 (file)
index 1e32318..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/* src/server/map_objects.h
- *
- * Structs for objects on the map and their type definitions, and routines to
- * initialize these and load and save them from/to files.
- */
-
-#ifndef MAP_OBJECTS_H
-#define MAP_OBJECTS_H
-
-#include <stdint.h> /* uint8_t */
-#include "../common/yx_uint8.h" /* yx_uint8 structs */
-
-
-
-struct MapObj
-{
-    struct MapObj * next;        /* pointer to next one in map object chain */
-    struct MapObj * owns;        /* chain of map objects owned / in inventory */
-    struct yx_uint8 pos;         /* coordinate on map */
-    uint8_t * fov_map;           /* map of the object's field of view */
-    uint8_t id;                  /* individual map object's unique identifier */
-    uint8_t type;                /* ID of appropriate map object definition */
-    uint8_t lifepoints;          /* 0: object is inanimate; >0: hitpoints */
-    uint8_t command;             /* map object's current action; 0 if none */
-    uint8_t arg;                 /* optional field for .command argument */
-    uint8_t progress;            /* turns already passed to realize .command */
-};
-
-struct MapObjDef
-{
-    uint8_t id;         /* map object definition identifier / sets .type */
-    struct MapObjDef * next;
-    char char_on_map;   /* map object symbol to appear on map */
-    char * name;        /* string to describe object in game log */
-    uint8_t corpse_id;  /* type to change map object into upon destruction */
-    uint8_t lifepoints; /* default start value for map object's .lifepoints */
-    uint8_t consumable; /* can be eaten if !0, for so much hitpoint win */
-    uint8_t start_n;    /* how many of these does the map start with? */
-};
-
-
-
-/* Free map object definitions chain starting at "mod_start". */
-extern void free_map_object_defs(struct MapObjDef * mod_start);
-
-/* Add object(s) ("n": how many?) of "type" to map on random position(s). New
- * animate objects are never placed in the same square with other animate ones.
- */
-extern void add_map_objects(uint8_t type, uint8_t n);
-
-/* Free map objects in map object chain starting at "mo_start. */
-extern void free_map_objects(struct MapObj * mo_start);
-
-/* Move object of "id" from "source" inventory to "target" inventory. */
-extern void own_map_object(struct MapObj ** target, struct MapObj ** source,
-                           uint8_t id);
-
-/* Get pointer to the MapObj struct that represents the player. */
-extern struct MapObj * get_player();
-
-/* Get pointer to the map object definition of identifier "def_id". */
-extern struct MapObjDef * get_map_object_def(uint8_t id);
-
-/* Move not only "mo" to "pos", but also all map objects owned by it. */
-extern void set_object_position(struct MapObj * mo, struct yx_uint8 pos);
-
-
-
-#endif
index 414549227f963db1d3c21135cdfe51891cfb24de..952cebb566d317d46bc62df7a1a8a3233d02fd73 100644 (file)
@@ -16,8 +16,8 @@
 #include "cleanup.h" /* unset_cleanup_flag() */
 #include "init.h" /* remake_world() */
 #include "io.h" /* io_round() */
-#include "map_object_actions.h" /* get_moa_id_by_name() */
-#include "map_objects.h" /* struct MapObj, get_player() */
+#include "thing_actions.h" /* get_thing_action_id_by_name() */
+#include "things.h" /* Thing, get_player() */
 #include "world.h" /* global world */
 
 
@@ -27,7 +27,7 @@
  */
 static void turn_over();
 
-/* If "msg"'s first part matches "command_name", set player's MapObj's .command
+/* If "msg"'s first part matches "command_name", set player's Thing's .command
  * to the command's id and its .arg to a numerical value following in the latter
  * part of "msg" (if no digits are found, use 0); then finish player's turn and
  * turn game over to the NPCs via turn_over(); then return 1. Else, return 0.
@@ -45,41 +45,41 @@ static void server_test();
 
 static void turn_over()
 {
-    struct MapObj * player = get_player();
-    struct MapObj * map_object = player;
+    struct Thing * player = get_player();
+    struct Thing * thing = player;
     uint16_t start_turn = world.turn;
     while (    0 < player->lifepoints
            || (0 == player->lifepoints && start_turn == world.turn))
     {
-        if (NULL == map_object)
+        if (NULL == thing)
         {
             world.turn++;
-            map_object = world.map_objs;
+            thing = world.things;
         }
-        if (0 < map_object->lifepoints)
+        if (0 < thing->lifepoints)
         {
-            if (0 == map_object->command)
+            if (0 == thing->command)
             {
-                if (map_object == player)
+                if (thing == player)
                 {
                     break;
                 }
-                ai(map_object);
+                ai(thing);
             }
-            map_object->progress++;
-            struct MapObjAct * moa = world.map_obj_acts;
-            while (moa->id != map_object->command)
+            thing->progress++;
+            struct ThingAction * ta = world.thing_actions;
+            while (ta->id != thing->command)
             {
-                moa = moa->next;
+                ta = ta->next;
             }
-            if (map_object->progress == moa->effort)
+            if (thing->progress == ta->effort)
             {
-                moa->func(map_object);
-                map_object->command = 0;
-                map_object->progress = 0;
+                ta->func(thing);
+                thing->command = 0;
+                thing->progress = 0;
             }
         }
-        map_object = map_object->next;
+        thing = thing->next;
     }
 }
 
@@ -89,9 +89,9 @@ static uint8_t apply_player_command(char * msg, char * command_name)
 {
     if (!strncmp(msg, command_name, strlen(command_name)))
     {
-        struct MapObj * player = get_player();
+        struct Thing * player = get_player();
         player->arg = atoi(&(msg[strlen(command_name)]));
-        player->command = get_moa_id_by_name(command_name);
+        player->command = get_thing_action_id_by_name(command_name);
         turn_over();
         return 1;
     }
@@ -126,10 +126,10 @@ extern void obey_msg(char * msg, uint8_t do_record)
     char * f_name = "obey_msg()";
     if (   apply_player_command(msg, "wait")   /* TODO: Check for non-error   */
         || apply_player_command(msg, "move")   /* return value of a modified  */
-        || apply_player_command(msg, "pick_up")/* get_moa_id_by_name(); if id */
-        || apply_player_command(msg, "drop")   /* found, execute on it what's */
-        || apply_player_command(msg, "use"));  /* in apply_player_command().  */
-    else
+        || apply_player_command(msg, "pick_up")/*get_thing_action_id_by_name()*/
+        || apply_player_command(msg, "drop")   /* and if id found, execute on */
+        || apply_player_command(msg, "use"));  /* it what's in                */
+    else                                       /* apply_player_command().     */
     {
         char * seed_command = "seed";
         if (!strncmp(msg, seed_command, strlen(seed_command)))
diff --git a/src/server/thing_actions.c b/src/server/thing_actions.c
new file mode 100644 (file)
index 0000000..e4e5276
--- /dev/null
@@ -0,0 +1,353 @@
+/* src/server/thing_actions.c */
+
+#include "thing_actions.h"
+#include <stddef.h> /* NULL */
+#include <stdint.h> /* uint8_t, uint16_t */
+#include <stdio.h> /* sprintf() */
+#include <stdlib.h> /* free() */
+#include <string.h> /* strlen(), strcmp(), memcpy(), strncmp() */
+#include "../common/rexit.h" /* exit_err() */
+#include "../common/try_malloc.h" /* try_malloc() */
+#include "../common/yx_uint8.h" /* struct yx_uint8 */
+#include "field_of_view.h" /* build_fov_map() */
+#include "things.h" /* structs Thing, ThingType, get_player(), own_thing(),
+                     * set_thing_position(), get_thing_type()
+                     */
+#include "map.h" /* is_passable() */
+#include "yx_uint8.h" /* mv_yx_in_dir(), yx_uint8_cmp() */
+#include "world.h" /* global world */
+
+
+
+/* Append "text" to game log, or a "." if "text" is the same as the last one. */
+static void update_log(char * text);
+
+/* One actor "wounds" another actor, decrementing his lifepoints and, if they
+ * reach zero in the process, killing it. Generates appropriate log message.
+ */
+static void actor_hits_actor(struct Thing * hitter, struct Thing * hitted);
+
+/* Bonus stuff to actor_*() to happen if actor==player. Mostly writing of log
+ * messages; _pick and _drop also decrement world.inventory_sel by 1 if >0.
+ * (match_dir() is just a little helper to playerbonus_move().)
+ */
+static void playerbonus_wait();
+static uint8_t match_dir(char d, char ** dsc_d, char match, char * dsc_match);
+static void playerbonus_move(char d, uint8_t passable);
+static void playerbonus_drop(uint8_t owns_none);
+static void playerbonus_pick(uint8_t picked);
+static void playerbonus_use(uint8_t no_thing, uint8_t wrong_thing);
+
+
+
+static void update_log(char * text)
+{
+    char * f_name = "update_log()";
+    uint16_t len_new = strlen(text);
+    uint16_t len_old = 0;
+    if (world.log)
+    {
+        len_old = strlen(world.log);
+        uint16_t last_nl = len_old - 1;
+        while (last_nl != 0)
+        {
+            if ('\n' == world.log[last_nl])
+            {
+                break;
+            }
+            last_nl--;
+        }
+        uint16_t last_stop = len_old - 1;
+        while (last_stop != 0)
+        {
+            if ('.' == world.log[last_stop] && '.' != world.log[last_stop - 1])
+            {
+                break;
+            }
+            last_stop--;
+        }
+        if (   (last_stop + 1) - last_nl == (uint16_t) strlen(text)
+            && 0 == strncmp(world.log + last_nl, text, strlen(text)))
+        {
+            text = ".";
+        }
+    }
+    uint16_t len_whole = len_old + len_new + 1;
+    char * new_text = try_malloc(len_whole, f_name);
+    memcpy(new_text, world.log, len_old);
+    sprintf(new_text + len_old, "%s", text);
+    free(world.log);
+    world.log = new_text;
+}
+
+
+
+static void actor_hits_actor(struct Thing * hitter, struct Thing * hitted)
+{
+    struct ThingType * tt_hitter = get_thing_type(hitter->type);
+    struct ThingType * tt_hitted = get_thing_type(hitted->type);
+    struct Thing * player = get_player();
+    char * msg1 = "You";
+    char * msg2 = "wound";
+    char * msg3 = "you";
+    if      (player != hitter)
+    {
+        msg1 = tt_hitter->name;
+        msg2 = "wounds";
+    }
+    if (player != hitted)
+    {
+        msg3 = tt_hitted->name;
+    }
+    uint8_t len = 1 + strlen(msg1) + 1 + strlen(msg2) + 1 + strlen(msg3) + 2;
+    char msg[len];
+    sprintf(msg, "\n%s %s %s.", msg1, msg2, msg3);
+    update_log(msg);
+    hitted->lifepoints--;
+    if (0 == hitted->lifepoints)
+    {
+        hitted->type = tt_hitted->corpse_id;
+        if (player == hitted)
+        {
+            update_log(" You die.");
+            return;
+        }
+        update_log(" It dies.");
+    }
+}
+
+
+
+static void playerbonus_wait()
+{
+        update_log("\nYou wait.");
+}
+
+
+
+static uint8_t match_dir(char d, char ** dsc_d, char match, char * dsc_match)
+{
+    if (d == match)
+    {
+        * dsc_d = dsc_match;
+        return 1;
+    }
+    return 0;
+}
+
+
+
+static void playerbonus_move(char d, uint8_t passable)
+{
+    char * dsc_dir = "north-east";
+    if (   match_dir(d, &dsc_dir, 'd', "east")
+        || match_dir(d, &dsc_dir, 'c', "south-east")
+        || match_dir(d, &dsc_dir, 'x', "south-west")
+        || match_dir(d, &dsc_dir, 's', "west")
+        || match_dir(d, &dsc_dir, 'w', "north-west"))
+    {
+        ;
+    }
+    char * dsc_move = "You move ";
+    if (0 == passable)
+    {
+        dsc_move = "You fail to move ";
+    }
+    char msg[strlen(dsc_move) + strlen (dsc_dir) + 3];
+    sprintf(msg, "\n%s%s.", dsc_move, dsc_dir);
+    update_log(msg);
+}
+
+
+
+static void playerbonus_drop(uint8_t owns_none)
+{
+    if (0 != owns_none)
+    {
+        update_log("\nYou try to drop an object, but you own none.");
+        return;
+    }
+    update_log("\nYou drop an object.");
+}
+
+
+
+static void playerbonus_pick(uint8_t picked)
+{
+    if (picked)
+    {
+        update_log("\nYou pick up an object.");
+        return;
+    }
+    update_log("\nYou try to pick up an object, but there is none.");
+}
+
+
+
+static void playerbonus_use(uint8_t no_thing, uint8_t wrong_thing)
+{
+    if      (no_thing)
+    {
+        update_log("\nYou try to use an object, but you own none.");
+        return;
+    }
+    else if (wrong_thing)
+    {
+        update_log("\nYou try to use this object, but fail.");
+        return;
+    }
+    update_log("\nYou consume MAGIC MEAT.");
+}
+
+
+
+extern void free_thing_actions(struct ThingAction * ta)
+{
+    if (NULL == ta)
+    {
+        return;
+    }
+    free(ta->name);
+    free_thing_actions(ta->next);
+    free(ta);
+}
+
+
+
+extern uint8_t get_thing_action_id_by_name(char * name)
+{
+    struct ThingAction * ta = world.thing_actions;
+    while (NULL != ta)
+    {
+        if (0 == strcmp(ta->name, name))
+        {
+            break;
+        }
+        ta = ta->next;
+    }
+    exit_err(NULL == ta, "get_thing_action_id_by_name() did not find action.");
+    return ta->id;
+}
+
+
+
+extern void actor_wait(struct Thing * t)
+{
+    if (t == get_player())
+    {
+        playerbonus_wait();
+    }
+}
+
+
+
+extern void actor_move(struct Thing * t)
+{
+    char d = t->arg;
+    struct yx_uint8 target = mv_yx_in_dir(d, t->pos);
+    struct Thing * other_t;
+    for (other_t = world.things; other_t != 0; other_t = other_t->next)
+    {
+        if (0 == other_t->lifepoints || other_t == t)
+        {
+            continue;
+        }
+        if (yx_uint8_cmp(&target, &other_t->pos))
+        {
+            actor_hits_actor(t, other_t);
+            return;
+        }
+    }
+    uint8_t passable = is_passable(target);
+    if (passable)
+    {
+        set_thing_position(t, target);
+        free(t->fov_map);
+        t->fov_map = build_fov_map(t);
+    }
+    if (t == get_player())
+    {
+        playerbonus_move(d, passable);
+    }
+}
+
+
+
+extern void actor_drop(struct Thing * t)
+{
+    uint8_t owns_none = (NULL == t->owns);
+    if (!owns_none)
+    {
+        uint8_t select = t->arg;
+        struct Thing * owned = t->owns;
+        uint8_t i = 0;
+        for (; i != select; i++, owned = owned->next);
+        own_thing(&world.things, &t->owns, owned->id);
+    }
+    if (t == get_player())
+    {
+        playerbonus_drop(owns_none);
+    }
+}
+
+
+
+extern void actor_pick(struct Thing * t)
+{
+    struct Thing * picked = NULL;
+    struct Thing * t_i;
+    for (t_i = world.things; NULL != t_i; t_i = t_i->next)
+    {
+        if (t_i != t && yx_uint8_cmp(&t_i->pos, &t->pos))
+        {
+            picked = t_i;
+        }
+    }
+    if (NULL != picked)
+    {
+        own_thing(&t->owns, &world.things, picked->id);
+        set_thing_position(picked, t->pos);
+    }
+    if (t == get_player())
+    {
+        playerbonus_pick(NULL != picked);
+    }
+}
+
+
+
+extern void actor_use(struct Thing * t)
+{
+    uint8_t wrong_thing = 1;
+    uint8_t no_thing = (NULL == t->owns);
+    if (!no_thing)
+    {
+        uint8_t select = t->arg;
+        uint8_t i = 0;
+        struct Thing * selected = t->owns;
+        for (; i != select; i++, selected = selected->next);
+        struct ThingType * tt = get_thing_type(selected->type);
+        if (tt->consumable)
+        {
+            wrong_thing = 0;
+            struct Thing * next = selected->next;
+            free(selected);
+            if (0 < select)
+            {
+                select--;
+                selected = t->owns;
+                for (i = 0; i != select; i++, selected = selected->next);
+                selected->next = next;
+            }
+            else
+            {
+                t->owns = next;
+            }
+            t->lifepoints = t->lifepoints + tt->consumable;
+        }
+    }
+    if (t == get_player())
+    {
+        playerbonus_use(no_thing, wrong_thing);
+    }
+}
diff --git a/src/server/thing_actions.h b/src/server/thing_actions.h
new file mode 100644 (file)
index 0000000..861f5c2
--- /dev/null
@@ -0,0 +1,57 @@
+/* src/server/thing_actions.h
+ *
+ * Actions that can be performed by living things / "actors". Note that apart
+ * from the consequences described below, each action may also trigger log
+ * messages and other minor stuff if the actor is equal to the player.
+ */
+
+#ifndef THING_ACTIONS_H
+#define THING_ACTIONS_H
+
+#include <stdint.h> /* uint8_t */
+struct Thing;
+
+
+
+struct ThingAction
+{
+    uint8_t id; /* identifies action in Thing.command; therefore must be >0 */
+    struct ThingAction * next;
+    void (* func) (struct Thing *); /* function called after .effort turns */
+    char * name; /* human-readable identifier */
+    uint8_t effort; /* how many turns the action takes */
+};
+
+
+
+/* Free ThingAction * chain starting at "ta". */
+extern void free_thing_actions(struct ThingAction * ta);
+
+/* Return world.thing_actions ThingAction.id for "name". */
+extern uint8_t get_thing_action_id_by_name(char * name);
+
+/* Actor "t" does nothing. */
+extern void actor_wait(struct Thing * t);
+
+/* Actor "t" tries to move one step in direction described by char t->arg (where
+ * north-east is 'e', east 'd' etc.) Move either succeeds, or another actor is
+ * encountered and hit (which leads ot its lifepoint decreasing by one and
+ * eventually death), or the move fails due to an impassable target square. On
+ * success, update thing's field of view map.
+ */
+extern void actor_move(struct Thing * t);
+
+/* Actor "t" tries to drop from inventory thing indexed by number t->args. */
+extern void actor_drop(struct Thing * t);
+
+/* Actor "t" tries to pick up topmost thing from ground into its inventory. */
+extern void actor_pick(struct Thing * t);
+
+/* Actor "t" tries to use thing in inventory indexed by number t->args.
+ * (Currently the only valid use is consuming items defined as consumable.)
+ */
+extern void actor_use(struct Thing * t);
+
+
+
+#endif
diff --git a/src/server/things.c b/src/server/things.c
new file mode 100644 (file)
index 0000000..d5aff96
--- /dev/null
@@ -0,0 +1,186 @@
+/* src/server/things.c */
+
+#include "things.h"
+#include <stddef.h> /* NULL */
+#include <stdint.h> /* uint8_t, uint16_t, UINT16_MAX */
+#include <stdlib.h> /* free() */
+#include <string.h> /* memset(), strlen() */
+#include "../common/rexit.h" /* exit_err() */
+#include "../common/try_malloc.h" /* try_malloc() */
+#include "../common/yx_uint8.h" /* yx_uint8 struct */
+#include "map.h" /* is_passable() */
+#include "rrand.h" /* rrand() */
+#include "world.h" /* global world */
+#include "yx_uint8.h" /* yx_uint8_cmp() */
+
+
+
+/* Return pointer to thing of "id" in chain starting at "ptr". */
+static struct Thing * get_thing(struct Thing * ptr, uint8_t id);
+
+/* Add thing of "type" to map on passable position. Don't put actor on actor. */
+static void add_thing(uint8_t type);
+
+
+
+static struct Thing * get_thing(struct Thing * ptr, uint8_t id)
+{
+    while (1)
+    {
+        if (NULL == ptr || id == ptr->id)
+        {
+            return ptr;
+        }
+        struct Thing * owned_thing = get_thing(ptr->owns, id);
+        if (NULL != owned_thing)
+        {
+            return ptr;
+        }
+        ptr = ptr->next;
+    }
+}
+
+
+
+static void add_thing(uint8_t type)
+{
+    char * f_name = "add_thing()";
+    struct ThingType * tt = get_thing_type(type);
+    struct Thing *     t  = try_malloc(sizeof(struct Thing), f_name);
+    memset(t, 0, sizeof(struct Thing));
+    t->id         = world.thing_count++;
+    t->type       = tt->id;
+    t->lifepoints = tt->lifepoints;
+    char * err = "Space to put thing on too hard to find. Map too small?";
+    uint16_t i = 0;
+    while (1)
+    {
+        struct yx_uint8 pos;
+        for (pos.y = pos.x = 0; 0 == is_passable(pos); i++)
+        {
+            exit_err(UINT16_MAX == i, err);
+            pos.y = rrand() % world.map.length;
+            pos.x = rrand() % world.map.length;
+        }
+        struct Thing * t_ptr;
+        uint8_t clear = 1;
+        for (t_ptr = world.things; t_ptr != NULL; t_ptr = t_ptr->next)
+        {
+            if (yx_uint8_cmp(&pos, &t_ptr->pos) && 0 != t_ptr->lifepoints)
+            {
+                clear = 0;
+                break;
+            }
+        }
+        if (1 == clear)
+        {
+            t->pos = pos;
+            break;
+        }
+    }
+    struct Thing ** t_ptr_ptr = &world.things;
+    for (; NULL != * t_ptr_ptr; t_ptr_ptr = &(*t_ptr_ptr)->next);
+    * t_ptr_ptr = t;
+}
+
+
+
+extern void free_thing_types(struct ThingType * tt_start)
+{
+    if (NULL == tt_start)
+    {
+        return;
+    }
+    free_thing_types(tt_start->next);
+    free(tt_start->name);
+    free(tt_start);
+}
+
+
+
+extern void add_things(uint8_t type, uint8_t n)
+{
+    uint8_t i;
+    for (i = 0; i < n; i++)
+    {
+        add_thing(type);
+    }
+}
+
+
+
+extern void free_things(struct Thing * t_start)
+{
+    if (NULL == t_start)
+    {
+        return;
+    }
+    free_things(t_start->owns);
+    free_things(t_start->next);
+    free(t_start->fov_map);
+    free(t_start);
+    if (t_start == world.things)   /* So add_things()' NULL-delimited thing   */
+    {                              /* iteration loop does not iterate over    */
+        world.things = NULL;       /* freed memory when called the first time */
+    }                              /* after world re-seeding.                 */
+}
+
+
+
+extern void own_thing(struct Thing ** target, struct Thing ** source,
+                      uint8_t id)
+{
+    struct Thing * t;
+    if (id == (*source)->id)
+    {
+        t = * source;
+        * source = t->next;
+    }
+    else
+    {
+        struct Thing * penult = * source;
+        while (1)
+        {
+            if (id == penult->next->id)
+            {
+                break;
+            }
+            penult = penult->next;
+        }
+        t = penult->next;
+        penult->next = t->next;
+    }
+    struct Thing ** t_ptr_ptr = target;
+    for (; NULL != * t_ptr_ptr; t_ptr_ptr = &(*t_ptr_ptr)->next);
+    * t_ptr_ptr = t;
+    t->next = NULL;
+}
+
+
+
+extern struct Thing * get_player()
+{
+    return get_thing(world.things, 0);
+}
+
+
+
+extern struct ThingType * get_thing_type(uint8_t id)
+{
+    struct ThingType * tt = world.thing_types;
+    for (; NULL != tt && id != tt->id; tt = tt->next);
+    char * err_intro = "Requested thing type of unused ID ";
+    char err[strlen(err_intro) + 3 + 1 + 1];
+    sprintf(err, "%s%d.", err_intro, id);
+    exit_err(NULL == tt, err);
+    return tt;
+}
+
+
+
+extern void set_thing_position(struct Thing * t, struct yx_uint8 pos)
+{
+    t->pos = pos;
+    struct Thing * owned = t->owns;
+    for (; owned != NULL; set_thing_position(owned, pos), owned = owned->next);
+}
diff --git a/src/server/things.h b/src/server/things.h
new file mode 100644 (file)
index 0000000..3040d04
--- /dev/null
@@ -0,0 +1,69 @@
+/* src/server/things.h
+ *
+ * Structs for things and their type definitions, and routines to initialize
+ * these and load and save them from/to files.
+ */
+
+#ifndef THINGS_H
+#define THINGS_H
+
+#include <stdint.h> /* uint8_t */
+#include "../common/yx_uint8.h" /* yx_uint8 structs */
+
+
+
+struct Thing
+{
+    struct Thing * next;        /* pointer to next one in things chain */
+    struct Thing * owns;        /* chain of things owned / in inventory */
+    struct yx_uint8 pos;         /* coordinate on map */
+    uint8_t * fov_map;           /* map of the thing's field of view */
+    uint8_t id;                  /* individual thing's unique identifier */
+    uint8_t type;                /* ID of appropriate thing definition */
+    uint8_t lifepoints;          /* 0: thing is inanimate; >0: hitpoints */
+    uint8_t command;             /* thing's current action; 0 if none */
+    uint8_t arg;                 /* optional field for .command argument */
+    uint8_t progress;            /* turns already passed to realize .command */
+};
+
+struct ThingType
+{
+    uint8_t id;         /* thing type identifier / sets .type */
+    struct ThingType * next;
+    char char_on_map;   /* thing symbol to appear on map */
+    char * name;        /* string to describe thing in game log */
+    uint8_t corpse_id;  /* type to change thing into upon destruction */
+    uint8_t lifepoints; /* default start value for thing's .lifepoints */
+    uint8_t consumable; /* can be eaten if !0, for so much hitpoint win */
+    uint8_t start_n;    /* how many of these does the map start with? */
+};
+
+
+
+/* Free thing types chain starting at "tt_start". */
+extern void free_thing_types(struct ThingType * tt_start);
+
+/* Add thing(s) ("n": how many?) of "type" to map on random position(s). New
+ * animate things are never placed in the same square with other animate ones.
+ */
+extern void add_things(uint8_t type, uint8_t n);
+
+/* Free things in things chain starting at "t_start. */
+extern void free_things(struct Thing * t_start);
+
+/* Move thing of "id" from "source" inventory to "target" inventory. */
+extern void own_thing(struct Thing ** target, struct Thing ** source,
+                      uint8_t id);
+
+/* Get pointer to the Thing struct that represents the player. */
+extern struct Thing * get_player();
+
+/* Get pointer to the thing type of identifier "def_id". */
+extern struct ThingType * get_thing_type(uint8_t id);
+
+/* Move not only "t" to "pos", but also all things owned by it. */
+extern void set_thing_position(struct Thing * t, struct yx_uint8 pos);
+
+
+
+#endif
index 732c8107c231118d0966171d7877cf89524d30de..91a32a7cbf0d2e117f38a4121768b5c0a636eeec 100644 (file)
@@ -9,9 +9,9 @@
 #include <stdint.h> /* uint8_t, uint16_t, uint32_t */
 #include <stdio.h> /* define FILE */
 #include "../common/map.h" /* struct Map */
-struct MapObjDef;
-struct MapObjAct;
-struct MapObj;
+struct ThingType;
+struct ThingAction;
+struct Thing;
 
 
 
@@ -20,16 +20,16 @@ struct World
     FILE * file_in; /* Input stream on file at .path_in. */
     FILE * file_out; /* Output stream on file at .path_out. */
     struct Map map;
-    struct MapObjDef * map_obj_defs; /* Map object definitions. */
-    struct MapObjAct * map_obj_acts; /* Map object action definitions. */
-    struct MapObj * map_objs; /* Map objects. */
+    struct ThingType * thing_types; /* Thing type definitions. */
+    struct ThingAction * thing_actions; /* Thing action definitions. */
+    struct Thing * things; /* All physical things of the game world. */
     char * log; /* Logs the game events from the player's view. */
     char * server_test; /* String uniquely identifying server process. */
     char * path_in; /* File to write client messages into. */
     char * path_out; /* File to write server messages into. */
     char * path_worldstate; /* File to represent world state  to clients.*/
     char * path_record; /* Record file from which to read the game history. */
-    char * path_config; /* Path for map object (action) definitions file. */
+    char * path_config; /* Path for thing type / action definitions file. */
     char * tmp_suffix; /* Appended to paths of files for their tmp versions. */
     char * queue; /* Stores un-processed messages read from the input file. */
     uint32_t queue_size;/* Length of .queue sequence of \0-terminated strings.*/
@@ -37,9 +37,9 @@ struct World
     uint16_t replay; /* Turn up to which to replay game. No replay if zero. */
     uint16_t turn; /* Current game turn. */
     uint16_t last_update_turn; /* Last turn the .path_out file was updated. */
-    uint8_t player_type; /* Map object type that player will start as. */
+    uint8_t player_type; /* Thing type that player will start as. */
     uint8_t is_verbose; /* Should server send debugging info to stdout? */
-    uint8_t map_obj_count; /* Counts map objects generated so far. */
+    uint8_t thing_count; /* Counts things generated so far. */
     uint8_t enemy_fov; /* != 0 if non-player actors only see field of view. */
 };