(svn r17080) [0.7] -Backport from trunk:

- Fix: [NoAI] Documentation of AITile::LevelTiles was wrong (r17049)
- Add: [NoAI] AICompany::Get/Set PresidentGender (r17016)
- Add: [NoAI] AIEngine::GetDesignDate (r17014)
- Add: [NoAI] AIStation::GetConstructionDate (r17012)
- Add: [NoAI] AIAbstractList::SORT_ASCENDING / SORT_DESCENDING (r17005)
- Fix: [NoAI] AIBridge::GetPrice returned incorrect values (r16986)
This commit is contained in:
rubidium 2009-08-05 23:57:41 +00:00
parent fa713d0e3b
commit ad2c54d119
20 changed files with 157 additions and 39 deletions

View File

@ -58,7 +58,7 @@ function Regression::TestInit()
}
list = AIList();
list.Sort(AIAbstractList.SORT_BY_VALUE, true);
list.Sort(AIAbstractList.SORT_BY_VALUE, AIAbstractList.SORT_ASCENDING);
print("");
print(" Value Ascending");
list.AddItem( 5, 10);
@ -93,7 +93,7 @@ function Regression::TestInit()
}
list = AIList();
list.Sort(AIAbstractList.SORT_BY_ITEM, false);
list.Sort(AIAbstractList.SORT_BY_ITEM, AIAbstractList.SORT_DESCENDING);
print("");
print(" Item Descending");
list.AddItem( 5, 10);
@ -128,7 +128,7 @@ function Regression::TestInit()
}
list = AIList();
list.Sort(AIAbstractList.SORT_BY_ITEM, true);
list.Sort(AIAbstractList.SORT_BY_ITEM, AIAbstractList.SORT_ASCENDING);
print("");
print(" Item Ascending");
list.AddItem( 5, 10);
@ -545,7 +545,7 @@ function Regression::Industry()
print("--Industry--");
print(" GetIndustryCount(): " + AIIndustry.GetIndustryCount());
local list = AIIndustryList();
list.Sort(AIAbstractList.SORT_BY_ITEM, true);
list.Sort(AIAbstractList.SORT_BY_ITEM, AIAbstractList.SORT_ASCENDING);
for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
if (AIIndustry.IsValidIndustry(i)) j++;
print(" Industry " + i);
@ -667,7 +667,7 @@ function Regression::List()
print(" HasItem(1050): " + list.HasItem(1050));
print(" HasItem(1051): " + list.HasItem(1051));
print(" IsEmpty(): " + list.IsEmpty());
list.Sort(AIAbstractList.SORT_BY_ITEM, true);
list.Sort(AIAbstractList.SORT_BY_ITEM, AIAbstractList.SORT_ASCENDING);
print(" List Dump:");
for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
print(" " + i + " => " + list.GetValue(i));
@ -1078,7 +1078,7 @@ function Regression::Sign()
print(" RemoveSign(" + sign_id + "): " + AISign.RemoveSign(sign_id));
print("");
local list = AISignList();
list.Sort(AIAbstractList.SORT_BY_ITEM, true);
list.Sort(AIAbstractList.SORT_BY_ITEM, AIAbstractList.SORT_ASCENDING);
for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
j++;
print(" Sign " + i);
@ -1347,7 +1347,7 @@ function Regression::Town()
print("--Town--");
print(" GetTownCount(): " + AITown.GetTownCount());
local list = AITownList();
list.Sort(AIAbstractList.SORT_BY_ITEM, true);
list.Sort(AIAbstractList.SORT_BY_ITEM, AIAbstractList.SORT_ASCENDING);
for (local i = list.Begin(); list.HasNext(); i = list.Next()) {
if (AITown.IsValidTown(i)) j++;
print(" Town " + i);

View File

@ -648,70 +648,70 @@
IsValidBridge(): true
GetName(): Wooden rail bridge
GetMaxSpeed(): 32
GetPrice(): 10
GetPrice(): 15
GetMaxLength(): 102
GetMinLength(): 2
Bridge 1
IsValidBridge(): true
GetName(): Concrete rail bridge
GetMaxSpeed(): 48
GetPrice(): 15
GetPrice(): 21
GetMaxLength(): 4
GetMinLength(): 2
Bridge 2
IsValidBridge(): true
GetName(): Steel girder rail bridge
GetMaxSpeed(): 64
GetPrice(): 19
GetPrice(): 27
GetMaxLength(): 7
GetMinLength(): 2
Bridge 3
IsValidBridge(): true
GetName(): Reinforced concrete suspension rail bridge
GetMaxSpeed(): 80
GetPrice(): 22
GetPrice(): 32
GetMaxLength(): 12
GetMinLength(): 4
Bridge 4
IsValidBridge(): true
GetName(): Steel suspension rail bridge
GetMaxSpeed(): 96
GetPrice(): 25
GetPrice(): 35
GetMaxLength(): 102
GetMinLength(): 5
Bridge 5
IsValidBridge(): true
GetName(): Steel suspension rail bridge
GetMaxSpeed(): 112
GetPrice(): 26
GetPrice(): 36
GetMaxLength(): 102
GetMinLength(): 5
Bridge 6
IsValidBridge(): true
GetName(): Steel cantilever rail bridge
GetMaxSpeed(): 160
GetPrice(): 30
GetPrice(): 42
GetMaxLength(): 9
GetMinLength(): 5
Bridge 7
IsValidBridge(): true
GetName(): Steel cantilever rail bridge
GetMaxSpeed(): 208
GetPrice(): 31
GetPrice(): 44
GetMaxLength(): 10
GetMinLength(): 5
Bridge 8
IsValidBridge(): true
GetName(): Steel cantilever rail bridge
GetMaxSpeed(): 240
GetPrice(): 33
GetPrice(): 47
GetMaxLength(): 11
GetMinLength(): 5
Bridge 9
IsValidBridge(): true
GetName(): Steel girder rail bridge
GetMaxSpeed(): 256
GetPrice(): 32
GetPrice(): 45
GetMaxLength(): 4
GetMinLength(): 2
Bridge 10
@ -773,16 +773,16 @@
1 => 48
0 => 32
Price ListDump:
8 => 33
9 => 32
7 => 31
6 => 30
5 => 26
4 => 25
3 => 22
2 => 19
1 => 15
0 => 10
8 => 47
9 => 45
7 => 44
6 => 42
5 => 36
4 => 35
3 => 32
2 => 27
1 => 21
0 => 15
MaxLength ListDump:
5 => 102
4 => 102
@ -813,9 +813,9 @@
4 => 96
0 => 32
Price ListDump:
5 => 73
4 => 70
0 => 30
5 => 220
4 => 212
0 => 91
--AICargo--
Cargo -1

View File

@ -25,6 +25,11 @@ public:
SORT_BY_ITEM, //!< Sort the list based on the item itself.
};
/** Sort ascending */
static const bool SORT_ASCENDING = true;
/** Sort descnding */
static const bool SORT_DESCENDING = false;
private:
AIAbstractListSorter *sorter;
SorterType sorter_type;
@ -123,6 +128,7 @@ public:
* @param sorter the type of sorter to use
* @param ascending if true, lowest value is on top, else at bottom.
* @note the current item stays at the same place.
* @see SORT_ASCENDING SORT_DESCENDING
*/
void Sort(SorterType sorter, bool ascending);

View File

@ -24,6 +24,9 @@ void SQAIAbstractList_Register(Squirrel *engine) {
SQAIAbstractList.DefSQConst(engine, AIAbstractList::SORT_BY_VALUE, "SORT_BY_VALUE");
SQAIAbstractList.DefSQConst(engine, AIAbstractList::SORT_BY_ITEM, "SORT_BY_ITEM");
SQAIAbstractList.DefSQConst(engine, AIAbstractList::SORT_ASCENDING, "SORT_ASCENDING");
SQAIAbstractList.DefSQConst(engine, AIAbstractList::SORT_DESCENDING, "SORT_DESCENDING");
SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::Clear, "Clear", 1, "x");
SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::HasItem, "HasItem", 2, "xi");
SQAIAbstractList.DefSQMethod(engine, &AIAbstractList::Begin, "Begin", 1, "x");

View File

@ -139,7 +139,7 @@ static void _DoCommandReturnBuildBridge1(class AIInstance *instance)
{
if (!IsValidBridge(bridge_id)) return -1;
return length * _price.build_bridge * ::GetBridgeSpec(bridge_id)->price >> 8;
return ::CalcBridgeLenCostFactor(length) * _price.build_bridge * ::GetBridgeSpec(bridge_id)->price >> 8;
}
/* static */ int32 AIBridge::GetMaxLength(BridgeID bridge_id)

View File

@ -8,6 +8,7 @@
#include "../../command_func.h"
#include "../../company_func.h"
#include "../../company_base.h"
#include "../../company_manager_face.h"
#include "../../economy_func.h"
#include "../../strings_func.h"
#include "../../tile_map.h"
@ -71,6 +72,27 @@
return president_name;
}
/* static */ bool AICompany::SetPresidentGender(Gender gender)
{
EnforcePrecondition(false, gender == GENDER_MALE || gender == GENDER_FEMALE);
EnforcePrecondition(false, GetPresidentGender(AICompany::COMPANY_SELF) != gender);
CompanyManagerFace cmf;
GenderEthnicity ge = (GenderEthnicity)((gender == GENDER_FEMALE ? (1 << ::GENDER_FEMALE) : 0) | (::InteractiveRandom() & (1 << ETHNICITY_BLACK)));
RandomCompanyManagerFaceBits(cmf, ge, false);
return AIObject::DoCommand(0, 0, cmf, CMD_SET_COMPANY_MANAGER_FACE);
}
/* static */ AICompany::Gender AICompany::GetPresidentGender(CompanyID company)
{
company = ResolveCompanyID(company);
if (company == COMPANY_INVALID) return GENDER_INVALID;
GenderEthnicity ge = (GenderEthnicity)GetCompanyManagerFaceBits(GetCompany(company)->face, CMFV_GEN_ETHN, GE_WM);
return HasBit(ge, ::GENDER_FEMALE) ? GENDER_FEMALE : GENDER_MALE;
}
/* static */ Money AICompany::GetCompanyValue(AICompany::CompanyID company)
{
company = ResolveCompanyID(company);

View File

@ -26,6 +26,13 @@ public:
COMPANY_SELF = 254, //!< Constant that gets resolved to the correct company index for your company.
};
/** Possible genders for company presidents. */
enum Gender {
GENDER_MALE, //!< A male person.
GENDER_FEMALE, //!< A female person.
GENDER_INVALID = -1, //!< An invalid gender.
};
/**
* Resolved the given company index to the correct index for the company. If
* the company index was COMPANY_SELF it will be resolved to the index of
@ -78,6 +85,22 @@ public:
*/
static char *GetPresidentName(CompanyID company);
/**
* Set the gender of the president of your company.
* @param gender The new gender for your president.
* @pre GetPresidentGender(AICompany.COMPANY_SELF) != gender.
* @return True if the gender was changed.
* @note When succesfull a random face will be created.
*/
static bool SetPresidentGender(Gender gender);
/**
* Get the gender of the president of the given company.
* @param company The company to get the presidents gender off.
* @return The gender of the president.
*/
static Gender GetPresidentGender(CompanyID company);
/**
* Sets the amount to loan.
* @param loan The amount to loan (multiplier of GetLoanInterval()).

View File

@ -7,6 +7,8 @@ namespace SQConvert {
/* Allow enums to be used as Squirrel parameters */
template <> AICompany::CompanyID GetParam(ForceType<AICompany::CompanyID>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (AICompany::CompanyID)tmp; }
template <> int Return<AICompany::CompanyID>(HSQUIRRELVM vm, AICompany::CompanyID res) { sq_pushinteger(vm, (int32)res); return 1; }
template <> AICompany::Gender GetParam(ForceType<AICompany::Gender>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (AICompany::Gender)tmp; }
template <> int Return<AICompany::Gender>(HSQUIRRELVM vm, AICompany::Gender res) { sq_pushinteger(vm, (int32)res); return 1; }
/* Allow AICompany to be used as Squirrel parameter */
template <> AICompany *GetParam(ForceType<AICompany *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (AICompany *)instance; }
@ -25,6 +27,9 @@ void SQAICompany_Register(Squirrel *engine) {
SQAICompany.DefSQConst(engine, AICompany::COMPANY_FIRST, "COMPANY_FIRST");
SQAICompany.DefSQConst(engine, AICompany::COMPANY_LAST, "COMPANY_LAST");
SQAICompany.DefSQConst(engine, AICompany::COMPANY_SELF, "COMPANY_SELF");
SQAICompany.DefSQConst(engine, AICompany::GENDER_MALE, "GENDER_MALE");
SQAICompany.DefSQConst(engine, AICompany::GENDER_FEMALE, "GENDER_FEMALE");
SQAICompany.DefSQConst(engine, AICompany::GENDER_INVALID, "GENDER_INVALID");
SQAICompany.DefSQStaticMethod(engine, &AICompany::ResolveCompanyID, "ResolveCompanyID", 2, ".i");
SQAICompany.DefSQStaticMethod(engine, &AICompany::IsMine, "IsMine", 2, ".i");
@ -32,6 +37,8 @@ void SQAICompany_Register(Squirrel *engine) {
SQAICompany.DefSQStaticMethod(engine, &AICompany::GetName, "GetName", 2, ".i");
SQAICompany.DefSQStaticMethod(engine, &AICompany::SetPresidentName, "SetPresidentName", 2, ".s");
SQAICompany.DefSQStaticMethod(engine, &AICompany::GetPresidentName, "GetPresidentName", 2, ".i");
SQAICompany.DefSQStaticMethod(engine, &AICompany::SetPresidentGender, "SetPresidentGender", 2, ".i");
SQAICompany.DefSQStaticMethod(engine, &AICompany::GetPresidentGender, "GetPresidentGender", 2, ".i");
SQAICompany.DefSQStaticMethod(engine, &AICompany::SetLoanAmount, "SetLoanAmount", 2, ".i");
SQAICompany.DefSQStaticMethod(engine, &AICompany::SetMinimumLoanAmount, "SetMinimumLoanAmount", 2, ".i");
SQAICompany.DefSQStaticMethod(engine, &AICompany::GetLoanAmount, "GetLoanAmount", 1, ".");

View File

@ -152,6 +152,13 @@
return ::GetEngine(engine_id)->GetDisplayMaxTractiveEffort();
}
/* static */ int32 AIEngine::GetDesignDate(EngineID engine_id)
{
if (!IsValidEngine(engine_id)) return -1;
return ::GetEngine(engine_id)->intro_date;
}
/* static */ AIVehicle::VehicleType AIEngine::GetVehicleType(EngineID engine_id)
{
if (!IsValidEngine(engine_id)) return AIVehicle::VT_INVALID;

View File

@ -152,6 +152,14 @@ public:
*/
static int32 GetMaxTractiveEffort(EngineID engine_id);
/**
* Get the date this engine was designed.
* @param engine_id The engine to get the design date of.
* @pre IsValidEngine(engine_id).
* @return The date this engine was designed.
*/
static int32 GetDesignDate(EngineID engine_id);
/**
* Get the type of an engine.
* @param engine_id The engine to get the type of.

View File

@ -31,6 +31,7 @@ void SQAIEngine_Register(Squirrel *engine) {
SQAIEngine.DefSQStaticMethod(engine, &AIEngine::GetPower, "GetPower", 2, ".i");
SQAIEngine.DefSQStaticMethod(engine, &AIEngine::GetWeight, "GetWeight", 2, ".i");
SQAIEngine.DefSQStaticMethod(engine, &AIEngine::GetMaxTractiveEffort, "GetMaxTractiveEffort", 2, ".i");
SQAIEngine.DefSQStaticMethod(engine, &AIEngine::GetDesignDate, "GetDesignDate", 2, ".i");
SQAIEngine.DefSQStaticMethod(engine, &AIEngine::GetVehicleType, "GetVehicleType", 2, ".i");
SQAIEngine.DefSQStaticMethod(engine, &AIEngine::IsWagon, "IsWagon", 2, ".i");
SQAIEngine.DefSQStaticMethod(engine, &AIEngine::CanRunOnRail, "CanRunOnRail", 3, ".ii");

View File

@ -13,9 +13,7 @@
class AIMap : public AIObject {
public:
#ifdef DEFINE_SCRIPT_FILES
enum MapType {
TILE_INVALID = INVALID_TILE, //!< Invalid TileIndex.
};
static const int TILE_INVALID = INVALID_TILE; //!< Invalid TileIndex.
#endif /* DEFINE_SCRIPT_FILES */
#ifdef DOXYGEN_SKIP
const static TileIndex TILE_INVALID; //!< Invalid TileIndex.

View File

@ -4,10 +4,6 @@
#include "ai_map.hpp"
namespace SQConvert {
/* Allow enums to be used as Squirrel parameters */
template <> AIMap::MapType GetParam(ForceType<AIMap::MapType>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (AIMap::MapType)tmp; }
template <> int Return<AIMap::MapType>(HSQUIRRELVM vm, AIMap::MapType res) { sq_pushinteger(vm, (int32)res); return 1; }
/* Allow AIMap to be used as Squirrel parameter */
template <> AIMap *GetParam(ForceType<AIMap *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (AIMap *)instance; }
template <> AIMap &GetParam(ForceType<AIMap &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIMap *)instance; }

View File

@ -55,6 +55,13 @@
return ::GetStation(station_id)->xy;
}
/* static */ int32 AIStation::GetConstructionDate(StationID station_id)
{
if (!IsValidStation(station_id)) return -1;
return ::GetStation(station_id)->build_date;
}
/* static */ int32 AIStation::GetCargoWaiting(StationID station_id, CargoID cargo_id)
{
if (!IsValidStation(station_id)) return -1;

View File

@ -102,6 +102,13 @@ public:
*/
static TileIndex GetLocation(StationID station_id);
/**
* Get the last date a station part was added to this station.
* @param station_id The station to look at.
* @return The last date some part of this station was build.
*/
static int32 GetConstructionDate(StationID station_id);
/**
* See how much cargo there is waiting on a station.
* @param station_id The station to get the cargo-waiting of.

View File

@ -59,6 +59,7 @@ void SQAIStation_Register(Squirrel *engine) {
SQAIStation.DefSQStaticMethod(engine, &AIStation::GetName, "GetName", 2, ".i");
SQAIStation.DefSQStaticMethod(engine, &AIStation::SetName, "SetName", 3, ".is");
SQAIStation.DefSQStaticMethod(engine, &AIStation::GetLocation, "GetLocation", 2, ".i");
SQAIStation.DefSQStaticMethod(engine, &AIStation::GetConstructionDate, "GetConstructionDate", 2, ".i");
SQAIStation.DefSQStaticMethod(engine, &AIStation::GetCargoWaiting, "GetCargoWaiting", 3, ".ii");
SQAIStation.DefSQStaticMethod(engine, &AIStation::GetCargoRating, "GetCargoRating", 3, ".ii");
SQAIStation.DefSQStaticMethod(engine, &AIStation::GetCoverageRadius, "GetCoverageRadius", 2, ".i");

View File

@ -386,7 +386,7 @@ public:
* @pre end_tile < AIMap::GetMapSize().
* @exception AIError::ERR_AREA_NOT_CLEAR
* @exception AIError::ERR_TOO_CLOSE_TO_EDGE
* @return True if and only if the area was completely leveled.
* @return True if one or more tiles were leveled.
* @note Even if leveling some part fails, some other part may have been
* succesfully leveled already.
* @note This function may return true in AITestMode, although it fails in

View File

@ -34,6 +34,7 @@ BEGIN {
enum_value_size = 0
enum_string_to_error_size = 0
enum_error_to_string_size = 0
const_size = 0
struct_size = 0
method_size = 0
static_method_size = 0
@ -217,6 +218,17 @@ BEGIN {
}
if (enum_value_size != 0) print ""
# Const values
mlen = 0
for (i = 1; i <= const_size; i++) {
if (mlen <= length(const_value[i])) mlen = length(const_value[i])
}
for (i = 1; i <= const_size; i++) {
print " SQ" cls ".DefSQConst(engine, " cls "::" const_value[i] ", " substr(spaces, 1, mlen - length(const_value[i])) "\"" const_value[i] "\");"
delete const_value[i]
}
if (const_size != 0) print ""
# Mapping of OTTD strings to errors
mlen = 0
for (i = 1; i <= enum_string_to_error_size; i++) {
@ -320,6 +332,13 @@ BEGIN {
}
}
# Add a const (non-enum) value
/^[ ]*static const \w+ \w+ = \w+;/ {
const_size++
const_value[const_size] = $4
next
}
# Add a method to the list
/^.*\(.*\).*$/ {
if (cls_level != 1) next

View File

@ -131,6 +131,13 @@ void Squirrel::AddConst(const char *var_name, int value)
sq_newslot(this->vm, -3, SQTrue);
}
void Squirrel::AddConst(const char *var_name, bool value)
{
sq_pushstring(this->vm, OTTD2FS(var_name), -1);
sq_pushbool(this->vm, value);
sq_newslot(this->vm, -3, SQTrue);
}
void Squirrel::AddClassBegin(const char *class_name)
{
sq_pushroottable(this->vm);

View File

@ -77,6 +77,12 @@ public:
*/
void AddConst(const char *var_name, int value);
/**
* Adds a const to the stack. Depending on the current state this means
* either a const to a class or to the global space.
*/
void AddConst(const char *var_name, bool value);
/**
* Adds a class to the global scope. Make sure to call AddClassEnd when you
* are done adding methods.