Skip to content

Commit

Permalink
Merge branch 'just-optimization'
Browse files Browse the repository at this point in the history
Conflicts:
	map.cpp
  • Loading branch information
kevingranade committed Oct 19, 2012
2 parents e228af3 + 39a7e8a commit d383930
Show file tree
Hide file tree
Showing 7 changed files with 144 additions and 64 deletions.
151 changes: 104 additions & 47 deletions map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ map::map()
my_MAPSIZE = 2;
else
my_MAPSIZE = MAPSIZE;
veh_in_active_range = true;
}

map::map(std::vector<itype*> *itptr, std::vector<itype_id> (*miptr)[num_itloc],
Expand All @@ -42,6 +43,7 @@ map::map(std::vector<itype*> *itptr, std::vector<itype_id> (*miptr)[num_itloc],
my_MAPSIZE = MAPSIZE;
for (int n = 0; n < my_MAPSIZE * my_MAPSIZE; n++)
grid[n] = NULL;
veh_in_active_range = true;
}

map::~map()
Expand All @@ -50,30 +52,15 @@ map::~map()

vehicle* map::veh_at(int x, int y, int &part_num)
{
if (!inbounds(x, y))
// This function is called A LOT. Move as much out of here as possible.
if (!veh_in_active_range || !inbounds(x, y))
return NULL; // Out-of-bounds - null vehicle
int nonant = int(x / SEEX) + int(y / SEEY) * my_MAPSIZE;

x %= SEEX;
y %= SEEY;

// must check 3x3 map chunks, as vehicle part may span to neighbour chunk
// we presume that vehicles don't intersect (they shouldn't by any means)
for (int mx = -1; mx <= 1; mx++) {
for (int my = -1; my <= 1; my++) {
int nonant1 = nonant + mx + my * my_MAPSIZE;
if (nonant1 < 0 || nonant1 >= my_MAPSIZE * my_MAPSIZE)
continue; // out of grid
for (int i = 0; i < grid[nonant1]->vehicles.size(); i++) {
vehicle *veh = &(grid[nonant1]->vehicles[i]);
int part = veh->part_at (x - (veh->posx + mx * SEEX),
y - (veh->posy + my * SEEY));
if (part >= 0) {
part_num = part;
return veh;
}
}
}
std::pair<int,int> point(x,y);
std::map< std::pair<int,int>, std::pair<vehicle*,int> >::iterator it;
if ((it = veh_cached_parts.find(point)) != veh_cached_parts.end())
{
part_num = it->second.second;
return it->second.first;
}
return NULL;
}
Expand All @@ -85,6 +72,47 @@ vehicle* map::veh_at(int x, int y)
return veh;
}

void map::reset_vehicle_cache()
{
// Cache all vehicles
veh_cached_parts.clear();
veh_in_active_range = false;
for( std::set<vehicle*>::iterator veh = vehicle_list.begin(),
it_end = vehicle_list.end(); veh != it_end; ++veh ) {
update_vehicle_cache(*veh, true);
}
}

void map::update_vehicle_cache(vehicle * veh, bool brand_new)
{
veh_in_active_range = true;
if(!brand_new){
// Existing must be cleared
std::map< std::pair<int,int>, std::pair<vehicle*,int> >::iterator it =
veh_cached_parts.begin(), end = veh_cached_parts.end(), tmp;
while( it != end ) {
if( it->second.first == veh ) {
tmp = it;
++it;
veh_cached_parts.erase( tmp );
}else
++it;
}
}
// Get parts
std::vector<vehicle_part> & parts = veh->parts;
const int gx = veh->global_x();
const int gy = veh->global_y();
int partid = 0;
for( std::vector<vehicle_part>::iterator it = parts.begin(),
end = parts.end(); it != end; ++it, ++partid ) {
const int px = gx + it->precalc_dx[0];
const int py = gy + it->precalc_dy[0];
veh_cached_parts.insert( std::make_pair( std::make_pair(px,py),
std::make_pair(veh,partid) ));
}
}

void map::board_vehicle(game *g, int x, int y, player *p)
{
if (!p) {
Expand Down Expand Up @@ -155,7 +183,9 @@ void map::destroy_vehicle (vehicle *veh)
}
int sm = veh->smx + veh->smy * my_MAPSIZE;
for (int i = 0; i < grid[sm]->vehicles.size(); i++) {
if (&(grid[sm]->vehicles[i]) == veh) {
if (grid[sm]->vehicles[i] == veh) {
vehicle_list.erase(veh);
reset_vehicle_cache();
grid[sm]->vehicles.erase (grid[sm]->vehicles.begin() + i);
return;
}
Expand Down Expand Up @@ -194,8 +224,8 @@ bool map::displace_vehicle (game *g, int &x, int &y, int dx, int dy, bool test=f
// first, let's find our position in current vehicles vector
int our_i = -1;
for (int i = 0; i < grid[src_na]->vehicles.size(); i++) {
if (grid[src_na]->vehicles[i].posx == srcx &&
grid[src_na]->vehicles[i].posy == srcy) {
if (grid[src_na]->vehicles[i]->posx == srcx &&
grid[src_na]->vehicles[i]->posy == srcy) {
our_i = i;
break;
}
Expand All @@ -205,7 +235,7 @@ bool map::displace_vehicle (game *g, int &x, int &y, int dx, int dy, bool test=f
return false;
}
// move the vehicle
vehicle *veh = &(grid[src_na]->vehicles[our_i]);
vehicle *veh = grid[src_na]->vehicles[our_i];
// don't let it go off grid
if (!inbounds(x2, y2))
veh->stop();
Expand Down Expand Up @@ -254,16 +284,18 @@ bool map::displace_vehicle (game *g, int &x, int &y, int dx, int dy, bool test=f
veh->posx = dstx;
veh->posy = dsty;
if (src_na != dst_na) {
vehicle veh1 = *veh;
veh1.smx = int(x2 / SEEX);
veh1.smy = int(y2 / SEEY);
vehicle * veh1 = veh;
veh1->smx = int(x2 / SEEX);
veh1->smy = int(y2 / SEEY);
grid[dst_na]->vehicles.push_back (veh1);
grid[src_na]->vehicles.erase (grid[src_na]->vehicles.begin() + our_i);
}

x += dx;
y += dy;

update_vehicle_cache(veh);

bool was_update = false;
if (need_update &&
(upd_x < SEEX * int(my_MAPSIZE / 2) || upd_y < SEEY *int(my_MAPSIZE / 2) ||
Expand All @@ -281,6 +313,7 @@ bool map::displace_vehicle (game *g, int &x, int &y, int dx, int dy, bool test=f
g->update_map(upd_x, upd_y);
was_update = true;
}

return (src_na != dst_na) || was_update;
}

Expand All @@ -291,7 +324,7 @@ void map::vehmove(game *g)
for (int j = 0; j < my_MAPSIZE; j++) {
int sm = i + j * my_MAPSIZE;
for (int v = 0; v < grid[sm]->vehicles.size(); v++) {
vehicle *veh = &(grid[sm]->vehicles[v]);
vehicle *veh = grid[sm]->vehicles[v];
// velocity is ability to make more one-tile steps per turn
veh->gain_moves (abs (veh->velocity));
}
Expand All @@ -307,7 +340,7 @@ void map::vehmove(game *g)
int sm = i + j * my_MAPSIZE;

for (int v = 0; v < grid[sm]->vehicles.size(); v++) {
vehicle *veh = &(grid[sm]->vehicles[v]);
vehicle *veh = grid[sm]->vehicles[v];
bool pl_ctrl = veh->player_in_control(&g->u);
while (!sm_change && veh->moves > 0 && veh->velocity != 0) {
int x = veh->posx + i * SEEX;
Expand Down Expand Up @@ -515,6 +548,7 @@ void map::vehmove(game *g)
if (count > 10)
break;
} while (sm_change);

}

bool map::displace_water (int x, int y)
Expand Down Expand Up @@ -611,8 +645,11 @@ int map::move_cost_ter_only(int x, int y)
return terlist[ter(x, y)].movecost;
}

bool map::trans(int x, int y)
bool map::trans(int x, int y, char * trans_buf)
{
if(trans_buf && trans_buf[x + (y * my_MAPSIZE * SEEX)] != -1)
return trans_buf[x + (y + my_MAPSIZE * SEEX)];

// Control statement is a problem. Normally returning false on an out-of-bounds
// is how we stop rays from going on forever. Instead we'll have to include
// this check in the ray loop.
Expand All @@ -628,9 +665,16 @@ bool map::trans(int x, int y)
}
} else
tertr = terlist[ter(x, y)].flags & mfb(transparent);
return tertr &&
(field_at(x, y).type == 0 || // Fields may obscure the view, too
fieldlist[field_at(x, y).type].transparent[field_at(x, y).density - 1]);
if( tertr )
{
field & f(field_at(x, y));
if(f.type == 0 || // Fields may obscure the view, too
fieldlist[f.type].transparent[f.density - 1]);
if(trans_buf) trans_buf[x + (y * my_MAPSIZE * SEEX)] = 1;
return true;
}
if(trans_buf) trans_buf[x + (y * my_MAPSIZE * SEEX)] = 0;
return false;
}

bool map::has_flag(t_flag flag, int x, int y)
Expand Down Expand Up @@ -1805,6 +1849,8 @@ void map::draw(game *g, WINDOW* w, point center)
}
int t = 0;
int light = g->u.sight_range(g->light_level());
char trans_buf[my_MAPSIZE*SEEX][my_MAPSIZE*SEEY];
memset(trans_buf, -1, sizeof(trans_buf));
for (int realx = center.x - SEEX; realx <= center.x + SEEX; realx++) {
for (int realy = center.y - SEEY; realy <= center.y + SEEY; realy++) {
int dist = rl_dist(g->u.posx, g->u.posy, realx, realy);
Expand Down Expand Up @@ -1917,7 +1963,7 @@ void map::drawsq(WINDOW* w, player &u, int x, int y, bool invert,
map::sees based off code by Steve Register [[email protected]]
http://roguebasin.roguelikedevelopment.org/index.php?title=Simple_Line_of_Sight
*/
bool map::sees(int Fx, int Fy, int Tx, int Ty, int range, int &tc)
bool map::sees(int Fx, int Fy, int Tx, int Ty, int range, int &tc, char * trans_buf)
{
int dx = Tx - Fx;
int dy = Ty - Fy;
Expand Down Expand Up @@ -1952,7 +1998,7 @@ bool map::sees(int Fx, int Fy, int Tx, int Ty, int range, int &tc)
tc *= st;
return true;
}
} while ((trans(x, y)) && (INBOUNDS(x,y)));
} while ((trans(x, y, trans_buf)) && (INBOUNDS(x,y)));
}
return false;
} else { // Same as above, for mostly-vertical lines
Expand All @@ -1972,7 +2018,7 @@ bool map::sees(int Fx, int Fy, int Tx, int Ty, int range, int &tc)
tc *= st;
return true;
}
} while ((trans(x, y)) && (INBOUNDS(x,y)));
} while ((trans(x, y, trans_buf)) && (INBOUNDS(x,y)));
}
return false;
}
Expand Down Expand Up @@ -2214,6 +2260,7 @@ void map::shift(game *g, int wx, int wy, int sx, int sy)
g->u.posy -= sy * SEEY;
}


// Shift the map sx submaps to the right and sy submaps down.
// sx and sy should never be bigger than +/-1.
// wx and wy are our position in the world, for saving/loading purposes.
Expand Down Expand Up @@ -2278,6 +2325,7 @@ void map::shift(game *g, int wx, int wy, int sx, int sy)
}
}
}
reset_vehicle_cache();
}

// saven saves a single nonant. worldx and worldy are used for the file
Expand Down Expand Up @@ -2312,9 +2360,19 @@ bool map::loadn(game *g, int worldx, int worldy, int gridx, int gridy, bool upda
submap *tmpsub = MAPBUFFER.lookup_submap(absx, absy, g->cur_om.posz);
if (tmpsub) {
grid[gridn] = tmpsub;
for (int i = 0; update_vehicles && i < grid[gridn]->vehicles.size(); i++) {
grid[gridn]->vehicles[i].smx = gridx;
grid[gridn]->vehicles[i].smy = gridy;

// Update vehicle data
for( std::vector<vehicle*>::iterator it = tmpsub->vehicles.begin(),
end = tmpsub->vehicles.end(); it != end; ++it ) {

// Only add if not tracking already.
if( vehicle_list.find( *it ) == vehicle_list.end() ) {
// gridx/y not correct. TODO: Fix
(*it)->smx = gridx;
(*it)->smy = gridy;
vehicle_list.insert(*it);
update_vehicle_cache(*it);
}
}
} else { // It doesn't exist; we must generate it!
map tmp_map(itypes, mapitems, traps);
Expand All @@ -2327,8 +2385,6 @@ bool map::loadn(game *g, int worldx, int worldy, int gridx, int gridy, bool upda
newmapx = worldx + gridx;
if (worldy + gridy < 0)
newmapy = worldy + gridy;
if (worldx + gridx < 0)
newmapx = worldx + gridx;
tmp_map.generate(g, &(g->cur_om), newmapx, newmapy, int(g->turn));
return false;
}
Expand All @@ -2338,9 +2394,10 @@ bool map::loadn(game *g, int worldx, int worldy, int gridx, int gridy, bool upda
void map::copy_grid(int to, int from)
{
grid[to] = grid[from];
for (int i = 0; i < grid[to]->vehicles.size(); i++) {
grid[to]->vehicles[i].smx = to % my_MAPSIZE;
grid[to]->vehicles[i].smy = to / my_MAPSIZE;
for( std::vector<vehicle*>::iterator it = grid[to]->vehicles.begin(),
end = grid[to]->vehicles.end(); it != end; ++it ) {
(*it)->smx = to % my_MAPSIZE;
(*it)->smy = to / my_MAPSIZE;
}
}

Expand Down
12 changes: 10 additions & 2 deletions map.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#include <stdlib.h>
#include <vector>
#include <string>
#include <set>
#include <map>

#include "mapdata.h"
#include "mapitems.h"
Expand Down Expand Up @@ -51,11 +53,11 @@ class map
// Movement and LOS
int move_cost(int x, int y); // Cost to move through; 0 = impassible
int move_cost_ter_only(int x, int y); // same as above, but don't take vehicles into account
bool trans(int x, int y); // Transparent?
bool trans(int x, int y, char * trans_buf = NULL); // Transparent?
// (Fx, Fy) sees (Tx, Ty), within a range of (range)?
// tc indicates the Bresenham line used to connect the two points, and may
// subsequently be used to form a path between them
bool sees(int Fx, int Fy, int Tx, int Ty, int range, int &tc);
bool sees(int Fx, int Fy, int Tx, int Ty, int range, int &tc, char * trans_buf = NULL);
// clear_path is the same idea, but uses cost_min <= move_cost <= cost_max
bool clear_path(int Fx, int Fy, int Tx, int Ty, int range, int cost_min,
int cost_max, int &tc);
Expand All @@ -69,6 +71,8 @@ class map
// put player on vehicle at x,y
void board_vehicle(game *g, int x, int y, player *p);
void unboard_vehicle(game *g, int x, int y);//remove player from vehicle at x,y
void update_vehicle_cache(vehicle *, bool brand_new = false);
void reset_vehicle_cache();

void destroy_vehicle (vehicle *veh);
// Change vehicle coords and move vehicle's driver along.
Expand Down Expand Up @@ -155,6 +159,8 @@ class map
computer* add_computer(int x, int y, std::string name, int security);

std::vector <itype*> *itypes;
std::set<vehicle*> vehicle_list;
std::map< std::pair<int,int>, std::pair<vehicle*,int> > veh_cached_parts;

protected:
void saven(overmap *om, unsigned int turn, int x, int y, int gridx, int gridy);
Expand All @@ -181,6 +187,8 @@ class map
std::vector <trap*> *traps;
std::vector <itype_id> (*mapitems)[num_itloc];

bool veh_in_active_range;

private:
submap* grid[MAPSIZE * MAPSIZE];
};
Expand Down
7 changes: 4 additions & 3 deletions mapbuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ void mapbuffer::save()
// Output the vehicles
for (int i = 0; i < sm->vehicles.size(); i++) {
fout << "V ";
sm->vehicles[i].save (fout);
sm->vehicles[i]->save (fout);
}
// Output the computer
if (sm->comp.name != "")
Expand Down Expand Up @@ -234,10 +234,11 @@ void mapbuffer::load()
spawnname);
sm->spawns.push_back(tmp);
} else if (string_identifier == "V") {
vehicle veh(master_game);
veh.load (fin);
vehicle * veh = new vehicle(master_game);
veh->load (fin);
//veh.smx = gridx;
//veh.smy = gridy;
master_game->m.vehicle_list.insert(veh);
sm->vehicles.push_back(veh);
} else if (string_identifier == "c") {
getline(fin, databuff);
Expand Down
Loading

0 comments on commit d383930

Please sign in to comment.