Esempio n. 1
0
// TODO: Shunt redundant drawing code elsewhere
std::vector<point> game::target(int &x, int &y, int lowx, int lowy, int hix,
                                int hiy, std::vector <monster> t, int &target,
                                item *relevent)
{
 std::vector<point> ret;
 int tarx, tary, junk, tart;
 int range=(hix-u.posx);
// First, decide on a target among the monsters, if there are any in range
 if (!t.empty()) {
// Check for previous target
  if (target == -1) {
// If no previous target, target the closest there is
   double closest = -1;
   double dist;
   for (int i = 0; i < t.size(); i++) {
    dist = rl_dist(t[i].posx(), t[i].posy(), u.posx, u.posy);
    if (closest < 0 || dist < closest) {
     closest = dist;
     target = i;
    }
   }
  }
  x = t[target].posx();
  y = t[target].posy();
 } else
  target = -1; // No monsters in range, don't use target, reset to -1

 bool sideStyle = use_narrow_sidebar();
 int height = 13;
 int width  = getmaxx(w_messages);
 int top    = sideStyle ? getbegy(w_messages) : (getbegy(w_minimap) + getmaxy(w_minimap));
 int left   = getbegx(w_messages);
 WINDOW* w_target = newwin(height, width, top, left);
 draw_border(w_target);
 mvwprintz(w_target, 0, 2, c_white, "< ");
 if (!relevent) { // currently targetting vehicle to refill with fuel
   wprintz(w_target, c_red, _("Select a vehicle"));
 } else {
   if (relevent == &u.weapon && relevent->is_gun()) {
     wprintz(w_target, c_red, _("Firing %s (%d)"), // - %s (%d)",
            u.weapon.tname().c_str(),// u.weapon.curammo->name.c_str(),
            u.weapon.charges);
   } else {
     wprintz(w_target, c_red, _("Throwing %s"), relevent->tname().c_str());
   }
 }
 wprintz(w_target, c_white, " >");
/* Annoying clutter @ 2 3 4. */
 int text_y = getmaxy(w_target) - 4;
 if (is_mouse_enabled()) {
     --text_y;
 }
 mvwprintz(w_target, text_y++, 1, c_white,
           _("Move cursor to target with directional keys"));
 if (relevent) {
  mvwprintz(w_target, text_y++, 1, c_white,
            _("'<' '>' Cycle targets; 'f' or '.' to fire"));
  mvwprintz(w_target, text_y++, 1, c_white,
            _("'0' target self; '*' toggle snap-to-target"));
 }

 if (is_mouse_enabled()) {
     mvwprintz(w_target, text_y++, 1, c_white,
         _("Mouse: LMB: Target, Wheel: Cycle, RMB: Fire"));
 }

 wrefresh(w_target);
 bool snap_to_target = OPTIONS["SNAP_TO_TARGET"];
 do {
  if (m.sees(u.posx, u.posy, x, y, -1, tart))
    ret = line_to(u.posx, u.posy, x, y, tart);
  else
    ret = line_to(u.posx, u.posy, x, y, 0);

  if(trigdist && trig_dist(u.posx,u.posy, x,y) > range) {
    bool cont=true;
    int cx=x;
    int cy=y;
    for (int i = 0; i < ret.size() && cont; i++) {
      if(trig_dist(u.posx,u.posy, ret[i].x, ret[i].y) > range) {
        ret.resize(i);
        cont=false;
      } else {
        cx=0+ret[i].x; cy=0+ret[i].y;
      }
    }
    x=cx;y=cy;
  }
  point center;
  if (snap_to_target)
   center = point(x, y);
  else
   center = point(u.posx + u.view_offset_x, u.posy + u.view_offset_y);
  // Clear the target window.
  for (int i = 1; i < getmaxy(w_target) - 5; i++) {
   for (int j = 1; j < getmaxx(w_target) - 2; j++)
    mvwputch(w_target, i, j, c_white, ' ');
  }
  /* Start drawing w_terrain things -- possibly move out to centralized draw_terrain_window function as they all should be roughly similar*/
  m.build_map_cache(); // part of the SDLTILES drawing code
  m.draw(w_terrain, center); // embedded in SDL drawing code
  // Draw the Monsters
  for (int i = 0; i < num_zombies(); i++) {
   if (u_see(&(zombie(i)))) {
    zombie(i).draw(w_terrain, center.x, center.y, false);
   }
  }
  // Draw the NPCs
  for (int i = 0; i < active_npc.size(); i++) {
   if (u_see(active_npc[i]->posx, active_npc[i]->posy))
    active_npc[i]->draw(w_terrain, center.x, center.y, false);
  }
  if (x != u.posx || y != u.posy) {

   // Draw the player
   int atx = POSX + u.posx - center.x, aty = POSY + u.posy - center.y;
   if (atx >= 0 && atx < TERRAIN_WINDOW_WIDTH && aty >= 0 && aty < TERRAIN_WINDOW_HEIGHT)
    mvwputch(w_terrain, aty, atx, u.color(), '@');

   // Only draw a highlighted trajectory if we can see the endpoint.
   // Provides feedback to the player, and avoids leaking information about tiles they can't see.
   draw_line(x, y, center, ret);
/*
   if (u_see( x, y)) {
    for (int i = 0; i < ret.size(); i++) {
      int mondex = mon_at(ret[i].x, ret[i].y),
          npcdex = npc_at(ret[i].x, ret[i].y);
      // NPCs and monsters get drawn with inverted colors
      if (mondex != -1 && u_see(&(zombie(mondex))))
       zombie(mondex).draw(w_terrain, center.x, center.y, true);
      else if (npcdex != -1)
       active_npc[npcdex]->draw(w_terrain, center.x, center.y, true);
      else
       m.drawsq(w_terrain, u, ret[i].x, ret[i].y, true,true,center.x, center.y);
    }
   }
//*/
            // Print to target window
            if (!relevent) {
                // currently targetting vehicle to refill with fuel
                vehicle *veh = m.veh_at(x, y);
                if (veh) {
                    mvwprintw(w_target, 1, 1, _("There is a %s"),
                              veh->name.c_str());
                }
            } else if (relevent == &u.weapon && relevent->is_gun()) {
                // firing a gun
                mvwprintw(w_target, 1, 1, _("Range: %d"),
                          rl_dist(u.posx, u.posy, x, y));
                // get the current weapon mode or mods
                std::string mode = "";
                if (u.weapon.mode == "MODE_BURST") {
                    mode = _("Burst");
                } else {
                    item* gunmod = u.weapon.active_gunmod();
                    if (gunmod != NULL) {
                        mode = gunmod->type->name;
                    }
                }
                if (mode != "") {
                    mvwprintw(w_target, 1, 14, _("Firing mode: %s"),
                              mode.c_str());
                }
            } else {
                // throwing something
                mvwprintw(w_target, 1, 1, _("Range: %d"),
                          rl_dist(u.posx, u.posy, x, y));
            }

   const int zid = mon_at(x, y);
   if (zid == -1) {
    if (snap_to_target)
     mvwputch(w_terrain, POSY, POSX, c_red, '*');
    else
     mvwputch(w_terrain, POSY + y - center.y, POSX + x - center.x, c_red, '*');
   } else {
    if (u_see(&(zombie(zid)))) {
     zombie(zid).print_info(w_target,2);
    }
   }
  }
  wrefresh(w_target);
  wrefresh(w_terrain);
  wrefresh(w_status);
  refresh();

  input_context ctxt("TARGET");
  // "ANY_INPUT" should be added before any real help strings
  // Or strings will be writen on window border.
  ctxt.register_action("ANY_INPUT");
  ctxt.register_directions();
  ctxt.register_action("COORDINATE");
  ctxt.register_action("SELECT");
  ctxt.register_action("FIRE");
  ctxt.register_action("NEXT_TARGET");
  ctxt.register_action("PREV_TARGET");
  ctxt.register_action("WAIT");
  ctxt.register_action("CENTER");
  ctxt.register_action("TOGGLE_SNAP_TO_TARGET");
  ctxt.register_action("HELP_KEYBINDINGS");
  ctxt.register_action("QUIT");

  const std::string& action = ctxt.handle_input();


  tarx = 0; tary = 0;
  // Our coordinates will either be determined by coordinate input(mouse),
  // by a direction key, or by the previous value.
  if (action == "SELECT" && ctxt.get_coordinates(g->w_terrain, tarx, tary)) {
      if (!OPTIONS["USE_TILES"] && snap_to_target) {
          // Snap to target doesn't currently work with tiles.
          tarx += x - u.posx;
          tary += y - u.posy;
      }
      tarx -= x;
      tary -= y;


  } else {
    ctxt.get_direction(tarx, tary, action);
    if(tarx == -2) {
        tarx = 0;
        tary = 0;
    }
  }

  /* More drawing to terrain */
  if (tarx != 0 || tary != 0) {
   int mondex = mon_at(x, y), npcdex = npc_at(x, y);
   if (mondex != -1 && u_see(&(zombie(mondex))))
    zombie(mondex).draw(w_terrain, center.x, center.y, false);
   else if (npcdex != -1)
    active_npc[npcdex]->draw(w_terrain, center.x, center.y, false);
   else if (m.sees(u.posx, u.posy, x, y, -1, junk))
    m.drawsq(w_terrain, u, x, y, false, true, center.x, center.y);
   else
    mvwputch(w_terrain, POSY, POSX, c_black, 'X');
   x += tarx;
   y += tary;
   if (x < lowx)
    x = lowx;
   else if (x > hix)
    x = hix;
   if (y < lowy)
    y = lowy;
   else if (y > hiy)
    y = hiy;
  } else if ((action == "PREV_TARGET") && (target != -1)) {
   target--;
   if (target == -1) target = t.size() - 1;
   x = t[target].posx();
   y = t[target].posy();
  } else if ((action == "NEXT_TARGET") && (target != -1)) {
   target++;
   if (target == t.size()) target = 0;
   x = t[target].posx();
   y = t[target].posy();
  } else if (action == "WAIT" || action == "FIRE") {
   for (int i = 0; i < t.size(); i++) {
    if (t[i].posx() == x && t[i].posy() == y)
     target = i;
   }
   if (u.posx == x && u.posy == y)
       ret.clear();
   break;
  } else if (action == "CENTER") {
   x = u.posx;
   y = u.posy;
   ret.clear();
  } else if (action == "TOGGLE_SNAP_TO_TARGET")
   snap_to_target = !snap_to_target;
  else if (action == "QUIT") { // return empty vector (cancel)
   ret.clear();
   break;
  }
 } while (true);

 return ret;
}
Esempio n. 2
0
/*
 * Save to opened character.sav
 */
void game::serialize(std::ofstream & fout) {
/*
 * Format version 12: Fully json, save the header. Weather and memorial exist elsewhere.
 * To prevent (or encourage) confusion, there is no version 8. (cata 0.8 uses v7)
 */
        // Header
        fout << "# version " << savegame_version << std::endl;

        std::map<std::string, picojson::value> data;
        // basic game state information.
        data["turn"] = pv( (int)turn );
        data["last_target"] = pv( (int)last_target );
        data["run_mode"] = pv( (int)run_mode );
        data["mostseen"] = pv( mostseen );
        data["nextinv"] = pv( (int)nextinv );
        data["next_npc_id"] = pv( next_npc_id );
        data["next_faction_id"] = pv( next_faction_id );
        data["next_mission_id"] = pv( next_mission_id );
        data["nextspawn"] = pv( (int)nextspawn );
        // current map coordinates
        data["levx"] = pv( levx );
        data["levy"] = pv( levy );
        data["levz"] = pv( levz );
        data["om_x"] = pv( cur_om->pos().x );
        data["om_y"] = pv( cur_om->pos().y );

        // Next, the scent map.
        std::stringstream rle_out;
        int rle_lastval = -1;
        int rle_count = 0;
        for (int i = 0; i < SEEX * MAPSIZE; i++) {
            for (int j = 0; j < SEEY * MAPSIZE; j++) {
               int val = grscent[i][j];
               if (val == rle_lastval) {
                   rle_count++;
               } else {
                   if ( rle_count ) {
                       rle_out << rle_count << " ";
                   }
                   rle_out << val << " ";
                   rle_lastval = val;
                   rle_count = 1;
               }
            }
        }
        rle_out << rle_count;
        data["grscent"] = pv ( rle_out.str() );

        // Then each monster
        std::vector<picojson::value> amdata;
        for (int i = 0; i < num_zombies(); i++) {
            amdata.push_back( _active_monsters[i].json_save(true) );
        }
        data["active_monsters"] = pv( amdata );

        // save killcounts.
        std::map<std::string, picojson::value> killmap;
        for (std::map<std::string, int>::iterator kill = kills.begin(); kill != kills.end(); ++kill){
            killmap[kill->first] = pv(kill->second);
        }
        data["kills"] = pv( killmap );

        data["player"] = pv( u.json_save(true) );

        fout << pv(data).serialize() << std::endl;
        ////////
}
Esempio n. 3
0
/*
 * Save to opened character.sav
 */
void game::serialize(std::ofstream & fout) {
/*
 * Format version 9: Hybrid format. Ordered, line by line mix of json chunks, and stringstream bits that don't
 * really make sense as json. New data can be added to the basic game state json, or tacked onto the end as a
 * new line.
 * To prevent (or encourage) confusion, there is no version 8. (cata 0.8 uses v7)
 */
        // Header
        fout << "# version " << savegame_version << std::endl;

        std::map<std::string, picojson::value> data;
        // basic game state information.
        data["turn"] = pv( (int)turn );
        data["last_target"] = pv( (int)last_target );
        data["run_mode"] = pv( (int)run_mode );
        data["mostseen"] = pv( mostseen );
        data["nextinv"] = pv( (int)nextinv );
        data["next_npc_id"] = pv( next_npc_id );
        data["next_faction_id"] = pv( next_faction_id );
        data["next_mission_id"] = pv( next_mission_id );
        data["nextspawn"] = pv( (int)nextspawn );
        // current map coordinates
        data["levx"] = pv( levx );
        data["levy"] = pv( levy );
        data["levz"] = pv( levz );
        data["om_x"] = pv( cur_om->pos().x );
        data["om_y"] = pv( cur_om->pos().y );
        fout << pv(data).serialize();
        fout << std::endl;

        // Weather. todo: move elsewhere
        fout << save_weather();
        fout << std::endl;

        // Next, the scent map.
        for (int i = 0; i < SEEX * MAPSIZE; i++) {
            for (int j = 0; j < SEEY * MAPSIZE; j++) {
                fout << grscent[i][j] << " ";
            }
        }

        // Now save all monsters. First the amount
        fout << std::endl << num_zombies() << std::endl;
        // Then each monster + inv in a 1 line json string
        for (int i = 0; i < num_zombies(); i++) {
            fout << _active_monsters[i].save_info() << std::endl;
        }

        // save killcounts.
        std::map<std::string, picojson::value> killmap;
        for (int i = 0; i < num_monsters; i++) {
            if ( kills[i] > 0 ) {
                killmap[ monster_names[ i ] ] = pv ( kills[i] );
            }
        }
        fout << pv( killmap ).serialize() << std::endl;

        // And finally the player.
        // u.save_info dumps player + contents in a single json line, followed by memorial log
        // one entry per line starting with '|'
        fout << u.save_info() << std::endl; 

        fout << std::endl;
        ////////
}