|
From: <be...@us...> - 2016-06-01 22:27:09
|
Revision: 1005
http://sourceforge.net/p/freesynd/code/1005
Author: benblan
Date: 2016-06-01 22:27:06 +0000 (Wed, 01 Jun 2016)
Log Message:
-----------
Train implementation
- moved vehicle files to model directory and added train files
- Changed Vehicle::isDrivable() by Vehicle::isCar()
- removed unnecessary warning message
- fixed some warnings
- hacked mission 22 with car position
Modified Paths:
--------------
freesynd/trunk/src/CMakeLists.txt
freesynd/trunk/src/ia/actions.cpp
freesynd/trunk/src/mapobject.cpp
freesynd/trunk/src/menus/gameplaymenu.cpp
freesynd/trunk/src/menus/maprenderer.cpp
freesynd/trunk/src/menus/minimaprenderer.cpp
freesynd/trunk/src/menus/selectmenu.cpp
freesynd/trunk/src/menus/squadselection.cpp
freesynd/trunk/src/mission.cpp
freesynd/trunk/src/missionmanager.cpp
freesynd/trunk/src/missionmanager.h
freesynd/trunk/src/model/train.cpp
freesynd/trunk/src/model/train.h
freesynd/trunk/src/ped.cpp
freesynd/trunk/src/pedmanager.cpp
freesynd/trunk/src/weapon.cpp
Added Paths:
-----------
freesynd/trunk/src/model/vehicle.cpp
freesynd/trunk/src/model/vehicle.h
Removed Paths:
-------------
freesynd/trunk/src/vehicle.cpp
freesynd/trunk/src/vehicle.h
Modified: freesynd/trunk/src/CMakeLists.txt
===================================================================
--- freesynd/trunk/src/CMakeLists.txt 2016-05-03 20:11:20 UTC (rev 1004)
+++ freesynd/trunk/src/CMakeLists.txt 2016-06-01 22:27:06 UTC (rev 1005)
@@ -14,6 +14,8 @@
model/objectivedesc.cpp
model/weaponholder.cpp
model/shot.cpp
+ model/vehicle.cpp
+ model/train.cpp
core/squad.cpp
core/gamesession.cpp
core/gamecontroller.cpp
@@ -79,7 +81,6 @@
utils/log.cpp
utils/portablefile.cpp
utils/seqmodel.cpp
- vehicle.cpp
weapon.cpp
weaponmanager.cpp
)
@@ -115,7 +116,7 @@
resources.h
system.h
system_sdl.h
- vehicle.h
+ model/vehicle.h
version.h
weapon.h
weaponmanager.h
@@ -142,6 +143,7 @@
model/leveldata.h
model/shot.h
model/weaponholder.h
+ model/train.h
menus/agentselectorrenderer.h
menus/maprenderer.h
menus/minimaprenderer.h
@@ -218,7 +220,7 @@
editor/animmenu.h
editor/searchmissionmenu.h
editor/listmissionmenu.h)
-
+
add_executable (dump
dump.cpp
gfx/dirtylist.cpp
@@ -253,7 +255,7 @@
mod.cpp
modmanager.cpp
missionmanager.cpp
- vehicle.cpp
+ model/vehicle.cpp
weapon.cpp
weaponmanager.cpp
core/gamecontroller.cpp
@@ -287,7 +289,7 @@
${DEV_TOOLS_HEADERS}
)
target_link_libraries (dump ${PNG_LIBRARIES} ${SDL_LIBRARY} ${SDLIMAGE_LIBRARY} ${SDLMIXER_LIBRARY})
-
+
target_compile_definitions (dump PRIVATE EDITOR_)
else ()
# We only define an install target if we're doing a release build.
Modified: freesynd/trunk/src/ia/actions.cpp
===================================================================
--- freesynd/trunk/src/ia/actions.cpp 2016-05-03 20:11:20 UTC (rev 1004)
+++ freesynd/trunk/src/ia/actions.cpp 2016-06-01 22:27:06 UTC (rev 1005)
@@ -29,7 +29,7 @@
#include "app.h"
#include "ped.h"
#include "weapon.h"
-#include "vehicle.h"
+#include "model/vehicle.h"
#include "mission.h"
#include "agentmanager.h"
#include "core/squad.h"
@@ -601,7 +601,7 @@
}
void DriveVehicleAction::doStart(Mission *pMission, PedInstance *pPed) {
- if (pVehicle_->isDead() || !pVehicle_->isInsideVehicle(pPed)) {
+ if (pVehicle_->isDead() || !pVehicle_->containsPed(pPed)) {
setFailed();
}
Modified: freesynd/trunk/src/mapobject.cpp
===================================================================
--- freesynd/trunk/src/mapobject.cpp 2016-05-03 20:11:20 UTC (rev 1004)
+++ freesynd/trunk/src/mapobject.cpp 2016-06-01 22:27:06 UTC (rev 1005)
@@ -28,7 +28,7 @@
#include "common.h"
#include "utils/log.h"
#include "app.h"
-#include "vehicle.h"
+#include "model/vehicle.h"
#include "core/gamesession.h"
#include "mission.h"
Modified: freesynd/trunk/src/menus/gameplaymenu.cpp
===================================================================
--- freesynd/trunk/src/menus/gameplaymenu.cpp 2016-05-03 20:11:20 UTC (rev 1004)
+++ freesynd/trunk/src/menus/gameplaymenu.cpp 2016-06-01 22:27:06 UTC (rev 1005)
@@ -33,7 +33,7 @@
#include "menus/gamemenuid.h"
#include "gfx/fliplayer.h"
#include "utils/file.h"
-#include "vehicle.h"
+#include "model/vehicle.h"
#include "mission.h"
#include "model/shot.h"
@@ -993,7 +993,7 @@
uint8 weapon_idx = (uint8) key.keyFunc - (uint8) KFC_F5;
handleWeaponSelection(weapon_idx, ctrl);
return true;
- } else if (isLetterD(key.unicode) && ctrl) { // selected agents are killed with 'd'
+ } else if ((isLetterD(key.unicode)) && ctrl) { // selected agents are killed with 'd'
// save current selection as it will be modified when agents die
std::vector<PedInstance *> agents_suicide;
for (SquadSelection::Iterator it = selection_.begin();
@@ -1431,9 +1431,9 @@
if (mission_->getSquad()->isAllDead()) {
mission_->endWithStatus(Mission::kMissionStatusFailed);
// clear signal on minimap
- GameEvent evt;
- evt.type = GameEvent::kObjFailed;
- mm_renderer_.handleGameEvent(evt);
+ GameEvent sigEvt;
+ sigEvt.type = GameEvent::kObjFailed;
+ mm_renderer_.handleGameEvent(sigEvt);
}
// Anyway update selection
Modified: freesynd/trunk/src/menus/maprenderer.cpp
===================================================================
--- freesynd/trunk/src/menus/maprenderer.cpp 2016-05-03 20:11:20 UTC (rev 1004)
+++ freesynd/trunk/src/menus/maprenderer.cpp 2016-06-01 22:27:06 UTC (rev 1005)
@@ -28,7 +28,7 @@
#include "menus/maprenderer.h"
#include "common.h"
#include "mission.h"
-#include "vehicle.h"
+#include "model/vehicle.h"
#include "agentmanager.h"
#include "mapobject.h"
#include "core/squad.h"
Modified: freesynd/trunk/src/menus/minimaprenderer.cpp
===================================================================
--- freesynd/trunk/src/menus/minimaprenderer.cpp 2016-05-03 20:11:20 UTC (rev 1004)
+++ freesynd/trunk/src/menus/minimaprenderer.cpp 2016-06-01 22:27:06 UTC (rev 1005)
@@ -25,7 +25,7 @@
#include "core/missionbriefing.h"
#include "mission.h"
#include "gfx/screen.h"
-#include "vehicle.h"
+#include "model/vehicle.h"
#include "ped.h"
const int MinimapRenderer::kMiniMapSizePx = 128;
Modified: freesynd/trunk/src/menus/selectmenu.cpp
===================================================================
--- freesynd/trunk/src/menus/selectmenu.cpp 2016-05-03 20:11:20 UTC (rev 1004)
+++ freesynd/trunk/src/menus/selectmenu.cpp 2016-06-01 22:27:06 UTC (rev 1005)
@@ -88,8 +88,8 @@
/*!
* Draws a dashed line around the currently selected agent selector.
- * \param x Coordinates of the top left corner
- * \param y Coordinates of the top left corner
+ * \param x Coordinates of the top left corner
+ * \param y Coordinates of the top left corner
*/
void SelectMenu::drawAgentSelector(int x, int y) {
// First create a transparent sprite
@@ -259,7 +259,7 @@
tick_count_ += elapsed;
// Updates the moving agent selector
if (tick_count_ > 300) {
- rnd_ = ++rnd_ % 8;
+ rnd_ = (rnd_ + 1) % 8;
tick_count_ = 0;
needRendering();
}
@@ -270,7 +270,7 @@
}
}
-/*!
+/*!
* Update the game time display
*/
void SelectMenu::updateClock() {
@@ -347,7 +347,7 @@
g_Screen.drawRect(502, 268, 124, 2, fs_cmn::kColorDarkGreen);
g_Screen.drawRect(502, 292, 124, 2, fs_cmn::kColorDarkGreen);
g_Screen.drawRect(502, 318, 124, 2, fs_cmn::kColorDarkGreen);
-
+
getMenuFont(FontManager::SIZE_1)->drawText(x, y, pSelectedMod_->getName(), true);
char tmp[100];
sprintf(tmp, "COST :%d", pSelectedMod_->cost());
@@ -693,7 +693,7 @@
// get the selected agent from the team listbox
std::pair<int, void *> * pPair = static_cast<std::pair<int, void *> *> (ctx);
Agent *pNewAgent = static_cast<Agent *> (pPair->second);
-
+
bool found = false;
// check if selected agent is already part of the mission squad
for (size_t j = 0; j < AgentManager::kMaxSlot; j++) {
@@ -717,7 +717,7 @@
// redraw agent buttons
dirtyAgentSelector();
}
-
+
} else if (actionId == pModsLBox_->getId()) {
std::pair<int, void *> * pPair = static_cast<std::pair<int, void *> *> (ctx);
pSelectedMod_ = static_cast<Mod *> (pPair->second);
@@ -785,7 +785,7 @@
}
showItemList();
}
-
+
} else if (actionId == sellButId_ && selectedWInstId_) {
addDirtyRect(360, 305, 135, 70);
Agent *selected = g_gameCtrl.agents().squadMember(cur_agent_);
Modified: freesynd/trunk/src/menus/squadselection.cpp
===================================================================
--- freesynd/trunk/src/menus/squadselection.cpp 2016-05-03 20:11:20 UTC (rev 1004)
+++ freesynd/trunk/src/menus/squadselection.cpp 2016-06-01 22:27:06 UTC (rev 1005)
@@ -22,7 +22,7 @@
#include "menus/squadselection.h"
#include "ped.h"
-#include "vehicle.h"
+#include "model/vehicle.h"
#include "core/gameevent.h"
#include "mission.h"
@@ -245,22 +245,21 @@
*/
void SquadSelection::enterOrLeaveVehicle(Vehicle *pVehicle, bool addAction) {
// true means every one get in the vehicle
- bool getIn = leader()->inVehicle() == NULL;
+ bool leaderIsInVehicle = leader()->inVehicle() == NULL;
for (SquadSelection::Iterator it = begin(); it != end(); ++it)
{
PedInstance *pAgent = *it;
- if (getIn && !pAgent->inVehicle()) {
- // Agent is out and everybody must get in
+ if (leaderIsInVehicle && !pAgent->inVehicle()) {
+ // Agent is out and leader is in
MovementAction *pAction =
pAgent->createActionEnterVehicle(pVehicle);
pAgent->addMovementAction(pAction, addAction);
- //pAgent->addActionEnterVehicle(kOrigUser, pVehicle, addAction);
- } else if (!getIn && pAgent->inVehicle() == pVehicle) {
- // Agent is in the given car and everybody must get out
+ } else if (!leaderIsInVehicle && pAgent->inVehicle() == pVehicle) {
+ // Agent is in the given car and leader is out
// first stops the vehicle if it's a car
- if (pVehicle->speed() != 0 && pVehicle->isDrivable()) {
+ if (pVehicle->speed() != 0 && pVehicle->isCar()) {
pVehicle->clearDestination();
// tells the driver to stop
VehicleInstance *pVi = dynamic_cast<VehicleInstance *>(pVehicle);
@@ -291,7 +290,7 @@
PedInstance *pAgent = *it;
Vehicle *pVehicle = pAgent->inVehicle();
if (pVehicle) {
- if (pVehicle->isDrivable()) {
+ if (pVehicle->isCar()) {
// Agent is in drivable vehicle
VehicleInstance *pCar = dynamic_cast<VehicleInstance *>(pVehicle);
if (pCar->isDriver(pAgent))
Modified: freesynd/trunk/src/mission.cpp
===================================================================
--- freesynd/trunk/src/mission.cpp 2016-05-03 20:11:20 UTC (rev 1004)
+++ freesynd/trunk/src/mission.cpp 2016-06-01 22:27:06 UTC (rev 1005)
@@ -35,7 +35,7 @@
#include "app.h"
#include "model/objectivedesc.h"
#include "utils/log.h"
-#include "vehicle.h"
+#include "model/vehicle.h"
#include "core/squad.h"
#include "model/shot.h"
Modified: freesynd/trunk/src/missionmanager.cpp
===================================================================
--- freesynd/trunk/src/missionmanager.cpp 2016-05-03 20:11:20 UTC (rev 1004)
+++ freesynd/trunk/src/missionmanager.cpp 2016-06-01 22:27:06 UTC (rev 1005)
@@ -33,11 +33,16 @@
#include "core/gamecontroller.h"
#include "core/missionbriefing.h"
#include "model/objectivedesc.h"
-#include "vehicle.h"
+#include "model/vehicle.h"
#include "mission.h"
#include "core/squad.h"
#include "pedmanager.h"
+/*!
+ * Offset in the game data from the start to find the scenario section.
+ */
+const uint32 kScenarioOffset = 97128;
+
class LoadMissionException : public std::exception
{
public:
@@ -194,20 +199,26 @@
if (missionId == 10) { // Western Europe
// Change the second destination of the car for ped #168
// as in original scenario that destination seems non walkable
- uint8 *scen_start = data + 97128 + 8 * 8;
+ uint8 *scen_start = data + kScenarioOffset + 8 * 8;
scen_start[4] = 74;
scen_start[5] = 120;
scen_start[6] = 2;
- }else if (missionId == 40) {
- // Kenya map, adding additional walking points to scenarios
- uint8 *scen_start = data + 97128 + 8 * 86;
+ } else if (missionId == 22) { // Siberia
+ // Change destination of second action for ped #192 (police)
+ // because in original it is not walkable
+ uint8 *scen_start = data + kScenarioOffset + 8 * 7;
+ scen_start[5] = 120;
+ scen_start[6] = 3;
+ } else if (missionId == 40) { // Kenya
+ // adding additional walking points to scenarios
+ uint8 *scen_start = data + kScenarioOffset + 8 * 86;
// coord offsets changing for next point
scen_start[4] = ((scen_start[4] & 0xFE) | 1);
scen_start[5] = (scen_start[5] & 0xFE);
- scen_start = data + 97128 + 8 * 87;
+ scen_start = data + kScenarioOffset + 8 * 87;
WRITE_LE_UINT16(scen_start, 90 * 8);
- scen_start = data + 97128 + 8 * 90;
+ scen_start = data + kScenarioOffset + 8 * 90;
WRITE_LE_UINT16(scen_start, 91 *8);
scen_start += 4;
// coords x = 72,ox = 128, y = 32, oy = 128, z = 2
@@ -483,7 +494,7 @@
// car.sub_type 0x09 - train
if (car.type == 0x0)
continue;
- VehicleInstance *v =
+ Vehicle *v =
createVehicleInstance(car, i, pMission->mapId());
if (v) {
di.vindx[i] = pMission->numVehicles();
@@ -499,7 +510,7 @@
/*!
*
*/
-VehicleInstance * MissionManager::createVehicleInstance(const LevelData::Cars &gamdata, uint16 id, uint16 map)
+Vehicle * MissionManager::createVehicleInstance(const LevelData::Cars &gamdata, uint16 id, uint16 map)
{
// TODO: check all maps
// TODO: train, join somehow
@@ -511,10 +522,10 @@
int cur_anim = READ_LE_UINT16(gamdata.index_current_anim) - dir;
//setVehicleBaseAnim(vehicleanim, cur_anim);
vehicleanim->set_base_anims(cur_anim);
- VehicleInstance *vehicle_new = new VehicleInstance(vehicleanim, id, map);
+ Vehicle *vehicle_new = new VehicleInstance(vehicleanim, id, gamdata.sub_type, map);
vehicle_new->setHealth(hp);
vehicle_new->setStartHealth(hp);
- vehicle_new->setType(gamdata.sub_type);
+
switch (gamdata.sub_type) {
case 0x01:
// large armored
@@ -530,8 +541,11 @@
break;
case 0x05:
// train head
+ LOG(Log::k_FLG_GAME, "MissionManager","createVehicleInstance", ("Create Train Head %d", id))
+ break;
case 0x09:
// train body
+ LOG(Log::k_FLG_GAME, "MissionManager","createVehicleInstance", ("Create Train Body %d", id))
break;
case 0x0D:
// grey vehicle
@@ -576,6 +590,12 @@
gamdata.mapposy[0], oz);
vehicle_new->setDirection(gamdata.orientation);
+ LOG(Log::k_FLG_GAME, "MissionManager","createVehicleInstance", (" - field unknown 1 %u", gamdata.unkn1))
+ LOG(Log::k_FLG_GAME, "MissionManager","createVehicleInstance", (" - field unknown 2 %u", gamdata.unkn2))
+ LOG(Log::k_FLG_GAME, "MissionManager","createVehicleInstance", (" - field unknown 3 %u", gamdata.unkn3))
+ LOG(Log::k_FLG_GAME, "MissionManager","createVehicleInstance", (" - field unknown 4 %u", gamdata.unkn4))
+ LOG(Log::k_FLG_GAME, "MissionManager","createVehicleInstance", (" - field unknown 6 %u", gamdata.unkn6))
+
return vehicle_new;
}
@@ -698,9 +718,14 @@
pPed->addToDefaultActions(new TriggerAction(6 * 256, locW));
}
if (v) {
- LOG(Log::k_FLG_GAME, "MissionManager","createScriptedActionsForPed", (" - Drive car to (%d, %d, %d) (%d, %d)", locT.tx, locT.ty, locT.tz, locT.ox, locT.oy))
- VehicleInstance *pCar = dynamic_cast<VehicleInstance *>(v);
- pPed->addToDefaultActions(new DriveVehicleAction(pCar, locT));
+ if (v->isCar()) {
+ LOG(Log::k_FLG_GAME, "MissionManager","createScriptedActionsForPed", (" - Drive car %d to (%d, %d, %d) (%d, %d)", v->id(), locT.tx, locT.ty, locT.tz, locT.ox, locT.oy))
+ VehicleInstance *pCar = dynamic_cast<VehicleInstance *>(v);
+ pPed->addToDefaultActions(new DriveVehicleAction(pCar, locT));
+ } else {
+ LOG(Log::k_FLG_GAME, "MissionManager","createScriptedActionsForPed", (" - Drive train %d to (%d, %d, %d) (%d, %d)", v->id(), locT.tx, locT.ty, locT.tz, locT.ox, locT.oy))
+ // TODO : add drive train action
+ }
} else {
LOG(Log::k_FLG_GAME, "MissionManager","createScriptedActionsForPed", (" - Walk toward location (%d, %d, %d)", locT.tx, locT.ty, locT.tz))
pPed->addToDefaultActions(new WalkToDirectionAction(locW));
@@ -711,7 +736,7 @@
}
} else if (sc.type == LevelData::kScenarioTypeUseVehicle) {
if (!isInVehicle) {
- LOG(Log::k_FLG_GAME, "MissionManager","createScriptedActionsForPed", (" - Enter car"))
+ LOG(Log::k_FLG_GAME, "MissionManager","createScriptedActionsForPed", (" - Enter vehicle"))
uint16 bindx = READ_LE_UINT16(sc.offset_object);
// TODO: test all maps for objects other then vehicle
assert(bindx >= 0x5C02 && bindx < 0x6682);
@@ -725,10 +750,14 @@
pPed->addToDefaultActions(pAction);
}
} else {
- LOG(Log::k_FLG_GAME, "MissionManager","createScriptedActionsForPed", (" - Drive to (%d, %d, %d) (%d, %d)", v->tileX(), v->tileY(), v->tileZ(), v->offX(), v->offY()))
- VehicleInstance *pCar = dynamic_cast<VehicleInstance *>(v);
- pPed->addToDefaultActions(
+ if (v->isCar()) {
+ LOG(Log::k_FLG_GAME, "MissionManager","createScriptedActionsForPed", (" - Drive car %d to (%d, %d, %d) (%d, %d)", v->id(), v->tileX(), v->tileY(), v->tileZ(), v->offX(), v->offY()))
+ VehicleInstance *pCar = dynamic_cast<VehicleInstance *>(v);
+ pPed->addToDefaultActions(
new DriveVehicleAction(pCar, v->position()));
+ } else {
+ LOG(Log::k_FLG_GAME, "MissionManager","createScriptedActionsForPed", (" - Drive train %d to (%d, %d, %d) (%d, %d)", v->id(), v->tileX(), v->tileY(), v->tileZ(), v->offX(), v->offY()))
+ }
}
} else if (sc.type == LevelData::kScenarioTypeEscape) {
LOG(Log::k_FLG_GAME, "MissionManager","createScriptedActionsForPed", (" - Escape"))
@@ -737,7 +766,7 @@
LOG(Log::k_FLG_GAME, "MissionManager","createScriptedActionsForPed", (" - Reset actions"))
pPed->addToDefaultActions(new ResetScriptedAction(Action::kActionDefault));
} else if (sc.type == 10) {
- printf("Scenario type 10\n");
+ LOG(Log::k_FLG_GAME, "MissionManager","createScriptedActionsForPed", (" scenario type 10"))
} else {
LOG(Log::k_FLG_GAME, "MissionManager","createScriptedActionsForPed", (" - unknown type %d", sc.type))
}
Modified: freesynd/trunk/src/missionmanager.h
===================================================================
--- freesynd/trunk/src/missionmanager.h 2016-05-03 20:11:20 UTC (rev 1004)
+++ freesynd/trunk/src/missionmanager.h 2016-06-01 22:27:06 UTC (rev 1005)
@@ -81,7 +81,7 @@
void createVehicles(const LevelData::LevelDataAll &level_data,
DataIndex &di, Mission *pMission);
//! Creates a vehicle from the game data
- VehicleInstance * createVehicleInstance(const LevelData::Cars &gamdata, uint16 id, uint16 map);
+ Vehicle * createVehicleInstance(const LevelData::Cars &gamdata, uint16 id, uint16 map);
//! Creates all peds
void createPeds(const LevelData::LevelDataAll &level_data,
DataIndex &di, Mission *pMission);
Modified: freesynd/trunk/src/model/train.cpp
===================================================================
--- freesynd/trunk/src/model/train.cpp 2016-05-03 20:11:20 UTC (rev 1004)
+++ freesynd/trunk/src/model/train.cpp 2016-06-01 22:27:06 UTC (rev 1005)
@@ -1,24 +1,19 @@
#include "train.h"
-Train::Train() {
+TrainHead::TrainHead(uint16 anId, uint8 aType) : TrainBody(anId, aType) {
}
-Train::~Train() {
- for (std::list < TrainElement * >::iterator it = elements_.begin();
- it != elements_.end(); it++) {
- TrainElement *elem = *it;
- delete elem;
- }
- elements_.clear();
+TrainHead::~TrainHead() {
+
}
-bool Train::animate(int elapsed) {
+bool TrainHead::animate(int elapsed) {
return false;
}
-TrainElement::TrainElement() : Vehicle(-1, false) {
-//TrainElement::TrainElement() : Vehicle(-1) {
+TrainBody::TrainBody(uint16 anId, uint8 aType) : Vehicle(anId, aType, -1) {
+
}
-TrainElement::~TrainElement() {
-}
\ No newline at end of file
+TrainBody::~TrainBody() {
+}
Modified: freesynd/trunk/src/model/train.h
===================================================================
--- freesynd/trunk/src/model/train.h 2016-05-03 20:11:20 UTC (rev 1004)
+++ freesynd/trunk/src/model/train.h 2016-06-01 22:27:06 UTC (rev 1005)
@@ -35,27 +35,25 @@
/*!
* .
*/
-class TrainElement : public Vehicle {
+class TrainBody : public Vehicle {
public:
- TrainElement();
- ~TrainElement();
+ TrainBody(uint16 id, uint8 aType);
+ ~TrainBody();
};
/*!
* .
*/
-class Train {
+class TrainHead : public TrainBody {
public:
- Train();
- ~Train();
+ TrainHead(uint16 id, uint8 aType);
+ ~TrainHead();
- std::list<TrainElement *> & elements() { return elements_; }
-
//! Animates the train
bool animate(int elapsed);
private:
- std::list<TrainElement *> elements_;
+
};
-#endif // MODEL_TRAIN_H_
\ No newline at end of file
+#endif // MODEL_TRAIN_H_
Copied: freesynd/trunk/src/model/vehicle.cpp (from rev 1004, freesynd/trunk/src/vehicle.cpp)
===================================================================
--- freesynd/trunk/src/model/vehicle.cpp (rev 0)
+++ freesynd/trunk/src/model/vehicle.cpp 2016-06-01 22:27:06 UTC (rev 1005)
@@ -0,0 +1,860 @@
+/************************************************************************
+ * *
+ * FreeSynd - a remake of the classic Bullfrog game "Syndicate". *
+ * *
+ * Copyright (C) 2005 Stuart Binge <sk...@gm...> *
+ * Copyright (C) 2005 Joost Peters <jo...@us...> *
+ * Copyright (C) 2006 Trent Waddington <qg...@bi...> *
+ * Copyright (C) 2006 Tarjei Knapstad <tar...@gm...> *
+ * Copyright (C) 2010 Bohdan Stelmakh <ch...@us...> *
+ * Copyright (C) 2013 Benoit Blancard <be...@us...>*
+ * *
+ * This program is free software; you can redistribute it and / or *
+ * modify it under the terms of the GNU General Public License as *
+ * published by the Free Software Foundation; either version 2 of the *
+ * License, or (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * General Public License for more details. *
+ * *
+ * You can view the GNU General Public License, online, at the GNU *
+ * project's web site; see <http://www.gnu.org/licenses/gpl.html>. *
+ * The full text of the license is also included in the file COPYING. *
+ * *
+ ************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#include "app.h"
+#include "core/gamesession.h"
+#include "gfx/screen.h"
+#include "vehicle.h"
+#include "model/shot.h"
+
+const uint8 Vehicle::kVehicleTypeLargeArmored = 0x01;
+const uint8 Vehicle::kVehicleTypeLargeArmoredDamaged = 0x04;
+const uint8 Vehicle::kVehicleTypeTrainHead = 0x05;
+const uint8 Vehicle::kVehicleTypeTrainBody = 0x09;
+const uint8 Vehicle::kVehicleTypeRegularCar = 0x0D;
+const uint8 Vehicle::kVehicleTypeFireFighter = 0x11;
+const uint8 Vehicle::kVehicleTypeSmallArmored = 0x1C;
+const uint8 Vehicle::kVehicleTypePolice = 0x24;
+const uint8 Vehicle::kVehicleTypeMedics = 0x28;
+
+VehicleAnimation::VehicleAnimation() {
+ vehicle_anim_ = kNormalAnim;
+}
+
+void VehicleAnimation::draw(int x, int y, int dir, int frame)
+{
+ switch (vehicle_anim_) {
+ case kNormalAnim:
+ g_App.gameSprites().drawFrame(anims_ + dir * 2, frame, x, y);
+ break;
+ case kOnFireAnim:
+ g_App.gameSprites().drawFrame(anims_burning_ + dir, frame, x, y);
+ break;
+ case kBurntAnim:
+ g_App.gameSprites().drawFrame(anims_burnt_ + dir, frame, x, y);
+ break;
+ }
+}
+
+void VehicleAnimation::set_base_anims(int anims) {
+ anims_ = anims;
+ anims_burning_ = anims + 8;
+ anims_burnt_ = anims + 12;
+}
+
+/**
+ * Adds given ped to the list of passengers.
+ * \param pPed PedInstance*
+ * \return void
+ *
+ */
+void Vehicle::addPassenger(PedInstance *pPed) {
+ if(!containsPed(pPed)) {
+ passengers_.insert(pPed);
+ pPed->putInVehicle(this);
+ }
+}
+
+/*!
+ * Removes given passenger from vehicle.
+ * \param pPed Ped to remove
+ */
+void Vehicle::dropPassenger(PedInstance *pPed) {
+ if(containsPed(pPed)) {
+ pPed->leaveVehicle();
+ passengers_.erase(passengers_.find(pPed));
+ }
+}
+
+/*!
+ * Returns true if at least one of our agent is inside the vehicle.
+ */
+bool Vehicle::containsOurAgents() {
+ for (std::set<PedInstance *>::iterator it = passengers_.begin();
+ it != passengers_.end(); it++)
+ {
+ if ((*it)->isOurAgent()) {
+ return true;
+ }
+ }
+ return false;
+}
+
+/*!
+ * Returns true if the vehicle contains peds considered hostile by the given ped.
+ * \param pPed The ped evaluating the hostility of the vehicle
+ * \param hostile_desc_alt Parameter for evaluating the hostility
+ * \return True if at least one hostile ped is found.
+ */
+bool Vehicle::containsHostilesForPed(PedInstance* p,
+ unsigned int hostile_desc_alt)
+{
+ for (std::set<PedInstance *>::iterator it = passengers_.begin();
+ it != passengers_.end(); it++)
+ {
+ if (p->isHostileTo((ShootableMapObject *)(*it), hostile_desc_alt))
+ return true;
+ }
+ return false;
+}
+
+VehicleInstance::VehicleInstance(VehicleAnimation * vehicle, uint16 anId, uint8 aType, int m):
+ Vehicle(anId, aType, m), vehicle_(vehicle)
+{
+ pDriver_ = NULL;
+ hold_on_.wayFree = 0;
+}
+
+bool VehicleInstance::animate(int elapsed)
+{
+ bool updated = false;
+
+ if (health_ > 0) {
+ updated = move_vehicle(elapsed);
+ }
+
+ if (vehicle_->animation_type() == VehicleAnimation::kOnFireAnim) {
+ if (leftTimeShowAnim(elapsed))
+ updated |= MapObject::animate(elapsed);
+ else {
+ vehicle_->set_animation_type(VehicleAnimation::kBurntAnim);
+ frame_ = 0;
+ updated = true;
+ }
+ }
+
+ return updated;
+}
+
+void VehicleInstance::draw(int x, int y)
+{
+ y += TILE_HEIGHT / 3;
+ addOffs(x, y);
+
+ // ensure on map
+ if (x < 90 || y < -20)
+ return;
+
+ vehicle_->draw(x, y, getDirection(4), frame_);
+}
+
+uint16 VehicleInstance::tileDir(int x, int y, int z) {
+ uint16 dir = 0x0;
+ int near_tile;
+ Map *pMap = g_App.maps().map(map());
+
+ switch(pMap->tileAt(x, y, z)){
+ case 80:
+ if(g_App.maps().map(map())->tileAt(x + 1, y, z) == 80)
+ dir = (0)|(0xFFF0);
+ if(pMap->tileAt(x - 1, y, z) == 80)
+ dir = (4<<8)|(0xF0FF);
+ break;
+ case 81:
+ if(pMap->tileAt(x, y - 1, z) == 81)
+ dir = (2<<4)|(0xFF0F);
+ if(pMap->tileAt(x, y + 1, z) == 81)
+ dir = (6<<12)|(0x0FFF);
+ break;
+ case 106:
+ dir = (0)|(2<<4)|(6<<12)|(0x0F00);
+
+ if(pMap->tileAt(x + 1, y - 1, z) != 118)
+ dir |= 0x0FF0;
+ if(pMap->tileAt(x + 1, y + 1, z) != 118)
+ dir |= 0xFF00;
+ near_tile = pMap->tileAt(x + 1, y, z);
+ if (near_tile == 108 || near_tile == 109)
+ dir = (dir & 0x0FFF) | 0x6000;
+
+ break;
+ case 107:
+ dir = (2<<4)|(4<<8)|(6<<12)|(0x000F);
+
+ if(pMap->tileAt(x - 1, y - 1, z) != 118)
+ dir |= 0x00FF;
+ if(pMap->tileAt(x - 1, y + 1, z) != 118)
+ dir |= 0xF00F;
+ near_tile = pMap->tileAt(x - 1, y, z);
+ if (near_tile == 108 || near_tile == 109)
+ dir = (dir & 0xFF0F) | 0x0020;
+
+ break;
+ case 108:
+ dir = (0)|(2<<4)|(4<<8)|(0xF000);
+
+ if(pMap->tileAt(x + 1, y - 1, z) != 118)
+ dir |= 0xF00F;
+ if(pMap->tileAt(x - 1, y - 1, z) != 118)
+ dir |= 0xFF00;
+ near_tile = pMap->tileAt(x, y - 1, z);
+ if (near_tile == 106 || near_tile == 107)
+ dir = dir & 0xFFF0;
+
+ break;
+ case 109:
+ dir = (0)|(4<<8)|(6<<12)|(0x00F0);
+
+ if(pMap->tileAt(x + 1, y + 1, z) != 118)
+ dir |= 0x00FF;
+ if(pMap->tileAt(x - 1, y + 1, z) != 118)
+ dir |= 0x0FF0;
+ near_tile = pMap->tileAt(x, y + 1, z);
+ if (near_tile == 106 || near_tile == 107)
+ dir = (dir & 0xF0FF) | 0x0400;
+
+ break;
+ case 110:
+ dir = (0) | (2<<4)|(0xFF00);
+ break;
+ case 111:
+ dir = (0) | (6<<12)|(0x0FF0);
+ break;
+ case 112:
+ dir = (2<<4)|(4<<8)|(0xF00F);
+ break;
+ case 113:
+ dir = (4<<8)|(6<<12)|(0x00FF);
+ break;
+ /*case 119:
+ // TODO: Greenland map needs fixing
+ dir = 0xFFFF;
+ near_tile = pMap->tileAt(x, y + 1, z);
+ if (near_tile == 107 || near_tile == 225 || near_tile == 226)
+ dir = (dir & 0xF0FF) | 0x0400;
+ near_tile = pMap->tileAt(x, y + 1, z);
+ if (near_tile == 106 || near_tile == 225 || near_tile == 226)
+ dir &= 0xFFF0;
+ near_tile = pMap->tileAt(x + 1, y, z);
+ if (near_tile == 109 || near_tile == 225 || near_tile == 226)
+ dir = (dir & 0xFF0F) | 0x0020;
+ near_tile = pMap->tileAt(x - 1, y, z);
+ if (near_tile == 108 || near_tile == 225 || near_tile == 226)
+ dir = (dir & 0x0FFF) | 0x6000;
+ if (dir ==0xFFFF)
+ dir = 0x0;
+ break;*/
+ case 120:
+ dir = (0)|(2<<4)|(0xFF00);
+ break;
+ case 121:
+ dir = (0)|(6<<12)|(0x0FF0);
+ break;
+ case 122:
+ dir = (4<<8)|(6<<12)|(0x00FF);
+ break;
+ case 123:
+ dir = (2<<4)|(4<<8)|(0xF00F);
+ break;
+ case 225:/*
+ if(g_App.maps().map(map())->getTileAt(x + 1, y, z)->type() == Tile::kRoadPedCross)
+ dir = (0)|(0xFFF0);
+ else if(g_App.maps().map(map())->getTileAt(x - 1, y, z)->type() == Tile::kRoadPedCross)
+ dir = (4<<8)|(0xF0FF);
+ else {*/
+ dir = 0xFFFF;
+ near_tile = pMap->tileAt(x, y + 1, z);
+ if (/*near_tile == 119 || */near_tile == 106
+ || near_tile == 107 || near_tile == 80 || near_tile == 225)
+ dir = (dir & 0xF0FF) | 0x0400;
+ near_tile = pMap->tileAt(x, y - 1, z);
+ if (/*near_tile == 119 || */near_tile == 106
+ || near_tile == 107 || near_tile == 80 || near_tile == 225)
+ dir &= 0xFFF0;
+ near_tile = pMap->tileAt(x + 1, y, z);
+ if (/*near_tile == 119 || */near_tile == 108 || near_tile == 81)
+ dir = (dir & 0xFF0F) | 0x0020;
+ near_tile = pMap->tileAt(x - 1, y, z);
+ if (/*near_tile == 119 || */near_tile == 109 || near_tile == 81)
+ dir = (dir & 0x0FFF) | 0x6000;
+ if (dir == 0xFFFF)
+ dir = 0x0;
+ //}
+ break;
+ case 226:/*
+ if(g_App.maps().map(map())->getTileAt(x, y - 1, z)->type() == Tile::kRoadPedCross)
+ dir = (2<<4)|(0xFF0F);
+ else if(g_App.maps().map(map())->getTileAt(x, y + 1, z)->type() == Tile::kRoadPedCross)
+ dir = (6<<12)|(0x0FFF);
+ else {*/
+ dir = 0xFFFF;
+ near_tile = pMap->tileAt(x, y + 1, z);
+ if (/*near_tile == 119 || */near_tile == 106 || near_tile == 80)
+ dir = (dir & 0xF0FF) | 0x0400;
+ near_tile = pMap->tileAt(x, y - 1, z);
+ if (/*near_tile == 119 || */near_tile == 107 || near_tile == 80)
+ dir &= 0xFFF0;
+ near_tile = pMap->tileAt(x + 1, y, z);
+ if (/*near_tile == 119 || */near_tile == 108 || near_tile == 109
+ || near_tile == 81 || near_tile == 226)
+ dir = (dir & 0xFF0F) | 0x0020;
+ near_tile = pMap->tileAt(x - 1, y, z);
+ if (/*near_tile == 119 || */near_tile == 108 || near_tile == 109
+ || near_tile == 81 || near_tile == 226)
+ dir = (dir & 0x0FFF) | 0x6000;
+ if (dir == 0xFFFF)
+ dir = 0;
+ //}
+ break;
+ default:
+ dir = 0xFFFF;
+ }
+
+ return dir;
+}
+
+bool VehicleInstance::dirWalkable(TilePoint *p, int x, int y, int z) {
+ Map *pMap = g_App.maps().map(map());
+ if(!(pMap->isTileWalkableByCar(x,y,z)))
+ return false;
+
+ uint16 dirStart = tileDir(p->tx,p->ty,p->tz);
+ uint16 dirEnd = tileDir(x,y,z);
+ if (dirStart == 0x0 || dirEnd == 0x0)
+ return false;
+ if (dirStart == 0xFFFF || dirEnd == 0xFFFF)
+ return true;
+
+ if (((dirStart & 0xF000) != 0xF000)
+ || ((dirEnd & 0xF000) != 0xF000))
+ if ((dirStart & 0xF000) == (dirEnd & 0xF000))
+ return true;
+ if (((dirStart & 0x0F00) != 0x0F00)
+ || ((dirEnd & 0x0F00) != 0x0F00))
+ if ((dirStart & 0x0F00) == (dirEnd & 0x0F00))
+ return true;
+ if (((dirStart & 0x00F0) != 0x00F0)
+ || ((dirEnd & 0x00F0) != 0x00F0))
+ if ((dirStart & 0x00F0) == (dirEnd & 0x00F0))
+ return true;
+ if (((dirStart & 0x000F) != 0x000F)
+ || ((dirEnd & 0x000F) != 0x000F))
+ if ((dirStart & 0x000F) == (dirEnd & 0x000F))
+ return true;
+
+ return false;
+}
+
+/*!
+ * Sets a destination point for the vehicle to reach at given speed.
+ * \param m
+ * \param locT destination point
+ * \param newSpeed Speed of movement
+ * \return true if destination has been set correctly.
+ */
+bool VehicleInstance::setDestination(Mission *m, const TilePoint &locT, int newSpeed) {
+ speed_ = newSpeed;
+ setDestinationV(locT.tx, locT.ty, locT.tz, locT.ox, locT.oy, newSpeed);
+ return !dest_path_.empty();
+}
+
+void VehicleInstance::setDestinationV(int x, int y, int z, int ox, int oy, int new_speed)
+{
+ std::map < TilePoint, uint16 > open;
+ std::set < TilePoint > closed;
+ std::map < TilePoint, TilePoint > parent;
+ int basex = pos_.tx, basey = pos_.ty;
+ std::vector < TilePoint > path2add;
+ path2add.reserve(16);
+ Map *pMap = g_App.maps().map(map_);
+
+ pMap->adjXYZ(x, y, z);
+ // NOTE: we will be using lower tiles, later will restore Z coord
+ z = pos_.tz - 1;
+
+ dest_path_.clear();
+ setSpeed(0);
+
+ if (map_ == -1 || health_ <= 0 || !(pMap->isTileWalkableByCar(x, y, z))) {
+#if 0
+#if _DEBUG
+ if (!(map_ == -1 || health_ <= 0)) {
+ printf("non-walking tile is target to drive\n");
+ printf("tileAt %i\n",
+ (unsigned int)g_App.maps().map(map())->tileAt(x, y, z));
+ printf("tile x = %i, y = %i, z = %i\n", x, y, z);
+ }
+#endif
+#endif
+ return;
+ }
+
+ if (!pMap->isTileWalkableByCar(pos_.tx, pos_.ty, z)) {
+ int dBest = 100000, dCur;
+ std::vector < TilePoint > path2wtile;
+ path2wtile.reserve(16);
+ // we got somewhere we shouldn't, we need to find somewhere that is walkable
+ TilePoint pntile(pos_.tx , pos_.ty, z, pos_.ox, pos_.oy);
+ for (int i = 1; i < 16; i++) {
+ if (pos_.tx + i >= pMap->maxX())
+ break;
+ pntile.tx = pos_.tx + i;
+ path2wtile.push_back(pntile);
+ if (pMap->isTileWalkableByCar(pos_.tx + i, pos_.ty, z)) {
+ dCur = i * i;
+ if(dCur < dBest) {
+ dBest = dCur;
+ path2add = path2wtile;
+ basex = pos_.tx + i;
+ basey = pos_.ty;
+ break;
+ }
+ }
+ }
+
+ path2wtile.clear();
+ pntile = TilePoint(pos_.tx , pos_.ty, z, pos_.ox, pos_.oy);
+ for (int i = -1; i > -16; --i) {
+ if (pos_.tx + i < 0)
+ break;
+ pntile.tx = (pos_.tx + i);
+ path2wtile.push_back(pntile);
+ if (pMap->isTileWalkableByCar(pos_.tx + i, pos_.ty, z)) {
+ dCur = i * i;
+ if(dCur < dBest) {
+ dBest = dCur;
+ path2add = path2wtile;
+ basex = pos_.tx + i;
+ basey = pos_.ty;
+ break;
+ }
+ }
+ }
+
+ path2wtile.clear();
+ pntile = TilePoint(pos_.tx , pos_.ty, z, pos_.ox, pos_.oy);
+ for (int i = -1; i > -16; --i) {
+ if (pos_.ty + i < 0)
+ break;
+ pntile.ty = (pos_.ty + i);
+ path2wtile.push_back(pntile);
+ if (pMap->isTileWalkableByCar(pos_.tx, pos_.ty + i, z)) {
+ dCur = i * i;
+ if(dCur < dBest) {
+ dBest = dCur;
+ path2add = path2wtile;
+ basex = pos_.tx;
+ basey = pos_.ty + i;
+ break;
+ }
+ }
+ }
+
+ path2wtile.clear();
+ pntile = TilePoint(pos_.tx , pos_.ty, z, pos_.ox, pos_.oy);
+ for (int i = 1; i < 16; i++) {
+ if (pos_.ty + i >= pMap->maxY())
+ break;
+ pntile.ty = pos_.ty + i;
+ path2wtile.push_back(pntile);
+ if (pMap->isTileWalkableByCar(pos_.tx, pos_.ty + i, z)) {
+ dCur = i * i;
+ if(dCur < dBest) {
+ dBest = dCur;
+ path2add = path2wtile;
+ basex = pos_.tx;
+ basey = pos_.ty + i;
+ break;
+ }
+ }
+ }
+ if(dBest == 100000)
+ return;
+ }
+
+ TilePoint closest;
+ float closest_dist = 100000;
+
+ uint16 wrong_dir = (uint16)getDirection(4);
+ if (wrong_dir == 0x0)
+ wrong_dir = 0x0400;
+ else if(wrong_dir == 0x1)
+ wrong_dir = 0x6000;
+ else if(wrong_dir == 0x2)
+ wrong_dir = 0x0;
+ else if(wrong_dir == 0x3)
+ wrong_dir = 0x0020;
+ open.insert(std::pair< TilePoint, uint16 >(TilePoint(basex, basey, z, pos_.ox, pos_.oy),
+ wrong_dir));
+ int watchDog = 1000;
+
+ while (!open.empty()) {
+ watchDog--;
+ float dist = 100000;
+ TilePoint p;
+ std::map < TilePoint, uint16 >::iterator pit;
+ for (std::map < TilePoint, uint16 >::iterator it = open.begin();
+ it != open.end(); it++)
+ {
+ float d =
+ sqrt((float) (x - it->first.tx) * (x - it->first.tx) +
+ (y - it->first.ty) * (y - it->first.ty));
+ if (d < dist) {
+ dist = d;
+ p = it->first;
+ pit = it; // it cannot be const_iterator because of this assign
+ wrong_dir = it->second;
+ }
+ }
+ if (dist < closest_dist) {
+ closest = p;
+ closest_dist = dist;
+ }
+ //printf("found best dist %f in %i nodes\n", dist, open.size());
+ open.erase(pit);
+ closed.insert(p);
+
+ if ((p.tx == x && p.ty == y && p.tz == z)
+ || watchDog < 0)
+ {
+ if (watchDog < 0) {
+ p = closest;
+ dest_path_.
+ push_front(TilePoint
+ (p.tx, p.ty, p.tz, ox, oy));
+ } else
+ dest_path_.push_front(TilePoint(x, y, z, ox, oy));
+ while (parent.find(p) != parent.end()) {
+ p = parent[p];
+ if (p.tx == pos_.tx && p.ty == pos_.ty
+ && p.tz == z)
+ break;
+ dest_path_.push_front(p);
+ }
+ break;
+ }
+
+ std::map <TilePoint, uint16> neighbours;
+ uint16 goodDir = tileDir(p.tx, p.ty, p.tz);
+
+ if (wrong_dir != 0x6000 && p.tx > 0) {
+ if (dirWalkable(&p, p.tx - 1, p.ty, p.tz)
+ && ((goodDir & 0xF000) == 0x6000 || goodDir == 0xFFFF))
+ neighbours[TilePoint(p.tx - 1, p.ty, p.tz)] = 0x0020;
+ }
+
+ if (wrong_dir != 0x0020 && p.tx < g_App.maps().map(map())->maxX()) {
+ if (dirWalkable(&p, p.tx + 1, p.ty, p.tz)
+ && ((goodDir & 0x00F0) == 0x0020 || goodDir == 0xFFFF))
+ neighbours[TilePoint(p.tx + 1, p.ty, p.tz)] = 0x6000;
+ }
+
+ if (wrong_dir != 0x0400 && p.ty > 0)
+ if (dirWalkable(&p, p.tx, p.ty - 1, p.tz)
+ && ((goodDir & 0x0F00) == 0x0400 || goodDir == 0xFFFF))
+ neighbours[TilePoint(p.tx, p.ty - 1, p.tz)] = 0x0;
+
+ if (wrong_dir != 0x0000 && p.ty < g_App.maps().map(map())->maxY())
+ if (dirWalkable(&p, p.tx, p.ty + 1, p.tz)
+ && ((goodDir & 0x000F) == 0x0 || goodDir == 0xFFFF))
+ neighbours[TilePoint(p.tx, p.ty + 1, p.tz)] = 0x0400;
+
+ for (std::map <TilePoint, uint16>::iterator it = neighbours.begin();
+ it != neighbours.end(); it++)
+ if (dirWalkable(&p, it->first.tx, it->first.ty,
+ it->first.tz)
+ && open.find(it->first) == open.end()
+ && closed.find(it->first) == closed.end())
+ {
+ parent[it->first] = p;
+ open.insert(*it);
+ }
+ }
+
+ if(!dest_path_.empty()) {
+ // Adjusting offsets for correct positioning
+ speed_ = new_speed;
+ int curox = pos_.ox;
+ int curoy = pos_.oy;
+ for(std::list < TilePoint >::iterator it = dest_path_.begin();
+ it != dest_path_.end(); it++)
+ {
+ // TODO : adjust offsets respecting direction relative to
+ // close next tiles
+ switch(tileDir(it->tx, it->ty, it->tz)) {
+ case 0xFFF0:
+ case 0xFF20:
+ it->ox = 200;
+ it->oy = 32;
+ curox = 200;
+ curoy = 32;
+ break;
+ case 0xF4FF:
+ it->ox = 32;
+ it->oy = 200;
+ curox = 32;
+ curoy = 200;
+ break;
+ case 0xFF2F:
+ case 0xF42F:
+ it->ox = 32;
+ it->oy = 32;
+ curox = 32;
+ curoy = 32;
+ break;
+ case 0x6FFF:
+ case 0x64FF:
+ it->ox = 32;
+ it->oy = 200;
+ curox = 32;
+ curoy = 200;
+ break;
+ case 0x6FF0:
+ it->ox = 200;
+ it->oy = 200;
+ curox = 200;
+ curoy = 200;
+ break;
+ default:
+#if 0
+#if _DEBUG
+ printf("hmm tileDir %X at %i, %i, %i\n",
+ (unsigned int)tileDir(it->tileX(), it->tileY(),
+ it->tileZ()), it->tileX(), it->tileY(), it->tileZ());
+ printf("tileAt %i\n",
+ (unsigned int)g_App.maps().map(map())->tileAt(
+ it->tileX(), it->tileY(), it->tileZ()));
+#endif
+#endif
+ it->ox = curox;
+ it->oy = curoy;
+ break;
+ }
+ it->tz = pos_.tz;
+ }
+ }
+ if((!path2add.empty()) && (!dest_path_.empty())) {
+ for (std::vector < TilePoint >::reverse_iterator it = path2add.rbegin();
+ it != path2add.rend(); it++)
+ {
+ it->tz = pos_.tz;
+ dest_path_.push_front(*it);
+ }
+ }
+}
+
+/*!
+ * Moves a vehicle on the map.
+ * \param elapsed Elapsed time sine last frame.
+ */
+bool VehicleInstance::move_vehicle(int elapsed)
+{
+ bool updated = false;
+ int used_time = elapsed;
+
+ while ((!dest_path_.empty()) && used_time != 0) {
+ if (hold_on_.wayFree == 1) { // Must wait
+ return updated;
+ } else if (hold_on_.wayFree == 2){
+ // Must stop : clear destination and stop
+ clearDestination();
+ return updated;
+ }
+
+ // Get distance between car and next NodePath
+ int adx =
+ dest_path_.front().tx * 256 + dest_path_.front().ox;
+ int ady =
+ dest_path_.front().ty * 256 + dest_path_.front().oy;
+ int atx = pos_.tx * 256 + pos_.ox;
+ int aty = pos_.ty * 256 + pos_.oy;
+ int diffx = adx - atx, diffy = ady - aty;
+
+ if (abs(diffx) < 16 && abs(diffy) < 16) {
+ // We reached the next point : remove it from path
+ pos_.oy = dest_path_.front().oy;
+ pos_.ox = dest_path_.front().ox;
+ pos_.ty = dest_path_.front().ty;
+ pos_.tx = dest_path_.front().tx;
+ dest_path_.pop_front();
+ // There's no following point so stop moving
+ if (dest_path_.size() == 0)
+ speed_ = 0;
+ updated = true;
+ } else {
+ setDirection(diffx, diffy, &dir_);
+ int dx = 0, dy = 0;
+ double d = sqrt((double)(diffx * diffx + diffy * diffy));
+ // This is the time for all the remaining distance to the node
+ double avail_time_use = (d / (double)speed_) * 1000.0;
+ // correcting time available regarding the time we have
+ if (avail_time_use > used_time)
+ avail_time_use = used_time;
+
+ // computes distance travelled by vehicle in the available time
+ if (abs(diffx) > 0)
+ // dx = diffx * (speed_ * used_time / 1000) / d;
+ dx = (int)((diffx * (speed_ * avail_time_use) / d) / 1000);
+ if (abs(diffy) > 0)
+ // dy = diffy * (speed_ * used_time / 1000) / d;
+ dy = (int)((diffy * (speed_ * avail_time_use) / d) / 1000);
+
+ // Updates the available time
+ if (dx || dy) {
+ int prv_time = used_time;
+ if (dx) {
+ used_time -= (int)(((double) dx * 1000.0 * d)
+ / (double)(diffx * speed_));
+ } else if (dy) {
+ used_time -= (int)(((double) dy * 1000.0 * d)
+ / (double)(diffy * speed_));
+ } else
+ used_time = 0;
+ if (used_time < 0 || prv_time == used_time)
+ used_time = 0;
+ } else
+ used_time = 0;
+
+ // Moves vehicle
+ updatePlacement(pos_.ox + dx, pos_.oy + dy);
+#if 0
+ if (updatePlacement(pos_.ox + dx, pos_.oy + dy)) {
+ ;
+ } else {
+ // TODO: avoid obstacles.
+ speed_ = 0;
+ }
+#endif
+ if(dest_path_.front().tx == pos_.tx
+ && dest_path_.front().ty == pos_.ty
+ && dest_path_.front().ox == pos_.ox
+ && dest_path_.front().oy == pos_.oy)
+ dest_path_.pop_front();
+ if (dest_path_.size() == 0)
+ speed_ = 0;
+
+ updated = true;
+ }
+ }
+
+ if (dest_path_.empty() && speed_) {
+ printf("Destination Unknown, full speed driving = %i ... doing full stop\n",
+ speed_);
+ speed_ = 0;
+ }
+ if (!passengers_.empty()) {
+ for (std::set<PedInstance *>::iterator it = passengers_.begin();
+ it != passengers_.end(); it++
+ ) {
+ (*it)->setPosition(pos_);
+ }
+ }
+
+ return updated;
+}
+
+
+/*!
+ * Method called when object is hit by a weapon shot.
+ * \param d Damage description
+ */
+void VehicleInstance::handleHit(ShootableMapObject::DamageInflictType &d) {
+ if (health_ <= 0)
+ return;
+
+ decreaseHealth(d.dvalue);
+ if (health_ == 0) {
+ clearDestination();
+ switch ((unsigned int)d.dtype) {
+ case MapObject::dmg_Bullet:
+ case MapObject::dmg_Laser:
+ case MapObject::dmg_Burn:
+ case MapObject::dmg_Explosion:
+ vehicle_->set_animation_type(VehicleAnimation::kOnFireAnim);
+ setTimeShowAnim(10000);
+ break;
+ }
+ pDriver_ = NULL;
+ while (passengers_.size() != 0)
+ {
+ PedInstance *p = *(passengers_.begin());
+ dropPassenger(p);
+ }
+
+ Explosion::createExplosion(g_Session.getMission(), this, 512.0);
+ } else {// NOTE: maybe reduce speed on hit?
+ // TODO: let passengers know that vehicle is attacked
+ }
+}
+
+/*!
+ * Adds the given ped to the passenger but if the vehicle
+ * has no driver, ped becomes the driver.
+ * \param p The ped
+ */
+void VehicleInstance::addPassenger(PedInstance *p) {
+ Vehicle::addPassenger(p);
+ if (pDriver_ == NULL) {
+ // Ped becomes the driver
+ pDriver_ = p;
+ }
+}
+
+/*!
+ * Overload initial method to manage driver.
+ * \param pPed The ped to remove.
+ */
+void VehicleInstance::dropPassenger(PedInstance *pPed) {
+ Vehicle::dropPassenger(pPed);
+ if (pDriver_ == pPed) {
+ pDriver_ = NULL;
+ clearDestination();
+
+ // find another driver in the remaining passengers
+ for (std::set<PedInstance *>::iterator it = passengers_.begin();
+ it != passengers_.end(); it++) {
+ // take the first one
+ pDriver_ = *it;
+ break;
+ }
+ }
+}
+
+/**
+ * Set this ped as the driver of the vehicle and add him as a passenger
+ * if he's not already in the vehicle.
+ * \param pPed PedInstance*
+ * \param forceDriver bool if true, set the driver even if there is already
+ * another driver
+ * \return void
+ *
+ */
+void VehicleInstance::setDriver(PedInstance *pPed, bool forceDriver) {
+ if (pPed != NULL) {
+ if (pDriver_ == NULL || forceDriver) {
+ pDriver_ = pPed;
+ }
+
+ if (!containsPed(pPed)) {
+ Vehicle::addPassenger(pPed);
+ }
+ }
+}
Copied: freesynd/trunk/src/model/vehicle.h (from rev 1004, freesynd/trunk/src/vehicle.h)
===================================================================
--- freesynd/trunk/src/model/vehicle.h (rev 0)
+++ freesynd/trunk/src/model/vehicle.h 2016-06-01 22:27:06 UTC (rev 1005)
@@ -0,0 +1,179 @@
+/************************************************************************
+ * *
+ * FreeSynd - a remake of the classic Bullfrog game "Syndicate". *
+ * *
+ * Copyright (C) 2005 Stuart Binge <sk...@gm...> *
+ * Copyright (C) 2005 Joost Peters <jo...@us...> *
+ * Copyright (C) 2006 Trent Waddington <qg...@bi...> *
+ * Copyright (C) 2006 Tarjei Knapstad <tar...@gm...> *
+ * Copyright (C) 2010 Bohdan Stelmakh <ch...@us...> *
+ * Copyright (C) 2013 Benoit Blancard <be...@us...>*
+ * *
+ * This program is free software; you can redistribute it and / or *
+ * modify it under the terms of the GNU General Public License as *
+ * published by the Free Software Foundation; either version 2 of the *
+ * License, or (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * General Public License for more details. *
+ * *
+ * You can view the GNU General Public License, online, at the GNU *
+ * project's web site; see <http://www.gnu.org/licenses/gpl.html>. *
+ * The full text of the license is also included in the file COPYING. *
+ * *
+ ************************************************************************/
+
+#ifndef VEHICLE_H
+#define VEHICLE_H
+
+#include <string>
+
+#include "mapobject.h"
+#include "ped.h"
+#include "map.h"
+
+/*!
+ * This class holds informations about the animation of a vehicle.
+ */
+class VehicleAnimation {
+public:
+ /*!
+ * This enumeration lists the type of animations.
+ */
+ enum AnimationType {
+ //! Vehicule under normal condition
+ kNormalAnim,
+ //! Burning vehicle
+ kOnFireAnim,
+ //! Burnt vehicle
+ kBurntAnim,
+ } ;
+
+ VehicleAnimation();
+ virtual ~VehicleAnimation() {}
+
+ //! Draw the vehicle
+ void draw(int x, int y, int dir, int frame);
+
+ void set_base_anims(int anims);
+ //void setAnimsBurning(int anims) { anims_burning_ = anims; }
+ //void setAnimsBurnt(int anims) { anims_burnt_ = anims; }
+ //! Sets the current animation for the vehicle
+ void set_animation_type(AnimationType anim) {
+ vehicle_anim_ = anim;
+ }
+ //! Returns the current vehicle animation
+ AnimationType animation_type() {
+ return vehicle_anim_;
+ }
+protected:
+ int anims_, anims_burning_, anims_burnt_;
+ //! Current type of animation
+ AnimationType vehicle_anim_;
+};
+
+/*!
+ * Generic class for all transports.
+ * Transport can be driven or not.
+ */
+class Vehicle : public ShootableMovableMapObject{
+public:
+ static const uint8 kVehicleTypeLargeArmored;
+ static const uint8 kVehicleTypeLargeArmoredDamaged;
+ static const uint8 kVehicleTypeTrainHead;
+ static const uint8 kVehicleTypeTrainBody;
+ static const uint8 kVehicleTypeRegularCar;
+ static const uint8 kVehicleTypeFireFighter;
+ static const uint8 kVehicleTypeSmallArmored;
+ static const uint8 kVehicleTypePolice;
+ static const uint8 kVehicleTypeMedics;
+
+ Vehicle(uint16 anId, uint8 aType, int m) : ShootableMovableMapObject(anId, m, MapObject::kNatureVehicle) {
+ type_ = aType;
+ }
+
+ //! Return true if vehicle is a car
+ bool isCar() { return type_ != kVehicleTypeTrainHead && type_ != kVehicleTypeTrainBody; }
+
+ //void setType(uint8 type) { type_ = type; }
+
+ //! Adds the given ped to the list of passengers
+ virtual void addPassenger(PedInstance *p);
+ //! Removes the passenger from the vehicle
+ virtual void dropPassenger(PedInstance *p);
+
+ //! Returns true if given ped is in the vehicle
+ bool containsPed(PedInstance *p) {
+ return (passengers_.find(p) != passengers_.end());
+ }
+ //! Returns true if the vehicle contains one of our agent
+ bool containsOurAgents();
+ //! Returns true if the vehicle contains peds considered hostile by the given ped
+ bool containsHostilesForPed(PedInstance *p, unsigned int hostile_desc_alt);
+protected:
+ /*! The passengers of the vehicle.*/
+ std::set <PedInstance *> passengers_;
+
+private:
+ /*! Type of vehicle.*/
+ uint8 type_;
+};
+
+/*!
+ * This class represents a Vehicle on a map.
+ */
+class VehicleInstance : public Vehicle
+{
+public:
+ VehicleInstance(VehicleAnimation *vehicle, uint16 id, uint8 aType, int m);
+ virtual ~VehicleInstance() { delete vehicle_;}
+
+ bool animate(int elapsed);
+ void draw(int x, int y);
+
+ //! Set the destination to reach at given speed (todo : replace setDestinationV())
+ bool setDestination(Mission *m, const TilePoint &locT, int newSpeed = -1);
+
+ void addDestinationV(int x, int y, int z, int ox = 128, int oy = 128,
+ int new_speed = 160) {
+ dest_path_.push_back(TilePoint(x, y, z, ox, oy));
+ speed_ = new_speed;
+ }
+
+ void setDestinationV(int x, int y, int z, int ox = 128, int oy = 128, int new_speed = 160);
+
+ //! Adds the given ped to the list of passengers
+ void addPassenger(PedInstance *p);
+ //! Removes the passenger from the vehicle
+ void dropPassenger(PedInstance *p);
+
+ PedInstance *getDriver(void) {
+ return pDriver_;
+ }
+ //! Set this ped as the new driver
+ void setDriver(PedInstance *pPed, bool forceDriver = true);
+
+ /*!
+ * Return true given ped is the driver of this vehicle.
+ * \param pPed a Ped.
+ */
+ bool isDriver(PedInstance *pPed) {
+ return (pPed != NULL && pDriver_ == pPed);
+ }
+
+ void handleHit(ShootableMapObject::DamageInflictType &d);
+
+protected:
+ bool move_vehicle(int elapsed);
+ uint16 tileDir(int x, int y, int z);
+ bool dirWalkable(TilePoint *p, int x, int y, int z);
+
+protected:
+ VehicleAnimation *vehicle_;
+ //! Vehicle driver
+ PedInstance *pDriver_;
+};
+
+#endif
Modified: freesynd/trunk/src/ped.cpp
===================================================================
--- freesynd/trunk/src/ped.cpp 2016-05-03 20:11:20 UTC (rev 1004)
+++ freesynd/trunk/src/ped.cpp 2016-06-01 22:27:06 UTC (rev 1005)
@@ -28,7 +28,7 @@
#include "common.h"
#include "app.h"
#include "utils/log.h"
-#include "vehicle.h"
+#include "model/vehicle.h"
#include "mission.h"
#include "core/squad.h"
#include "core/gamesession.h"
Modified: freesynd/trunk/src/pedmanager.cpp
=...
[truncated message content] |