コード例 #1
0
bool monster::make_fungus()
{
    char polypick = 0;
    std::string tid = type->id;
    if (tid == "mon_ant" || tid == "mon_ant_soldier" || tid == "mon_ant_queen" || tid == "mon_fly" || tid == "mon_bee" || tid == "mon_dermatik")
    {
        polypick = 1;
    }else if (tid == "mon_zombie" || tid == "mon_zombie_shrieker" || tid == "mon_zombie_electric" || tid == "mon_zombie_spitter" || tid == "mon_zombie_dog" ||
              tid == "mon_zombie_brute" || tid == "mon_zombie_hulk"){
        polypick = 2;
    }else if (tid == "mon_boomer" || tid == "mon_zombie_gasbag"){
        polypick = 3;
    }else if (tid == "mon_triffid" || tid == "mon_triffid_young" || tid == "mon_triffid_queen"){
        polypick = 4;
    }
    switch (polypick) {
        case 1: // bugs, why do they all turn into fungal ants?
            poly(GetMType("mon_ant_fungus"));
            return true;
        case 2: // zombies, non-boomer
            poly(GetMType("mon_zombie_fungus"));
            return true;
        case 3:
            poly(GetMType("mon_boomer_fungus"));
            return true;
        case 4:
            poly(GetMType("mon_fungaloid"));
            return true;
        default:
            return true;
    }
}
コード例 #2
0
ファイル: wish.cpp プロジェクト: 8Z/Cataclysm-DDA
        virtual void select(int entnum, uimenu *menu) {
            if ( ! started ) {
                started = true;
                setup(menu);
            }
            if (entnum != lastent) {
                lastent = entnum;
                tmp = monster(GetMType(entnum));
                if (friendly) {
                    tmp.friendly = -1;
                }
            }

            werase(w_info);
            tmp.print_info(g, w_info);

            std::string header = string_format("#%d: %s", entnum, GetMType(entnum)->name.c_str()
                                              );
            mvwprintz(w_info, 1, ( getmaxx(w_info) - header.size() ) / 2, c_cyan, "%s",
                      header.c_str()
                     );

            mvwprintz(w_info, getmaxy(w_info) - 3, 0, c_green, "%s", msg.c_str());
            msg = padding;
            mvwprintw(w_info, getmaxy(w_info) - 2, 0, "[/] find, [f] friendly, [q]uit");
            //wrefresh(w_info); // for some reason this makes everything disappear on first run? Not needed, at any rate.
        }
コード例 #3
0
ファイル: wish.cpp プロジェクト: Camkitsune/Cataclysm-DDA
        virtual void select(int entnum, uimenu *menu) override
        {
            if ( ! started ) {
                started = true;
                setup(menu);
            }
            if (entnum != lastent) {
                lastent = entnum;
                tmp = monster(GetMType(entnum));
                if (friendly) {
                    tmp.friendly = -1;
                }
            }

            werase(w_info);
            tmp.print_info( w_info, 6, 5, 1 );

            std::string header = string_format("#%d: %s", entnum, GetMType(entnum)->nname().c_str());
            mvwprintz(w_info, 1, ( getmaxx(w_info) - header.size() ) / 2, c_cyan, "%s",
                      header.c_str());
            if( hallucination ) {
                wprintw( w_info, _( " (hallucination)" ) );
            }

            mvwprintz(w_info, getmaxy(w_info) - 3, 0, c_green, "%s", msg.c_str());
            msg = padding;
            mvwprintw(w_info, getmaxy(w_info) - 2, 0,
                      _("[/] find, [f]riendly, [h]allucination [i]ncrease group, [d]ecrease group, [q]uit"));
        }
コード例 #4
0
bool monster::make_fungus()
{
    if( is_hallucination() ) {
        return true;
    }
    char polypick = 0;
    std::string tid = type->id;
    if (type->in_species("FUNGUS")) { // No friendly-fungalizing ;-)
        return true;
    }
    if (tid == "mon_ant" || tid == "mon_ant_soldier" || tid == "mon_ant_queen" || tid == "mon_fly" ||
      tid == "mon_bee" || tid == "mon_dermatik") {
        polypick = 1;
    } else if (tid == "mon_zombie" || tid == "mon_zombie_shrieker" || tid == "mon_zombie_electric" ||
      tid == "mon_zombie_spitter" || tid == "mon_zombie_dog" || tid == "mon_zombie_brute" ||
      tid == "mon_zombie_hulk" || tid == "mon_zombie_soldier" || tid == "mon_zombie_tough" ||
      tid == "mon_zombie_scientist" || tid == "mon_zombie_hunter" || tid == "mon_zombie_child"||
      tid == "mon_zombie_bio_op" || tid == "mon_zombie_survivor" || tid == "mon_zombie_fireman" ||
      tid == "mon_zombie_cop" || tid == "mon_zombie_fat" || tid == "mon_zombie_rot" ||
      tid == "mon_zombie_swimmer" || tid == "mon_zombie_grabber" || tid == "mon_zombie_technician" ||
      tid == "mon_zombie_brute_shocker") {
        polypick = 2; // Necro and Master have enough Goo to resist conversion.
        // Firefighter, hazmat, and scarred/beekeeper have the PPG on.
    } else if (tid == "mon_zombie_necro" || tid == "mon_zombie_master" || tid == "mon_zombie_fireman" ||
      tid == "mon_zombie_hazmat" || tid == "mon_beekeeper") {
        return true;
    } else if (tid == "mon_boomer" || tid == "mon_zombie_gasbag" || tid == "mon_zombie_smoker") {
        polypick = 3;
    } else if (tid == "mon_triffid" || tid == "mon_triffid_young" || tid == "mon_triffid_queen") {
        polypick = 4;
    }
    switch (polypick) {
        case 1: // bugs, why do they all turn into fungal ants?
            poly(GetMType("mon_ant_fungus"));
            return true;
        case 2: // zombies, non-boomer
            poly(GetMType("mon_zombie_fungus"));
            return true;
        case 3:
            poly(GetMType("mon_boomer_fungus"));
            return true;
        case 4:
            poly(GetMType("mon_fungaloid"));
            return true;
        default:
            return false;
    }
}
コード例 #5
0
item Single_item_creator::create_single(int birthday, RecursionList &rec) const
{
    item tmp;
    if (type == S_ITEM) {
        if (id == "corpse") {
            tmp.make_corpse("corpse", GetMType("mon_null"), birthday);
        } else {
            tmp = item(id, birthday);
        }
    } else if (type == S_ITEM_GROUP) {
        if (std::find(rec.begin(), rec.end(), id) != rec.end()) {
            debugmsg("recursion in item spawn list %s", id.c_str());
            return item(null_item_id, birthday);
        }
        rec.push_back(id);
        Item_spawn_data *isd = item_controller->get_group(id);
        if (isd == NULL) {
            debugmsg("unknown item spawn list %s", id.c_str());
            return item(null_item_id, birthday);
        }
        tmp = isd->create_single(birthday, rec);
    } else if (type == S_NONE) {
        return item(null_item_id, birthday);
    }
    if (modifier.get() != NULL) {
        modifier->modify(tmp);
    }
    // TODO: change the spawn lists to contain proper references to containers
    tmp = tmp.in_its_container();
    return tmp;
}
コード例 #6
0
ファイル: trapfunc.cpp プロジェクト: noppa354/Cataclysm-DDA
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);
 }
}
コード例 #7
0
ファイル: trapfunc.cpp プロジェクト: Deadjack/Cataclysm-DDA
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);
}
コード例 #8
0
ファイル: mondeath.cpp プロジェクト: 9600bauds/Cataclysm-DDA
void mdeath::worm(monster *z) {
    if (g->u_see(z))
        g->add_msg(_("The %s splits in two!"), z->name().c_str());

    std::vector <point> wormspots;
    int wormx, wormy;
    for (int i = -1; i <= 1; i++) {
        for (int j = -1; j <= 1; j++) {
            wormx = z->posx() + i;
            wormy = z->posy() + j;
            if (g->m.has_flag("DIGGABLE", wormx, wormy) &&
                    !(g->u.posx == wormx && g->u.posy == wormy)) {
                wormspots.push_back(point(wormx, wormy));
            }
        }
    }
    int worms = 0;
    while(worms < 2 && wormspots.size() > 0) {
        monster worm(GetMType("mon_halfworm"));
        int rn = rng(0, wormspots.size() - 1);
        if(-1 == g->mon_at(wormspots[rn])) {
            worm.spawn(wormspots[rn].x, wormspots[rn].y);
            g->add_zombie(worm);
            worms++;
        }
        wormspots.erase(wormspots.begin() + rn);
    }
}
コード例 #9
0
ファイル: mondeath.cpp プロジェクト: Waladil/Cataclysm-DDA
void mdeath::ratking(monster *z)
{
    g->u.rem_disease("rat");
    if (g->u_see(z)) {
        add_msg(m_warning, _("Rats suddenly swarm into view."));
    }

    std::vector <point> ratspots;
    int ratx, raty;
    for (int i = -1; i <= 1; i++) {
        for (int j = -1; j <= 1; j++) {
            ratx = z->posx() + i;
            raty = z->posy() + i;
            if (g->m.move_cost(ratx, raty) > 0 && g->mon_at(ratx, raty) == -1 &&
                !(g->u.posx == ratx && g->u.posy == raty)) {
                ratspots.push_back(point(ratx, raty));
            }
        }
    }
    int rn;
    monster rat(GetMType("mon_sewer_rat"));
    for (int rats = 0; rats < 7 && !ratspots.empty(); rats++) {
        rn = rng(0, ratspots.size() - 1);
        rat.spawn(ratspots[rn].x, ratspots[rn].y);
        g->add_zombie(rat);
        ratspots.erase(ratspots.begin() + rn);
    }
}
コード例 #10
0
ファイル: mondeath.cpp プロジェクト: Waladil/Cataclysm-DDA
void mdeath::worm(monster *z)
{
    if (g->u_see(z)) {
        if(z->type->dies.size() == 1) {
            add_msg(m_good, _("The %s splits in two!"), z->name().c_str());
        } else {
            add_msg(m_warning, _("Two worms crawl out of the %s's corpse."), z->name().c_str());
        }
    }

    std::vector <point> wormspots;
    int wormx, wormy;
    for (int i = -1; i <= 1; i++) {
        for (int j = -1; j <= 1; j++) {
            wormx = z->posx() + i;
            wormy = z->posy() + j;
            if (g->m.has_flag("DIGGABLE", wormx, wormy) &&
                !(g->u.posx == wormx && g->u.posy == wormy)) {
                wormspots.push_back(point(wormx, wormy));
            }
        }
    }
    int worms = 0;
    while(worms < 2 && !wormspots.empty()) {
        monster worm(GetMType("mon_halfworm"));
        int rn = rng(0, wormspots.size() - 1);
        if(-1 == g->mon_at(wormspots[rn])) {
            worm.spawn(wormspots[rn].x, wormspots[rn].y);
            g->add_zombie(worm);
            worms++;
        }
        wormspots.erase(wormspots.begin() + rn);
    }
}
コード例 #11
0
void mdeath::ratking(monster *z)
{
    g->u.remove_effect("rat");
    if (g->u_see(z)) {
        add_msg(m_warning, _("Rats suddenly swarm into view."));
    }

    std::vector <point> ratspots;
    int ratx, raty;
    for (int i = -1; i <= 1; i++) {
        for (int j = -1; j <= 1; j++) {
            ratx = z->posx() + i;
            raty = z->posy() + j;
            if (g->is_empty(ratx, raty)) {
                ratspots.push_back(point(ratx, raty));
            }
        }
    }
    monster rat(GetMType("mon_sewer_rat"));
    for (int rats = 0; rats < 7 && !ratspots.empty(); rats++) {
        int rn = rng(0, ratspots.size() - 1);
        point rp = ratspots[rn];
        ratspots.erase(ratspots.begin() + rn);
        rat.spawn(rp.x, rp.y);
        g->add_zombie(rat);
    }
}
コード例 #12
0
ファイル: catalua.cpp プロジェクト: Chase-san/Cataclysm-DDA
/** Create a new monster of the given type. */
monster *create_monster(std::string mon_type, int x, int y) {
    monster new_monster(GetMType(mon_type), x, y);
    if(!g->add_zombie(new_monster)) {
        return NULL;
    } else {
        return &(g->zombie(g->mon_at(x, y)));
    }
}
コード例 #13
0
ファイル: catalua.cpp プロジェクト: Devanon/Cataclysm-DDA
// mtype = game.monster_type(name)
static int game_monster_type(lua_State *L) {
    const char* parameter1 = (const char*) lua_tostring(L, 1);

    mtype** monster_type = (mtype**) lua_newuserdata(L, sizeof(mtype*));
    *monster_type = GetMType(parameter1);
    luah_setmetatable(L, "mtype_metatable");

    return 1; // 1 return values

}
コード例 #14
0
ファイル: defense.cpp プロジェクト: 8Z/Cataclysm-DDA
void defense_game::spawn_wave(game *g)
{
 g->add_msg("********");
 int diff = initial_difficulty + current_wave * wave_difficulty;
 bool themed_wave = one_in(SPECIAL_WAVE_CHANCE); // All a single monster type
 g->u.cash += cash_per_wave + (current_wave - 1) * cash_increase;
 std::vector<std::string> valid;
 valid = pick_monster_wave(g);
 while (diff > 0) {
// Clear out any monsters that exceed our remaining difficulty
  for (int i = 0; i < valid.size(); i++) {
   if (GetMType(valid[i])->difficulty > diff) {
    valid.erase(valid.begin() + i);
    i--;
   }
  }
  if (valid.empty()) {
   g->add_msg(_("Welcome to Wave %d!"), current_wave);
   g->add_msg("********");
   return;
  }
  int rn = rng(0, valid.size() - 1);
  mtype *type = GetMType(valid[rn]);
  if (themed_wave) {
   int num = diff / type->difficulty;
   if (num >= SPECIAL_WAVE_MIN) {
// TODO: Do we want a special message here?
    for (int i = 0; i < num; i++)
     spawn_wave_monster(g, type);
    g->add_msg( special_wave_message(type->name).c_str() );
    g->add_msg("********");
    return;
   } else
    themed_wave = false; // No partially-themed waves
  }
  diff -= type->difficulty;
  spawn_wave_monster(g, type);
 }
 g->add_msg(_("Welcome to Wave %d!"), current_wave);
 g->add_msg("********");
}
コード例 #15
0
ファイル: trapfunc.cpp プロジェクト: Deadjack/Cataclysm-DDA
void trapfuncm::goo(monster *z, int x, int y)
{
 if (z->type->id == "mon_blob") {
  z->speed += 15;
  z->hp = z->speed;
 } else {
  z->poly(GetMType("mon_blob"));
  z->speed -= 15;
  z->hp = z->speed;
 }
 g->m.remove_trap(x, y);
}
コード例 #16
0
void mdeath::jackson(monster *z) {
    for( size_t i = 0; i < g->num_zombies(); i++ ) {
        monster *candidate = &g->zombie( i );
        if(candidate->type->id == "mon_zombie_dancer" ) {
            candidate->poly(GetMType("mon_zombie_hulk"));
            candidate->remove_effect("controlled");
        }
        if (g->u_see(z->posx(), z->posy())) {
            add_msg(m_warning, _("The music stops!"));
        }
    }
}
コード例 #17
0
bool monster::make_fungus()
{
    char polypick = 0;
    std::string tid = type->id;
    if (type->in_species("FUNGUS")) { // No friendly-fungalizing ;-)
        return true;
    }
    if (tid == "mon_ant" || tid == "mon_ant_soldier" || tid == "mon_ant_queen" || tid == "mon_fly" ||
      tid == "mon_bee" || tid == "mon_dermatik") {
        polypick = 1;
    } else if (tid == "mon_zombie" || tid == "mon_zombie_shrieker" || tid == "mon_zombie_electric" ||
      tid == "mon_zombie_spitter" || tid == "mon_zombie_dog" || tid == "mon_zombie_brute" ||
      tid == "mon_zombie_hulk" || tid == "mon_zombie_soldier" || tid == "mon_zombie_tough" ||
      tid == "mon_zombie_scientist" || tid == "mon_zombie_hunter" || tid == "mon_zombie_child"||
      tid == "mon_zombie_bio_op" || tid == "mon_zombie_survivor" || tid == "mon_zombie_fireman" ||
      tid == "mon_zombie_cop" || tid == "mon_zombie_fat") {
        polypick = 2;
    } else if (tid == "mon_boomer" || tid == "mon_zombie_gasbag") {
        polypick = 3;
    } else if (tid == "mon_triffid" || tid == "mon_triffid_young" || tid == "mon_triffid_queen") {
        polypick = 4;
    }
    switch (polypick) {
        case 1: // bugs, why do they all turn into fungal ants?
            poly(GetMType("mon_ant_fungus"));
            return true;
        case 2: // zombies, non-boomer
            poly(GetMType("mon_zombie_fungus"));
            return true;
        case 3:
            poly(GetMType("mon_boomer_fungus"));
            return true;
        case 4:
            poly(GetMType("mon_fungaloid"));
            return true;
        default:
            return false;
    }
}
コード例 #18
0
ファイル: wish.cpp プロジェクト: Acherontius/Cataclysm-DDA
void game::wishmonster( const tripoint &p )
{
    const std::map<std::string, mtype *> montypes = MonsterGenerator::generator().get_all_mtypes();

    uimenu wmenu;
    wmenu.w_x = 0;
    wmenu.w_width = TERMX;
    // disabled due to foldstring crash //( TERMX - getmaxx(w_terrain) - 30 > 24 ? getmaxx(w_terrain) : TERMX );
    wmenu.pad_right = ( wmenu.w_width - 30 );
    wmenu.return_invalid = true;
    wmenu.selected = uistate.wishmonster_selected;
    wish_monster_callback *cb = new wish_monster_callback();
    wmenu.callback = cb;

    int i = 0;
    for( const auto &montype : montypes ) {
        wmenu.addentry( i, true, 0, "%s", montype.second->nname().c_str() );
        wmenu.entries[i].extratxt.txt = montype.second->sym;
        wmenu.entries[i].extratxt.color = montype.second->color;
        wmenu.entries[i].extratxt.left = 1;
        ++i;
    }

    do {
        wmenu.query();
        if ( wmenu.ret >= 0 ) {
            monster mon = monster(GetMType(wmenu.ret));
            mon.reset_last_load();
            if (cb->friendly) {
                mon.friendly = -1;
            }
            if (cb->hallucination) {
                mon.hallucination = true;
            }
            tripoint spawn = ( p == tripoint_min ? look_around() : p );
            if( spawn != tripoint_min ) {
                std::vector<tripoint> spawn_points = closest_tripoints_first( cb->group, spawn );
                for( auto spawn_point : spawn_points ) {
                    mon.spawn( spawn_point );
                    add_zombie(mon);
                }
                cb->msg = _("Monster spawned, choose another or 'q' to quit.");
                uistate.wishmonster_selected = wmenu.ret;
                wmenu.redraw();
            }
        }
    } while ( wmenu.keypress != 'q' && wmenu.keypress != KEY_ESCAPE && wmenu.keypress != ' ' );
    delete cb;
    cb = NULL;
    return;
}
コード例 #19
0
ファイル: wish.cpp プロジェクト: CptJean-Luc/Cataclysm-DDA
        virtual void select(int entnum, uimenu *menu) {
            if ( ! started ) {
                started = true;
                setup(menu);
            }
            if (entnum != lastent) {
                lastent = entnum;
                tmp = monster(GetMType(entnum));
                if (friendly) {
                    tmp.friendly = -1;
                }
            }

            werase(w_info);
            tmp.print_info(w_info);

            std::string header = string_format("#%d: %s", entnum, GetMType(entnum)->name.c_str());
            mvwprintz(w_info, 1, ( getmaxx(w_info) - header.size() ) / 2, c_cyan, "%s",
                      header.c_str());

            mvwprintz(w_info, getmaxy(w_info) - 3, 0, c_green, "%s", msg.c_str());
            msg = padding;
            mvwprintw(w_info, getmaxy(w_info) - 2, 0, _("[/] find, [f] friendly, [q]uit"));
        }
コード例 #20
0
ファイル: wish.cpp プロジェクト: CptJean-Luc/Cataclysm-DDA
void game::wishmonster(int x, int y)
{
    const std::map<std::string, mtype *> montypes = MonsterGenerator::generator().get_all_mtypes();

    uimenu wmenu;
    wmenu.w_x = 0;
    wmenu.w_width = TERMX;
    // disabled due to foldstring crash //( TERMX - getmaxx(w_terrain) - 30 > 24 ? getmaxx(w_terrain) : TERMX );
    wmenu.pad_right = ( wmenu.w_width - 30 );
    wmenu.return_invalid = true;
    wmenu.selected = uistate.wishmonster_selected;
    wish_monster_callback *cb = new wish_monster_callback();
    wmenu.callback = cb;

    int i = 0;
    for (std::map<std::string, mtype *>::const_iterator mon = montypes.begin();
         mon != montypes.end(); ++mon) {
        wmenu.addentry( i, true, 0, "%s", mon->second->name.c_str() );
        wmenu.entries[i].extratxt.txt = string_format("%c", mon->second->sym);
        wmenu.entries[i].extratxt.color = mon->second->color;
        wmenu.entries[i].extratxt.left = 1;
        ++i;
    }

    do {
        wmenu.query();
        if ( wmenu.ret >= 0 ) {
            monster mon = monster(GetMType(wmenu.ret));
            if (cb->friendly) {
                mon.friendly = -1;
            }
            point spawn = ( x == -1 && y == -1 ? look_around() : point ( x, y ) );
            if (spawn.x != -1) {
                mon.spawn(spawn.x, spawn.y);
                add_zombie(mon);
                cb->msg = _("Monster spawned, choose another or 'q' to quit.");
                uistate.wishmonster_selected = wmenu.ret;
                wmenu.redraw();
            }
        }
    } while ( wmenu.keypress != 'q' && wmenu.keypress != KEY_ESCAPE && wmenu.keypress != ' ' );
    delete cb;
    cb = NULL;
    return;
}
コード例 #21
0
ファイル: mondeath.cpp プロジェクト: Waladil/Cataclysm-DDA
void mdeath::blobsplit(monster *z)
{
    int speed = z->speed - rng(30, 50);
    g->m.spawn_item(z->posx(), z->posy(), "slime_scrap", 1, 0, calendar::turn, rng(1, 4));
    if (speed <= 0) {
        if (g->u_see(z)) {
            //  TODO:  Add vermin-tagged tiny versions of the splattered blob  :)
            add_msg(m_good, _("The %s splatters apart."), z->name().c_str());
        }
        return;
    }
    monster blob(GetMType((speed < 50 ? "mon_blob_small" : "mon_blob")));
    blob.speed = speed;
    // If we're tame, our kids are too
    blob.friendly = z->friendly;
    if (g->u_see(z)) {
        if(z->type->dies.size() == 1) {
            add_msg(m_good, _("The %s splits in two!"), z->name().c_str());
        } else {
            add_msg(m_bad, _("Two small blobs slither out of the corpse."), z->name().c_str());
        }
    }
    blob.hp = blob.speed;
    std::vector <point> valid;

    for (int i = -1; i <= 1; i++) {
        for (int j = -1; j <= 1; j++) {
            bool moveOK = (g->m.move_cost(z->posx() + i, z->posy() + j) > 0);
            bool monOK = g->mon_at(z->posx() + i, z->posy() + j) == -1;
            bool posOK = (g->u.posx != z->posx() + i || g->u.posy != z->posy() + j);
            if (moveOK && monOK && posOK) {
                valid.push_back(point(z->posx() + i, z->posy() + j));
            }
        }
    }

    int rn;
    for (int s = 0; s < 2 && !valid.empty(); s++) {
        rn = rng(0, valid.size() - 1);
        blob.spawn(valid[rn].x, valid[rn].y);
        g->add_zombie(blob);
        valid.erase(valid.begin() + rn);
    }
}
コード例 #22
0
void event::per_turn()
{
    switch (type) {
    case EVENT_WANTED: {
        // About once every 10 minutes. Suppress in classic zombie mode.
        if (g->levz >= 0 && one_in(100) && !ACTIVE_WORLD_OPTIONS["CLASSIC_ZOMBIES"]) {
            monster eyebot(GetMType("mon_eyebot"));
            eyebot.faction_id = faction_id;
            point place = g->m.random_outdoor_tile();
            if (place.x == -1 && place.y == -1)
                return; // We're safely indoors!
            eyebot.spawn(place.x, place.y);
            g->add_zombie(eyebot);
            if (g->u_see(place.x, place.y))
                add_msg(_("An eyebot swoops down nearby!"));
        }
    }
    break;

    case EVENT_SPAWN_WYRMS:
        if (g->levz >= 0) {
            turn--;
            return;
        }
        if (int(calendar::turn) % 3 == 0)
            add_msg(_("You hear screeches from the rock above and around you!"));
        break;

    case EVENT_AMIGARA:
        add_msg(_("The entire cavern shakes!"));
        break;

    case EVENT_TEMPLE_OPEN:
        add_msg(_("The earth rumbles."));
        break;


    default:
        break; // Nothing happens for other events
    }
}
コード例 #23
0
void monster::deserialize(JsonIn &jsin)
{
    JsonObject data = jsin.get_object();

    int iidtmp;
    std::string sidtmp;
    // load->str->int
    if ( ! data.read("typeid", sidtmp) ) {
        // or load->int->str->possibly_shifted_int
        data.read("typeid", iidtmp);
        sidtmp = legacy_mon_id[ iidtmp ];
    }
    type = GetMType(sidtmp);

    data.read("posx", _posx);
    data.read("posy", _posy);
    data.read("wandx", wandx);
    data.read("wandy", wandy);
    data.read("wandf", wandf);
    data.read("moves", moves);
    data.read("speed", speed);
    data.read("hp", hp);
    data.read("sp_timeout", sp_timeout);
    data.read("friendly", friendly);
    data.read("faction_id", faction_id);
    data.read("mission_id", mission_id);
    data.read("no_extra_death_drops", no_extra_death_drops);
    data.read("dead", dead);
    data.read("anger", anger);
    data.read("morale", morale);
    data.read("hallucination", hallucination);
    data.read("onstairs", onstairs);
    data.read("stairscount", staircount); // really?

    data.read("plans", plans);

    data.read("effects", effects);

    data.read("inv", inv);
    if (!data.read("ammo", ammo)) { ammo = 100; }
}
コード例 #24
0
// fish-with-rod fish catching function.
static void rod_fish( player *p, int sSkillLevel, int fishChance )
{
    if( sSkillLevel > fishChance ) {
        std::vector<monster *> fishables = g->get_fishable(60); //get the nearby fish list.
        //if the vector is empty (no fish around) the player is still given a small chance to get a (let us say it was hidden) fish
        if( fishables.size() < 1 ) {
            if( one_in(20) ) {
                item fish;
                std::vector<std::string> fish_group = MonsterGroupManager::GetMonstersFromGroup( mongroup_id( "GROUP_FISH" ) );
                std::string fish_mon = fish_group[rng(1, fish_group.size()) - 1];
                fish.make_corpse( fish_mon, calendar::turn );
                g->m.add_item_or_charges(p->pos(), fish);
                p->add_msg_if_player(m_good, _("You caught a %s."), GetMType(fish_mon)->nname().c_str());
            } else {
                p->add_msg_if_player(_("You didn't catch anything."));
            }
        } else {
            g->catch_a_monster(fishables, p->pos3(), p, 30000);
        }

    } else {
        p->add_msg_if_player(_("You didn't catch anything."));
    }
}
コード例 #25
0
ファイル: event.cpp プロジェクト: 3721assistant/Cataclysm-DDA
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
 }
}
コード例 #26
0
ファイル: mondeath.cpp プロジェクト: Waladil/Cataclysm-DDA
void mdeath::thing(monster *z)
{
    monster thing(GetMType("mon_thing"));
    thing.spawn(z->posx(), z->posy());
    g->add_zombie(thing);
}
コード例 #27
0
ファイル: mondeath.cpp プロジェクト: Waladil/Cataclysm-DDA
void mdeath::fungus(monster *z)
{
    monster spore(GetMType("mon_spore"));
    bool fungal = false;
    int mondex = -1;
    int sporex, sporey;
    //~ the sound of a fungus dying
    g->sound(z->posx(), z->posy(), 10, _("Pouf!"));
    for (int i = -1; i <= 1; i++) {
        for (int j = -1; j <= 1; j++) {
            sporex = z->posx() + i;
            sporey = z->posy() + j;
            mondex = g->mon_at(sporex, sporey);
            if (g->m.move_cost(sporex, sporey) > 0) {
                if (mondex != -1) {
                    // Spores hit a monster
                    fungal = g->zombie(mondex).type->in_species("FUNGUS");
                    if (g->u_see(sporex, sporey) && !fungal) {
                        add_msg(_("The %s is covered in tiny spores!"),
                                g->zombie(mondex).name().c_str());
                    }
                    monster &critter = g->zombie( mondex );
                    if( !critter.make_fungus() ) {
                        critter.die( z ); // counts as kill by monster z
                    }
                } else if (g->u.posx == sporex && g->u.posy == sporey) {
                    // Spores hit the player
                    if (g->u.has_trait("TAIL_CATTLE") && one_in(20 - g->u.dex_cur - g->u.skillLevel("melee"))) {
                        add_msg(_("The spores land on you, but you quickly swat them off with your tail!"));
                        return;
                    }
                    bool hit = false;
                    if (one_in(4) && g->u.infect("spores", bp_head, 3, 90, false, 1, 3, 120, 1, true)) {
                        hit = true;
                    }
                    if (one_in(2) && g->u.infect("spores", bp_torso, 3, 90, false, 1, 3, 120, 1, true)) {
                        hit = true;
                    }
                    if (one_in(4) && g->u.infect("spores", bp_arm_l, 3, 90, false, 1, 3, 120, 1, true)) {
                        hit = true;
                    }
                    if (one_in(4) && g->u.infect("spores", bp_arm_r, 3, 90, false, 1, 3, 120, 1, true)) {
                        hit = true;
                    }
                    if (one_in(4) && g->u.infect("spores", bp_leg_l, 3, 90, false, 1, 3, 120, 1, true)) {
                        hit = true;
                    }
                    if (one_in(4) && g->u.infect("spores", bp_leg_r, 3, 90, false, 1, 3, 120, 1, true)) {
                        hit = true;
                    }
                    if (hit && (g->u.has_trait("TAIL_CATTLE") &&
                                one_in(20 - g->u.dex_cur - g->u.skillLevel("melee")))) {
                        add_msg(_("The spores land on you, but you quickly swat them off with your tail!"));
                        hit = false;
                    }
                    if (hit) {
                        add_msg(m_warning, _("You're covered in tiny spores!"));
                    }
                } else if (one_in(2) && g->num_zombies() <= 1000) {
                    // Spawn a spore
                    spore.spawn(sporex, sporey);
                    g->add_zombie(spore);
                }
            }
        }
    }
}
コード例 #28
0
ファイル: event.cpp プロジェクト: CepheidVar/Cataclysm-DDA
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
 }
}
コード例 #29
0
ファイル: tutorial.cpp プロジェクト: Catacstone/Cataclysm-DDA
void tutorial_game::post_action(action_id act)
{
 switch (act) {
 case ACTION_RELOAD:
  if (g->u.weapon.is_gun() && !tutorials_seen[LESSON_GUN_FIRE]) {
   monster tmp(GetMType("mon_zombie"), tripoint( g->u.posx(), g->u.posy() - 6, g->u.posz() ) );
   g->add_zombie(tmp);
   tmp.spawn(g->u.posx() + 2, g->u.posy() - 5);
   g->add_zombie(tmp);
   tmp.spawn(g->u.posx() - 2, g->u.posy() - 5);
   g->add_zombie(tmp);
   add_message(LESSON_GUN_FIRE);
  }
  break;

 case ACTION_OPEN:
  add_message(LESSON_CLOSE);
  break;

 case ACTION_CLOSE:
  add_message(LESSON_SMASH);
  break;

 case ACTION_USE:
  if (g->u.has_amount("grenade_act", 1))
   add_message(LESSON_ACT_GRENADE);
  for (int x = g->u.posx() - 1; x <= g->u.posx() + 1; x++) {
   for (int y = g->u.posy() - 1; y <= g->u.posy() + 1; y++) {
    if (g->m.tr_at(x, y) == tr_bubblewrap)
     add_message(LESSON_ACT_BUBBLEWRAP);
   }
  }
  break;

 case ACTION_EAT:
  if (g->u.last_item == "codeine")
   add_message(LESSON_TOOK_PAINKILLER);
  else if (g->u.last_item == "cig")
   add_message(LESSON_TOOK_CIG);
  else if (g->u.last_item == "water")
   add_message(LESSON_DRANK_WATER);
  break;

 case ACTION_WEAR: {
  item it( g->u.last_item, 0 );
  if (it.is_armor()) {
   if (it.get_coverage() >= 2 || it.get_thickness() >= 2)
    add_message(LESSON_WORE_ARMOR);
   if (it.get_storage() >= 20)
    add_message(LESSON_WORE_STORAGE);
   if (it.get_env_resist() >= 2)
    add_message(LESSON_WORE_MASK);
  }
 } break;

 case ACTION_WIELD:
  if (g->u.weapon.is_gun())
   add_message(LESSON_GUN_LOAD);
  break;

 case ACTION_EXAMINE:
  add_message(LESSON_INTERACT);
// Fall through to...
 case ACTION_PICKUP: {
  item it( g->u.last_item, 0 );
  if (it.is_armor())
   add_message(LESSON_GOT_ARMOR);
  else if (it.is_gun())
   add_message(LESSON_GOT_GUN);
  else if (it.is_ammo())
   add_message(LESSON_GOT_AMMO);
  else if (it.is_tool())
   add_message(LESSON_GOT_TOOL);
  else if (it.is_food())
   add_message(LESSON_GOT_FOOD);
  else if (it.is_weap())
   add_message(LESSON_GOT_WEAPON);

  if (g->u.volume_carried() > g->u.volume_capacity() - 2)
   add_message(LESSON_OVERLOADED);
 } break;

 default: //TODO: add more actions here
  break;

 }
}
コード例 #30
0
//Quantity is adjusted directly as a side effect of this function
MonsterGroupResult MonsterGroupManager::GetResultFromGroup(
        std::string group_name, int *quantity, int turn )
{
    int spawn_chance = rng(1, 1000);
    MonsterGroup group = monsterGroupMap[group_name];

    //Our spawn details specify, by default, a single instance of the default monster
    MonsterGroupResult spawn_details = MonsterGroupResult(group.defaultMonster,1);
    //If the default monster is too difficult, replace this with "mon_null"
    if(turn!=-1 && (turn + 900 < MINUTES(STARTING_MINUTES) + HOURS(GetMType(group.defaultMonster)->difficulty))){
        spawn_details = MonsterGroupResult("mon_null",0);
    }

    bool monster_found = false;
    // Step through spawn definitions from the monster group until one is found or
    for (FreqDef_iter it = group.monsters.begin(); it != group.monsters.end() && !monster_found; ++it){
        // There's a lot of conditions to work through to see if this spawn definition is valid
        bool valid_entry = true;
        // I don't know what turn == -1 is checking for, but it makes monsters always valid for difficulty purposes
        valid_entry = valid_entry && (turn == -1 || (turn+900) >= (MINUTES(STARTING_MINUTES) + HOURS(GetMType(it->name)->difficulty)));
        // If we are in classic mode, require the monster type to be either CLASSIC or WILDLIFE
        if(ACTIVE_WORLD_OPTIONS["CLASSIC_ZOMBIES"]){
            valid_entry = valid_entry && (GetMType(it->name)->in_category("CLASSIC") || GetMType(it->name)->in_category("WILDLIFE"));
        }
        //Insure that the time is not before the spawn first appears or after it stops appearing
        valid_entry = valid_entry && (HOURS(it->starts) < g->turn.get_turn());
        valid_entry = valid_entry && (it->lasts_forever() || HOURS(it->ends) > g->turn.get_turn());

        std::vector<std::pair<int,int> > valid_times_of_day;
        bool season_limited = false;
        bool season_matched = false;
        //Collect the various spawn conditions, and then insure they are met appropriately
        for(std::vector<std::string>::iterator condition = it->conditions.begin(); condition != it->conditions.end(); ++condition){
            //Collect valid time of day ranges
            if( (*condition) == "DAY" || (*condition) == "NIGHT" || (*condition) == "DUSK" || (*condition) == "DAWN" ){
                int sunset = g->turn.sunset().get_turn();
                int sunrise = g->turn.sunrise().get_turn();
                if((*condition) == "DAY"){
                    valid_times_of_day.push_back( std::make_pair(sunrise,sunset) );
                } else if((*condition) == "NIGHT"){
                    valid_times_of_day.push_back( std::make_pair(sunset,sunrise) );
                } else if((*condition) == "DUSK"){
                    valid_times_of_day.push_back( std::make_pair(sunset-HOURS(1),sunset+HOURS(1)) );
                } else if((*condition) == "DAWN"){
                    valid_times_of_day.push_back( std::make_pair(sunrise-HOURS(1),sunrise+HOURS(1)) );
                }
            }
            
            //If we have any seasons listed, we know to limit by season, and if any season matches this season, we are good to spawn
            if( (*condition) == "SUMMER" || (*condition) == "WINTER" || (*condition) == "SPRING" || (*condition) == "AUTUMN" ){
                season_limited = true;
                if( (g->turn.get_season() == SUMMER && (*condition) == "SUMMER") ||
                    (g->turn.get_season() == WINTER && (*condition) == "WINTER") ||
                    (g->turn.get_season() == SPRING && (*condition) == "SPRING") ||
                    (g->turn.get_season() == AUTUMN && (*condition) == "AUTUMN") ){
                    season_matched = true;
                }
            }
        }

        //Make sure the current time of day is within one of the valid time ranges for this spawn
        bool is_valid_time_of_day = false;
        if(valid_times_of_day.size() < 1){
            //Then it can spawn whenever, since no times were defined
            is_valid_time_of_day = true;
        } else {
            //Otherwise, it's valid if it matches any of the times of day
            for(std::vector<std::pair<int,int> >::iterator time_pair = valid_times_of_day.begin(); time_pair != valid_times_of_day.end(); ++time_pair){
                int time_now = g->turn.get_turn();
                if(time_now > time_pair->first &&  time_now < time_pair->second){
                    is_valid_time_of_day = true;
                }
            }
        }
        if(!is_valid_time_of_day){
            valid_entry = false;
        }

        //If we are limited by season, make sure we matched a season
        if(season_limited && !season_matched){
            valid_entry = false;
        }

        //If the entry was valid, check to see if we actually spawn it
        if(valid_entry){
            //If the monsters frequency is greater than the spawn_chance, select this spawn rule
            if(it->frequency >= spawn_chance){
                if(it->pack_maximum > 1){
                  spawn_details = MonsterGroupResult(it->name, rng(it->pack_minimum,it->pack_maximum));
                } else {
                  spawn_details = MonsterGroupResult(it->name, 1);
                }
                //And if a quantity pointer with remaining value was passed, will will modify the external value as a side effect
                //We will reduce it by the spawn rule's cost multiplier
                if(quantity){
                    *quantity -= it->cost_multiplier * spawn_details.pack_size;
                }
                monster_found = true;
            //Otherwise, subtract the frequency from spawn result for the next loop around
            }else{
                spawn_chance -= it->frequency;
            }
        }
    }

    return spawn_details;
}