summaryrefslogtreecommitdiff
path: root/saedit/action.c
diff options
context:
space:
mode:
Diffstat (limited to 'saedit/action.c')
-rw-r--r--saedit/action.c176
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);
+}