diff options
Diffstat (limited to 'saedit/action.c')
-rw-r--r-- | saedit/action.c | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/saedit/action.c b/saedit/action.c new file mode 100644 index 0000000..a9b31e2 --- /dev/null +++ b/saedit/action.c @@ -0,0 +1,176 @@ +#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); +} |