+extern void free_things_in_memory(struct ThingInMemory * tm)
+{
+ if (!tm)
+ {
+ return;
+ }
+ free_things_in_memory(tm->next);
+ free(tm);
+}
+
+
+
+extern struct ThingAction * get_thing_action(uint8_t id)
+{
+ struct ThingAction * ta = world.thing_actions;
+ for (; ta && id != ta->id; ta = ta->next);
+ return ta;
+}
+
+
+
+extern struct ThingType * get_thing_type(uint8_t id)
+{
+ struct ThingType * tt = world.thing_types;
+ for (; tt && id != tt->id; tt = tt->next);
+ return tt;
+}
+
+
+
+extern uint8_t get_thing_action_id_by_name(char * name)
+{
+ struct ThingAction * ta = world.thing_actions;
+ while (ta)
+ {
+ if (0 == strcmp(ta->name, name))
+ {
+ break;
+ }
+ ta = ta->next;
+ }
+ if (!ta)
+ {
+ return 0;
+ }
+ return ta->id;
+}
+
+
+
+extern struct Thing * get_thing(struct Thing * ptr, uint8_t id, uint8_t deep)
+{
+ while (1)
+ {
+ if (!ptr || id == ptr->id)
+ {
+ return ptr;
+ }
+ if (deep)
+ {
+ struct Thing * owned_thing = get_thing(ptr->owns, id, 1);
+ if (owned_thing)
+ {
+ return ptr;
+ }
+ }
+ ptr = ptr->next;
+ }
+}
+
+
+
+extern struct Thing * get_player()
+{
+ return get_thing(world.things, 0, 0);
+}
+
+
+
+extern void try_thing_proliferation(struct Thing * t)
+{
+ struct ThingType * tt = get_thing_type(t->type);
+ if (tt->proliferate)
+ {
+ if (1 == tt->proliferate || 1 == (rrand() % tt->proliferate))
+ {
+ struct yx_uint8 candidates[6];
+ uint8_t n_candidates = 0;
+ char dirs[7] = "cxswed";
+ struct yx_uint8 test = t->pos;
+ uint8_t i;
+ for (i = 0; i < strlen(dirs); i++)
+ {
+ if ( mv_yx_in_dir_legal(dirs[i], &test)
+ && cell_is_proliferable(test, t))
+ {
+ candidates[n_candidates] = test;
+ n_candidates++;
+ }
+ }
+ if (!n_candidates)
+ {
+ return;
+ }
+ i = rrand() % n_candidates;
+ add_thing(-1, tt->id, candidates[i].y, candidates[i].x);
+ }
+ }
+}
+
+
+
+extern void add_things(uint8_t type, uint8_t n)
+{
+ uint8_t i;
+ for (i = 0; i < n; i++)
+ {
+ struct yx_uint8 pos;
+ while (1)
+ {
+ char * err="Space to put thing on too hard to find. Map too small?";
+ uint16_t i_pos = 0;
+ for (pos.y = pos.x = 0;
+ '.' != world.map.cells[pos.y * world.map.length + pos.x];
+ i_pos++)
+ {
+ exit_err(UINT16_MAX == i_pos, err);
+ pos.y = rrand() % world.map.length;
+ pos.x = rrand() % world.map.length;
+ }
+ struct Thing * t;
+ uint8_t clear = 1;
+ for (t = world.things; t; t = t->next)
+ {
+ if (0 != t->lifepoints && pos.y==t->pos.y && pos.x==t->pos.x)
+ {
+ clear = 0;
+ break;
+ }
+ }
+ if (1 == clear)
+ {
+ break;
+ }
+ }
+ add_thing(-1, type, pos.y, pos.x);
+ }
+}
+
+
+