Mercurial > molko
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 } |