mirror of
https://github.com/CorsixTH/CorsixTH.git
synced 2025-07-23 04:13:01 +02:00
Apply whitespace fix to SDL2 branch.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
@@ -66,7 +66,7 @@ protected:
|
||||
|
||||
std::vector<_sprite_t> m_vSprites;
|
||||
THAnimations m_oAnims;
|
||||
|
||||
|
||||
wxTextCtrl* m_txtTable;
|
||||
wxTextCtrl* m_txtData;
|
||||
wxTextCtrl* m_txtPalette;
|
||||
|
@@ -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();
|
||||
}
|
||||
|
@@ -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;
|
||||
};
|
||||
};
|
||||
|
@@ -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';
|
||||
|
@@ -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 )
|
||||
{
|
||||
|
@@ -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.
|
||||
|
@@ -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
|
||||
|
@@ -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 ] =
|
||||
{
|
||||
{ "&", 5, '&' },
|
||||
{ "<", 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
|
||||
|
@@ -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"]))
|
||||
|
@@ -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 "")))
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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.
|
||||
-------------------------------------------------------------------------------------------------------------------------
|
||||
|
@@ -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.
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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)
|
||||
|
@@ -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)
|
||||
|
@@ -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")
|
||||
|
@@ -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)
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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 = "-"
|
||||
|
@@ -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
|
||||
|
@@ -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)
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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"))
|
||||
|
@@ -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)
|
||||
|
@@ -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)
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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)
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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()
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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)
|
||||
|
@@ -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
|
||||
|
@@ -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)
|
||||
|
@@ -49,4 +49,4 @@ function UILoadGame:close()
|
||||
if self.mode == "menu" then
|
||||
self.ui:addWindow(UIMainMenu(self.ui))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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()
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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)
|
||||
|
@@ -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"},
|
||||
}
|
||||
|
@@ -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)
|
||||
|
@@ -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)
|
||||
|
@@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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)
|
||||
|
@@ -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
|
||||
|
@@ -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)
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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.
|
||||
|
@@ -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.
|
||||
|
@@ -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.
|
||||
|
@@ -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.
|
||||
|
@@ -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.
|
||||
|
@@ -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.
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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.
|
||||
|
@@ -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.
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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.
|
||||
|
@@ -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.
|
||||
|
@@ -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.
|
||||
|
@@ -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.
|
||||
|
@@ -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
|
||||
|
@@ -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.
|
||||
|
@@ -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.
|
||||
|
@@ -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.
|
||||
|
@@ -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.
|
||||
|
@@ -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.
|
||||
|
@@ -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.
|
||||
|
@@ -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.
|
||||
|
@@ -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.
|
||||
|
@@ -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.
|
||||
|
@@ -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.
|
||||
|
@@ -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
|
||||
|
@@ -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),
|
||||
})
|
||||
|
@@ -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
Reference in New Issue
Block a user