diff options
Diffstat (limited to 'hero.c')
-rw-r--r-- | hero.c | 188 |
1 files changed, 188 insertions, 0 deletions
@@ -0,0 +1,188 @@ +/* $Id: hero.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" + +struct hero { + struct coord pos, initpos; + int state; +}; + +static struct hero hero; + +void +hero_init (void) +{ + hero.state = STATE_ALIVE; + hero_draw (); + usr_reset_input (); +} + +void +hero_draw (void) +{ + gfx_show_sprite (SP_HERO, &hero.pos); +} + +void +hero_set_pos (const struct coord *pos) +{ + coord_set_yx (&hero.pos, pos->y, pos->x); + if (hero.pos.y < 0) + lvl_won (); +} + +void +hero_set_initpos (const struct coord *pos) +{ + coord_set_yx (&hero.initpos, pos->y, pos->x); +} + +void +hero_get_pos (struct coord *pos) +{ + coord_set_yx (pos, hero.pos.y, hero.pos.x); +} + +void +hero_get_initpos (struct coord *pos) +{ + coord_set_yx (pos, hero.initpos.y, hero.initpos.x); +} + +unsigned +hero_at_pos (const struct coord *pos) +{ + if (coord_equal (&hero.pos, pos)) + return 1; + return 0; +} + +void +check_collisions (const struct coord *hero_pos) +{ + if (lvl_got_hole_below (hero_pos)) + { + struct coord below; + + hero_trapped (); + coord_below (hero_pos, &below); + gfx_move_sprite (SP_HERO, hero_pos, &below); + hero_set_pos (&below); + } + else + { + if (foes_at_pos (hero_pos)) + hero_die (); + money_check_at (hero_pos); + if (money_all_collected ()) + lvl_draw_escape_ladder (); + } +} + +void +hero_move (enum move move) +{ + struct coord orig, dest; + + /* First check if the move is valid with regards to current player state. */ + if (hero.state & STATE_DIGGING) + return; + + if ((hero.state & STATE_FALLING) && (move != MOV_FALL)) + move = MOV_FALL; + + /* Then check if the move is valid with regards to the level layout. */ + hero_get_pos (&orig); + if (!lvl_valid_move (&orig, move, &dest, SP_HERO)) + { + if (hero.state & STATE_FALLING) + hero.state &= ~STATE_FALLING; + return; + } + else + hero_set_pos (&dest); + + if (move == MOV_FALL || lvl_nothing_below (&hero.pos)) + hero.state |= STATE_FALLING; + + gfx_move_sprite (SP_HERO, &orig, &hero.pos); + check_collisions (&hero.pos); +} + +void +hero_dig (enum move dir) +{ + struct coord heropos, digpos; + + hero_get_pos (&heropos); + coord_set_yx (&digpos, + heropos.y + 1, heropos.x + (dir == MOV_RIGHT ? 1 : -1)); + if (lvl_valid_dig (&digpos)) + { + hero.state |= STATE_DIGGING; + bricks_break (&digpos); + } +} + +void +hero_dig_done (void) +{ + hero.state &= ~STATE_DIGGING; +} + +void +hero_trapped (void) +{ + hero.state |= STATE_TRAPPED | STATE_FALLING; + usr_reset_input (); +} + +void +hero_die (void) +{ + gfx_alert (); + game_lives_dec (); + lvl_lost (); +} + +unsigned +hero_wallup_at (const struct coord *pos) +{ + if (coord_equal (pos, &hero.pos)) + { + hero_die (); + return 1; + } + + return 0; +} |