💾 Archived View for thrig.me › blog › 2024 › 02 › 29 › animate.c captured on 2024-03-21 at 15:41:33.

View Raw

More Information

-=-=-=-=-=-=-

// animate - a different take on handling entities than ECS but still an
// integer energy system

#include "animate.h"

struct anivec *
ani_init(size_t count)
{
	struct anivec *av = malloc(sizeof(struct anivec));
	if (!av) abort();
	struct ani *el = calloc(count, sizeof(struct ani));
	if (!el) abort();
	av->count = count;
	av->entry = el;
	return av;
}

struct ani *
ani_create(struct anivec *av, int disp, int energy, ani_update func)
{
	size_t max = av->count;
	for (size_t i = 0; i < max; ++i) {
		if (!av->entry[i].alive) {
			struct ani *ep = &av->entry[i];
			ep->alive = ep->newbie = 1;
			ep->disp               = disp;
			ep->energy             = energy;
			ep->pos.xx = ep->pos.yy = 0;
			ep->update              = func;
			return ep;
		}
	}
	abort(); // whoops, no space left
}

void
ani_murder(struct ani *ep)
{
	ep->alive = 0;
	// they are new at being dead (has energy system ramifications)
	ep->newbie = 1;
}

void
anivec_update(struct anivec *av, size_t turn)
{
	size_t avcnt = av->count;
	int min      = INT_MAX;
	for (size_t i = 0; i < avcnt; ++i) {
		if (av->entry[i].alive && av->entry[i].energy < min)
			min = av->entry[i].energy;
	}
	assert(min < INT_MAX); // no animates or everything is dead??
	for (size_t i = 0; i < avcnt; ++i) {
		if (av->entry[i].alive ^ av->entry[i].newbie) {
			if (!(av->entry[i].energy -= min)) {
				int neweng =
				  av->entry[i].update(&av->entry[i], turn);
				assert(neweng > 0);
				av->entry[i].energy = neweng;
			}
		}
	}
	for (size_t i = 0; i < avcnt; ++i)
		av->entry[i].newbie = 0;
}