void monster_update(struct monster *monster, struct map *map){ if((SDL_GetTicks()-monster_clock_fixed(monster))%10==9){ int randmonster = rand()%4; switch(randmonster){ case NORTH: monster_set_current_way(monster,NORTH); monster_move(monster,map); break; case SOUTH: monster_set_current_way(monster,SOUTH); monster_move(monster,map); break; case EAST: monster_set_current_way(monster,EAST); monster_move(monster,map); break; case WEST: monster_set_current_way(monster,WEST); monster_move(monster,map); break; } } }
int main (void) { uint16_t tick = 0; uint8_t col; monster_t monsters[NUM_MONSTERS]; system_init (); tinygl_init (LOOP_RATE); pacer_init (LOOP_RATE); monsters_create (monsters, NUM_MONSTERS); while (1) { /* Refresh monsters. */ for (col = 0; col < TINYGL_WIDTH; col++) { pacer_wait (); tinygl_update (); } tick++; if (tick >= LOOP_RATE / MOVE_RATE) { tick = 0; monster_move (monsters, NUM_MONSTERS); } } return 0; }
void game_display(struct game* game) { assert(game); int map_w, map_h; window_clear(); if(game->nb_player == 1) { map_w = map_get_width(level_get_curr_map(game->curr_level)); map_h = map_get_height(level_get_curr_map(game->curr_level)); for(int i = 0; i < map_w; i++) for(int j = 0; j < map_h+2; j++) window_display_image(sprite_get_empty(), i * SIZE_BLOC, j * SIZE_BLOC); } level_display(game_get_curr_level(game)); monster_display(level_get_curr_map(game->curr_level)); bomb_display(game, level_get_curr_map(game->curr_level)); game_banner_display(game); if(game->nb_player == 1) { // Single player struct player* player = game->players[0]; // Always display player_display(player); if(game->game_state == PLAYING) { player_move(game, player, level_get_curr_map(game->curr_level)); monster_move(game, level_get_curr_map(game->curr_level), player); player_update(player); monster_update(level_get_curr_map(game->curr_level)); } } else { // Multi player struct player* players_in_order[game->nb_player]; for(int i=0; i<game->nb_player; i++) players_in_order[i] = game->players[i]; game_order_players_array(game, players_in_order); for(int i = 0; i < game->nb_player; i++) { player_display(players_in_order[i]); if(game->game_state == PLAYING) { player_move(game, players_in_order[i], level_get_curr_map(game->curr_level)); player_update(players_in_order[i]); } } // end for each player } // end Multi player if(game->game_state == PLAYING) { bomb_update(level_get_curr_map(game->curr_level)); } else if(game->game_state == PAUSED) { map_w = map_get_width(level_get_curr_map(game->curr_level)); map_h = map_get_height(level_get_curr_map(game->curr_level)); int mid_w = map_w / 2 * SIZE_BLOC + map_w%2 * SIZE_BLOC / 2; int mid_h = map_h / 2 * SIZE_BLOC + map_h%2 * SIZE_BLOC / 2; menu_display(mid_w, mid_h); } window_refresh(); }
void plan_monsters(faction * f) { region *r; assert(f); attack_chance = get_param_flt(global.parameters, "rules.monsters.attack_chance", 0.4); f->lastorders = turn; for (r = regions; r; r = r->next) { unit *u; bool attacking = false; for (u = r->units; u; u = u->next) { attrib *ta; order *long_order = NULL; /* Ab hier nur noch Befehle für NPC-Einheiten. */ if (!is_monsters(u->faction)) continue; /* Befehle müssen jede Runde neu gegeben werden: */ free_orders(&u->orders); if (skill_enabled(SK_PERCEPTION)) { /* Monster bekommen jede Runde ein paar Tage Wahrnehmung dazu */ /* TODO: this only works for playerrace */ produceexp(u, SK_PERCEPTION, u->number); } if (!attacking) { if (chance(attack_chance)) attacking = true; } if (u->status > ST_BEHIND) { setstatus(u, ST_FIGHT); /* all monsters fight */ } if (attacking && (!r->land || is_guard(u, GUARD_TAX))) { monster_attacks(u); } /* units with a plan to kill get ATTACK orders: */ ta = a_find(u->attribs, &at_hate); if (ta && !monster_is_waiting(u)) { unit *tu = (unit *)ta->data.v; if (tu && tu->region == r) { order * ord = monster_attack(u, tu); if (ord) { addlist(&u->orders, ord); } } else if (tu) { tu = findunitg(ta->data.i, NULL); if (tu != NULL) { long_order = make_movement_order(u, tu->region, 2, allowed_walk); } } else a_remove(&u->attribs, ta); } /* All monsters guard the region: */ if (!monster_is_waiting(u) && r->land) { addlist(&u->orders, create_order(K_GUARD, u->faction->locale, NULL)); } /* Einheiten mit Bewegungsplan kriegen ein NACH: */ if (long_order == NULL) { attrib *ta = a_find(u->attribs, &at_targetregion); if (ta) { if (u->region == (region *)ta->data.v) { a_remove(&u->attribs, ta); } } else if (u_race(u)->flags & RCF_MOVERANDOM) { if (rng_int() % 100 < MOVECHANCE || check_overpopulated(u)) { long_order = monster_move(r, u); } } } if (long_order == NULL && unit_can_study(u)) { /* Einheiten, die Waffenlosen Kampf lernen könnten, lernen es um * zu bewachen: */ if (u_race(u)->bonus[SK_WEAPONLESS] != -99) { if (effskill(u, SK_WEAPONLESS, 0) < 1) { long_order = create_order(K_STUDY, f->locale, "'%s'", skillname(SK_WEAPONLESS, f->locale)); } } } if (long_order == NULL) { /* Ab hier noch nicht generalisierte Spezialbehandlungen. */ if (!u->orders) { handle_event(u->attribs, "ai_move", u); } switch (old_race(u_race(u))) { case RC_SEASERPENT: long_order = create_order(K_PIRACY, f->locale, NULL); break; #ifdef TODO_ALP case RC_ALP: long_order = monster_seeks_target(r, u); break; #endif case RC_FIREDRAGON: case RC_DRAGON: case RC_WYRM: long_order = plan_dragon(u); break; default: if (u_race(u)->flags & RCF_LEARN) { long_order = monster_learn(u); } break; } } if (long_order) { addlist(&u->orders, long_order); } } } pathfinder_cleanup(); }
/* Consider one monster's action */ void m_pulse(struct monster *m) { int range = distance(m->x, m->y, Player.x, Player.y); if(Time % 10 == 0) { if(m->hp < Monsters[m->id].hp) { ++m->hp; } } if(!m_statusp(m, AWAKE) && (range <= m->wakeup)) { m_status_set(m, AWAKE); resetgamestatus(FAST_MOVE); } if(m_statusp(m, AWAKE)) { if(m_statusp(m, WANDERING)) { if(m_statusp(m, MOBILE)) { m_random_move(m); } if(range <= m->sense) { m_status_reset(m, WANDERING); } } else { /* Not wandering */ if(m_statusp(m, HOSTILE)) { if((range > 2) && (range < m->sense) && (random_range(2) == 1)) { if(los_p(m->x, m->y, Player.x, Player.y) && (Player.status[INVISIBLE] == 0)) { monster_strike(m); } } } if((m_statusp(m, HOSTILE) || m_statusp(m, NEEDY)) && (range > 1) && m_statusp(m, MOBILE)) { monster_move(m); /* If monster is greedy, picks up treasure it finds */ if(m_statusp(m, GREEDY)) { while(Level->site[m->x][m->y].things != NULL) { m_pickup(m, Level->site[m->x][m->y].things->thing); Level->site[m->x][m->y].things = Level->site[m->x][m->y].things->next; } } } if(m_statusp(m, HOSTILE) && (range == 1)) { resetgamestatus(FAST_MOVE); tacmonster(m); } } /* Prevents monsters form casting spells from other side of dungeon */ if(range < max(5, m->level)) { monster_special(m); } } }
char Engine ( int *counter, int *tanks, short BackGround[][ROW + 1], int level ) { BOMB rocket; BOMB skad; MONSTER bonus; MONSTER monster_arrey[MONSTER_SIZE] = {0}; ARROW arrow_arrey[ARROW_SIZE] = {0}; short screen[COL][ROW] = {0}; short Tools_Color[5] = {0}; clock_t tankSpeed = 0; clock_t arrowSpeed = 0; clock_t monsterMoveTime = 0; clock_t bombSpeed = 0; clock_t bombWait = 0; clock_t bonusSpeed = 0; clock_t bonusWait = 0; clock_t rocketSpeed = 0; int tank_x = 35; int win_loose = TIE; int newarrow = 0 ; int monster_faster = 0; int newline = 1; int BOMB_WAIT = 0; int MONSTER_MOVE = 0; int BONUS_WAIT = 0; char key = NULL; char monster_shape [6] = {'\0'}; char tank_shape[6] = {'\0'}; system ("cls"); BackGround_define ( BackGround, Tools_Color, &BOMB_WAIT, &MONSTER_MOVE, &BONUS_WAIT, level ); bonus.y = 2; bonus.x = 70; bonus.on = false; skad.on = false; rocket.on = false; TIMER(bonusWait, 20000); monster_define ( monster_arrey, monster_shape, screen, BackGround, Tools_Color, level ); tank_define ( screen, tank_shape, tank_x, BackGround, Tools_Color ); SetColor (YELLOW, BackGround[0][0]); SetCursor (0, 0); printf("POINTS:%d",*counter); SetCursor (70, 0); printf("TANKS:%d",*tanks); //unending loop while (key != ESC) { //keyboard interrupts. if (kbhit()) { key = getch(); if (key == -32) key = getch(); fflush(stdin); if (key == SHOT)//stdin { //approve new arrow. new_arrow_approval( BackGround, arrow_arrey, &newarrow, tank_x, counter ); } else if (tankSpeed < clock() && key == RIGHT || key == LEFT) { TIMER (tankSpeed, TANK_SPEED); // move the tank left/right. direction ( key, &tank_x, tank_shape, screen, BackGround, Tools_Color ); } } //go to shoting while there a still a arrow in the air. if (arrow_arrey[newarrow].on &&\ arrowSpeed < clock()) { TIMER(arrowSpeed, ARROW_SPEED); shoting( arrow_arrey, screen, monster_arrey, &skad, counter, &monster_faster, BackGround, &bonus, tanks, Tools_Color ); } // if its time go to move some monsters. if (monsterMoveTime < clock()) { monsterMoveTime = (clock_t) MONSTER_MOVE *\ MilliSecond - (monster_faster) + clock(); win_loose = monster_move( monster_arrey, monster_shape, screen, &newline, BackGround, Tools_Color ); if (win_loose == WIN || win_loose == LOOSE) break; } // if its time for a new bonus turn one on. if (!bonus.on && bonusWait < clock()) { TIMER(bonusWait, BONUS_WAIT); bonus.on = true; } //go while still there bonus flying. if (bonus.on && bonusSpeed < clock()) { TIMER(bonusSpeed, BONUS_SPEED); bonus_monster( &bonus, BackGround, screen, Tools_Color ); } // from level 2 if (level > 1) { //if there no bomb on air and its time for new one if (!skad.on && bombWait < clock()) { TIMER(bombWait, BOMB_WAIT); // turn on on and choose the bomber. bomber_choose ( monster_arrey, &skad ); } //go while still a bomb on air. if (skad.on && bombSpeed < clock()) { TIMER(bombSpeed, BOMB_SPEED); win_loose = drop_bombs ( &skad, monster_arrey, &tank_x, tanks, screen, tank_shape, BackGround, Tools_Color ); if (win_loose == WIN || win_loose == LOOSE) break; } } //from level 3. if (level > 2) { //when the bonus monsetr find the tank unrder her, //she drop a guided rocket. if (bonus.on && !rocket.on && bonus.x == tank_x) { rocket.on = true; rocket.x = tank_x; rocket.y = 3; } //the rocket run after the tank. //the only reason you can get away from it is //because the tank run a little faster. else if (rocket.on && rocketSpeed < clock()) { TIMER(rocketSpeed, ROCKET_SPEED); win_loose = drop_rocket ( &rocket, &tank_x, tanks, screen, tank_shape, BackGround, Tools_Color ); if (win_loose == WIN || win_loose == LOOSE) break; } } } if (win_loose == WIN) key = 'w'; else if (win_loose == LOOSE) key = 'l'; return key; }