summaryrefslogblamecommitdiff
path: root/saedit/action.c
blob: a9b31e22e209bb18ceae701aec232b182cb5f194 (plain) (tree)















































































































































































                                                                              
#include "action.h"
#include "animation.h"
#include "imageset.h"
#include "context.h"

Action *
action_new (
	const SpriteContext *context,
	const XMLNode *node, 
	gint included_from
) {
	Action *action;
	GList  *list;
	gchar  *imgset_name;
	gboolean fail = FALSE;
	Imageset *imageset;

	g_return_val_if_fail (g_strcmp0 (node->name, "action") == 0, NULL);
	
	action = (Action *) g_new0 (Action, 1);

	action->name = xml_node_get_attr_value (node, "name");
	if (action->name == NULL) {
		/* TODO: report error */
		fail = TRUE;
	}

	imgset_name = xml_node_get_attr_value (node, "imageset");
	if (imgset_name == NULL) {
		/* TODO: report error */
		fail = TRUE;
	} else {
		imageset = sprite_context_get_imageset (context, imgset_name);
		if (imageset == NULL) {
			/* TODO: report error */
			fail = TRUE;
		}
	}

	if (fail) {
		g_free (action);
		return NULL;
	}

	action->hp = xml_node_get_int_attr_value (node, "hp", 100);

	list = node->sub_nodes;
	while (list != NULL) {
		XMLNode *current = (XMLNode *) list->data;
		
		if (g_strcmp0 (current->name, "animation") == 0) {
			action_add_animation (
				action,
				imageset,
				current,
				included_from
			);
		} else {
			/* TODO: action contains something unknown */
		}

		list = g_list_next (list);
	}

	return action;
}

void
action_add_animation (
	Action *action,
	const Imageset *imageset,
	const XMLNode *node,
	gint included_from
) {
	Animation *animation;

	g_return_if_fail (g_strcmp0 (node->name, "animation") == 0);

	animation = animation_new (imageset, node, included_from);
	if (animation == NULL)
		return;

	if (g_list_find_custom (
		action->animations, animation,
		(GCompareFunc) animation_compare_by_direction) != NULL
	) {
		animation_free (animation);
		return;
	}

	action->animations = g_list_append (action->animations, animation);
}

void
action_free (Action *action) {
	g_list_free_full (
		action->animations,
		(GDestroyNotify) animation_free
	);

	g_free (action->name);
	g_free (action);
}

gint
action_compare_by_hp_and_name (
	const Action *first,
	const Action *second
) {
	if (first->hp != second->hp) {
		return first->hp - second->hp;
	}
	return g_strcmp0 (first->name, second->name);
}

gboolean
action_hp_and_name_equals (
	const Action *action,
	gint hp,
	const gchar *name
) {
	return
		action->hp == hp &&
		g_strcmp0 (action->name, name) == 0;
}

const Animation *
action_get_animation (
	const Action *action,
	const gchar *direction
) {
	GList *animation = action->animations;
	g_return_val_if_fail (animation != NULL, NULL);
	
	while (direction != NULL && animation != NULL) {
		Animation *current = (Animation *) animation->data;
		g_assert (current != NULL);
		if (animation_direction_equals (current, direction))
			return current;
		
		animation = g_list_next (animation);
	}

	return (Animation *) action->animations->data;
}

void
action_get_hp_and_name (
	const Action *action,
	gint *hp,
	gchar **name
) {
	if (hp != NULL)
		*hp = action->hp;
	if (name != NULL)
		*name = action->name;
}

GList *
action_get_directions (const Action *action) {
	GList *result = NULL;
	GList *animations = action->animations;

	while (animations != NULL) {
		Animation *animation = (Animation *) animations->data;
		result = g_list_append (result, animation->direction);
		animations = g_list_next (animations);
	}

	return result;
}

gchar *
get_action_id (gint hp, const gchar *name) {
	return g_strdup_printf ("%d:%s", hp, name);
}