void drawvision(int x, int y) { static int oldx = -1,oldy = -1; int i,j,c; if (Current_Environment != E_COUNTRYSIDE) { if (Player.status[BLINDED]) { drawspot(oldx,oldy); drawspot(x,y); drawplayer(); } else { if (Player.status[ILLUMINATION] > 0) { for (i= -2;i<3;i++) for (j= -2;j<3;j++) if (inbounds(x+i,y+j)) if (view_los_p(x+i,y+j,Player.x,Player.y)) dodrawspot(x+i,y+j); } else { for (i= -1;i<2;i++) for (j= -1;j<2;j++) if (inbounds(x+i,y+j)) dodrawspot(x+i,y+j); } drawplayer(); drawmonsters(FALSE); /* erase all monsters */ drawmonsters(TRUE); /* draw those now visible */ } if ((! gamestatusp(FAST_MOVE)) || (! optionp(JUMPMOVE))) omshowcursor(Player.x,Player.y); oldx = x; oldy = y; } else { for (i= -1;i<2;i++) for (j= -1;j<2;j++) if (inbounds(x+i,y+j)) { c_set(x+i, y+j, SEEN); if (!offscreen(x+i,y+j)) { wmove(Levelw,screenmody(y+j),screenmodx(x+i)); c = Country[x+i][y+j].current_terrain_type; if (optionp(SHOW_COLOUR)) wattrset(Levelw, CHARATTR(c)); waddch(Levelw,(c&0xff)); } } drawplayer(); omshowcursor(Player.x,Player.y); } }
/* * turn_player: * Change the direction the player is facing */ static void turn_player(PLAYER *pp, int dir) { if (pp->p_face != dir) { pp->p_face = dir; drawplayer(pp, true); } }
/* * face: * Change the direction the player is facing */ static void face(PLAYER *pp, int dir) { if (pp->p_face != dir) { pp->p_face = dir; drawplayer(pp, TRUE); } }
static void redraw_all(void) { uint8_t i; clear(); for (i = 0; i < MAP_H; i++) { moveto(2 + i, left); write(1, map.map[i], MAP_W); } drawplayer(); }
void screencheck(int x, int y) { int change = 0; #ifdef CENTER_ON_PLAYER change = 1; ScreenOffset = y - (ScreenLength/2); ScreenXOffset = x - (ScreenWidth/2); #else #if 0 int width = 0; #endif if (((y-ScreenOffset) < (ScreenLength/8)) || ((y-ScreenOffset) > (7*ScreenLength/8))) { change = 1; ScreenOffset = y - (ScreenLength/2); } if (((x-ScreenXOffset) < (ScreenWidth/8)) || ((x-ScreenXOffset) > (7*ScreenWidth/8))) { #if 0 if ( Current_Environment == E_COUNTRYSIDE ) width = COUNTRY_WIDTH; else width = Level->level_width; /* PGM: this code prevents scrolling when near the right edge of the level, but this unfortunately results in a badly placed view when, for examples, restoring a save near the edge of a level. Ideas on fixing this, or moving it, appreciated. PGM July 1999. */ if ( ( (x-ScreenXOffset) + (7*ScreenWidth/8) ) < width +( ScreenWidth/8 ) ) #endif { change = 1; ScreenXOffset = x - (ScreenWidth/2); if (ScreenXOffset < 0) ScreenXOffset = 0; } } #endif if ( change == 1 ) { show_screen(); if (Current_Environment != E_COUNTRYSIDE) drawmonsters(TRUE); if (!offscreen(Player.x,Player.y)) drawplayer(); } }
void screencheck(int y) { if (((y-ScreenOffset) < (ScreenLength/8)) || ((y-ScreenOffset) > (7*ScreenLength/8))) { ScreenOffset = y - (ScreenLength/2); show_screen(); if (Current_Environment != E_COUNTRYSIDE) drawmonsters(TRUE); if (!offscreen(Player.x,Player.y)) drawplayer(); } }
static void move(uint8_t dir) { int8_t *dp; uint8_t ny, nx, n; dp = delta[dir]; ny = map.py + *dp; nx = map.px + dp[1]; n = map.map[ny][nx]; if (n == MAP_WALL) return; if (n == MAP_BLOCK || n == MAP_BLOCK_ON) { uint8_t by = ny + *dp; uint8_t bx = nx + dp[1]; uint8_t m = map.map[by][bx]; if (m == MAP_WALL || m == MAP_BLOCK || m == MAP_BLOCK_ON) return; /* Adjust count of blocks positioned */ if (map.map[by][bx] == MAP_TARGET) { draw(by, bx, MAP_BLOCK_ON); map.done++; } else draw(by, bx, MAP_BLOCK); /* Move on the map */ map.map[by][bx] = MAP_BLOCK; map.map[ny][nx] = fixup(base_map.map[ny][nx]); if (map.map[ny][nx] == MAP_TARGET) map.done--; /* We don't need to redraw dy dx as we will put the player on it */ dir |= BLOCK_MOVED; /* For undo */ } draw(map.py, map.px, map.map[map.py][map.px]); map.py += *dp; map.px += *++dp; drawplayer(); moves++; if (undop == MAX_UNDO) { memmove(undolist, undolist + 1, MAX_UNDO - 1); undop--; } undolist[undop++] = dir; }
void drawanimatedplayer() { /* Gestion du timer */ // Si notre timer (un compte à rebours en fait) arrive à zéro if (player.frameTimer <= 0) { //On le réinitialise player.frameTimer = TIME_BETWEEN_2_FRAMES; //Et on incrémente notre variable qui compte les frames de 1 pour passer à la suivante player.frameNumber++; //Mais si on dépasse la frame max, il faut revenir à la première //Pour connaître la frame max, il suffit de diviser la longueur du spritesheet //par la longueur de notre héros : 480 / 40 = 12 frames //Puisque la première frame est la numéro 0, la dernière est donc la numéro 11 if(player.frameNumber >= player.sprite->w / PLAYER_WIDTH) player.frameNumber = 0; } //Sinon, on décrémente notre timer else player.frameTimer--; //Ensuite, on peut passer la main à notre fonction drawplayer(); }
/* * move_player: * Execute a move in the given direction */ static void move_player(PLAYER *pp, int dir) { PLAYER *newp; int x, y; bool moved; BULLET *bp; y = pp->p_y; x = pp->p_x; switch (dir) { case LEFTS: x--; break; case RIGHT: x++; break; case ABOVE: y--; break; case BELOW: y++; break; } moved = false; switch (Maze[y][x]) { case SPACE: #ifdef RANDOM case DOOR: #endif moved = true; break; case WALL1: case WALL2: case WALL3: #ifdef REFLECT case WALL4: case WALL5: #endif break; case MINE: case GMINE: if (dir == pp->p_face) pickup(pp, y, x, 2, Maze[y][x]); else if (opposite(dir, pp->p_face)) pickup(pp, y, x, 95, Maze[y][x]); else pickup(pp, y, x, 50, Maze[y][x]); Maze[y][x] = SPACE; moved = true; break; case SHOT: case GRENADE: case SATCHEL: case BOMB: #ifdef OOZE case SLIME: #endif #ifdef DRONE case DSHOT: #endif bp = is_bullet(y, x); if (bp != NULL) bp->b_expl = true; Maze[y][x] = SPACE; moved = true; break; case LEFTS: case RIGHT: case ABOVE: case BELOW: if (dir != pp->p_face) sendcom(pp, BELL); else { newp = play_at(y, x); checkdam(newp, pp, pp->p_ident, STABDAM, KNIFE); } break; #ifdef FLY case FLYER: newp = play_at(y, x); message(newp, "Oooh, there's a short guy waving at you!"); message(pp, "You couldn't quite reach him!"); break; #endif #ifdef BOOTS case BOOT: case BOOT_PAIR: if (Maze[y][x] == BOOT) pp->p_nboots++; else pp->p_nboots += 2; for (newp = Boot; newp < &Boot[NBOOTS]; newp++) { if (newp->p_flying < 0) continue; if (newp->p_y == y && newp->p_x == x) { newp->p_flying = -1; if (newp->p_undershot) fixshots(y, x, newp->p_over); } } if (pp->p_nboots == 2) message(pp, "Wow! A pair of boots!"); else message(pp, "You can hobble around on one boot."); Maze[y][x] = SPACE; moved = true; break; #endif } if (moved) { if (pp->p_ncshot > 0) if (--pp->p_ncshot == MAXNCSHOT) { cgoto(pp, STAT_GUN_ROW, STAT_VALUE_COL); outstr(pp, " ok", 3); } if (pp->p_undershot) { fixshots(pp->p_y, pp->p_x, pp->p_over); pp->p_undershot = false; } drawplayer(pp, false); pp->p_over = Maze[y][x]; pp->p_y = y; pp->p_x = x; drawplayer(pp, true); } }
/* * zap: * Kill off a player and take them out of the game. * The 'was_player' flag indicates that the player was not * a monitor and needs extra cleaning up. */ static void zap(PLAYER *pp, FLAG was_player) { int len; BULLET *bp; PLAYER *np; int x, y; int savefd; if (was_player) { /* If they died from a shot, clean up shrapnel */ if (pp->p_undershot) fixshots(pp->p_y, pp->p_x, pp->p_over); /* Let the player see their last position: */ drawplayer(pp, FALSE); /* Remove from game: */ Nplayer--; } /* Display the cause of death in the centre of the screen: */ len = strlen(pp->p_death); x = (WIDTH - len) / 2; outyx(pp, HEIGHT / 2, x, "%s", pp->p_death); /* Put some horizontal lines around and below the death message: */ memset(pp->p_death + 1, '-', len - 2); pp->p_death[0] = '+'; pp->p_death[len - 1] = '+'; outyx(pp, HEIGHT / 2 - 1, x, "%s", pp->p_death); outyx(pp, HEIGHT / 2 + 1, x, "%s", pp->p_death); /* Move to bottom left */ cgoto(pp, HEIGHT, 0); savefd = pp->p_fd; if (was_player) { int expl_charge; int expl_type; int ammo_exploding; /* Check all the bullets: */ for (bp = Bullets; bp != NULL; bp = bp->b_next) { if (bp->b_owner == pp) /* Zapped players can't own bullets: */ bp->b_owner = NULL; if (bp->b_x == pp->p_x && bp->b_y == pp->p_y) /* Bullets over the player are now over air: */ bp->b_over = SPACE; } /* Explode a random fraction of the player's ammo: */ ammo_exploding = rand_num(pp->p_ammo); /* Determine the type and amount of detonation: */ expl_charge = rand_num(ammo_exploding + 1); if (pp->p_ammo == 0) /* Ignore the no-ammo case: */ expl_charge = expl_type = 0; else if (ammo_exploding >= pp->p_ammo - 1) { /* Maximal explosions always appear as slime: */ expl_charge = pp->p_ammo; expl_type = SLIME; } else { /* * Figure out the best effective explosion * type to use, given the amount of charge */ int btype, stype; for (btype = MAXBOMB - 1; btype > 0; btype--) if (expl_charge >= shot_req[btype]) break; for (stype = MAXSLIME - 1; stype > 0; stype--) if (expl_charge >= slime_req[stype]) break; /* Pick the larger of the bomb or slime: */ if (btype >= 0 && stype >= 0) { if (shot_req[btype] > slime_req[btype]) btype = -1; } if (btype >= 0) { expl_type = shot_type[btype]; expl_charge = shot_req[btype]; } else expl_type = SLIME; } if (expl_charge > 0) { char buf[BUFSIZ]; /* Detonate: */ (void) add_shot(expl_type, pp->p_y, pp->p_x, pp->p_face, expl_charge, NULL, TRUE, SPACE); /* Explain what the explosion is about. */ snprintf(buf, sizeof buf, "%s detonated.", pp->p_ident->i_name); message(ALL_PLAYERS, buf); while (pp->p_nboots-- > 0) { /* Throw one of the boots away: */ for (np = Boot; np < &Boot[NBOOTS]; np++) if (np->p_flying < 0) break; #ifdef DIAGNOSTIC if (np >= &Boot[NBOOTS]) err(1, "Too many boots"); #endif /* Start the boots from where the player is */ np->p_undershot = FALSE; np->p_x = pp->p_x; np->p_y = pp->p_y; /* Throw for up to 20 steps */ np->p_flying = rand_num(20); np->p_flyx = 2 * rand_num(6) - 5; np->p_flyy = 2 * rand_num(6) - 5; np->p_over = SPACE; np->p_face = BOOT; showexpl(np->p_y, np->p_x, BOOT); } } /* No explosion. Leave the player's boots behind. */ else if (pp->p_nboots > 0) { if (pp->p_nboots == 2) Maze[pp->p_y][pp->p_x] = BOOT_PAIR; else Maze[pp->p_y][pp->p_x] = BOOT; if (pp->p_undershot) fixshots(pp->p_y, pp->p_x, Maze[pp->p_y][pp->p_x]); } /* Any unexploded ammo builds up in the volcano: */ volcano += pp->p_ammo - expl_charge; /* Volcano eruption: */ if (conf_volcano && rand_num(100) < volcano / conf_volcano_max) { /* Erupt near the middle of the map */ do { x = rand_num(WIDTH / 2) + WIDTH / 4; y = rand_num(HEIGHT / 2) + HEIGHT / 4; } while (Maze[y][x] != SPACE); /* Convert volcano charge into lava: */ (void) add_shot(LAVA, y, x, LEFTS, volcano, NULL, TRUE, SPACE); volcano = 0; /* Tell eveyone what's happening */ message(ALL_PLAYERS, "Volcano eruption."); } /* Drone: */ if (conf_drone && rand_num(100) < 2) { /* Find a starting place near the middle of the map: */ do { x = rand_num(WIDTH / 2) + WIDTH / 4; y = rand_num(HEIGHT / 2) + HEIGHT / 4; } while (Maze[y][x] != SPACE); /* Start the drone going: */ add_shot(DSHOT, y, x, rand_dir(), shot_req[conf_mindshot + rand_num(MAXBOMB - conf_mindshot)], NULL, FALSE, SPACE); } /* Tell the zapped player's client to shut down. */ sendcom(pp, ENDWIN, ' '); (void) fclose(pp->p_output); /* Close up the gap in the Player array: */ End_player--; if (pp != End_player) { /* Move the last player into the gap: */ memcpy(pp, End_player, sizeof *pp); outyx(ALL_PLAYERS, STAT_PLAY_ROW + 1 + (pp - Player), STAT_NAME_COL, "%5.2f%c%-10.10s %c", pp->p_ident->i_score, stat_char(pp), pp->p_ident->i_name, pp->p_ident->i_team); } /* Erase the last player from the display: */ cgoto(ALL_PLAYERS, STAT_PLAY_ROW + 1 + Nplayer, STAT_NAME_COL); ce(ALL_PLAYERS); } else { /* Zap a monitor */ /* Close the session: */ sendcom(pp, ENDWIN, LAST_PLAYER); (void) fclose(pp->p_output); /* shuffle the monitor table */ End_monitor--; if (pp != End_monitor) { memcpy(pp, End_monitor, sizeof *pp); outyx(ALL_PLAYERS, STAT_MON_ROW + 1 + (pp - Player), STAT_NAME_COL, "%5.5s %-10.10s %c", " ", pp->p_ident->i_name, pp->p_ident->i_team); } /* Erase the last monitor in the list */ cgoto(ALL_PLAYERS, STAT_MON_ROW + 1 + (End_monitor - Monitor), STAT_NAME_COL); ce(ALL_PLAYERS); } /* Update the file descriptor sets used by select: */ FD_CLR(savefd, &Fds_mask); if (Num_fds == savefd + 1) { Num_fds = Socket; if (Server_socket > Socket) Num_fds = Server_socket; for (np = Player; np < End_player; np++) if (np->p_fd > Num_fds) Num_fds = np->p_fd; for (np = Monitor; np < End_monitor; np++) if (np->p_fd > Num_fds) Num_fds = np->p_fd; Num_fds++; } }
void main() { if(InitGraphics() == -1) return; initialisedata(); clearviewport(); rectangle(0,0,(maxx+1)*width+2, (maxy+1)*width+2); sx = (maxx+1)*width+6; sy = (maxy+1)*width+2; int loop = 0; while(!endgame) { loop++; for (int i = 0; i < NUM_PLAYERS; i++) { drawplayer(plist[i]); } showscoreboard(); delay(DELAY_INTERVAL); for (i = 0; i < NUM_PLAYERS; i++) { showbox(plist[i]); } if (kbhit()) { handlekeypress(); } if (endgame) break; // 1 to n is computer plaer, 0 is me for (i = 1; i < NUM_PLAYERS; i++) { decidemove(plist[i]); } for (i = 0; i < NUM_PLAYERS; i++) { adjustdir(plist[i]); moveit(plist[i]); } for (i = 0; i < NUM_PLAYERS; i++) { updatescore(plist[i]); if (plist[i].score >= WINNING_SCORE) { endgame = true; setfillstyle(1, BLUE); bar(200,120,439,300); outtextxy(250,200,"GAME OVER"); if (i == 0) { outtextxy(250,250,"YOU WIN"); } else { outtextxy(250,250,"YOU LOSE"); } showscoreboard(); char tr = getch(); } } } }
/** * Initializes a player status. * @param[out] newpp The new player to initialize. * @param[in] enter_status The enter mode of a player. * [PSR] */ void stplayer(PLAYER *newpp, int enter_status) { int x, y; PLAYER *pp; nplayer++; for (y = 0; y < UBOUND; y++) { for (x = 0; x < WIDTH; x++) { newpp->p_maze[y][x] = maze[y][x]; } } for (; y < DBOUND; y++) { for (x = 0; x < LBOUND; x++) { newpp->p_maze[y][x] = maze[y][x]; } for (; x < RBOUND; x++) { newpp->p_maze[y][x] = SPACE; } for (; x < WIDTH; x++) { newpp->p_maze[y][x] = maze[y][x]; } } for (; y < HEIGHT; y++) { for (x = 0; x < WIDTH; x++) { newpp->p_maze[y][x] = maze[y][x]; } } do { x = rand_num(WIDTH - 1) + 1; y = rand_num(HEIGHT - 1) + 1; } while (maze[y][x] != SPACE); newpp->p_over = SPACE; newpp->p_x = x; newpp->p_y = y; newpp->p_undershot = false; # ifdef FLY if (enter_status == Q_FLY) { newpp->p_flying = rand_num(20); newpp->p_flyx = 2 * rand_num(6) - 5; newpp->p_flyy = 2 * rand_num(6) - 5; newpp->p_face = FLYER; } else # endif { # ifdef FLY newpp->p_flying = -1; # endif newpp->p_face = rand_dir(); } newpp->p_damage = 0; newpp->p_damcap = MAXDAM; newpp->p_nchar = 0; newpp->p_ncount = 0; newpp->p_nexec = 0; newpp->p_ammo = ISHOTS; # ifdef BOOTS newpp->p_nboots = 0; # endif if (enter_status == Q_SCAN) { newpp->p_scan = SCANLEN; newpp->p_cloak = 0; } else { newpp->p_scan = 0; newpp->p_cloak = CLOAKLEN; } newpp->p_ncshot = 0; do { x = rand_num(WIDTH - 1) + 1; y = rand_num(HEIGHT - 1) + 1; } while (maze[y][x] != SPACE); maze[y][x] = GMINE; # ifdef MONITOR for (pp = monitor; pp < end_monitor; pp++) { check(pp, y, x); } # endif do { x = rand_num(WIDTH - 1) + 1; y = rand_num(HEIGHT - 1) + 1; } while (maze[y][x] != SPACE); maze[y][x] = MINE; # ifdef MONITOR for (pp = monitor; pp < end_monitor; pp++) { check(pp, y, x); } # endif (void) sprintf(gen_buf, "%5.2f%c%-10.10s %c", newpp->p_ident->i_score, stat_char(newpp), newpp->p_ident->i_name, newpp->p_ident->i_team); y = STAT_PLAY_ROW + 1 + (newpp - player); for (pp = player; pp < end_player; pp++) { if (pp != newpp) { char smallbuf[10]; pp->p_ammo += NSHOTS; newpp->p_ammo += NSHOTS; cgoto(pp, y, STAT_NAME_COL); outstr(pp, gen_buf, STAT_NAME_LEN); (void) sprintf(smallbuf, "%3d", pp->p_ammo); cgoto(pp, STAT_AMMO_ROW, STAT_VALUE_COL); outstr(pp, smallbuf, 3); } } # ifdef MONITOR for (pp = monitor; pp < end_monitor; pp++) { cgoto(pp, y, STAT_NAME_COL); outstr(pp, gen_buf, STAT_NAME_LEN); } # endif drawmaze(newpp); drawplayer(newpp, true); look(newpp); # ifdef FLY if (enter_status == Q_FLY) { /* Make sure that the position you enter in will be erased */ showexpl(newpp->p_y, newpp->p_x, FLYER); } # endif sendcom(newpp, REFRESH); sendcom(newpp, READY, 0); (void) fflush(newpp->p_output); }
/* * move_player: * Try to move player 'pp' in direction 'dir'. */ static void move_player(PLAYER *pp, int dir) { PLAYER *newp; int x, y; FLAG moved; BULLET *bp; y = pp->p_y; x = pp->p_x; switch (dir) { case LEFTS: x--; break; case RIGHT: x++; break; case ABOVE: y--; break; case BELOW: y++; break; } moved = FALSE; /* What would the player move over: */ switch (Maze[y][x]) { /* Players can move through spaces and doors, no problem: */ case SPACE: case DOOR: moved = TRUE; break; /* Can't move through walls: */ case WALL1: case WALL2: case WALL3: case WALL4: case WALL5: break; /* Moving over a mine - try to pick it up: */ case MINE: case GMINE: if (dir == pp->p_face) /* facing it: 2% chance of trip */ pickup(pp, y, x, conf_ptrip_face, Maze[y][x]); else if (opposite(dir, pp->p_face)) /* facing away: 95% chance of trip */ pickup(pp, y, x, conf_ptrip_back, Maze[y][x]); else /* facing sideways: 50% chance of trip */ pickup(pp, y, x, conf_ptrip_side, Maze[y][x]); /* Remove the mine: */ Maze[y][x] = SPACE; moved = TRUE; break; /* Moving into a bullet: */ case SHOT: case GRENADE: case SATCHEL: case BOMB: case SLIME: case DSHOT: /* Find which bullet: */ bp = is_bullet(y, x); if (bp != NULL) /* Detonate it: */ bp->b_expl = TRUE; /* Remove it: */ Maze[y][x] = SPACE; moved = TRUE; break; /* Moving into another player: */ case LEFTS: case RIGHT: case ABOVE: case BELOW: if (dir != pp->p_face) /* Can't walk backwards/sideways into another player: */ sendcom(pp, BELL); else { /* Stab the other player */ newp = play_at(y, x); checkdam(newp, pp, pp->p_ident, conf_stabdam, KNIFE); } break; /* Moving into a player flying overhead: */ case FLYER: newp = play_at(y, x); message(newp, "Oooh, there's a short guy waving at you!"); message(pp, "You couldn't quite reach him!"); break; /* Picking up a boot, or two: */ case BOOT_PAIR: pp->p_nboots++; case BOOT: pp->p_nboots++; for (newp = Boot; newp < &Boot[NBOOTS]; newp++) { if (newp->p_flying < 0) continue; if (newp->p_y == y && newp->p_x == x) { newp->p_flying = -1; if (newp->p_undershot) fixshots(y, x, newp->p_over); } } if (pp->p_nboots == 2) message(pp, "Wow! A pair of boots!"); else message(pp, "You can hobble around on one boot."); Maze[y][x] = SPACE; moved = TRUE; break; } /* Can the player be moved? */ if (moved) { /* Check the gun status: */ if (pp->p_ncshot > 0) if (--pp->p_ncshot == conf_maxncshot) outyx(pp, STAT_GUN_ROW, STAT_VALUE_COL, " ok"); /* Check for bullets flying past: */ if (pp->p_undershot) { fixshots(pp->p_y, pp->p_x, pp->p_over); pp->p_undershot = FALSE; } /* Erase the player: */ drawplayer(pp, FALSE); /* Save under: */ pp->p_over = Maze[y][x]; /* Move the player: */ pp->p_y = y; pp->p_x = x; /* Draw the player in their new position */ drawplayer(pp, TRUE); } }