Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement obscure SetVehicle behaviour (and 2 minor fixes) #1257

Merged
merged 5 commits into from Sep 12, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
50 changes: 47 additions & 3 deletions src/game_interpreter.cpp
Expand Up @@ -1501,6 +1501,12 @@ bool Game_Interpreter::CommandChangeActorFace(RPG::EventCommand const& com) { //
bool Game_Interpreter::CommandChangeVehicleGraphic(RPG::EventCommand const& com) { // code 10650
Game_Vehicle::Type vehicle_id = (Game_Vehicle::Type) (com.parameters[0] + 1);
Game_Vehicle* vehicle = Game_Map::GetVehicle(vehicle_id);

if (!vehicle) {
Output::Warning("ChangeVehicleGraphic: Invalid vehicle ID %d", vehicle_id);
return true;
}

const std::string& name = com.string;
int vehicle_index = com.parameters[1];

Expand Down Expand Up @@ -1575,11 +1581,40 @@ bool Game_Interpreter::CommandMemorizeLocation(RPG::EventCommand const& com) { /
bool Game_Interpreter::CommandSetVehicleLocation(RPG::EventCommand const& com) { // code 10850
Game_Vehicle::Type vehicle_id = (Game_Vehicle::Type) (com.parameters[0] + 1);
Game_Vehicle* vehicle = Game_Map::GetVehicle(vehicle_id);

if (!vehicle) {
// SetVehicleLocation moves the party, too, when she is in the referenced
// vehicle. In RPG_RT a party that is in no vehicle has the vehicle_id -1.
// Due to this implementation detail passing -1 as vehicle_id will move the
// party instead.
if (vehicle_id == 0) {
// 0 because we adjust all vehicle IDs by +1 to match the lcf values
Output::Debug("SetVehicleLocation: Party referenced");
} else {
Output::Warning("SetVehicleLocation: Invalid vehicle ID %d", vehicle_id);
return true;
}
}

int map_id = ValueOrVariable(com.parameters[1], com.parameters[2]);
int x = ValueOrVariable(com.parameters[1], com.parameters[3]);
int y = ValueOrVariable(com.parameters[1], com.parameters[4]);

vehicle->SetPosition(map_id, x, y);
// Check if the party is in the current vehicle
if (Main_Data::game_player->GetVehicle() == vehicle) {
if (map_id != Game_Map::GetMapId()) {
Output::Warning("SetVehicleLocation: Can't move %s to new map %d while the party is boarded.",
Game_Vehicle::TypeNames[vehicle_id], map_id);
return true;
}

// Transfer the party together with the vehicle
Main_Data::game_player->MoveTo(x, y);
}

if (vehicle) {
vehicle->SetPosition(map_id, x, y);
}

return true;
}
Expand Down Expand Up @@ -2300,10 +2335,19 @@ bool Game_Interpreter::CommandConditionalBranch(RPG::EventCommand const& com) {
result = character->GetSpriteDirection() == com.parameters[2];
}
break;
case 7:
case 7: {
// Vehicle in use
result = Game_Map::GetVehicle((Game_Vehicle::Type) (com.parameters[1] + 1))->IsInUse();
Game_Vehicle::Type vehicle_id = (Game_Vehicle::Type) (com.parameters[1] + 1);
Game_Vehicle* vehicle = Game_Map::GetVehicle(vehicle_id);

if (!vehicle) {
Output::Warning("ConditionalBranch: Invalid vehicle ID %d", vehicle_id);
return true;
}

result = vehicle->IsInUse();
break;
}
case 8:
// Key decision initiated this event
result = triggered_by_decision_key;
Expand Down
9 changes: 6 additions & 3 deletions src/game_map.cpp
Expand Up @@ -1150,10 +1150,13 @@ void Game_Map::SetChipset(int id) {
}

Game_Vehicle* Game_Map::GetVehicle(Game_Vehicle::Type which) {
if (which == Game_Vehicle::None) {
return NULL;
if (which == Game_Vehicle::Boat ||
which == Game_Vehicle::Ship ||
which == Game_Vehicle::Airship) {
return vehicles[which - 1].get();
}
return vehicles[which - 1].get();

return nullptr;
}

bool Game_Map::IsAnyEventStarting() {
Expand Down
7 changes: 7 additions & 0 deletions src/game_vehicle.cpp
Expand Up @@ -25,6 +25,13 @@
#include "game_vehicle.h"
#include "output.h"

const char Game_Vehicle::TypeNames[4][8] {
"Party", // RPG_RT special case, see CommandSetVehicleLocation
"Boat",
"Ship",
"Airship"
};

Game_Vehicle::Game_Vehicle(Type _type) :
data(_type == Boat ? Main_Data::game_data.boat_location :
_type == Ship ? Main_Data::game_data.ship_location :
Expand Down
2 changes: 2 additions & 0 deletions src/game_vehicle.h
Expand Up @@ -36,6 +36,8 @@ class Game_Vehicle : public Game_Character {
Airship
};

static const char TypeNames[4][8];

Game_Vehicle(Type _type);

/**
Expand Down
1 change: 1 addition & 0 deletions src/message_overlay.cpp
Expand Up @@ -92,6 +92,7 @@ void MessageOverlay::AddMessage(const std::string& message, Color color) {
if (message == last_message) {
// The message matches the previous message -> increase counter
messages.back().repeat_count++;
messages.back().hidden = false;
// Keep the old message (with a new counter) on the screen
counter = 0;

Expand Down
11 changes: 8 additions & 3 deletions src/spriteset_map.cpp
Expand Up @@ -88,9 +88,14 @@ void Spriteset_Map::Update() {
std::string name = Game_Map::Parallax::GetName();
if (name != panorama_name) {
panorama_name = name;
FileRequestAsync* request = AsyncHandler::RequestFile("Panorama", panorama_name);
panorama_request_id = request->Bind(&Spriteset_Map::OnPanoramaSpriteReady, this);
request->Start();
if (name.empty()) {
panorama->SetBitmap(BitmapRef());
tilemap->SetFastBlitDown(true);
} else {
FileRequestAsync *request = AsyncHandler::RequestFile("Panorama", panorama_name);
panorama_request_id = request->Bind(&Spriteset_Map::OnPanoramaSpriteReady, this);
request->Start();
}
}
panorama->SetOx(Game_Map::Parallax::GetX());
panorama->SetOy(Game_Map::Parallax::GetY());
Expand Down