comparison libmlk-rpg/rpg/battle-state-item.c @ 290:9948e288925b

rpg: add support for items in battle
author David Demelier <markand@malikania.fr>
date Fri, 08 Jan 2021 12:56:10 +0100
parents
children 5d8700074dd7
comparison
equal deleted inserted replaced
289:63d9fb56c609 290:9948e288925b
1 /*
2 * battle-state-item.c -- battle state (using item)
3 *
4 * Copyright (c) 2020 David Demelier <markand@malikania.fr>
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19 #include <assert.h>
20 #include <stdlib.h>
21
22 #include <core/alloc.h>
23 #include <core/panic.h>
24 #include <core/window.h>
25
26 #include <rpg/inventory.h>
27 #include <rpg/item.h>
28
29 #include <ui/align.h>
30 #include <ui/frame.h>
31 #include <ui/label.h>
32
33 #include "battle-entity-state.h"
34 #include "battle-state.h"
35 #include "battle.h"
36
37 enum substate {
38 SUBSTATE_ADVANCING,
39 SUBSTATE_MESSAGE,
40 SUBSTATE_RETURNING
41 };
42
43 struct msg {
44 struct frame frame;
45 struct label label;
46 unsigned int elapsed;
47 };
48
49 struct self {
50 enum substate substate;
51 struct msg msg;
52 struct battle_entity *source;
53 struct battle_entity *target;
54 struct battle_state state;
55 struct inventory_slot *slot;
56 int origin_x;
57 };
58
59 static bool
60 update(struct battle_state *st, struct battle *bt, unsigned int ticks)
61 {
62 struct self *self = st->data;
63
64 switch (self->substate) {
65 case SUBSTATE_ADVANCING:
66 /* Entity is updating from battle, so just inspect its status. */
67 if (battle_entity_update(self->source, 0)) {
68 self->substate = SUBSTATE_MESSAGE;
69 battle_entity_state_normal(self->source);
70 }
71 break;
72 case SUBSTATE_MESSAGE:
73 self->msg.elapsed += ticks;
74
75 if (self->msg.elapsed >= 2000) {
76 self->substate = SUBSTATE_RETURNING;
77 battle_entity_state_moving(self->source, self->origin_x, self->source->y);
78 }
79 break;
80 default:
81 if (battle_entity_update(self->source, 0)) {
82 battle_entity_state_normal(self->source);
83 battle_use(bt, self->slot->item, self->source->ch, self->target->ch);
84 }
85 break;
86 }
87
88 return false;
89 }
90
91 static void
92 draw(const struct battle_state *st, const struct battle *bt)
93 {
94 struct self *self = st->data;
95
96 if (self->substate == SUBSTATE_MESSAGE) {
97 frame_draw(&self->msg.frame);
98 label_draw(&self->msg.label);
99 }
100 }
101
102 static void
103 finish(struct battle_state *st, struct battle *bt)
104 {
105 (void)bt;
106
107 free(st->data);
108 }
109
110 void
111 battle_state_item(struct battle *bt,
112 struct character *source,
113 struct character *target,
114 struct inventory_slot *slot)
115 {
116 assert(bt);
117 assert(source);
118 assert(target);
119 assert(slot);
120
121 struct self *self;
122 unsigned int lw, lh;
123
124 if (!(self = alloc_new0(sizeof (*self))))
125 panic();
126
127 self->source = battle_find(bt, source);
128 self->target = battle_find(bt, target);
129 self->slot = slot;
130 self->origin_x = self->source->x;
131
132 /* Prepare message frame. */
133 self->msg.frame.w = window.w / 3;
134 self->msg.frame.h = window.h / 15;
135 self->msg.frame.theme = bt->theme;
136
137 align(ALIGN_TOP,
138 &self->msg.frame.x, &self->msg.frame.y, self->msg.frame.w, self->msg.frame.h,
139 0, 20, window.w, window.h);
140
141 /* Prepare message label box. */
142 self->msg.label.text = slot->item->name;
143 self->msg.label.flags = LABEL_FLAGS_SHADOW;
144 self->msg.label.theme = bt->theme;
145 label_query(&self->msg.label, &lw, &lh);
146
147 align(ALIGN_CENTER,
148 &self->msg.label.x, &self->msg.label.y, lw, lh,
149 self->msg.frame.x, self->msg.frame.y, self->msg.frame.w, self->msg.frame.h);
150
151 self->state.data = self;
152 self->state.update = update;
153 self->state.draw = draw;
154 self->state.finish = finish;
155
156 battle_entity_state_moving(self->source, self->origin_x - 100, self->source->y);
157 battle_switch(bt, &self->state);
158 }