Mercurial > molko
comparison libmlk-adventure/adventure/action/chest.c @ 272:a49ae1b6ea4f
adventure: don't use plural in directories
author | David Demelier <markand@malikania.fr> |
---|---|
date | Sat, 12 Dec 2020 12:16:47 +0100 |
parents | libmlk-adventure/adventure/actions/chest.c@eadd3dbfa0af |
children | 87b8c7510717 |
comparison
equal
deleted
inserted
replaced
271:eadd3dbfa0af | 272:a49ae1b6ea4f |
---|---|
1 /* | |
2 * chest.c -- chest object | |
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 #include <string.h> | |
22 | |
23 #include <core/animation.h> | |
24 #include <core/event.h> | |
25 #include <core/maths.h> | |
26 #include <core/panic.h> | |
27 #include <core/save.h> | |
28 #include <core/sound.h> | |
29 #include <core/sprite.h> | |
30 | |
31 #include <rpg/map.h> | |
32 | |
33 #include "chest.h" | |
34 | |
35 #define X(c) ((c)->x - ((c)->map)->view_x) | |
36 #define Y(c) ((c)->y - ((c)->map)->view_y) | |
37 #define W(c) ((c)->animation.sprite->cellw) | |
38 #define H(c) ((c)->animation.sprite->cellh) | |
39 #define TOLERANCE (10) | |
40 | |
41 static bool | |
42 is_near(const struct chest *c) | |
43 { | |
44 const int x = c->x - c->map->player_sprite->cellw - TOLERANCE; | |
45 const int y = c->y - c->map->player_sprite->cellh - TOLERANCE; | |
46 const unsigned int w = W(c) + c->map->player_sprite->cellw + (TOLERANCE * 2); | |
47 const unsigned int h = H(c) + c->map->player_sprite->cellh + (TOLERANCE * 2); | |
48 | |
49 return maths_is_boxed(x, y, w, h, c->map->player_x, c->map->player_y); | |
50 } | |
51 | |
52 static void | |
53 invoke(struct chest *c) | |
54 { | |
55 c->state = CHEST_STATE_ANIMATE; | |
56 | |
57 animation_start(&c->animation); | |
58 | |
59 if (c->sound) | |
60 sound_play(c->sound, -1, 0); | |
61 } | |
62 | |
63 static void | |
64 handle(struct action *act, const union event *ev) | |
65 { | |
66 struct chest *c = act->data; | |
67 | |
68 if (!is_near(c) || c->state != CHEST_STATE_CLOSED) | |
69 return; | |
70 | |
71 switch (ev->type) { | |
72 case EVENT_KEYDOWN: | |
73 if (ev->key.key == KEY_ENTER) | |
74 invoke(c); | |
75 break; | |
76 case EVENT_CLICKDOWN: | |
77 if (maths_is_boxed(X(c), Y(c), W(c), H(c), ev->click.x, ev->click.y)) | |
78 invoke(c); | |
79 break; | |
80 default: | |
81 break; | |
82 } | |
83 } | |
84 | |
85 static bool | |
86 update(struct action *act, unsigned int ticks) | |
87 { | |
88 struct chest *c = act->data; | |
89 | |
90 if (c->state != CHEST_STATE_ANIMATE) | |
91 return false; | |
92 | |
93 if (animation_update(&c->animation, ticks)) { | |
94 c->state = CHEST_STATE_OPEN; | |
95 | |
96 if (c->exec) | |
97 c->exec(c); | |
98 } | |
99 | |
100 return false; | |
101 } | |
102 | |
103 static void | |
104 draw(struct action *act) | |
105 { | |
106 struct chest *c = act->data; | |
107 | |
108 switch (c->state) { | |
109 case CHEST_STATE_OPEN: | |
110 sprite_draw( | |
111 c->animation.sprite, | |
112 c->animation.sprite->nrows - 1, | |
113 c->animation.sprite->ncols - 1, | |
114 X(c), | |
115 Y(c) | |
116 ); | |
117 break; | |
118 case CHEST_STATE_ANIMATE: | |
119 animation_draw(&c->animation, X(c), Y(c)); | |
120 break; | |
121 default: | |
122 sprite_draw(c->animation.sprite, 0, 0, X(c), Y(c)); | |
123 break; | |
124 } | |
125 } | |
126 | |
127 void | |
128 chest_init(struct chest *c) | |
129 { | |
130 assert(c); | |
131 | |
132 if (c->save && c->property) { | |
133 if (!save_get_property(c->save, c->property)) | |
134 panic(); | |
135 | |
136 /* TODO: add an utility. */ | |
137 if (strcmp(c->property->value, "true") == 0) | |
138 c->state = CHEST_STATE_OPEN; | |
139 } | |
140 } | |
141 | |
142 struct action * | |
143 chest_action(struct chest *c) | |
144 { | |
145 assert(c); | |
146 | |
147 c->action.data = c; | |
148 c->action.handle = handle; | |
149 c->action.update = update; | |
150 c->action.draw = draw; | |
151 | |
152 return &c->action; | |
153 } |