16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-22 13:59:19 +02:00

build 170913. improved AI driving on slopes, consist collision distance in whois event, cab render fix

This commit is contained in:
tmj-fstate
2017-09-14 00:29:55 +02:00
parent d75c9ff14d
commit f6fa8ee09b
7 changed files with 83 additions and 68 deletions

View File

@@ -1355,7 +1355,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
// modifies brake distance for low target speeds, to ease braking rate in such situations // modifies brake distance for low target speeds, to ease braking rate in such situations
float float
TController::braking_distance_multiplier( float const Targetvelocity ) { TController::braking_distance_multiplier( float const Targetvelocity ) const {
if( Targetvelocity > 65.f ) { return 1.f; } if( Targetvelocity > 65.f ) { return 1.f; }
if( Targetvelocity < 5.f ) { return 1.f; } if( Targetvelocity < 5.f ) { return 1.f; }
@@ -3989,6 +3989,11 @@ TController::UpdateSituation(double dt) {
// bottom margin raised to 2 km/h to give the AI more leeway at low speed limits // bottom margin raised to 2 km/h to give the AI more leeway at low speed limits
fVelPlus = clamp( std::ceil( 0.05 * VelDesired ), 2.0, 5.0 ); fVelPlus = clamp( std::ceil( 0.05 * VelDesired ), 2.0, 5.0 );
} }
if( mvOccupied->BrakeDelayFlag == bdelay_G ) {
// increase distances for cargo trains to take into account slower reaction to brakes
fMinProximityDist += 10.0;
fMaxProximityDist += 10.0;
}
} }
else { else {
// samochod (sokista też) // samochod (sokista też)
@@ -4299,6 +4304,12 @@ TController::UpdateSituation(double dt) {
if( vehicle->fTrackBlock <= fMinProximityDist ) { if( vehicle->fTrackBlock <= fMinProximityDist ) {
VelDesired = 0.0; VelDesired = 0.0;
} }
if( ( mvOccupied->CategoryFlag & 1 )
&& ( OrderCurrentGet() & Obey_train ) ) {
// trains which move normally should try to stop at safe margin
ActualProximityDist -= fDriverDist;
}
} }
} }
else { else {
@@ -4561,13 +4572,14 @@ TController::UpdateSituation(double dt) {
// jesli jedzie za szybko do AKTUALNEGO // jesli jedzie za szybko do AKTUALNEGO
if( VelDesired == 0.0 ) { if( VelDesired == 0.0 ) {
// jesli stoj, to hamuj, ale i tak juz za pozno :) // jesli stoj, to hamuj, ale i tak juz za pozno :)
AccDesired = std::min( AccDesired, -0.9 ); // hamuj solidnie AccDesired = std::min( AccDesired, -0.85 ); // hamuj solidnie
} }
else { else {
// slow down, not full stop // try to estimate increase of current velocity before engaged brakes start working
if( vel > ( VelDesired + fVelPlus ) ) { // if it looks like we'll exceed maximum allowed speed start thinking about slight slowing down
if( ( vel + vel * ( 1.0 - fBrake_a0[ 0 ] ) * AbsAccS ) > ( VelDesired + fVelPlus ) ) {
// hamuj tak średnio // hamuj tak średnio
AccDesired = std::min( AccDesired, -fBrake_a0[ 0 ] * 0.5 ); AccDesired = std::min( AccDesired, -0.25 );
} }
else { else {
// o 5 km/h to olej (zacznij luzować) // o 5 km/h to olej (zacznij luzować)
@@ -4581,6 +4593,8 @@ TController::UpdateSituation(double dt) {
// last step sanity check, until the whole calculation is straightened out // last step sanity check, until the whole calculation is straightened out
AccDesired = std::min( AccDesired, AccPreferred ); AccDesired = std::min( AccDesired, AccPreferred );
// also take into account impact of gravity
AccDesired = clamp( AccDesired - fAccGravity, -0.9, 0.9 );
@@ -4637,15 +4651,20 @@ TController::UpdateSituation(double dt) {
} }
// NOTE: as a stop-gap measure the routine is limited to trains only while car calculations seem off // NOTE: as a stop-gap measure the routine is limited to trains only while car calculations seem off
if( mvControlling->CategoryFlag == 1 ) { if( mvControlling->CategoryFlag == 1 ) {
if( vel < VelDesired ) {
// don't adjust acceleration when going above current goal speed
if( -AccDesired * BrakeAccFactor() < ( if( -AccDesired * BrakeAccFactor() < (
( ( fReady > 0.4 ) || ( VelNext > vel - 40.0 ) ) ? ( ( fReady > 0.4 )
|| ( VelNext > vel - 40.0 ) ) ?
fBrake_a0[ 0 ] * 0.8 : fBrake_a0[ 0 ] * 0.8 :
-fAccThreshold ) -fAccThreshold )
/ braking_distance_multiplier( VelNext ) ) { / braking_distance_multiplier( VelNext ) ) {
AccDesired = std::max( -0.06, AccDesired ); AccDesired = std::max( -0.06, AccDesired );
} }
}
else { else {
ReactionTime = 0.25; // i orientuj się szybciej, jeśli hamujesz // i orientuj się szybciej, jeśli hamujesz
ReactionTime = 0.25;
} }
} }
if (mvOccupied->BrakeSystem == Pneumatic) // napełnianie uderzeniowe if (mvOccupied->BrakeSystem == Pneumatic) // napełnianie uderzeniowe
@@ -5510,6 +5529,13 @@ bool TController::IsStop()
return TrainParams->IsStop(); return TrainParams->IsStop();
}; };
// returns most recently calculated distance to potential obstacle ahead
double
TController::TrackBlock() const {
return pVehicles[ TMoverParameters::side::front ]->fTrackBlock;
}
void TController::MoveTo(TDynamicObject *to) void TController::MoveTo(TDynamicObject *to)
{ // przesunięcie AI do innego pojazdu (przy zmianie kabiny) { // przesunięcie AI do innego pojazdu (przy zmianie kabiny)
// mvOccupied->CabDeactivisation(); //wyłączenie kabiny w opuszczanym // mvOccupied->CabDeactivisation(); //wyłączenie kabiny w opuszczanym

View File

@@ -186,8 +186,8 @@ class TController
private: // parametry aktualnego składu private: // parametry aktualnego składu
double fLength = 0.0; // długość składu (do wyciągania z ograniczeń) double fLength = 0.0; // długość składu (do wyciągania z ograniczeń)
double fMass = 0.0; // całkowita masa do liczenia stycznej składowej grawitacji double fMass = 0.0; // całkowita masa do liczenia stycznej składowej grawitacji
double fAccGravity = 0.0; // przyspieszenie składowej stycznej grawitacji
public: public:
double fAccGravity = 0.0; // przyspieszenie składowej stycznej grawitacji
TEvent *eSignNext = nullptr; // sygnał zmieniający prędkość, do pokazania na [F2] TEvent *eSignNext = nullptr; // sygnał zmieniający prędkość, do pokazania na [F2]
std::string asNextStop; // nazwa następnego punktu zatrzymania wg rozkładu std::string asNextStop; // nazwa następnego punktu zatrzymania wg rozkładu
int iStationStart = 0; // numer pierwszej stacji pokazywanej na podglądzie rozkładu int iStationStart = 0; // numer pierwszej stacji pokazywanej na podglądzie rozkładu
@@ -245,25 +245,20 @@ private:
double AccPreferred = 0.0; // preferowane przyspieszenie (wg psychiki kierującego, zmniejszana przy wykryciu kolizji) double AccPreferred = 0.0; // preferowane przyspieszenie (wg psychiki kierującego, zmniejszana przy wykryciu kolizji)
double AccDesired = AccPreferred; // przyspieszenie, jakie ma utrzymywać (<0:nie przyspieszaj,<-0.1:hamuj) double AccDesired = AccPreferred; // przyspieszenie, jakie ma utrzymywać (<0:nie przyspieszaj,<-0.1:hamuj)
double VelDesired = 0.0; // predkość, z jaką ma jechać, wynikająca z analizy tableki; <=VelSignal double VelDesired = 0.0; // predkość, z jaką ma jechać, wynikająca z analizy tableki; <=VelSignal
double fAccDesiredAv = 0.0; // uśrednione przyspieszenie z kolejnych przebłysków świadomości, żeby double fAccDesiredAv = 0.0; // uśrednione przyspieszenie z kolejnych przebłysków świadomości, żeby ograniczyć migotanie
// ograniczyć migotanie
public:
double VelforDriver = -1.0; // prędkość, używana przy zmianie kierunku (ograniczenie przy nieznajmości szlaku?) double VelforDriver = -1.0; // prędkość, używana przy zmianie kierunku (ograniczenie przy nieznajmości szlaku?)
double VelSignal = 0.0; // ograniczenie prędkości z kompilacji znaków i sygnałów // normalnie na początku ma stać, no chyba że jedzie double VelSignal = 0.0; // ograniczenie prędkości z kompilacji znaków i sygnałów // normalnie na początku ma stać, no chyba że jedzie
double VelLimit = -1.0; // predkość zadawana przez event jednokierunkowego ograniczenia prędkości // -1: brak ograniczenia prędkości double VelLimit = -1.0; // predkość zadawana przez event jednokierunkowego ograniczenia prędkości // -1: brak ograniczenia prędkości
public:
double VelSignalLast = -1.0; // prędkość zadana na ostatnim semaforze // ostatni semafor też bez ograniczenia double VelSignalLast = -1.0; // prędkość zadana na ostatnim semaforze // ostatni semafor też bez ograniczenia
double VelSignalNext = 0.0; // prędkość zadana na następnym semaforze double VelSignalNext = 0.0; // prędkość zadana na następnym semaforze
double VelLimitLast = -1.0; // prędkość zadana przez ograniczenie // ostatnie ograniczenie bez ograniczenia double VelLimitLast = -1.0; // prędkość zadana przez ograniczenie // ostatnie ograniczenie bez ograniczenia
double VelRoad = -1.0; // aktualna prędkość drogowa (ze znaku W27) (PutValues albo komendą) // prędkość drogowa bez ograniczenia double VelRoad = -1.0; // aktualna prędkość drogowa (ze znaku W27) (PutValues albo komendą) // prędkość drogowa bez ograniczenia
public:
double VelNext = 120.0; // prędkość, jaka ma być po przejechaniu długości ProximityDist double VelNext = 120.0; // prędkość, jaka ma być po przejechaniu długości ProximityDist
private: private:
double fProximityDist = 0.0; // odleglosc podawana w SetProximityVelocity(); >0:przeliczać do punktu, <0:podana wartość double fProximityDist = 0.0; // odleglosc podawana w SetProximityVelocity(); >0:przeliczać do punktu, <0:podana wartość
double FirstSemaphorDist = 10000.0; // odległość do pierwszego znalezionego semafora double FirstSemaphorDist = 10000.0; // odległość do pierwszego znalezionego semafora
public: public:
double double ActualProximityDist = 1.0; // odległość brana pod uwagę przy wyliczaniu prędkości i przyspieszenia
ActualProximityDist = 1.0; // odległość brana pod uwagę przy wyliczaniu prędkości i przyspieszenia
private: private:
vector3 vCommandLocation; // polozenie wskaznika, sygnalizatora lub innego obiektu do ktorego vector3 vCommandLocation; // polozenie wskaznika, sygnalizatora lub innego obiektu do ktorego
// odnosi sie komenda // odnosi sie komenda
@@ -297,7 +292,7 @@ private:
double fStopTime = 0.0; // czas postoju przed dalszą jazdą (np. na przystanku) double fStopTime = 0.0; // czas postoju przed dalszą jazdą (np. na przystanku)
double WaitingTime = 0.0; // zliczany czas oczekiwania do samoistnego ruszenia double WaitingTime = 0.0; // zliczany czas oczekiwania do samoistnego ruszenia
double WaitingExpireTime = 31.0; // tyle ma czekać, zanim się ruszy // maksymlany czas oczekiwania do samoistnego ruszenia double WaitingExpireTime = 31.0; // tyle ma czekać, zanim się ruszy // maksymlany czas oczekiwania do samoistnego ruszenia
// TEvent* eSignLast; //ostatnio znaleziony sygnał, o ile nie minięty
private: //---//---//---//---// koniec zmiennych, poniżej metody //---//---//---//---// private: //---//---//---//---// koniec zmiennych, poniżej metody //---//---//---//---//
void SetDriverPsyche(); void SetDriverPsyche();
bool PrepareEngine(); bool PrepareEngine();
@@ -314,23 +309,16 @@ private:
void AutoRewident(); // ustawia hamulce w składzie void AutoRewident(); // ustawia hamulce w składzie
double ESMVelocity(bool Main); double ESMVelocity(bool Main);
public: public:
Mtable::TTrainParameters *Timetable() Mtable::TTrainParameters *Timetable() {
{ return TrainParams; };
return TrainParams;
};
void PutCommand(std::string NewCommand, double NewValue1, double NewValue2, void PutCommand(std::string NewCommand, double NewValue1, double NewValue2,
const TLocation &NewLocation, TStopReason reason = stopComm); const TLocation &NewLocation, TStopReason reason = stopComm);
bool PutCommand(std::string NewCommand, double NewValue1, double NewValue2, bool PutCommand(std::string NewCommand, double NewValue1, double NewValue2,
const vector3 *NewLocation, TStopReason reason = stopComm); const vector3 *NewLocation, TStopReason reason = stopComm);
void UpdateSituation(double dt); // uruchamiac przynajmniej raz na sekundę void UpdateSituation(double dt); // uruchamiac przynajmniej raz na sekundę
// procedury dotyczace rozkazow dla maszynisty // procedury dotyczace rozkazow dla maszynisty
void SetVelocity(double NewVel, double NewVelNext, // uaktualnia informacje o prędkości
TStopReason r = stopNone); // uaktualnia informacje o prędkości void SetVelocity(double NewVel, double NewVelNext, TStopReason r = stopNone);
/*
bool SetProximityVelocity(
double NewDist,
double NewVelNext); // uaktualnia informacje o prędkości przy nastepnym semaforze
*/
public: public:
void JumpToNextOrder(); void JumpToNextOrder();
void JumpToFirstOrder(); void JumpToFirstOrder();
@@ -349,9 +337,7 @@ private:
void OrdersInit(double fVel); void OrdersInit(double fVel);
void OrdersClear(); void OrdersClear();
void OrdersDump(); void OrdersDump();
TController(bool AI, TDynamicObject *NewControll, bool InitPsyche, TController( bool AI, TDynamicObject *NewControll, bool InitPsyche, bool primary = true );
bool primary = true // czy ma aktywnie prowadzić?
);
std::string OrderCurrent(); std::string OrderCurrent();
void WaitingSet(double Seconds); void WaitingSet(double Seconds);
@@ -360,33 +346,24 @@ private:
void DirectionForward(bool forward); void DirectionForward(bool forward);
int OrderDirectionChange(int newdir, TMoverParameters *Vehicle); int OrderDirectionChange(int newdir, TMoverParameters *Vehicle);
void Lights(int head, int rear); void Lights(int head, int rear);
// double Distance(vector3 &p1, vector3 &n, vector3 &p2); // Ra: metody obsługujące skanowanie toru
private: // Ra: metody obsługujące skanowanie toru
TEvent *CheckTrackEvent(TTrack *Track, double const fDirection ) const; TEvent *CheckTrackEvent(TTrack *Track, double const fDirection ) const;
// bool TableCheckEvent(TEvent *e);
bool TableAddNew(); bool TableAddNew();
bool TableNotFound(TEvent const *Event) const; bool TableNotFound(TEvent const *Event) const;
// TEvent *TableCheckTrackEvent(double fDirection, TTrack *Track);
void TableTraceRoute(double fDistance, TDynamicObject *pVehicle = nullptr); void TableTraceRoute(double fDistance, TDynamicObject *pVehicle = nullptr);
void TableCheck(double fDistance); void TableCheck(double fDistance);
TCommandType TableUpdate(double &fVelDes, double &fDist, double &fNext, double &fAcc); TCommandType TableUpdate(double &fVelDes, double &fDist, double &fNext, double &fAcc);
// modifies brake distance for low target speeds, to ease braking rate in such situations // modifies brake distance for low target speeds, to ease braking rate in such situations
float float
braking_distance_multiplier( float const Targetvelocity ); braking_distance_multiplier( float const Targetvelocity ) const;
void TablePurger(); void TablePurger();
void TableSort(); void TableSort();
inline double MoveDistanceGet() inline double MoveDistanceGet() const {
{ return dMoveLen; }
return dMoveLen; inline void MoveDistanceReset() {
} dMoveLen = 0.0; }
inline void MoveDistanceReset()
{
dMoveLen = 0.0;
}
public: public:
inline void MoveDistanceAdd(double distance) inline void MoveDistanceAdd(double distance) {
{
dMoveLen += distance * iDirection; //jak jedzie do tyłu to trzeba uwzględniać, że distance jest ujemna dMoveLen += distance * iDirection; //jak jedzie do tyłu to trzeba uwzględniać, że distance jest ujemna
} }
std::size_t TableSize() const { return sSpeedTable.size(); } std::size_t TableSize() const { return sSpeedTable.size(); }
@@ -396,8 +373,7 @@ private:
private: // Ra: stare funkcje skanujące, używane do szukania sygnalizatora z tyłu private: // Ra: stare funkcje skanujące, używane do szukania sygnalizatora z tyłu
bool BackwardTrackBusy(TTrack *Track); bool BackwardTrackBusy(TTrack *Track);
TEvent *CheckTrackEventBackward(double fDirection, TTrack *Track); TEvent *CheckTrackEventBackward(double fDirection, TTrack *Track);
TTrack *BackwardTraceRoute(double &fDistance, double &fDirection, TTrack *Track, TTrack *BackwardTraceRoute(double &fDistance, double &fDirection, TTrack *Track, TEvent *&Event);
TEvent *&Event);
void SetProximityVelocity(double dist, double vel, const vector3 *pos); void SetProximityVelocity(double dist, double vel, const vector3 *pos);
TCommandType BackwardScan(); TCommandType BackwardScan();
@@ -417,13 +393,16 @@ private:
return ( ( iDrivigFlags & movePrimary ) != 0 ); }; return ( ( iDrivigFlags & movePrimary ) != 0 ); };
inline inline
int DrivigFlags() const { int DrivigFlags() const {
return iDrivigFlags; return iDrivigFlags; };
}; // returns most recently calculated distance to potential obstacle ahead
double
TrackBlock() const;
void MoveTo(TDynamicObject *to); void MoveTo(TDynamicObject *to);
void DirectionInitial(); void DirectionInitial();
std::string TableText(std::size_t const Index); std::string TableText(std::size_t const Index);
int CrossRoute(TTrack *tr); int CrossRoute(TTrack *tr);
void RouteSwitch(int d); void RouteSwitch(int d);
std::string OwnerName() const; std::string OwnerName() const;
TMoverParameters const *Controlling() const { return mvControlling; } TMoverParameters const *Controlling() const {
return mvControlling; }
}; };

View File

@@ -2426,7 +2426,7 @@ bool TGround::InitEvents()
Current->Params[9].asTrack = tmp->pTrack; Current->Params[9].asTrack = tmp->pTrack;
if (!Current->Params[9].asTrack) if (!Current->Params[9].asTrack)
{ {
ErrorLog("Bad event: Track \"" + cellastext + "\" does not exist in \"" + Current->asName + "\""); ErrorLog( "Bad event: multi-event \"" + Current->asName + "\" cannot find track \"" + cellastext + "\"" );
Current->iFlags &= ~(conditional_trackoccupied | conditional_trackfree); // zerowanie flag Current->iFlags &= ~(conditional_trackoccupied | conditional_trackfree); // zerowanie flag
} }
} }
@@ -2437,7 +2437,7 @@ bool TGround::InitEvents()
Current->Params[9].asMemCell = tmp->MemCell; Current->Params[9].asMemCell = tmp->MemCell;
if (!Current->Params[9].asMemCell) if (!Current->Params[9].asMemCell)
{ {
ErrorLog("Bad event: MemCell \"" + cellastext + "\" does not exist in \"" + Current->asName + "\""); ErrorLog( "Bad event: multi-event \"" + Current->asName + "\" cannot find memory cell \"" + cellastext + "\"" );
Current->iFlags &= ~(conditional_memstring | conditional_memval1 | conditional_memval2); Current->iFlags &= ~(conditional_memstring | conditional_memval1 | conditional_memval2);
} }
} }
@@ -2448,11 +2448,11 @@ bool TGround::InitEvents()
cellastext = Current->Params[ i ].asText; cellastext = Current->Params[ i ].asText;
SafeDeleteArray(Current->Params[i].asText); SafeDeleteArray(Current->Params[i].asText);
Current->Params[i].asEvent = FindEvent(cellastext); Current->Params[i].asEvent = FindEvent(cellastext);
if( !Current->Params[ i ].asEvent ) { // Ra: tylko w logu informacja o braku if( !Current->Params[ i ].asEvent ) {
// Ra: tylko w logu informacja o braku
if( ( Current->Params[ i ].asText == NULL ) if( ( Current->Params[ i ].asText == NULL )
|| ( std::string( Current->Params[ i ].asText ).substr( 0, 5 ) != "none_" ) ) { || ( std::string( Current->Params[ i ].asText ).substr( 0, 5 ) != "none_" ) ) {
WriteLog( "Event \"" + cellastext + "\" does not exist" ); ErrorLog( "Bad event: multi-event \"" + Current->asName + "\" cannot find event \"" + cellastext + "\"" );
ErrorLog( "Missed event: " + cellastext + " in multiple " + Current->asName );
} }
} }
} }
@@ -3401,18 +3401,22 @@ bool TGround::CheckQuery()
owner != nullptr ? owner != nullptr ?
owner->fReady : owner->fReady :
-1.0 ); -1.0 );
auto const collisiondistance = (
owner != nullptr ?
owner->TrackBlock() :
-1.0 );
tmpEvent->Params[ 9 ].asMemCell->UpdateValues( tmpEvent->Params[ 9 ].asMemCell->UpdateValues(
tmpEvent->Activator->MoverParameters->TypeName, // typ pojazdu tmpEvent->Activator->MoverParameters->TypeName, // typ pojazdu
consistbrakelevel, consistbrakelevel,
0, // na razie nic collisiondistance,
tmpEvent->iFlags & ( update_memstring | update_memval1 | update_memval2 ) ); tmpEvent->iFlags & ( update_memstring | update_memval1 | update_memval2 ) );
WriteLog( WriteLog(
"whois request (" + to_string( tmpEvent->iFlags ) + ") " "whois request (" + to_string( tmpEvent->iFlags ) + ") "
+ "[name: " + tmpEvent->Activator->MoverParameters->TypeName + "], " + "[name: " + tmpEvent->Activator->MoverParameters->TypeName + "], "
+ "[consist brake level: " + to_string( consistbrakelevel, 2 ) + "], " + "[consist brake level: " + to_string( consistbrakelevel, 2 ) + "], "
+ "[]" ); + "[obstacle distance: " + to_string( collisiondistance, 2 ) + " m]" );
} }
else { else {
// jeśli parametry ładunku // jeśli parametry ładunku

View File

@@ -2497,7 +2497,7 @@ void TTrain::OnCommand_instrumentlighttoggle( TTrain *Train, command_data const
// TODO: proper control deviced definition for the interiors, that doesn't hinge of presence of 3d submodels // TODO: proper control deviced definition for the interiors, that doesn't hinge of presence of 3d submodels
if( Train->ggInstrumentLightButton.SubModel == nullptr ) { if( Train->ggInstrumentLightButton.SubModel == nullptr ) {
if( Command.action == GLFW_PRESS ) { if( Command.action == GLFW_PRESS ) {
WriteLog( "Universal3 switch is missing, or wasn't defined" ); WriteLog( "Instrument light switch is missing, or wasn't defined" );
} }
return; return;
} }

View File

@@ -1433,6 +1433,10 @@ TWorld::Update_UI() {
+ ", Fr: " + to_string( tmp->MoverParameters->RunningTrack.friction, 2 ) + ", Fr: " + to_string( tmp->MoverParameters->RunningTrack.friction, 2 )
+ ( tmp->MoverParameters->SlippingWheels ? " (!)" : "" ); + ( tmp->MoverParameters->SlippingWheels ? " (!)" : "" );
if( tmp->Mechanik ) {
uitextline2 += "; Ag: " + to_string( tmp->Mechanik->fAccGravity, 2 );
}
uitextline2 += uitextline2 +=
"; TC:" "; TC:"
+ to_string( tmp->MoverParameters->TotalCurrent, 0 ); + to_string( tmp->MoverParameters->TotalCurrent, 0 );

View File

@@ -22,6 +22,8 @@ http://mozilla.org/MPL/2.0/.
#include "logs.h" #include "logs.h"
#include "usefull.h" #include "usefull.h"
#define EU07_NEW_CAB_RENDERCODE
opengl_renderer GfxRenderer; opengl_renderer GfxRenderer;
extern TWorld World; extern TWorld World;

View File

@@ -1,5 +1,5 @@
#pragma once #pragma once
#define VERSION_MAJOR 17 #define VERSION_MAJOR 17
#define VERSION_MINOR 911 #define VERSION_MINOR 913
#define VERSION_REVISION 0 #define VERSION_REVISION 0