diff options
author | culot <culot@FreeBSD.org> | 2018-07-27 11:22:11 +0200 |
---|---|---|
committer | culot <culot@FreeBSD.org> | 2018-07-27 11:22:11 +0200 |
commit | 2b3b9dc4649727851004b8223b6af38b57c0c790 (patch) | |
tree | 418867a8ac458e7b0a7fcaca90b551628a8e6810 /bricks.c | |
download | oldrunner-2b3b9dc4649727851004b8223b6af38b57c0c790.tar.gz |
oldrunner initial import
Diffstat (limited to 'bricks.c')
-rw-r--r-- | bricks.c | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/bricks.c b/bricks.c new file mode 100644 index 0000000..3060c21 --- /dev/null +++ b/bricks.c @@ -0,0 +1,169 @@ +/* $Id: bricks.c,v 1.1.1.1 2010/07/17 17:30:32 culot Exp $ */ + +/* + * Copyright (c) 2010 Frederic Culot <frederic@culot.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the + * following disclaimer in the documentation and/or other + * materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "oldrunner.h" + +#define BRICK_LATENCY (OLDRUNNER_TIMEOUT * 4) + +enum brick_state { + BRICK_SMALL_CRACK, + BRICK_LARGE_CRACK, + BRICK_BROKEN, + BRICK_COMEBACK_LARGE_CRACK, + BRICK_COMEBACK_SMALL_CRACK, + BRICK_REBUILT, + BRICK_STATES +}; + +struct brick { + enum brick_state state; + struct timer timer; + struct coord pos; + SLIST_ENTRY(brick) bricksp; +}; + +SLIST_HEAD(, brick) bricks; + +void +bricks_init (void) +{ + SLIST_INIT (&bricks); +} + +void +bricks_free (void) +{ + while (!SLIST_EMPTY (&bricks)) + { + struct brick *b; + + b = SLIST_FIRST (&bricks); + SLIST_REMOVE_HEAD (&bricks, bricksp); + xfree (b); + } +} + +void +bricks_break (const struct coord *pos) +{ + struct brick *b; + + b = xmalloc (sizeof *b); + coord_set_yx (&b->pos, pos->y, pos->x); + b->state = BRICK_SMALL_CRACK; + timer_start (&b->timer); + SLIST_INSERT_HEAD (&bricks, b, bricksp); +} + +static void +draw_brick (const struct coord *pos, enum brick_state state) +{ + switch (state) + { + case BRICK_SMALL_CRACK: + case BRICK_COMEBACK_SMALL_CRACK: + gfx_show_sprite (SP_BRICK_SCRACK, pos); + break; + case BRICK_LARGE_CRACK: + case BRICK_COMEBACK_LARGE_CRACK: + gfx_show_sprite (SP_BRICK_LCRACK, pos); + break; + case BRICK_BROKEN: + if (hero_at_pos (pos)) + gfx_show_sprite (SP_HERO, pos); + else if (foes_at_pos (pos)) + gfx_show_sprite (SP_FOE, pos); + else + gfx_show_sprite (SP_BRICK_BROKEN, pos); + break; + case BRICK_REBUILT: + gfx_show_sprite (SP_BRICK, pos); + break; + default: + return; + /* NOTREACHED */ + } +} + +void +bricks_draw (void) +{ + struct brick *b; + + SLIST_FOREACH (b, &bricks, bricksp) + draw_brick (&b->pos, b->state); +} + +unsigned +bricks_broken_at (const struct coord *pos) +{ + struct brick *b; + + SLIST_FOREACH (b, &bricks, bricksp) + { + if (b->state == BRICK_BROKEN && coord_equal (&b->pos, pos)) + return 1; + } + + return 0; +} + +void +bricks_update (void) +{ + struct brick *b; + struct timer now; + + timer_get_time (&now); + SLIST_FOREACH (b, &bricks, bricksp) + { + double difftot; + + difftot = timer_diff (&now, &b->timer); + if (difftot > BRICK_LATENCY) + { + timer_set (&now, &b->timer); + b->state++; + if (b->state == BRICK_BROKEN) + { + hero_dig_done (); + timer_add (&b->timer, BRICK_COMEBACK_TIME); + } + else if (b->state > BRICK_REBUILT) + { + foes_wallup_at (&b->pos); + if (!hero_wallup_at (&b->pos)) + SLIST_REMOVE (&bricks, b, brick, bricksp); + } + } + } +} |