(svn r12838) [NoAI] -Add: added AIEventEnginePreview, which tells you when you have been chosen for testing an engine, and allows you to accept it
--- a/src/ai/ai_squirrel.cpp Mon Apr 21 21:15:50 2008 +0000
+++ b/src/ai/ai_squirrel.cpp Tue Apr 22 17:04:06 2008 +0000
@@ -230,6 +230,7 @@
SQAIError_Register(this->engine);
SQAIEvent_Register(this->engine);
SQAIEventController_Register(this->engine);
+ SQAIEventEnginePreview_Register(this->engine);
SQAIEventSubsidyOffer_Register(this->engine);
SQAIEventTest_Register(this->engine);
SQAIEventVehicleCrash_Register(this->engine);
--- a/src/ai/api/ai_event.hpp Mon Apr 21 21:15:50 2008 +0000
+++ b/src/ai/api/ai_event.hpp Tue Apr 22 17:04:06 2008 +0000
@@ -24,6 +24,7 @@
AI_ET_TEST,
AI_ET_CRASHED_VEHICLE,
AI_ET_SUBSIDY_OFFER,
+ AI_ET_ENGINE_PREVIEW,
};
/**
--- a/src/ai/api/ai_event.hpp.sq Mon Apr 21 21:15:50 2008 +0000
+++ b/src/ai/api/ai_event.hpp.sq Tue Apr 22 17:04:06 2008 +0000
@@ -25,6 +25,7 @@
SQAIEvent.DefSQConst(engine, AIEvent::AI_ET_TEST, "AI_ET_TEST");
SQAIEvent.DefSQConst(engine, AIEvent::AI_ET_CRASHED_VEHICLE, "AI_ET_CRASHED_VEHICLE");
SQAIEvent.DefSQConst(engine, AIEvent::AI_ET_SUBSIDY_OFFER, "AI_ET_SUBSIDY_OFFER");
+ SQAIEvent.DefSQConst(engine, AIEvent::AI_ET_ENGINE_PREVIEW, "AI_ET_ENGINE_PREVIEW");
SQAIEvent.DefSQStaticMethod(engine, &AIEvent::GetClassName, "GetClassName", 1, "x");
--- a/src/ai/api/ai_event_types.cpp Mon Apr 21 21:15:50 2008 +0000
+++ b/src/ai/api/ai_event_types.cpp Tue Apr 22 17:04:06 2008 +0000
@@ -3,8 +3,183 @@
/** @file ai_event_types.cpp Implementation of all EventTypes. */
#include "ai_event_types.hpp"
+#include "../../strings_func.h"
+#include "../../roadveh.h"
+#include "../../train.h"
+#include "../../ship.h"
+#include "../../aircraft.h"
+#include "../../settings_type.h"
+#include "../../articulated_vehicles.h"
+#include "table/strings.h"
bool AIEventVehicleCrash::CloneCrashedVehicle(TileIndex depot)
{
return false;
}
+
+char *AIEventEnginePreview::GetName()
+{
+ static const int len = 64;
+ char *engine_name = MallocT<char>(len);
+
+ ::SetDParam(0, engine);
+ ::GetString(engine_name, STR_ENGINE_NAME, &engine_name[len - 1]);
+ return engine_name;
+}
+
+CargoID AIEventEnginePreview::GetCargoType()
+{
+ switch (::GetEngine(engine)->type) {
+ case VEH_ROAD: {
+ const RoadVehicleInfo *vi = ::RoadVehInfo(engine);
+ return vi->cargo_type;
+ } break;
+
+ case VEH_TRAIN: {
+ const RailVehicleInfo *vi = ::RailVehInfo(engine);
+ return vi->cargo_type;
+ } break;
+
+ case VEH_SHIP: {
+ const ShipVehicleInfo *vi = ::ShipVehInfo(engine);
+ return vi->cargo_type;
+ } break;
+
+ case VEH_AIRCRAFT: {
+ return CT_PASSENGERS;
+ } break;
+
+ default: NOT_REACHED();
+ }
+}
+
+int32 AIEventEnginePreview::GetCapacity()
+{
+ switch (::GetEngine(engine)->type) {
+ case VEH_ROAD:
+ case VEH_TRAIN: {
+ uint16 *capacities = GetCapacityOfArticulatedParts(engine, ::GetEngine(engine)->type);
+ for (CargoID c = 0; c < NUM_CARGO; c++) {
+ if (capacities[c] == 0) continue;
+ return capacities[c];
+ }
+ return -1;
+ } break;
+
+ case VEH_SHIP: {
+ const ShipVehicleInfo *vi = ::ShipVehInfo(engine);
+ return vi->capacity;
+ } break;
+
+ case VEH_AIRCRAFT: {
+ const AircraftVehicleInfo *vi = ::AircraftVehInfo(engine);
+ return vi->passenger_capacity;
+ } break;
+
+ default: NOT_REACHED();
+ }
+}
+
+int32 AIEventEnginePreview::GetMaxSpeed()
+{
+ switch (::GetEngine(engine)->type) {
+ case VEH_ROAD: {
+ const RoadVehicleInfo *vi = ::RoadVehInfo(engine);
+ /* Internal speeds are km/h * 2 */
+ return vi->max_speed / 2;
+ } break;
+
+ case VEH_TRAIN: {
+ const RailVehicleInfo *vi = ::RailVehInfo(engine);
+ return vi->max_speed;
+ } break;
+
+ case VEH_SHIP: {
+ const ShipVehicleInfo *vi = ::ShipVehInfo(engine);
+ /* Internal speeds are km/h * 2 */
+ return vi->max_speed / 2;
+ } break;
+
+ case VEH_AIRCRAFT: {
+ const AircraftVehicleInfo *vi = ::AircraftVehInfo(engine);
+ return vi->max_speed / _patches.plane_speed;
+ } break;
+
+ default: NOT_REACHED();
+ }
+}
+
+Money AIEventEnginePreview::GetPrice()
+{
+ switch (::GetEngine(engine)->type) {
+ case VEH_ROAD: {
+ const RoadVehicleInfo *vi = ::RoadVehInfo(engine);
+ return (_price.roadveh_base >> 3) * vi->base_cost >> 5;
+ } break;
+
+ case VEH_TRAIN: {
+ const RailVehicleInfo *vi = ::RailVehInfo(engine);
+ return (_price.build_railvehicle >> 3) * vi->base_cost >> 5;
+ } break;
+
+ case VEH_SHIP: {
+ const ShipVehicleInfo *vi = ::ShipVehInfo(engine);
+ return (_price.ship_base >> 3) * vi->base_cost >> 5;
+ } break;
+
+ case VEH_AIRCRAFT: {
+ const AircraftVehicleInfo *vi = ::AircraftVehInfo(engine);
+ return (_price.aircraft_base >> 3) * vi->base_cost >> 5;
+ } break;
+
+ default: NOT_REACHED();
+ }
+}
+
+Money AIEventEnginePreview::GetRunningCost()
+{
+ /* We need to create an instance in order to obtain GetRunningCost.
+ * This means we temporary allocate a vehicle in the pool, but
+ * there is no other way.. */
+ Vehicle *vehicle;
+ switch (::GetEngine(engine)->type) {
+ case VEH_ROAD: {
+ vehicle = new RoadVehicle();
+ } break;
+
+ case VEH_TRAIN: {
+ vehicle = new Train();
+ } break;
+
+ case VEH_SHIP: {
+ vehicle = new Ship();
+ } break;
+
+ case VEH_AIRCRAFT: {
+ vehicle = new Aircraft();
+ } break;
+
+ default: NOT_REACHED();
+ }
+
+ vehicle->engine_type = engine;
+ Money runningCost = vehicle->GetRunningCost();
+ delete vehicle;
+ return runningCost >> 8;
+}
+
+AIVehicle::VehicleType AIEventEnginePreview::GetVehicleType()
+{
+ switch (::GetEngine(engine)->type) {
+ case VEH_ROAD: return AIVehicle::VEHICLE_ROAD;
+ case VEH_TRAIN: return AIVehicle::VEHICLE_RAIL;
+ case VEH_SHIP: return AIVehicle::VEHICLE_WATER;
+ case VEH_AIRCRAFT: return AIVehicle::VEHICLE_AIR;
+ default: NOT_REACHED();
+ }
+}
+
+bool AIEventEnginePreview::AcceptPreview()
+{
+ return AIObject::DoCommand(0, engine, 0, CMD_WANT_ENGINE_PREVIEW);
+}
--- a/src/ai/api/ai_event_types.hpp Mon Apr 21 21:15:50 2008 +0000
+++ b/src/ai/api/ai_event_types.hpp Tue Apr 22 17:04:06 2008 +0000
@@ -9,6 +9,7 @@
#include "ai_event.hpp"
#include "ai_town.hpp"
#include "ai_industry.hpp"
+#include "ai_engine.hpp"
/**
* Event Test: a simple test event, to see if the event system is working.
@@ -167,4 +168,83 @@
uint32 to;
};
+/**
+ * Event Engine Preview, indicating a manufacturer offer you to test a new engine.
+ * You can get the type of engine.
+ */
+class AIEventEnginePreview : public AIEvent {
+public:
+ static const char *GetClassName() { return "AIEventEnginePreview"; }
+
+ /**
+ * @param engine The engine offered to test.
+ */
+ AIEventEnginePreview(EngineID engine) :
+ AIEvent(AI_ET_ENGINE_PREVIEW),
+ engine(engine)
+ {}
+
+ /**
+ * Convert an AIEvent to the real instance.
+ * @param instance The instance to convert.
+ * @return The converted instance.
+ */
+ static AIEventEnginePreview *Convert(AIEvent *instance) { return (AIEventEnginePreview *)instance; }
+
+ /**
+ * Get the name of the offered engine.
+ * @return The name the engine has.
+ */
+ char *GetName();
+
+ /**
+ * Get the cargo-type of the offered engine. In case it can transport 2 cargos, it
+ * returns the first.
+ * @return The cargo-type of the engine.
+ */
+ CargoID GetCargoType();
+
+ /**
+ * Get the capacity of the offered engine. In case it can transport 2 cargos, it
+ * returns the first.
+ * @return The capacity of the engine.
+ */
+ int32 GetCapacity();
+
+ /**
+ * Get the maximum speed of the offered engine.
+ * @return The maximum speed the engine has.
+ * @note The speed is in km/h.
+ */
+ int32 GetMaxSpeed();
+
+ /**
+ * Get the new cost of the offered engine.
+ * @return The new cost the engine has.
+ */
+ Money GetPrice();
+
+ /**
+ * Get the running cost of the offered engine.
+ * @return The running cost of the vehicle per year.
+ * @note Cost is per year; divide by 364 to get per day.
+ */
+ Money GetRunningCost();
+
+ /**
+ * Get the type of the offered engine.
+ * @return The type the engine has.
+ */
+ AIVehicle::VehicleType GetVehicleType();
+
+ /**
+ * Accept the engine preview.
+ * @return True when the accepting succeeded.
+ */
+ bool AcceptPreview();
+
+private:
+ EngineID engine;
+};
+
#endif /* AI_EVENT_TYPES_HPP */
--- a/src/ai/api/ai_event_types.hpp.sq Mon Apr 21 21:15:50 2008 +0000
+++ b/src/ai/api/ai_event_types.hpp.sq Tue Apr 22 17:04:06 2008 +0000
@@ -74,3 +74,32 @@
SQAIEventSubsidyOffer.PostRegister(engine);
}
+
+namespace SQConvert {
+ /* Allow AIEventEnginePreview to be used as Squirrel parameter */
+ template <> AIEventEnginePreview *GetParam(ForceType<AIEventEnginePreview *>, HSQUIRRELVM vm, int index) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (AIEventEnginePreview *)instance; }
+ template <> AIEventEnginePreview &GetParam(ForceType<AIEventEnginePreview &>, HSQUIRRELVM vm, int index) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIEventEnginePreview *)instance; }
+ template <> const AIEventEnginePreview *GetParam(ForceType<const AIEventEnginePreview *>, HSQUIRRELVM vm, int index) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (AIEventEnginePreview *)instance; }
+ template <> const AIEventEnginePreview &GetParam(ForceType<const AIEventEnginePreview &>, HSQUIRRELVM vm, int index) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIEventEnginePreview *)instance; }
+ template <> int Return<AIEventEnginePreview *>(HSQUIRRELVM vm, AIEventEnginePreview *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIEventEnginePreview", res, NULL, DefSQDestructorCallback<AIEventEnginePreview>); return 1; }
+}; // namespace SQConvert
+
+void SQAIEventEnginePreview_Register(Squirrel *engine) {
+ DefSQClass <AIEventEnginePreview> SQAIEventEnginePreview("AIEventEnginePreview");
+ SQAIEventEnginePreview.PreRegister(engine, "AIEvent");
+ SQAIEventEnginePreview.AddConstructor<void (AIEventEnginePreview::*)(EngineID engine), 2>(engine, "xi");
+
+ SQAIEventEnginePreview.DefSQStaticMethod(engine, &AIEventEnginePreview::GetClassName, "GetClassName", 1, "x");
+ SQAIEventEnginePreview.DefSQStaticMethod(engine, &AIEventEnginePreview::Convert, "Convert", 2, "xx");
+
+ SQAIEventEnginePreview.DefSQMethod(engine, &AIEventEnginePreview::GetName, "GetName", 1, "x");
+ SQAIEventEnginePreview.DefSQMethod(engine, &AIEventEnginePreview::GetCargoType, "GetCargoType", 1, "x");
+ SQAIEventEnginePreview.DefSQMethod(engine, &AIEventEnginePreview::GetCapacity, "GetCapacity", 1, "x");
+ SQAIEventEnginePreview.DefSQMethod(engine, &AIEventEnginePreview::GetMaxSpeed, "GetMaxSpeed", 1, "x");
+ SQAIEventEnginePreview.DefSQMethod(engine, &AIEventEnginePreview::GetPrice, "GetPrice", 1, "x");
+ SQAIEventEnginePreview.DefSQMethod(engine, &AIEventEnginePreview::GetRunningCost, "GetRunningCost", 1, "x");
+ SQAIEventEnginePreview.DefSQMethod(engine, &AIEventEnginePreview::GetVehicleType, "GetVehicleType", 1, "x");
+ SQAIEventEnginePreview.DefSQMethod(engine, &AIEventEnginePreview::AcceptPreview, "AcceptPreview", 1, "x");
+
+ SQAIEventEnginePreview.PostRegister(engine);
+}
--- a/src/engine.cpp Mon Apr 21 21:15:50 2008 +0000
+++ b/src/engine.cpp Tue Apr 22 17:04:06 2008 +0000
@@ -26,6 +26,7 @@
#include "string_func.h"
#include "settings_type.h"
#include "oldpool_func.h"
+#include "ai/ai.h"
#include "table/strings.h"
#include "table/engines.h"
@@ -247,14 +248,10 @@
continue;
}
- if (!IsHumanPlayer(best_player)) {
- /* XXX - TTDBUG: TTD has a bug here ???? */
- AcceptEnginePreview(i, best_player);
- } else {
- e->flags |= ENGINE_OFFER_WINDOW_OPEN;
- e->preview_wait = 20;
- if (IsInteractivePlayer(best_player)) ShowEnginePreviewWindow(i);
- }
+ e->flags |= ENGINE_OFFER_WINDOW_OPEN;
+ e->preview_wait = 20;
+ AI_Event(best_player, new AIEventEnginePreview(i));
+ if (IsInteractivePlayer(best_player)) ShowEnginePreviewWindow(i);
}
}
}