Apply whitespace fix to SDL2 branch.

This commit is contained in:
Jørgen P. Tjernø
2014-04-19 13:24:05 -07:00
parent a147ce9b80
commit 486baadfe8
241 changed files with 9665 additions and 9665 deletions

View File

@@ -112,7 +112,7 @@ frmMain::frmMain()
m_bPlayingAnimation = true;
//m_bPlayingAnimation = false;
pSidebarSizer->Add(pFrame, 0, wxEXPAND | wxALL, 0);
#define ID(layer, id) (ID_LAYER_CHECKS + (layer) * 25 + (id))
wxStaticBoxSizer *pLayer0 = new wxStaticBoxSizer(wxHORIZONTAL, this, L"Layer 0 (Patient Head)");
pLayer0->Add(new wxCheckBox(this, ID(0, 0), L"0"), 0, wxALIGN_CENTER | wxALL, 1);
@@ -263,7 +263,7 @@ frmMain::frmMain()
SetBackgroundColour(m_btnPlayPause->GetBackgroundColour());
SetSizer(pMainSizer);
SetMinSize(ClientToWindowSize(pMainSizer->CalcMin()));
SetSize(GetMinSize());
@@ -405,7 +405,7 @@ your hard disk (~250MB). \n If you click No, it will write the XML and element f
the DATA folder, the Animation Viewer will use PNG sprites instead of Theme Hospital data files.",
L"Export Warning", wxYES_NO | wxCANCEL);
if( response == wxYES) { bWriteFrames = true; }
if( response != wxCANCEL)
if( response != wxCANCEL)
{
//Start with animations, then move on to sprite sheets (map tiles)
if(!m_oAnims.loadAnimationFile(_getCaseSensitivePath(L"VSTART-1.ANI", sdPath))
@@ -439,7 +439,7 @@ the DATA folder, the Animation Viewer will use PNG sprites instead of Theme Hosp
wxTextOutputStream outputXml(fosxml);
outputXml.WriteString(wxString::Format(L"<?xml version='1.0' encoding='ISO-8859-1' standalone='no'?>\n"));
outputXml.WriteString(wxString::Format(L"<theme_hospital_graphics scale_factor='1'>\n"));
int iAnimationCount = 0;
int iFrameCountTotal = 1;
int iElementCount = 0;
@@ -454,7 +454,7 @@ the DATA folder, the Animation Viewer will use PNG sprites instead of Theme Hosp
{
wxFileName::Mkdir(aiPath);
}
outputXml.WriteString(wxString::Format(L"<an id='%u' fr='%u' un='%u'>\n",
outputXml.WriteString(wxString::Format(L"<an id='%u' fr='%u' un='%u'>\n",
iAnimation, m_oAnims.getFrameField(iAnimation), m_oAnims.getUnknownField(iAnimation)));
aiPath += wxFileName::GetPathSeparator();
size_t iFrameCount = m_oAnims.getFrameCount(iAnimation);
@@ -462,7 +462,7 @@ the DATA folder, the Animation Viewer will use PNG sprites instead of Theme Hosp
{
wxImage imgCanvas;
th_frame_t* pFrame = m_oAnims.getFrameStruct(iAnimation,iFrame);
outputXml.WriteString(wxString::Format(L"\t<fr id='%u' li='%u' w='%u' h='%u' fl='%u' nx='%u'>\n",
outputXml.WriteString(wxString::Format(L"\t<fr id='%u' li='%u' w='%u' h='%u' fl='%u' nx='%u'>\n",
iFrameCountTotal, iListIndex, pFrame->width, pFrame->height, pFrame->flags, pFrame->next));
wxSize oSize;
@@ -488,7 +488,7 @@ the DATA folder, the Animation Viewer will use PNG sprites instead of Theme Hosp
}
m_oAnims.drawFrame(imgCanvas, iAnimation, iFrame, &m_mskLayers, oSize, 0, 0);
outputLog.WriteString(wxString::Format(L"%s\t%u\t%u\t%u\t%u\t%u\n", L"VSPR-0", iAnimation, iFrame,
outputLog.WriteString(wxString::Format(L"%s\t%u\t%u\t%u\t%u\t%u\n", L"VSPR-0", iAnimation, iFrame,
oSize.x, oSize.y, m_oAnims.getUnknownField(iAnimation)));
}
@@ -506,7 +506,7 @@ the DATA folder, the Animation Viewer will use PNG sprites instead of Theme Hosp
iAnimationCount++;
}
}
//outputXml.WriteString(wxString::Format(L"\t<graphics_totals animations='%u' frames='%u' elements='%u' sprites='%u'>\n",
//outputXml.WriteString(wxString::Format(L"\t<graphics_totals animations='%u' frames='%u' elements='%u' sprites='%u'>\n",
// iAnimationCount, iFrameCount, iElementCount, iSpriteCount));
outputXml.WriteString(wxString::Format(L"</theme_hospital_graphics>\n"));
@@ -520,7 +520,7 @@ the DATA folder, the Animation Viewer will use PNG sprites instead of Theme Hosp
exportSpritesPage(true, sdPath, L"WATCH01V");
//Skip DataM directory because it appears to be low-res versions of same
//Sprite sheet code for QData directory
//Sprite sheet code for QData directory
wxString sqPath = _getCaseSensitivePath(L"QDATA", sPath);
sqPath += wxFileName::GetPathSeparator();
exportSpritesPage(true, sqPath, L"AWARD03V", L"", L"AWARD02V.PAL");
@@ -604,7 +604,7 @@ the DATA folder, the Animation Viewer will use PNG sprites instead of Theme Hosp
void frmMain::exportSpritesPage(bool bComplex, wxString sPath, wxString sFilename, wxString spPath, wxString sPalette)
{
if(spPath.length() == 0)
if(spPath.length() == 0)
{
spPath = sPath;
}
@@ -660,7 +660,7 @@ void frmMain::_onToggleMask(wxCommandEvent& evt)
int iID = evt.GetId() - ID_LAYER_CHECKS;
int iLayer = iID / 25;
iID %= 25;
if(evt.IsChecked())
m_mskLayers.set(iLayer, iID);
else
@@ -985,11 +985,11 @@ wxString frmMain::_getCaseSensitivePath(const wxString& sInsensitivePathPart, co
{
bool found;
bool cont;
if(!wxFileName::IsCaseSensitive()) { return sPath + sInsensitivePathPart; }
wxString retStr(sPath);
wxStringTokenizer pathTokenizer(sInsensitivePathPart, wxFileName::GetPathSeparator());
while(pathTokenizer.HasMoreTokens())
{
@@ -998,9 +998,9 @@ wxString frmMain::_getCaseSensitivePath(const wxString& sInsensitivePathPart, co
{
break;
}
wxString pathPart = pathTokenizer.GetNextToken();
wxString realName;
cont = dir.GetFirst(&realName, wxEmptyString, wxDIR_DIRS|wxDIR_FILES|wxDIR_HIDDEN|wxDIR_DOTDOT);
found = false;
@@ -1018,7 +1018,7 @@ wxString frmMain::_getCaseSensitivePath(const wxString& sInsensitivePathPart, co
}
cont = dir.GetNext(&realName);
}
if(!found)
{
retStr += wxFileName::GetPathSeparator();
@@ -1026,7 +1026,7 @@ wxString frmMain::_getCaseSensitivePath(const wxString& sInsensitivePathPart, co
break;
}
}
while(pathTokenizer.HasMoreTokens())
{
wxString pathPart = pathTokenizer.GetNextToken();
@@ -1036,6 +1036,6 @@ wxString frmMain::_getCaseSensitivePath(const wxString& sInsensitivePathPart, co
}
retStr += pathPart;
}
return retStr;
}

View File

@@ -66,7 +66,7 @@ protected:
std::vector<_sprite_t> m_vSprites;
THAnimations m_oAnims;
wxTextCtrl* m_txtTable;
wxTextCtrl* m_txtData;
wxTextCtrl* m_txtPalette;

View File

@@ -481,7 +481,7 @@ bool THAnimations::loadXMLFile(TiXmlDocument* xmlDocument)
return m_bXmlLoaded;
}
void THAnimations::writeElementData(wxString aPath, wxTextOutputStream *outputLog, wxTextOutputStream *outputXml,
void THAnimations::writeElementData(wxString aPath, wxTextOutputStream *outputLog, wxTextOutputStream *outputXml,
size_t iAnimation, size_t iFrame, const THLayerMask* pMask, wxSize& size, int *iListIndex)
{
if(iAnimation >= m_iAnimCount)
@@ -504,7 +504,7 @@ void THAnimations::writeElementData(wxString aPath, wxTextOutputStream *outputLo
if(pElement->flags >> 4 != 1)
{
uint16_t iElementIndex = m_pElementList[iOldListIndex];
outputXml->WriteString(wxString::Format(L"\t\t<el id='%u' tb='%u' fl='%u' ox='%u' oy='%u' ly='%u' ",
outputXml->WriteString(wxString::Format(L"\t\t<el id='%u' tb='%u' fl='%u' ox='%u' oy='%u' ly='%u' ",
iElementIndex, pElement->table_position, pElement->flags, pElement->offx, pElement->offy, pElement->layerid ));
uint16_t iSpriteIndex = pElement->table_position / sizeof(th_sprite_t);
wxString spriteFile = aPath + wxString::Format(L"a%04ue.png", iSpriteIndex);
@@ -518,7 +518,7 @@ void THAnimations::writeElementData(wxString aPath, wxTextOutputStream *outputLo
iFarY = iBottom;
//if(pMask != NULL && !pMask->isSet(pElement->flags >> 4, pElement->layerid))
// continue;
outputXml->WriteString(wxString::Format(L"sp='%u' of='%u' w='%u' h='%u'/>\n",
outputXml->WriteString(wxString::Format(L"sp='%u' of='%u' w='%u' h='%u'/>\n",
iSpriteIndex, pSprite->offset, pSprite->width, pSprite->height ));
if(!wxFileName::FileExists(spriteFile) && pSprite->width > 0 && pSprite->height > 0)
{
@@ -539,8 +539,8 @@ void THAnimations::writeElementData(wxString aPath, wxTextOutputStream *outputLo
getSpriteBitmap(iSpriteIndex)->blit(imgSprite, 0, 0, m_pGhostMaps + m_iGhostMapOffset, m_pColours, 0 & 0xF);
if(!imgSprite.SaveFile(spriteFile,wxBITMAP_TYPE_PNG))
return;
outputLog->WriteString(wxString::Format(L"E%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\n", iSpriteIndex,
pElement->table_position, pElement->flags, pElement->layerid, pElement->offx, pElement->offy,
outputLog->WriteString(wxString::Format(L"E%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\n", iSpriteIndex,
pElement->table_position, pElement->flags, pElement->layerid, pElement->offx, pElement->offy,
iNewListIndex, sizeof(th_sprite_t), pSprite->width, pSprite->height, pSprite->offset));
}
iNewListIndex++;
@@ -750,7 +750,7 @@ void THAnimations::drawFrame(wxImage& imgCanvas, size_t iAnimation, size_t iFram
}
void THAnimations::copySpriteToCanvas(wxString spriteFile, int iSpriteIndex, wxImage& imgCanvas, int iX, int iY, int iFlags) {
if(!m_pSpriteImages[iSpriteIndex].IsOk())
if(!m_pSpriteImages[iSpriteIndex].IsOk())
{
th_sprite_t* pSprite = m_pSprites + iSpriteIndex;
if(m_pSpriteScaleFactors[iSpriteIndex] > 1)
@@ -764,7 +764,7 @@ void THAnimations::copySpriteToCanvas(wxString spriteFile, int iSpriteIndex, wxI
m_pSpriteImages[iSpriteIndex].LoadFile(spriteFile,wxBITMAP_TYPE_PNG);
}
//m_pSpriteImages[iSpriteIndex].SetMaskColour(0,0,0);
if(!m_pSpriteImages[iSpriteIndex].HasAlpha())
if(!m_pSpriteImages[iSpriteIndex].HasAlpha())
{
m_pSpriteImages[iSpriteIndex].InitAlpha();
}

View File

@@ -177,7 +177,7 @@ public:
bool loadGhostFile(wxString sFilename, int iIndex);
bool loadXMLFile(TiXmlDocument* xmlDocument);
void writeElementData(wxString aPath, wxTextOutputStream *outputLog, wxTextOutputStream *outputXml,
void writeElementData(wxString aPath, wxTextOutputStream *outputLog, wxTextOutputStream *outputXml,
size_t iAnimation, size_t iFrame, const THLayerMask* pMask, wxSize& size, int* iListIndex);
void writeTableDataHeader(wxTextOutputStream *outputLog);
@@ -257,4 +257,4 @@ protected:
size_t m_iColourCount;
bool m_bXmlLoaded;
wxString m_sSpritePath;
};
};

View File

@@ -224,7 +224,7 @@ class TiXmlString
// to the normal allocation, although use an 'int' for systems
// that are overly picky about structure alignment.
const size_type bytesNeeded = sizeof(Rep) + cap;
const size_type intsNeeded = ( bytesNeeded + sizeof(int) - 1 ) / sizeof( int );
const size_type intsNeeded = ( bytesNeeded + sizeof(int) - 1 ) / sizeof( int );
rep_ = reinterpret_cast<Rep*>( new int[ intsNeeded ] );
rep_->str[ rep_->size = sz ] = '\0';

View File

@@ -57,7 +57,7 @@ void TiXmlBase::EncodeString( const TIXML_STRING& str, TIXML_STRING* outString )
{
unsigned char c = (unsigned char) str[i];
if ( c == '&'
if ( c == '&'
&& i < ( (int)str.length() - 2 )
&& str[i+1] == '#'
&& str[i+2] == 'x' )
@@ -110,12 +110,12 @@ void TiXmlBase::EncodeString( const TIXML_STRING& str, TIXML_STRING* outString )
// Easy pass at non-alpha/numeric/symbol
// Below 32 is symbolic.
char buf[ 32 ];
#if defined(TIXML_SNPRINTF)
#if defined(TIXML_SNPRINTF)
TIXML_SNPRINTF( buf, sizeof(buf), "&#x%02X;", (unsigned) ( c & 0xff ) );
#else
sprintf( buf, "&#x%02X;", (unsigned) ( c & 0xff ) );
#endif
#endif
//*ME: warning C4267: convert 'size_t' to 'int'
//*ME: Int-Cast to make compiler happy ...
@@ -154,14 +154,14 @@ TiXmlNode::~TiXmlNode()
temp = node;
node = node->next;
delete temp;
}
}
}
void TiXmlNode::CopyTo( TiXmlNode* target ) const
{
target->SetValue (value.c_str() );
target->userData = userData;
target->userData = userData;
target->location = location;
}
@@ -176,7 +176,7 @@ void TiXmlNode::Clear()
temp = node;
node = node->next;
delete temp;
}
}
firstChild = 0;
lastChild = 0;
@@ -191,7 +191,7 @@ TiXmlNode* TiXmlNode::LinkEndChild( TiXmlNode* node )
if ( node->Type() == TiXmlNode::TINYXML_DOCUMENT )
{
delete node;
if ( GetDocument() )
if ( GetDocument() )
GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
return 0;
}
@@ -215,7 +215,7 @@ TiXmlNode* TiXmlNode::InsertEndChild( const TiXmlNode& addThis )
{
if ( addThis.Type() == TiXmlNode::TINYXML_DOCUMENT )
{
if ( GetDocument() )
if ( GetDocument() )
GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
return 0;
}
@@ -228,13 +228,13 @@ TiXmlNode* TiXmlNode::InsertEndChild( const TiXmlNode& addThis )
TiXmlNode* TiXmlNode::InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis )
{
{
if ( !beforeThis || beforeThis->parent != this ) {
return 0;
}
if ( addThis.Type() == TiXmlNode::TINYXML_DOCUMENT )
{
if ( GetDocument() )
if ( GetDocument() )
GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
return 0;
}
@@ -267,7 +267,7 @@ TiXmlNode* TiXmlNode::InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& a
}
if ( addThis.Type() == TiXmlNode::TINYXML_DOCUMENT )
{
if ( GetDocument() )
if ( GetDocument() )
GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
return 0;
}
@@ -304,7 +304,7 @@ TiXmlNode* TiXmlNode::ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& wit
if ( withThis.ToDocument() ) {
// A document can never be a child. Thanks to Noam.
TiXmlDocument* document = GetDocument();
if ( document )
if ( document )
document->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
return 0;
}
@@ -339,7 +339,7 @@ bool TiXmlNode::RemoveChild( TiXmlNode* removeThis )
}
if ( removeThis->parent != this )
{
{
assert( 0 );
return false;
}
@@ -410,7 +410,7 @@ const TiXmlNode* TiXmlNode::IterateChildren( const char * val, const TiXmlNode*
}
const TiXmlNode* TiXmlNode::NextSibling( const char * _value ) const
const TiXmlNode* TiXmlNode::NextSibling( const char * _value ) const
{
const TiXmlNode* node;
for ( node = next; node; node = node->next )
@@ -531,7 +531,7 @@ TiXmlElement::TiXmlElement (const char * _value)
#ifdef TIXML_USE_STL
TiXmlElement::TiXmlElement( const std::string& _value )
TiXmlElement::TiXmlElement( const std::string& _value )
: TiXmlNode( TiXmlNode::TINYXML_ELEMENT )
{
firstChild = lastChild = 0;
@@ -544,7 +544,7 @@ TiXmlElement::TiXmlElement( const TiXmlElement& copy)
: TiXmlNode( TiXmlNode::TINYXML_ELEMENT )
{
firstChild = lastChild = 0;
copy.CopyTo( this );
copy.CopyTo( this );
}
@@ -685,18 +685,18 @@ int TiXmlElement::QueryBoolAttribute( const char* name, bool* bval ) const
const TiXmlAttribute* node = attributeSet.Find( name );
if ( !node )
return TIXML_NO_ATTRIBUTE;
int result = TIXML_WRONG_TYPE;
if ( StringEqual( node->Value(), "true", true, TIXML_ENCODING_UNKNOWN )
|| StringEqual( node->Value(), "yes", true, TIXML_ENCODING_UNKNOWN )
|| StringEqual( node->Value(), "1", true, TIXML_ENCODING_UNKNOWN ) )
if ( StringEqual( node->Value(), "true", true, TIXML_ENCODING_UNKNOWN )
|| StringEqual( node->Value(), "yes", true, TIXML_ENCODING_UNKNOWN )
|| StringEqual( node->Value(), "1", true, TIXML_ENCODING_UNKNOWN ) )
{
*bval = true;
result = TIXML_SUCCESS;
}
else if ( StringEqual( node->Value(), "false", true, TIXML_ENCODING_UNKNOWN )
|| StringEqual( node->Value(), "no", true, TIXML_ENCODING_UNKNOWN )
|| StringEqual( node->Value(), "0", true, TIXML_ENCODING_UNKNOWN ) )
else if ( StringEqual( node->Value(), "false", true, TIXML_ENCODING_UNKNOWN )
|| StringEqual( node->Value(), "no", true, TIXML_ENCODING_UNKNOWN )
|| StringEqual( node->Value(), "0", true, TIXML_ENCODING_UNKNOWN ) )
{
*bval = false;
result = TIXML_SUCCESS;
@@ -738,7 +738,7 @@ int TiXmlElement::QueryDoubleAttribute( const std::string& name, double* dval )
void TiXmlElement::SetAttribute( const char * name, int val )
{
{
TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
if ( attrib ) {
attrib->SetIntValue( val );
@@ -748,7 +748,7 @@ void TiXmlElement::SetAttribute( const char * name, int val )
#ifdef TIXML_USE_STL
void TiXmlElement::SetAttribute( const std::string& name, int val )
{
{
TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
if ( attrib ) {
attrib->SetIntValue( val );
@@ -758,7 +758,7 @@ void TiXmlElement::SetAttribute( const std::string& name, int val )
void TiXmlElement::SetDoubleAttribute( const char * name, double val )
{
{
TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
if ( attrib ) {
attrib->SetDoubleValue( val );
@@ -768,13 +768,13 @@ void TiXmlElement::SetDoubleAttribute( const char * name, double val )
#ifdef TIXML_USE_STL
void TiXmlElement::SetDoubleAttribute( const std::string& name, double val )
{
{
TiXmlAttribute* attrib = attributeSet.FindOrCreate( name );
if ( attrib ) {
attrib->SetDoubleValue( val );
}
}
#endif
#endif
void TiXmlElement::SetAttribute( const char * cname, const char * cvalue )
@@ -855,7 +855,7 @@ void TiXmlElement::CopyTo( TiXmlElement* target ) const
// superclass:
TiXmlNode::CopyTo( target );
// Element class:
// Element class:
// Clone the attributes, then clone the children.
const TiXmlAttribute* attribute = 0;
for( attribute = attributeSet.First();
@@ -874,7 +874,7 @@ void TiXmlElement::CopyTo( TiXmlElement* target ) const
bool TiXmlElement::Accept( TiXmlVisitor* visitor ) const
{
if ( visitor->VisitEnter( *this, attributeSet.First() ) )
if ( visitor->VisitEnter( *this, attributeSet.First() ) )
{
for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() )
{
@@ -968,7 +968,7 @@ bool TiXmlDocument::LoadFile( const char* _filename, TiXmlEncoding encoding )
value = filename;
// reading in binary mode so that tinyxml can normalize the EOL
FILE* file = TiXmlFOpen( value.c_str (), "rb" );
FILE* file = TiXmlFOpen( value.c_str (), "rb" );
if ( file )
{
@@ -985,7 +985,7 @@ bool TiXmlDocument::LoadFile( const char* _filename, TiXmlEncoding encoding )
bool TiXmlDocument::LoadFile( FILE* file, TiXmlEncoding encoding )
{
if ( !file )
if ( !file )
{
SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
return false;
@@ -1012,13 +1012,13 @@ bool TiXmlDocument::LoadFile( FILE* file, TiXmlEncoding encoding )
// 2.11 End-of-Line Handling
// <snip>
// <quote>
// ...the XML processor MUST behave as if it normalized all line breaks in external
// parsed entities (including the document entity) on input, before parsing, by translating
// both the two-character sequence #xD #xA and any #xD that is not followed by #xA to
// ...the XML processor MUST behave as if it normalized all line breaks in external
// parsed entities (including the document entity) on input, before parsing, by translating
// both the two-character sequence #xD #xA and any #xD that is not followed by #xA to
// a single #xA character.
// </quote>
//
// It is not clear fgets does that, and certainly isn't clear it works cross platform.
// It is not clear fgets does that, and certainly isn't clear it works cross platform.
// Generally, you expect fgets to translate from the convention of the OS to the c/unix
// convention, and not work generally.
@@ -1043,7 +1043,7 @@ bool TiXmlDocument::LoadFile( FILE* file, TiXmlEncoding encoding )
// a newline-carriage return is hit.
//
// Wikipedia:
// Systems based on ASCII or a compatible character set use either LF (Line feed, '\n', 0x0A, 10 in decimal) or
// Systems based on ASCII or a compatible character set use either LF (Line feed, '\n', 0x0A, 10 in decimal) or
// CR (Carriage return, '\r', 0x0D, 13 in decimal) individually, or CR followed by LF (CR+LF, 0x0D 0x0A)...
// * LF: Multics, Unix and Unix-like systems (GNU/Linux, AIX, Xenix, Mac OS X, FreeBSD, etc.), BeOS, Amiga, RISC OS, and others
// * CR+LF: DEC RT-11 and most other early non-Unix, non-IBM OSes, CP/M, MP/M, DOS, OS/2, Microsoft Windows, Symbian OS
@@ -1097,7 +1097,7 @@ bool TiXmlDocument::SaveFile( const char * filename ) const
bool TiXmlDocument::SaveFile( FILE* fp ) const
{
if ( useMicrosoftBOM )
if ( useMicrosoftBOM )
{
const unsigned char TIXML_UTF_LEAD_0 = 0xefU;
const unsigned char TIXML_UTF_LEAD_1 = 0xbbU;
@@ -1127,7 +1127,7 @@ void TiXmlDocument::CopyTo( TiXmlDocument* target ) const
for ( node = firstChild; node; node = node->NextSibling() )
{
target->LinkEndChild( node->Clone() );
}
}
}
@@ -1250,7 +1250,7 @@ int TiXmlAttribute::QueryDoubleValue( double* dval ) const
void TiXmlAttribute::SetIntValue( int _value )
{
char buf [64];
#if defined(TIXML_SNPRINTF)
#if defined(TIXML_SNPRINTF)
TIXML_SNPRINTF(buf, sizeof(buf), "%d", _value);
#else
sprintf (buf, "%d", _value);
@@ -1261,7 +1261,7 @@ void TiXmlAttribute::SetIntValue( int _value )
void TiXmlAttribute::SetDoubleValue( double _value )
{
char buf [256];
#if defined(TIXML_SNPRINTF)
#if defined(TIXML_SNPRINTF)
TIXML_SNPRINTF( buf, sizeof(buf), "%g", _value);
#else
sprintf (buf, "%g", _value);
@@ -1364,7 +1364,7 @@ bool TiXmlText::Accept( TiXmlVisitor* visitor ) const
TiXmlNode* TiXmlText::Clone() const
{
{
TiXmlText* clone = 0;
clone = new TiXmlText( "" );
@@ -1403,7 +1403,7 @@ TiXmlDeclaration::TiXmlDeclaration( const std::string& _version,
TiXmlDeclaration::TiXmlDeclaration( const TiXmlDeclaration& copy )
: TiXmlNode( TiXmlNode::TINYXML_DECLARATION )
{
copy.CopyTo( this );
copy.CopyTo( this );
}
@@ -1454,7 +1454,7 @@ bool TiXmlDeclaration::Accept( TiXmlVisitor* visitor ) const
TiXmlNode* TiXmlDeclaration::Clone() const
{
{
TiXmlDeclaration* clone = new TiXmlDeclaration();
if ( !clone )
@@ -1592,7 +1592,7 @@ TiXmlAttribute* TiXmlAttributeSet::FindOrCreate( const char* _name )
}
#ifdef TIXML_USE_STL
#ifdef TIXML_USE_STL
std::istream& operator>> (std::istream & in, TiXmlNode & base)
{
TIXML_STRING tag;
@@ -1605,7 +1605,7 @@ std::istream& operator>> (std::istream & in, TiXmlNode & base)
#endif
#ifdef TIXML_USE_STL
#ifdef TIXML_USE_STL
std::ostream& operator<< (std::ostream & out, const TiXmlNode & base)
{
TiXmlPrinter printer;
@@ -1775,12 +1775,12 @@ bool TiXmlPrinter::VisitEnter( const TiXmlElement& element, const TiXmlAttribute
attrib->Print( 0, 0, &buffer );
}
if ( !element.FirstChild() )
if ( !element.FirstChild() )
{
buffer += " />";
DoLineBreak();
}
else
else
{
buffer += ">";
if ( element.FirstChild()->ToText()
@@ -1795,7 +1795,7 @@ bool TiXmlPrinter::VisitEnter( const TiXmlElement& element, const TiXmlAttribute
DoLineBreak();
}
}
++depth;
++depth;
return true;
}
@@ -1803,11 +1803,11 @@ bool TiXmlPrinter::VisitEnter( const TiXmlElement& element, const TiXmlAttribute
bool TiXmlPrinter::VisitExit( const TiXmlElement& element )
{
--depth;
if ( !element.FirstChild() )
if ( !element.FirstChild() )
{
// nothing.
}
else
else
{
if ( simpleTextPrint )
{

View File

@@ -78,7 +78,7 @@ distribution.
#define TIXML_SNPRINTF snprintf
#define TIXML_SSCANF sscanf
#endif
#endif
#endif
class TiXmlDocument;
class TiXmlElement;
@@ -93,7 +93,7 @@ const int TIXML_MAJOR_VERSION = 2;
const int TIXML_MINOR_VERSION = 6;
const int TIXML_PATCH_VERSION = 2;
/* Internal structure for tracking location of items
/* Internal structure for tracking location of items
in the XML file.
*/
struct TiXmlCursor
@@ -116,7 +116,7 @@ struct TiXmlCursor
If you return 'true' from a Visit method, recursive parsing will continue. If you return
false, <b>no children of this node or its sibilings</b> will be Visited.
All flavors of Visit methods have a default implementation that returns 'true' (continue
All flavors of Visit methods have a default implementation that returns 'true' (continue
visiting). You need to only override methods that are interesting to you.
Generally Accept() is called on the TiXmlDocument, although all nodes suppert Visiting.
@@ -151,8 +151,8 @@ public:
};
// Only used by Attribute::Query functions
enum
{
enum
{
TIXML_SUCCESS,
TIXML_NO_ATTRIBUTE,
TIXML_WRONG_TYPE
@@ -204,10 +204,10 @@ public:
/** All TinyXml classes can print themselves to a filestream
or the string class (TiXmlString in non-STL mode, std::string
in STL mode.) Either or both cfile and str can be null.
This is a formatted print, and will insert
This is a formatted print, and will insert
tabs and newlines.
(For an unformatted stream, use the << operator.)
*/
virtual void Print( FILE* cfile, int depth ) const = 0;
@@ -252,11 +252,11 @@ public:
// in the UTF-8 sequence.
static const int utf8ByteTable[256];
virtual const char* Parse( const char* p,
TiXmlParsingData* data,
virtual const char* Parse( const char* p,
TiXmlParsingData* data,
TiXmlEncoding encoding /*= TIXML_ENCODING_UNKNOWN */ ) = 0;
/** Expands entities in a string. Note this should not contian the tag's '<', '>', etc,
/** Expands entities in a string. Note this should not contian the tag's '<', '>', etc,
or they will be transformed into entities!
*/
static void EncodeString( const TIXML_STRING& str, TIXML_STRING* out );
@@ -287,9 +287,9 @@ protected:
static const char* SkipWhiteSpace( const char*, TiXmlEncoding encoding );
inline static bool IsWhiteSpace( char c )
{
return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' );
inline static bool IsWhiteSpace( char c )
{
return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' );
}
inline static bool IsWhiteSpace( int c )
{
@@ -374,7 +374,7 @@ protected:
/// Field containing a generic user pointer
void* userData;
// None of these methods are reliable for any language except English.
// Good for approximation, not great for accuracy.
static int IsAlpha( unsigned char anyByte, TiXmlEncoding encoding );
@@ -426,7 +426,7 @@ class TiXmlNode : public TiXmlBase
friend class TiXmlElement;
public:
#ifdef TIXML_USE_STL
#ifdef TIXML_USE_STL
/** An input stream operator, for every class. Tolerant of newlines and
formatting, but doesn't expect them.
@@ -440,7 +440,7 @@ public:
The operator<< and operator>> are not completely symmetric. Writing
a node to a stream is very well defined. You'll get a nice stream
of output, without any extra whitespace or newlines.
But reading is not as well defined. (As it always is.) If you create
a TiXmlElement (for example) and read that from an input stream,
the text needs to define an element or junk will result. This is
@@ -448,7 +448,7 @@ public:
A TiXmlDocument will read nodes until it reads a root element, and
all the children of that root element.
*/
*/
friend std::ostream& operator<< (std::ostream& out, const TiXmlNode& base);
/// Appends the XML node or attribute to a std::string.
@@ -530,7 +530,7 @@ public:
}
const TiXmlNode* LastChild() const { return lastChild; } /// The last child of this node. Will be null if there are no children.
TiXmlNode* LastChild() { return lastChild; }
const TiXmlNode* LastChild( const char * value ) const; /// The last child of this node matching 'value'. Will be null if there are no children.
TiXmlNode* LastChild( const char * _value ) {
return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->LastChild( _value ));
@@ -709,11 +709,11 @@ public:
virtual TiXmlDeclaration* ToDeclaration() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
/** Create an exact duplicate of this node and return it. The memory must be deleted
by the caller.
by the caller.
*/
virtual TiXmlNode* Clone() const = 0;
/** Accept a hierchical visit the nodes in the TinyXML DOM. Every node in the
/** Accept a hierchical visit the nodes in the TinyXML DOM. Every node in the
XML tree will be conditionally visited and the host will be called back
via the TiXmlVisitor interface.
@@ -724,7 +724,7 @@ public:
The interface has been based on ideas from:
- http://www.saxproject.org/
- http://c2.com/cgi/wiki?HierarchicalVisitorPattern
- http://c2.com/cgi/wiki?HierarchicalVisitorPattern
Which are both good references for "visiting".
@@ -821,7 +821,7 @@ public:
/** QueryIntValue examines the value string. It is an alternative to the
IntValue() method with richer error checking.
If the value is an integer, it is stored in 'value' and
If the value is an integer, it is stored in 'value' and
the call returns TIXML_SUCCESS. If it is not
an integer, it returns TIXML_WRONG_TYPE.
@@ -840,21 +840,21 @@ public:
#ifdef TIXML_USE_STL
/// STL std::string form.
void SetName( const std::string& _name ) { name = _name; }
/// STL std::string form.
void SetName( const std::string& _name ) { name = _name; }
/// STL std::string form.
void SetValue( const std::string& _value ) { value = _value; }
#endif
/// Get the next sibling attribute in the DOM. Returns null at end.
const TiXmlAttribute* Next() const;
TiXmlAttribute* Next() {
return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Next() );
return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Next() );
}
/// Get the previous sibling attribute in the DOM. Returns null at beginning.
const TiXmlAttribute* Previous() const;
TiXmlAttribute* Previous() {
return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Previous() );
return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Previous() );
}
bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; }
@@ -890,7 +890,7 @@ private:
/* A class used to manage a group of attributes.
It is only used internally, both by the ELEMENT and the DECLARATION.
The set can be changed transparent to the Element and Declaration
classes that use it, but NOT transparent to the Attribute
which has to implement a next() and previous() method. Which makes
@@ -977,15 +977,15 @@ public:
/** QueryIntAttribute examines the attribute - it is an alternative to the
Attribute() method with richer error checking.
If the attribute is an integer, it is stored in 'value' and
If the attribute is an integer, it is stored in 'value' and
the call returns TIXML_SUCCESS. If it is not
an integer, it returns TIXML_WRONG_TYPE. If the attribute
does not exist, then TIXML_NO_ATTRIBUTE is returned.
*/
*/
int QueryIntAttribute( const char* name, int* _value ) const;
/// QueryUnsignedAttribute examines the attribute - see QueryIntAttribute().
int QueryUnsignedAttribute( const char* name, unsigned* _value ) const;
/** QueryBoolAttribute examines the attribute - see QueryIntAttribute().
/** QueryBoolAttribute examines the attribute - see QueryIntAttribute().
Note that '1', 'true', or 'yes' are considered true, while '0', 'false'
and 'no' are considered false.
*/
@@ -1016,7 +1016,7 @@ public:
/** Template form of the attribute query which will try to read the
attribute into the specified type. Very easy, very powerful, but
be careful to make sure to call this with the correct type.
NOTE: This method doesn't work correctly for 'string' types that contain spaces.
@return TIXML_SUCCESS, TIXML_WRONG_TYPE, or TIXML_NO_ATTRIBUTE
@@ -1089,7 +1089,7 @@ public:
/** Convenience function for easy access to the text inside an element. Although easy
and concise, GetText() is limited compared to getting the TiXmlText child
and accessing it directly.
If the first child of 'this' is a TiXmlText, the GetText()
returns the character string of the Text node, else null is returned.
@@ -1099,23 +1099,23 @@ public:
const char* str = fooElement->GetText();
@endverbatim
'str' will be a pointer to "This is text".
'str' will be a pointer to "This is text".
Note that this function can be misleading. If the element foo was created from
this XML:
@verbatim
<foo><b>This is text</b></foo>
<foo><b>This is text</b></foo>
@endverbatim
then the value of str would be null. The first child node isn't a text node, it is
another element. From this XML:
@verbatim
<foo>This is <b>text</b></foo>
<foo>This is <b>text</b></foo>
@endverbatim
GetText() will return "This is ".
WARNING: GetText() accesses a child node - don't become confused with the
similarly named TiXmlHandle::Text() and TiXmlNode::ToText() which are
WARNING: GetText() accesses a child node - don't become confused with the
similarly named TiXmlHandle::Text() and TiXmlNode::ToText() which are
safe type casts on the referenced node.
*/
const char* GetText() const;
@@ -1133,7 +1133,7 @@ public:
virtual const TiXmlElement* ToElement() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
virtual TiXmlElement* ToElement() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
/** Walk the XML tree visiting this node and all of its children.
/** Walk the XML tree visiting this node and all of its children.
*/
virtual bool Accept( TiXmlVisitor* visitor ) const;
@@ -1186,7 +1186,7 @@ public:
virtual const TiXmlComment* ToComment() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
virtual TiXmlComment* ToComment() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
/** Walk the XML tree visiting this node and all of its children.
/** Walk the XML tree visiting this node and all of its children.
*/
virtual bool Accept( TiXmlVisitor* visitor ) const;
@@ -1204,16 +1204,16 @@ private:
};
/** XML text. A text node can have 2 ways to output the next. "normal" output
/** XML text. A text node can have 2 ways to output the next. "normal" output
and CDATA. It will default to the mode it was parsed from the XML file and
you generally want to leave it alone, but you can change the output mode with
you generally want to leave it alone, but you can change the output mode with
SetCDATA() and query it with CDATA().
*/
class TiXmlText : public TiXmlNode
{
friend class TiXmlElement;
public:
/** Constructor for text element. By default, it is treated as
/** Constructor for text element. By default, it is treated as
normal, encoded text. If you want it be output as a CDATA text
element, set the parameter _cdata to 'true'
*/
@@ -1249,7 +1249,7 @@ public:
virtual const TiXmlText* ToText() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
virtual TiXmlText* ToText() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
/** Walk the XML tree visiting this node and all of its children.
/** Walk the XML tree visiting this node and all of its children.
*/
virtual bool Accept( TiXmlVisitor* content ) const;
@@ -1325,7 +1325,7 @@ public:
virtual const TiXmlDeclaration* ToDeclaration() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
virtual TiXmlDeclaration* ToDeclaration() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
/** Walk the XML tree visiting this node and all of its children.
/** Walk the XML tree visiting this node and all of its children.
*/
virtual bool Accept( TiXmlVisitor* visitor ) const;
@@ -1370,7 +1370,7 @@ public:
virtual const TiXmlUnknown* ToUnknown() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
virtual TiXmlUnknown* ToUnknown() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
/** Walk the XML tree visiting this node and all of its children.
/** Walk the XML tree visiting this node and all of its children.
*/
virtual bool Accept( TiXmlVisitor* content ) const;
@@ -1456,7 +1456,7 @@ public:
- The ErrorId() will contain the integer identifier of the error (not generally useful)
- The ErrorDesc() method will return the name of the error. (very useful)
- The ErrorRow() and ErrorCol() will return the location of the error (if known)
*/
*/
bool Error() const { return error; }
/// Contains a textual (english) description of the error if one occurs.
@@ -1467,7 +1467,7 @@ public:
*/
int ErrorId() const { return errorId; }
/** Returns the location (if known) of the error. The first column is column 1,
/** Returns the location (if known) of the error. The first column is column 1,
and the first row is row 1. A value of 0 means the row and column wasn't applicable
(memory errors, for example, have no row/column) or the parser lost the error. (An
error in the error reporting, in that case.)
@@ -1480,7 +1480,7 @@ public:
/** SetTabSize() allows the error reporting functions (ErrorRow() and ErrorCol())
to report the correct values for row and column. It does not change the output
or input in any way.
By calling this method, with a tab size
greater than 0, the row and column of each node and attribute is stored
when the file is loaded. Very useful for tracking the DOM back in to
@@ -1508,11 +1508,11 @@ public:
/** If you have handled the error, it can be reset with this call. The error
state is automatically cleared if you Parse a new XML block.
*/
void ClearError() { error = false;
errorId = 0;
errorDesc = "";
errorLocation.row = errorLocation.col = 0;
//errorLocation.last = 0;
void ClearError() { error = false;
errorId = 0;
errorDesc = "";
errorLocation.row = errorLocation.col = 0;
//errorLocation.last = 0;
}
/** Write the document to standard out using formatted printing ("pretty print"). */
@@ -1522,7 +1522,7 @@ public:
will allocate a character array (new char[]) and return it as a pointer. The
calling code pust call delete[] on the return char* to avoid a memory leak.
*/
//char* PrintToMemory() const;
//char* PrintToMemory() const;
/// Print this Document to a FILE stream.
virtual void Print( FILE* cfile, int depth = 0 ) const;
@@ -1532,7 +1532,7 @@ public:
virtual const TiXmlDocument* ToDocument() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
virtual TiXmlDocument* ToDocument() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
/** Walk the XML tree visiting this node and all of its children.
/** Walk the XML tree visiting this node and all of its children.
*/
virtual bool Accept( TiXmlVisitor* content ) const;
@@ -1570,7 +1570,7 @@ private:
<Document>
@endverbatim
Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very
Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very
easy to write a *lot* of code that looks like:
@verbatim
@@ -1590,7 +1590,7 @@ private:
@endverbatim
And that doesn't even cover "else" cases. TiXmlHandle addresses the verbosity
of such code. A TiXmlHandle checks for null pointers so it is perfectly safe
of such code. A TiXmlHandle checks for null pointers so it is perfectly safe
and correct to use:
@verbatim
@@ -1611,7 +1611,7 @@ private:
What they should not be used for is iteration:
@verbatim
int i=0;
int i=0;
while ( true )
{
TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", i ).ToElement();
@@ -1622,8 +1622,8 @@ private:
}
@endverbatim
It seems reasonable, but it is in fact two embedded while loops. The Child method is
a linear walk to find the element, so this code would iterate much more than it needs
It seems reasonable, but it is in fact two embedded while loops. The Child method is
a linear walk to find the element, so this code would iterate much more than it needs
to. Instead, prefer:
@verbatim
@@ -1653,20 +1653,20 @@ public:
/// Return a handle to the first child element with the given name.
TiXmlHandle FirstChildElement( const char * value ) const;
/** Return a handle to the "index" child with the given name.
/** Return a handle to the "index" child with the given name.
The first child is 0, the second 1, etc.
*/
TiXmlHandle Child( const char* value, int index ) const;
/** Return a handle to the "index" child.
/** Return a handle to the "index" child.
The first child is 0, the second 1, etc.
*/
TiXmlHandle Child( int index ) const;
/** Return a handle to the "index" child element with the given name.
/** Return a handle to the "index" child element with the given name.
The first child element is 0, the second 1, etc. Note that only TiXmlElements
are indexed: other types are not counted.
*/
TiXmlHandle ChildElement( const char* value, int index ) const;
/** Return a handle to the "index" child element.
/** Return a handle to the "index" child element.
The first child element is 0, the second 1, etc. Note that only TiXmlElements
are indexed: other types are not counted.
*/
@@ -1682,7 +1682,7 @@ public:
/** Return the handle as a TiXmlNode. This may return null.
*/
TiXmlNode* ToNode() const { return node; }
TiXmlNode* ToNode() const { return node; }
/** Return the handle as a TiXmlElement. This may return null.
*/
TiXmlElement* ToElement() const { return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); }
@@ -1693,11 +1693,11 @@ public:
*/
TiXmlUnknown* ToUnknown() const { return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); }
/** @deprecated use ToNode.
/** @deprecated use ToNode.
Return the handle as a TiXmlNode. This may return null.
*/
TiXmlNode* Node() const { return ToNode(); }
/** @deprecated use ToElement.
TiXmlNode* Node() const { return ToNode(); }
/** @deprecated use ToElement.
Return the handle as a TiXmlElement. This may return null.
*/
TiXmlElement* Element() const { return ToElement(); }
@@ -1757,7 +1757,7 @@ public:
void SetIndent( const char* _indent ) { indent = _indent ? _indent : "" ; }
/// Query the indention string.
const char* Indent() { return indent.c_str(); }
/** Set the line breaking string. By default set to newline (\n).
/** Set the line breaking string. By default set to newline (\n).
Some operating systems prefer other characters, or can be
set to the null/empty string for no indenation.
*/
@@ -1765,12 +1765,12 @@ public:
/// Query the current line breaking string.
const char* LineBreak() { return lineBreak.c_str(); }
/** Switch over to "stream printing" which is the most dense formatting without
/** Switch over to "stream printing" which is the most dense formatting without
linebreaks. Common when the XML is needed for network transmission.
*/
void SetStreamPrinting() { indent = "";
lineBreak = "";
}
}
/// Return the result.
const char* CStr() { return buffer.c_str(); }
/// Return the length of the result string.

View File

@@ -2,12 +2,12 @@
www.sourceforge.net/projects/tinyxml
Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com)
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must

View File

@@ -2,23 +2,23 @@
www.sourceforge.net/projects/tinyxml
Original code by Lee Thomason (www.grinninglizard.com)
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
3. This notice may not be removed or altered from any source
distribution.
*/
@@ -39,8 +39,8 @@ distribution.
// Note tha "PutString" hardcodes the same list. This
// is less flexible than it appears. Changing the entries
// or order will break putstring.
TiXmlBase::Entity TiXmlBase::entity[ TiXmlBase::NUM_ENTITY ] =
// or order will break putstring.
TiXmlBase::Entity TiXmlBase::entity[ TiXmlBase::NUM_ENTITY ] =
{
{ "&amp;", 5, '&' },
{ "&lt;", 4, '<' },
@@ -54,16 +54,16 @@ TiXmlBase::Entity TiXmlBase::entity[ TiXmlBase::NUM_ENTITY ] =
// Including the basic of this table, which determines the #bytes in the
// sequence from the lead byte. 1 placed for invalid sequences --
// although the result will be junk, pass it through as much as possible.
// Beware of the non-characters in UTF-8:
// Beware of the non-characters in UTF-8:
// ef bb bf (Microsoft "lead bytes")
// ef bf be
// ef bf bf
// ef bf bf
const unsigned char TIXML_UTF_LEAD_0 = 0xefU;
const unsigned char TIXML_UTF_LEAD_1 = 0xbbU;
const unsigned char TIXML_UTF_LEAD_2 = 0xbfU;
const int TiXmlBase::utf8ByteTable[256] =
const int TiXmlBase::utf8ByteTable[256] =
{
// 0 1 2 3 4 5 6 7 8 9 a b c d e f
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x00
@@ -75,9 +75,9 @@ const int TiXmlBase::utf8ByteTable[256] =
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x60
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x70 End of ASCII range
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x80 0x80 to 0xc1 invalid
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x90
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xa0
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xb0
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0x90
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xa0
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 0xb0
1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xc0 0xc2 to 0xdf 2 byte
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, // 0xd0
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // 0xe0 0xe0 to 0xef 3 byte
@@ -91,7 +91,7 @@ void TiXmlBase::ConvertUTF32ToUTF8( unsigned long input, char* output, int* leng
const unsigned long BYTE_MARK = 0x80;
const unsigned long FIRST_BYTE_MARK[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
if (input < 0x80)
if (input < 0x80)
*length = 1;
else if ( input < 0x800 )
*length = 2;
@@ -105,22 +105,22 @@ void TiXmlBase::ConvertUTF32ToUTF8( unsigned long input, char* output, int* leng
output += *length;
// Scary scary fall throughs.
switch (*length)
switch (*length)
{
case 4:
--output;
*output = (char)((input | BYTE_MARK) & BYTE_MASK);
--output;
*output = (char)((input | BYTE_MARK) & BYTE_MASK);
input >>= 6;
case 3:
--output;
*output = (char)((input | BYTE_MARK) & BYTE_MASK);
--output;
*output = (char)((input | BYTE_MARK) & BYTE_MASK);
input >>= 6;
case 2:
--output;
*output = (char)((input | BYTE_MARK) & BYTE_MASK);
--output;
*output = (char)((input | BYTE_MARK) & BYTE_MASK);
input >>= 6;
case 1:
--output;
--output;
*output = (char)(input | FIRST_BYTE_MARK[*length]);
}
}
@@ -130,7 +130,7 @@ void TiXmlBase::ConvertUTF32ToUTF8( unsigned long input, char* output, int* leng
{
// This will only work for low-ascii, everything else is assumed to be a valid
// letter. I'm not sure this is the best approach, but it is quite tricky trying
// to figure out alhabetical vs. not across encoding. So take a very
// to figure out alhabetical vs. not across encoding. So take a very
// conservative approach.
// if ( encoding == TIXML_ENCODING_UTF8 )
@@ -151,7 +151,7 @@ void TiXmlBase::ConvertUTF32ToUTF8( unsigned long input, char* output, int* leng
{
// This will only work for low-ascii, everything else is assumed to be a valid
// letter. I'm not sure this is the best approach, but it is quite tricky trying
// to figure out alhabetical vs. not across encoding. So take a very
// to figure out alhabetical vs. not across encoding. So take a very
// conservative approach.
// if ( encoding == TIXML_ENCODING_UTF8 )
@@ -224,7 +224,7 @@ void TiXmlParsingData::Stamp( const char* now, TiXmlEncoding encoding )
case '\r':
// bump down to the next line
++row;
col = 0;
col = 0;
// Eat the character
++p;
@@ -266,11 +266,11 @@ void TiXmlParsingData::Stamp( const char* now, TiXmlEncoding encoding )
// In these cases, don't advance the column. These are
// 0-width spaces.
if ( *(pU+1)==TIXML_UTF_LEAD_1 && *(pU+2)==TIXML_UTF_LEAD_2 )
p += 3;
p += 3;
else if ( *(pU+1)==0xbfU && *(pU+2)==0xbeU )
p += 3;
p += 3;
else if ( *(pU+1)==0xbfU && *(pU+2)==0xbfU )
p += 3;
p += 3;
else
{ p +=3; ++col; } // A normal character.
}
@@ -322,10 +322,10 @@ const char* TiXmlBase::SkipWhiteSpace( const char* p, TiXmlEncoding encoding )
while ( *p )
{
const unsigned char* pU = (const unsigned char*)p;
// Skip the stupid Microsoft UTF-8 Byte order marks
if ( *(pU+0)==TIXML_UTF_LEAD_0
&& *(pU+1)==TIXML_UTF_LEAD_1
&& *(pU+1)==TIXML_UTF_LEAD_1
&& *(pU+2)==TIXML_UTF_LEAD_2 )
{
p += 3;
@@ -413,12 +413,12 @@ const char* TiXmlBase::ReadName( const char* p, TIXML_STRING * name, TiXmlEncodi
// After that, they can be letters, underscores, numbers,
// hyphens, or colons. (Colons are valid ony for namespaces,
// but tinyxml can't tell namespaces from names.)
if ( p && *p
if ( p && *p
&& ( IsAlpha( (unsigned char) *p, encoding ) || *p == '_' ) )
{
const char* start = p;
while( p && *p
&& ( IsAlphaNum( (unsigned char ) *p, encoding )
&& ( IsAlphaNum( (unsigned char ) *p, encoding )
|| *p == '_'
|| *p == '-'
|| *p == '.'
@@ -469,7 +469,7 @@ const char* TiXmlBase::GetEntity( const char* p, char* value, int* length, TiXml
ucs += mult * (*q - 'a' + 10);
else if ( *q >= 'A' && *q <= 'F' )
ucs += mult * (*q - 'A' + 10 );
else
else
return 0;
mult *= 16;
--q;
@@ -492,7 +492,7 @@ const char* TiXmlBase::GetEntity( const char* p, char* value, int* length, TiXml
{
if ( *q >= '0' && *q <= '9' )
ucs += mult * (*q - '0');
else
else
return 0;
mult *= 10;
--q;
@@ -571,10 +571,10 @@ bool TiXmlBase::StringEqual( const char* p,
return false;
}
const char* TiXmlBase::ReadText( const char* p,
TIXML_STRING * text,
bool trimWhiteSpace,
const char* endTag,
const char* TiXmlBase::ReadText( const char* p,
TIXML_STRING * text,
bool trimWhiteSpace,
const char* endTag,
bool caseInsensitive,
TiXmlEncoding encoding )
{
@@ -647,7 +647,7 @@ void TiXmlDocument::StreamIn( std::istream * in, TIXML_STRING * tag )
// This "pre-streaming" will never read the closing ">" so the
// sub-tag can orient itself.
if ( !StreamTo( in, '<', tag ) )
if ( !StreamTo( in, '<', tag ) )
{
SetError( TIXML_ERROR_PARSING_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
return;
@@ -669,7 +669,7 @@ void TiXmlDocument::StreamIn( std::istream * in, TIXML_STRING * tag )
if ( in->good() )
{
// We now have something we presume to be a node of
// We now have something we presume to be a node of
// some sort. Identify it, and call the node to
// continue streaming.
TiXmlNode* node = Identify( tag->c_str() + tagIndex, TIXML_DEFAULT_ENCODING );
@@ -778,7 +778,7 @@ const char* TiXmlDocument::Parse( const char* p, TiXmlParsingData* prevData, TiX
encoding = TIXML_ENCODING_UTF8;
else if ( StringEqual( enc, "UTF8", true, TIXML_ENCODING_UNKNOWN ) )
encoding = TIXML_ENCODING_UTF8; // incorrect, but be nice
else
else
encoding = TIXML_ENCODING_LEGACY;
}
@@ -796,7 +796,7 @@ const char* TiXmlDocument::Parse( const char* p, TiXmlParsingData* prevData, TiX
}
void TiXmlDocument::SetError( int err, const char* pError, TiXmlParsingData* data, TiXmlEncoding encoding )
{
{
// The first error in a chain is more accurate - don't set again!
if ( error )
return;
@@ -832,7 +832,7 @@ TiXmlNode* TiXmlNode::Identify( const char* p, TiXmlEncoding encoding )
return 0;
}
// What is this thing?
// What is this thing?
// - Elements start with a letter or underscore, but xml is reserved.
// - Comments: <!--
// - Decleration: <?xml
@@ -915,7 +915,7 @@ void TiXmlElement::StreamIn (std::istream * in, TIXML_STRING * tag)
return;
}
(*tag) += (char) c ;
if ( c == '>' )
break;
}
@@ -925,7 +925,7 @@ void TiXmlElement::StreamIn (std::istream * in, TIXML_STRING * tag)
// Okay...if we are a "/>" tag, then we're done. We've read a complete tag.
// If not, identify and stream.
if ( tag->at( tag->length() - 1 ) == '>'
if ( tag->at( tag->length() - 1 ) == '>'
&& tag->at( tag->length() - 2 ) == '/' )
{
// All good!
@@ -943,7 +943,7 @@ void TiXmlElement::StreamIn (std::istream * in, TIXML_STRING * tag)
StreamWhiteSpace( in, tag );
// Do we have text?
if ( in->good() && in->peek() != '<' )
if ( in->good() && in->peek() != '<' )
{
// Yep, text.
TiXmlText text( "" );
@@ -976,7 +976,7 @@ void TiXmlElement::StreamIn (std::istream * in, TIXML_STRING * tag)
document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
return;
}
if ( c == '>' )
break;
@@ -1095,7 +1095,7 @@ const char* TiXmlElement::Parse( const char* p, TiXmlParsingData* data, TiXmlEnc
// Empty tag.
if ( *p != '>' )
{
if ( document ) document->SetError( TIXML_ERROR_PARSING_EMPTY, p, data, encoding );
if ( document ) document->SetError( TIXML_ERROR_PARSING_EMPTY, p, data, encoding );
return 0;
}
return (p+1);
@@ -1117,7 +1117,7 @@ const char* TiXmlElement::Parse( const char* p, TiXmlParsingData* data, TiXmlEnc
// We should find the end tag now
// note that:
// </foo > and
// </foo>
// </foo>
// are both valid end tags.
if ( StringEqual( p, endTag.c_str(), false, encoding ) )
{
@@ -1211,8 +1211,8 @@ const char* TiXmlElement::ReadValue( const char* p, TiXmlParsingData* data, TiXm
LinkEndChild( textNode );
else
delete textNode;
}
else
}
else
{
// We hit a '<'
// Have we hit a new element or an end tag? This could also be
@@ -1228,7 +1228,7 @@ const char* TiXmlElement::ReadValue( const char* p, TiXmlParsingData* data, TiXm
{
p = node->Parse( p, data, encoding );
LinkEndChild( node );
}
}
else
{
return 0;
@@ -1242,7 +1242,7 @@ const char* TiXmlElement::ReadValue( const char* p, TiXmlParsingData* data, TiXm
if ( !p )
{
if ( document ) document->SetError( TIXML_ERROR_READING_ELEMENT_VALUE, 0, 0, encoding );
}
}
return p;
}
@@ -1252,7 +1252,7 @@ void TiXmlUnknown::StreamIn( std::istream * in, TIXML_STRING * tag )
{
while ( in->good() )
{
int c = in->get();
int c = in->get();
if ( c <= 0 )
{
TiXmlDocument* document = GetDocument();
@@ -1265,7 +1265,7 @@ void TiXmlUnknown::StreamIn( std::istream * in, TIXML_STRING * tag )
if ( c == '>' )
{
// All is well.
return;
return;
}
}
}
@@ -1298,7 +1298,7 @@ const char* TiXmlUnknown::Parse( const char* p, TiXmlParsingData* data, TiXmlEnc
if ( !p )
{
if ( document )
if ( document )
document->SetError( TIXML_ERROR_PARSING_UNKNOWN, 0, 0, encoding );
}
if ( p && *p == '>' )
@@ -1311,7 +1311,7 @@ void TiXmlComment::StreamIn( std::istream * in, TIXML_STRING * tag )
{
while ( in->good() )
{
int c = in->get();
int c = in->get();
if ( c <= 0 )
{
TiXmlDocument* document = GetDocument();
@@ -1322,12 +1322,12 @@ void TiXmlComment::StreamIn( std::istream * in, TIXML_STRING * tag )
(*tag) += (char) c;
if ( c == '>'
if ( c == '>'
&& tag->at( tag->length() - 2 ) == '-'
&& tag->at( tag->length() - 3 ) == '-' )
{
// All is well.
return;
return;
}
}
}
@@ -1363,11 +1363,11 @@ const char* TiXmlComment::Parse( const char* p, TiXmlParsingData* data, TiXmlEnc
//
// from the XML spec:
/*
[Definition: Comments may appear anywhere in a document outside other markup; in addition,
they may appear within the document type declaration at places allowed by the grammar.
They are not part of the document's character data; an XML processor MAY, but need not,
make it possible for an application to retrieve the text of comments. For compatibility,
the string "--" (double-hyphen) MUST NOT occur within comments.] Parameter entity
[Definition: Comments may appear anywhere in a document outside other markup; in addition,
they may appear within the document type declaration at places allowed by the grammar.
They are not part of the document's character data; an XML processor MAY, but need not,
make it possible for an application to retrieve the text of comments. For compatibility,
the string "--" (double-hyphen) MUST NOT occur within comments.] Parameter entity
references MUST NOT be recognized within comments.
An example of a comment:
@@ -1382,7 +1382,7 @@ const char* TiXmlComment::Parse( const char* p, TiXmlParsingData* data, TiXmlEnc
value.append( p, 1 );
++p;
}
if ( p && *p )
if ( p && *p )
p += strlen( endTag );
return p;
@@ -1421,7 +1421,7 @@ const char* TiXmlAttribute::Parse( const char* p, TiXmlParsingData* data, TiXmlE
if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding );
return 0;
}
const char* end;
const char SINGLE_QUOTE = '\'';
const char DOUBLE_QUOTE = '\"';
@@ -1450,7 +1450,7 @@ const char* TiXmlAttribute::Parse( const char* p, TiXmlParsingData* data, TiXmlE
{
if ( *p == SINGLE_QUOTE || *p == DOUBLE_QUOTE ) {
// [ 1451649 ] Attribute values with trailing quotes not handled correctly
// We did not have an opening quote but seem to have a
// We did not have an opening quote but seem to have a
// closing one. Give up and throw an error.
if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding );
return 0;
@@ -1467,8 +1467,8 @@ void TiXmlText::StreamIn( std::istream * in, TIXML_STRING * tag )
{
while ( in->good() )
{
int c = in->peek();
if ( !cdata && (c == '<' ) )
int c = in->peek();
if ( !cdata && (c == '<' ) )
{
return;
}
@@ -1489,7 +1489,7 @@ void TiXmlText::StreamIn( std::istream * in, TIXML_STRING * tag )
// terminator of cdata.
return;
}
}
}
}
}
#endif
@@ -1529,7 +1529,7 @@ const char* TiXmlText::Parse( const char* p, TiXmlParsingData* data, TiXmlEncodi
++p;
}
TIXML_STRING dummy;
TIXML_STRING dummy;
p = ReadText( p, &dummy, false, endTag, false, encoding );
return p;
}
@@ -1603,19 +1603,19 @@ const char* TiXmlDeclaration::Parse( const char* p, TiXmlParsingData* data, TiXm
if ( StringEqual( p, "version", true, _encoding ) )
{
TiXmlAttribute attrib;
p = attrib.Parse( p, data, _encoding );
p = attrib.Parse( p, data, _encoding );
version = attrib.Value();
}
else if ( StringEqual( p, "encoding", true, _encoding ) )
{
TiXmlAttribute attrib;
p = attrib.Parse( p, data, _encoding );
p = attrib.Parse( p, data, _encoding );
encoding = attrib.Value();
}
else if ( StringEqual( p, "standalone", true, _encoding ) )
{
TiXmlAttribute attrib;
p = attrib.Parse( p, data, _encoding );
p = attrib.Parse( p, data, _encoding );
standalone = attrib.Value();
}
else

View File

@@ -73,7 +73,7 @@ end
function App:init()
-- App initialisation 1st goal: Get the loading screen up
print("")
print("")
print("---------------------------------------------------------------")
@@ -103,11 +103,11 @@ function App:init()
local good_install_folder, error_message = self:checkInstallFolder()
self.good_install_folder = good_install_folder
-- self:checkLanguageFile()
self:initSavegameDir()
self:initScreenshotsDir()
-- Create the window
if not SDL.init("audio", "video", "timer") then
return false, "Cannot initialise SDL"
@@ -146,7 +146,7 @@ function App:init()
self.video = assert(TH.surface(self.config.width, self.config.height, unpack(modes)))
self.video:setBlueFilterActive(false)
SDL.wm.setIconWin32()
local caption_descs = {self.video:getRendererDetails()}
if compile_opts.jit then
caption_descs[#caption_descs + 1] = compile_opts.jit
@@ -156,12 +156,12 @@ function App:init()
end
self.caption = "CorsixTH (" .. table.concat(caption_descs, ", ") .. ")"
self.video:setCaption(self.caption)
-- Prereq 2: Load and initialise the graphics subsystem
dofile "persistance"
dofile "graphics"
self.gfx = Graphics(self)
-- Put up the loading screen
if good_install_folder then
self.video:startFrame()
@@ -185,15 +185,15 @@ function App:init()
self.video:endFrame()
end
end
-- App initialisation 2nd goal: Load remaining systems and data in an appropriate order
math.randomseed(os.time() + SDL.getTicks())
-- Add math.n_random globally. It generates pseudo random normally distributed
-- numbers using the Box-Muller transform.
strict_declare_global "math.n_random"
math.n_random = function(mean, variance)
return mean + math.sqrt(-2 * math.log(math.random()))
return mean + math.sqrt(-2 * math.log(math.random()))
* math.cos(2 * math.pi * math.random()) * variance
end
-- Also add the nice-to-have function math.round
@@ -205,7 +205,7 @@ function App:init()
dofile "audio"
self.audio = Audio(self)
self.audio:init()
-- Load movie player
dofile "movie_player"
self.moviePlayer = MoviePlayer(self, self.audio, self.video)
@@ -224,10 +224,10 @@ function App:init()
-- (or insert "true or" after the "if" in the above)
self:dumpStrings()
end
-- Load map before world
dofile "map"
-- Load additional Lua before world
if good_install_folder then
self.anims = self.gfx:loadAnimations("Data", "V")
@@ -240,7 +240,7 @@ function App:init()
local objects = self:loadLuaFolder"objects"
self.objects = self:loadLuaFolder("objects/machines", nil, objects)
-- Doors are in their own folder to ensure that the swing doors (which
-- Doors are in their own folder to ensure that the swing doors (which
-- depend on the door) are loaded after the door object.
self.objects = self:loadLuaFolder("objects/doors", nil, objects)
for _, v in ipairs(self.objects) do
@@ -258,7 +258,7 @@ function App:init()
-- Load world before UI
dofile "world"
end
-- Load UI
dofile "ui"
if good_install_folder then
@@ -277,7 +277,7 @@ function App:init()
self.ui:addWindow(UIDirectoryBrowser(self.ui, nil, _S.install.th_directory, "InstallDirTreeNode", callback))
return true
end
-- Load main menu (which creates UI)
if _MAP_EDITOR then
self:loadLevel("")
@@ -292,7 +292,7 @@ function App:init()
" to English because the desired language could not be loaded. "..
"Please make sure you have specified a font file in the config file."}))
end
-- If a savegame was specified, load it
if self.command_line.load then
local status, err = pcall(self.load, self, self.command_line.load)
@@ -380,7 +380,7 @@ function App:initLanguage()
-- For immediate compatibility:
getmetatable(_S).__call = function(_, sec, str, ...)
assert(_S.deprecated[sec] and _S.deprecated[sec][str], "_S(".. sec ..", ".. str ..") does not exist!")
str = _S.deprecated[sec][str]
if ... then
str = str:format(...)
@@ -417,10 +417,10 @@ function App:loadMainMenu(message)
self.ui:setMenuBackground()
self.ui:addWindow(UIMainMenu(self.ui))
self.ui:addWindow(UITipOfTheDay(self.ui))
-- Show update window if there's an update
self:checkForUpdates()
-- If a message was supplied, show it
if message then
self.ui:addWindow(UIInformation(self.ui, message))
@@ -450,7 +450,7 @@ function App:loadLevel(level, ...)
},
}
end
-- Make sure there is no blue filter active.
self.video:setBlueFilterActive(false)
@@ -458,24 +458,24 @@ function App:loadLevel(level, ...)
self.ui = nil
self.world = nil
self.map = nil
-- Load map
self.map = new_map
self.map:setBlocks(self.gfx:loadSpriteTable("Data", "VBlk-0"))
self.map:setDebugFont(self.gfx:loadFont("QData", "Font01V"))
-- Load world
self.world = World(self)
self.world:createMapObjects(map_objects)
-- Load UI
self.ui = GameUI(self, self.world:getLocalPlayerHospital())
self.world:setUI(self.ui) -- Function call allows world to set up its keyHandlers
if tonumber(level) then
self.moviePlayer:playAdvanceMovie(level)
end
-- Now restore progress from previous levels.
if carry_to_next_level then
self.world:initFromPreviousLevel(carry_to_next_level)
@@ -506,7 +506,7 @@ function App:dumpStrings()
fi:write"\n"
end
fi:close()
local function dump_by_line(file, obj, prefix)
for n, o in pairs(obj) do
if n ~= "deprecated" then
@@ -524,7 +524,7 @@ function App:dumpStrings()
end
end
end
local function dump_grouped(file, obj, prefix)
for n, o in pairs(obj) do
if n ~= "deprecated" then
@@ -545,15 +545,15 @@ function App:dumpStrings()
end
end
end
fi = assert(io.open(dir .. "debug-strings-new-lines.txt", "wt"))
dump_by_line(fi, _S, "")
fi:close()
fi = assert(io.open(dir .. "debug-strings-new-grouped.txt", "wt"))
dump_grouped(fi, _S, "")
fi:close()
self:checkMissingStringsInLanguage(dir, self.config.language)
-- Uncomment these lines to get diffs for all languages in the game
-- for _, lang in ipairs(self.strings.languages_english) do
@@ -611,7 +611,7 @@ function App:checkMissingStringsInLanguage(dir, language)
end
end
end
-- if possible, use the English name of the language for the file name.
local language_english = language
for _, lang_eng in ipairs(self.strings.languages_english) do
@@ -620,7 +620,7 @@ function App:checkMissingStringsInLanguage(dir, language)
break
end
end
local fi = assert(io.open(dir .. "debug-strings-diff-" .. language_english:lower() .. ".txt", "wt"))
fi:write("------------------------------------\n")
fi:write("MISSING STRINGS IN LANGUAGE \"" .. language:upper() .. "\":\n")
@@ -642,7 +642,7 @@ function App:fixConfig()
self.config[k] = v
end
end
for key, value in pairs(self.config) do
-- Trim whitespace from beginning and end string values - it shouldn't be
-- there (at least in any current configuration options).
@@ -651,17 +651,17 @@ function App:fixConfig()
self.config[key] = value:match"^[%s]*(.-)[%s]*$"
end
end
-- For language, make language name lower case
if key == "language" and type(value) == "string" then
self.config[key] = value:lower()
end
-- For resolution, check that resolution is at least 640x480
if key == "width" and type(value) == "number" and value < 640 then
self.config[key] = 640
end
if key == "height" and type(value) == "number" and value < 480 then
self.config[key] = 480
end
@@ -686,7 +686,7 @@ function App:saveConfig()
-- Remove enclosing [[]], if necessary
local _, _, temp = string.find(value, "^%[%[(.*)%]%]$")
value = temp or value
-- If identifier also exists in runtime options, compare their values and
-- replace the line, if needed
--if self.config[identifier] ~= nil then
@@ -745,12 +745,12 @@ function App:run()
repaint = dispatch(self, yield(repaint))
end
end)
if self.config.track_fps then
SDL.trackFPS(true)
SDL.limitFPS(false)
end
self.running = true
do
local num_iterations = 0
@@ -863,7 +863,7 @@ function App:drawFrame()
self.ui:draw(self.video)
end
self.video:endFrame()
if self.config.track_fps then
fps_sum = fps_sum - fps_history[fps_next]
fps_history[fps_next] = SDL.getFPS()
@@ -937,7 +937,7 @@ function App:checkInstallFolder()
-- app, and give the user a dialog asking for the correct directory.
return false
end
-- Check that a few core files are present
local missing = {}
local function check(path)
@@ -957,14 +957,14 @@ function App:checkInstallFolder()
print("Trying to let the user select a new one.")
return false, {message}
end
-- Check for demo version
if self.fs:readContents("DataM", "Demo.dat") then
self.using_demo_files = true
print "Notice: Using data files from demo version of Theme Hospital."
print "Consider purchasing a full copy of the game to support EA."
end
-- Do a few more checks to make sure that commonly corrupted files are OK.
local corrupt = {}
@@ -973,7 +973,7 @@ function App:checkInstallFolder()
local real_path = self.fs:getFilePath(path)
-- If the file exists but is smaller than usual it is probably corrupt
if real_path then
local real_size = lfs.attributes(real_path, "size")
local real_size = lfs.attributes(real_path, "size")
if real_size + 1024 < correct_size or real_size - 1024 > correct_size then
corrupt[#corrupt + 1] = path .. " (Size: " .. math.floor(real_size/1024) .. " kB / Correct: about " .. math.floor(correct_size/1024) .. " kB)"
end
@@ -987,14 +987,14 @@ function App:checkInstallFolder()
check_corrupt("INTRO" .. pathsep .. "INTRO.SM4", 33616520)
check_corrupt("QDATA" .. pathsep .. "FONT00V.DAT", 1024)
check_corrupt("ANIMS" .. pathsep .. "LOSE1.SMK", 1009728)
if #corrupt ~= 0 then
table.insert(corrupt, 1, "There appears to be corrupt files in your Theme Hospital folder, " ..
table.insert(corrupt, 1, "There appears to be corrupt files in your Theme Hospital folder, " ..
"so don't be suprised if CorsixTH crashes. At least the following files are wrong:")
table.insert(corrupt, message)
end
end
return true, #corrupt ~= 0 and corrupt or nil
end
@@ -1005,7 +1005,7 @@ function App:checkLanguageFile()
-- providing every language file. If the user has selected a language which
-- isn't present, then we should detect this and inform the user of their
-- options.
local filename = self:getDataFilename("Lang-" .. self.config.language .. ".dat")
local file, err = io.open(filename, "rb")
if file then
@@ -1013,7 +1013,7 @@ function App:checkLanguageFile()
file:close()
return
end
print "Theme Hospital install seems to be missing the language file for the language which you requested."
print "The following language files are present:"
local none = true
@@ -1184,9 +1184,9 @@ end
function App:quickLoad()
local filename = "quicksave"
if lfs.attributes(self.savegame_dir .. filename) then
self:load(filename)
else
self:quickSave()
self:load(filename)
else
self:quickSave()
self.ui:addWindow(UIInformation(self.ui, {_S.errors.load_quick_save}))
end
end
@@ -1233,7 +1233,7 @@ end
function App:afterLoad()
local old = self.world.savegame_version or 0
local new = self.savegame_version
if old == 0 then
-- Game log was not present before introduction of savegame versions, so create it now.
self.world.game_log = {}
@@ -1244,13 +1244,13 @@ function App:afterLoad()
end
local first = self.world.original_savegame_version
if new == old then
self.world:gameLog("Savegame version is " .. new .. " (" .. self:getVersion()
self.world:gameLog("Savegame version is " .. new .. " (" .. self:getVersion()
.. "), originally it was " .. first .. " (" .. self:getVersion(first) .. ")")
return
elseif new > old then
self.world:gameLog("Savegame version changed from " .. old .. " (" .. self:getVersion(old) ..
") to " .. new .. " (" .. self:getVersion() ..
"). The save was created using " .. first ..
") to " .. new .. " (" .. self:getVersion() ..
"). The save was created using " .. first ..
" (" .. self:getVersion(first) .. ")")
else
-- TODO: This should maybe be forbidden completely.
@@ -1258,7 +1258,7 @@ function App:afterLoad()
")" .. " in older version " .. new .. " (" .. self:getVersion() .. ").")
end
self.world.savegame_version = new
if new < 79 then
self.key_modifiers = {}
end
@@ -1272,15 +1272,15 @@ function App:checkForUpdates()
-- Only check for updates once per application launch
if not self.check_for_updates or not self.config.check_for_updates then return end
self.check_for_updates = false
-- Default language to use for the changelog if no localised version is available
local default_language = "en"
local update_url = 'http://www.corsixth.com/check-for-updates'
local current_version = self:getVersion()
-- Only URLs that match this list of trusted domains will be accepted.
local trusted_domains = { 'corsixth.com', 'code.google.com' }
-- Only check for updates against released versions
if current_version == "Trunk" then
print "Will not check for updates since this is the Trunk version."
@@ -1307,14 +1307,14 @@ function App:checkForUpdates()
end
local update_table = loadstring_envcall(update_body, "@updatechecker"){}
local changelog = update_table["changelog_" .. default_language]
local changelog = update_table["changelog_" .. default_language]
local new_version = update_table["major"] .. '.' .. update_table["minor"] .. update_table["revision"]
if (new_version <= current_version) then
print "You are running the latest version of CorsixTH."
return
end
-- Check to make sure download URL is trusted
local download_url = url.parse(update_table["download_url"])
local valid_url = false
@@ -1324,11 +1324,11 @@ function App:checkForUpdates()
break
end
end
if not valid_url then
if not valid_url then
print ("Update download url is not on the trusted domains list (" .. updateTable["download_url"] .. ")")
return
end
-- Check to see if there's a changelog in the user's language
local current_langs = self.strings:getLanguageNames(self.config.language)
for _,v in ipairs(current_langs) do
@@ -1337,7 +1337,7 @@ function App:checkForUpdates()
break
end
end
print ("New version found: " .. new_version)
-- Display the update window
self.ui:addWindow(UIUpdate(self.ui, current_version, new_version, changelog, update_table["download_url"]))

View File

@@ -31,7 +31,7 @@ class "Audio"
function Audio:Audio(app)
self.app = app
self.has_bg_music = false
self.not_loaded = not app.config.audio
end
@@ -79,18 +79,18 @@ function Audio:init()
end
return t
end
--[[
Find the music files on disk.
-----------------------------
- Will search through all the files in music_dir.
- Adds xmi and mp3 files.
- If ATLANTIS.XMI and ATLANTIS.MP3 exists, the MP3 is preferred.
- Uses titles from MIDI.TXT if found, else the filename.
--]]
local midi_txt -- File name of midi.txt file, if any.
local _f, _s, _v
if music_dir then
_f, _s, _v = lfs.dir(music_dir)
@@ -101,7 +101,7 @@ function Audio:init()
local filename, ext = file:match"^(.*)%.([^.]+)$"
ext = ext and ext:upper()
-- Music file found (mp3/xmi).
if ext == "MP3" or ext == "XMI" then
if ext == "MP3" or ext == "XMI" then
local info = musicFileTable(filename)
info.title = filename
if ext == "MP3" then
@@ -122,16 +122,16 @@ function Audio:init()
elseif ext == "TXT" and (file:sub(1, 4):upper() == "MIDI" or
file:sub(1, 5):upper() == "NAMES") then
-- If it Looks like the midi.txt or equiv, then remember it for later.
midi_txt = file
midi_txt = file
end
end
-- Enable music files and add them to the playlist.
for _, info in pairs(music_array) do
info.enabled = true
self.background_playlist[#self.background_playlist + 1] = info
end
-- This is later. If we found a midi.txt, go through it and add the titles to the files we know
if midi_txt then
local data
@@ -159,7 +159,7 @@ function Audio:init()
end)
self.has_bg_music = true
end
local status, err = SDL.audio.init(self.app.config.audio_frequency,
self.app.config.audio_channels, self.app.config.audio_buffer_size)
if status then
@@ -180,7 +180,7 @@ function Audio:initSpeech(speech_file)
if self.not_loaded then
return
end
local function load_sound_file(file)
return self.app.fs:readContents("Sound", "Data", file)
end
@@ -190,8 +190,8 @@ function Audio:initSpeech(speech_file)
return
end
local archive_data, err = load_sound_file(speech_file)
-- If sound file not found and language choosen is not English,
-- If sound file not found and language choosen is not English,
-- maybe we can have more chance loading English sounds
if not archive_data and speech_file ~= "Sound-0.dat" and self.app.good_install_folder then
if self.speech_file_name == "Sound-0.dat" then
@@ -201,7 +201,7 @@ function Audio:initSpeech(speech_file)
speech_file = "Sound-0.dat"
archive_data = load_sound_file(speech_file)
end
if not archive_data then
if self.app.good_install_folder then
print("Notice: No sound effects as no SOUND/DATA/".. speech_file ..
@@ -215,7 +215,7 @@ function Audio:initSpeech(speech_file)
self.sound_archive = TH.soundArchive()
if not self.sound_archive:load(archive_data) then
print("Notice: No sound effects as SOUND/DATA/" .. speech_file .. " could not be loaded")
if #self.background_playlist == 0 then
if #self.background_playlist == 0 then
self.not_loaded = true
end
else
@@ -231,13 +231,13 @@ end
function Audio:dumpSoundArchive(out_dir)
local info,warning = io.open(out_dir .. "info.csv", "wt")
if info == nil then
print("Error: Audio dump failed because info.csv couldn't be created and/or opened in the dump directory:" .. out_dir)
print(warning)
return
end
for i = 1, #self.sound_archive - 1 do
local filename = self.sound_archive:getFilename(i)
info:write(i, ",", filename, ",", self.sound_archive:getDuration(i), ",\n")
@@ -325,7 +325,7 @@ function Audio:findIndexOfCurrentTrack()
return i
end
end
return 1
end
@@ -333,14 +333,14 @@ function Audio:playNextOrPreviousBackgroundTrack(direction)
if self.not_loaded or #self.background_playlist == 0 then
return
end
if not self.background_music then
self:playRandomBackgroundTrack()
return
end
local index = self:findIndexOfCurrentTrack()
-- Find next/previous track
for i = 1, #self.background_playlist do
i = ((index + direction * i - 1) % #self.background_playlist) + 1
@@ -379,7 +379,7 @@ function Audio:pauseBackgroundTrack()
status = SDL.audio.pauseMusic()
self.background_paused = true
end
-- NB: Explicit false check, as old C side returned nil in all cases
if status == false then
-- SDL doesn't seem to support pausing/resuming for this format/driver,
@@ -440,11 +440,11 @@ function Audio:playBackgroundTrack(index)
end
-- Loading of music files can incur a slight pause, which is why it is
-- done asynchronously.
-- Someone might want to stop the player from
-- Someone might want to stop the player from
-- starting to play once it's loaded though.
self.load_music = true
SDL.audio.loadMusicAsync(data, function(music, e)
if music == nil then
error("Could not load music file \'" .. (info.filename_mp3 or info.filename) .. "\'"
.. (e and (" (" .. e .. ")" or "")))

View File

@@ -18,7 +18,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. --]]
-- To keep in line with the original, tables start their indexing at 0.
-- To keep in line with the original, tables start their indexing at 0.
-- NOTE: This makes index iterations over tables omit the first element!
local configuration = {
@@ -29,12 +29,12 @@ local configuration = {
InterestRate = 0.01,
StartCash = 40000,
},
-- New value, but should only be defined if starting staff is included.
--start_staff = {
-- {Doctor = 0, Shrink = 0, Skill = 0},
--},
-----------------------------------------------------------
-- Original configuration values --
-----------------------------------------------------------
@@ -56,59 +56,59 @@ local configuration = {
20, -- Research
},
-- Divides ability to find an extra salary addition. must be > 0
SalaryAbilityDivisor = 10,
SalaryAbilityDivisor = 10,
-- Divides research input to arrive at research points. must be > 0
ResearchPointsDivisor = 5,
ResearchPointsDivisor = 5,
-- When a drug is researched what rating does it have
StartRating = 100,
StartRating = 100,
-- When a drug is researched how much does it cost
StartCost = 100,
StartCost = 100,
-- Minimum Drug Cost
MinDrugCost = 50,
MinDrugCost = 50,
-- If contagious how much - rand up to this figure. higher = more contagious. must be > 0
HowContagious = 25,
HowContagious = 25,
-- 0-100 Higher equals more chance of spreading.
ContagiousSpreadFactor = 25,
ContagiousSpreadFactor = 25,
-- Reduce cont illnesses until X months have passed
ReduceContMonths = 14,
ReduceContMonths = 14,
-- Reduce cont illnesses until X peep have arrived
ReduceContPeepCount = 20,
ReduceContPeepCount = 20,
-- Rate to reduce cont illneses to - 0 means do not produce contagious illnesses at all
ReduceContRate = 0,
ReduceContRate = 0,
-- Hold all visual illnesses until x months. 0 never hold
HoldVisualMonths = 2,
HoldVisualMonths = 2,
-- Hold all visual illnesses until x peeps have arrived. 0 never hold
HoldVisualPeepCount = 6,
HoldVisualPeepCount = 6,
-- Maximum strength value an object can be improved to (by research)
MaxObjectStrength = 20,
MaxObjectStrength = 20,
-- Increase object strength by this amount when researching
ResearchIncrement = 2,
ResearchIncrement = 2,
-- x Start Score for level = ceiling for normal score increases (2 dp)
ScoreMaxInc = 300,
ScoreMaxInc = 300,
-- Cost per vaccination
VacCost = 50,
VacCost = 50,
-- If epidemic coverup fails - how much per person you are fined max 20000
EpidemicFine = 2000,
-- If an epidemic coverup succeeds how much compensation is received - lo value
EpidemicCompLo = 1000,
EpidemicFine = 2000,
-- If an epidemic coverup succeeds how much compensation is received - lo value
EpidemicCompLo = 1000,
-- If an epidemic coverup succeeds how much compensation is received - hi value max 20000
EpidemicCompHi = 15000,
EpidemicCompHi = 15000,
-- % of research completed for an autopsy
AutopsyRschPercent = 33,
AutopsyRschPercent = 33,
-- % rep hit for discovered autopsy
AutopsyRepHitPercent = 25,
AutopsyRepHitPercent = 25,
-- Frequency of Mayor visits. Lower is more frequent.
MayorLaunch = 150,
MayorLaunch = 150,
-- Add to student doctor's ability when being taught MIN 1 MAX 255
TrainingRate = 40,
TrainingRate = 40,
-- MIN 1 MAX 100 (Percentage)
DrugImproveRate = 5,
DrugImproveRate = 5,
-- How many months until population allocation is done for real
AllocDelay = 3,
AbilityThreshold = {
[0] = {Value = 75}, -- SURGEON
{Value = 60}, -- PSYCHIATRIST
{Value = 60}, -- PSYCHIATRIST
{Value = 45}, -- RESEARCHER
},
TrainingValue = {
@@ -117,15 +117,15 @@ local configuration = {
{Value = 20}, -- Bookcase
},
-- >This value gives doctor
DoctorThreshold = 250,
DoctorThreshold = 250,
-- >This value gives consultant
ConsultantThreshold = 750,
ConsultantThreshold = 750,
-- % of original rsch cost required to improve
RschImproveCostPercent = 10,
RschImproveCostPercent = 10,
-- %-point increase in improve cost per improvement
RschImproveIncrementPercent = 10,
RschImproveIncrementPercent = 10,
},
towns = {
{StartCash = 40000, InterestRate = 100}, -- Level 1
{StartCash = 40000, InterestRate = 200}, -- Level 2
@@ -181,7 +181,7 @@ local configuration = {
{StartPrice = 350, Known = 0, RschReqd = 20000, MaxDiagDiff = 1000}, -- GUT_ROT
{StartPrice = 1600, Known = 0, RschReqd = 20000, MaxDiagDiff = 700}, -- GOLF_STONES
{StartPrice = 500, Known = 0, RschReqd = 20000, MaxDiagDiff = 700}, -- UNEXPECTED_SWELLING
{StartPrice = 300, Known = 0, RschReqd = 40000}, -- I_D_SCANNER
{StartPrice = 300, Known = 0, RschReqd = 40000}, -- I_D_SCANNER
{StartPrice = 250, Known = 0, RschReqd = 50000}, -- I_D_BLOOD_MACHINE DIAGNOSIS
{StartPrice = 150, Known = 0, RschReqd = 20000}, -- I_D_CARDIO DIAGNOSIS
{StartPrice = 200, Known = 0, RschReqd = 30000}, -- I_D_XRAY DIAGNOSIS
@@ -234,7 +234,7 @@ local configuration = {
{StartCost = 200, StartAvail = 1, WhenAvail = 0, StartStrength = 10, AvailableForLevel = 1}, -- 38 Bed Screen Open
{StartCost = 1000, StartAvail = 1, WhenAvail = 0, StartStrength = 10, AvailableForLevel = 1}, -- 39 Pharmacy Cabinet
{StartCost = 5000, StartAvail = 0, WhenAvail = 0, StartStrength = 10, AvailableForLevel = 0}, -- 40 Research Computer
{StartCost = 10000, StartAvail = 0, WhenAvail = 0, StartStrength = 10, AvailableForLevel = 0}, -- 41 Chemical Mixer
{StartCost = 10000, StartAvail = 0, WhenAvail = 0, StartStrength = 10, AvailableForLevel = 0}, -- 41 Chemical Mixer
{StartCost = 3000, StartAvail = 0, WhenAvail = 0, StartStrength = 10, AvailableForLevel = 0}, -- 42 Blood Machine
{StartCost = 25, StartAvail = 1, WhenAvail = 0, StartStrength = 10, AvailableForLevel = 1}, -- 43 Fire Extinguisher
{StartCost = 20, StartAvail = 1, WhenAvail = 0, StartStrength = 10, AvailableForLevel = 1}, -- 44 Radiator
@@ -257,7 +257,7 @@ local configuration = {
{StartCost = 100, StartAvail = 1, WhenAvail = 0, StartStrength = 10, AvailableForLevel = 1}, -- 61 Comfy Chair
},
-- Cost for the room itself without any objects.
-- For some reason it starts at 7,
-- For some reason it starts at 7,
-- but that must be retained in order to work with the original.
rooms = {
[7] = {Cost = 2280}, -- GP_OFFICE
@@ -358,10 +358,10 @@ local configuration = {
},
staff_levels = {
[0] = {Month = 0, Nurses = 8, Doctors = 8, Handymen = 3, Receptionists = 2,
[0] = {Month = 0, Nurses = 8, Doctors = 8, Handymen = 3, Receptionists = 2,
ShrkRate = 10, SurgRate = 10, RschRate = 10, ConsRate = 10, JrRate = 5},
},
emergency_control = {
[0] = {StartMonth = 0, EndMonth = 0, Min = 0, Max = 0, Illness = 0, PercWin = 0, Bonus = 0},
},
@@ -383,28 +383,28 @@ local configuration = {
{Playing = 0}, -- EDVIN
},
awards_trophies = {
-- Trophy win conditions
-- Kill more than this number of rats in a year to win this award
-- MIN 0
RatKillsAbsolute = 25,
-- Sell more than this number of cans to win the award MIN 0
CansofCoke = 100,
CansofCoke = 100,
-- If player's reputation is >x all through the year then win trophy MIN 0 MAX 1000
Reputation = 400,
Reputation = 400,
-- Percentage - keep your plants >x or more watered MIN 0 MAX 100
Plant = 80,
-- Percentage - keep mean staff happiness >x throughout the year to win the trophy
-- Percentage - keep mean staff happiness >x throughout the year to win the trophy
-- MIN 0 MAX 100
TrophyStaffHappiness = 85,
-- Percentage - Rats shot:Rats killed - only valid if player kills at least
-- Percentage - Rats shot:Rats killed - only valid if player kills at least
-- half the number of rats needed to win the other rats trophy
RatKillsPercentage = 11,
-- TODO: this one is hard to understand! percentage of what exactly?
-- Percentage (0-100) low is good needs at 2 mayor visits to be triggered
-- So for now, it is super visits that will trigger this prize
-- Please all of the VIPs that visit your hospital during the year
-- you will have to get a super feedback for each visit
-- Please all of the VIPs that visit your hospital during the year
-- you will have to get a super feedback for each visit
-- TrophyMayor = 25,
-- Trophy win bonuses
@@ -424,14 +424,14 @@ local configuration = {
-- Bonus to money for NO DEATHS in the year (MONEY BONUS)
TrophyDeathBonus = 10000,
-- Bonus to money for approximately 100% Cure Rate in the year (MONEY BONUS)
TrophyCuresBonus = 6000,
TrophyCuresBonus = 6000,
-- Bonus to reputation for pleasing VIPs in the year (REPUTATION BONUS)
TrophyMayorBonus = 5,
TrophyMayorBonus = 5,
------------------- Award win/loss criteria -------------------
-- >x to win the award MIN 0 MAX 255
CuresAward = 50,
-- <x to win this award MIN 0 MAX 255
@@ -479,11 +479,11 @@ local configuration = {
-- Percentages - low is well looked after, high is bad
WellKeptTechAward = 20,
WellKeptTechPoor = 70,
---------------- Award bonuses and penalties --------------------
-- MIN -32000 MAX +32000 - MONEY
CuresBonus = 2000,
-- MIN -32000 MAX +32000 - MONEY

View File

@@ -54,7 +54,7 @@ function CallsDispatcher:callForStaff(room)
anyone_missed = true
for i = 1, count do
self:callForStaffEachRoom(room, attribute, attribute .. i)
end
end
end
local sound = room.room_info.call_sound
if anyone_missed and sound and not room.sound_played then
@@ -91,7 +91,7 @@ end
-- If urgent or manual is specified, lock_room will be true automatically
function CallsDispatcher:callForRepair(object, urgent, manual, lock_room)
lock_room = manual or lock_room
local call = {
verification = --[[persistable:call_dispatcher_repair_verification]] function(staff) return false end,
priority = --[[persistable:call_dispatcher_repair_priority]] function(staff) return 1 end,
@@ -104,7 +104,7 @@ function CallsDispatcher:callForRepair(object, urgent, manual, lock_room)
assigned = nil,
dropped = nil
}
object:setRepairingMode(lock_room and true or false)
local message
local ui = object.world.ui
@@ -112,7 +112,7 @@ function CallsDispatcher:callForRepair(object, urgent, manual, lock_room)
-- Advise about hiring Handyman
message = _A.warnings.machinery_damaged2
end
if not manual and urgent then
local room = object:getRoom();
local sound = room.room_info.handyman_call_sound
@@ -125,7 +125,7 @@ function CallsDispatcher:callForRepair(object, urgent, manual, lock_room)
if message then
ui.adviser:say(message)
end
if not self.call_queue[object] then
self.call_queue[object] = {}
end
@@ -135,9 +135,9 @@ end
function CallsDispatcher:callForWatering(plant)
local call = {
verification = --[[persistable:call_dispatcher_watering_verification]]function(staff)
verification = --[[persistable:call_dispatcher_watering_verification]]function(staff)
return false end,
priority = --[[persistable:call_dispatcher_watering_priority]] function(staff)
priority = --[[persistable:call_dispatcher_watering_priority]] function(staff)
return 1 end,
execute = --[[persistable:call_dispatcher_watering_execute]] function(staff) return CallsDispatcher.sendStaffToWatering(plant, staff) end,
object = plant,
@@ -182,15 +182,15 @@ function CallsDispatcher:enqueue(object, key, description, verification, priorit
end
-- Find suitable (best) staff for working on a specific call
-- True
-- True
function CallsDispatcher:findSuitableStaff(call)
if call.dropped then
if call.dropped then
-- If a call was thought needed to be reinserted, but actually it was dropped...
return
end
end
-- TODO: Preempt staff those even on_call already.
-- Say - when an machine broke down, preempt the nearby handyman for repairing
-- Say - when an machine broke down, preempt the nearby handyman for repairing
-- even if he was going to water a far away plant
-- TODO: Doctor could go to other room with real needs, even there are patients queued up
-- (think of emergency? or surgeons still in GP office?)
@@ -255,8 +255,8 @@ function CallsDispatcher:answerCall(staff)
if min_call then
if debug then self:dump() CallsDispatcher.dumpCall(min_call, 'answered') end
if min_call.assigned then
CallsDispatcher.unassignCall(min_call)
if min_call.assigned then
CallsDispatcher.unassignCall(min_call)
end
-- Check if the object is still in the world, live and not destroy
assert(min_call.object.tile_x or min_call.object.x, "An destroyed object still has requested in the dispatching queue. Please check the Entity:onDestroy function")
@@ -290,19 +290,19 @@ function CallsDispatcher.dumpCall(call, message)
if call.object.x then
position = call.object.x ..','..call.object.y
end
print((call.object.room_info and call.object.room_info.id or call.object.object_type.id) .. '-' .. call.key ..
print((call.object.room_info and call.object.room_info.id or call.object.object_type.id) .. '-' .. call.key ..
'@' .. position .. message)
end
-- Add checkpoint action
-- All call execution method should add this action in apporiate place to signify
-- All call execution method should add this action in apporiate place to signify
-- the job is finished.
-- A interrupt handler could be supplied if special handling is needed.
-- A interrupt handler could be supplied if special handling is needed.
-- If not, the default would be reinsert the call into the queue
function CallsDispatcher.queueCallCheckpointAction(humanoid, interrupt_handler)
return humanoid:queueAction{
name = "call_checkpoint",
call = humanoid.on_call,
name = "call_checkpoint",
call = humanoid.on_call,
on_remove = interrupt_handler or CallsDispatcher.actionInterruptHandler
}
end
@@ -339,7 +339,7 @@ end
-- Drop any call associated with the object (and/or key).
--
-- Expected to be called when the call is no longer needed
-- Expected to be called when the call is no longer needed
-- (like a machine that needed repaired were replaced),
-- or when the object is destroyed, etc.
function CallsDispatcher:dropFromQueue(object, key)
@@ -348,7 +348,7 @@ function CallsDispatcher:dropFromQueue(object, key)
local call = self.call_queue[object][key]
if call then
call.dropped = true
if call.assigned then
if call.assigned then
CallsDispatcher.unassignCall(call)
end
self.call_queue[object][key] = nil
@@ -388,7 +388,7 @@ end
function CallsDispatcher.getPriorityForRoom(room, attribute, staff)
local score = 0;
local x, y = room:getEntranceXY()
-- Doctor prefer serving nearby rooms
local distance = room.world:getPathDistance(staff.tile_x, staff.tile_y, x, y);
if distance then
@@ -419,11 +419,11 @@ end
function CallsDispatcher.sendStaffToRoom(room, staff)
if staff:getRoom() == room then
room:onHumanoidLeave(staff)
CallsDispatcher.queueCallCheckpointAction(staff, CallsDispatcher.staffActionInterruptHandler)
CallsDispatcher.queueCallCheckpointAction(staff, CallsDispatcher.staffActionInterruptHandler)
room:onHumanoidEnter(staff)
else
staff:setNextAction(room:createEnterAction(staff))
CallsDispatcher.queueCallCheckpointAction(staff, CallsDispatcher.staffActionInterruptHandler)
CallsDispatcher.queueCallCheckpointAction(staff, CallsDispatcher.staffActionInterruptHandler)
end
staff:setDynamicInfoText(_S.dynamic_info.staff.actions.heading_for:format(room.room_info.name))
end

View File

@@ -61,7 +61,7 @@ local function define_class(name, super, adopts_self)
local mt = {}
local methods = {}
local methods_mt = {}
local function new_class(methods, ...)
local constructor = methods[name]
local self
@@ -74,7 +74,7 @@ local function define_class(name, super, adopts_self)
end
return self
end
mt.__index = methods
setmetatable(methods, methods_mt)
if super ~= nil then
@@ -82,7 +82,7 @@ local function define_class(name, super, adopts_self)
end
methods_mt.__call = new_class
methods_mt.__class_name = name
_G[name] = methods
end
@@ -91,7 +91,7 @@ class = destrict(function(_, name)
define_class(name)
local adopts_self = false
local super = nil
local function extend(arg)
if type(arg) == "table" and next(arg) == nil and not getmetatable(arg) then
-- {} decorator

View File

@@ -1,26 +1,26 @@
--[[ Copyright (c) 2013 Alan Woolley
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. --]]
class "Command"
function Command:Command(can_undo)
self.can_undo = can_undo
end
--[[ Copyright (c) 2013 Alan Woolley
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. --]]
class "Command"
function Command:Command(can_undo)
self.can_undo = can_undo
end

View File

@@ -1,58 +1,58 @@
--[[ Copyright (c) 2013 Alan Woolley
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. --]]
class "CommandStack"
function CommandStack:CommandStack()
self.undo_stack = {}
self.redo_stack = {}
end
function CommandStack:redo()
if (#self.redo_stack == 0) then
print "Nothing left to redo!"
return
end
local cmd = self.redo_stack[#self.redo_stack]
table.remove(self.redo_stack, #self.redo_stack)
table.insert(self.undo_stack, #self.undo_stack + 1, cmd)
cmd:perform()
return #self.redo_stack == 0
end
function CommandStack:undo()
if (#self.undo_stack == 0) then
print "Nothing left to undo!"
return
end
local cmd = self.undo_stack[#self.undo_stack]
table.remove(self.undo_stack, #self.undo_stack)
table.insert(self.redo_stack, #self.redo_stack + 1, cmd)
cmd:undo()
return #self.undo_stack == 0
end
function CommandStack:add(cmd)
if not cmd.can_undo then
self.undo_stack = {}
end
self.redo_stack = {}
table.insert(self.undo_stack, #self.undo_stack + 1, cmd)
end
--[[ Copyright (c) 2013 Alan Woolley
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. --]]
class "CommandStack"
function CommandStack:CommandStack()
self.undo_stack = {}
self.redo_stack = {}
end
function CommandStack:redo()
if (#self.redo_stack == 0) then
print "Nothing left to redo!"
return
end
local cmd = self.redo_stack[#self.redo_stack]
table.remove(self.redo_stack, #self.redo_stack)
table.insert(self.undo_stack, #self.undo_stack + 1, cmd)
cmd:perform()
return #self.redo_stack == 0
end
function CommandStack:undo()
if (#self.undo_stack == 0) then
print "Nothing left to undo!"
return
end
local cmd = self.undo_stack[#self.undo_stack]
table.remove(self.undo_stack, #self.undo_stack)
table.insert(self.redo_stack, #self.redo_stack + 1, cmd)
cmd:undo()
return #self.undo_stack == 0
end
function CommandStack:add(cmd)
if not cmd.can_undo then
self.undo_stack = {}
end
self.redo_stack = {}
table.insert(self.undo_stack, #self.undo_stack + 1, cmd)
end

View File

@@ -1,45 +1,45 @@
--[[ Copyright (c) 2013 Alan Woolley
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. --]]
class "CompoundCommand" (Command)
function CompoundCommand:CompoundCommand()
self:Command(true)
self.command_list = {}
end
function CompoundCommand:addCommand(cmd)
table.insert(self.command_list, #self.command_list + 1, cmd)
end
function CompoundCommand:perform()
for i = 1 , #self.command_list do
local cmd = self.command_list[i]
cmd:perform()
end
end
function CompoundCommand:undo()
for i = #self.command_list, 1, -1 do
local cmd = self.command_list[i]
cmd:undo()
end
end
--[[ Copyright (c) 2013 Alan Woolley
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. --]]
class "CompoundCommand" (Command)
function CompoundCommand:CompoundCommand()
self:Command(true)
self.command_list = {}
end
function CompoundCommand:addCommand(cmd)
table.insert(self.command_list, #self.command_list + 1, cmd)
end
function CompoundCommand:perform()
for i = 1 , #self.command_list do
local cmd = self.command_list[i]
cmd:perform()
end
end
function CompoundCommand:undo()
for i = #self.command_list, 1, -1 do
local cmd = self.command_list[i]
cmd:undo()
end
end

View File

@@ -1,47 +1,47 @@
--[[ Copyright (c) 2013 Alan Woolley
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. --]]
class "SetMapCellCommand" (Command)
function SetMapCellCommand:SetMapCellCommand(map)
self:Command(true)
self.map = map
self.paint_list = {}
end
function SetMapCellCommand:addTile(x_tile, y_tile, ...)
local old = {self.map:getCell(x_tile, y_tile)}
table.insert(self.paint_list, #self.paint_list + 1, {x = x_tile, y = y_tile, new_flags = {...}, old_flags = old})
end
function SetMapCellCommand:perform()
for i = 1 , #self.paint_list do
local cell_table = self.paint_list[i]
self.map:setCell(cell_table.x, cell_table.y, unpack(cell_table.new_flags))
end
end
function SetMapCellCommand:undo()
for i = #self.paint_list, 1, -1 do
local cell_table = self.paint_list[i]
self.map:setCell(cell_table.x, cell_table.y, unpack(cell_table.old_flags))
end
end
--[[ Copyright (c) 2013 Alan Woolley
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. --]]
class "SetMapCellCommand" (Command)
function SetMapCellCommand:SetMapCellCommand(map)
self:Command(true)
self.map = map
self.paint_list = {}
end
function SetMapCellCommand:addTile(x_tile, y_tile, ...)
local old = {self.map:getCell(x_tile, y_tile)}
table.insert(self.paint_list, #self.paint_list + 1, {x = x_tile, y = y_tile, new_flags = {...}, old_flags = old})
end
function SetMapCellCommand:perform()
for i = 1 , #self.paint_list do
local cell_table = self.paint_list[i]
self.map:setCell(cell_table.x, cell_table.y, unpack(cell_table.new_flags))
end
end
function SetMapCellCommand:undo()
for i = #self.paint_list, 1, -1 do
local cell_table = self.paint_list[i]
self.map:setCell(cell_table.x, cell_table.y, unpack(cell_table.old_flags))
end
end

View File

@@ -1,46 +1,46 @@
--[[ Copyright (c) 2013 Alan Woolley
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. --]]
class "SetMapCellFlagsCommand" (Command)
function SetMapCellFlagsCommand:SetMapCellFlagsCommand(map)
self:Command(true)
self.map = map
self.paint_list = {}
end
function SetMapCellFlagsCommand:addTile(x_tile, y_tile, ...)
local old = {self.map:getCellFlags(x_tile, y_tile)}
table.insert(self.paint_list, #self.paint_list + 1, {x = x_tile, y = y_tile, new_flags = {...}, old_flags = old})
end
function SetMapCellFlagsCommand:perform()
for i = 1 , #self.paint_list do
local cell_table = self.paint_list[i]
self.map:setCellFlags(cell_table.x, cell_table.y, unpack(cell_table.new_flags))
end
end
function SetMapCellFlagsCommand:undo()
for i = #self.paint_list, 1, -1 do
local cell_table = self.paint_list[i]
self.map:setCellFlags(cell_table.x, cell_table.y, unpack(cell_table.old_flags))
end
end
--[[ Copyright (c) 2013 Alan Woolley
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. --]]
class "SetMapCellFlagsCommand" (Command)
function SetMapCellFlagsCommand:SetMapCellFlagsCommand(map)
self:Command(true)
self.map = map
self.paint_list = {}
end
function SetMapCellFlagsCommand:addTile(x_tile, y_tile, ...)
local old = {self.map:getCellFlags(x_tile, y_tile)}
table.insert(self.paint_list, #self.paint_list + 1, {x = x_tile, y = y_tile, new_flags = {...}, old_flags = old})
end
function SetMapCellFlagsCommand:perform()
for i = 1 , #self.paint_list do
local cell_table = self.paint_list[i]
self.map:setCellFlags(cell_table.x, cell_table.y, unpack(cell_table.new_flags))
end
end
function SetMapCellFlagsCommand:undo()
for i = #self.paint_list, 1, -1 do
local cell_table = self.paint_list[i]
self.map:setCellFlags(cell_table.x, cell_table.y, unpack(cell_table.old_flags))
end
end

View File

@@ -93,32 +93,32 @@ local config_defaults = {
width = 800,
height = 600,
language = [[English]],
audio = true,
audio = true,
free_build_mode = false,
play_sounds = true,
sound_volume = 0.5,
play_sounds = true,
sound_volume = 0.5,
play_announcements = true,
announcement_volume = 0.5,
announcement_volume = 0.5,
play_music = true,
music_volume = 0.5,
prevent_edge_scrolling = false,
adviser_disabled = false,
scrolling_momentum = 0.8,
twentyfour_hour_clock = true,
music_volume = 0.5,
prevent_edge_scrolling = false,
adviser_disabled = false,
scrolling_momentum = 0.8,
twentyfour_hour_clock = true,
warmth_colors_display_default = 1,
grant_wage_increase = false,
grant_wage_increase = false,
movies = true,
play_intro = true,
allow_user_actions_while_paused = false,
volume_opens_casebook = false,
volume_opens_casebook = false,
alien_dna_only_by_emergency = true,
alien_dna_must_stand = true,
alien_dna_can_knock_on_doors = false,
disable_fractured_bones_females = true,
enable_avg_contents = false,
enable_avg_contents = false,
audio_frequency = 22050,
audio_channels = 2,
audio_buffer_size = 2048,
audio_buffer_size = 2048,
theme_hospital_install = [[F:\ThemeHospital\hospital]],
debug = false,
track_fps = false,
@@ -144,7 +144,7 @@ if fi then
needs_rewrite = true
else
ind = ind + (string.find(file_contents, key, ind) - ind) + string.len(key)
ind = string.find(file_contents, "=", ind) + 1
ind = string.find(file_contents, "=", ind) + 1
if type(value) ~= "string" then
ind = string.find(file_contents, "[%a%d]", ind)
config_values[key] = string.sub(file_contents, ind, string.find(file_contents, "[ \n-]", ind + 1) - 1)
@@ -153,19 +153,19 @@ if fi then
config_values[key] = string.sub(file_contents, ind + 1, string.find(file_contents, "]", ind, true) - 1)
end
end
end
end
else
needs_rewrite = true
end
if needs_rewrite then
fi = io.open(config_filename, "w")
if fi then
if fi then
fi:write([=[
----------------------------------------- CorsixTH configuration file -------------------------------------------
-- Lines starting with two dashes (like this one) are ignored.
-- Text settings should have their values between double square braces, e.g.
-- setting = [[value]]
-- Number settings should not have anything around their value,
-- Number settings should not have anything around their value,
-- e.g. setting = 42
--
-------------------------------------------- SETTINGS MENU ---------------------------------------------
@@ -175,10 +175,10 @@ if needs_rewrite then
-- hardware in order to maintain a playable framerate. The fullscreen setting
-- can be true or false, and the game will run windowed if not fullscreen.
--
fullscreen = ]=].. tostring(config_values.fullscreen) ..[=[
width = ]=].. tostring(config_values.width) ..[=[
height = ]=].. tostring(config_values.height) ..[=[
fullscreen = ]=].. tostring(config_values.fullscreen) ..[=[
width = ]=].. tostring(config_values.width) ..[=[
height = ]=].. tostring(config_values.height) ..[=[
-------------------------------------------------------------------------------------------------------------------------
-- Language to use for ingame text. Between the square braces should be one of:
@@ -198,77 +198,77 @@ height = ]=].. tostring(config_values.height) ..[=[
-- Swedish / sv / swe
--
language = [[]=].. config_values.language ..[=[]]
-------------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------------
-- Audio global on/off switch.
-- Note that audio will also be disabled if CorsixTH was compiled without the
-- SDL_mixer library.
audio = ]=].. tostring(config_values.audio) ..[=[
audio = ]=].. tostring(config_values.audio) ..[=[
--------------------------------------------- CUSTOM GAME MENU ----------------------------------------------
-- These settings can also be changed from the opening menu screen in the custom games menu
-------------------------------------------------------------------------------------------------------------------------
-- Free Build or Sandbox mode
-- You cannot win or lose custom made maps if this is set to true.
-- You cannot win or lose custom made maps if this is set to true.
-- You also don't have to worry about money.
-- This setting does not apply to any of the campaign maps.
--
free_build_mode = ]=].. tostring(config_values.free_build_mode) ..[=[
----------------------------------------------- OPTIONS MENU ---------------------------------------------------
--These settings can also be changed from within the game from the options menu
-------------------------------------------------------------------------------------------------------------------------
-- Sounds: By default enabled and set at level 0.5
play_sounds = ]=].. tostring(config_values.play_sounds) ..[=[
sound_volume = ]=].. tostring(config_values.sound_volume) ..[=[
play_sounds = ]=].. tostring(config_values.play_sounds) ..[=[
sound_volume = ]=].. tostring(config_values.sound_volume) ..[=[
-------------------------------------------------------------------------------------------------------------------------
-- Announcements: By default set at level 0.5
play_announcements = ]=].. tostring(config_values.play_announcements) ..[=[
announcement_volume = ]=].. tostring(config_values.announcement_volume) ..[=[
play_announcements = ]=].. tostring(config_values.play_announcements) ..[=[
announcement_volume = ]=].. tostring(config_values.announcement_volume) ..[=[
-------------------------------------------------------------------------------------------------------------------------
-- Background music: By default enabled and set at level 0.5
--
play_music = ]=].. tostring(config_values.play_music) ..[=[
music_volume = ]=].. tostring(config_values.music_volume) ..[=[
play_music = ]=].. tostring(config_values.play_music) ..[=[
music_volume = ]=].. tostring(config_values.music_volume) ..[=[
-------------------------------------------------------------------------------------------------------------------------
-- Edge scrolling: By default enabled (prevent_edge_scrolling = false).
--
prevent_edge_scrolling = ]=].. tostring(config_values.prevent_edge_scrolling) ..[=[
prevent_edge_scrolling = ]=].. tostring(config_values.prevent_edge_scrolling) ..[=[
-------------------------------------------------------------------------------------------------------------------------
-- Adviser on/off: If you set this to true the adviser will no longer
-- pop up.
--
adviser_disabled = ]=].. tostring(config_values.adviser_disabled) ..[=[
adviser_disabled = ]=].. tostring(config_values.adviser_disabled) ..[=[
-------------------------------------------------------------------------------------------------------------------------
-- Scrolling Momentum.
-- Determines the amount of momentum when scrolling the map with the mouse.
-- This should be a value between 0 and 1 where 0 is no momentum
scrolling_momentum = ]=] .. tostring(config_values.scrolling_momentum) .. [=[
-------------------------------------------------------------------------------------------------------------------------
-- Top menu clock is by default is always on
-- setting to true will give you a twentyfour hours display
-- change to false if you want AM / PM time displayed.
--
twentyfour_hour_clock = ]=].. tostring(config_values.twentyfour_hour_clock) ..[=[
twentyfour_hour_clock = ]=].. tostring(config_values.twentyfour_hour_clock) ..[=[
-------------------------------------------------------------------------------------------------------------------------
-- Automatically check for updates.
-- If set to true, CorsixTH will automatically check for and alert you to newer
-- versions on startup.
check_for_updates = ]=].. tostring(config_values.check_for_updates) ..[=[
check_for_updates = ]=].. tostring(config_values.check_for_updates) ..[=[
-------------------------------------------------------------------------------------------------------------------------
-- Warmth Colors display settings.
-- This specifies which display method is set for warmth colours by default.
-- This specifies which display method is set for warmth colours by default.
-- Possible values: 1 (Red), 2 (Blue Green Red) and 3 (Yellow Orange Red).
--
warmth_colors_display_default = ]=].. tostring(config_values.warmth_colors_display_default) ..[=[
warmth_colors_display_default = ]=].. tostring(config_values.warmth_colors_display_default) ..[=[
--------------------------------------------- CUSTOMISE SETTINGS --------------------------------------------
-- These settings can also be changed from the Customise Menu
@@ -283,52 +283,52 @@ grant_wage_increase = ]=].. tostring(config_values.grant_wage_increase) ..[=[
-- Movie global on/off switch.
-- Note that movies will also be disabled if CorsixTH was compiled without the
-- FFMPEG library.
movies = ]=].. tostring(config_values.movies) ..[=[
movies = ]=].. tostring(config_values.movies) ..[=[
-- Intro movie: By default enabled
play_intro = ]=].. tostring(config_values.play_intro) ..[=[
play_intro = ]=].. tostring(config_values.play_intro) ..[=[
-------------------------------------------------------------------------------------------------------------------------
-- Allow user actions while game is paused
-- In Theme Hospital the player would only be allowed to use the top menu if
-- the game was paused. That is the default setting in CorsixTH too, but by
-- setting this to true everything is allowed while the game is paused.
allow_user_actions_while_paused = ]=].. tostring(config_defaults.allow_user_actions_while_paused) ..[=[
-------------------------------------------------------------------------------------------------------------------------
-- VOLUME CONTROL IS OPENING THE DRUG CASEBOOK?
-- If your keyboard volume control opens the Drug Casebook at the same time
-- then change this to true. From then on you will have to use Shift + C to open
-- the Casebook and volume down will not open it.
-- For example for shift + C to open casebook change the setting below to = true
volume_opens_casebook = ]=] .. tostring(config_values.volume_opens_casebook) .. [=[
-------------------------------------------------------------------------------------------------------------------------
-- To allow patients with Alien DNA to visit your hospital other than by an emergency change
-- the settings below. Understand that there are no animations for sitting down, opening
-- the settings below. Understand that there are no animations for sitting down, opening
-- or knocking on doors etc.
-- So, like with Theme Hospital to do these things they will appear to change to normal
-- looking and then change back.
--
alien_dna_only_by_emergency = ]=].. tostring(config_values.alien_dna_only_by_emergency) ..[=[
alien_dna_must_stand = ]=].. tostring(config_values.alien_dna_must_stand) ..[=[
alien_dna_can_knock_on_doors = ]=].. tostring(config_values.alien_dna_can_knock_on_doors) ..[=[
alien_dna_only_by_emergency = ]=].. tostring(config_values.alien_dna_only_by_emergency) ..[=[
alien_dna_must_stand = ]=].. tostring(config_values.alien_dna_must_stand) ..[=[
alien_dna_can_knock_on_doors = ]=].. tostring(config_values.alien_dna_can_knock_on_doors) ..[=[
-- To allow female patients with fractured bones, which are by default disabled due to poor
-- animation that skips and jumps a bit
disable_fractured_bones_females = ]=].. tostring(config_values.disable_fractured_bones_females) ..[=[
disable_fractured_bones_females = ]=].. tostring(config_values.disable_fractured_bones_females) ..[=[
--
-------------------------------------------------------------------------------------------------------------------------
-- By default the player selects any extra objects they want for each room they build.
-- If you would like the game to remember what you usually add, then change this option to true.
enable_avg_contents = ]=].. tostring(config_values.enable_avg_contents) ..[=[
enable_avg_contents = ]=].. tostring(config_values.enable_avg_contents) ..[=[
--
----------------------------------------------- FOLDER SETTINGS ----------------------------------------------
@@ -342,14 +342,14 @@ enable_avg_contents = ]=].. tostring(config_values.enable_avg_contents) ..[=[
-- preferred.
--
theme_hospital_install = [[]=].. config_values.theme_hospital_install ..[=[]]
-------------------------------------------------------------------------------------------------------------------------
-- Font file setting. Can be changed from main game menu
-- Specify a font file here if you wish to play the game in a language not
-- present in the original game. Examples include Russian, Chinese and Polish.
--
unicode_font = nil -- [[X:\ThemeHospital\font.ttc]]
unicode_font = nil -- [[X:\ThemeHospital\font.ttc]]
-------------------------------------------------------------------------------------------------------------------------
-- Savegames. By default, the "Saves" directory alongside this config file will
-- be used for storing saved games in. Should this not be suitable, then
@@ -370,14 +370,14 @@ use_new_graphics = false
-- uncomment the following line and point it to the directory which contains the new
-- graphics.
new_graphics_folder = nil -- [[X:\ThemeHospital\Graphics]]
-------------------------------------------------------------------------------------------------------------------------
-- Screenshots. By default, the "Screenshots" directory alongside this config
-- file will be used for saving screenshots. Should this not be suitable, then
-- uncomment the following line, and point it to a directory which exists and
-- is more suitable.
screenshots = nil -- [[X:\ThemeHospital\Screenshots]]
-------------------------------------------------------------------------------------------------------------------------
-- High quality (MP3 rather than MIDI) audio replacements.
-- If you want to listen to high quality MP3 audio rather than the original XMI
@@ -386,12 +386,12 @@ screenshots = nil -- [[X:\ThemeHospital\Screenshots]]
-- from http://www.a-base.dds.nl/temp/ThemeHospital_ZRRemix.zip ) or any
-- other music you want to listen to.
-- 2) Ensure that SMPEG.dll (or equivalent for your platform) is present.
-- 3) Uncomment the next line and point it to where the mp3s are.
-- 4) If you want to change the names of songs ingame, make a file called
-- 3) Uncomment the next line and point it to where the mp3s are.
-- 4) If you want to change the names of songs ingame, make a file called
-- "names.txt" and write the file name on one row, followed by the desired
-- ingame name on the next row.
audio_mp3 = nil -- [[X:\ThemeHospital\Music]]
----------------------------------------------- SPECIAL SETTINGS ----------------------------------------------
-- These settings can only be changed here
-------------------------------------------------------------------------------------------------------------------------
@@ -400,43 +400,43 @@ audio_mp3 = nil -- [[X:\ThemeHospital\Music]]
-- Note: On some platforms, these settings may not effect MIDI playback - only
-- sound effects and MP3 audio. If you are experiencing poor audio playback,
-- then try doubling the buffer size.
audio_frequency = ]=].. tostring(config_values.audio_frequency) ..[=[
audio_channels = ]=].. tostring(config_values.audio_channels) ..[=[
audio_buffer_size = ]=].. tostring(config_values.audio_buffer_size) ..[=[
audio_frequency = ]=].. tostring(config_values.audio_frequency) ..[=[
audio_channels = ]=].. tostring(config_values.audio_channels) ..[=[
audio_buffer_size = ]=].. tostring(config_values.audio_buffer_size) ..[=[
------------------------------------------------------------------------------------------------------------------------
-- Debug settings.
-- If set to true more detailed information will be printed in the terminal
-- and a debug menu will be visible.
debug = ]=].. tostring(config_values.debug) ..[=[
debug = ]=].. tostring(config_values.debug) ..[=[
-- If set to true, the FPS, Lua memory usage, and entity count will be shown
-- in the dynamic information bar. Note that setting this to true also turns
-- off the FPS limiter, causing much higher CPU utilisation, but resulting in
-- more useful FPS values, as they are not artificially capped.
track_fps = ]=].. tostring(config_values.track_fps) ..[=[
track_fps = ]=].. tostring(config_values.track_fps) ..[=[
--
-------------------------------------------------------------------------------------------------------------------------
-- Zoom Speed: By default this is set at 80
-- Any number value between 10 and 1000, 10 is very slow and 1000 is very fast!
--
zoom_speed = ]=].. tostring(config_values.zoom_speed) ..[=[
zoom_speed = ]=].. tostring(config_values.zoom_speed) ..[=[
--
-------------------------------------------------------------------------------------------------------------------------
-- Scroll Speed: By default this is set at level 2
-- Any number value between 1 and 10, 1 is very slow and 10 is fast!
-- Press shift when you are scrolling and it will be a lot quicker
--
scroll_speed = ]=].. tostring(config_values.scroll_speed) ..[=[
scroll_speed = ]=].. tostring(config_values.scroll_speed) ..[=[
--
------------------------------------------------ CAMPAIGN MENU -----------------------------------------------
-- By default your computer log in will be your name in the game. You can change it in the
-- By default your computer log in will be your name in the game. You can change it in the
-- campaign menu or between the brace brackets below [[YOUR NAME]].
-- Note: space is limited in the game, so don't enter a name that is too long!
--
-- If you have specified any other locations for things like saves, music or screenshots you will find these below. If
-- If you have specified any other locations for things like saves, music or screenshots you will find these below. If
-- you change your mind and wish to go back to the default folders, just delete the relevant line.
--
--
-- If you wish to go back to the default settings for everything, you can delete this text file and it will be re-created
-- you play the game.
-------------------------------------------------------------------------------------------------------------------------

View File

@@ -25,9 +25,9 @@ class "UIAdviser" (Window)
function UIAdviser:UIAdviser(ui)
self:Window()
local app = ui.app
self.esc_closes = false
self.modal_class = "adviser"
self.tick_rate = app.world.tick_rate
@@ -50,7 +50,7 @@ function UIAdviser:UIAdviser(ui)
self.balloon_width = 0
self.panel_sprites = app.gfx:loadSpriteTable("Data", "Panel02V", true)
self.black_font = app.gfx:loadFont("QData", "Font50V")
local th = TH.animation()
self.th = th
end
@@ -85,7 +85,7 @@ function UIAdviser:talk()
self.stay_up = self.queued_messages[best].stay_up
table.remove(self.queued_messages, best)
self.speech = speech
-- Calculate number of lines needed for the text.
-- Calculate number of lines needed for the text.
-- Each "/" at end of string indicates a blank line
local number_lines = 3
local speech_trimmed = speech:gsub("/*$", "")
@@ -126,7 +126,7 @@ end
--!param speech The table containing the text he should say and the priority.
--!param talk_until_next_announce Whether he should stay up
-- until the next say() call is made. Useful for the tutorial.
--!param override_current Cancels previous messages (if any) immediately
--!param override_current Cancels previous messages (if any) immediately
-- and shows this new one instead.
function UIAdviser:say(speech, talk_until_next_announce, override_current)
assert(type(speech) == "table")
@@ -162,7 +162,7 @@ end
function UIAdviser:draw(canvas, x, y)
Window.draw(self, canvas, x, y)
x, y = x + self.x, y + self.y
self.th:draw(canvas, x + 200, y)
if self.phase == 2 then
@@ -186,7 +186,7 @@ function UIAdviser:onMouseDown(button, x, y)
end
-- Normal operation outside the adviser bounds
if x + self.balloon_width < 128 or x > 200 or y + self.y > 0 or y + self.y + 40 < 0 then
if x < self.x - 200 or y < self.y - 40 or x > self.x - 200 + self.width
if x < self.x - 200 or y < self.y - 40 or x > self.x - 200 + self.width
or y > self.y + self.height - 40 then
return Window.onMouseDown(self, button, x, y)
end
@@ -228,7 +228,7 @@ function UIAdviser:onTick()
-- Adviser is now up, let him speak.
self:talk()
elseif self.phase == 2 then
-- Adviser finished to talk so make him idle unless
-- Adviser finished to talk so make him idle unless
-- there's another message waiting.
if #self.queued_messages > 0 then
-- Show the next queued message
@@ -238,7 +238,7 @@ function UIAdviser:onTick()
self:idle()
end
elseif self.phase == 4 then
-- The adviser is getting down so we want to hide him, but we have
-- The adviser is getting down so we want to hide him, but we have
-- to wait until the animation ends.
if self.up_again then
-- Another message arrived while getting down.

View File

@@ -23,7 +23,7 @@ class "UIBottomPanel" (Window)
function UIBottomPanel:UIBottomPanel(ui)
self:Window()
local app = ui.app
self.ui = ui
@@ -37,17 +37,17 @@ function UIBottomPanel:UIBottomPanel(ui)
self.date_font = app.gfx:loadFont("QData", "Font16V")
self.white_font = app.gfx:loadFont("QData", "Font01V", 0, -2)
self.pause_font = app.gfx:loadFont("QData", "Font124V")
-- State relating to fax notification messages
self.show_animation = true
self.factory_counter = 22
self.factory_direction = 0
self.message_windows = {}
self.message_queue = {}
self.default_button_sound = "selectx.wav"
self.countdown = 0
self.bank_button = self:addPanel( 1, 0, 0):makeToggleButton(6, 6, 35, 36, 2, self.dialogBankManager, nil, self.dialogBankStats):setTooltip(_S.tooltip.toolbar.bank_button)
self:addPanel( 3, 40, 0) -- Background for balance, rep and date
self:addPanel( 4, 206, 0):makeButton(6, 6, 35, 36, 5, self.dialogBuildRoom):setTooltip(_S.tooltip.toolbar.rooms)
@@ -61,11 +61,11 @@ function UIBottomPanel:UIBottomPanel(ui)
self:addPanel(13, x, 0)
end
self:addPanel(14, 627, 0)
-- Buttons that are shown instead of the dynamic info bar when hovering over it.
local panels = {}
local buttons = {}
panels[1] = self:addPanel(15, 364, 0) -- Staff management button
buttons[1] = panels[1]:makeToggleButton(6, 6, 35, 36, 16, self.dialogStaffManagement):setTooltip(_S.tooltip.toolbar.staff_list)
panels[2] = self:addPanel(17, 407, 0) -- Town map button
@@ -86,7 +86,7 @@ function UIBottomPanel:UIBottomPanel(ui)
end
self.additional_panels = panels
self.additional_buttons = buttons
self:makeTooltip(_S.tooltip.toolbar.balance, 41, 5, 137, 28)
self:makeTooltip(_S.tooltip.toolbar.date, 140, 5, 200, 42)
self:makeDynamicTooltip(--[[persistable:reputation_tooltip]] function()
@@ -103,7 +103,7 @@ function UIBottomPanel:UIBottomPanel(ui)
ui:addKeyHandler("F7", buttons[5], buttons[5].handleClick, "left") -- status
ui:addKeyHandler("F8", buttons[6], buttons[6].handleClick, "left") -- charts
ui:addKeyHandler("F9", buttons[7], buttons[7].handleClick, "left") -- policy
-- "old" keyboard shortcuts for some of the fullscreen windows
ui:addKeyHandler("T", buttons[2], buttons[2].handleClick, "left") -- T for town map
ui:addKeyHandler("R", buttons[4], buttons[4].handleClick, "left") -- R for research
@@ -112,14 +112,14 @@ function UIBottomPanel:UIBottomPanel(ui)
ui:addKeyHandler("C", buttons[3], buttons[3].handleClick, "left") -- C for casebook
else
ui:addKeyHandler({"shift", "C"}, buttons[3], buttons[3].handleClick, "left") -- Shift + C for casebook
end
end
ui:addKeyHandler({"shift", "L"}, self, self.openLoad) -- Shift + L for Load saved game menu
ui:addKeyHandler({"shift", "S"}, self, self.openSave) -- Shift + S for Load create save menu
ui:addKeyHandler({"shift", "R"}, self, self.restart) -- Shift + R for restart the level
ui:addKeyHandler({"shift", "Q"}, self, self.quit) -- Shift + Q quit the game and return to main menu
ui:addKeyHandler({"shift", "alt", "S"}, self, self.quickSave) -- Shift+Alt+S quick save
ui:addKeyHandler({"shift", "alt", "L"}, self, self.quickLoad) -- Shift+Alt+L load last quick save
ui:addKeyHandler({"shift", "alt", "L"}, self, self.quickLoad) -- Shift+Alt+L load last quick save
-- misc. keyhandlers
ui:addKeyHandler("M", self, self.openFirstMessage) -- M for message
ui:addKeyHandler("I", self, self.toggleInformation) -- I for Information when you first build
@@ -132,11 +132,11 @@ end
function UIBottomPanel:openSave()
self.ui:addWindow(UISaveGame(self.ui))
end
end
function UIBottomPanel:openLoad()
self.ui:addWindow(UILoadGame(self.ui, "game"))
end
end
function UIBottomPanel:quickSave()
self.ui.app:quickSave()
@@ -144,14 +144,14 @@ end
function UIBottomPanel:quickLoad()
self.ui.app:quickLoad()
end
end
function UIBottomPanel:restart()
self.ui.app:restart()
end
end
function UIBottomPanel:quit()
self.ui:quit()
self.ui:quit()
end
function UIBottomPanel:draw(canvas, x, y)
@@ -161,28 +161,28 @@ function UIBottomPanel:draw(canvas, x, y)
self.money_font:draw(canvas, ("%7i"):format(self.ui.hospital.balance), x + 44, y + 9)
local month, day = self.world:getDate()
self.date_font:draw(canvas, _S.date_format.daymonth:format(day, month), x + 140, y + 20, 60, 0)
-- Draw possible information in the dynamic info bar
if not self.additional_panels[1].visible then
self:drawDynamicInfo(canvas, x + 364, y)
end
if self.show_animation then
if self.factory_counter >= 1 then
self.panel_sprites:draw(canvas, 40, x + 177, y + 1)
end
if self.factory_counter > 1 and self.factory_counter <= 22 then
for dx = 0, self.factory_counter do
self.panel_sprites:draw(canvas, 41, x + 179 + dx, y + 1)
end
end
if self.factory_counter == 22 then
self.panel_sprites:draw(canvas, 42, x + 201, y + 1)
end
end
self:drawReputationMeter(canvas, x + 55, y + 35)
end
@@ -314,7 +314,7 @@ end
-- first performing the necessary animation.
function UIBottomPanel:showMessage()
if self.factory_direction ~= -1 then
self.factory_direction = -1
self.factory_direction = -1
if self.factory_counter < 0 then
-- Factory is already opened so don't wait to show the message
self.show_animation = false
@@ -372,7 +372,7 @@ function UIBottomPanel:createMessageWindow(index)
end
table.remove(self.message_windows, index_to_remove)
end
if not index then
index = 1
end
@@ -413,7 +413,7 @@ function UIBottomPanel:onTick()
self.factory_counter = self.factory_counter - 1
end
end
-- The dynamic info bar is there a while longer when hovering an entity has stopped
if self.countdown then
if self.countdown < 1 then
@@ -432,12 +432,12 @@ function UIBottomPanel:onTick()
self.countdown = self.countdown - 1
end
end
-- Move an item out of the message queue if there is room
if #self.message_windows < 5 and #self.message_queue > 0 then
self:showMessage()
end
Window.onTick(self)
end
@@ -454,7 +454,7 @@ function UIBottomPanel:dialogBankCommon(enable, stats)
self:updateButtonStates()
return
end
if enable then
self:addDialog("UIBankManager", stats and "showStatistics")
else
@@ -723,7 +723,7 @@ function UIBottomPanel:afterLoad(old, new)
self.additional_buttons[i] = self.buttons[5 + i]:makeToggle() -- made them toggle buttons
end
self.bank_button = self.buttons[1]:makeToggle()
-- keyboard shortcuts have been added/changed
self.ui:addKeyHandler("F1", self.bank_button, self.bank_button.handleClick, "left") -- bank manager
self.ui:addKeyHandler("F2", self.bank_button, self.bank_button.handleClick, "right") -- bank manager
@@ -757,13 +757,13 @@ function UIBottomPanel:afterLoad(old, new)
self.ui:addKeyHandler("J", self, self.openJukebox) -- open the jukebox
self.ui:addKeyHandler({"shift", "L"}, self, self.openLoad) -- Shift + L for Load saved game menu
self.ui:addKeyHandler({"shift", "S"}, self, self.openSave) -- Shift + S for Load create save menu
self.ui:addKeyHandler({"shift", "R"}, self, self.restart) -- Shift + R for restart the level
self.ui:addKeyHandler({"shift", "Q"}, self, self.quit) -- Shift + Q quit the game and return to main menu
end
self.ui:addKeyHandler({"shift", "R"}, self, self.restart) -- Shift + R for restart the level
self.ui:addKeyHandler({"shift", "Q"}, self, self.quit) -- Shift + Q quit the game and return to main menu
end
if old < 82 then
self.ui:addKeyHandler({"shift","alt", "S"}, self, self.quickSave) -- Shift+Alt+S quick save
self.ui:addKeyHandler({"shift","alt", "L"}, self, self.quickLoad) -- Shift+Alt+L load last quick save
end
end
Window.afterLoad(self, old, new)
end

View File

@@ -24,7 +24,7 @@ class "UIBuildRoom" (Window)
function UIBuildRoom:UIBuildRoom(ui)
self:Window()
local app = ui.app
self.ui = ui
self.modal_class = "main"
@@ -39,7 +39,7 @@ function UIBuildRoom:UIBuildRoom(ui)
self.list_hover_index = 0
self.preview_anim = false
self.default_button_sound = "selectx.wav"
local function cat(n)
return --[[persistable:build_room_set_category]] function(self)
return self:setCategory(n)
@@ -53,7 +53,7 @@ function UIBuildRoom:UIBuildRoom(ui)
return self:buildRoom(n)
end
end
self:addPanel(210, 0, 0):makeButton(9, 9, 129, 32, 211, cat(1)):setTooltip(_S.tooltip.build_room_window.room_classes.diagnosis)
self:addPanel(212, 0, 41):makeButton(9, 0, 129, 31, 213, cat(2)):setTooltip(_S.tooltip.build_room_window.room_classes.treatment)
-- Clinics should really be at y=73, but TH skips a pixel here
@@ -70,7 +70,7 @@ function UIBuildRoom:UIBuildRoom(ui)
self:addPanel(222, 146, y):makeButton(12, 0, 126, 19, 223, rm()) -- List body
.enabled = false
end
-- The close button has no sprite for when pressed, so it has to be custom drawn
local build_room_dialog_close = TheApp.gfx:loadSpriteTable("Bitmap", "aux_ui", true)
self:addPanel(224, 146, 224):makeButton(8, 34, 134, 27, 224, self.close):setTooltip(_S.tooltip.build_room_window.close)
@@ -83,7 +83,7 @@ function UIBuildRoom:UIBuildRoom(ui)
build_room_dialog_close:draw(canvas, 1, x + 8, y + 34)
end
end
self.list_title = _S.build_room_window.pick_department
self.cost_box = _S.build_room_window.cost .. "0"
self.list = {}
@@ -107,7 +107,7 @@ function UIBuildRoom:UIBuildRoom(ui)
end
table.sort(rooms, function(r1, r2) return r1.categories[category] < r2.categories[category] end)
end
self:makeTooltip(_S.tooltip.build_room_window.cost, 160, 228, 282, 242)
end
@@ -115,21 +115,21 @@ local cat_label_y = {21, 53, 84, 116}
function UIBuildRoom:draw(canvas, x, y)
Window.draw(self, canvas, x, y)
x, y = self.x + x, self.y + y
self.white_font:draw(canvas, self.list_title, x + 163, y + 18)
for i = 1, 4 do
(i == self.category_index and self.blue_font or self.white_font)
:draw(canvas, self.category_titles[i], x + 19, y + cat_label_y[i])
end
for i, room in ipairs(self.list) do
(i == self.list_hover_index and self.blue_font or self.white_font)
:draw(canvas, room.name, x + 163, y + 21 + i * 19)
end
self.white_font:draw(canvas, self.cost_box, x + 163, y + 232)
if self.preview_anim then
self.preview_anim:draw(canvas, x + 70, y + 200)
end
@@ -144,7 +144,7 @@ function UIBuildRoom:setCategory(index)
self.category_index = index
self.list_title = _S.build_room_window.pick_room_type
self.list = self.category_rooms[index]
local last = #self.list + 5
for i = 5, 14 do
self.buttons[i].enabled = i < last
@@ -172,13 +172,13 @@ function UIBuildRoom:buildRoom(index)
self.ui.adviser:say(_A.warnings.money_very_low_take_loan, false, true)
self.ui:playSound("Wrong2.wav")
else
self.ui:playSound("Wrong2.wav")
self.ui:playSound("Wrong2.wav")
end
end
function UIBuildRoom:onMouseMove(x, y, dx, dy)
local repaint = Window.onMouseMove(self, x, y, dx, dy)
local hover_idx = 0
if 156 <= x and x < 287 and 31 <= y and y < 226 then
for i = 5, 14 do
@@ -189,7 +189,7 @@ function UIBuildRoom:onMouseMove(x, y, dx, dy)
end
end
end
if hover_idx ~= self.list_hover_index then
self.ui:playSound "HLightP2.wav"
if hover_idx == 0 then
@@ -204,7 +204,7 @@ function UIBuildRoom:onMouseMove(x, y, dx, dy)
self.list_hover_index = hover_idx
repaint = true
end
return repaint
end

View File

@@ -23,7 +23,7 @@ class "UIConfirmDialog" (Window)
function UIConfirmDialog:UIConfirmDialog(ui, text, callback_ok, callback_cancel)
self:Window()
local app = ui.app
self.modal_class = "information"
self.esc_closes = true
@@ -55,7 +55,7 @@ function UIConfirmDialog:UIConfirmDialog(ui, text, callback_ok, callback_cancel)
:setTooltip(_S.tooltip.window_general.cancel):setSound"No4.wav"
self:addPanel(362, 90, last_y + 10):makeButton(0, 10, 82, 34, 363, self.ok)
:setTooltip(_S.tooltip.window_general.confirm):setSound"YesX.wav"
self:addKeyHandler("Enter", self.ok)
end
@@ -85,7 +85,7 @@ end
function UIConfirmDialog:draw(canvas, x, y)
Window.draw(self, canvas, x, y)
x, y = x + self.x, y + self.y
self.white_font:drawWrapped(canvas, self.text, x + 17, y + 17, 153)
end

View File

@@ -21,7 +21,7 @@ SOFTWARE. --]]
local TH = require "TH"
local math_floor
= math.floor
dofile "dialogs/place_objects"
class "UIEditRoom" (UIPlaceObjects)
@@ -121,7 +121,7 @@ end
dialog is being opened. If the room is in the objects phase and all
required objects have been placed it will be completed. Otherwise
it is cancelled instead.
--]]
--]]
function UIEditRoom:verifyOrAbortRoom()
if self.phase == "objects" and self.confirm_button.enabled then
-- The room can be finished
@@ -237,7 +237,7 @@ function UIEditRoom:confirm(force)
self.ui.hospital:spendMoney(cost, _S.transactions.build_room .. ": " .. self.title_text, cost)
self.paid = true
end
self.world:markRoomAsBuilt(self.room)
self.closed_cleanly = true
-- If information dialogs are disabled, go ahead.
@@ -289,7 +289,7 @@ function UIEditRoom:clearArea()
if class.is(entity, Humanoid)
and self:isHumanoidObscuringArea(entity, x1, x2, y1, y2) then
humanoids_to_watch[entity] = true
-- Try to make the humanoid leave the area
local meander = entity.action_queue[2]
if meander and meander.name == "meander" then
@@ -328,13 +328,13 @@ function UIEditRoom:clearArea()
end
end
end
if next(humanoids_to_watch) == nil then
-- No humanoids within the area, so continue with the room placement
self:confirm(true)
return
end
self.check_for_clear_area_timer = 10
self.humanoids_to_watch = humanoids_to_watch
self.ui:setDefaultCursor "sleep"
@@ -504,7 +504,7 @@ function UIEditRoom:purchaseItems()
local object = TheApp.objects[o]
local research = self.ui.hospital.research
local avail = research.level_config.objects[object.thob].AvailableForLevel
if avail == 1 and (not research.research_progress[object]
if avail == 1 and (not research.research_progress[object]
or research.research_progress[object].discovered) then
-- look up current quantity
local cur_qty = 0
@@ -513,10 +513,10 @@ function UIEditRoom:purchaseItems()
cur_qty = p.qty
end
end
-- look up minimum quantity (required objects list)
local min_qty = self.room.room_info.objects_needed[o] or 0
-- subtract number of objects in room from minimum quantity
for obj, _ in pairs(self.room.objects) do
if min_qty == 0 then break end
@@ -527,13 +527,13 @@ function UIEditRoom:purchaseItems()
object_list[i] = { object = TheApp.objects[o], qty = cur_qty, min_qty = min_qty }
end
end
self.ui:addWindow(UIFurnishCorridor(self.ui, object_list, self))
end
-- callback for item pick up button
function UIEditRoom:pickupItems()
if self.in_pickup_mode then
if self.in_pickup_mode then
self:stopPickupItems()
else
self.in_pickup_mode = true
@@ -586,10 +586,10 @@ function UIEditRoom:returnToDoorPhase()
if room.door and room.door.queue then
room.door.queue:rerouteAllPatients({name = "seek_room", room_type = room.room_info.id})
end
self.purchase_button:enable(false)
self.pickup_button:enable(false)
-- Remove any placed objects (add them to list again)
for x = room.x, room.x + room.width - 1 do
for y = room.y, room.y + room.height - 1 do
@@ -612,15 +612,15 @@ function UIEditRoom:returnToDoorPhase()
if self.room.door2 then
self.world:destroyEntity(self.room.door2)
end
-- backup list of objects
self.objects_backup = {}
for k, o in pairs(self.objects) do
self.objects_backup[k] = { object = o.object, qty = o.qty }
end
UIPlaceObjects.removeAllObjects(self, true)
-- Remove walls
local function remove_wall_line(x, y, step_x, step_y, n_steps, layer, neigh_x, neigh_y)
for i = 1, n_steps do
@@ -653,17 +653,17 @@ function UIEditRoom:returnToDoorPhase()
remove_wall_line(room.x, room.y, 1, 0, room.width , 2, 0, -1)
remove_wall_line(room.x + room.width, room.y , 0, 1, room.height, 3, 0, 0)
remove_wall_line(room.x, room.y + room.height, 1, 0, room.width , 2, 0, 0)
-- Reset floor tiles and flags
self.world.map.th:unmarkRoom(room.x, room.y, room.width, room.height)
-- Re-create blueprint
local rect = self.blueprint_rect
local old_w, old_h = rect.w, rect.h
rect.w = 0
rect.h = 0
self:setBlueprintRect(rect.x, rect.y, old_w, old_h)
-- We've gone all the way back to wall phase, so step forward to door phase
self.phase = "door"
self:enterDoorPhase()
@@ -674,13 +674,13 @@ function UIEditRoom:screenToWall(x, y)
cellx = math_floor(cellx)
celly = math_floor(celly)
local rect = self.blueprint_rect
if cellx == rect.x or cellx == rect.x - 1 or cellx == rect.x + rect.w or cellx == rect.x + rect.w - 1 or
celly == rect.y or celly == rect.y - 1 or celly == rect.y + rect.h or celly == rect.y + rect.h - 1 then
else
return
end
-- NB: Doors and windows cannot be placed on corner tiles, hence walls of corner tiles
-- are never returned, and the nearest non-corner wall is returned instead. If they
-- could be placed on corner tiles, then you would have to consider the interaction of
@@ -761,7 +761,7 @@ function UIEditRoom:screenToWall(x, y)
if cellx == rect.x then
cellx = rect.x + 1
elseif cellx == rect.x + rect.w - 1 then
cellx = rect.x + rect.w - 2
cellx = rect.x + rect.w - 2
end
return cellx, rect.y + rect.h - 1, "south"
end
@@ -772,12 +772,12 @@ end
function UIEditRoom:checkReachability()
local map = self.ui.app.map.th
local world = self.ui.app.world
local rect = self.blueprint_rect
local prev_x, prev_y
local x, y = rect.x, rect.y - 1
local flags = {}
local function check(flag)
if map:getCellFlags(x, y, flags).passable and flags[flag] then
if prev_x and not world:getPathDistance(prev_x, prev_y, x, y) then
@@ -787,7 +787,7 @@ function UIEditRoom:checkReachability()
end
return true
end
while x < rect.x + rect.w do
if not check"travelSouth" then return false end
x = x + 1
@@ -807,7 +807,7 @@ function UIEditRoom:checkReachability()
if not check"travelEast" then return false end
y = y - 1
end
return true
end
@@ -819,7 +819,7 @@ function UIEditRoom:enterDoorPhase()
self.ui.app.map:setCellFlags(x, y, {passable = false})
end
end
-- check if all adjacent tiles of the rooms are still connected
if not self:checkReachability() then
-- undo passable flags and go back to walls phase
@@ -829,10 +829,10 @@ function UIEditRoom:enterDoorPhase()
self.ui.adviser:say(_A.room_forbidden_non_reachable_parts)
return
end
self.desc_text = _S.place_objects_window.place_door
self.confirm_button:enable(false) -- Confirmation is via placing door
-- Change the floor tiles to opaque blue
local map = self.ui.app.map.th
for y = self.blueprint_rect.y, self.blueprint_rect.y + self.blueprint_rect.h - 1 do
@@ -840,7 +840,7 @@ function UIEditRoom:enterDoorPhase()
map:setCell(x, y, 4, 24)
end
end
-- Re-organise wall anims to index by x and y
local walls = {}
for _, wall in ipairs(self.blueprint_wall_anims) do
@@ -872,7 +872,7 @@ function UIEditRoom:enterObjectsPhase()
self.purchase_button:enable(true)
end
self.pickup_button:enable(true)
if self.objects_backup then
self:addObjects(self.objects_backup, true)
else
@@ -937,7 +937,7 @@ function UIEditRoom:draw(canvas, ...)
self.cell_outline:draw(canvas, 2, x - 32, y)
canvas:scale(1)
end
UIPlaceObjects.draw(self, canvas, ...)
end
@@ -979,12 +979,12 @@ function UIEditRoom:onMouseUp(button, x, y)
self.mouse_down_x = false
self.mouse_down_y = false
end
if self.move_rect_x then
self.move_rect_x = false
self.move_rect_y = false
end
return UIPlaceObjects.onMouseUp(self, button, x, y)
end
@@ -999,14 +999,14 @@ function UIEditRoom:setBlueprintRect(x, y, w, h)
local map = self.ui.app.map
if x + w > map.width then w = map.width - x end
if y + h > map.height then h = map.height - y end
if rect.x == x and rect.y == y and rect.w == w and rect.h == h then
-- Nothing to do
return
end
local too_small = w < self.room_type.minimum_size or h < self.room_type.minimum_size
-- Entire update of floor tiles and wall animations done in C to replace
-- several hundred calls into C with just a single call. The price for this
-- is reduced flexibility. See l_map_updateblueprint in th_lua.cpp for code.
@@ -1025,9 +1025,9 @@ function UIEditRoom:setBlueprintRect(x, y, w, h)
self.ui:tutorialStep(3, {4, 5, 6}, 8)
end
end
self.confirm_button:enable(is_valid)
rect.x = x
rect.y = y
rect.w = w
@@ -1052,7 +1052,7 @@ function UIEditRoom:setDoorBlueprint(x, y, wall)
local orig_x = x
local orig_y = y
local orig_wall = wall
-- Used to get the adjacent tiles when placing swing doors.
local x_mod
local y_mod
@@ -1070,7 +1070,7 @@ function UIEditRoom:setDoorBlueprint(x, y, wall)
y_mod = 2
end
local map = self.ui.app.map.th
if self.blueprint_door.anim then
if self.room_type.swing_doors then
if self.blueprint_door.anim[1] then
@@ -1137,7 +1137,7 @@ function UIEditRoom:setDoorBlueprint(x, y, wall)
end
-- If it is a swing door there are two more locations to check.
if self.room_type.swing_doors then
if map:getCell(x, y - 1, 3) % 0x100 ~= 0
if map:getCell(x, y - 1, 3) % 0x100 ~= 0
or map:getCell(x, y + 1, 3) % 0x100 ~= 0 then
self.blueprint_door.valid = false
end
@@ -1150,7 +1150,7 @@ function UIEditRoom:setDoorBlueprint(x, y, wall)
end
-- If it is a swing door there are two more locations to check.
if self.room_type.swing_doors then
if map:getCell(x - 1, y, 2) % 0x100 ~= 0
if map:getCell(x - 1, y, 2) % 0x100 ~= 0
or map:getCell(x + 1, y, 2) % 0x100 ~= 0 then
self.blueprint_door.valid = false
end
@@ -1159,7 +1159,7 @@ function UIEditRoom:setDoorBlueprint(x, y, wall)
if self.blueprint_door.valid then
-- Ensure that the door isn't being built on top of an object
local flags = {}
local flag_names
local flag_names
if wall == "west" then
flag_names = {"buildableNorth", "buildableSouth"}
else
@@ -1195,7 +1195,7 @@ function UIEditRoom:setDoorBlueprint(x, y, wall)
anim:setAnimation(self.anims, 126, flags)
end
if self.blueprint_door.valid then
map:setCell(self.blueprint_door.floor_x, self.blueprint_door.floor_y, 4,
map:setCell(self.blueprint_door.floor_x, self.blueprint_door.floor_y, 4,
door_floor_blueprint_markers[orig_wall])
end
end
@@ -1213,7 +1213,7 @@ function UIEditRoom:setWindowBlueprint(x, y, wall)
local orig_x = x
local orig_y = y
local orig_wall = wall
if wall == "south" then
y = y + 1
wall = "north"
@@ -1221,10 +1221,10 @@ function UIEditRoom:setWindowBlueprint(x, y, wall)
x = x + 1
wall = "west"
end
local map = self.ui.app.map.th
local world = self.ui.app.world
if self.blueprint_window.anim then
self.blueprint_window.anim:setAnimation(self.anims, self.blueprint_window.old_anim,
self.blueprint_window.old_flags)
@@ -1232,12 +1232,12 @@ function UIEditRoom:setWindowBlueprint(x, y, wall)
self.blueprint_window.anim = nil
map:setCell(self.blueprint_window.floor_x, self.blueprint_window.floor_y, 4, 24)
end
local anim = x and self.blueprint_wall_anims[x][y]
if anim and anim:getTag() then
x, y, wall, orig_x, orig_y, orig_wall = nil
end
self.blueprint_window.x = x
self.blueprint_window.y = y
self.blueprint_window.wall = wall
@@ -1247,7 +1247,7 @@ function UIEditRoom:setWindowBlueprint(x, y, wall)
if not wall then
return
end
if anim ~= self.blueprint_window.anim then
self.blueprint_window.anim = anim
self.blueprint_window.anim:setTag"window"
@@ -1271,16 +1271,16 @@ function UIEditRoom:setWindowBlueprint(x, y, wall)
end
anim:setAnimation(self.anims, 130, flags)
if self.blueprint_window.valid then
map:setCell(self.blueprint_window.floor_x, self.blueprint_window.floor_y, 4,
map:setCell(self.blueprint_window.floor_x, self.blueprint_window.floor_y, 4,
window_floor_blueprint_markers[orig_wall])
end
end
function UIEditRoom:onCursorWorldPositionChange(x, y)
local repaint = UIPlaceObjects.onCursorWorldPositionChange(self, x, y)
local ui = self.ui
-- Is the game paused?
if not self.world.user_actions_allowed or self.confirm_dialog_open then
ui:setCursor(ui.default_cursor)
@@ -1289,7 +1289,7 @@ function UIEditRoom:onCursorWorldPositionChange(x, y)
local wx, wy = ui:ScreenToWorld(self.x + x, self.y + y)
wx = math_floor(wx)
wy = math_floor(wy)
if self.phase == "walls" then
local rect = self.blueprint_rect
if not self.mouse_down_x then
@@ -1312,7 +1312,7 @@ function UIEditRoom:onCursorWorldPositionChange(x, y)
w = (wx == rect.x),
e = (wx == rect.x + rect.w - 1) and not (wx == rect.x),
}
if (self.resize_rect.w or self.resize_rect.e) and (self.resize_rect.n or self.resize_rect.s) then
ui:setCursor(ui.app.gfx:loadMainCursor("nswe_arrow"))
elseif self.resize_rect.w or self.resize_rect.e then
@@ -1328,9 +1328,9 @@ function UIEditRoom:onCursorWorldPositionChange(x, y)
self:setDoorBlueprint(cell_x, cell_y, wall)
elseif self.phase == "windows" then
self:setWindowBlueprint(cell_x, cell_y, wall)
end
end
end
if self.mouse_down_x and self.move_rect then
local rect = self.blueprint_rect
self:setBlueprintRect(wx - self.move_rect_x, wy - self.move_rect_y, rect.w, rect.h)
@@ -1364,13 +1364,13 @@ function UIEditRoom:onCursorWorldPositionChange(x, y)
if y1 > y2 then y1, y2 = y2, y1 end
self:setBlueprintRect(x1, y1, x2 - x1 + 1, y2 - y1 + 1)
end
if wx ~= self.mouse_cell_x or wy ~= self.mouse_cell_y then
repaint = true
end
self.mouse_cell_x = wx
self.mouse_cell_y = wy
return repaint
end
@@ -1381,7 +1381,7 @@ function UIEditRoom:checkEnableConfirm()
for k, v in pairs(self.room.room_info.objects_needed) do
needed[k] = v
end
-- subtract existing objects from the required numbers
for o in pairs(self.room.objects) do
local id = o.object_type.id
@@ -1392,16 +1392,16 @@ function UIEditRoom:checkEnableConfirm()
end
end
end
-- disable if there are not fulfilled requirements
local confirm = not next(needed)
if confirm then
self.ui:tutorialStep(3, {13, 14}, 15)
else
self.ui:tutorialStep(3, {14, 15}, 13)
end
self.confirm_button:enable(confirm)
return confirm
end

View File

@@ -23,7 +23,7 @@ class "UIFullscreen" (Window)
function UIFullscreen:UIFullscreen(ui)
self:Window()
local app = ui.app
self.esc_closes = true
self.ui = ui
@@ -31,7 +31,7 @@ function UIFullscreen:UIFullscreen(ui)
self.width = 640
self.height = 480
self:onChangeResolution()
end
@@ -51,7 +51,7 @@ function UIFullscreen:onChangeResolution()
end
-- not draggable in actual fullscreen mode
self.draggable = not not self.border_sprites
local config = self.ui.app.runtime_config.window_position
if config then
config = config[self:getSavedWindowPositionName()]
@@ -59,9 +59,9 @@ function UIFullscreen:onChangeResolution()
return self:setPosition(config.x, config.y)
end
end
self.x = (app.config.width - self.width) / 2
-- NB: Bottom panel is 48 pixels high
if app.config.height > 480 + 48 then
self.y = (app.config.height - 48 - self.height) / 2

View File

@@ -61,20 +61,20 @@ function UIAnnualReport:UIAnnualReport(ui, world)
-- stand alone dialog since it has (2) sprites in another sprite file?
self.state = 2
self.default_button_sound = "selectx.wav"
-- Close button, in the future different behaviours for different screens though
--self.first_close = self:addPanel(0, 609, 449):makeButton(0, 0, 26, 26, 1, self.changePage)
self.second_close = self:addPanel(0, 608, 449):makeButton(0, 0, 26, 26, 1, self.close)
self:setActive(self.second_close, true)
-- Change page buttons for the second and third pages
local --[[persistable:annual_report_change_page]] function change() self:changePage(3) end
self.second_change = self:addPanel(0, 274, 435):makeButton(0, 0, 91, 42, 3, change)
self:setActive(self.second_change, true)
self.third_change = self:addPanel(0, 272, 367):makeButton(0, 0, 91, 42, 3, self.changePage)
self:setActive(self.third_change, false)
-- The plaque showed after the player has clicked on a trophy
local plaque = {}
plaque[1] = self:addPanel(19, 206, 87)
@@ -115,7 +115,7 @@ function UIAnnualReport:UIAnnualReport(ui, world)
self:checkTrophiesAndAwards(world)
-- Get and sort values used on the statistics screen.
-- The six categories. The extra tables are used to be able to sort the values.
-- The six categories. The extra tables are used to be able to sort the values.
self.money = {}
self.money_sort = {}
self.visitors = {}
@@ -128,7 +128,7 @@ function UIAnnualReport:UIAnnualReport(ui, world)
self.cures_sort = {}
self.value = {}
self.value_sort = {}
-- TODO: Right now there are no real competitors, they all have initial values.
for i, hospital in ipairs(world.hospitals) do
self.money[hospital.name] = hospital.balance - hospital.loan
@@ -144,7 +144,7 @@ function UIAnnualReport:UIAnnualReport(ui, world)
self.salary[hospital.name] = hospital.player_salary
self.salary_sort[i] = hospital.player_salary
end
local sort_order = function(a,b) return a>b end
table.sort(self.money_sort, sort_order)
table.sort(self.visitors_sort, sort_order)
@@ -152,7 +152,7 @@ function UIAnnualReport:UIAnnualReport(ui, world)
table.sort(self.cures_sort, sort_order)
table.sort(self.value_sort, sort_order)
table.sort(self.salary_sort, sort_order)
-- Pause the game to allow the player plenty of time to check all statistics and trophies won
if world and world:isCurrentSpeed("Speed Up") then
world:setSpeed("Pause")
@@ -226,7 +226,7 @@ function UIAnnualReport:checkTrophiesAndAwards(world)
self.rep_amount = self.rep_amount + win_value
elseif hosp.value < prices.HospValuePoor then
-- added some here so you get odd amounts as in TH!
local lose_value = prices.HospValuePenalty * math.random(1, 15)
local lose_value = prices.HospValuePenalty * math.random(1, 15)
self:addAward(_S.trophy_room.hosp_value.penalty[1], "reputation", lose_value)
self.rep_amount = self.rep_amount + lose_value
end
@@ -279,8 +279,8 @@ function UIAnnualReport:updateAwards()
if self.rep_amount ~= 0 then
hosp:changeReputation("year_end", nil, math.floor(self.rep_amount))
end
end
end
-- A table defining which type of shadow each award should have.
local award_shadows = {
{ shadow = 4 },
@@ -502,18 +502,18 @@ end
function UIAnnualReport:draw(canvas, x, y)
self.background:draw(canvas, self.x + x, self.y + y)
UIFullscreen.draw(self, canvas, x, y)
x, y = self.x + x, self.y + y
local font = self.stat_font
local world = self.ui.app.world
if self.state == 1 then -- Fame screen
-- Title and column names
font:draw(canvas, _S.high_score.best_scores, x + 220, y + 104, 200, 0)
font:draw(canvas, _S.high_score.pos, x + 218, y + 132)
font:draw(canvas, _S.high_score.player, x + 260, y + 132)
font:draw(canvas, _S.high_score.score, x + 360, y + 132)
-- Players and their score
local i = 1
local dy = 0
@@ -562,9 +562,9 @@ function UIAnnualReport:drawStatisticsScreen(canvas, x, y)
local font = self.stat_font
local world = self.ui.app.world
-- Draw titles
font:draw(canvas, _S.menu.charts .. " "
font:draw(canvas, _S.menu.charts .. " "
.. (world.year + 1999), x + 210, y + 30, 200, 0)
font:draw(canvas, _S.high_score.categories.money, x + 140, y + 98, 170, 0)
font:draw(canvas, _S.high_score.categories.salary, x + 328, y + 98, 170, 0)
@@ -572,7 +572,7 @@ function UIAnnualReport:drawStatisticsScreen(canvas, x, y)
font:draw(canvas, _S.high_score.categories.deaths, x + 328, y + 205, 170, 0)
font:draw(canvas, _S.high_score.categories.visitors, x + 140, y + 310, 170, 0)
font:draw(canvas, _S.high_score.categories.total_value, x + 328, y + 310, 170, 0)
-- TODO: Add possibility to right align text.
-- Helper function to find where the person is in the array.
@@ -603,52 +603,52 @@ function UIAnnualReport:drawStatisticsScreen(canvas, x, y)
local dup_value = 0
for _, player in ipairs(world.hospitals) do
local name = player.name
-- Most Money
local index, dup_m = getindex(self.money_sort, self.money[name])
-- index is the returned value of the sorted place for this player.
-- However there might be many players with the same value, so each iteration a
-- duplicate has been found, one additional row lower is the right place to be.
font:draw(canvas, name:upper(), x + 140,
font:draw(canvas, name:upper(), x + 140,
y + row_y + row_dy*(index-1) + row_dy*(dup_money))
font:draw(canvas, self.money[name], x + 240,
font:draw(canvas, self.money[name], x + 240,
y + row_y + row_dy*(index-1) + row_dy*(dup_money), 70, 0, "right")
-- Highest Salary
local index, dup_s = getindex(self.salary_sort, self.salary[name])
font:draw(canvas, name:upper(), x + 140 + col_x,
font:draw(canvas, name:upper(), x + 140 + col_x,
y + row_y + row_dy*(index-1) + row_dy*(dup_salary))
font:draw(canvas, self.salary[name], x + 240 + col_x,
font:draw(canvas, self.salary[name], x + 240 + col_x,
y + row_y + row_dy*(index-1) + row_dy*(dup_salary), 70, 0, "right")
-- Most Cures
local index, dup_c = getindex(self.cures_sort, self.cures[name])
font:draw(canvas, name:upper(), x + 140,
font:draw(canvas, name:upper(), x + 140,
y + row_y + row_no_y + row_dy*(index-1) + row_dy*(dup_cures))
font:draw(canvas, self.cures[name], x + 240,
font:draw(canvas, self.cures[name], x + 240,
y + row_y + row_no_y + row_dy*(index-1) + row_dy*(dup_cures), 70, 0, "right")
-- Most Deaths
local index, dup_d = getindex(self.deaths_sort, self.deaths[name])
font:draw(canvas, name:upper(), x + 140 + col_x,
font:draw(canvas, name:upper(), x + 140 + col_x,
y + row_y + row_no_y + row_dy*(index-1) + row_dy*(dup_deaths))
font:draw(canvas, self.deaths[name], x + 240 + col_x,
font:draw(canvas, self.deaths[name], x + 240 + col_x,
y + row_y + row_no_y + row_dy*(index-1) + row_dy*(dup_deaths), 70, 0, "right")
-- Most Visitors
local index, dup_v = getindex(self.visitors_sort, self.visitors[name])
font:draw(canvas, name:upper(), x + 140,
font:draw(canvas, name:upper(), x + 140,
y + row_y + row_no_y*2 + row_dy*(index-1) + row_dy*(dup_visitors))
font:draw(canvas, self.visitors[name], x + 240,
font:draw(canvas, self.visitors[name], x + 240,
y + row_y + row_no_y*2 + row_dy*(index-1) + row_dy*(dup_visitors), 70, 0, "right")
-- Highest Value
local index, dup_v2 = getindex(self.value_sort, self.value[name])
font:draw(canvas, name:upper(), x + 140 + col_x,
font:draw(canvas, name:upper(), x + 140 + col_x,
y + row_y + row_no_y*2 + row_dy*(index-1) + row_dy*(dup_value))
font:draw(canvas, self.value[name], x + 240 + col_x,
font:draw(canvas, self.value[name], x + 240 + col_x,
y + row_y + row_no_y*2 + row_dy*(index-1) + row_dy*(dup_value), 70, 0, "right")
if dup_m > 1 then dup_money = dup_money + 1 else dup_money = 0 end
if dup_s > 1 then dup_salary = dup_salary + 1 else dup_salary = 0 end
if dup_c > 1 then dup_cures = dup_cures + 1 else dup_cures = 0 end

View File

@@ -32,8 +32,8 @@ function UIBankManager:UIBankManager(ui)
palette:setEntry(255, 0xFF, 0x00, 0xFF) -- Make index 255 transparent
self.panel_sprites = gfx:loadSpriteTable("QData", "Bank02V", true, palette)
self.font = gfx:loadFont("QData", "Font36V", false, palette)
-- The statistics font
-- The statistics font
palette = gfx:loadPalette("QData", "Stat01V.pal")
palette:setEntry(255, 0xFF, 0x00, 0xFF) -- Make index 255 transparent
self.stat_font = gfx:loadFont("QData", "Font37V", false, palette)
@@ -47,12 +47,12 @@ function UIBankManager:UIBankManager(ui)
self.browsclk = 0
self.smilesclk = 0
self.eyesclk = 0
-- sprites for the animation
self.smiles = self:addPanel(12, 303, 199)
self.eyesblink = self:addPanel(7, 298, 173)
self.browslift = self:addPanel(9, 296, 165)
-- Button so that the user can click in the middle and get the statistics page and
-- vice versa
self.stat_button = self:addPanel(0, 230, 100)
@@ -60,36 +60,36 @@ function UIBankManager:UIBankManager(ui)
self.return_from_stat_button = self:addPanel(0, 0, 0)
:makeButton(0, 0, 640, 440, 0, self.hideStatistics)
self.return_from_stat_button.enabled = false
-- Buttons
-- The close button needs to be movable
self.close_panel = self:addPanel(0, 607, 448)
self.close_button = self.close_panel:makeButton(0, 0, 26, 26, 4, self.close):setTooltip(_S.tooltip.bank_manager.close)
self:addPanel(0, 250, 390):makeButton(0, 0, 200, 50, 0, self.openTownMap):setTooltip(_S.tooltip.toolbar.town_map)
self:addPanel(0, 192, 265):makeButton(0, 0, 21, 21, 6, self.increaseLoan):setTooltip(_S.tooltip.bank_manager.borrow_5000)
self:addPanel(0, 50, 265):makeButton(0, 0, 21, 21, 5, self.decreaseLoan):setTooltip(_S.tooltip.bank_manager.repay_5000)
self.graph_buttons = {
self:addPanel(0, 547, 157):makeButton(0, 0, 42, 23, 3, self.showGraph1):setTooltip(_S.tooltip.bank_manager.show_graph:format(self.ui.hospital.insurance[1])),
self:addPanel(0, 547, 217):makeButton(0, 0, 42, 23, 3, self.showGraph2):setTooltip(_S.tooltip.bank_manager.show_graph:format(self.ui.hospital.insurance[2])),
self:addPanel(0, 547, 277):makeButton(0, 0, 42, 23, 3, self.showGraph3):setTooltip(_S.tooltip.bank_manager.show_graph:format(self.ui.hospital.insurance[3]))
}
self.graph = self:addPanel(1, 417, 150)
self.graph.visible = false
self.graph.enabled = false
self.return_from_graph_button = self:addPanel(0, 547, 277)
self.return_from_graph_button:makeButton(0, 0, 42, 23, 2, self.returnFromGraph):setTooltip(_S.tooltip.bank_manager.graph_return)
self.return_from_graph_button.visible = false
self.return_from_graph_button.enabled = false
self:makeTooltip(_S.tooltip.bank_manager.hospital_value, 60, 105, 203, 157)
self:makeTooltip(_S.tooltip.bank_manager.balance, 60, 170, 203, 222)
self:makeTooltip(_S.tooltip.bank_manager.current_loan, 60, 235, 203, 287)
self:makeTooltip(_S.tooltip.bank_manager.interest_payment, 60, 300, 203, 352)
local --[[persistable:insurance_tooltip_template]] function insurance_tooltip(i)
return --[[persistable:insurance_tooltip]] function()
if not self.graph.visible then
@@ -97,7 +97,7 @@ function UIBankManager:UIBankManager(ui)
end
end
end
self:makeDynamicTooltip(insurance_tooltip(1), 430, 128, 589, 180)
self:makeDynamicTooltip(insurance_tooltip(2), 430, 188, 589, 240)
self:makeDynamicTooltip(insurance_tooltip(3), 430, 248, 589, 300)
@@ -123,7 +123,7 @@ end
local function sum(t)
local sum = 0
for _, entry in ipairs(t) do
for _, entry in ipairs(t) do
sum = sum + entry
end
return sum
@@ -138,7 +138,7 @@ function UIBankManager:onTick()
if self.eyesclk > 2 then
self.eyesclk = 0
self.eyesblink.sprite_index = self.eyesblink.sprite_index + 1
if self.eyesblink.sprite_index > 8 then
if self.eyesblink.sprite_index > 8 then
self.eyesblink.sprite_index = 7
end
end
@@ -160,7 +160,7 @@ function UIBankManager:onTick()
if self.smilesclk > 3 then
self.smilesclk = 0
self.smiles.sprite_index = self.smiles.sprite_index + 1
if self.smiles.sprite_index > 15 then
if self.smiles.sprite_index > 15 then
self.smiles.sprite_index = 12
end
end
@@ -178,7 +178,7 @@ function UIBankManager:onTick()
-- up and down once
elseif self.counter >= 88 and self.counter < 100 then
animateBrows()
-- smile
-- smile
elseif self.counter >= 132 and self.counter < 140 then
animateSmile()
-- two blinks
@@ -200,7 +200,7 @@ function UIBankManager:onTick()
elseif self.counter >= 298 and self.counter < 322 then
animateBrows()
-- two blinks
elseif self.counter >= 340 and self.counter < 352 then
elseif self.counter >= 340 and self.counter < 352 then
animateEyes()
end
-- reset the animation counter
@@ -211,21 +211,21 @@ end
function UIBankManager:draw(canvas, x, y)
local hospital = self.ui.hospital
-- Either draw the statistics page or the normal bank page
if self.showingStatistics then
local font = self.stat_font
self.stat_background:draw(canvas, self.x + x, self.y + y)
UIFullscreen.draw(self, canvas, x, y)
x, y = self.x + x, self.y + y
-- Titles
font:draw(canvas, _S.bank_manager.statistics_page.date, x + 44, y + 37, 65, 0)
font:draw(canvas, _S.bank_manager.statistics_page.details, x + 125, y + 40, 230, 0)
font:draw(canvas, _S.bank_manager.statistics_page.money_out, x + 373, y + 42, 70, 0)
font:draw(canvas, _S.bank_manager.statistics_page.money_in, x + 449, y + 41, 70, 0)
font:draw(canvas, _S.bank_manager.statistics_page.balance, x + 525, y + 40, 70, 0)
-- Each transaction
-- A for loop going backwards
for no = 1, #hospital.transactions do
@@ -240,7 +240,7 @@ function UIBankManager:draw(canvas, x, y)
end
font:draw(canvas, "$ " .. values.balance, x + 529, current_y)
end
-- Summary
font:draw(canvas, _S.bank_manager.statistics_page.current_balance, x + 373, y + 420, 140, 0)
font:draw(canvas, "$ " .. hospital.balance, x + 526, y + 421, 70, 0)
@@ -249,7 +249,7 @@ function UIBankManager:draw(canvas, x, y)
self.background:draw(canvas, self.x + x, self.y + y)
UIFullscreen.draw(self, canvas, x, y)
x, y = self.x + x, self.y + y
-- The left side
font:draw(canvas, _S.bank_manager.hospital_value, x + 60, y + 109, 143, 0)
font:draw(canvas, "$ " .. hospital.value, x + 60, y + 139, 143, 0)
@@ -260,7 +260,7 @@ function UIBankManager:draw(canvas, x, y)
font:draw(canvas, _S.bank_manager.interest_payment, x + 60, y + 305, 143, 0)
local interest = math.floor(hospital.loan * hospital.interest_rate / 12)
font:draw(canvas, "$ " .. interest, x + 60, y + 334, 143, 0)
-- The right side
font:draw(canvas, _S.bank_manager.insurance_owed, x + 430, y + 102, 158, 0)
if self.graph.visible then
@@ -312,10 +312,10 @@ function UIBankManager:showStatistics(keep_cursor)
self.showingStatistics = true
self.return_from_stat_button.enabled = true
self.stat_button.enabled = false
-- hides the animated parts of the bank manager when viewing the statement
-- hides the animated parts of the bank manager when viewing the statement
self.smiles.visible = false
self.eyesblink.visible = false
self.browslift.visible = false
self.browslift.visible = false
-- The close button has been slightly moved.
local panel = self.close_panel
panel.x = panel.x - 6
@@ -339,9 +339,9 @@ function UIBankManager:hideStatistics()
-- shows the animated parts of the bank manager when viewing the main screen
self.smiles.visible = true
self.eyesblink.visible = true
self.browslift.visible = true
-- resets the animation counter if the screen is switched to the statement and back
self.counter = -1
self.browslift.visible = true
-- resets the animation counter if the screen is switched to the statement and back
self.counter = -1
-- return the close button again
local panel = self.close_panel
panel.x = panel.x + 6

View File

@@ -37,11 +37,11 @@ function UICasebook:UICasebook(ui, disease_selection)
self:close()
return
end
self.hospital = ui.hospital
self.casebook = self.hospital.disease_casebook
self:updateDiseaseList()
-- Buttons
self:addPanel(0, 607, 449):makeButton(0, 0, 26, 26, 3, self.close):setTooltip(_S.tooltip.casebook.close)
self:addPanel(0, 439, 29):makeRepeatButton(0, 0, 70, 46, 1, self.scrollUp):setTooltip(_S.tooltip.casebook.up)
@@ -50,13 +50,13 @@ function UICasebook:UICasebook(ui, disease_selection)
self:addPanel(0, 237, 133):makeRepeatButton(0, 0, 22, 22, 4, self.decreasePay):setTooltip(_S.tooltip.casebook.decrease)
self:addPanel(0, 235, 400):makeButton(0, 0, 140, 20, 0, self.concentrateResearch)
:setTooltip(_S.tooltip.casebook.research)
-- Hotkeys
self:addKeyHandler("up", self.scrollUp)
self:addKeyHandler("down", self.scrollDown)
self:addKeyHandler("right", self.increasePay)
self:addKeyHandler("left", self.decreasePay)
-- Icons representing cure effectiveness and other important information.
self.machinery = self:addPanel(6, 306, 352):setTooltip(_S.tooltip.casebook.cure_type.machine)
self.machinery.visible = false
@@ -70,21 +70,21 @@ function UICasebook:UICasebook(ui, disease_selection)
self.unknown.visible = false
self.psychiatry = self:addPanel(10, 306, 352):setTooltip(_S.tooltip.casebook.cure_type.psychiatrist)
self.psychiatry.visible = false
self.curable = self:addPanel(11, 335, 352):setTooltip(_S.tooltip.casebook.cure_requirement.possible)
self.curable.visible = false
self.not_curable = self:addPanel(12, 335, 352):setTooltip(_S.tooltip.casebook.cure_requirement.not_possible) -- TODO: split up in more specific requirements
self.not_curable.visible = false
self.percentage_counter = false -- Counter for displaying cure price percentage for a certain time before switching to price.
self:makeTooltip(_S.tooltip.casebook.reputation, 249, 72, 362, 117)
self:makeTooltip(_S.tooltip.casebook.treatment_charge, 249, 117, 362, 161)
self:makeTooltip(_S.tooltip.casebook.earned_money, 247, 161, 362, 205)
self:makeTooltip(_S.tooltip.casebook.cured, 247, 205, 362, 249)
self:makeTooltip(_S.tooltip.casebook.deaths, 247, 249, 362, 293)
self:makeTooltip(_S.tooltip.casebook.sent_home, 247, 293, 362, 337)
if disease_selection then
self:selectDisease(disease_selection)
else
@@ -138,7 +138,7 @@ function UICasebook:updateIcons()
local disease = self.selected_disease
local hosp = self.hospital
local world = hosp.world
local known = true
-- Curable / not curable icons and their tooltip
if self.casebook[disease].pseudo then
@@ -152,7 +152,7 @@ function UICasebook:updateIcons()
else
self.curable.visible = false
self.not_curable.visible = true
-- Strings for the tooltip
local research = false
local build = false
@@ -171,7 +171,7 @@ function UICasebook:updateIcons()
end
research = research and (_S.tooltip.casebook.cure_requirement.research_machine .. research .. "). ") or ""
build = build and (_S.tooltip.casebook.cure_requirement.build_room .. build .. "). ") or ""
local staffclass_to_string = {
Nurse = _S.staff_title.nurse,
Doctor = _S.staff_title.doctor,
@@ -185,17 +185,17 @@ function UICasebook:updateIcons()
staff = (staff and (staff .. ", ") or " (") .. staffclass_to_string[sclass] .. ": " .. amount
end
staff = staff and (_S.tooltip.casebook.cure_requirement.hire_staff .. staff .. "). ") or ""
self.not_curable:setTooltip(research .. build .. staff)
end
end
self.unknown.visible = not known
self.drug.visible = known and not not self.casebook[disease].drug
self.machinery.visible = known and not not self.casebook[disease].machine and not self.casebook[disease].pseudo
self.psychiatry.visible = known and not not self.casebook[disease].psychiatrist
self.surgery.visible = known and not not self.casebook[disease].surgeon
self.ui:updateTooltip() -- for the case that mouse is hovering over icon while player scrolls through list with keys
self.percentage_counter = 50
end
@@ -203,13 +203,13 @@ end
function UICasebook:draw(canvas, x, y)
self.background:draw(canvas, self.x + x, self.y + y)
UIFullscreen.draw(self, canvas, x, y)
x, y = self.x + x, self.y + y
local titles = self.title_font
local book = self.casebook
local disease = self.selected_disease
local selected = self.selected_index
-- All titles
titles:draw(canvas, _S.casebook.reputation, x + 278, y + 68)
titles:draw(canvas, _S.casebook.treatment_charge, x + 260, y + 113)
@@ -218,7 +218,7 @@ function UICasebook:draw(canvas, x, y)
titles:draw(canvas, _S.casebook.deaths, x + 279, y + 245)
titles:draw(canvas, _S.casebook.sent_home, x + 270, y + 289)
titles:draw(canvas, _S.casebook.cure, x + 255, y + 354)
-- Specific disease information
if self.hospital:canConcentrateResearch(disease) then
if book[disease].concentrate_research then -- Concentrate research
@@ -240,12 +240,12 @@ function UICasebook:draw(canvas, x, y)
local price_text = self.percentage_counter and ("%.0f%%"):format(book[disease].price * 100)
or "$" .. self.hospital:getTreatmentPrice(disease)
titles:draw(canvas, price_text, x + 262, y + 137, 90, 0) -- Treatment Charge
titles:draw(canvas, "$" .. book[disease].money_earned, x + 248, y + 181, 114, 0) -- Money Earned
titles:draw(canvas, book[disease].recoveries, x + 248, y + 225, 114, 0) -- Recoveries
titles:draw(canvas, book[disease].fatalities, x + 248, y + 269, 114, 0) -- Fatalities
titles:draw(canvas, book[disease].turned_away, x + 248, y + 313, 114, 0) -- Turned away
-- Cure percentage
if self.drug.visible then
self.drug_font:draw(canvas, book[disease].cure_effectiveness, x + 313, y + 364, 16, 0)

View File

@@ -31,9 +31,9 @@ function UIFax:UIFax(ui, icon)
self.icon = icon
self.message = icon.message or {}
self.owner = icon.owner
self.code = ""
-- Add choice buttons
local choices = self.message.choices
self.choice_buttons = {}
@@ -52,31 +52,31 @@ function UIFax:UIFax(ui, icon)
:setDisabledSprite(19):enable(enabled)
end
end
-- Close button
self:addPanel(0, 598, 440):makeButton(0, 0, 26, 26, 16, self.close):setTooltip(_S.tooltip.fax.close)
self:addPanel(0, 471, 349):makeButton(0, 0, 87, 20, 14, self.cancel) -- Cancel code button
self:addPanel(0, 474, 372):makeButton(0, 0, 91, 27, 15, self.validate) -- Validate code button
self:addPanel(0, 168, 348):makeButton(0, 0, 43, 10, 1, self.correct) -- Correction button
local function button(char)
return --[[persistable:fax_button]] function() self:appendNumber(char) end
end
self:addPanel(0, 220, 348):makeButton(0, 0, 43, 10, 2, button"1"):setSound"Fax_1.wav"
self:addPanel(0, 272, 348):makeButton(0, 0, 44, 10, 3, button"2"):setSound"Fax_2.wav"
self:addPanel(0, 327, 348):makeButton(0, 0, 43, 10, 4, button"3"):setSound"Fax_3.wav"
self:addPanel(0, 219, 358):makeButton(0, 0, 44, 10, 5, button"4"):setSound"Fax_4.wav"
self:addPanel(0, 272, 358):makeButton(0, 0, 43, 10, 6, button"5"):setSound"Fax_5.wav"
self:addPanel(0, 326, 358):makeButton(0, 0, 44, 10, 7, button"6"):setSound"Fax_6.wav"
self:addPanel(0, 218, 370):makeButton(0, 0, 44, 11, 8, button"7"):setSound"Fax_7.wav"
self:addPanel(0, 271, 370):makeButton(0, 0, 44, 11, 9, button"8"):setSound"Fax_8.wav"
self:addPanel(0, 326, 370):makeButton(0, 0, 44, 11, 10, button"9"):setSound"Fax_9.wav"
self:addPanel(0, 217, 382):makeButton(0, 0, 45, 12, 11, button"*")
self:addPanel(0, 271, 382):makeButton(0, 0, 44, 11, 12, button"0"):setSound"Fax_0.wav"
self:addPanel(0, 326, 382):makeButton(0, 0, 44, 11, 13, button"#")
@@ -95,11 +95,11 @@ function UIFax:draw(canvas, x, y)
self.background:draw(canvas, self.x + x, self.y + y)
UIFullscreen.draw(self, canvas, x, y)
x, y = self.x + x, self.y + y
if self.message then
local last_y = y + 40
for i, message in ipairs(self.message) do
last_y = self.fax_font:drawWrapped(canvas, message.text, x + 190,
last_y = self.fax_font:drawWrapped(canvas, message.text, x + 190,
last_y + (message.offset or 0), 330,
"center")
end
@@ -225,7 +225,7 @@ function UIFax:validate()
return
end
self.ui:playSound("fax_yes.wav")
-- TODO: Other cheats (preferably with slight obfuscation, as above)
end
@@ -240,7 +240,7 @@ function UIFax:close()
UIFullscreen.close(self)
if world and world:isCurrentSpeed("Pause") then
world:setSpeed(world.prev_speed)
end
end
end
function UIFax:afterLoad(old, new)

View File

@@ -51,24 +51,24 @@ function UIGraphs:UIGraphs(ui)
self:close()
return
end
local hosp = ui.hospital
self.hospital = hosp
-- Buttons
self:addPanel(0, 63, 384):makeButton(0, 0, 26, 26, 3, self.close):setTooltip(_S.tooltip.graphs.close)
-- The possible scales are:
-- 1: Increments of four years per line
-- 2: Increments of one year per line
-- 3: Increments of one month per line
self.graph_scale = 3
self.graph_scale_panel = self:addPanel(0, 371, 384)
self.graph_scale_button = self.graph_scale_panel:makeButton(0, 0, 65, 26, 2, self.toggleGraphScale):setTooltip(_S.tooltip.graphs.scale)
self.hide_graph = {}
local function buttons(name)
return --[[persistable:graphs_button]] function()
self:toggleGraph(name)
@@ -84,7 +84,7 @@ function UIGraphs:UIGraphs(ui)
self:addPanel(0, 590, 347):makeToggleButton(0, 0, 42, 42, 1, buttons("deaths")):setTooltip(_S.tooltip.graphs.deaths),
self:addPanel(0, 590, 400):makeToggleButton(0, 0, 42, 42, 1, buttons("reputation")):setTooltip(_S.tooltip.graphs.reputation)
}
self:updateLines()
end
@@ -117,7 +117,7 @@ function UIGraphs:updateLines()
values[#values + 1] = statistics[i]
end
self.values = values
-- Decide maximum and minimum for normalisation of each line
for _, part in ipairs(values) do
if type(part) == "table" then
@@ -131,14 +131,14 @@ function UIGraphs:updateLines()
end
end
end
-- Start from the right part of the graph window
local top_y = 85
local bottom_y = 353
local first_x = 346
local dx = -25
local text = {}
-- First start at the correct place
local part = values[1]
for stat, value in pairs(part) do
@@ -158,7 +158,7 @@ function UIGraphs:updateLines()
table.sort(text, compare)
self.text_positions = text
local aux_lines = {}
-- Then add all the nodes available for each graph
for i, part in ipairs(values) do
@@ -222,7 +222,7 @@ function UIGraphs:draw(canvas, x, y)
local dx = -25
local number = math.floor(#self.hospital.statistics / 12)
local decrements = -4 -- Four years
if self.graph_scale == 2 then
decrements = -1 -- One year
@@ -231,7 +231,7 @@ function UIGraphs:draw(canvas, x, y)
number = #self.hospital.statistics - number * 12
end
local no = 1
-- Draw numbers (or month names) below the graph
for _, _ in ipairs(self.values) do
self.black_font:drawWrapped(canvas, self.graph_scale == 3 and _S.months[(number - 1) % 12 + 1] or number, x + first_x, y + 363, 25, "center")

View File

@@ -36,10 +36,10 @@ function UIPolicy:UIPolicy(ui, disease_selection)
self:close()
return
end
local hosp = ui.hospital
self.hospital = hosp
local --[[persistable:hospital_policy_allow_staff]] function allowStaff(name, state, btn)
if name == "Allow" then
if self.prohibit_button.toggled then -- Changing setting from prohibit to allow
@@ -57,24 +57,24 @@ function UIPolicy:UIPolicy(ui, disease_selection)
end
end
end
-- Buttons
self:addPanel(0, 607, 447):makeButton(0, 0, 26, 26, 6, self.close):setTooltip(_S.tooltip.policy.close)
self.allow_button = self:addPanel(0, 348, 379):makeToggleButton(0, 0, 48, 17, 4, allowStaff, "Allow"):setTooltip(_S.tooltip.policy.staff_leave) -- Allow staff to move
self.prohibit_button = self:addPanel(0, 395, 379):makeToggleButton(0, 0, 48, 17, 5, allowStaff, "Prohibit"):setTooltip(_S.tooltip.policy.staff_stay) -- Prohibit staff to move
if self.hospital.policies["staff_allowed_to_move"] then
self.allow_button:toggle()
else
self.prohibit_button:toggle()
end
-- Slider positions
local guess = 129 + hosp.policies["guess_cure"]*299
local home = 129 + hosp.policies["send_home"]*299
local stop = 124 + (hosp.policies["stop_procedure"] - 1)*299
local staffroom = 149 + hosp.policies["goto_staffroom"]*250
-- Sliders
self.sliders = {}
self.sliders["guess_cure"] = self:addPanel(2, guess, 119, 82, 44)
@@ -82,7 +82,7 @@ function UIPolicy:UIPolicy(ui, disease_selection)
self.sliders["stop_procedure"] = self:addPanel(3, stop, 210, 92, 28)
self.sliders["goto_staffroom"] = self:addPanel(3, staffroom, 285, 92, 28)
self.sliders["guess_cure"].min_x = home
self.sliders["guess_cure"].total_min_x = 129 -- Needed to get the correct value set when
self.sliders["guess_cure"].total_min_x = 129 -- Needed to get the correct value set when
-- windows is closed.
self.sliders["guess_cure"].max_x = 428
self.sliders["send_home"].min_x = 129
@@ -93,7 +93,7 @@ function UIPolicy:UIPolicy(ui, disease_selection)
self.sliders["stop_procedure"].addition = true -- This value goes from 1 to 2.
self.sliders["goto_staffroom"].min_x = 149
self.sliders["goto_staffroom"].max_x = 399
-- Tooltips for slider bars
self:makeTooltip(_S.tooltip.policy.diag_procedure, 161, 119, 479, 174)
self:makeTooltip(_S.tooltip.policy.diag_termination, 161, 210, 479, 249)
@@ -104,7 +104,7 @@ function UIPolicy:draw(canvas, x, y)
self.background:draw(canvas, self.x + x, self.y + y)
UIFullscreen.draw(self, canvas, x, y)
x, y = self.x + x, self.y + y
local text = self.text_font
local label = self.label_font
@@ -117,7 +117,7 @@ function UIPolicy:draw(canvas, x, y)
label:draw(canvas, _S.policy.sliders.stop, x + added_x, y + added_y + 2, 92, 0)
added_x, added_y = self.sliders["goto_staffroom"].x, self.sliders["goto_staffroom"].y
label:draw(canvas, _S.policy.sliders.staff_room, x + added_x, y + added_y + 2, 92, 0)
-- All other text
text:draw(canvas, _S.policy.header, x + 160, y + 78, 300, 0)
text:draw(canvas, _S.policy.diag_procedure, x + 161, y + 100)

View File

@@ -45,9 +45,9 @@ function UIProgressReport:UIProgressReport(ui)
self:close()
return
end
self.default_button_sound = "selectx.wav"
-- Selected hospital number
self.selected = 1
@@ -65,7 +65,7 @@ function UIProgressReport:UIProgressReport(ui)
end
if world_goals[crit_name].lose_value then
world_goals[crit_name].red = false
if cur_value < world_goals[crit_name].boundary then
world_goals[crit_name].red = true
res_value = world_goals[crit_name].lose_value
@@ -95,9 +95,9 @@ function UIProgressReport:UIProgressReport(ui)
x = x + 30
end
end
self:addPanel(0, 606, 447):makeButton(0, 0, 26, 26, 8, self.close):setTooltip(_S.tooltip.status.close)
-- Own and competitor hospital buttons
local function btn_handler(num)
return --[[persistable:progress_report_hospital_button]] function()
@@ -114,16 +114,16 @@ function UIProgressReport:UIProgressReport(ui)
:setTooltip(tooltip(num))
:enable(num == 1)
end
for i = 1, math.min(#world.hospitals, 4) do
make_hosp_button(i)
end
self:makeTooltip(_S.tooltip.status.population_chart .. " " .. _S.misc.not_yet_implemented, 433, 64, 578, 179)
self:makeTooltip(_S.tooltip.status.happiness, 433, 179, 578, 209)
self:makeTooltip(_S.tooltip.status.thirst, 433, 209, 578, 239)
self:makeTooltip(_S.tooltip.status.warmth, 433, 239, 578, 270)
self.warning = self:addPanel(7, 252, 295)
self.warning.visible = false
-- TODO: 6 gray
@@ -147,12 +147,12 @@ function UIProgressReport:drawMarkers(canvas, x, y)
self.panel_sprites:draw(canvas, 5, x + x_min + width * happiness, y + 193)
self.panel_sprites:draw(canvas, 5, x + x_min + width * thirst, y + 223)
self.panel_sprites:draw(canvas, 5, x + x_min + width * warmth, y + 254)
if world.free_build_mode then
self.normal_font:drawWrapped(canvas, _S.progress_report.free_build, x + 265, y + 194, 150, "center")
end
-- Possibly show warning that it's too cold, too hot, patients not happy
-- Possibly show warning that it's too cold, too hot, patients not happy
-- or if theres need to build drink machines as folks are thirsty. Only show one at a time though!
-- TODO the levels may need adjustment
local msg = self.ui.hospital.show_progress_screen_warnings
@@ -179,13 +179,13 @@ end
function UIProgressReport:draw(canvas, x, y)
self.background:draw(canvas, self.x + x, self.y + y)
UIFullscreen.draw(self, canvas, x, y)
x, y = self.x + x, self.y + y
local app = self.ui.app
local hospital = self.ui.hospital
local world = hospital.world
local world_goals = world.goals
-- Names of the players playing
local ly = 73
for pnum, player in ipairs(world.hospitals) do
@@ -193,7 +193,7 @@ function UIProgressReport:draw(canvas, x, y)
font:draw(canvas, player.name:upper(), x + 272, y + ly)
ly = ly + 25
end
-- Draw the vertical bars for the winning conditions
local lx = 270
for i, tab in ipairs(world_goals) do
@@ -224,10 +224,10 @@ function UIProgressReport:draw(canvas, x, y)
end
self:drawMarkers(canvas, x, y)
self.normal_font:draw(canvas, _S.progress_report.header .. " "
self.normal_font:draw(canvas, _S.progress_report.header .. " "
.. (world.year + 1999), x + 227, y + 40, 400, 0)
self.small_font:draw(canvas, _S.progress_report.win_criteria:upper(), x + 263, y + 172)
self.small_font:draw(canvas, _S.progress_report.percentage_pop:upper() .. " "
self.small_font:draw(canvas, _S.progress_report.percentage_pop:upper() .. " "
.. (hospital.population*100) .. "%", x + 450, y + 65)
end

View File

@@ -38,31 +38,31 @@ function UIResearch:UIResearch(ui)
self:UIFullscreen(ui)
local gfx = ui.app.gfx
if not pcall(function()
self.background = gfx:loadRaw("Res01V", 640, 480)
self.background = gfx:loadRaw("Res01V", 640, 480)
local palette = gfx:loadPalette("QData", "Res01V.pal")
palette:setEntry(255, 0xFF, 0x00, 0xFF) -- Make index 255 transparent
self.panel_sprites = gfx:loadSpriteTable("QData", "Res02V", true, palette)
self.label_font = gfx:loadFont("QData", "Font43V", false, palette)
self.number_font = gfx:loadFont("QData", "Font43V", false, palette)
self.number_font = gfx:loadFont("QData", "Font43V", false, palette)
end) then
ui:addWindow(UIInformation(ui, {_S.errors.dialog_missing_graphics}))
self:close()
return
end
self.hospital = ui.hospital
self.research = ui.hospital.research
-- stubs for backwards compatibility
local --[[persistable:research_policy_adjust]] function adjust(name) end
local --[[persistable:research_less_stub]] function less_stub() end
local --[[persistable:research_more_stub]] function more_stub() end
-- Close button
self:addPanel(0, 607, 447):makeButton(0, 0, 40, 40, 4, self.close):setTooltip(_S.tooltip.research.close)
self.adjust_buttons = {}
self:updateCategories()
self.waterclk = 0
self.ratclk = 0
self.waterpanel= self:addPanel(5, 2, 312)
@@ -94,7 +94,7 @@ function UIResearch:updateCategories()
local spacing = 41
local c1 = 372
local c2 = 450
local function handler_factory(area, mode)
return --[[persistable:research_policy_adjust_handler]] function(self)
self:adjustResearch(area, mode)
@@ -154,7 +154,7 @@ function UIResearch:adjustResearch(area, mode)
self.ui:playSound("Wrong2.wav")
end
end
res.research_policy.global = 0
for _, category in ipairs(research_categories) do
res.research_policy.global = res.research_policy.global + res.research_policy[category].frac
@@ -163,18 +163,18 @@ end
function UIResearch:onTick()
-- sprite index for the water are between 5 and 12
-- We use a sub clock
-- We use a sub clock
self.waterclk = self.waterclk + 1
if self.waterclk > 3 then
self.waterclk = 0
self.waterpanel.sprite_index = self.waterpanel.sprite_index + 1
if self.waterpanel.sprite_index > 12 then
self.waterpanel.sprite_index = 5
end
end
end
-- sprite index for the rat are between 10 and 15
-- We use a sub clock
-- We use a sub clock
self.ratclk = self.ratclk + 1
if self.ratclk > 3 then
self.ratclk = 0
@@ -182,9 +182,9 @@ function UIResearch:onTick()
self.ratpanel.sprite_index = self.ratpanel.sprite_index + 1
if self.ratpanel.sprite_index > 20 then
self.ratpanel.sprite_index = 13
end
end
end
return UIFullscreen.onTick(self)
end
@@ -192,7 +192,7 @@ function UIResearch:draw(canvas, x, y)
self.background:draw(canvas, self.x + x, self.y + y)
UIFullscreen.draw(self, canvas, x, y)
x, y = self.x + x, self.y + y
local num_font = self.number_font
local lbl_font = self.label_font
@@ -200,7 +200,7 @@ function UIResearch:draw(canvas, x, y)
local spacing = 41
local config = self.hospital.world.map.level_config
local research = self.research.research_policy
for i, category in ipairs(research_categories) do
local y = y + ytop + i * spacing
lbl_font:draw(canvas, _S.research.categories[category], x + 170, y)
@@ -210,7 +210,7 @@ function UIResearch:draw(canvas, x, y)
num_font:draw(canvas, research[category].frac, x + 270, y, 300, 0)
end
-- Display research progress.
if research[category].current
if research[category].current
and not research[category].current.dummy then
local ly = y + 26
local lx = x + 172
@@ -224,7 +224,7 @@ function UIResearch:draw(canvas, x, y)
end
end
end
num_font:draw(canvas, research.global, x + 270, y + 288, 300, 0)
end

View File

@@ -19,7 +19,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. --]]
local math_floor = math.floor
--! Staff management screen
class "UIStaffManagement" (UIFullscreen)
@@ -38,19 +38,19 @@ function UIStaffManagement:UIStaffManagement(ui, disease_selection)
self:close()
return
end
local hosp = ui.hospital
self.ui = ui
self.hospital = hosp
-- Order the staff
self:updateStaffList()
self.default_button_sound = "selectx.wav"
-- Close button
self:addPanel(0, 603, 443):makeButton(0, 0, 26, 26, 10, self.close):setTooltip(_S.tooltip.staff_list.close)
-- Top categories
local --[[persistable:staff_management_category]] function category(name, state, btn)
self:setCategory(name)
@@ -67,16 +67,16 @@ function UIStaffManagement:UIStaffManagement(ui, disease_selection)
self:addPanel(0, 319, 372):makeButton(0, 0, 112, 39, 7, self.payBonus):setTooltip(_S.tooltip.staff_list.bonus)
self:addPanel(0, 319, 418):makeButton(0, 0, 112, 39, 8, self.increaseSalary):setTooltip(_S.tooltip.staff_list.pay_rise)
self:addPanel(0, 438, 372):makeButton(0, 0, 45, 85, 9, self.fire):setTooltip(_S.tooltip.staff_list.sack)
-- "Arrow" to show title of doctors
self.arrow = self:addPanel(12, 259, 397)
self.arrow_position = 259
self.arrow.visible = false
-- Scroll bar dot
self.scroll_dot = self:addPanel(11, 21, 168)
self.scroll_dot.visible = false
-- Doctors' skills or progress towards them
self.progress_surgeon = self:addPanel(17, 188, 408)
self.progress_surgeon.visible = false
@@ -90,7 +90,7 @@ function UIStaffManagement:UIStaffManagement(ui, disease_selection)
self.progress_researcher.visible = false
self.qualified_researcher = self:addPanel(22, 268, 408):setTooltip(_S.tooltip.staff_list.researcher)
self.qualified_researcher.visible = false
-- Blankers for each row
local row_blankers = {}
local i
@@ -98,22 +98,22 @@ function UIStaffManagement:UIStaffManagement(ui, disease_selection)
row_blankers[i] = self:addColourPanel(50, 55 + i*27, 580, 27, 60, 174, 203)
end
self.row_blankers = row_blankers
-- Extra background for the portrait
self.portrait_back = self:addColourPanel(65, 374, 71, 81, 210, 255, 255)
self.portrait_back.visible = false
-- Doctor skill blankers
self.title_blanker = self:addColourPanel(225, 365, 90, 39, 57, 166, 198)
self.skill_blanker = self:addColourPanel(142, 406, 168, 54, 57, 166, 198)
-- Tooltip regions
self:makeTooltip(_S.tooltip.staff_list.happiness, 321, 51, 421, 75)
self:makeTooltip(_S.tooltip.staff_list.tiredness, 426, 51, 526, 75)
self:makeTooltip(_S.tooltip.staff_list.ability, 530, 51, 629, 75)
self:makeTooltip(_S.tooltip.staff_list.detail, 146, 367, 226, 407)
self:makeTooltip(_S.tooltip.staff_list.view_staff, 495, 371, 583, 458)
self.row_tooltips = {}
for line_num = 1, 10 do
self.row_tooltips[line_num] = {
@@ -123,7 +123,7 @@ function UIStaffManagement:UIStaffManagement(ui, disease_selection)
self:makeTooltip(_S.tooltip.staff_list.ability_2, 529, 84 + 27 * (line_num - 1), 628, 108 + 27 * (line_num - 1)),
}
end
self.seniority_tooltip =
self:makeTooltip(_S.tooltip.staff_list.doctor_seniority, 230, 367, 310, 407)
self.skills_tooltip =
@@ -154,7 +154,7 @@ function UIStaffManagement:updateStaffList(staff_member_removed)
selected_staff = nil
end
end
local hosp = self.hospital
local staff_members = {
Doctor = {},
@@ -196,7 +196,7 @@ function UIStaffManagement:setCategory(name)
else
self.scroll_dot.visible = false
end
self:updateTooltips()
end
@@ -224,18 +224,18 @@ function UIStaffManagement:draw(canvas, x, y)
UIFullscreen.draw(self, canvas, x, y)
x, y = self.x + x, self.y + y
local titles = self.title_font
-- Titles
titles:draw(canvas, _S.staff_list.morale, x + 323, y + 31, 95, 0)
titles:draw(canvas, _S.staff_list.tiredness, x + 427, y + 31, 95, 0)
titles:draw(canvas, _S.staff_list.skill, x + 530, y + 31, 95, 0)
-- Number of employees
titles:draw(canvas, #self.staff_members["Doctor"], x + 79, y + 57)
titles:draw(canvas, #self.staff_members["Nurse"], x + 145, y + 57)
titles:draw(canvas, #self.staff_members["Handyman"], x + 211, y + 57)
titles:draw(canvas, #self.staff_members["Receptionist"], x + 277, y + 57)
local total_happiness = 0
local total_fatigue = 0
local total_skill = 0
@@ -265,7 +265,7 @@ function UIStaffManagement:draw(canvas, x, y)
titles:draw(canvas, row_no + 10*(self.page-1), x + 58, y + 63 + row_no*27)
titles:draw(canvas, staff.profile.name, x + 88, y + 63 + row_no*27)
titles:draw(canvas, "$" .. staff.profile.wage, x + 230, y + 63 + row_no*27, 80, 0)
-- Draw the morale, tiredness and skill for this staff member
if happiness_bar_width ~= 0 then
for dx = 0, happiness_bar_width - 1 do
@@ -296,7 +296,7 @@ function UIStaffManagement:draw(canvas, x, y)
self.panel_sprites:draw(canvas, 16, x + 351 + dx, y + 59)
end
end
local fatigue_bar_width = math_floor((1 - (total_fatigue/#staff_list)) * 40 + 0.5)
if fatigue_bar_width ~= 0 then
for dx = 0, fatigue_bar_width - 1 do
@@ -336,11 +336,11 @@ function UIStaffManagement:draw(canvas, x, y)
-- Portrait
self.portrait_back.visible = true
profile:drawFace(canvas, x + 68, y + 377, self.face_parts)
-- 10 % increase in salary or a bonus:
titles:draw(canvas, "$" .. math_floor(profile.wage*0.1), x + 377, y + 387, 45, 0)
titles:draw(canvas, "$" .. math_floor(profile.wage*0.1 + profile.wage), x + 377, y + 432, 45, 0)
-- Attention to detail
local attention_bar_width = math_floor(profile.attention_to_detail * 40 + 0.5)
if attention_bar_width ~= 0 then

View File

@@ -45,7 +45,7 @@ function UITownMap:UITownMap(ui)
self:close()
return
end
self.default_button_sound = "selectx.wav"
self.default_buy_sound = "buy.wav"
@@ -58,7 +58,7 @@ function UITownMap:UITownMap(ui)
-- TODO display the areas, in the right color
-- TODO display everything in the areas
-- TODO multiplayer mode
-- NB: original TH closed the town map on right click of balance button.
-- This is likely a bug and we do not copy this behavior.
self:addPanel(0, 30, 420):makeButton(0, 0, 200, 50, 0, self.bankManager, nil, self.bankStats):setTooltip(_S.tooltip.town_map.balance)
@@ -79,7 +79,7 @@ function UITownMap:UITownMap(ui)
toggle_button(3, 140, 141, "fire_ext_enabled", _S.tooltip.town_map.fire_extinguishers)
toggle_button(4, 140, 193, "objects_enabled", _S.tooltip.town_map.objects)
toggle_button(5, 140, 246, "radiators_enabled", _S.tooltip.town_map.radiators)
self:makeTooltip(_S.tooltip.town_map.heat_level, 94, 318, 167, 331)
self:makeTooltip(_S.tooltip.town_map.heating_bill, 72, 351, 167, 374)
end
@@ -95,7 +95,7 @@ function UITownMap:initRuntimeConfig()
config.plants_enabled = true
config.fire_ext_enabled = true
config.objects_enabled = true
config.radiators_enabled = true
config.radiators_enabled = true
end
return config
end
@@ -144,17 +144,17 @@ function UITownMap:onMouseUp(button, x, y)
local sx, sy = self.ui.app.map:WorldToScreen(tx, ty)
self.ui:scrollMapTo(sx, sy)
self:close()
end
end
end
end
return UIFullscreen.onMouseUp(self, button, x, y) or redraw
end
function UITownMap:draw(canvas, x, y)
self.background:draw(canvas, self.x + x, self.y + y)
UIFullscreen.draw(self, canvas, x, y)
x, y = self.x + x, self.y + y
local app = self.ui.app
local hospital = self.ui.hospital
@@ -166,7 +166,7 @@ function UITownMap:draw(canvas, x, y)
if not config then
config = self:initRuntimeConfig()
end
-- We need to draw number of people, plants, fire extinguisers, other objects
-- and radiators.
-- NB: original TH's patient count was always 1 too big (started counting at 1)
@@ -182,7 +182,7 @@ function UITownMap:draw(canvas, x, y)
self.info_font:draw(canvas, fireext, x + 95, y + 157)
self.info_font:draw(canvas, objs, x + 95, y + 211)
self.info_font:draw(canvas, radiators, x + 95, y + 265)
-- Heating costs
local heating_costs = math.floor(((hospital.radiator_heat *10)* radiators)* 7.5)
self.info_font:draw(canvas, ("%8i"):format(heating_costs), x + 100, y + 355)
@@ -213,7 +213,7 @@ function UITownMap:draw(canvas, x, y)
town_map_offset_y + ent.tile_y * 3 + 1, size, size)
end
end
local function draw_entities_in_hospital(list, color, size)
for i, ent in ipairs(list) do
local tile_x, tile_y = ent.tile_x, ent.tile_y
@@ -231,22 +231,22 @@ function UITownMap:draw(canvas, x, y)
draw_entities_in_hospital(self.ui.hospital.staff, staff_color, 2)
draw_entities_in_hospital(self.ui.hospital.patients, patient_color, 2)
end
if config.radiators_enabled then
local radiator_color = canvas:mapRGB(255, 0, 70)
draw_entities(world:getObjectsById("radiator"), radiator_color, 1)
end
if config.fire_ext_enabled then
local fire_ext_color = canvas:mapRGB(216, 0, 0)
draw_entities(world:getObjectsById("extinguisher"), fire_ext_color, 2)
end
if config.plants_enabled then
local plant_color = canvas:mapRGB(127, 180, 73)
draw_entities(world:getObjectsById("plant"), plant_color, 2)
end
if config.objects_enabled then
local machine_list = {}
for _, obj_list in pairs(world.objects) do
@@ -260,7 +260,7 @@ function UITownMap:draw(canvas, x, y)
local machine_color = canvas:mapRGB(142, 182, 182)
draw_entities(machine_list, machine_color, 3)
end
-- plot number, owner, area and price
local plot_num = "-"
local tile_count = "-"

View File

@@ -27,7 +27,7 @@ class "UIFurnishCorridor" (Window)
function UIFurnishCorridor:UIFurnishCorridor(ui, objects, edit_dialog)
self:Window()
local app = ui.app
if edit_dialog then
self.modal_class = "furnish"
@@ -49,10 +49,10 @@ function UIFurnishCorridor:UIFurnishCorridor(ui, objects, edit_dialog)
self.total_text = (_S.buy_objects_window.total .. " "):gsub(" $", " ")
self.item_price = 0
self.total_price = 0
self.list_hover_index = 0
self.preview_anim = TH.animation()
self.objects = {
}
if objects then
@@ -69,7 +69,7 @@ function UIFurnishCorridor:UIFurnishCorridor(ui, objects, edit_dialog)
return o1.object.corridor_object < o2.object.corridor_object
end)
end
self:addPanel(228, 0, 0) -- Grid top
for y = 33, 103, 10 do
self:addPanel(229, 0, y) -- Grid body
@@ -81,12 +81,12 @@ function UIFurnishCorridor:UIFurnishCorridor(ui, objects, edit_dialog)
self:addPanel(234, 0, 248) -- Close button background
self:addPanel(234, 0, 252) -- Close button background extension
self:addPanel(242, 9, 237):makeButton(0, 0, 129, 28, 243, self.close):setTooltip(_S.tooltip.buy_objects_window.cancel)
self:addPanel(235, 146, 0) -- List top
self:addPanel(236, 146, 223) -- List bottom
self:addPanel(237, 154, 238):makeButton(0, 0, 197, 28, 238, self.confirm):setTooltip(_S.tooltip.buy_objects_window.confirm)
local i = 1
local function item_callback(index, qty)
local function item_callback(index, qty)
local is_negative_quantity = qty < 0
return --[[persistable:furnish_corridor_item_callback]] function(self)
if self:purchaseItem(index, qty) == 0 and not is_negative_quantity then
@@ -110,7 +110,7 @@ function UIFurnishCorridor:UIFurnishCorridor(ui, objects, edit_dialog)
end
i = i + 1
end
self:makeTooltip(_S.tooltip.buy_objects_window.price, 20, 168, 127, 187)
self:makeTooltip(_S.tooltip.buy_objects_window.total_value, 20, 196, 127, 215)
@@ -151,7 +151,7 @@ end
function UIFurnishCorridor:confirm()
self.ui:tutorialStep(1, 3, 4)
local to_purchase = {}
local to_sell = {}
for i, o in ipairs(self.objects) do
@@ -166,7 +166,7 @@ function UIFurnishCorridor:confirm()
self.ui.hospital:receiveMoney(build_cost * diff_qty, _S.transactions.sell_object .. ": " .. o.object.name, build_cost * diff_qty)
end
end
if self.edit_dialog then
self.edit_dialog:addObjects(to_purchase, false) -- payment already handled here
self.edit_dialog:removeObjects(to_sell, false) -- payment already handled here
@@ -190,12 +190,12 @@ end
function UIFurnishCorridor:draw(canvas, x, y)
Window.draw(self, canvas, x, y)
x, y = x + self.x, y + self.y
self.white_font:draw(canvas, self.title_text, x + 163, y + 18)
self.white_font:draw(canvas, self.price_text .. self.item_price, x + 24, y + 173)
self.white_font:draw(canvas, self.total_text .. self.total_price, x + 24, y + 202)
for i, o in ipairs(self.objects) do
local font = self.white_font
if i == self.list_hover_index then
@@ -204,18 +204,18 @@ function UIFurnishCorridor:draw(canvas, x, y)
font:draw(canvas, o.object.name, x + 163, y + 20 + i * 19)
font:draw(canvas, o.qty, x + 306, y + 20 + i * 19, 19, 0)
end
self.preview_anim:draw(canvas, x + 72, y + 57)
end
function UIFurnishCorridor:onMouseMove(x, y, dx, dy)
local repaint = Window.onMouseMove(self, x, y, dx, dy)
local hover_idx = 0
if 158 <= x and x < 346 and 34 <= y and y < 224 then
hover_idx = math_floor((y - 15) / 19)
end
if hover_idx ~= self.list_hover_index then
if 1 <= hover_idx and hover_idx <= #self.objects then
local obj = self.objects[hover_idx].object
@@ -225,6 +225,6 @@ function UIFurnishCorridor:onMouseMove(x, y, dx, dy)
self.list_hover_index = hover_idx
repaint = true
end
return repaint
end

View File

@@ -33,13 +33,13 @@ function UIHireStaff:UIHireStaff(ui)
self.white_font = ui.app.gfx:loadFont("QData", "Font01V")
self.face_parts = ui.app.gfx:loadRaw("Face01V", 65, 1350, nil, "Data", "MPalette.dat")
self:addKeyHandler("Enter", self.hire)
-- Left hand side tab backgrounds
self:addPanel(253, 0, 0)
self:addPanel(254, 0, 83)
self:addPanel(254, 0, 162)
self:addPanel(255, 0, 241)
-- Left hand side tabs
local --[[persistable:hire_staff_category]] function category(name, state, btn)
if #self.world.available_staff[name] == 0 then
@@ -58,15 +58,15 @@ function UIHireStaff:UIHireStaff(ui)
self:addPanel(268, 8, 166):makeToggleButton(0, 0, 40, 69, 269, category, "Handyman"):setTooltip(_S.tooltip.hire_staff_window.handymen),
self:addPanel(270, 8, 245):makeToggleButton(0, 0, 40, 69, 271, category, "Receptionist"):setTooltip(_S.tooltip.hire_staff_window.receptionists),
}
-- Right hand side
self:addPanel(256, 56, 0) -- Dialog header
for y = 49, 113, 11 do
self:addPanel(257,56, y) -- Dialog background
end
self.ability_bg_panel =
self.ability_bg_panel =
self:addPanel(260, 55, 114) -- Abilities background
self.skill_bg_panel =
self.skill_bg_panel =
self:addPanel(259, 68, 95):setTooltip(_S.tooltip.hire_staff_window.staff_ability, 109, 95) -- Skill background
self.skill_bg_panel.visible = false
self:addPanel(261, 55, 160) -- Wage background
@@ -83,7 +83,7 @@ function UIHireStaff:UIHireStaff(ui)
self:addPanel(274, 106, 277):makeButton(0, 10, 58, 27, 275, self.hire):setTooltip(_S.tooltip.hire_staff_window.hire)
self:addPanel(276, 163, 277):makeButton(0, 10, 28, 27, 277, self.close):setTooltip(_S.tooltip.hire_staff_window.cancel)
self:addPanel(278, 190, 277):makeButton(0, 10, 44, 27, 279, self.moveNext):setTooltip(_S.tooltip.hire_staff_window.next_person)
self:makeTooltip(_S.tooltip.hire_staff_window.salary, 68, 173, 227, 194)
self:makeTooltip(_S.tooltip.hire_staff_window.doctor_seniority, 68, 44, 151, 95)
self:makeTooltip(_S.tooltip.hire_staff_window.qualifications, 68, 134, 107, 167)
@@ -91,14 +91,14 @@ function UIHireStaff:UIHireStaff(ui)
self:makeTooltip(_S.tooltip.hire_staff_window.surgeon, 120, 136, 137, 167)
self:makeTooltip(_S.tooltip.hire_staff_window.psychiatrist, 137, 136, 164, 167)
self:makeTooltip(_S.tooltip.hire_staff_window.researcher, 164, 136, 191, 167)
self:updateTooltips()
end
function UIHireStaff:updateTooltips()
local cond = not not self.category
self.tooltip_regions[1].enabled = cond
cond = cond and self.category == "Doctor"
self.tooltip_regions[2].enabled = cond
self.tooltip_regions[3].enabled = cond
@@ -126,8 +126,8 @@ function UIHireStaff:hire()
if not profile then
self.ui:playSound "wrong2.wav"
return
end
if self.ui.hospital.balance < profile.wage then
end
if self.ui.hospital.balance < profile.wage then
self:cannotAfford()
self.ui:playSound "wrong2.wav"
return
@@ -143,12 +143,12 @@ function UIHireStaff:cannotAfford()
}
if msg then
self.world.ui.adviser:say(msg[math.random(1, #msg)])
end
end
end
function UIHireStaff:draw(canvas, x, y)
Window.draw(self, canvas, x, y)
x, y = self.x + x, self.y + y
local font = self.white_font
local staff = self.world.available_staff
font:draw(canvas, #staff.Doctor , x + 16, y + 58, 26, 0)

View File

@@ -25,11 +25,11 @@ class "UIInformation" (Window)
--!param text The text to show, held in a table. All elements of the table will be written
-- beneath each other. If instead a table within the table is supplied the texts
-- will be shown in consecutive dialogs.
--!param use_built_in_font Whether the built-in font should be used to make sure that
--!param use_built_in_font Whether the built-in font should be used to make sure that
-- the given message can be read without distortions.
function UIInformation:UIInformation(ui, text, use_built_in_font)
self:Window()
local app = ui.app
self.modal_class = "information"
self.esc_closes = true
@@ -49,7 +49,7 @@ function UIInformation:UIInformation(ui, text, use_built_in_font)
else
self.text = text
end
-- Window size parameters
self.text_width = 300
self.spacing = {
@@ -58,9 +58,9 @@ function UIInformation:UIInformation(ui, text, use_built_in_font)
t = 20,
b = 20,
}
self:onChangeLanguage()
-- Enter closes the window
self:addKeyHandler("Enter", self.close)
end
@@ -72,13 +72,13 @@ function UIInformation:onChangeLanguage()
rows = rows + math.floor(self.black_font:sizeOf(text) / 300 + 1)
rows = rows + 1
end
self.width = self.spacing.l + self.text_width + self.spacing.r
self.height = self.spacing.t + rows*12 + self.spacing.b
self:setDefaultPosition(0.5, 0.5)
self:removeAllPanels()
for x = 4, self.width - 4, 4 do
self:addPanel(12, x, 0) -- Dialog top and bottom borders
self:addPanel(16, x, self.height-4)
@@ -91,7 +91,7 @@ function UIInformation:onChangeLanguage()
self:addPanel(17, 0, self.height-4) -- Border bottom left corner
self:addPanel(13, self.width-4, 0) -- Border top right corner
self:addPanel(15, self.width-4, self.height-4) -- Border bottom right corner
-- Close button
self:addPanel(19, self.width - 30, self.height - 30):makeButton(0, 0, 18, 18, 20, self.close):setTooltip(_S.tooltip.information.close)
end
@@ -105,7 +105,7 @@ function UIInformation:draw(canvas, x, y)
last_y = self.black_font:drawWrapped(canvas, text:gsub("//", ""), dx + self.spacing.l, last_y, self.text_width)
last_y = self.black_font:drawWrapped(canvas, " ", dx + self.spacing.l, last_y, self.text_width)
end
Window.draw(self, canvas, x, y)
end

View File

@@ -36,7 +36,7 @@ function UIJukebox:UIJukebox(app)
self.panel_sprites = app.gfx:loadSpriteTable("QData", "Req13V", true)
self.white_font = app.gfx:loadFont("QData", "Font01V")
self.blue_font = app.gfx:loadFont("QData", "Font02V")
-- Dialog head (current track title & exit button)
self:addPanel(389, 0, 0)
for x = 30, self.width - 61, 24 do
@@ -44,7 +44,7 @@ function UIJukebox:UIJukebox(app)
end
self:addPanel(391, self.width - 61, 0)
self:addPanel(409, self.width - 42, 19):makeButton(0, 0, 24, 24, 410, self.close):setTooltip(_S.tooltip.jukebox.close)
self.play_btn =
self:addPanel(392, 0, 49):makeToggleButton(19, 2, 50, 24, 393, self.togglePlayPause):setSound("selectx.wav"):setTooltip(_S.tooltip.jukebox.play)
self:updatePlayButton()
@@ -52,7 +52,7 @@ function UIJukebox:UIJukebox(app)
self:addPanel(396, 115, 49):makeButton(0, 2, 24, 24, 397, self.audio.playNextBackgroundTrack, self.audio):setSound("selectx.wav"):setTooltip(_S.tooltip.jukebox.fast_forward)
self:addPanel(398, 157, 49):makeButton(0, 2, 24, 24, 399, self.stopBackgroundTrack):setSound("selectx.wav"):setTooltip(_S.tooltip.jukebox.stop)
self:addPanel(400, 185, 49):makeButton(0, 2, 24, 24, 401, self.loopTrack):setSound("selectx.wav"):setTooltip(_S.tooltip.jukebox.loop)
-- Track list
self.track_buttons = {}
for i, info in ipairs(self.audio.background_playlist) do
@@ -69,7 +69,7 @@ function UIJukebox:UIJukebox(app)
self:toggleTrack(i, info, not off)
end
end
-- Dialog footer
local y = 74 + 30 * #self.audio.background_playlist
self:addPanel(406, 0, y)
@@ -77,7 +77,7 @@ function UIJukebox:UIJukebox(app)
self:addPanel(407, x, y)
end
self:addPanel(408, self.width - 61, y)
self:makeTooltip(_S.tooltip.jukebox.current_title, 17, 17, 212, 46)
end
@@ -124,7 +124,7 @@ end
function UIJukebox:loopTrack()
local index = self.audio:findIndexOfCurrentTrack()
local playlist = self.audio.background_playlist
if playlist[index].loop then
playlist[index].loop = false
@@ -134,7 +134,7 @@ function UIJukebox:loopTrack()
self:toggleTrack(i, list_entry, true)
self.track_buttons[i]:toggle()
end
end
end
else
playlist[index].loop = true
@@ -151,7 +151,7 @@ end
function UIJukebox:draw(canvas, x, y)
Window.draw(self, canvas, x, y)
x, y = self.x + x, self.y + y
local playing = self.audio.background_music or ""
for i, info in ipairs(self.audio.background_playlist) do
local y = y + 47 + i * 30

View File

@@ -22,7 +22,7 @@ class "UIMachine" (Window)
function UIMachine:UIMachine(ui, machine, room)
self:Window()
local app = ui.app
self.esc_closes = true
self.machine = machine
@@ -34,7 +34,7 @@ function UIMachine:UIMachine(ui, machine, room)
self:setDefaultPosition(-20, 30)
self.panel_sprites = app.gfx:loadSpriteTable("QData", "Req03V", true)
self.white_font = app.gfx:loadFont("QData", "Font01V")
self:addPanel(333, 0, 0) -- Dialog header
self:addPanel(334, 0, 74) -- The next part
for y = 131, 180, 7 do
@@ -55,7 +55,7 @@ function UIMachine:UIMachine(ui, machine, room)
-- Close button
self:addPanel(337, 146, 18):makeButton(0, 0, 24, 24, 338, self.close)
:setTooltip(_S.tooltip.machine_window.close)
self:makeTooltip(_S.tooltip.machine_window.name, 18, 19, 139, 42)
self:makeTooltip(_S.tooltip.machine_window.times_used, 18, 49, 139, 77)
self:makeTooltip(_S.tooltip.machine_window.status, 24, 88, 128, 115)
@@ -65,7 +65,7 @@ function UIMachine:draw(canvas, x, y)
Window.draw(self, canvas, x, y)
x, y = self.x + x, self.y + y
local mach = self.machine
local font = self.white_font
local output
if self.room.needs_repair then
@@ -110,7 +110,7 @@ function UIMachine:replaceMachine()
self.ui:addWindow(UIConfirmDialog(self.ui,
_S.confirmation.replace_machine:format(machine.object_type.name, cost),
--[[persistable:replace_machine_confirm_dialog]]function()
hosp:spendMoney(cost, _S.transactions.machine_replacement)
machine.total_usage = 0
machine.times_used = 0

View File

@@ -38,30 +38,30 @@ function UIMapEditor:UIMapEditor(ui)
self.width = math.huge
self.height = math.huge
self.ui = ui
self.command_stack = CommandStack()
-- For when there are multiple things which could be sampled from a tile,
-- keep track of the index of which one was most recently sampled, so that
-- next time a different one is sampled.
self.sample_i = 1
-- The block to put on the UI layer as a preview for what will be placed
-- by the current drawing operation.
self.block_brush_preview = 0
self:classifyBlocks()
-- A sprite table containing a "cell outline" sprite
self.cell_outline = TheApp.gfx:loadSpriteTable("Bitmap", "aux_ui", true)
-- Coordinates in Lua tile space of the mouse cursor.
self.mouse_cell_x = 0
self.mouse_cell_y = 0
end
function UIMapEditor:classifyBlocks()
-- Classify each block / tile with a type, subtype, and category.
-- Type and subtype are used by this file, and by the UI code to determine
@@ -139,17 +139,17 @@ function UIMapEditor:classifyBlocks()
block_info[i] = {"floor", "simple", "Outside"}
end
block_info[208].base = 3
-- adds street lights, could do with mirrors of these to have lamps facing different directions
-- adds street lights, could do with mirrors of these to have lamps facing different directions
for i = 209, 210 do
local pair
local category = "External"
local dir = i % 2 == 0 and "north" or "west"
if i ~= 209 then
local dir = i % 2 == 0 and "north" or "west"
if i ~= 209 then
pair = i - 1
end
end
block_info[i] = {"wall", dir, category, pair = pair}
end
MapEditorSetBlocks(self.ui.app.map.blocks, block_info) -- pass data to UI
self.block_info = block_info
end
@@ -158,20 +158,20 @@ function UIMapEditor:draw(canvas, ...)
local ui = self.ui
local x, y = ui:WorldToScreen(self.mouse_cell_x, self.mouse_cell_y)
self.cell_outline:draw(canvas, 2, x - 32, y)
Window.draw(self, canvas, ...)
end
function UIMapEditor:onMouseMove(x, y, dx, dy)
local repaint = Window.onMouseMove(self, x, y, dx, dy)
local ui = self.ui
local wxr, wyr = ui:ScreenToWorld(self.x + x, self.y + y)
local wx = math_floor(wxr)
local wy = math_floor(wyr)
local map = self.ui.app.map
-- Update the stored state of cursor position, and trigger a repaint as the
-- cell outline sprite should track the cursor position.
if wx ~= self.mouse_cell_x or wy ~= self.mouse_cell_y then
@@ -227,7 +227,7 @@ function UIMapEditor:onMouseMove(x, y, dx, dy)
repaint = true
end
end
return repaint
end
@@ -262,7 +262,7 @@ function UIMapEditor:onMouseDown(button, x, y)
self:setPaintRect(0, 0, 0, 0)
repaint = true
end
return Window.onMouseDown(self, button, x, y) or repaint
end
@@ -279,7 +279,7 @@ function UIMapEditor:onMouseUp(button, x, y)
self.command_stack:add(self.current_command)
repaint = true
end
return Window.onMouseUp(self, button, x, y) or repaint
end
@@ -318,7 +318,7 @@ end
function UIMapEditor:doLargePaint(x, y)
-- Perform a "large" paint. At the moment, this is triggered by a double
-- left click, and results in a floor tile "flood fill" operation.
-- Get the Lua tile coordinate of the tile to start filling from.
x, y = self.ui:ScreenToWorld(x, y)
x = math_floor(x)
@@ -326,7 +326,7 @@ function UIMapEditor:doLargePaint(x, y)
if x <= 0 or y <= 0 then
return
end
-- The click which preceeded the double click should have set "old_floors"
-- with the contents of the tile prior to the single click.
if not self.old_floors then
@@ -349,12 +349,12 @@ function UIMapEditor:doLargePaint(x, y)
if match_f == brush_f then
return
end
-- Reset the starting tile as to simplify the upcoming loop.
self.current_command_cell:addTile(x, y, 1, match_f)
map:setCell(x, y, 1, match_f)
local to_visit = {[key] = {x, y}}
local visited = {[key] = true}
-- Mark the tiles beyond the edge of the map as visited, as to prevent the
@@ -412,13 +412,13 @@ function UIMapEditor:finishPaint(apply)
local step_base_y = math.floor(self.paint_start_wy)
local xstep = self.paint_step_x
local ystep = self.paint_step_y
-- Determine what kind of thing is being painted.
local is_wall = self.block_info[self.block_brush_preview]
is_wall = is_wall and is_wall[1] == "wall" and is_wall[2]
local is_simple_floor = self.block_info[self.block_brush_preview]
is_simple_floor = is_simple_floor and is_simple_floor[1] == "floor" and is_simple_floor[2] == "simple"
-- To allow the double click handler to know what was present before the
-- single click which preceeds it, the prior contents of the floor layer is
-- saved.
@@ -500,7 +500,7 @@ function UIMapEditor:setPaintRect(x, y, w, h, xstep, ystep)
local step_base_y = math.floor(self.paint_start_wy)
xstep = xstep or old_xstep
ystep = ystep or old_ystep
-- Create a rectangle which contains both the old and new rectangles, as
-- this contains all tiles which may need to change.
local left, right, top, bottom = x, x + w - 1, y, y + h - 1
@@ -518,7 +518,7 @@ function UIMapEditor:setPaintRect(x, y, w, h, xstep, ystep)
bottom = rect.y + rect.h - 1
end
end
-- Determine what kind of thing is being painted
local is_wall = self.block_info[self.block_brush_preview]
local block_brush_preview_pair = is_wall and is_wall.pair
@@ -610,7 +610,7 @@ function UIMapEditor:sampleBlock(x, y)
end
end
end
if wx == self.recent_sample_x and wy == self.recent_sample_y then
self.sample_i = self.sample_i + 1
else

View File

@@ -27,7 +27,7 @@ class "UIMenuBar" (Window)
function UIMenuBar:UIMenuBar(ui)
self:Window()
local app = ui.app
self.ui = ui
self.on_top = true
@@ -47,7 +47,7 @@ function UIMenuBar:UIMenuBar(ui)
-- The list of menus which should be displayed
-- This list satifies: open_menus[x] == nil or open_menus[x].level == x
self.open_menus = {}
self:makeMenu(app)
end
@@ -160,20 +160,20 @@ function UIMenuBar:draw(canvas)
panel_sprites_draw(panel_sprites, canvas, 3, x, 0)
panel_sprites_draw(panel_sprites, canvas, 6, x, 6)
panel_sprites_draw(panel_sprites, canvas, 9, x, 10)
for _, menu in ipairs(self.menus) do
self.white_font:draw(canvas, menu.title, menu.x, menu.y, 0, menu.height)
end
for _, menu in ipairs(self.open_menus) do
self:drawMenu(menu, canvas)
end
-- Draw clock
if self.ui.app.config.twentyfour_hour_clock then
if self.ui.app.config.twentyfour_hour_clock then
self.white_font:draw(canvas, os.date("%H:%M"), self.width-45, 2, 0)
else
self.white_font:draw(canvas, os.date("%I:%M %p"), self.width-65, 2, 0)
end
end
end
function UIMenuBar:drawMenu(menu, canvas)
@@ -184,12 +184,12 @@ function UIMenuBar:drawMenu(menu, canvas)
menu.render_list:draw(canvas, x, y)
canvas:nonOverlapping(false)
local btmy = y + h - 6
panel_sprites_draw(panel_sprites, canvas, 3, x + w - 10, y)
panel_sprites_draw(panel_sprites, canvas, 3, x + w - 10, y)
for y = y + 6, y + h - 6, 4 do
panel_sprites_draw(panel_sprites, canvas, 6, x + w - 10, y)
end
panel_sprites_draw(panel_sprites, canvas, 9, x + w - 10, btmy)
x = menu.x
y = menu.y + 4
for i, item in ipairs(menu.items) do
@@ -433,7 +433,7 @@ function UIMenuBar:calculateMenuSize(menu)
local render_list = TH.spriteList()
menu.render_list = render_list
render_list:setSheet(self.panel_sprites)
render_list:append(1, 0, 0)
for x = 10, w - 10, 10 do
render_list:append(2, x, 0)
@@ -448,8 +448,8 @@ function UIMenuBar:calculateMenuSize(menu)
render_list:append(7, 0, btmy)
for x = 10, w - 10, 10 do
render_list:append(8, x, btmy)
end
end
end
end
@@ -519,7 +519,7 @@ function UIMenuBar:makeMenu(app)
:appendItem(_S.menu_file.restart, function() app:restart() end)
:appendItem(_S.menu_file.quit, function() self.ui:quit() end)
self:addMenu(_S.menu.file, menu)
local options = UIMenu()
if app.audio.has_bg_music then
local function vol(level, setting)
@@ -546,7 +546,7 @@ function UIMenuBar:makeMenu(app)
""
end
end
local function appendVolume(setting)
local menu = UIMenu() -- The three Volume menus
for level = 10, 100, 10 do
@@ -554,53 +554,53 @@ function UIMenuBar:makeMenu(app)
end
return menu
end
options:appendCheckItem(_S.menu_options.sound,
app.config.play_sounds,
function(item)
app.audio:playSoundEffects(item.checked)
function(item)
app.audio:playSoundEffects(item.checked)
app:saveConfig()
end,
nil,
function()
return app.config.play_sounds
function()
return app.config.play_sounds
end)
options:appendCheckItem(_S.menu_options.announcements,
app.config.play_announcements,
function(item)
app.config.play_announcements = item.checked
app:saveConfig()
app.config.play_announcements,
function(item)
app.config.play_announcements = item.checked
app:saveConfig()
end,
nil,
function()
return app.config.play_announcements
function()
return app.config.play_announcements
end)
local function musicStatus(item)
return not not app.audio.background_music and not app.audio.background_paused
end
end
options:appendCheckItem(_S.menu_options.music,
app.config.play_music,
app.config.play_music,
function(item)
app.config.play_music = item.checked
self.ui:togglePlayMusic(item)
app:saveConfig()
app:saveConfig()
end,
nil,
function(musicStatus)
return app.config.play_music
end)
options
function(musicStatus)
return app.config.play_music
end)
options
:appendMenu(_S.menu_options.sound_vol, appendVolume("sound"))
:appendMenu(_S.menu_options.announcements_vol, appendVolume("announcement"))
:appendMenu(_S.menu_options.music_vol, appendVolume("music"))
:appendMenu(_S.menu_options.music_vol, appendVolume("music"))
:appendItem(_S.menu_options.jukebox, function() self.ui:addWindow(UIJukebox(app)) end)
end
local function boolean_runtime_config(option)
return not not app.runtime_config[option], function(item)
app.runtime_config[option] = item.checked
@@ -613,35 +613,35 @@ function UIMenuBar:makeMenu(app)
function(item) app.config.prevent_edge_scrolling = not item.checked end,
nil,
function() return not app.config.prevent_edge_scrolling end)
options:appendCheckItem(_S.menu_options.adviser_disabled,
options:appendCheckItem(_S.menu_options.adviser_disabled,
not app.config.adviser_disabled,
function(item)
function(item)
app.config.adviser_disabled = not item.checked
app:saveConfig()
app:saveConfig()
end,
nil,
function()
function()
return not app.config.adviser_disabled
end)
options:appendCheckItem(_S.menu_options.twentyfour_hour_clock,
options:appendCheckItem(_S.menu_options.twentyfour_hour_clock,
app.config.twentyfour_hour_clock,
function(item)
app.config.twentyfour_hour_clock = item.checked
app:saveConfig()
end)
local function temperatureDisplay(method)
return method == 1, function()
app.world.map:setTemperatureDisplayMethod(method)
end, "", function ()
end, "", function ()
return app.world.map.temperature_display_method == method
end
end
end
local function wageIncreaseRequests(grant)
return grant, function()
return grant, function()
app.world:getLocalPlayerHospital().policies.grant_wage_increase = grant
end, "", function ()
if app.world:getLocalPlayerHospital().policies.grant_wage_increase == nil then
@@ -650,18 +650,18 @@ function UIMenuBar:makeMenu(app)
return app.world:getLocalPlayerHospital().policies.grant_wage_increase == grant
end
end
options:appendMenu(_S.menu_options.wage_increase, UIMenu()
:appendCheckItem(_S.menu_options_wage_increase.grant, wageIncreaseRequests(true))
:appendCheckItem(_S.menu_options_wage_increase.deny, wageIncreaseRequests(false))
)
options:appendMenu(_S.menu_options.warmth_colors, UIMenu()
:appendCheckItem(_S.menu_options_warmth_colors.choice_1, temperatureDisplay(1))
:appendCheckItem(_S.menu_options_warmth_colors.choice_2, temperatureDisplay(2))
:appendCheckItem(_S.menu_options_warmth_colors.choice_3, temperatureDisplay(3))
)
local function rate(speed)
return speed == "Normal", function()
app.world:setSpeed(speed)
@@ -669,7 +669,7 @@ function UIMenuBar:makeMenu(app)
return app.world:isCurrentSpeed(speed)
end
end
options:appendMenu(_S.menu_options.game_speed, UIMenu()
:appendCheckItem(_S.menu_options_game_speed.pause, rate("Pause"))
:appendCheckItem(_S.menu_options_game_speed.slowest, rate("Slowest"))

View File

@@ -23,10 +23,10 @@ class "UIMessage" (Window)
function UIMessage:UIMessage(ui, x, stop_x, onClose, type, message, owner, timeout, default_choice, callback)
self:Window()
local app = ui.app
ui:playSound("NewFax.wav")
self.esc_closes = false
self.on_top = false
self.onClose = onClose
@@ -57,12 +57,12 @@ function UIMessage:UIMessage(ui, x, stop_x, onClose, type, message, owner, timeo
self.y = 4
self.panel_sprites = app.gfx:loadSpriteTable("Data", "Panel02V", true)
self.type = type
local types = { emergency = 43, epidemy = 45, strike = 47, personality = 49, information = 51, disease = 53, report = 55 }
local type = types[type]
self.can_dismiss = self.type ~= "strike" and #self.message.choices == 1
self.button = self:addPanel(type, 0, 0)
:setTooltip(self.can_dismiss and _S.tooltip.message.button_dismiss or _S.tooltip.message.button) -- FIXME: tooltip doesn't work very well here
:makeToggleButton(0, 0, 30, 28, type + 1, self.openMessage, nil, self.dismissMessage)

View File

@@ -32,7 +32,7 @@ class "UIPatient" (Window)
function UIPatient:UIPatient(ui, patient)
self:Window()
local app = ui.app
self.esc_closes = true
self.ui = ui
@@ -44,7 +44,7 @@ function UIPatient:UIPatient(ui, patient)
self.font = app.gfx:loadFont("QData", "Font74V") -- Font used in the treatment history
self.patient = patient
self.visible_diamond = ui:makeVisibleDiamond(75, 76)
self:addPanel(320, 15, 0) -- Graph top
self:addPanel(321, 15, 61) -- Graph bottom
@@ -58,7 +58,7 @@ function UIPatient:UIPatient(ui, patient)
self:addPanel(323, 0, 201) -- View circle top
self:addPanel(324, 0, 254) -- View circle bottom
self:addPanel(325, 147, 21):makeButton(0, 0, 24, 24, 326, self.close):setTooltip(_S.tooltip.patient_window.close)
-- If the patient has been diagnosed the "guess cure" button is not visible and
-- if the patient is going home it is not possible to kick him/her anymore.
self:addPanel(411, 14 + 132, 61 + 19):makeButton(0, 0, 25, 31, 412, self.viewQueue):setTooltip(_S.tooltip.patient_window.queue)
@@ -74,21 +74,21 @@ function UIPatient:UIPatient(ui, patient)
self.guess_button = self:addPanel(413, 14 + 117, 61 + 58):makeButton(0, 0, 38, 38, 414, self.guessDisease):setTooltip(_S.tooltip.patient_window.abort_diagnosis)
self.guess_blanker = self:addColourPanel(14 + 115, 61 + 56, 45, 45, 113, 117, 170)
-- Set correct initial visibility/enabledness of the three buttons and their blankers
self:updateInformation()
self:makeTooltip(_S.tooltip.patient_window.happiness, 33, 117, 124, 141)
self:makeTooltip(_S.tooltip.patient_window.thirst, 33, 141, 124, 169)
self:makeTooltip(_S.tooltip.patient_window.warmth, 33, 169, 124, 203)
-- Non-rectangular tooltip has to be realized with dynamic tooltip at the moment
self:makeDynamicTooltip(--[[persistable:patient_window_center_tooltip]]function(x, y)
if is_in_view_circle(x, y) then
return _S.tooltip.patient_window.center_view
end
end, 17, 216, 92, 292)
-- Always add this because of a race condition if the user clicks a patient
-- that's already going home, then clicks another, the handler is left empty. Bad.
-- Just do a going_home check when called.
@@ -132,8 +132,8 @@ function UIPatient:draw(canvas, x_, y_)
px, py = self.ui.limitPointToDiamond(px, py, self.visible_diamond, true)
self.ui.app.map:draw(canvas, px, py, 75, 76, x + 17, y + 216)
Window.draw(self, canvas, x_, y_)
-- The patients happiness. Each bar is by default half way if the actual value
-- The patients happiness. Each bar is by default half way if the actual value
-- cannot be found.
local happiness_bar_width = 22
if patient.attributes["happiness"] then
@@ -291,7 +291,7 @@ function UIPatient:guessDisease()
end
patient:setDiagnosed(true)
patient:setNextAction({
name = "seek_room",
name = "seek_room",
room_type = patient.disease.treatment_rooms[1],
treatment_room = true,
}, 1)

View File

@@ -33,16 +33,16 @@ class "UIPlaceObjects" (Window)
--[[ Constructor for the class.
!param ui (UI) The active ui.
!param object_list (table) a list of tables with objects to place. Keys are "object", "qty" and
"existing_object". The first is the object_type of the object, the second how many, and if the key
"existing_object". The first is the object_type of the object, the second how many, and if the key
"existing_object" is set it should be an already existing object that is about to be moved.
In particular, if that object has a variable called current_frame then that frame will be used
In particular, if that object has a variable called current_frame then that frame will be used
when drawing the object as it is being moved.
]]
function UIPlaceObjects:UIPlaceObjects(ui, object_list, pay_for)
self:Window()
object_list = object_list or {} -- Default argument
local app = ui.app
self.modal_class = "main"
self.ui = ui
@@ -57,7 +57,7 @@ function UIPlaceObjects:UIPlaceObjects(ui, object_list, pay_for)
self.blue_font = app.gfx:loadFont("QData", "Font02V")
self.title_text = _S.rooms_short.corridor_objects
self.desc_text = _S.place_objects_window.place_objects_in_corridor
self:addPanel(112, 0, 0) -- Dialog header
for y = 48, 83, 7 do
self:addPanel(113, 0, y) -- Desc text box
@@ -71,20 +71,20 @@ function UIPlaceObjects:UIPlaceObjects(ui, object_list, pay_for)
self.pickup_button =
self:addPanel(119, 92, 100):makeButton(1, 8, 41, 42, 120, self.pickupItems):setTooltip(_S.tooltip.place_objects_window.pick_up)
:setDisabledSprite(128):enable(false):makeToggle() -- Disabled pick up items button
self.confirm_button =
self.confirm_button =
self:addPanel(121, 134, 100):makeButton(1, 8, 43, 42, 122, self.confirm):setTooltip(_S.tooltip.place_objects_window.confirm)
:setDisabledSprite(129):enable(false):setSound"YesX.wav" -- Disabled confirm button
self.list_header = self:addPanel(123, 0, 146) -- Object list header
self.list_header.visible = false
self.objects = {}
self.object_footprint = {}
self.num_slots = 0
self:addObjects(object_list, pay_for)
self:addKeyHandler("space", self.tryNextOrientation)
ui:setWorldHitTest(false)
end
@@ -93,13 +93,13 @@ function UIPlaceObjects:resize(num_slots)
if self.num_slots == num_slots then
return
end
if num_slots == 0 then
self.list_header.visible = false
else
self.list_header.visible = true
end
local function idx(i)
return --[[persistable:place_objects_idx1]] function(self)
if i == self.active_index then
@@ -115,7 +115,7 @@ function UIPlaceObjects:resize(num_slots)
end
end
end
if self.num_slots < num_slots then
-- change last panel
if self.num_slots > 0 then
@@ -123,7 +123,7 @@ function UIPlaceObjects:resize(num_slots)
last_panel.y = last_panel.y + 4
last_panel.sprite_index = 124
end
-- add new panels (save last one)
for i = self.num_slots + 1, num_slots - 1 do
self:addPanel(124, 0, 121 + i * 29)
@@ -159,11 +159,11 @@ function UIPlaceObjects:addObjects(object_list, pay_for)
if not object_list then
object_list = {}
end
if #object_list == 0 and #self.objects == 0 then
return
end
local function idx(i)
return --[[persistable:place_objects_idx2]] function(self)
if i == self.active_index then
@@ -173,7 +173,7 @@ function UIPlaceObjects:addObjects(object_list, pay_for)
end
end
end
-- Detect objects already existing in self.objects and increment its quantity rather than adding new objects lines
local new_index = 1
while true do
@@ -210,7 +210,7 @@ function UIPlaceObjects:addObjects(object_list, pay_for)
self.object_slave_anim = TH.animation()
local total_objects = #self.objects + #object_list
self:resize(total_objects)
for _, object in pairs(object_list) do
if object.existing_object then
object.existing_objects = {object.existing_object}
@@ -221,7 +221,7 @@ function UIPlaceObjects:addObjects(object_list, pay_for)
self.ui.hospital:spendMoney(object.qty * build_cost, _S.transactions.buy_object .. ": " .. object.object.name, object.qty * build_cost)
end
end
-- sort list by size of object (number of tiles in the first existing orientation (usually north))
table.sort(self.objects, function(o1, o2)
local orient1 = o1.object.orientations.north or o1.object.orientations.east
@@ -230,7 +230,7 @@ function UIPlaceObjects:addObjects(object_list, pay_for)
or o2.object.orientations.south or o2.object.orientations.west
return #orient1.footprint > #orient2.footprint
end)
self.active_index = 0 -- avoid case of index changing from 1 to 1
self:setActiveIndex(1)
self:onCursorWorldPositionChange(self.ui:getCursorPosition(self))
@@ -292,7 +292,7 @@ function UIPlaceObjects:removeObjects(object_list, refund)
if not object_list then
object_list = {}
end
for i, o in ipairs(object_list) do
for j, p in ipairs(self.objects) do
if o.object.id == p.object.id then
@@ -322,7 +322,7 @@ function UIPlaceObjects:setActiveIndex(index)
return
end
self.active_index = index
local object = self.objects[self.active_index].object
if object.id == "reception_desk" then
self.ui:tutorialStep(1, 6, 4)
@@ -339,7 +339,7 @@ function UIPlaceObjects:setActiveIndex(index)
anims:setAnimationGhostPalette(anim, ghost)
end
end
if object.locked_to_wall then
local wx, wy, wo = self:calculateBestPlacementPosition(0, 0)
self.object_cell_x, self.object_cell_y = wx, wy
@@ -366,7 +366,7 @@ local orient_next = {
function UIPlaceObjects:setOrientation(orient)
self.object_orientation = orient
local object_data = self.objects[self.active_index]
local object = object_data.object
local anim = object.idle_animations[orient]
@@ -450,10 +450,10 @@ function UIPlaceObjects:onMouseUp(button, x, y)
-- We don't want to place objects because we are selecting new objects for adding in a room being built/edited
-- Or the game is paused.
if not self.place_objects or not self.world.user_actions_allowed then
if not self.place_objects or not self.world.user_actions_allowed then
return
end
if button == "right" then
self:tryNextOrientation()
repaint = true
@@ -469,7 +469,7 @@ function UIPlaceObjects:onMouseUp(button, x, y)
end
end
end
return repaint
end
@@ -488,7 +488,7 @@ function UIPlaceObjects:placeObject(dont_close_if_empty)
end
if real_obj then
-- If there is such an object then we don't want to make a new one, but move this one instead.
if real_obj.orientation_before and real_obj.orientation_before ~= self.object_orientation then
if real_obj.orientation_before and real_obj.orientation_before ~= self.object_orientation then
real_obj:initOrientation(self.object_orientation)
end
real_obj:setTile(self.object_cell_x, self.object_cell_y)
@@ -511,7 +511,7 @@ function UIPlaceObjects:placeObject(dont_close_if_empty)
self:removeObject(object, dont_close_if_empty)
object.orientation_before = nil
return real_obj
end
@@ -535,13 +535,13 @@ function UIPlaceObjects:draw(canvas, x, y)
canvas:scale(1)
end
end
Window.draw(self, canvas, x, y)
x, y = x + self.x, y + self.y
self.white_font:draw(canvas, self.title_text, x + 17, y + 21, 153, 0)
self.white_font:drawWrapped(canvas, self.desc_text, x + 20, y + 46, 147)
for i, o in ipairs(self.objects) do
local font = self.white_font
local y = y + 136 + i * 29
@@ -597,7 +597,7 @@ function UIPlaceObjects:setBlueprintCell(x, y)
local opt_tiles_blocked = 0
local world = self.ui.app.world
local roomId = self.room and self.room.id
local passable_flag
local passable_flag
local direction = self.object_orientation
local direction_parameters = {
north = { x = 0, y = -1, buildable_flag = "buildableNorth", passable_flag = "travelNorth", needed_side = "need_north_side"},
@@ -605,7 +605,7 @@ function UIPlaceObjects:setBlueprintCell(x, y)
south = { x = 0, y = 1, buildable_flag = "buildableSouth", passable_flag = "travelSouth", needed_side = "need_south_side"},
west = { x = -1, y = 0, buildable_flag = "buildableWest", passable_flag = "travelWest", needed_side = "need_west_side"}
}
local function setAllGood(xy)
if xy.optional then
opt_tiles_blocked = opt_tiles_blocked + 1
@@ -616,7 +616,7 @@ function UIPlaceObjects:setBlueprintCell(x, y)
allgood = false
end
end
for i, xy in ipairs(object_footprint) do
local x = x + xy[1]
local y = y + xy[2]
@@ -638,7 +638,7 @@ function UIPlaceObjects:setBlueprintCell(x, y)
flag = direction_parameters[direction]["buildable_flag"]
passable_flag = direction_parameters[direction]["passable_flag"]
end
local cell_flags = map:getCellFlags(x, y, flags)[flag]
local is_object_allowed = false
if roomId and flags.roomId ~= roomId then
@@ -663,19 +663,19 @@ function UIPlaceObjects:setBlueprintCell(x, y)
end
end
end
local function isTileValid(x, y, complete_cell, flags, flag_name, need_side)
local function isTileValid(x, y, complete_cell, flags, flag_name, need_side)
if complete_cell or need_side then
return flags[flag_name]
end
for i, xy in ipairs(object_footprint) do
if(xy[1] == x and xy[2] == y) then
if(xy[1] == x and xy[2] == y) then
return flags[flag_name]
end
end
end
return true
end
if cell_flags and not xy.only_side then
for _, value in pairs(direction_parameters) do
local x1, y1 = xy[1] + value["x"], xy[2] + value["y"]
@@ -684,13 +684,13 @@ function UIPlaceObjects:setBlueprintCell(x, y)
break
end
end
end
end
if cell_flags and is_object_allowed then
if not xy.invisible then
map:setCell(x, y, 4, good_tile)
end
else
else
if not xy.invisible then
map:setCell(x, y, 4, bad_tile)
end
@@ -766,11 +766,11 @@ function UIPlaceObjects:setBlueprintCell(x, y)
if map:getCellFlags(x, y)[passable_flag] == true then
local checked_x, checked_y = x, y
if passable_flag == "travelNorth" or passable_flag == "travelSouth" then
checked_y = checked_y + (passable_flag == "travelNorth" and -1 or 1)
else
checked_x = checked_x + (passable_flag == "travelEast" and 1 or -1)
checked_y = checked_y + (passable_flag == "travelNorth" and -1 or 1)
else
checked_x = checked_x + (passable_flag == "travelEast" and 1 or -1)
end
flags = {}
flags[passable_flag] = false
map:setCellFlags(x, y, flags)
@@ -791,7 +791,7 @@ function UIPlaceObjects:setBlueprintCell(x, y)
self.object_blueprint_good = allgood
self.ui:tutorialStep(1, allgood and 5 or 4, allgood and 4 or 5)
end
else
self.object_footprint = {}
end
@@ -803,11 +803,11 @@ local function NearestPointOnLine(lx1, ly1, lx2, ly2, px, py)
local ly = ly1 - ly2
px = px - lx2
py = py - ly2
-- Project point onto line (scale everything to make (lx, ly) be on the unit
-- circle, then dot product).
local d = (lx * px + ly * py) / (lx * lx + ly * ly)
if d <= 0 then
return lx2, ly2
elseif d >= 1 then
@@ -856,7 +856,7 @@ function UIPlaceObjects:onCursorWorldPositionChange(x, y)
if not self.place_objects then -- We don't want to place objects because we are selecting new objects for adding in a room being built/edited
return repaint
end
repaint = true
if self.world.user_actions_allowed then
local wx, wy, wo = self:calculateBestPlacementPosition(x, y)
@@ -871,7 +871,7 @@ function UIPlaceObjects:onCursorWorldPositionChange(x, y)
else
self:clearBlueprint()
end
return repaint
end

View File

@@ -78,7 +78,7 @@ function UIPlaceStaff:draw(canvas)
self.world.map.th:getCellFlags(self.tile_x, self.tile_y, flag_cache)
local room = self.world:getRoom(self.tile_x, self.tile_y)
local valid = flag_cache.hospital and flag_cache.passable and
(self.allow_in_rooms or flag_cache.roomId == 0) and
(self.allow_in_rooms or flag_cache.roomId == 0) and
(not room and true or not room.crashed)
self.anim:setFlag(valid and 0 or flag_altpal)
local zoom = self.ui.zoom_factor
@@ -104,7 +104,7 @@ function UIPlaceStaff:onMouseUp(button, x, y)
self.world.map.th:getCellFlags(self.tile_x, self.tile_y, flag_cache)
local room = self.world:getRoom(self.tile_x, self.tile_y)
if flag_cache.hospital and flag_cache.passable
and (self.allow_in_rooms or flag_cache.roomId == 0)
and (self.allow_in_rooms or flag_cache.roomId == 0)
and (not room and true or not room.crashed) then
if self.staff then
self.staff:setTile(self.tile_x, self.tile_y)

View File

@@ -27,7 +27,7 @@ class "UIQueue" (Window)
function UIQueue:UIQueue(ui, queue)
self:Window()
local app = ui.app
self.esc_closes = true
self.ui = ui
@@ -37,9 +37,9 @@ function UIQueue:UIQueue(ui, queue)
self:setDefaultPosition(0.5, 0.5)
self.panel_sprites = app.gfx:loadSpriteTable("QData", "Req06V", true)
self.white_font = app.gfx:loadFont("QData", "Font01V")
self.queue = queue
self:addPanel(364, 0, 0) -- Right extremity of the panel
for x = 21, 83, 4 do
self:addPanel(365, x, 0)
@@ -52,12 +52,12 @@ function UIQueue:UIQueue(ui, queue)
self:addPanel(369, 97, self.height - 33):makeButton(0, 0, 17, 17, 370, self.decreaseMaxSize):setTooltip(_S.tooltip.queue_window.dec_queue_size)
self:addPanel(371, 144, self.height - 33):makeButton(0, 0, 17, 17, 372, self.increaseMaxSize):setTooltip(_S.tooltip.queue_window.inc_queue_size)
self:addPanel(373, self.width - 42, 17):makeButton(0, 0, 24, 24, 374, self.close):setTooltip(_S.tooltip.queue_window.close)
self:makeTooltip(_S.tooltip.queue_window.num_in_queue, 15, 15, 163, 36)
self:makeTooltip(_S.tooltip.queue_window.num_expected, 15, 39, 163, 60)
self:makeTooltip(_S.tooltip.queue_window.num_entered, 15, 62, 163, 83)
self:makeTooltip(_S.tooltip.queue_window.max_queue_size, 15, 87, 163, 108)
self:makeTooltip(_S.tooltip.queue_window.front_of_queue, 168, 25, 213, 105)
self:makeTooltip(_S.tooltip.queue_window.end_of_queue, 543, 51, 586, 105)
self:makeTooltip(_S.tooltip.queue_window.patient .. " " .. _S.misc.not_yet_implemented, 218, 15, 537, 107)
@@ -86,23 +86,23 @@ end
function UIQueue:draw(canvas, x, y)
Window.draw(self, canvas, x, y)
x, y = self.x + x, self.y + y
local font = self.white_font
local queue = self.queue
local queue = self.queue
local num_patients = queue:reportedSize()
font:draw(canvas, _S.queue_window.num_in_queue, x + 22, y + 22)
font:draw(canvas, num_patients, x + 140, y + 22)
font:draw(canvas, _S.queue_window.num_expected, x + 22, y + 45)
font:draw(canvas, queue.expected_count, x + 140, y + 45)
font:draw(canvas, _S.queue_window.num_entered, x + 22, y + 68)
font:draw(canvas, queue.visitor_count, x + 140, y + 68)
font:draw(canvas, _S.queue_window.max_queue_size, x + 22, y + 93)
font:draw(canvas, queue.max_size, x + 119, y + 93)
self:drawPatients(canvas, x, y)
-- Draw dragged patient in the cursor location

View File

@@ -30,30 +30,30 @@ local border_size_y = 40
function UIResizable:UIResizable(ui, width, height, colour, no_borders, background_bevel)
self:Window()
local app = ui.app
self.ui = ui
self.resizable = false -- by default, not user-resizable
if not no_borders then
self.border_sprites = app.gfx:loadSpriteTable("Bitmap", "aux_ui", true)
end
if background_bevel then
self.background_panel = self:addBevelPanel(0, 0, 0, 0, colour)
self.background_panel.lowered = true
else
self.background_panel = self:addColourPanel(0, 0, 0, 0, 0, 0, 0)
end
-- Minimum size. Can be changed per window, but should never be smaller than this
-- because it would result in visual glitches
self.min_width = 50
self.min_height = 50
self.border_pos = {}
self.border_pos.left = -border_offset_x
self.border_pos.upper = -border_offset_y
-- NB: intentionally calling like this to allow subclasses to extend setSize without being called from here
UIResizable.setSize(self, width, height)
self:setColour(colour)
@@ -62,12 +62,12 @@ end
function UIResizable:setSize(width, height)
width = math.max(self.min_width, width)
height = math.max(self.min_height, height)
self.width = width
self.height = height
self.background_panel.w = width
self.background_panel.h = height
self.border_pos.right = self.width
self.border_pos.corner_right = self.width - border_size_x
@@ -86,13 +86,13 @@ function UIResizable:draw(canvas, x, y)
local draw = sprites.draw
local x = self.x + x
local y = self.y + y
canvas:nonOverlapping(true)
draw(sprites, canvas, 10, x + self.border_pos.left , y + self.border_pos.upper) -- upper left corner
draw(sprites, canvas, 12, x + self.border_pos.corner_right, y + self.border_pos.upper) -- upper right corner
draw(sprites, canvas, 15, x + self.border_pos.left , y + self.border_pos.corner_lower) -- lower left corner
draw(sprites, canvas, 17, x + self.border_pos.corner_right, y + self.border_pos.corner_lower) -- lower right corner
for x = x + border_size_x, x + self.border_pos.corner_right - 1, border_size_x do
draw(sprites, canvas, 11, x, y + self.border_pos.upper) -- upper edge
draw(sprites, canvas, 16, x, y + self.border_pos.lower) -- lower edge
@@ -101,7 +101,7 @@ function UIResizable:draw(canvas, x, y)
draw(sprites, canvas, 13, x + self.border_pos.left, y) -- left edge
draw(sprites, canvas, 14, x + self.border_pos.right, y) -- right edge
end
canvas:nonOverlapping(false)
end
-- Draw window components
@@ -142,7 +142,7 @@ function UIResizable:hitTestCorners(x, y)
if self.border_sprites then
local yzone = (-9 <= y and y < 0) and "u" or (self.height <= y and y < self.height + 9) and "l"
local xzone = (-9 <= x and x < 0) and "l" or (self.width <= x and x < self.width + 9) and "r"
local sprite_ids = {ul = 10, ur = 12, ll = 15, lr = 17}
if yzone and xzone then
local zone = yzone .. xzone
@@ -166,29 +166,29 @@ function UIResizable:beginResize(x, y, mode)
local ref_y = self.y + y
local orig_width = self.width
local orig_height = self.height
self.dragging = true
self.ui.drag_mouse_move = --[[persistable:window_resize_mouse_move]] function (sx, sy)
-- sx and sy are cursor screen co-ords. Convert to relative change.
sx = sx - ref_x
sy = sy - ref_y
local invert_x = mode == "ul" or mode == "ll"
local invert_y = mode == "ul" or mode == "ur"
sx = invert_x and -sx or sx
sy = invert_y and -sy or sy
self:setSize(orig_width + sx, orig_height + sy)
local new_x, new_y
if invert_x then
new_x = orig_x + orig_width - self.width
end
if invert_y then
new_y = orig_y + orig_height - self.height
end
if new_x or new_y then
self:setPosition(new_x or orig_x, new_y or orig_y)
end

View File

@@ -51,9 +51,9 @@ function UICallsDispatcher:UICallsDispatcher(ui)
self.call_list = {}
self.list_table = {}
self.rows_shown = 0
self:createControls()
self:createControls()
self:setDefaultPosition(0.05, 0.05)
self.default_button_sound = "selectx.wav"
self.dispatcher:addChangeCallback(self.update, self)
@@ -65,7 +65,7 @@ local window_margin = 15
function UICallsDispatcher:createControls()
local rows = math.floor((self.height - window_margin * 3 - 60) / row_height)
if rows ~= self.rows_shown then
local function assigned_factory(num)
return --[[persistable:calls_dispatcher_assigned_button]] function(self)
@@ -77,7 +77,7 @@ function UICallsDispatcher:createControls()
self:itemButtonClicked(num)
end
end
local callback = --[[persistable:calls_dispatcher_scrollbar]] function()
local callback = --[[persistable:calls_dispatcher_scrollbar]] function()
self:scrollbarChange()
end
@@ -120,13 +120,13 @@ function UICallsDispatcher:update()
end
end
end
table.sort(self.call_list,
table.sort(self.call_list,
function(a,b)
if a.created == nil or b.created == nil then return false end
return a.created < b.created
end
)
self.summary_panel:setLabel(_S.calls_dispatcher.summary:format(#self.call_list, assigned), nil, "left")
self.scrollbar:setRange(1, math.max(1, #self.call_list), self.rows_shown, self.scrollbar.value)
self:scrollbarChange()

View File

@@ -67,34 +67,34 @@ function UICheats:UICheats(ui)
{name = "lose_level", func = self.cheatLose},
{name = "win_level", func = self.cheatWin},
}
self:UIResizable(ui, 300, 200, col_bg)
self.default_button_sound = "selectx.wav"
local app = ui.app
self.modal_class = "cheats"
self.esc_closes = true
self.resizable = false
self:setDefaultPosition(0.2, 0.4)
local y = 10
self:addBevelPanel(20, y, 260, 20, col_caption):setLabel(_S.cheats_window.caption)
.lowered = true
y = y + 30
self:addColourPanel(20, y, 260, 40, col_bg.red, col_bg.green, col_bg.blue):setLabel({_S.cheats_window.warning})
y = y + 40
self.cheated_panel = self:addBevelPanel(20, y, 260, 18, col_cheated_no, col_border, col_border)
local function button_clicked(num)
return --[[persistable:cheats_button]] function(self)
self:buttonClicked(num)
end
end
self.item_panels = {}
self.item_buttons = {}
@@ -106,11 +106,11 @@ function UICheats:UICheats(ui)
:setTooltip(_S.tooltip.cheats_window.cheats[self.cheats[num].name])
y = y + 20
end
y = y + 20
self:addBevelPanel(20, y, 260, 40, col_bg):setLabel(_S.cheats_window.close)
:makeButton(0, 0, 260, 40, nil, self.buttonBack):setTooltip(_S.tooltip.cheats_window.close)
y = y + 60
self:setSize(300, y)
self:updateCheatedStatus()
@@ -135,7 +135,7 @@ function UICheats:buttonClicked(num)
end
else
-- It was not possible to use this cheat.
self.ui:addWindow(UIInformation(self.ui, {_S.information.cheat_not_possible}))
self.ui:addWindow(UIInformation(self.ui, {_S.information.cheat_not_possible}))
end
end
@@ -188,4 +188,4 @@ end
function UICheats:buttonBack()
self:close()
end
end

View File

@@ -1,230 +1,230 @@
--[[ Copyright (c) 2013 Mark (Mark L) Lawlor
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. --]]
--! Customise window used in the main menu and ingame.
class "UICustomise" (UIResizable)
local col_bg = {
red = 154,
green = 146,
blue = 198,
}
local col_button = {
red = 84,
green = 200,
blue = 84,
}
local col_textbox = {
red = 0,
green = 0,
blue = 0,
}
local col_highlight = {
red = 174,
green = 166,
blue = 218,
}
local col_shadow = {
red = 134,
green = 126,
blue = 178,
}
local col_caption = {
red = 174,
green = 166,
blue = 218,
}
function UICustomise:UICustomise(ui, mode)
self:UIResizable(ui, 320, 280, col_bg)
local app = ui.app
self.mode = mode
self.modal_class = mode == "menu" and "main menu" or "options" or "customise"
self.on_top = mode == "menu"
self.esc_closes = true
self.resizable = false
self:setDefaultPosition(0.5, 0.25)
self.default_button_sound = "selectx.wav"
self.app = app
-- Window parts definition
-- Title
self:addBevelPanel(80, 10, 160, 20, col_caption):setLabel(_S.customise_window.caption)
.lowered = true
-- Movies, global switch
self:addBevelPanel(20, 40, 135, 20, col_shadow, col_bg, col_bg)
:setLabel(_S.customise_window.movies):setTooltip(_S.tooltip.customise_window.movies).lowered = true
self.movies_panel =
self:addBevelPanel(160, 40, 135, 20, col_bg):setLabel(app.config.movies and _S.customise_window.option_on or _S.customise_window.option_off)
self.movies_button = self.movies_panel:makeToggleButton(0, 0, 140, 20, nil, self.buttonMoviesGlobal)
:setToggleState(app.config.movies):setTooltip(_S.tooltip.customise_window.movies)
-- Intro movie
self:addBevelPanel(20, 65, 135, 20, col_shadow, col_bg, col_bg)
:setLabel(_S.customise_window.intro):setTooltip(_S.tooltip.customise_window.intro).lowered = true
self.intro_panel =
self:addBevelPanel(160, 65, 135, 20, col_bg):setLabel(app.config.play_intro and _S.customise_window.option_on or _S.customise_window.option_off)
self.intro_button = self.intro_panel:makeToggleButton(0, 0, 140, 20, nil, self.buttonIntro)
:setToggleState(app.config.play_intro):setTooltip(_S.tooltip.customise_window.intro)
-- Allow user actions when paused
self:addBevelPanel(20, 90, 135, 20, col_shadow, col_bg, col_bg)
:setLabel(_S.customise_window.paused):setTooltip(_S.tooltip.customise_window.paused).lowered = true
self.paused_panel =
self:addBevelPanel(160, 90, 135, 20, col_bg):setLabel(app.config.allow_user_actions_while_paused and _S.customise_window.option_on or _S.customise_window.option_off)
self.paused_button = self.paused_panel:makeToggleButton(0, 0, 140, 20, nil, self.buttonPaused)
:setToggleState(app.config.allow_user_actions_while_paused):setTooltip(_S.tooltip.customise_window.paused)
-- Volume down is opening casebook
self:addBevelPanel(20, 115, 135, 20, col_shadow, col_bg, col_bg)
:setLabel(_S.customise_window.volume):setTooltip(_S.tooltip.customise_window.volume).lowered = true
self.volume_panel =
self:addBevelPanel(160, 115, 135, 20, col_bg):setLabel(app.config.volume_opens_casebook and _S.customise_window.option_on or _S.customise_window.option_off)
self.volume_button = self.volume_panel:makeToggleButton(0, 0, 140, 20, nil, self.buttonVolume)
:setToggleState(app.config.volume_opens_casebook):setTooltip(_S.tooltip.customise_window.volume)
-- Alien DNA from emergencies only/must stand/can knock on doors
self:addBevelPanel(20, 140, 135, 20, col_shadow, col_bg, col_bg)
:setLabel(_S.customise_window.aliens):setTooltip(_S.tooltip.customise_window.aliens).lowered = true
self.aliens_panel =
self:addBevelPanel(160, 140, 135, 20, col_bg):setLabel(app.config.alien_dna_only_by_emergency and _S.customise_window.option_on or _S.customise_window.option_off)
self.aliens_button = self.aliens_panel:makeToggleButton(0, 0, 140, 20, nil, self.buttonAliens)
:setToggleState(app.config.alien_dna_only_by_emergency):setTooltip(_S.tooltip.customise_window.aliens)
-- Allow female patients with Fractured Bones
self:addBevelPanel(20, 165, 135, 20, col_shadow, col_bg, col_bg)
:setLabel(_S.customise_window.fractured_bones):setTooltip(_S.tooltip.customise_window.fractured_bones).lowered = true
self.fractured_bones_panel =
self:addBevelPanel(160, 165, 135, 20, col_bg):setLabel(app.config.disable_fractured_bones_females and _S.customise_window.option_on or _S.customise_window.option_off)
self.fractured_bones_button = self.fractured_bones_panel:makeToggleButton(0, 0, 140, 20, nil, self.buttonFractured_bones)
:setToggleState(app.config.disable_fractured_bones_females):setTooltip(_S.tooltip.customise_window.fractured_bones)
-- Allow average contents when building rooms
self:addBevelPanel(20, 190, 135, 20, col_shadow, col_bg, col_bg)
:setLabel(_S.customise_window.average_contents):setTooltip(_S.tooltip.customise_window.average_contents).lowered = true
self.average_contents_panel =
self:addBevelPanel(160, 190, 135, 20, col_bg):setLabel(app.config.enable_avg_contents and _S.customise_window.option_on or _S.customise_window.option_off)
self.average_contents_button = self.average_contents_panel:makeToggleButton(0, 0, 140, 20, nil, self.buttonAverage_contents)
:setToggleState(app.config.enable_avg_contents):setTooltip(_S.tooltip.customise_window.average_contents)
-- "Back" button
self:addBevelPanel(20, 220, 280, 40, col_bg):setLabel(_S.customise_window.back)
:makeButton(0, 0, 280, 40, nil, self.buttonBack):setTooltip(_S.tooltip.customise_window.back)
end
function UICustomise:buttonAudioGlobal(checked)
local window = UIAudio(self.ui, "menu")
self.ui:addWindow(window)
end
function UICustomise:buttonMoviesGlobal(checked)
local app = self.ui.app
app.config.movies = not app.config.movies
self.movies_button:toggle()
self.movies_panel:setLabel(app.config.movies and _S.customise_window.option_on or _S.customise_window.option_off)
self:reload()
app:saveConfig()
end
function UICustomise:buttonIntro(checked)
local app = self.ui.app
app.config.play_intro = not app.config.play_intro
self.intro_button:toggle()
self.intro_panel:setLabel(app.config.play_intro and _S.customise_window.option_on or _S.customise_window.option_off)
self:reload()
app:saveConfig()
end
function UICustomise:buttonPaused(checked)
local app = self.ui.app
app.config.allow_user_actions_while_paused = not app.config.allow_user_actions_while_paused
self.paused_button:toggle()
self.paused_panel:setLabel(app.config.allow_user_actions_while_paused and _S.customise_window.option_on or _S.customise_window.option_off)
self:reload()
app:saveConfig()
end
function UICustomise:buttonVolume(checked)
local app = self.ui.app
app.config.volume_opens_casebook = not app.config.volume_opens_casebook
self.volume_button:toggle()
self.volume_panel:setLabel(app.config.volume_opens_casebook and _S.customise_window.option_on or _S.customise_window.option_off)
self:reload()
app:saveConfig()
end
function UICustomise:buttonAliens(checked)
local app = self.ui.app
app.config.alien_dna_only_by_emergency = not app.config.alien_dna_only_by_emergency
app.config.alien_dna_must_stand = not app.config.alien_dna_must_stand
app.config.alien_dna_can_knock_on_doors = not app.config.alien_dna_can_knock_on_doors
self.aliens_button:toggle()
self.aliens_panel:setLabel(app.config.alien_dna_only_by_emergency and _S.customise_window.option_on or _S.customise_window.option_off)
app:saveConfig()
self:reload()
local err = {_S.errors.alien_dna}
self.ui:addWindow(UIInformation(self.ui, err))
end
function UICustomise:buttonFractured_bones(checked)
local app = self.ui.app
app.config.disable_fractured_bones_females = not app.config.disable_fractured_bones_females
self.fractured_bones_button:toggle()
self.fractured_bones_panel:setLabel(app.config.disable_fractured_bones_females and _S.customise_window.option_on or _S.customise_window.option_off)
app:saveConfig()
self:reload()
local err = {_S.errors.fractured_bones}
self.ui:addWindow(UIInformation(self.ui, err))
end
function UICustomise:buttonAverage_contents(checked)
local app = self.ui.app
app.config.enable_avg_contents = not app.config.enable_avg_contents
self.average_contents_button:toggle()
self.average_contents_panel:setLabel(app.config.enable_avg_contents and _S.customise_window.option_on or _S.customise_window.option_off)
app:saveConfig()
self:reload()
end
function UICustomise:buttonBack()
self:close()
local window = UIOptions(self.ui, "menu")
self.ui:addWindow(window)
end
-- So that we can see the option has been changed reload the menu
function UICustomise:reload()
local window = UICustomise(self.ui, "menu")
self.ui:addWindow(window)
end
function UICustomise:close()
UIResizable.close(self)
if self.mode == "menu" then
self.ui:addWindow(UIMainMenu(self.ui))
end
end
--[[ Copyright (c) 2013 Mark (Mark L) Lawlor
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. --]]
--! Customise window used in the main menu and ingame.
class "UICustomise" (UIResizable)
local col_bg = {
red = 154,
green = 146,
blue = 198,
}
local col_button = {
red = 84,
green = 200,
blue = 84,
}
local col_textbox = {
red = 0,
green = 0,
blue = 0,
}
local col_highlight = {
red = 174,
green = 166,
blue = 218,
}
local col_shadow = {
red = 134,
green = 126,
blue = 178,
}
local col_caption = {
red = 174,
green = 166,
blue = 218,
}
function UICustomise:UICustomise(ui, mode)
self:UIResizable(ui, 320, 280, col_bg)
local app = ui.app
self.mode = mode
self.modal_class = mode == "menu" and "main menu" or "options" or "customise"
self.on_top = mode == "menu"
self.esc_closes = true
self.resizable = false
self:setDefaultPosition(0.5, 0.25)
self.default_button_sound = "selectx.wav"
self.app = app
-- Window parts definition
-- Title
self:addBevelPanel(80, 10, 160, 20, col_caption):setLabel(_S.customise_window.caption)
.lowered = true
-- Movies, global switch
self:addBevelPanel(20, 40, 135, 20, col_shadow, col_bg, col_bg)
:setLabel(_S.customise_window.movies):setTooltip(_S.tooltip.customise_window.movies).lowered = true
self.movies_panel =
self:addBevelPanel(160, 40, 135, 20, col_bg):setLabel(app.config.movies and _S.customise_window.option_on or _S.customise_window.option_off)
self.movies_button = self.movies_panel:makeToggleButton(0, 0, 140, 20, nil, self.buttonMoviesGlobal)
:setToggleState(app.config.movies):setTooltip(_S.tooltip.customise_window.movies)
-- Intro movie
self:addBevelPanel(20, 65, 135, 20, col_shadow, col_bg, col_bg)
:setLabel(_S.customise_window.intro):setTooltip(_S.tooltip.customise_window.intro).lowered = true
self.intro_panel =
self:addBevelPanel(160, 65, 135, 20, col_bg):setLabel(app.config.play_intro and _S.customise_window.option_on or _S.customise_window.option_off)
self.intro_button = self.intro_panel:makeToggleButton(0, 0, 140, 20, nil, self.buttonIntro)
:setToggleState(app.config.play_intro):setTooltip(_S.tooltip.customise_window.intro)
-- Allow user actions when paused
self:addBevelPanel(20, 90, 135, 20, col_shadow, col_bg, col_bg)
:setLabel(_S.customise_window.paused):setTooltip(_S.tooltip.customise_window.paused).lowered = true
self.paused_panel =
self:addBevelPanel(160, 90, 135, 20, col_bg):setLabel(app.config.allow_user_actions_while_paused and _S.customise_window.option_on or _S.customise_window.option_off)
self.paused_button = self.paused_panel:makeToggleButton(0, 0, 140, 20, nil, self.buttonPaused)
:setToggleState(app.config.allow_user_actions_while_paused):setTooltip(_S.tooltip.customise_window.paused)
-- Volume down is opening casebook
self:addBevelPanel(20, 115, 135, 20, col_shadow, col_bg, col_bg)
:setLabel(_S.customise_window.volume):setTooltip(_S.tooltip.customise_window.volume).lowered = true
self.volume_panel =
self:addBevelPanel(160, 115, 135, 20, col_bg):setLabel(app.config.volume_opens_casebook and _S.customise_window.option_on or _S.customise_window.option_off)
self.volume_button = self.volume_panel:makeToggleButton(0, 0, 140, 20, nil, self.buttonVolume)
:setToggleState(app.config.volume_opens_casebook):setTooltip(_S.tooltip.customise_window.volume)
-- Alien DNA from emergencies only/must stand/can knock on doors
self:addBevelPanel(20, 140, 135, 20, col_shadow, col_bg, col_bg)
:setLabel(_S.customise_window.aliens):setTooltip(_S.tooltip.customise_window.aliens).lowered = true
self.aliens_panel =
self:addBevelPanel(160, 140, 135, 20, col_bg):setLabel(app.config.alien_dna_only_by_emergency and _S.customise_window.option_on or _S.customise_window.option_off)
self.aliens_button = self.aliens_panel:makeToggleButton(0, 0, 140, 20, nil, self.buttonAliens)
:setToggleState(app.config.alien_dna_only_by_emergency):setTooltip(_S.tooltip.customise_window.aliens)
-- Allow female patients with Fractured Bones
self:addBevelPanel(20, 165, 135, 20, col_shadow, col_bg, col_bg)
:setLabel(_S.customise_window.fractured_bones):setTooltip(_S.tooltip.customise_window.fractured_bones).lowered = true
self.fractured_bones_panel =
self:addBevelPanel(160, 165, 135, 20, col_bg):setLabel(app.config.disable_fractured_bones_females and _S.customise_window.option_on or _S.customise_window.option_off)
self.fractured_bones_button = self.fractured_bones_panel:makeToggleButton(0, 0, 140, 20, nil, self.buttonFractured_bones)
:setToggleState(app.config.disable_fractured_bones_females):setTooltip(_S.tooltip.customise_window.fractured_bones)
-- Allow average contents when building rooms
self:addBevelPanel(20, 190, 135, 20, col_shadow, col_bg, col_bg)
:setLabel(_S.customise_window.average_contents):setTooltip(_S.tooltip.customise_window.average_contents).lowered = true
self.average_contents_panel =
self:addBevelPanel(160, 190, 135, 20, col_bg):setLabel(app.config.enable_avg_contents and _S.customise_window.option_on or _S.customise_window.option_off)
self.average_contents_button = self.average_contents_panel:makeToggleButton(0, 0, 140, 20, nil, self.buttonAverage_contents)
:setToggleState(app.config.enable_avg_contents):setTooltip(_S.tooltip.customise_window.average_contents)
-- "Back" button
self:addBevelPanel(20, 220, 280, 40, col_bg):setLabel(_S.customise_window.back)
:makeButton(0, 0, 280, 40, nil, self.buttonBack):setTooltip(_S.tooltip.customise_window.back)
end
function UICustomise:buttonAudioGlobal(checked)
local window = UIAudio(self.ui, "menu")
self.ui:addWindow(window)
end
function UICustomise:buttonMoviesGlobal(checked)
local app = self.ui.app
app.config.movies = not app.config.movies
self.movies_button:toggle()
self.movies_panel:setLabel(app.config.movies and _S.customise_window.option_on or _S.customise_window.option_off)
self:reload()
app:saveConfig()
end
function UICustomise:buttonIntro(checked)
local app = self.ui.app
app.config.play_intro = not app.config.play_intro
self.intro_button:toggle()
self.intro_panel:setLabel(app.config.play_intro and _S.customise_window.option_on or _S.customise_window.option_off)
self:reload()
app:saveConfig()
end
function UICustomise:buttonPaused(checked)
local app = self.ui.app
app.config.allow_user_actions_while_paused = not app.config.allow_user_actions_while_paused
self.paused_button:toggle()
self.paused_panel:setLabel(app.config.allow_user_actions_while_paused and _S.customise_window.option_on or _S.customise_window.option_off)
self:reload()
app:saveConfig()
end
function UICustomise:buttonVolume(checked)
local app = self.ui.app
app.config.volume_opens_casebook = not app.config.volume_opens_casebook
self.volume_button:toggle()
self.volume_panel:setLabel(app.config.volume_opens_casebook and _S.customise_window.option_on or _S.customise_window.option_off)
self:reload()
app:saveConfig()
end
function UICustomise:buttonAliens(checked)
local app = self.ui.app
app.config.alien_dna_only_by_emergency = not app.config.alien_dna_only_by_emergency
app.config.alien_dna_must_stand = not app.config.alien_dna_must_stand
app.config.alien_dna_can_knock_on_doors = not app.config.alien_dna_can_knock_on_doors
self.aliens_button:toggle()
self.aliens_panel:setLabel(app.config.alien_dna_only_by_emergency and _S.customise_window.option_on or _S.customise_window.option_off)
app:saveConfig()
self:reload()
local err = {_S.errors.alien_dna}
self.ui:addWindow(UIInformation(self.ui, err))
end
function UICustomise:buttonFractured_bones(checked)
local app = self.ui.app
app.config.disable_fractured_bones_females = not app.config.disable_fractured_bones_females
self.fractured_bones_button:toggle()
self.fractured_bones_panel:setLabel(app.config.disable_fractured_bones_females and _S.customise_window.option_on or _S.customise_window.option_off)
app:saveConfig()
self:reload()
local err = {_S.errors.fractured_bones}
self.ui:addWindow(UIInformation(self.ui, err))
end
function UICustomise:buttonAverage_contents(checked)
local app = self.ui.app
app.config.enable_avg_contents = not app.config.enable_avg_contents
self.average_contents_button:toggle()
self.average_contents_panel:setLabel(app.config.enable_avg_contents and _S.customise_window.option_on or _S.customise_window.option_off)
app:saveConfig()
self:reload()
end
function UICustomise:buttonBack()
self:close()
local window = UIOptions(self.ui, "menu")
self.ui:addWindow(window)
end
-- So that we can see the option has been changed reload the menu
function UICustomise:reload()
local window = UICustomise(self.ui, "menu")
self.ui:addWindow(window)
end
function UICustomise:close()
UIResizable.close(self)
if self.mode == "menu" then
self.ui:addWindow(UIMainMenu(self.ui))
end
end

View File

@@ -31,7 +31,7 @@ end
function DirTreeNode:isValidFile(name)
-- Check parent criteria and that it's a directory.
if FileTreeNode.isValidFile(self, name)
if FileTreeNode.isValidFile(self, name)
and lfs.attributes(self:childPath(name), "mode") == "directory" then
-- Make sure that we are allowed to read the directory.
local status, result = pcall(lfs.dir, self:childPath(name))
@@ -69,7 +69,7 @@ function InstallDirTreeNode:getHighlightColour(canvas)
local highlight_colour = self.highlight_colour
if highlight_colour == nil then
highlight_colour = false
if self:getLevel() == 0 and not self.has_looked_for_children then
-- Assume root-level things are not TH directories, unless we've already
-- got a list of their children.
@@ -91,7 +91,7 @@ function InstallDirTreeNode:getHighlightColour(canvas)
end
self.highlight_colour = highlight_colour
end
return highlight_colour or nil
return highlight_colour or nil
end
--! Prompter for Theme Hospital install directory
@@ -140,7 +140,7 @@ function UIDirectoryBrowser:UIDirectoryBrowser(ui, mode, instruction, treenode_c
self:addKeyHandler("escape", self.exit)
self.exit_button:setLabel(_S.install.exit, self.font):makeButton(0, 0, 100, 18, nil, self.exit)
end
-- Create the root item (or items, on Windows), and set it as the
-- first_visible_node.
local root
@@ -160,10 +160,10 @@ function UIDirectoryBrowser:UIDirectoryBrowser(ui, mode, instruction, treenode_c
self:close()
end
end
local control = TreeControl(root, 5, 55, 490, 340, self.col_bg, self.col_scrollbar)
:setSelectCallback(select_function)
local ok_function = function()
if control.selected_node then
select_function(control.selected_node)

View File

@@ -39,20 +39,20 @@ function UIDropdown:UIDropdown(ui, parent_window, parent_button, items, callback
self.esc_closes = true
self.resizable = false
self.default_button_sound = "selectx.wav"
self.parent_window = parent_window
self.parent_button = parent_button
self.items = items
self.callback = callback
local panel = parent_button.panel_for_sprite
local width = panel.w
local height = panel.h
-- TODO: Somehow make the dropdown disappear if the user clicks outside it.
self:setPosition(panel.x, panel.y + panel.h)
local y = 0
for i, item in ipairs(items) do
self:addBevelPanel(1, y + 1, width - 2, height - 2, parent_window.colour):setLabel(item.text, item.font)
@@ -61,7 +61,7 @@ function UIDropdown:UIDropdown(ui, parent_window, parent_button, items, callback
--:setTooltip(item.tooltip)
y = y + height
end
-- Adjust size
self:setSize(width, y)
end

View File

@@ -20,7 +20,7 @@ SOFTWARE. --]]
local lfs = require "lfs"
--! A tree node representing a file (or directory) in the physical file-system
--! A tree node representing a file (or directory) in the physical file-system
-- that meets a given file extension criterion.
class "FilteredFileTreeNode" (FileTreeNode)
@@ -83,7 +83,7 @@ function FilteredTreeControl:FilteredTreeControl(root, x, y, width, height, col_
self:TreeControl(root, x, y, width, height, col_bg, col_fg, 14, has_font)
self.num_rows = (self.tree_rect.h - self.y_offset) / self.row_height
-- Add the two column headers and make buttons on them.
if show_dates then
self:addBevelPanel(1, 1, width - 170, 13, col_bg):setLabel(_S.menu_list_window.name)
@@ -178,7 +178,7 @@ function UIFileBrowser:UIFileBrowser(ui, mode, title, vertical_size, root, show_
self:UIResizable(ui, h_size, 380, self.col_bg)
self.default_button_sound = "selectx.wav"
local app = ui.app
self.mode = mode
self.modal_class = mode == "menu" and "main menu" or "saveload"
@@ -186,7 +186,7 @@ function UIFileBrowser:UIFileBrowser(ui, mode, title, vertical_size, root, show_
self.esc_closes = true
self.resizable = false
self:setDefaultPosition(0.5, 0.25)
self:addBevelPanel((h_size - 190) / 2, 10, 190, 20, col_caption):setLabel(title)
.lowered = true
@@ -203,7 +203,7 @@ function UIFileBrowser:UIFileBrowser(ui, mode, title, vertical_size, root, show_
end
end)
self:addWindow(self.control)
-- Create the back button.
self:addBevelPanel((h_size - 160) / 2, 340, 160, 30, self.col_bg):setLabel(_S.menu_list_window.back)
:makeButton(0, 0, 160, 40, nil, self.buttonBack):setTooltip(_S.tooltip.menu_list_window.back)

View File

@@ -49,4 +49,4 @@ function UILoadGame:close()
if self.mode == "menu" then
self.ui:addWindow(UIMainMenu(self.ui))
end
end
end

View File

@@ -48,7 +48,7 @@ function UISaveGame:UISaveGame(ui)
-- The most probable preference of sorting is by date - what you played last
-- is the thing you want to play soon again.
self.control:sortByDate()
-- Textbox for entering new savegame name
self.new_savegame_textbox = self:addBevelPanel(5, 310, self.width - 10, 17, col_textbox, col_highlight, col_shadow)
:setLabel(_S.save_game_window.new_save_game, nil, "left"):setTooltip(_S.tooltip.save_game_window.new_save_game)
@@ -92,7 +92,7 @@ function UISaveGame:doSave(filename)
local ui = self.ui
local app = ui.app
self:close()
local status, err = pcall(app.save, app, filename)
if not status then
err = _S.errors.save_prefix .. err

View File

@@ -1,222 +1,222 @@
--[[ Copyright (c) 2013 Mark (Mark L) Lawlor
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. --]]
--! Customise window used in the main menu and ingame.
class "UIFolder" (UIResizable)
local col_bg = {
red = 154,
green = 146,
blue = 198,
}
local col_button = {
red = 84,
green = 200,
blue = 84,
}
local col_textbox = {
red = 0,
green = 0,
blue = 0,
}
local col_highlight = {
red = 174,
green = 166,
blue = 218,
}
local col_shadow = {
red = 134,
green = 126,
blue = 178,
}
local col_caption = {
red = 174,
green = 166,
blue = 218,
}
function UIFolder:UIFolder(ui, mode)
self:UIResizable(ui, 360, 240, col_bg)
local app = ui.app
self.mode = mode
self.modal_class = mode == "menu" and "main menu" or "options" or "folders"
self.on_top = mode == "menu"
self.esc_closes = true
self.resizable = false
self:setDefaultPosition(0.5, 0.25)
self.default_button_sound = "selectx.wav"
self.app = app
-- Window parts definition
-- Title
self:addBevelPanel(80, 10, 200, 20, col_caption):setLabel(_S.folders_window.caption)
.lowered = true
-- Location of original game
local built_in = app.gfx:loadBuiltinFont()
self:addBevelPanel(20, 50, 130, 20, col_shadow, col_bg, col_bg)
:setLabel(_S.folders_window.data_label):setTooltip(_S.tooltip.folders_window.data_location)
.lowered = true
self:addBevelPanel(160, 50, 180, 20, col_bg)
:setLabel(app.config.theme_hospital_install, built_in):setAutoClip(true)
:makeButton(0, 0, 180, 20, nil, self.buttonBrowseForTHInstall):setTooltip(_S.tooltip.folders_window.browse_data:format(app.config.theme_hospital_install))
-- Location of font file
self:addBevelPanel(20, 75, 130, 20, col_shadow, col_bg, col_bg)
:setLabel(_S.folders_window.font_label):setTooltip(_S.tooltip.folders_window.font_location)
.lowered = true
local tooltip_font = app.config.unicode_font and _S.tooltip.folders_window.browse_font:format(app.config.unicode_font) or _S.tooltip.folders_window.no_font_specified
self:addBevelPanel(160, 75, 180, 20, col_bg)
:setLabel(app.config.unicode_font and app.config.unicode_font or tooltip_font, built_in):setAutoClip(true)
:makeButton(0, 0, 180, 20, nil, self.buttonBrowseForFont):setTooltip(tooltip_font)
-- Location saves alternative
self:addBevelPanel(20, 100, 130, 20, col_shadow, col_bg, col_bg)
:setLabel(_S.folders_window.savegames_label):setTooltip(_S.tooltip.folders_window.savegames_location)
.lowered = true
local tooltip_saves = app.config.savegames and _S.tooltip.folders_window.browse_saves:format(app.config.savegames) or _S.tooltip.folders_window.default
self.saves_panel = self:addBevelPanel(160, 100, 160, 20, col_bg)
self.saves_panel:setLabel(app.config.savegames and app.config.savegames or tooltip_saves , built_in):setAutoClip(true)
:makeButton(0, 0, 160, 20, nil, self.buttonBrowseForSavegames):setTooltip(tooltip_saves)
self:addBevelPanel(320, 100, 20, 20, col_bg):setLabel("X"):makeButton(0, 0, 20, 20, nil, self.resetSavegameDir):setTooltip(_S.tooltip.folders_window.reset_to_default)
-- location for screenshots
self:addBevelPanel(20, 125, 130, 20, col_shadow, col_bg, col_bg)
:setLabel(_S.folders_window.screenshots_label):setTooltip(_S.tooltip.folders_window.screenshots_location)
.lowered = true
local tooltip_screenshots = app.config.screenshots and _S.tooltip.folders_window.browse_screenshots:format(app.config.screenshots) or _S.tooltip.folders_window.default
self.screenshots_panel = self:addBevelPanel(160, 125, 160, 20, col_bg)
self.screenshots_panel:setLabel(app.config.screenshots and app.config.screenshots or tooltip_screenshots, built_in):setAutoClip(true)
:makeButton(0, 0, 160, 20, nil, self.buttonBrowseForScreenshots):setTooltip(tooltip_screenshots)
self:addBevelPanel(320, 125, 20, 20, col_bg):setLabel("X"):makeButton(0, 0, 20, 20, nil, self.resetScreenshotDir):setTooltip(_S.tooltip.folders_window.reset_to_default)
-- location for mp3 music files
self:addBevelPanel(20, 150, 130, 20, col_shadow, col_bg, col_bg)
:setLabel(_S.folders_window.music_label):setTooltip(_S.tooltip.folders_window.music_location)
.lowered = true
local tooltip_audio = app.config.audio_mp3 and _S.tooltip.folders_window.browse_music:format(app.config.audio_mp3) or _S.tooltip.folders_window.not_specified
self:addBevelPanel(160, 150, 180, 20, col_bg)
:setLabel(app.config.audio_mp3 and app.config.audio_mp3 or tooltip_audio, built_in):setAutoClip(true)
:makeButton(0, 0, 180, 20, nil, self.buttonBrowseForAudio_mp3):setTooltip(tooltip_audio)
-- "Back" button
self:addBevelPanel(20, 180, 320, 40, col_bg):setLabel(_S.folders_window.back)
:makeButton(0, 0, 320, 40, nil, self.buttonBack):setTooltip(_S.tooltip.folders_window.back)
self.built_in_font = built_in
end
function UIFolder:resetSavegameDir()
local app = TheApp
app.config.savegames = nil
app:saveConfig()
app:initSavegameDir()
self.saves_panel:setLabel(_S.tooltip.folders_window.default, self.built_in_font)
end
function UIFolder:resetScreenshotDir()
local app = TheApp
app.config.screenshots = nil
app:saveConfig()
app:initScreenshotsDir()
self.screenshots_panel:setLabel(_S.tooltip.folders_window.default, self.built_in_font)
end
function UIFolder:buttonBrowseForFont()
local browser = UIChooseFont(self.ui, self.mode)
self.ui:addWindow(browser)
end
function UIFolder:buttonBrowseForSavegames()
local app = TheApp
local old_path = app.config.savegames
local function callback(path)
if old_path ~= path then
app.config.savegames = path
app:saveConfig()
app:initSavegameDir()
self.saves_panel:setLabel(app.config.savegames and app.config.savegames or tooltip_saves , self.built_in_font)
end
end
local browser = UIDirectoryBrowser(self.ui, self.mode, _S.folders_window.savegames_location, "DirTreeNode", callback)
self.ui:addWindow(browser)
end
function UIFolder:buttonBrowseForTHInstall()
local function callback(path)
local app = TheApp
app.config.theme_hospital_install = path
app:saveConfig()
debug.getregistry()._RESTART = true
app.running = false
end
local browser = UIDirectoryBrowser(self.ui, self.mode, _S.folders_window.new_th_location, "InstallDirTreeNode", callback)
self.ui:addWindow(browser)
end
function UIFolder:buttonBrowseForScreenshots()
local app = TheApp
local old_path = app.config.savegames
local function callback(path)
if old_path ~= path then
app.config.screenshots = path
app:saveConfig()
app:initScreenshotsDir()
self.screenshots_panel:setLabel(app.config.screenshots and app.config.screenshots or tooltip_screenshots, self.built_in_font)
end
end
local browser = UIDirectoryBrowser(self.ui, self.mode, _S.folders_window.screenshots_location, "DirTreeNode", callback)
self.ui:addWindow(browser)
end
function UIFolder:buttonBrowseForAudio_mp3()
local function callback(path)
local app = TheApp
app.config.audio_mp3 = path
app:saveConfig()
debug.getregistry()._RESTART = true
app.running = false
end
local browser = UIDirectoryBrowser(self.ui, self.mode, _S.folders_window.music_location, "DirTreeNode", callback)
self.ui:addWindow(UIConfirmDialog(self.ui,
_S.confirmation.music_warning,
--[[persistable:mmusic_warning_confirm_dialog]]function()
self.ui:addWindow(browser)
end
))
end
function UIFolder:buttonBack()
self:close()
local window = UIOptions(self.ui, "menu")
self.ui:addWindow(window)
end
function UIFolder:close()
UIResizable.close(self)
if self.mode == "menu" then
self.ui:addWindow(UIMainMenu(self.ui))
end
end
--[[ Copyright (c) 2013 Mark (Mark L) Lawlor
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. --]]
--! Customise window used in the main menu and ingame.
class "UIFolder" (UIResizable)
local col_bg = {
red = 154,
green = 146,
blue = 198,
}
local col_button = {
red = 84,
green = 200,
blue = 84,
}
local col_textbox = {
red = 0,
green = 0,
blue = 0,
}
local col_highlight = {
red = 174,
green = 166,
blue = 218,
}
local col_shadow = {
red = 134,
green = 126,
blue = 178,
}
local col_caption = {
red = 174,
green = 166,
blue = 218,
}
function UIFolder:UIFolder(ui, mode)
self:UIResizable(ui, 360, 240, col_bg)
local app = ui.app
self.mode = mode
self.modal_class = mode == "menu" and "main menu" or "options" or "folders"
self.on_top = mode == "menu"
self.esc_closes = true
self.resizable = false
self:setDefaultPosition(0.5, 0.25)
self.default_button_sound = "selectx.wav"
self.app = app
-- Window parts definition
-- Title
self:addBevelPanel(80, 10, 200, 20, col_caption):setLabel(_S.folders_window.caption)
.lowered = true
-- Location of original game
local built_in = app.gfx:loadBuiltinFont()
self:addBevelPanel(20, 50, 130, 20, col_shadow, col_bg, col_bg)
:setLabel(_S.folders_window.data_label):setTooltip(_S.tooltip.folders_window.data_location)
.lowered = true
self:addBevelPanel(160, 50, 180, 20, col_bg)
:setLabel(app.config.theme_hospital_install, built_in):setAutoClip(true)
:makeButton(0, 0, 180, 20, nil, self.buttonBrowseForTHInstall):setTooltip(_S.tooltip.folders_window.browse_data:format(app.config.theme_hospital_install))
-- Location of font file
self:addBevelPanel(20, 75, 130, 20, col_shadow, col_bg, col_bg)
:setLabel(_S.folders_window.font_label):setTooltip(_S.tooltip.folders_window.font_location)
.lowered = true
local tooltip_font = app.config.unicode_font and _S.tooltip.folders_window.browse_font:format(app.config.unicode_font) or _S.tooltip.folders_window.no_font_specified
self:addBevelPanel(160, 75, 180, 20, col_bg)
:setLabel(app.config.unicode_font and app.config.unicode_font or tooltip_font, built_in):setAutoClip(true)
:makeButton(0, 0, 180, 20, nil, self.buttonBrowseForFont):setTooltip(tooltip_font)
-- Location saves alternative
self:addBevelPanel(20, 100, 130, 20, col_shadow, col_bg, col_bg)
:setLabel(_S.folders_window.savegames_label):setTooltip(_S.tooltip.folders_window.savegames_location)
.lowered = true
local tooltip_saves = app.config.savegames and _S.tooltip.folders_window.browse_saves:format(app.config.savegames) or _S.tooltip.folders_window.default
self.saves_panel = self:addBevelPanel(160, 100, 160, 20, col_bg)
self.saves_panel:setLabel(app.config.savegames and app.config.savegames or tooltip_saves , built_in):setAutoClip(true)
:makeButton(0, 0, 160, 20, nil, self.buttonBrowseForSavegames):setTooltip(tooltip_saves)
self:addBevelPanel(320, 100, 20, 20, col_bg):setLabel("X"):makeButton(0, 0, 20, 20, nil, self.resetSavegameDir):setTooltip(_S.tooltip.folders_window.reset_to_default)
-- location for screenshots
self:addBevelPanel(20, 125, 130, 20, col_shadow, col_bg, col_bg)
:setLabel(_S.folders_window.screenshots_label):setTooltip(_S.tooltip.folders_window.screenshots_location)
.lowered = true
local tooltip_screenshots = app.config.screenshots and _S.tooltip.folders_window.browse_screenshots:format(app.config.screenshots) or _S.tooltip.folders_window.default
self.screenshots_panel = self:addBevelPanel(160, 125, 160, 20, col_bg)
self.screenshots_panel:setLabel(app.config.screenshots and app.config.screenshots or tooltip_screenshots, built_in):setAutoClip(true)
:makeButton(0, 0, 160, 20, nil, self.buttonBrowseForScreenshots):setTooltip(tooltip_screenshots)
self:addBevelPanel(320, 125, 20, 20, col_bg):setLabel("X"):makeButton(0, 0, 20, 20, nil, self.resetScreenshotDir):setTooltip(_S.tooltip.folders_window.reset_to_default)
-- location for mp3 music files
self:addBevelPanel(20, 150, 130, 20, col_shadow, col_bg, col_bg)
:setLabel(_S.folders_window.music_label):setTooltip(_S.tooltip.folders_window.music_location)
.lowered = true
local tooltip_audio = app.config.audio_mp3 and _S.tooltip.folders_window.browse_music:format(app.config.audio_mp3) or _S.tooltip.folders_window.not_specified
self:addBevelPanel(160, 150, 180, 20, col_bg)
:setLabel(app.config.audio_mp3 and app.config.audio_mp3 or tooltip_audio, built_in):setAutoClip(true)
:makeButton(0, 0, 180, 20, nil, self.buttonBrowseForAudio_mp3):setTooltip(tooltip_audio)
-- "Back" button
self:addBevelPanel(20, 180, 320, 40, col_bg):setLabel(_S.folders_window.back)
:makeButton(0, 0, 320, 40, nil, self.buttonBack):setTooltip(_S.tooltip.folders_window.back)
self.built_in_font = built_in
end
function UIFolder:resetSavegameDir()
local app = TheApp
app.config.savegames = nil
app:saveConfig()
app:initSavegameDir()
self.saves_panel:setLabel(_S.tooltip.folders_window.default, self.built_in_font)
end
function UIFolder:resetScreenshotDir()
local app = TheApp
app.config.screenshots = nil
app:saveConfig()
app:initScreenshotsDir()
self.screenshots_panel:setLabel(_S.tooltip.folders_window.default, self.built_in_font)
end
function UIFolder:buttonBrowseForFont()
local browser = UIChooseFont(self.ui, self.mode)
self.ui:addWindow(browser)
end
function UIFolder:buttonBrowseForSavegames()
local app = TheApp
local old_path = app.config.savegames
local function callback(path)
if old_path ~= path then
app.config.savegames = path
app:saveConfig()
app:initSavegameDir()
self.saves_panel:setLabel(app.config.savegames and app.config.savegames or tooltip_saves , self.built_in_font)
end
end
local browser = UIDirectoryBrowser(self.ui, self.mode, _S.folders_window.savegames_location, "DirTreeNode", callback)
self.ui:addWindow(browser)
end
function UIFolder:buttonBrowseForTHInstall()
local function callback(path)
local app = TheApp
app.config.theme_hospital_install = path
app:saveConfig()
debug.getregistry()._RESTART = true
app.running = false
end
local browser = UIDirectoryBrowser(self.ui, self.mode, _S.folders_window.new_th_location, "InstallDirTreeNode", callback)
self.ui:addWindow(browser)
end
function UIFolder:buttonBrowseForScreenshots()
local app = TheApp
local old_path = app.config.savegames
local function callback(path)
if old_path ~= path then
app.config.screenshots = path
app:saveConfig()
app:initScreenshotsDir()
self.screenshots_panel:setLabel(app.config.screenshots and app.config.screenshots or tooltip_screenshots, self.built_in_font)
end
end
local browser = UIDirectoryBrowser(self.ui, self.mode, _S.folders_window.screenshots_location, "DirTreeNode", callback)
self.ui:addWindow(browser)
end
function UIFolder:buttonBrowseForAudio_mp3()
local function callback(path)
local app = TheApp
app.config.audio_mp3 = path
app:saveConfig()
debug.getregistry()._RESTART = true
app.running = false
end
local browser = UIDirectoryBrowser(self.ui, self.mode, _S.folders_window.music_location, "DirTreeNode", callback)
self.ui:addWindow(UIConfirmDialog(self.ui,
_S.confirmation.music_warning,
--[[persistable:mmusic_warning_confirm_dialog]]function()
self.ui:addWindow(browser)
end
))
end
function UIFolder:buttonBack()
self:close()
local window = UIOptions(self.ui, "menu")
self.ui:addWindow(window)
end
function UIFolder:close()
UIResizable.close(self)
if self.mode == "menu" then
self.ui:addWindow(UIMainMenu(self.ui))
end
end

View File

@@ -58,17 +58,17 @@ function UILuaConsole:UILuaConsole(ui)
self.min_width = 200
self.min_height = 150
self:setDefaultPosition(0.1, 0.1)
-- Window parts definition
self.default_button_sound = "selectx.wav"
-- Textbox for entering code
self.textbox = self:addBevelPanel(20, 20, 280, 140, col_textbox, col_highlight, col_shadow)
:setLabel("", app.gfx:loadBuiltinFont(), "left"):setTooltip(_S.tooltip.lua_console.textbox):setAutoClip(true)
:makeTextbox():allowedInput("all"):setText({""})
self.textbox:setActive(true) -- activated by default
-- "Execute" button
self.execute_button = self:addBevelPanel(20, self.height - 60, 130, 40, col_bg):setLabel(_S.lua_console.execute_code)
:makeButton(0, 0, 130, 40, nil, self.buttonExecute):setTooltip(_S.tooltip.lua_console.execute_code)
@@ -79,14 +79,14 @@ end
function UILuaConsole:setSize(width, height)
UIResizable.setSize(self, width, height)
self.textbox:setSize(self.width - 40, self.height - 100)
local button_width = math.floor((self.width - 60) / 2)
self.execute_button:setPosition(20, self.height - 60)
self.execute_button:setSize(button_width, 40)
self.close_button:setPosition(self.width - 20 - button_width, self.height - 60)
self.close_button:setSize(button_width, 40)
end

View File

@@ -29,7 +29,7 @@ local col_bg = {
function UIMainMenu:UIMainMenu(ui)
self:UIResizable(ui, 200, 300, col_bg)
local app = ui.app
self.esc_closes = false
self.modal_class = "main menu"
@@ -39,7 +39,7 @@ function UIMainMenu:UIMainMenu(ui)
-- The main menu also shows the version number of the player's copy of the game.
self.label_font = TheApp.gfx:loadFont("QData", "Font01V")
self.version_number = TheApp:getVersion()
-- individual buttons
self.default_button_sound = "selectx.wav"
self:addBevelPanel(20, 20, 160, 40, col_bg):setLabel(_S.main_menu.new_game):makeButton(0, 0, 160, 40, nil, self.buttonNewGame):setTooltip(_S.tooltip.main_menu.new_game)
@@ -71,7 +71,7 @@ end
function UIMainMenu:buttonNewGame()
local window = UINewGame(self.ui)
self.ui:addWindow(window)
end
function UIMainMenu:buttonCustomGame()

View File

@@ -54,7 +54,7 @@ function UIMenuList:UIMenuList(ui, mode, title, items, num_rows, extra_above_lis
self.default_button_sound = "selectx.wav"
self.items = items
self.num_rows = num_rows and num_rows or 10
local app = ui.app
self.mode = mode
self.modal_class = mode == "menu" and "main menu" or "saveload"
@@ -62,33 +62,33 @@ function UIMenuList:UIMenuList(ui, mode, title, items, num_rows, extra_above_lis
self.esc_closes = true
self.resizable = false
self:setDefaultPosition(0.5, 0.25)
self:addBevelPanel(20, 10, 240, 20, col_caption):setLabel(title)
.lowered = true
local scrollbar_base = self:addBevelPanel(240, 40 + extra_above_list, 20, self.num_rows*17, self.col_bg)
scrollbar_base.lowered = true
self.scrollbar = scrollbar_base:makeScrollbar(col_scrollbar, --[[persistable:menu_list_scrollbar_callback]] function()
self:updateButtons()
end, 1, math.max(#items, 1), self.num_rows)
local function button_clicked(num)
return --[[persistable:menu_list_button]] function(self)
self:buttonClicked(num)
end
end
self.item_panels = {}
self.item_buttons = {}
for num = 1, self.num_rows do
self.item_panels[num] = self:addBevelPanel(20, 40 + extra_above_list + (num - 1) * 17, 210, 17, self.col_bg):setLabel(nil, nil, "centre")
self.item_buttons[num] = self.item_panels[num]:makeButton(0, 0, 220, 17, nil, button_clicked(num))
end
self:addBevelPanel(20, 220 + extra_above_list, 240, 40, self.col_bg):setLabel(_S.menu_list_window.back)
:makeButton(0, 0, 240, 40, nil, self.buttonBack):setTooltip(_S.tooltip.menu_list_window.back)
self:updateButtons()
end

View File

@@ -51,7 +51,7 @@ function UICustomGame:UICustomGame(ui)
end
if level_name and level_file then
items[#items + 1] = {
name = level_name,
name = level_name,
tooltip = _S.tooltip.custom_game_window.start_game_with_name:format(level_file, level_intro),
level_file = level_file,
path = path .. file,
@@ -61,7 +61,7 @@ function UICustomGame:UICustomGame(ui)
end
end
self:UIMenuList(ui, "menu", _S.custom_game_window.caption, items, 10, 30)
-- Now add the free build button above the list.
if not pcall(function()
local palette = ui.app.gfx:loadPalette("QData", "DrugN01V.pal")
@@ -71,7 +71,7 @@ function UICustomGame:UICustomGame(ui)
self:close()
return
end
self:addBevelPanel(20, 40, 200, 20, self.col_bg):setLabel(_S.custom_game_window.free_build).lowered = true
local button = self:addPanel(12, 230, 36):makeToggleButton(0, 0, 29, 29, 11, self.buttonFreebuild)
:setTooltip(_S.tooltip.custom_game_window.free_build)

View File

@@ -59,14 +59,14 @@ local col_shadow = {
function UINewGame:UINewGame(ui)
self:UIResizable(ui, 320, 220, col_bg)
local app = ui.app
self.esc_closes = true
self.resizable = false
self.modal_class = "main menu"
self.on_top = true
self:setDefaultPosition(0.5, 0.25)
if TheApp.using_demo_files then
-- We're using the demo version of TH. Load directly and activate the tutorial.
-- Those who use the demo files probably want that anyway.
@@ -79,8 +79,8 @@ function UINewGame:UINewGame(ui)
self.border_sprites = app.gfx:loadSpriteTable("Bitmap", "aux_ui", true)
self.start_tutorial = false
self.difficulty = 1
local avail_diff = {
{text = _S.new_game_window.medium, tooltip = _S.tooltip.new_game_window.medium, param = "full"},
}

View File

@@ -69,9 +69,9 @@ function UIOptions:UIOptions(ui, mode)
self:setDefaultPosition(0.5, 0.25)
self.default_button_sound = "selectx.wav"
self.app = app
self:checkForAvailableLanguages()
-- Set up list of resolutions
self.available_resolutions = {
{text = "640x480 (4:3)", width = 640, height = 480},
@@ -89,12 +89,12 @@ function UIOptions:UIOptions(ui, mode)
{text = "1920x1200 (16:10)", width = 1920, height = 1200},
{text = _S.options_window.custom_resolution, custom = true},
}
-- Window parts definition
-- Title
self:addBevelPanel(80, 10, 165, 20, col_caption):setLabel(_S.options_window.caption)
.lowered = true
-- Fullscreen
self:addBevelPanel(20, 45, 135, 20, col_shadow, col_bg, col_bg)
:setLabel(_S.options_window.fullscreen):setTooltip(_S.tooltip.options_window.fullscreen).lowered = true
@@ -102,14 +102,14 @@ function UIOptions:UIOptions(ui, mode)
self:addBevelPanel(165, 45, 135, 20, col_bg):setLabel(app.fullscreen and _S.options_window.option_on or _S.options_window.option_off)
self.fullscreen_button = self.fullscreen_panel:makeToggleButton(0, 0, 140, 20, nil, self.buttonFullscreen)
:setToggleState(app.fullscreen):setTooltip(_S.tooltip.options_window.fullscreen_button)
-- Screen resolution
self:addBevelPanel(20, 70, 135, 20, col_shadow, col_bg, col_bg)
:setLabel(_S.options_window.resolution):setTooltip(_S.tooltip.options_window.resolution).lowered = true
self.resolution_panel = self:addBevelPanel(165, 70, 135, 20, col_bg):setLabel(app.config.width .. "x" .. app.config.height)
self.resolution_button = self.resolution_panel:makeToggleButton(0, 0, 135, 20, nil, self.dropdownResolution):setTooltip(_S.tooltip.options_window.select_resolution)
-- Language
local lang = string.upper(app.config.language)
self:addBevelPanel(20, 95, 135, 20, col_shadow, col_bg, col_bg)
@@ -123,17 +123,17 @@ function UIOptions:UIOptions(ui, mode)
self.volume_panel =
self:addBevelPanel(165, 120, 135, 20, col_bg):setLabel(app.config.audio and _S.customise_window.option_on or _S.customise_window.option_off)
self.volume_button = self.volume_panel:makeToggleButton(0, 0, 135, 20, nil, self.buttonAudioGlobal)
:setToggleState(app.config.audio):setTooltip(_S.tooltip.options_window.audio_toggle)
:setToggleState(app.config.audio):setTooltip(_S.tooltip.options_window.audio_toggle)
-- "Customise" button
self:addBevelPanel(20, 150, 135, 30, col_bg):setLabel(_S.options_window.customise)
:makeButton(0, 0, 135, 30, nil, self.buttonCustomise):setTooltip(_S.tooltip.options_window.customise_button)
:makeButton(0, 0, 135, 30, nil, self.buttonCustomise):setTooltip(_S.tooltip.options_window.customise_button)
-- "Folders" button
self:addBevelPanel(165, 150, 135, 30, col_bg):setLabel(_S.options_window.folder)
:makeButton(0, 0, 135, 30, nil, self.buttonFolder):setTooltip(_S.tooltip.options_window.folder_button)
:makeButton(0, 0, 135, 30, nil, self.buttonFolder):setTooltip(_S.tooltip.options_window.folder_button)
-- "Back" button
self:addBevelPanel(20, 190, 280, 40, col_bg):setLabel(_S.options_window.back)
:makeButton(0, 0, 280, 40, nil, self.buttonBack):setTooltip(_S.tooltip.options_window.back)
@@ -195,15 +195,15 @@ end
function UIOptions:selectResolution(number)
local res = self.available_resolutions[number]
local callback = --[[persistable:options_resolution_callback]] function(width, height)
if not self.ui:changeResolution(width, height) then
local err = {_S.errors.unavailable_screen_size}
self.ui:addWindow(UIInformation(self.ui, err))
self.ui:addWindow(UIInformation(self.ui, err))
end
self.resolution_panel:setLabel(self.ui.app.config.width .. "x" .. self.ui.app.config.height)
end
if res.custom then
self.resolution_panel:setLabel(self.ui.app.config.width .. "x" .. self.ui.app.config.height)
self.ui:addWindow(UIResolution(self.ui, callback))
@@ -274,7 +274,7 @@ class "UIResolution" (UIResizable)
function UIResolution:UIResolution(ui, callback)
self:UIResizable(ui, 200, 140, col_bg)
local app = ui.app
self.modal_class = "resolution"
self.on_top = true
@@ -282,9 +282,9 @@ function UIResolution:UIResolution(ui, callback)
self.resizable = false
self:setDefaultPosition(0.5, 0.5)
self.default_button_sound = "selectx.wav"
self.callback = callback
-- Window parts definition
-- Title
self:addBevelPanel(20, 10, 160, 20, col_caption):setLabel(_S.options_window.resolution)
@@ -300,7 +300,7 @@ function UIResolution:UIResolution(ui, callback)
self.height_textbox = self:addBevelPanel(100, 60, 80, 20, col_textbox, col_highlight, col_shadow)
:setTooltip(_S.tooltip.options_window.height)
:makeTextbox():allowedInput("numbers"):characterLimit(4):setText(tostring(app.config.height))
-- Apply and cancel
self:addBevelPanel(20, 90, 80, 40, col_bg):setLabel(_S.options_window.apply)
:makeButton(0, 0, 80, 40, nil, self.ok):setTooltip(_S.tooltip.options_window.apply)
@@ -318,8 +318,8 @@ function UIResolution:ok()
local err = {_S.errors.minimum_screen_size}
self.ui:addWindow(UIInformation(self.ui, err))
elseif width > 3000 or height > 2000 then
self.ui:addWindow(UIConfirmDialog(self.ui,
_S.confirmation.maximum_screen_size,
self.ui:addWindow(UIConfirmDialog(self.ui,
_S.confirmation.maximum_screen_size,
--[[persistable:maximum_screen_size_confirm_dialog]]function()
self:close(true)
self:close(false)

View File

@@ -29,13 +29,13 @@ local col_bg = {
function UITipOfTheDay:UITipOfTheDay(ui)
self:UIResizable(ui, 380, 110, col_bg)
local app = ui.app
self.ui = ui
self.resizable = false
self:setDefaultPosition(-20, -20)
self.white_font = app.gfx:loadFont("QData", "Font01V")
self.num_tips = #_S.totd_window.tips
if self.num_tips == 0 then
-- NB: #_S.totd_window.tips == 0, which implies something went wrong with
@@ -45,7 +45,7 @@ function UITipOfTheDay:UITipOfTheDay(ui)
return
end
self.tip_num = math.random(1, self.num_tips)
self:addBevelPanel(10, self.height - 30, self.width / 2 - 20, 20, col_bg):setLabel(_S.totd_window.previous)
:makeButton(0, 0, self.width / 2 - 20, 20, nil, self.buttonPrev):setTooltip(_S.tooltip.totd_window.previous)
self:addBevelPanel(self.width / 2 + 10, self.height - 30, self.width / 2 - 20, 20, col_bg):setLabel(_S.totd_window.next)

View File

@@ -1,130 +1,130 @@
--[[ Copyright (c) 2013 Alan Woolley
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. --]]
--! Options window used in the main menu and ingame.
class "UIUpdate" (UIResizable)
local col_bg = {
red = 154,
green = 146,
blue = 198,
}
local col_button = {
red = 84,
green = 200,
blue = 84,
}
local col_old_version = {
red = 255,
green = 0,
blue = 0,
}
local col_new_version = {
red = 0,
green = 255,
blue = 0,
}
local col_shadow = {
red = 134,
green = 126,
blue = 178,
}
local col_caption = {
red = 174,
green = 166,
blue = 218,
}
function UIUpdate:UIUpdate(ui, this_version, new_version, brief_description, download_url)
self:UIResizable(ui, 320, 320, col_bg)
local app = ui.app
self.modal_class = "main"
self.on_top = true
self.esc_closes = true
self.resizable = false
self:setDefaultPosition(0.5, 0.25)
self.default_button_sound = "selectx.wav"
self.description_text = brief_description
self.app = app
self.white_font = app.gfx:loadFont("QData", "Font01V")
self.download_url = download_url
local pathsep = package.config:sub(1, 1)
if pathsep == "\\" then
self.os_is_windows = true
else
self.os_is_windows = false
end
self:addBevelPanel(20, 50, 140, 20, col_shadow, col_bg, col_bg)
:setLabel(_S.update_window.current_version).lowered = true
self:addBevelPanel(20, 70, 140, 20, col_shadow, col_bg, col_bg)
:setLabel(_S.update_window.new_version).lowered = true
self:addBevelPanel (160,50,140,20, col_old_version, col_bg, col_bg):setLabel(this_version)
self:addBevelPanel (160,70,140,20, col_new_version, col_bg, col_bg):setLabel(new_version)
-- Title
self:addBevelPanel(80, 10, 160, 20, col_caption):setLabel(_S.update_window.caption)
.lowered = true
-- Download button
self:addBevelPanel(20, 225, 280, 40, col_bg):setLabel(_S.update_window.download)
:makeButton(0, 0, 280, 40, nil, self.buttonDownload):setTooltip(_S.tooltip.update_window.download)
-- Ignore button
self:addBevelPanel(20, 270, 280, 40, col_bg):setLabel(_S.update_window.ignore)
:makeButton(0, 0, 280, 40, nil, self.buttonIgnore):setTooltip(_S.tooltip.update_window.ignore)
end
function UIUpdate:draw(canvas, x, y)
-- Draw window components
UIResizable.draw(self, canvas, x, y)
-- Draw description
x, y = self.x + x, self.y + y
self.white_font:drawWrapped(canvas, self.description_text, x + 20, y + 100, self.width - 20)
end
function UIUpdate:buttonDownload()
if self.os_is_windows then
os.execute("start " .. self.download_url)
else
os.execute("xdg-open " .. self.download_url)
end
end
function UIUpdate:buttonIgnore()
self:close()
end
--[[ Copyright (c) 2013 Alan Woolley
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. --]]
--! Options window used in the main menu and ingame.
class "UIUpdate" (UIResizable)
local col_bg = {
red = 154,
green = 146,
blue = 198,
}
local col_button = {
red = 84,
green = 200,
blue = 84,
}
local col_old_version = {
red = 255,
green = 0,
blue = 0,
}
local col_new_version = {
red = 0,
green = 255,
blue = 0,
}
local col_shadow = {
red = 134,
green = 126,
blue = 178,
}
local col_caption = {
red = 174,
green = 166,
blue = 218,
}
function UIUpdate:UIUpdate(ui, this_version, new_version, brief_description, download_url)
self:UIResizable(ui, 320, 320, col_bg)
local app = ui.app
self.modal_class = "main"
self.on_top = true
self.esc_closes = true
self.resizable = false
self:setDefaultPosition(0.5, 0.25)
self.default_button_sound = "selectx.wav"
self.description_text = brief_description
self.app = app
self.white_font = app.gfx:loadFont("QData", "Font01V")
self.download_url = download_url
local pathsep = package.config:sub(1, 1)
if pathsep == "\\" then
self.os_is_windows = true
else
self.os_is_windows = false
end
self:addBevelPanel(20, 50, 140, 20, col_shadow, col_bg, col_bg)
:setLabel(_S.update_window.current_version).lowered = true
self:addBevelPanel(20, 70, 140, 20, col_shadow, col_bg, col_bg)
:setLabel(_S.update_window.new_version).lowered = true
self:addBevelPanel (160,50,140,20, col_old_version, col_bg, col_bg):setLabel(this_version)
self:addBevelPanel (160,70,140,20, col_new_version, col_bg, col_bg):setLabel(new_version)
-- Title
self:addBevelPanel(80, 10, 160, 20, col_caption):setLabel(_S.update_window.caption)
.lowered = true
-- Download button
self:addBevelPanel(20, 225, 280, 40, col_bg):setLabel(_S.update_window.download)
:makeButton(0, 0, 280, 40, nil, self.buttonDownload):setTooltip(_S.tooltip.update_window.download)
-- Ignore button
self:addBevelPanel(20, 270, 280, 40, col_bg):setLabel(_S.update_window.ignore)
:makeButton(0, 0, 280, 40, nil, self.buttonIgnore):setTooltip(_S.tooltip.update_window.ignore)
end
function UIUpdate:draw(canvas, x, y)
-- Draw window components
UIResizable.draw(self, canvas, x, y)
-- Draw description
x, y = self.x + x, self.y + y
self.white_font:drawWrapped(canvas, self.description_text, x + 20, y + 100, self.width - 20)
end
function UIUpdate:buttonDownload()
if self.os_is_windows then
os.execute("start " .. self.download_url)
else
os.execute("xdg-open " .. self.download_url)
end
end
function UIUpdate:buttonIgnore()
self:close()
end

View File

@@ -42,7 +42,7 @@ function UIStaff:changeParcel()
if not self.staff.hospital.ownedPlots[index + 1] then
self.staff.parcelNr = 0
else
self.staff.parcelNr = self.staff.hospital.ownedPlots[index + 1]
self.staff.parcelNr = self.staff.hospital.ownedPlots[index + 1]
end
end
@@ -59,7 +59,7 @@ end
function UIStaff:UIStaff(ui, staff)
self:Window()
local app = ui.app
local profile = staff.profile
self.esc_closes = true
@@ -76,7 +76,7 @@ function UIStaff:UIStaff(ui, staff)
self.panel_sprites = app.gfx:loadSpriteTable("QData", "Req01V", true)
self.white_font = app.gfx:loadFont("QData", "Font01V")
self.face_parts = app.gfx:loadRaw("Face01V", 65, 1350, nil, "Data", "MPalette.dat")
self:addPanel(297, 15, 0) -- Dialog header
for y = 51, 121, 10 do
self:addPanel(298, 15, y) -- Dialog background
@@ -85,7 +85,7 @@ function UIStaff:UIStaff(ui, staff)
self:addPanel(300, 105, 82) -- Tiredness
self:addPanel(301, 15, 114) -- Skills/Abilities
self:addColourPanel(35, 51, 71, 81, 208, 252, 252):makeButton(0, 0, 71, 81, nil, self.openStaffManagement):setTooltip(_S.tooltip.staff_window.face) -- Portrait background
if profile.humanoid_class == "Handyman" then
self:addPanel(311, 15, 131) -- Tasks top
for y = 149, 184, 5 do
@@ -113,16 +113,16 @@ function UIStaff:UIStaff(ui, staff)
end
self:addPanel(305, 178, 18):makeButton(0, 0, 24, 24, 306, self.close):setTooltip(_S.tooltip.staff_window.close)
self:makeTooltip(_S.tooltip.staff_window.name, 33, 19, 172, 42)
self:makeTooltip(_S.tooltip.staff_window.happiness, 113, 49, 204, 74)
self:makeTooltip(_S.tooltip.staff_window.tiredness, 113, 74, 204, 109)
self:makeTooltip(_S.tooltip.staff_window.ability, 113, 109, 204, 134)
if profile.humanoid_class == "Doctor" then
self:makeTooltip(_S.tooltip.staff_window.doctor_seniority, 30, 141, 111, 182)
self:makeTooltip(_S.tooltip.staff_window.skills, 111, 146, 141, 179)
local skill_to_string = {
is_surgeon = _S.tooltip.staff_window.surgeon,
is_psychiatrist = _S.tooltip.staff_window.psychiatrist,
@@ -135,15 +135,15 @@ function UIStaff:UIStaff(ui, staff)
end
end
end
self:makeDynamicTooltip(skill_tooltip("is_surgeon"), 143, 148, 155, 177)
self:makeDynamicTooltip(skill_tooltip("is_psychiatrist"), 155, 148, 177, 177)
self:makeDynamicTooltip(skill_tooltip("is_researcher"), 177, 148, 202, 177)
end
-- window for handyman is slightly different
local offset = profile.humanoid_class == "Handyman" and 27 or 0
self:makeTooltip(_S.tooltip.staff_window.salary, 90, 191 + offset, 204, 214 + offset)
-- Non-rectangular tooltip has to be realized with dynamic tooltip at the moment
self:makeDynamicTooltip(--[[persistable:staff_dialog_center_tooltip]]function(x, y)
@@ -151,7 +151,7 @@ function UIStaff:UIStaff(ui, staff)
return _S.tooltip.staff_window.center_view
end
end, 17, 211 + offset, 92, 286 + offset)
end
function UIStaff:getStaffPosition(dx, dy)
@@ -167,7 +167,7 @@ function UIStaff:draw(canvas, x_, y_)
local px, py = self:getStaffPosition(37, 61)
self.ui.app.map:draw(canvas, px, py, 75, 75, x + 17, y + self.height - 93)
Window.draw(self, canvas, x_, y_)
local profile = self.staff.profile
local font = self.white_font
@@ -200,7 +200,7 @@ function UIStaff:draw(canvas, x_, y_)
else
font:draw(canvas, "$" .. profile.wage, x + 135, y + 199) -- Wage
end
if self.staff.attributes["happiness"] then
local happiness_bar_width = math_floor(self.staff.attributes["happiness"] * 40 + 0.5)
if happiness_bar_width ~= 0 then
@@ -209,7 +209,7 @@ function UIStaff:draw(canvas, x_, y_)
end
end
end
local fatigue_bar_width = 40.5
if self.staff.attributes["fatigue"] then
fatigue_bar_width = math_floor((1 - self.staff.attributes["fatigue"]) * 40 + 0.5)
@@ -219,14 +219,14 @@ function UIStaff:draw(canvas, x_, y_)
self.panel_sprites:draw(canvas, 349, x + 139 + dx, y + 89)
end
end
local skill_bar_width = math_floor(profile.skill * 40 + 0.5)
if skill_bar_width ~= 0 then
for dx = 0, skill_bar_width - 1 do
self.panel_sprites:draw(canvas, 350, x + 139 + dx, y + 120)
end
end
if profile.humanoid_class == "Doctor" then
-- Junior / Doctor / Consultant marker
if profile.is_junior then
@@ -247,7 +247,7 @@ function UIStaff:draw(canvas, x_, y_)
self.panel_sprites:draw(canvas, 346, x + 178, y + 153)
end
end
profile:drawFace(canvas, x + 38, y + 54, self.face_parts) -- Portrait
end

View File

@@ -78,11 +78,11 @@ function UIStaffRise:UIStaffRise(ui, staff, rise_amount)
self:makeTooltip(_S.tooltip.staff_window.face, 96, 44, 168, 125)
self:makeTooltip(_S.tooltip.staff_window.salary, 14, 171, 168, 193)
self:makeTooltip(_S.tooltip.staff_window.ability, 12, 213, 89, 243)
if profile.humanoid_class == "Doctor" then
self:makeTooltip(_S.tooltip.staff_window.doctor_seniority, 89, 197, 168, 243)
self:makeTooltip(_S.tooltip.staff_window.skills, 14, 132, 47, 166)
-- NB: should be sufficient here to check only once, not make a dynamic tooltip
if profile.is_surgeon >= 1.0 then
self:makeTooltip(_S.tooltip.staff_window.surgeon, 72, 133, 87, 164)

View File

@@ -437,7 +437,7 @@ function TreeControl:TreeControl(root, x, y, width, height, col_bg, col_fg, y_of
self.width = width
self.height = height
self.y_offset = y_offset or 0
-- Load the graphical resources
local gfx = TheApp.gfx
if not has_font then
@@ -447,7 +447,7 @@ function TreeControl:TreeControl(root, x, y, width, height, col_bg, col_fg, y_of
end
self.tree_sprites = gfx:loadSpriteTable("Bitmap", "tree_ctrl", true,
gfx:loadPalette("Bitmap", "tree_ctrl.pal"))
-- Calculate sizes and counts
local scrollbar_width = 20
self.row_height = 14
@@ -590,7 +590,7 @@ end
function TreeControl:draw(canvas, x, y)
Window.draw(self, canvas, x, y)
x, y = self.x + x, self.y + y + self.y_offset
local node = self.first_visible_node
local num_nodes_drawn = 0
local y = y + self.tree_rect.y
@@ -600,7 +600,7 @@ function TreeControl:draw(canvas, x, y)
for i = 0, level - 1 do
self.tree_sprites:draw(canvas, 1, x + i * 14, y)
end
if node == self.highlighted_node then
local offset = (level + 1) * 14
local colour = node:getHighlightColour(canvas) or self.scrollbar.slider.colour
@@ -611,7 +611,7 @@ function TreeControl:draw(canvas, x, y)
local colour = node:getSelectColour(canvas) or self.scrollbar.slider.colour
canvas:drawRect(colour, x + offset - 1, y, self.tree_rect.w - offset - 1, self.row_height)
end
local icon
if not node:hasChildren() then
icon = 2

View File

@@ -25,9 +25,9 @@ class "UIWatch" (Window)
--!param count_type (string) One of: "open_countdown" or "emergency" or "epidemic"
function UIWatch:UIWatch(ui, count_type)
self:Window()
local app = ui.app
self.esc_closes = false
self.modal_class = "open_countdown"
self.tick_rate = math.floor((100 * app.world.hours_per_day) / 13)
@@ -41,15 +41,15 @@ function UIWatch:UIWatch(ui, count_type)
self.panel_sprites = app.gfx:loadSpriteTable("Data", "Watch01V", true)
self.epidemic = false
self.count_type = count_type
local end_sprite = (count_type == "epidemic") and 14 or 16
local tooltips = {
["initial_opening"] = _S.tooltip.watch.hospital_opening,
["emergency"] = _S.tooltip.watch.emergency,
["epidemic"] = _S.tooltip.watch.epidemic,
}
if count_type ~= "emergency" then
self.end_button = self:addPanel(end_sprite, 4, 0)
:makeButton(4, 0, 27, 28, end_sprite + 1, self.onCountdownEnd)

View File

@@ -52,7 +52,7 @@ disease.treatment_rooms = {
"inflation",
}
-- If a machine is required a small icon should appear in the drug casebook.
disease.requires_machine = true

View File

@@ -54,7 +54,7 @@ disease.diagnosis_rooms = {
"blood_machine",
"x_ray",
"psych",
"ward",
"ward",
}
-- Treatment rooms are the rooms which must be visited, in the given order, to
-- cure the disease.

View File

@@ -55,7 +55,7 @@ disease.diagnosis_rooms = {
"blood_machine",
"x_ray",
"psych",
"ward",
"ward",
}
-- Treatment rooms are the rooms which must be visited, in the given order, to
-- cure the disease.

View File

@@ -55,7 +55,7 @@ disease.diagnosis_rooms = {
"blood_machine",
"x_ray",
"psych",
"ward",
"ward",
}
-- Treatment rooms are the rooms which must be visited, in the given order, to
-- cure the disease.

View File

@@ -55,7 +55,7 @@ disease.diagnosis_rooms = {
"blood_machine",
"x_ray",
"psych",
"ward",
"ward",
}
-- Treatment rooms are the rooms which must be visited, in the given order, to
-- cure the disease.

View File

@@ -55,7 +55,7 @@ disease.diagnosis_rooms = {
"blood_machine",
"x_ray",
"psych",
"ward",
"ward",
}
-- Treatment rooms are the rooms which must be visited, in the given order, to
-- cure the disease.

View File

@@ -54,7 +54,7 @@ disease.diagnosis_rooms = {
"blood_machine",
"x_ray",
"psych",
"ward",
"ward",
}
-- Treatment rooms are the rooms which must be visited, in the given order, to
-- cure the disease.

View File

@@ -47,7 +47,7 @@ disease.initPatient = function(patient)
patient:setLayer(2, num1 * 2)
local num2 = math.random(0, 5) -- The second bandage yes/no
-- 6 does not exist, a few more arm bandages instead
if num2 == 3 then num2 = 4 end
if num2 == 3 then num2 = 4 end
patient:setLayer(3, num2 * 2)
-- There needs to be at least one bandage on the patient
local num3 = math.random(0, 5)
@@ -67,7 +67,7 @@ disease.diagnosis_rooms = {
disease.treatment_rooms = {
"fracture_clinic",
}
-- If a machine is required a small icon should appear in the drug casebook.
disease.requires_machine = true

View File

@@ -55,12 +55,12 @@ disease.diagnosis_rooms = {
"blood_machine",
"x_ray",
"psych",
"ward",
"ward",
}
-- Treatment rooms are the rooms which must be visited, in the given order, to
-- cure the disease.
disease.treatment_rooms = {
"pharmacy",
}
}
return disease

View File

@@ -54,7 +54,7 @@ disease.diagnosis_rooms = {
"blood_machine",
"x_ray",
"psych",
"ward",
"ward",
}
-- Treatment rooms are the rooms which must be visited, in the given order, to
-- cure the disease.

View File

@@ -55,7 +55,7 @@ disease.diagnosis_rooms = {
"blood_machine",
"x_ray",
"psych",
"ward",
"ward",
}
-- Treatment rooms are the rooms which must be visited, in the given order, to
-- cure the disease.

View File

@@ -32,7 +32,7 @@ disease.emergency_number = 12
disease.initPatient = function(patient)
patient:setType("Chewbacca Patient")
-- NB: Layers have no effect on the appearance until cured, at which point
-- they are standard male patient layers. The clinic does however sometimes
-- they are standard male patient layers. The clinic does however sometimes
-- change this so that a female emerge.
patient:setLayer(0, math.random(1, 5) * 2)
patient:setLayer(1, math.random(0, 3) * 2)
@@ -52,7 +52,7 @@ disease.diagnosis_rooms = {
disease.treatment_rooms = {
"electrolysis",
}
-- If a machine is required a small icon should appear in the drug casebook.
disease.requires_machine = true

View File

@@ -55,7 +55,7 @@ disease.diagnosis_rooms = {
"blood_machine",
"x_ray",
"psych",
"ward",
"ward",
}
-- Treatment rooms are the rooms which must be visited, in the given order, to
-- cure the disease.

View File

@@ -53,7 +53,7 @@ disease.diagnosis_rooms = {
"blood_machine",
"x_ray",
"psych",
"ward",
"ward",
}
-- Treatment rooms are the rooms which must be visited, in the given order, to
-- cure the disease.

View File

@@ -56,7 +56,7 @@ disease.diagnosis_rooms = {
"blood_machine",
"x_ray",
"psych",
"ward",
"ward",
}
-- Treatment rooms are the rooms which must be visited, in the given order, to
-- cure the disease.

View File

@@ -54,7 +54,7 @@ disease.diagnosis_rooms = {
"blood_machine",
"x_ray",
"psych",
"ward",
"ward",
}
-- Treatment rooms are the rooms which must be visited, in the given order, to
-- cure the disease.

View File

@@ -47,7 +47,7 @@ disease.diagnosis_rooms = {
"blood_machine",
"x_ray",
"psych",
"ward",
"ward",
}
-- Treatment rooms are the rooms which must be visited, in the given order, to

View File

@@ -54,7 +54,7 @@ disease.diagnosis_rooms = {
"blood_machine",
"x_ray",
"psych",
"ward",
"ward",
}
-- Treatment rooms are the rooms which must be visited, in the given order, to
-- cure the disease.

View File

@@ -56,7 +56,7 @@ disease.diagnosis_rooms = {
"blood_machine",
"x_ray",
"psych",
"ward",
"ward",
}
-- Treatment rooms are the rooms which must be visited, in the given order, to
-- cure the disease.

View File

@@ -56,7 +56,7 @@ disease.diagnosis_rooms = {
"blood_machine",
"x_ray",
"psych",
"ward",
"ward",
}
-- Treatment rooms are the rooms which must be visited, in the given order, to
-- cure the disease.

View File

@@ -54,7 +54,7 @@ disease.diagnosis_rooms = {
"blood_machine",
"x_ray",
"psych",
"ward",
"ward",
}
-- Treatment rooms are the rooms which must be visited, in the given order, to
-- cure the disease.

View File

@@ -54,7 +54,7 @@ disease.diagnosis_rooms = {
"blood_machine",
"x_ray",
"psych",
"ward",
"ward",
}
-- Treatment rooms are the rooms which must be visited, in the given order, to
-- cure the disease.

View File

@@ -56,7 +56,7 @@ disease.diagnosis_rooms = {
"blood_machine",
"x_ray",
"psych",
"ward",
"ward",
}
-- Treatment rooms are the rooms which must be visited, in the given order, to
-- cure the disease.

View File

@@ -54,7 +54,7 @@ disease.diagnosis_rooms = {
"blood_machine",
"x_ray",
"psych",
"ward",
"ward",
}
-- Treatment rooms are the rooms which must be visited, in the given order, to
-- cure the disease.

View File

@@ -54,7 +54,7 @@ disease.diagnosis_rooms = {
"blood_machine",
"x_ray",
"psych",
"ward",
"ward",
}
-- Treatment rooms are the rooms which must be visited, in the given order, to
-- cure the disease.

View File

@@ -55,7 +55,7 @@ disease.diagnosis_rooms = {
"blood_machine",
"x_ray",
"psych",
"ward",
"ward",
}
-- Treatment rooms are the rooms which must be visited, in the given order, to
-- cure the disease.

View File

@@ -54,7 +54,7 @@ disease.diagnosis_rooms = {
"blood_machine",
"x_ray",
"psych",
"ward",
"ward",
}
-- Treatment rooms are the rooms which must be visited, in the given order, to
-- cure the disease.

View File

@@ -103,7 +103,7 @@ anims("Standard Male Patient", 16, 18, 24, 26, 182, 184, 286,
anims("Gowned Male Patient", 406, 408, 414, 416) -- 0-10
anims("Stripped Male Patient", 818, 820, 826, 828) -- 0-16
anims("Stripped Male Patient 2", 818, 820, 826, 828) -- 0-16
anims("Stripped Male Patient 3", 818, 820, 826, 828)
anims("Stripped Male Patient 3", 818, 820, 826, 828)
anims("Alternate Male Patient", 2704, 2706, 2712, 2714, 2748, 2750, 2764, 2766) -- 0-10, ABC
anims("Slack Male Patient", 1484, 1486, 1492, 1494, 1524, 1526, 2764, 1494) -- 0-14, ABC
anims("Slack Female Patient", 0, 2, 8, 10, 258, 260, 294, 296, 2864, 2866) -- 0-16, ABC
@@ -112,7 +112,7 @@ anims("Standard Female Patient", 0, 2, 8, 10, 258, 260, 294,
anims("Gowned Female Patient", 2876, 2878, 2884, 2886) -- 0-8
anims("Stripped Female Patient", 834, 836, 842, 844) -- 0-16
anims("Stripped Female Patient 2", 834, 836, 842, 844) -- 0-16
anims("Stripped Female Patient 3", 834, 836, 842, 844)
anims("Stripped Female Patient 3", 834, 836, 842, 844)
anims("Transparent Female Patient",3012, 3014, 3020, 3022, 3052, 3054, 3068, 3070) -- 0-8, ABC
anims("Chewbacca Patient", 858, 860, 866, 868, 3526, 3528, 4150, 4152)
anims("Elvis Patient", 978, 980, 986, 988, 3634, 3636, 4868, 4870)
@@ -151,19 +151,19 @@ die_anims("Alien Female Patient", 4886, 3208, 3212, 3216, 3220)
-- | Falling Animations |
-- | Name |Anim| Notes
----+--------------------------------+-----+-----+-----+-----+------+------+
falling_anim("Standard Male Patient", 1682)
falling_anim("Standard Male Patient", 1682)
falling_anim("Standard Female Patient", 3116)
-- | On_ground Animations |
-- | Name |Anim| Notes
----+--------------------------------+-----+-----+-----+-----+------+------+
on_ground_anim("Standard Male Patient", 1258)
on_ground_anim("Standard Male Patient", 1258)
on_ground_anim("Standard Female Patient", 3116)
-- | Get_up Animations |
-- | Name |Anim| Notes
----+--------------------------------+-----+-----+-----+-----+------+------+
get_up_anim("Standard Male Patient", 384)
get_up_anim("Standard Male Patient", 384)
get_up_anim("Standard Female Patient", 580)
-- | Shake_fist Animations |
@@ -214,7 +214,7 @@ check_watch_anim("Slack Male Patient", 4060)
pee_anim("Elvis Patient", 970)
pee_anim("Standard Female Patient", 4744)
pee_anim("Slack Female Patient", 4744)
pee_anim("Standard Male Patient", 2244)
pee_anim("Standard Male Patient", 2244)
pee_anim("Alternate Male Patient", 4472)
pee_anim("Slack Male Patient", 4328)
pee_anim("Chewbacca Patient", 4178)
@@ -284,7 +284,7 @@ function Humanoid:Humanoid(...)
self.should_knock_on_doors = false
self.speed = "normal"
self.build_callbacks = {--[[set]]}
self.remove_callbacks = {--[[set]]}
end
@@ -293,7 +293,7 @@ end
function Humanoid:afterLoad(old, new)
if old < 38 then
-- should existing patients be updated and be getting really ill?
-- adds the new variables for health icons
-- adds the new variables for health icons
self.attributes["health"] = math.random(60, 100) /100
end
-- make sure female slack patients have the correct animation
@@ -365,7 +365,7 @@ function Humanoid:dump()
print("Actions:")
for i = 1, #self.action_queue do
local action = self.action_queue[i]
local flag =
local flag =
(action.must_happen and " must_happen" or " ") ..
(action.todo_interrupt and " " or " ")
if action.room_type then
@@ -380,7 +380,7 @@ function Humanoid:dump()
distance = "nil"
end
local standing = "false"
if action:isStanding() then
if action:isStanding() then
standing = "true"
end
print(action.name .. " - Bench distance: " .. distance .. " Standing: " .. standing)
@@ -424,9 +424,9 @@ function Humanoid:setHospital(hospital)
end
-- Function to activate/deactivate moods of a humanoid.
-- If mood_name is nil it is considered a refresh only.
-- If mood_name is nil it is considered a refresh only.
function Humanoid:setMood(mood_name, activate)
if mood_name then
if mood_name then
if activate and activate ~= "deactivate" then
if self.active_moods[mood_name] then
return -- No use doing anything if it already exists.
@@ -457,7 +457,7 @@ end
function Humanoid:setCallCompleted()
if self.on_call then
CallsDispatcher.onCheckpointCompleted(self.on_call)
CallsDispatcher.onCheckpointCompleted(self.on_call)
end
end
@@ -542,12 +542,12 @@ local function Humanoid_startAction(self)
end
))
action = self.action_queue[1]
end
---- There is an action to start ----
-- Call the action start handler
TheApp.humanoid_actions[action.name](action, self)
if action == self.action_queue[1] and action.todo_interrupt then
local high_priority = action.todo_interrupt == "high"
action.todo_interrupt = nil
@@ -566,13 +566,13 @@ function Humanoid:setNextAction(action, high_priority)
local i = 1
local queue = self.action_queue
local interrupted = false
-- Skip over any actions which must happen
while queue[i] and queue[i].must_happen do
interrupted = true
i = i + 1
end
-- Remove actions which are no longer going to happen
local done_set = {}
for j = #queue, i, -1 do
@@ -595,10 +595,10 @@ function Humanoid:setNextAction(action, high_priority)
end
end
end
-- Add the new action to the queue
queue[i] = action
-- Interrupt the current action and queue other actions to be interrupted
-- when they start.
if interrupted then
@@ -668,13 +668,13 @@ function Humanoid:setType(humanoid_class)
self.vomit_anim = vomit_animations[humanoid_class]
self.yawn_anim = yawn_animations[humanoid_class]
self.tap_foot_anim = tap_foot_animations[humanoid_class]
self.check_watch_anim = check_watch_animations[humanoid_class]
self.check_watch_anim = check_watch_animations[humanoid_class]
self.pee_anim = pee_animations[humanoid_class]
self.humanoid_class = humanoid_class
if #self.action_queue == 0 then
self:setNextAction {name = "idle"}
end
self.th:setPartialFlag(self.permanent_flags or 0, false)
if humanoid_class == "Invisible Patient" then
-- Invisible patients do not have very many pixels to hit, box works better
@@ -775,11 +775,11 @@ function Humanoid:tickDay()
if self.going_home then
return false
end
local temperature = self.world.map.th:getCellTemperature(self.tile_x, self.tile_y)
self.attributes.warmth = self.attributes.warmth * 0.75 + temperature * 0.25
-- If it is too hot or too cold, start to decrease happiness and
-- If it is too hot or too cold, start to decrease happiness and
-- show the corresponding icon. Otherwise we could get happier instead.
-- Let the player get into the level first though, don't decrease happiness the first year.
if self.attributes["warmth"] and self.hospital and not self.hospital.initial_grace then

View File

@@ -24,7 +24,7 @@ local TH = require "TH"
class "Machine" (Object)
function Machine:Machine(world, object_type, x, y, direction, etc)
self.total_usage = -1 -- Incremented in the constructor of Object.
self:Object(world, object_type, x, y, direction, etc)
@@ -102,7 +102,7 @@ function Machine:machineUsed(room)
if taskIndex == -1 then
local call = self.world.dispatcher:callForRepair(self, true, false, true)
self.hospital:addHandymanTask(self, "repairing", 2, self.tile_x, self.tile_y, call)
else
else
self.hospital:modifyHandymanTaskPriority(taskIndex, 2, "repairing")
end
elseif threshold >= 0.4 then
@@ -131,7 +131,7 @@ function Machine:createHandymanActions(handyman)
local --[[persistable:handyman_repair_after_use]] function after_use()
handyman:setCallCompleted()
handyman:setDynamicInfoText("")
handyman:setDynamicInfoText("")
self:machineRepaired(self:getRoom())
end
local action = {name = "walk", x = ux, y = uy, is_entering = this_room and true or false}
@@ -158,7 +158,7 @@ function Machine:createHandymanActions(handyman)
loop_callback = --[[persistable:handyman_meander_repair_loop_callback]] function()
if not self.user then
-- The machine is ready to be repaired.
-- The following statement will finish the meander action in the handyman's
-- The following statement will finish the meander action in the handyman's
-- action queue.
handyman:finishAction()
end
@@ -246,7 +246,7 @@ function Machine:updateDynamicInfo(only_update)
end
if self.strength then
self:setDynamicInfo("text", {
self.object_type.name,
self.object_type.name,
_S.dynamic_info.object.strength:format(self.strength),
_S.dynamic_info.object.times_used:format(self.times_used),
})

View File

@@ -37,7 +37,7 @@ end
function Object:Object(world, object_type, x, y, direction, etc)
local th = TH.animation()
self:Entity(th)
if etc == "map object" then
if direction % 2 == 0 then
direction = "north"
@@ -45,7 +45,7 @@ function Object:Object(world, object_type, x, y, direction, etc)
direction = "west"
end
end
self.ticks = object_type.ticks
self.object_type = object_type
self.world = world
@@ -113,7 +113,7 @@ function Object.slaveMixinClass(class_method_table)
local name = class.name(class_method_table)
local super = class.superclass(class_method_table)
local super_constructor = super[class.name(super)]
-- Constructor
class_method_table[name] = function(self, world, object_type, x, y, direction, ...)
super_constructor(self, world, object_type, x, y, direction, ...)
@@ -128,7 +128,7 @@ function Object.slaveMixinClass(class_method_table)
self.slave.master = self
end
end
-- Slave -> Master redirects
local function slave_to_master(method)
local super_method = super[method]
@@ -144,7 +144,7 @@ function Object.slaveMixinClass(class_method_table)
slave_to_master("onClick")
slave_to_master("updateDynamicInfo")
slave_to_master("getDynamicInfo")
-- Master -> Slave notifications
local function master_to_slave(method)
local super_method = super[method]
@@ -181,7 +181,7 @@ function Object.slaveMixinClass(class_method_table)
end
return super.setTile(self, x, y)
end
return slave_to_master, master_to_slave
end
@@ -293,13 +293,13 @@ end
function Object:setTile(x, y)
local function coordinatesAreInFootprint(object_footprint, x, y)
for i, xy in ipairs(object_footprint) do
if(xy[1] == x and xy[2] == y) then
if(xy[1] == x and xy[2] == y) then
return true
end
end
end
return false
end
end
local function isEmpty(table)
for _, _ in pairs(table) do
return false
@@ -314,7 +314,7 @@ function Object:setTile(x, y)
return passable_flag == "travelEast" and "travelWest" or "travelEast"
end
end
local function setPassableFlags(passable_flag, x, y, next_x, next_y, value)
local flags1 = {}
flags1[passable_flag] = value
@@ -323,27 +323,27 @@ function Object:setTile(x, y)
flags2[getComplementaryPassableFlag(passable_flag)] = value
self.world.map.th:setCellFlags(next_x, next_y, flags2)
end
local direction_parameters = {
north = { x = 0, y = -1, buildable_flag = "buildableNorth", passable_flag = "travelNorth", needed_side = "need_north_side"},
east = { x = 1, y = 0, buildable_flag = "buildableEast", passable_flag = "travelEast", needed_side = "need_east_side"},
south = { x = 0, y = 1, buildable_flag = "buildableSouth", passable_flag = "travelSouth", needed_side = "need_south_side"},
west = { x = -1, y = 0, buildable_flag = "buildableWest", passable_flag = "travelWest", needed_side = "need_west_side"}
}
local direction = self.direction
if self.object_type.thob == 50 and direction == "east" then
direction = "west"
end
if self.tile_x ~= nil then
self.world:removeObjectFromTile(self, self.tile_x, self.tile_y)
if self.footprint then
local map = self.world.map.th
for _, xy in ipairs(self.footprint) do
local x, y = self.tile_x + xy[1], self.tile_y + xy[2]
if xy.only_side then
if xy.only_side then
if self.set_passable_flags then
self.set_passable_flags = nil
local par = direction_parameters[direction]
@@ -356,15 +356,15 @@ function Object:setTile(x, y)
else
local flags_to_set = {}
for _, value in pairs(direction_parameters) do
if coordinatesAreInFootprint(self.footprint, xy[1] + value["x"], xy[2] + value["y"]) or
if coordinatesAreInFootprint(self.footprint, xy[1] + value["x"], xy[2] + value["y"]) or
xy.complete_cell or xy[value["needed_side"]] then
flags_to_set[value["buildable_flag"]] = true
end
end
if not isEmpty(flags_to_set) then
map:setCellFlags(x, y, flags_to_set)
end
end
if not map:getCellFlags(x, y).passable then
map:setCellFlags(x, y, {
buildable = true,
@@ -385,7 +385,7 @@ function Object:setTile(x, y)
end
self.tile_x = x
self.tile_y = y
if x then
if x then
self.th:setDrawingLayer(self:getDrawingLayer())
self.th:setTile(self.world.map.th, self:getRenderAttachTile())
self.world:addObjectToTile(self, x, y)
@@ -397,14 +397,14 @@ function Object:setTile(x, y)
local roomId = room and room.id
local next_tile_x, next_tile_y = x,y
local passable_flag
for _, xy in ipairs(self.footprint) do
local change_flags = true
local flags_to_set = {}
local lx = x + xy[1]
local ly = y + xy[2]
local flag
if xy.optional then
if optional_found then
-- An optional tile has been accepted, we don't need anymore such tiles.
@@ -415,7 +415,7 @@ function Object:setTile(x, y)
if xy.only_passable then
flag = "passable"
end
local cell_flags = map:getCellFlags(lx, ly, flags)[flag]
local is_object_allowed = true
if roomId and flags.roomId ~= roomId then
@@ -423,7 +423,7 @@ function Object:setTile(x, y)
elseif xy.only_passable and not self.world.pathfinder:isReachableFromHospital(lx, ly) then
is_object_allowed = false
end
if is_object_allowed then
change_flags = true
optional_found = true
@@ -432,15 +432,15 @@ function Object:setTile(x, y)
end
end
end
map:getCellFlags(lx, ly, flags)
if xy.only_side then
local par = direction_parameters[direction]
flags_to_set[par["buildable_flag"]] = false
passable_flag, next_tile_x, next_tile_y = par["passable_flag"], x + par["x"], y + par["y"]
else
else
for _, value in pairs(direction_parameters) do
if coordinatesAreInFootprint(self.footprint, xy[1] + value["x"], xy[2] + value["y"]) or
if coordinatesAreInFootprint(self.footprint, xy[1] + value["x"], xy[2] + value["y"]) or
xy.complete_cell or xy[value["needed_side"]] then
if map:getCellFlags(x, y, flags)[value["buildable_flag"]] == 0 then
change_flags = false
@@ -448,10 +448,10 @@ function Object:setTile(x, y)
flags_to_set[value["buildable_flag"]] = false
end
end
end
end
if change_flags then
if not xy.only_side then
if not xy.only_side then
map:setCellFlags(lx, ly, {
buildable = false,
passable = not not xy.only_passable,
@@ -459,7 +459,7 @@ function Object:setTile(x, y)
end
if not isEmpty(flags_to_set) then
map:setCellFlags(lx, ly, flags_to_set)
end
end
if xy.only_side then
if map:getCellFlags(lx, ly)[passable_flag] == true then
self.set_passable_flags = true
@@ -553,7 +553,7 @@ end
-- If multiple_users_allowed is true: Removes the user specified from this object's list of reserved users.
-- If the argument is nil it is assumed that the list should be emptied.
-- Note that if there are many humanoids reserving this object reserved_for might still be set after a
-- Note that if there are many humanoids reserving this object reserved_for might still be set after a
-- call to this function.
-- Otherwise: sets reserved_for to nil.
function Object:removeReservedUser(user)
@@ -622,7 +622,7 @@ function Object:onClick(ui, button, data)
local room = self:getRoom()
window = window and window.visible and window
local direction = self.direction
if (not room and window)
if (not room and window)
or (room and not (window and window.room == room) and not self.object_type.corridor_object)
or (not room and not self.object_type.corridor_object) then
return
@@ -636,14 +636,14 @@ function Object:onClick(ui, button, data)
if self.object_type.class == "Plant" or self.object_type.class == "Machine" then
local taskType = "watering"
if self.object_type.class == "Machine" then
taskType = "repairing"
taskType = "repairing"
end
local index = self.hospital:getIndexOfTask(self.tile_x, self.tile_y, taskType)
if index ~= -1 then
self.hospital:removeHandymanTask(index, taskType)
end
end
self.picked_up = true
self.world:destroyEntity(self)
-- NB: the object has to be destroyed before updating/creating the window,
@@ -693,9 +693,9 @@ function Object:onDestroy()
self.reserved_for:handleRemovedObject(self)
end
self.reserved_for = nil
Entity.onDestroy(self)
end
function Object:afterLoad(old, new)
@@ -715,7 +715,7 @@ function Object:afterLoad(old, new)
if object_type.class == "SideObject" then
local flags = {buildable = true}
self.world.map.th:setCellFlags(self.tile_x, self.tile_y, flags)
end
end
self:setTile(self.tile_x, self.tile_y)
end
end
@@ -727,8 +727,8 @@ local all_pathfind_dirs = {[0] = true, [1] = true, [2] = true, [3] = true}
function Object.processTypeDefinition(object_type)
if object_type.id == "extinguisher"
or object_type.id == "radiator"
or object_type.id == "plant"
or object_type.id == "reception_desk"
or object_type.id == "plant"
or object_type.id == "reception_desk"
or object_type.id == "bench" then
object_type.count_category = object_type.id
elseif object_type.id ~= "bin"
@@ -757,7 +757,7 @@ function Object.processTypeDefinition(object_type)
elseif not details.use_position then
details.use_position = {0, 0}
end
-- Set handyman repair tile
-- Set handyman repair tile
if object_type.default_strength and not details.handyman_position then
details.handyman_position = details.use_position
end

Some files were not shown because too many files have changed in this diff Show More