# HG changeset patch # User glx # Date 1208883846 0 # Node ID 433b21fd002ce2f81211185d8ce7a35698473ec2 # Parent 7798ae816af8a9163934161e8ec502351ada1a18 (svn r12838) [NoAI] -Add: added AIEventEnginePreview, which tells you when you have been chosen for testing an engine, and allows you to accept it diff -r 7798ae816af8 -r 433b21fd002c src/ai/ai_squirrel.cpp --- 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); diff -r 7798ae816af8 -r 433b21fd002c src/ai/api/ai_event.hpp --- 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, }; /** diff -r 7798ae816af8 -r 433b21fd002c src/ai/api/ai_event.hpp.sq --- 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"); diff -r 7798ae816af8 -r 433b21fd002c src/ai/api/ai_event_types.cpp --- 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(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); +} diff -r 7798ae816af8 -r 433b21fd002c src/ai/api/ai_event_types.hpp --- 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 */ diff -r 7798ae816af8 -r 433b21fd002c src/ai/api/ai_event_types.hpp.sq --- 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, HSQUIRRELVM vm, int index) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (AIEventEnginePreview *)instance; } + template <> AIEventEnginePreview &GetParam(ForceType, HSQUIRRELVM vm, int index) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIEventEnginePreview *)instance; } + template <> const AIEventEnginePreview *GetParam(ForceType, HSQUIRRELVM vm, int index) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (AIEventEnginePreview *)instance; } + template <> const AIEventEnginePreview &GetParam(ForceType, HSQUIRRELVM vm, int index) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIEventEnginePreview *)instance; } + template <> int Return(HSQUIRRELVM vm, AIEventEnginePreview *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIEventEnginePreview", res, NULL, DefSQDestructorCallback); return 1; } +}; // namespace SQConvert + +void SQAIEventEnginePreview_Register(Squirrel *engine) { + DefSQClass SQAIEventEnginePreview("AIEventEnginePreview"); + SQAIEventEnginePreview.PreRegister(engine, "AIEvent"); + SQAIEventEnginePreview.AddConstructor(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); +} diff -r 7798ae816af8 -r 433b21fd002c src/engine.cpp --- 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); } } }