Skip to content

Commit

Permalink
Merge PR #2520 - Dragging vehicles
Browse files Browse the repository at this point in the history
  • Loading branch information
i2amroy committed Aug 22, 2013
2 parents 2fa06f6 + 4040395 commit db2e2b8
Show file tree
Hide file tree
Showing 16 changed files with 254 additions and 83 deletions.
4 changes: 4 additions & 0 deletions action.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,8 @@ std::string action_ident(action_id act)
return "advinv";
case ACTION_PICKUP:
return "pickup";
case ACTION_GRAB:
return "grab";
case ACTION_BUTCHER:
return "butcher";
case ACTION_CHAT:
Expand Down Expand Up @@ -355,6 +357,8 @@ std::string action_name(action_id act)
return _("Examine Nearby Terrain");
case ACTION_PICKUP:
return _("Pick Item(s) Up");
case ACTION_GRAB:
return _("Grab a nearby vehicle");
case ACTION_BUTCHER:
return _("Butcher");
case ACTION_CHAT:
Expand Down
1 change: 1 addition & 0 deletions action.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ ACTION_CLOSE,
ACTION_SMASH,
ACTION_EXAMINE,
ACTION_PICKUP,
ACTION_GRAB,
ACTION_BUTCHER,
ACTION_CHAT,
ACTION_LOOK,
Expand Down
115 changes: 111 additions & 4 deletions game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1869,6 +1869,10 @@ bool game::handle_action()
pickup(u.posx, u.posy, 1);
break;

case ACTION_GRAB:
grab();
break;

case ACTION_BUTCHER:
butcher();
break;
Expand Down Expand Up @@ -8861,6 +8865,32 @@ void game::pickup(int posx, int posy, int min)
delwin(w_item_info);
}

// Establish or release a grab on a vehicle
void game::grab()
{
int grabx = 0;
int graby = 0;
if( 0 != u.grab_point.x || 0 != u.grab_point.y ) {
vehicle *veh = m.veh_at( u.posx + u.grab_point.x, u.posy + u.grab_point.y );
if( veh ) { add_msg(_("You release %s."), veh->name.c_str() ); }
u.grab_point.x = 0;
u.grab_point.y = 0;
return;
}
if( choose_adjacent( _("Grab"), grabx, graby ) ) {
vehicle *veh = m.veh_at(grabx, graby);
if( veh != NULL ) {
u.grab_point.x = grabx - u.posx;
u.grab_point.y = graby - u.posy;
add_msg(_("You grab the %s."), veh->name.c_str());
} else {
add_msg(_("There's no vehicle to grab there!"));
}
} else {
add_msg(_("Never Mind."));
}
}

// Handle_liquid returns false if we didn't handle all the liquid.
bool game::handle_liquid(item &liquid, bool from_ground, bool infinite, item *source)
{
Expand Down Expand Up @@ -10177,7 +10207,7 @@ void game::pldrive(int x, int y) {
u.practice(turn, "driving", 1);
}

void game::plmove(int x, int y)
void game::plmove(int dx, int dy)
{
if (run_mode == 2) { // Monsters around and we don't wanna run
add_msg(_("Monster spotted--safe mode is on! \
Expand All @@ -10186,12 +10216,14 @@ void game::plmove(int x, int y)
from_sentence_case(press_x(ACTION_IGNORE_ENEMY)).c_str());
return;
}
int x = 0;
int y = 0;
if (u.has_disease("stunned")) {
x = rng(u.posx - 1, u.posx + 1);
y = rng(u.posy - 1, u.posy + 1);
} else {
x += u.posx;
y += u.posy;
x = u.posx + dx;
y = u.posy + dy;

if (moveCount % 60 == 0) {
if (u.has_bionic("bio_torsionratchet")) {
Expand Down Expand Up @@ -10293,6 +10325,16 @@ void game::plmove(int x, int y)
int vpart0 = -1, vpart1 = -1, dpart = -1;
vehicle *veh0 = m.veh_at(u.posx, u.posy, vpart0);
vehicle *veh1 = m.veh_at(x, y, vpart1);
if( u.grab_point.x != 0 || u.grab_point.y ) {
vehicle *grabbed_vehicle = m.veh_at( u.posx + u.grab_point.x, u.posy + u.grab_point.y );
// If we're pushing a vehicle, the vehicle tile we'd be "stepping onto" is
// actually the current tile.
// If there's a vehicle there, it will actually result in failed movement.
if( grabbed_vehicle == veh1 ) {
veh1 = veh0;
vpart1 = vpart0;
}
}
bool veh_closed_door = false;
if (veh1) {
dpart = veh1->part_with_feature (vpart1, vpf_openable);
Expand Down Expand Up @@ -10348,9 +10390,63 @@ void game::plmove(int x, int y)
return;
}

float drag_multiplier = 1.0;
vehicle *grabbed_vehicle = NULL;
if( u.grab_point.x != 0 || u.grab_point.y != 0 ) {
grabbed_vehicle = m.veh_at( u.posx + u.grab_point.x, u.posy + u.grab_point.y );
if( NULL != grabbed_vehicle ) {
if( grabbed_vehicle == veh0 ) {
add_msg(_("You can't move %s while standing on it!"), grabbed_vehicle->name.c_str());
return;
}
drag_multiplier += (float)(grabbed_vehicle->total_mass() * 1000) /
(float)(u.weight_capacity() * 5);
if( drag_multiplier > 2.0 ) {
add_msg(_("The %s is too heavy for you to budge!"), grabbed_vehicle->name.c_str());
return;
}
tileray mdir;
mdir.init( dx, dy );
mdir.advance( 1 );
grabbed_vehicle->precalc_mounts( 1, mdir.dir() );
int imp = 0;
std::vector<veh_collision> veh_veh_colls;
bool can_move = true;
// Set player location to illegal value so it can't collide with vehicle.
int player_prev_x = u.posx;
int player_prev_y = u.posy;
u.posx = 0;
u.posy = 0;
if( grabbed_vehicle->collision( veh_veh_colls, dx, dy, can_move, imp, true ) ) {
// TODO: figure out what we collided with.
add_msg( _("The %s collides with something."), grabbed_vehicle->name.c_str() );
u.moves -= 10;
u.posx = player_prev_x;
u.posy = player_prev_y;
return;
}
u.posx = player_prev_x;
u.posy = player_prev_y;
int gx = grabbed_vehicle->global_x();
int gy = grabbed_vehicle->global_y();
for( int ep = 0; ep < grabbed_vehicle->external_parts.size(); ep++ ) {
const int p = grabbed_vehicle->external_parts[ ep ];
if( grabbed_vehicle->part_flag( p, vpf_wheel ) && one_in(2) )
grabbed_vehicle->handle_trap( gx + grabbed_vehicle->parts[p].precalc_dx[0] + dx,
gy + grabbed_vehicle->parts[p].precalc_dy[0] + dy, p );
}
m.displace_vehicle( this, gx, gy, dx, dy );
} else {
add_msg( _("No vehicle at grabbed point.") );
u.grab_point.x = 0;
u.grab_point.y = 0;
}
}

// Calculate cost of moving
bool diag = trigdist && u.posx != x && u.posy != y;
u.moves -= u.run_cost(m.combined_movecost(u.posx, u.posy, x, y), diag);
u.moves -= u.run_cost(m.combined_movecost(u.posx, u.posy, x, y, grabbed_vehicle), diag) *
drag_multiplier;

// Adjust recoil down
if (u.recoil > 0) {
Expand Down Expand Up @@ -10419,6 +10515,7 @@ void game::plmove(int x, int y)
z[mondex].move_to(this, u.posx, u.posy, true); // Force the movement even though the player is there right now.
add_msg(_("You displace the %s."), z[mondex].name().c_str());
}

if (x < SEEX * int(MAPSIZE / 2) || y < SEEY * int(MAPSIZE / 2) ||
x >= SEEX * (1 + int(MAPSIZE / 2)) || y >= SEEY * (1 + int(MAPSIZE / 2)))
update_map(x, y);
Expand Down Expand Up @@ -10816,6 +10913,16 @@ void game::vertical_move(int movez, bool force)
return;
}

if( force ) {
// Let go of a grabbed cart.
u.grab_point.x = 0;
u.grab_point.y = 0;
} else {
// TODO: Warp the cart along with you if you're on an elevator
add_msg(_("You can't drag things up and down stairs."));
return;
}

map tmpmap(&traps);
tmpmap.load(this, levx, levy, levz + movez, false);
// Find the corresponding staircase
Expand Down
2 changes: 2 additions & 0 deletions game.h
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,8 @@ void load_artifacts(); // Load artifact data
// open vehicle interaction screen
void exam_vehicle(vehicle &veh, int examx, int examy, int cx=0, int cy=0);
void pickup(int posx, int posy, int min);// Pickup items; ',' or via examine()
// Establish a grab on something.
void grab();
// Pick where to put liquid; false if it's left where it was

void compare(int iCompareX = -999, int iCompareY = -999); // Compare two Items 'I'
Expand Down
4 changes: 4 additions & 0 deletions itypedef.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ VAR_VEH_PART("wheel_small", _("small wheel"),140, ']', c_dkgray, "steel", "p
9, 2722, 10, 0, -1, 0, 6, 14, BIGNESS_WHEEL_DIAMETER, _("\
A pretty small wheel. Probably from one of those segway things.\
It is not very menacing."));
VAR_VEH_PART("wheel_caster", _("casters"),140, ']', c_dkgray, "steel", "plastic",
// VOL WGT DAM CUT HIT FLAGS BIGNESS_MIN BIGNESS_MAX ASPECT
5, 1500, 6, 0, -1, 0, 4, 6, BIGNESS_WHEEL_DIAMETER, _("\
A set of casters, like on a shopping cart."));

// NAME RAR PRC SYM COLOR MAT1 MAT2
VAR_VEH_PART("1cyl_combustion", _("1-cylinder engine"), 100, ':', c_ltcyan, "iron", "null",
Expand Down
5 changes: 3 additions & 2 deletions keypress.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ move_down >\n\
move_up <\n\
\n\
# MOVEMENT:\n\
center G\n\
center :\n\
shift_n K\n\
shift_e L\n\
shift_s J\n\
Expand All @@ -193,6 +193,7 @@ smash s\n\
examine e\n\
advinv /\n\
pickup , g\n\
grab G\n\
butcher B\n\
chat C\n\
look ; x\n\
Expand Down Expand Up @@ -238,7 +239,7 @@ quit Q\n\
\n\
# INFO SCREENS\n\
player_data @\n\
map m :\n\
map m\n\
missions M\n\
factions #\n\
kills )\n\
Expand Down
30 changes: 8 additions & 22 deletions map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ void map::destroy_vehicle (vehicle *veh)
debugmsg ("destroy_vehicle can't find it! sm=%d", veh_sm);
}

bool map::displace_vehicle (game *g, int &x, int &y, const int dx, const int dy, bool test=false)
bool map::displace_vehicle (game *g, int &x, int &y, const int dx, const int dy, bool test)
{
const int x2 = x + dx;
const int y2 = y + dy;
Expand Down Expand Up @@ -554,22 +554,7 @@ bool map::vehproceed(game* g){
if (veh->velocity == 0)
can_move = false;
// find collisions
for (int ep = 0; ep < veh->external_parts.size() && can_move; ep++) {
const int p = veh->external_parts[ep];
// coords of where part will go due to movement (dx/dy)
// and turning (precalc_dx/dy [1])
const int dsx = x + dx + veh->parts[p].precalc_dx[1];
const int dsy = y + dy + veh->parts[p].precalc_dy[1];
veh_collision coll = veh->part_collision (x, y, p, dsx, dsy);
if(coll.type == veh_coll_veh)
veh_veh_colls.push_back(coll);
else if (coll.type != veh_coll_nothing){ //run over someone?
if (can_move)
imp += coll.imp;
if (veh->velocity == 0)
can_move = false;
}
}
veh->collision( veh_veh_colls, dx, dy, can_move, imp );

if(veh_veh_colls.size()){ // we have dynamic crap!
// effects of colliding with another vehicle:
Expand Down Expand Up @@ -870,11 +855,11 @@ std::string map::features(const int x, const int y)
return ret;
}

int map::move_cost(const int x, const int y)
int map::move_cost(const int x, const int y, const vehicle *ignored_vehicle)
{
int vpart = -1;
vehicle *veh = veh_at(x, y, vpart);
if (veh) { // moving past vehicle cost
if (veh && veh != ignored_vehicle) { // moving past vehicle cost
const int dpart = veh->part_with_feature(vpart, vpf_obstacle);
if (dpart >= 0 && (!veh->part_flag(dpart, vpf_openable) || !veh->parts[dpart].open)) {
return 0;
Expand All @@ -897,10 +882,11 @@ int map::move_cost_ter_furn(const int x, const int y)
}

int map::combined_movecost(const int x1, const int y1,
const int x2, const int y2)
const int x2, const int y2,
const vehicle *ignored_vehicle)
{
int cost1 = move_cost(x1, y1);
int cost2 = move_cost(x2, y2);
int cost1 = move_cost(x1, y1, ignored_vehicle);
int cost2 = move_cost(x2, y2, ignored_vehicle);
// 50 moves taken per move_cost (70.71.. diagonally)
int mult = (trigdist && x1 != x2 && y1 != y2 ? 71 : 50);
return (cost1 + cost2) * mult / 2;
Expand Down
7 changes: 4 additions & 3 deletions map.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ class map
* 0 | Impassable
* n > 0 | x*n turns to move past this
*/
int move_cost(const int x, const int y);
int move_cost(const int x, const int y, const vehicle *ignored_vehicle = NULL);


/**
Expand All @@ -189,7 +189,8 @@ class map
*
* @return The cost in turns to move out of `(x1, y1)` and into `(x2, y2)`
*/
int combined_movecost(const int x1, const int y1, const int x2, const int y2);
int combined_movecost(const int x1, const int y1, const int x2, const int y2,
const vehicle *ignored_vehicle = NULL);

/**
* Returns whether the tile at `(x, y)` is transparent(you can look past it).
Expand Down Expand Up @@ -259,7 +260,7 @@ class map
// Returns true, if there was a submap change.
// If test is true, function only checks for submap change, no displacement
// WARNING: not checking collisions!
bool displace_vehicle (game *g, int &x, int &y, const int dx, const int dy, bool test);
bool displace_vehicle (game *g, int &x, int &y, const int dx, const int dy, bool test = false);
void vehmove(game* g); // Vehicle movement
bool vehproceed(game* g);
// move water under wheels. true if moved
Expand Down

0 comments on commit db2e2b8

Please sign in to comment.