void trapfunc::snake(game *g, int x, int y) { if (one_in(3)) { monster spawned(g->mtypes[mon_shadow_snake]); int tries = 0, monx, mony, junk; do { if (one_in(2)) { monx = rng(g->u.posx - 5, g->u.posx + 5); mony = (one_in(2) ? g->u.posy - 5 : g->u.posy + 5); } else { monx = (one_in(2) ? g->u.posx - 5 : g->u.posx + 5); mony = rng(g->u.posy - 5, g->u.posy + 5); } } while (tries < 5 && !g->is_empty(monx, mony) && !g->m.sees(monx, mony, g->u.posx, g->u.posy, 10, junk)); if (tries < 5) { g->add_msg("A shadowy snake forms nearby."); spawned.spawn(monx, mony); g->z.push_back(spawned); g->m.tr_at(x, y) = tr_null; return; } } g->sound(x, y, 10, "ssssssss"); if (one_in(6)) g->m.tr_at(x, y) = tr_null; }
void trapfunc::snake(int x, int y) { g->u.add_memorial_log(_("Triggered a shadow snake trap.")); if (one_in(3)) { monster spawned(GetMType("mon_shadow_snake")); int tries = 0, monx, mony, junk; do { if (one_in(2)) { monx = rng(g->u.posx - 5, g->u.posx + 5); mony = (one_in(2) ? g->u.posy - 5 : g->u.posy + 5); } else { monx = (one_in(2) ? g->u.posx - 5 : g->u.posx + 5); mony = rng(g->u.posy - 5, g->u.posy + 5); } } while (tries < 5 && !g->is_empty(monx, mony) && !g->m.sees(monx, mony, g->u.posx, g->u.posy, 10, junk)); if (tries < 5) { g->add_msg(_("A shadowy snake forms nearby.")); spawned.spawn(monx, mony); g->add_zombie(spawned); g->m.remove_trap(x, y); return; } } //~ the sound a snake makes g->sound(x, y, 10, _("ssssssss")); if (one_in(6)) g->m.remove_trap(x, y); }
void trapfunc::shadow(int x, int y) { g->u.add_memorial_log(pgettext("memorial_male", "Triggered a shadow trap."), pgettext("memorial_female", "Triggered a shadow trap.")); monster spawned(GetMType("mon_shadow")); int tries = 0, monx, mony, junk; do { if (one_in(2)) { monx = rng(g->u.posx - 5, g->u.posx + 5); mony = (one_in(2) ? g->u.posy - 5 : g->u.posy + 5); } else { monx = (one_in(2) ? g->u.posx - 5 : g->u.posx + 5); mony = rng(g->u.posy - 5, g->u.posy + 5); } } while (tries < 5 && !g->is_empty(monx, mony) && !g->m.sees(monx, mony, g->u.posx, g->u.posy, 10, junk)); if (tries < 5) { g->add_msg(_("A shadow forms nearby.")); spawned.sp_timeout = rng(2, 10); spawned.spawn(monx, mony); g->add_zombie(spawned); g->m.remove_trap(x, y); } }
void enemy::draw() const { if(spawned()) { map<enemy_animation,al_anim>::const_iterator it; it=animation.find(current_animation); unsigned int hoffset=it->second.get_height()/2; it->second.draw(position.first,position.second-hoffset); } }
void enemy::update() { if(spawned()) { if(alive()) { if(!idle()) { //not idle option position=movement_update(position,destiny,speed); } else set_to_idle(); //if reach destiny } else if(current_animation!=dead_anim) kill(); //killed animation[current_animation].update(); //animation update if(current_animation==dead_anim && animation[current_animation].is_active()==false) deactivate(); } }
void trapfunc::shadow(game *g, int x, int y) { monster spawned(g->mtypes[mon_shadow]); int tries = 0, monx, mony, junk; do { if (one_in(2)) { monx = rng(g->u.posx - 5, g->u.posx + 5); mony = (one_in(2) ? g->u.posy - 5 : g->u.posy + 5); } else { monx = (one_in(2) ? g->u.posx - 5 : g->u.posx + 5); mony = rng(g->u.posy - 5, g->u.posy + 5); } } while (tries < 5 && !g->is_empty(monx, mony) && !g->m.sees(monx, mony, g->u.posx, g->u.posy, 10, junk)); if (tries < 5) { g->add_msg("A shadow forms nearby."); spawned.sp_timeout = rng(2, 10); spawned.spawn(monx, mony); g->z.push_back(spawned); g->m.tr_at(x, y) = tr_null; } }
void event::actualize() { switch( type ) { case EVENT_HELP: debugmsg("Currently disabled while NPC and monster factions are being rewritten."); /* { int num = 1; if( faction_id >= 0 ) { num = rng( 1, 6 ); } for( int i = 0; i < num; i++ ) { npc *temp = new npc(); temp->normalize(); if( faction_id != -1 ) { faction *fac = g->faction_by_id( faction_id ); if( fac ) { temp->randomize_from_faction( fac ); } else { debugmsg( "EVENT_HELP run with invalid faction_id" ); temp->randomize(); } } else { temp->randomize(); } temp->attitude = NPCATT_DEFEND; // important: npc::spawn_at must be called to put the npc into the overmap temp->spawn_at( g->get_abs_levx(), g->get_abs_levy(), g->get_abs_levz() ); // spawn at the border of the reality bubble, outside of the players view if( one_in( 2 ) ) { temp->posx = rng( 0, SEEX * MAPSIZE - 1 ); temp->posy = rng( 0, 1 ) * SEEY * MAPSIZE; } else { temp->posx = rng( 0, 1 ) * SEEX * MAPSIZE; temp->posy = rng( 0, SEEY * MAPSIZE - 1 ); } // And tell the npc to go to the player. temp->goal.x = g->om_global_location().x; temp->goal.y = g->om_global_location().y; // The npcs will be loaded later by game::load_npcs() } } */ break; case EVENT_ROBOT_ATTACK: { if (rl_dist(g->get_abs_levx(), g->get_abs_levy(), map_point.x, map_point.y) <= 4) { mtype *robot_type = GetMType("mon_tripod"); if (faction_id == 0) { // The cops! if (one_in(2)) { robot_type = GetMType("mon_copbot"); } else { robot_type = GetMType("mon_riotbot"); } g->u.add_memorial_log(pgettext("memorial_male", "Became wanted by the police!"), pgettext("memorial_female", "Became wanted by the police!")); } monster robot(robot_type); int robx = (g->get_abs_levx() > map_point.x ? 0 - SEEX * 2 : SEEX * 4), roby = (g->get_abs_levy() > map_point.y ? 0 - SEEY * 2 : SEEY * 4); robot.spawn(robx, roby); g->add_zombie(robot); } } break; case EVENT_SPAWN_WYRMS: { if (g->levz >= 0) return; g->u.add_memorial_log(pgettext("memorial_male", "Awoke a group of dark wyrms!"), pgettext("memorial_female", "Awoke a group of dark wyrms!")); monster wyrm(GetMType("mon_dark_wyrm")); int num_wyrms = rng(1, 4); for (int i = 0; i < num_wyrms; i++) { int tries = 0; int monx = -1, mony = -1; do { monx = rng(0, SEEX * MAPSIZE); mony = rng(0, SEEY * MAPSIZE); tries++; } while (tries < 10 && !g->is_empty(monx, mony) && rl_dist(g->u.posx, g->u.posy, monx, mony) <= 2); if (tries < 10) { wyrm.spawn(monx, mony); g->add_zombie(wyrm); } } if (!one_in(25)) // They just keep coming! g->add_event(EVENT_SPAWN_WYRMS, int(calendar::turn) + rng(15, 25)); } break; case EVENT_AMIGARA: { g->u.add_memorial_log(pgettext("memorial_male", "Angered a group of amigara horrors!"), pgettext("memorial_female", "Angered a group of amigara horrors!")); int num_horrors = rng(3, 5); int faultx = -1, faulty = -1; bool horizontal = false; for (int x = 0; x < SEEX * MAPSIZE && faultx == -1; x++) { for (int y = 0; y < SEEY * MAPSIZE && faulty == -1; y++) { if (g->m.ter(x, y) == t_fault) { faultx = x; faulty = y; if (g->m.ter(x - 1, y) == t_fault || g->m.ter(x + 1, y) == t_fault) horizontal = true; else horizontal = false; } } } monster horror(GetMType("mon_amigara_horror")); for (int i = 0; i < num_horrors; i++) { int tries = 0; int monx = -1, mony = -1; do { if (horizontal) { monx = rng(faultx, faultx + 2 * SEEX - 8); for (int n = -1; n <= 1; n++) { if (g->m.ter(monx, faulty + n) == t_rock_floor) mony = faulty + n; } } else { // Vertical fault mony = rng(faulty, faulty + 2 * SEEY - 8); for (int n = -1; n <= 1; n++) { if (g->m.ter(faultx + n, mony) == t_rock_floor) monx = faultx + n; } } tries++; } while ((monx == -1 || mony == -1 || g->is_empty(monx, mony)) && tries < 10); if (tries < 10) { horror.spawn(monx, mony); g->add_zombie(horror); } } } break; case EVENT_ROOTS_DIE: g->u.add_memorial_log(pgettext("memorial_male", "Destroyed a triffid grove."), pgettext("memorial_female", "Destroyed a triffid grove.")); for (int x = 0; x < SEEX * MAPSIZE; x++) { for (int y = 0; y < SEEY * MAPSIZE; y++) { if (g->m.ter(x, y) == t_root_wall && one_in(3)) g->m.ter_set(x, y, t_underbrush); } } break; case EVENT_TEMPLE_OPEN: { g->u.add_memorial_log(pgettext("memorial_male", "Opened a strange temple."), pgettext("memorial_female", "Opened a strange temple.")); bool saw_grate = false; for (int x = 0; x < SEEX * MAPSIZE; x++) { for (int y = 0; y < SEEY * MAPSIZE; y++) { if (g->m.ter(x, y) == t_grate) { g->m.ter_set(x, y, t_stairs_down); if (!saw_grate && g->u_see(x, y)) saw_grate = true; } } } if (saw_grate) add_msg(_("The nearby grates open to reveal a staircase!")); } break; case EVENT_TEMPLE_FLOOD: { bool flooded = false; ter_id flood_buf[SEEX*MAPSIZE][SEEY*MAPSIZE]; for (int x = 0; x < SEEX * MAPSIZE; x++) { for (int y = 0; y < SEEY * MAPSIZE; y++) flood_buf[x][y] = g->m.ter(x, y); } for (int x = 0; x < SEEX * MAPSIZE; x++) { for (int y = 0; y < SEEY * MAPSIZE; y++) { if (g->m.ter(x, y) == t_water_sh) { bool deepen = false; for (int wx = x - 1; wx <= x + 1 && !deepen; wx++) { for (int wy = y - 1; wy <= y + 1 && !deepen; wy++) { if (g->m.ter(wx, wy) == t_water_dp) deepen = true; } } if (deepen) { flood_buf[x][y] = t_water_dp; flooded = true; } } else if (g->m.ter(x, y) == t_rock_floor) { bool flood = false; for (int wx = x - 1; wx <= x + 1 && !flood; wx++) { for (int wy = y - 1; wy <= y + 1 && !flood; wy++) { if (g->m.ter(wx, wy) == t_water_dp || g->m.ter(wx, wy) == t_water_sh) flood = true; } } if (flood) { flood_buf[x][y] = t_water_sh; flooded = true; } } } } if (!flooded) return; // We finished flooding the entire chamber! // Check if we should print a message if (flood_buf[g->u.posx][g->u.posy] != g->m.ter(g->u.posx, g->u.posy)) { if (flood_buf[g->u.posx][g->u.posy] == t_water_sh) { add_msg(m_warning, _("Water quickly floods up to your knees.")); g->u.add_memorial_log(pgettext("memorial_male", "Water level reached knees."), pgettext("memorial_female", "Water level reached knees.")); } else { // Must be deep water! add_msg(m_warning, _("Water fills nearly to the ceiling!")); g->u.add_memorial_log(pgettext("memorial_male", "Water level reached the ceiling."), pgettext("memorial_female", "Water level reached the ceiling.")); g->plswim(g->u.posx, g->u.posy); } } // flood_buf is filled with correct tiles; now copy them back to g->m for (int x = 0; x < SEEX * MAPSIZE; x++) { for (int y = 0; y < SEEY * MAPSIZE; y++) g->m.ter_set(x, y, flood_buf[x][y]); } g->add_event(EVENT_TEMPLE_FLOOD, int(calendar::turn) + rng(2, 3)); } break; case EVENT_TEMPLE_SPAWN: { std::string montype = "mon_null"; switch (rng(1, 4)) { case 1: montype = "mon_sewer_snake"; break; case 2: montype = "mon_centipede"; break; case 3: montype = "mon_dermatik"; break; case 4: montype = "mon_spider_widow_giant"; break; } monster spawned( GetMType(montype) ); int tries = 0, x, y; do { x = rng(g->u.posx - 5, g->u.posx + 5); y = rng(g->u.posy - 5, g->u.posy + 5); tries++; } while (tries < 20 && !g->is_empty(x, y) && rl_dist(x, y, g->u.posx, g->u.posy) <= 2); if (tries < 20) { spawned.spawn(x, y); g->add_zombie(spawned); } } break; default: break; // Nothing happens for other events } }
void event::actualize(game *g) { switch (type) { case EVENT_HELP: { npc tmp; int num = 1; if (faction_id >= 0) num = rng(1, 6); for (int i = 0; i < num; i++) { if (faction_id != -1) { faction* fac = g->faction_by_id(faction_id); if (fac) tmp.randomize_from_faction(g, fac); else debugmsg("EVENT_HELP run with invalid faction_id"); } else tmp.randomize(g); tmp.attitude = NPCATT_DEFEND; tmp.posx = g->u.posx - SEEX * 2 + rng(-5, 5); tmp.posy = g->u.posy - SEEY * 2 + rng(-5, 5); g->active_npc.push_back(&tmp); } } break; case EVENT_ROBOT_ATTACK: { if (rl_dist(g->levx, g->levy, map_point.x, map_point.y) <= 4) { mtype *robot_type = GetMType("mon_tripod"); if (faction_id == 0) { // The cops! robot_type = GetMType("mon_copbot"); g->u.add_memorial_log(_("Became wanted by the police!")); } monster robot(robot_type); int robx = (g->levx > map_point.x ? 0 - SEEX * 2 : SEEX * 4), roby = (g->levy > map_point.y ? 0 - SEEY * 2 : SEEY * 4); robot.spawn(robx, roby); g->add_zombie(robot); } } break; case EVENT_SPAWN_WYRMS: { if (g->levz >= 0) return; g->u.add_memorial_log(_("Awoke a group of dark wyrms!")); monster wyrm(GetMType("mon_dark_wyrm")); int num_wyrms = rng(1, 4); for (int i = 0; i < num_wyrms; i++) { int tries = 0; int monx = -1, mony = -1; do { monx = rng(0, SEEX * MAPSIZE); mony = rng(0, SEEY * MAPSIZE); tries++; } while (tries < 10 && !g->is_empty(monx, mony) && rl_dist(g->u.posx, g->u.posx, monx, mony) <= 2); if (tries < 10) { wyrm.spawn(monx, mony); g->add_zombie(wyrm); } } if (!one_in(25)) // They just keep coming! g->add_event(EVENT_SPAWN_WYRMS, int(g->turn) + rng(15, 25)); } break; case EVENT_AMIGARA: { g->u.add_memorial_log(_("Angered a group of amigara horrors!")); int num_horrors = rng(3, 5); int faultx = -1, faulty = -1; bool horizontal = false; for (int x = 0; x < SEEX * MAPSIZE && faultx == -1; x++) { for (int y = 0; y < SEEY * MAPSIZE && faulty == -1; y++) { if (g->m.ter(x, y) == t_fault) { faultx = x; faulty = y; if (g->m.ter(x - 1, y) == t_fault || g->m.ter(x + 1, y) == t_fault) horizontal = true; else horizontal = false; } } } monster horror(GetMType("mon_amigara_horror")); for (int i = 0; i < num_horrors; i++) { int tries = 0; int monx = -1, mony = -1; do { if (horizontal) { monx = rng(faultx, faultx + 2 * SEEX - 8); for (int n = -1; n <= 1; n++) { if (g->m.ter(monx, faulty + n) == t_rock_floor) mony = faulty + n; } } else { // Vertical fault mony = rng(faulty, faulty + 2 * SEEY - 8); for (int n = -1; n <= 1; n++) { if (g->m.ter(faultx + n, mony) == t_rock_floor) monx = faultx + n; } } tries++; } while ((monx == -1 || mony == -1 || g->is_empty(monx, mony)) && tries < 10); if (tries < 10) { horror.spawn(monx, mony); g->add_zombie(horror); } } } break; case EVENT_ROOTS_DIE: g->u.add_memorial_log(_("Destroyed a triffid grove.")); for (int x = 0; x < SEEX * MAPSIZE; x++) { for (int y = 0; y < SEEY * MAPSIZE; y++) { if (g->m.ter(x, y) == t_root_wall && one_in(3)) g->m.ter_set(x, y, t_underbrush); } } break; case EVENT_TEMPLE_OPEN: { g->u.add_memorial_log(_("Opened a strange temple.")); bool saw_grate = false; for (int x = 0; x < SEEX * MAPSIZE; x++) { for (int y = 0; y < SEEY * MAPSIZE; y++) { if (g->m.ter(x, y) == t_grate) { g->m.ter_set(x, y, t_stairs_down); if (!saw_grate && g->u_see(x, y)) saw_grate = true; } } } if (saw_grate) g->add_msg(_("The nearby grates open to reveal a staircase!")); } break; case EVENT_TEMPLE_FLOOD: { bool flooded = false; ter_id flood_buf[SEEX*MAPSIZE][SEEY*MAPSIZE]; for (int x = 0; x < SEEX * MAPSIZE; x++) { for (int y = 0; y < SEEY * MAPSIZE; y++) flood_buf[x][y] = g->m.ter(x, y); } for (int x = 0; x < SEEX * MAPSIZE; x++) { for (int y = 0; y < SEEY * MAPSIZE; y++) { if (g->m.ter(x, y) == t_water_sh) { bool deepen = false; for (int wx = x - 1; wx <= x + 1 && !deepen; wx++) { for (int wy = y - 1; wy <= y + 1 && !deepen; wy++) { if (g->m.ter(wx, wy) == t_water_dp) deepen = true; } } if (deepen) { flood_buf[x][y] = t_water_dp; flooded = true; } } else if (g->m.ter(x, y) == t_rock_floor) { bool flood = false; for (int wx = x - 1; wx <= x + 1 && !flood; wx++) { for (int wy = y - 1; wy <= y + 1 && !flood; wy++) { if (g->m.ter(wx, wy) == t_water_dp || g->m.ter(wx, wy) == t_water_sh) flood = true; } } if (flood) { flood_buf[x][y] = t_water_sh; flooded = true; } } } } if (!flooded) return; // We finished flooding the entire chamber! // Check if we should print a message if (flood_buf[g->u.posx][g->u.posy] != g->m.ter(g->u.posx, g->u.posy)) { if (flood_buf[g->u.posx][g->u.posy] == t_water_sh) { g->add_msg(_("Water quickly floods up to your knees.")); g->u.add_memorial_log(_("Water level reached knees.")); } else { // Must be deep water! g->add_msg(_("Water fills nearly to the ceiling!")); g->u.add_memorial_log(_("Water level reached the ceiling.")); g->plswim(g->u.posx, g->u.posy); } } // flood_buf is filled with correct tiles; now copy them back to g->m for (int x = 0; x < SEEX * MAPSIZE; x++) { for (int y = 0; y < SEEY * MAPSIZE; y++) g->m.ter_set(x, y, flood_buf[x][y]); } g->add_event(EVENT_TEMPLE_FLOOD, int(g->turn) + rng(2, 3)); } break; case EVENT_TEMPLE_SPAWN: { std::string montype = "mon_null"; switch (rng(1, 4)) { case 1: montype = "mon_sewer_snake"; break; case 2: montype = "mon_centipede"; break; case 3: montype = "mon_dermatik"; break; case 4: montype = "mon_spider_widow"; break; } monster spawned( GetMType(montype) ); int tries = 0, x, y; do { x = rng(g->u.posx - 5, g->u.posx + 5); y = rng(g->u.posy - 5, g->u.posy + 5); tries++; } while (tries < 20 && !g->is_empty(x, y) && rl_dist(x, y, g->u.posx, g->u.posy) <= 2); if (tries < 20) { spawned.spawn(x, y); g->add_zombie(spawned); } } break; default: break; // Nothing happens for other events } }