diff src/libmlk-rpg/rpg/battle-state-attacking.c @ 382:43d155668a55

rpg: expose battle state functions
author David Demelier <markand@malikania.fr>
date Sun, 13 Feb 2022 10:35:26 +0100
parents 460c78706989
children b944cd41e8f9
line wrap: on
line diff
--- a/src/libmlk-rpg/rpg/battle-state-attacking.c	Fri Jan 07 21:50:37 2022 +0100
+++ b/src/libmlk-rpg/rpg/battle-state-attacking.c	Sun Feb 13 10:35:26 2022 +0100
@@ -1,5 +1,5 @@
 /*
- * battle-state-attacking.h -- battle state (entity is moving for attacking)
+ * battle-state-attacking.c -- battle state (entity is moving for attacking)
  *
  * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr>
  *
@@ -25,33 +25,14 @@
 
 #include "battle.h"
 #include "battle-state.h"
+#include "battle-state-attacking.h"
+#include "battle-state-check.h"
 #include "battle-entity-state.h"
 #include "character.h"
 
-enum substate {
-	/* For team. */
-	SUBSTATE_ADVANCING,
-	SUBSTATE_ATTACKING,
-	SUBSTATE_RETURNING,
-
-	/* For enemies. */
-	SUBSTATE_BLINKING,
-};
-
-/*
- * This state is split into three parts:
- *
- * 1. entity walks a bit in front of its original position.
- * 2. entity animate itself while attacking.
- * 3. entity goes back to its original position.
- */
-struct data {
-	enum substate substate;
-	struct battle_entity *source;
-	struct battle_entity *target;
+struct self {
+	struct battle_state_attacking data;
 	struct battle_state state;
-	int origin_x;
-	int origin_y;
 };
 
 static void
@@ -71,43 +52,9 @@
 static int
 update(struct battle_state *st, struct battle *bt, unsigned int ticks)
 {
-	(void)bt;
 	(void)ticks;
 
-	struct data *data = st->data;
-
-	if (!battle_entity_update(data->source, 0))
-		return 0;
-
-	switch (data->substate) {
-	case SUBSTATE_ADVANCING:
-		/*
-		 * Current entity state is battle-entity-state-moving but it is
-		 * already updated from the game itself so pass 0 just to check
-		 * if it has finished moving.
-		 */
-		data->substate = SUBSTATE_ATTACKING;
-		/* TODO: determine sprite to use about equipment. */
-		battle_entity_state_attacking(data->source, data->source->ch->sprites[CHARACTER_SPRITE_SWORD]);
-		break;
-	case SUBSTATE_ATTACKING:
-		/* Move back to original position. */
-		data->substate = SUBSTATE_RETURNING;
-		damage(data->source, data->target, bt);
-		battle_entity_state_moving(data->source, data->origin_x, data->origin_y);
-		break;
-	case SUBSTATE_RETURNING:
-	case SUBSTATE_BLINKING:
-		/* Just wait. */
-		battle_entity_state_normal(data->source);
-		damage(data->source, data->target, bt);
-		battle_state_check(bt);
-		break;
-	default:
-		break;
-	}
-
-	return 0;
+	return battle_state_attacking_update(st->data, bt);
 }
 
 static void
@@ -119,36 +66,86 @@
 }
 
 void
-battle_state_attacking(struct battle *bt, struct character *source, struct character *target)
+battle_state_attacking_init(struct battle_state_attacking *atk,
+                            struct battle_entity *source,
+                            struct battle_entity *target)
 {
-	assert(bt);
+	assert(atk);
+	assert(source);
+	assert(target);
 
-	struct data *data;
 	int x, y;
 
-	if (!(data = alloc_new0(sizeof (*data))))
-		panic();
-
 	/* Starts this state with advancing. */
-	data->source = battle_find(bt, source);
-	data->target = battle_find(bt, target);
-	data->origin_x = data->source->x;
-	data->origin_y = data->source->y;
+	atk->source = source;
+	atk->target = target;
+	atk->origin_x = source->x;
+	atk->origin_y = source->y;
 
 	/* We go to the enemy. */
-	x = data->target->x + data->target->ch->sprites[CHARACTER_SPRITE_NORMAL]->cellw;
-	y = data->target->y;
+	x = target->x + target->ch->sprites[CHARACTER_SPRITE_NORMAL]->cellw;
+	y = target->y;
 
 	/* If it is an enemy we don't move it but blink instead. */
-	if (data->source->ch->exec) {
-		data->substate = SUBSTATE_BLINKING;
-		battle_entity_state_blinking(data->source);
+	if (source->ch->exec) {
+		atk->status = BATTLE_STATE_ATTACKING_BLINKING;
+		battle_entity_state_blinking(source);
 	} else
-		battle_entity_state_moving(data->source, x, y);
+		battle_entity_state_moving(source, x, y);
+}
+
+int
+battle_state_attacking_update(struct battle_state_attacking *atk, struct battle *bt)
+{
+	if (!battle_entity_update(atk->source, 0))
+		return 0;
+
+	switch (atk->status) {
+	case BATTLE_STATE_ATTACKING_ADVANCING:
+		/*
+		 * Current entity state is battle-entity-state-moving but it is
+		 * already updated from the game itself so pass 0 just to check
+		 * if it has finished moving.
+		 */
+		atk->status = BATTLE_STATE_ATTACKING_DAMAGING;
 
-	data->state.data = data;
-	data->state.update = update;
-	data->state.finish = finish;
+		/* TODO: determine sprite to use about equipment. */
+		battle_entity_state_attacking(atk->source, atk->source->ch->sprites[CHARACTER_SPRITE_SWORD]);
+		break;
+	case BATTLE_STATE_ATTACKING_DAMAGING:
+		/* Move back to original position. */
+		atk->status = BATTLE_STATE_ATTACKING_RETURNING;
+		damage(atk->source, atk->target, bt);
+		battle_entity_state_moving(atk->source, atk->origin_x, atk->origin_y);
+		break;
+	case BATTLE_STATE_ATTACKING_RETURNING:
+	case BATTLE_STATE_ATTACKING_BLINKING:
+		/* Just wait. */
+		battle_entity_state_normal(atk->source);
+		damage(atk->source, atk->target, bt);
+		battle_state_check(bt);
+		break;
+	default:
+		break;
+	}
 
-	battle_switch(bt, &data->state);
+	return 0;
 }
+
+void
+battle_state_attacking(struct battle_entity *source, struct battle_entity *target, struct battle *bt)
+{
+	assert(source);
+	assert(target);
+	assert(bt);
+
+	struct self *self;
+
+	self = alloc_new0(sizeof (*self));
+	self->state.data = self;
+	self->state.update = update;
+	self->state.finish = finish;
+
+	battle_state_attacking_init(&self->data, source, target);
+	battle_switch(bt, &self->state);
+}