Merge branch 'master' into blueprints

This commit is contained in:
dP
2021-09-21 23:48:34 +03:00
723 changed files with 42005 additions and 23143 deletions

View File

@@ -1,3 +1,4 @@
add_subdirectory(fmt)
add_subdirectory(md5)
add_subdirectory(squirrel)
add_subdirectory(opengl)

5
src/3rdparty/fmt/CMakeLists.txt vendored Normal file
View File

@@ -0,0 +1,5 @@
add_files(
core.h
format.h
format-inl.h
)

27
src/3rdparty/fmt/LICENSE.rst vendored Normal file
View File

@@ -0,0 +1,27 @@
Copyright (c) 2012 - present, Victor Zverovich
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.
--- Optional exception to the license ---
As an exception, if, as a result of your compiling your source code, portions
of this Software are embedded into a machine-executable object form of such
source code, you may redistribute such embedded portions in such object form
without including the above copyright and permission notices.

2122
src/3rdparty/fmt/core.h vendored Normal file

File diff suppressed because it is too large Load Diff

2801
src/3rdparty/fmt/format-inl.h vendored Normal file

File diff suppressed because it is too large Load Diff

3960
src/3rdparty/fmt/format.h vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -17,7 +17,7 @@ void sqstd_printcallstack(HSQUIRRELVM v)
SQFloat f;
const SQChar *s;
SQInteger level=1; //1 is to skip this function that is level 0
const SQChar *name=0;
const SQChar *name=nullptr;
SQInteger seq=0;
pf(v,"\nCALLSTACK\n");
while(SQ_SUCCEEDED(sq_stackinfos(v,level,&si)))
@@ -116,7 +116,7 @@ static SQInteger _sqstd_aux_printerror(HSQUIRRELVM v)
{
SQPRINTFUNCTION pf = sq_getprintfunc(v);
if(pf) {
const SQChar *sErr = 0;
const SQChar *sErr = nullptr;
if(sq_gettop(v)>=1) {
if(SQ_SUCCEEDED(sq_getstring(v,2,&sErr))) {
pf(v,"\nAN ERROR HAS OCCURRED [%s]\n",sErr);

View File

@@ -88,7 +88,7 @@ static SQRegFunction mathlib_funcs[] = {
#endif /* EXPORT_DEFAULT_SQUIRREL_FUNCTIONS */
_DECL_FUNC(fabs,2,".n"),
_DECL_FUNC(abs,2,".n"),
{0,0,0,0},
{nullptr,nullptr,0,nullptr},
};
#ifndef M_PI
@@ -98,7 +98,7 @@ static SQRegFunction mathlib_funcs[] = {
SQRESULT sqstd_register_mathlib(HSQUIRRELVM v)
{
SQInteger i=0;
while(mathlib_funcs[i].name!=0) {
while(mathlib_funcs[i].name!=nullptr) {
sq_pushstring(v,mathlib_funcs[i].name,-1);
sq_newclosure(v,mathlib_funcs[i].f,0);
sq_setparamscheck(v,mathlib_funcs[i].nparamscheck,mathlib_funcs[i].typemask);

View File

@@ -60,11 +60,11 @@ HSQUIRRELVM sq_open(SQInteger initialstacksize)
v = (SQVM *)SQ_MALLOC(sizeof(SQVM));
new (v) SQVM(ss);
ss->_root_vm = v;
if(v->Init(NULL, initialstacksize)) {
if(v->Init(nullptr, initialstacksize)) {
return v;
} else {
sq_delete(v, SQVM);
return NULL;
return nullptr;
}
return v;
}
@@ -83,7 +83,7 @@ HSQUIRRELVM sq_newthread(HSQUIRRELVM friendvm, SQInteger initialstacksize)
return v;
} else {
sq_delete(v, SQVM);
return NULL;
return nullptr;
}
}
@@ -135,7 +135,7 @@ void sq_close(HSQUIRRELVM v)
SQRESULT sq_compile(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p,const SQChar *sourcename,SQBool raiseerror)
{
SQObjectPtr o;
if(Compile(v, read, p, sourcename, o, raiseerror?true:false, _ss(v)->_debuginfo)) {
if(Compile(v, read, p, sourcename, o, raiseerror != 0, _ss(v)->_debuginfo)) {
v->Push(SQClosure::Create(_ss(v), _funcproto(o)));
return SQ_OK;
}
@@ -144,12 +144,12 @@ SQRESULT sq_compile(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p,const SQCha
void sq_enabledebuginfo(HSQUIRRELVM v, SQBool enable)
{
_ss(v)->_debuginfo = enable?true:false;
_ss(v)->_debuginfo = enable != 0;
}
void sq_notifyallexceptions(HSQUIRRELVM v, SQBool enable)
{
_ss(v)->_notifyallexceptions = enable?true:false;
_ss(v)->_notifyallexceptions = enable != 0;
}
void sq_addref(HSQUIRRELVM v,HSQOBJECT *po)
@@ -178,7 +178,7 @@ const SQChar *sq_objtostring(HSQOBJECT *o)
if(sq_type(*o) == OT_STRING) {
return _stringval(*o);
}
return NULL;
return nullptr;
}
SQInteger sq_objtointeger(HSQOBJECT *o)
@@ -224,7 +224,7 @@ void sq_pushinteger(HSQUIRRELVM v,SQInteger n)
void sq_pushbool(HSQUIRRELVM v,SQBool b)
{
v->Push(b?true:false);
v->Push(b != 0);
}
void sq_pushfloat(HSQUIRRELVM v,SQFloat n)
@@ -256,7 +256,7 @@ void sq_newarray(HSQUIRRELVM v,SQInteger size)
SQRESULT sq_newclass(HSQUIRRELVM v,SQBool hasbase)
{
SQClass *baseclass = NULL;
SQClass *baseclass = nullptr;
if(hasbase) {
SQObjectPtr &base = stack_get(v,-1);
if(type(base) != OT_CLASS)
@@ -555,7 +555,7 @@ SQRESULT sq_getbool(HSQUIRRELVM v,SQInteger idx,SQBool *b)
SQRESULT sq_getstring(HSQUIRRELVM v,SQInteger idx,const SQChar **c)
{
SQObjectPtr *o = NULL;
SQObjectPtr *o = nullptr;
_GETSAFE_OBJ(v, idx, OT_STRING,o);
*c = _stringval(*o);
return SQ_OK;
@@ -563,7 +563,7 @@ SQRESULT sq_getstring(HSQUIRRELVM v,SQInteger idx,const SQChar **c)
SQRESULT sq_getthread(HSQUIRRELVM v,SQInteger idx,HSQUIRRELVM *thread)
{
SQObjectPtr *o = NULL;
SQObjectPtr *o = nullptr;
_GETSAFE_OBJ(v, idx, OT_THREAD,o);
*thread = _thread(*o);
return SQ_OK;
@@ -598,7 +598,7 @@ SQInteger sq_getsize(HSQUIRRELVM v, SQInteger idx)
SQRESULT sq_getuserdata(HSQUIRRELVM v,SQInteger idx,SQUserPointer *p,SQUserPointer *typetag)
{
SQObjectPtr *o = NULL;
SQObjectPtr *o = nullptr;
_GETSAFE_OBJ(v, idx, OT_USERDATA,o);
(*p) = _userdataval(*o);
if(typetag) *typetag = _userdata(*o)->_typetag;
@@ -637,7 +637,7 @@ SQRESULT sq_gettypetag(HSQUIRRELVM v,SQInteger idx,SQUserPointer *typetag)
SQRESULT sq_getuserpointer(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p)
{
SQObjectPtr *o = NULL;
SQObjectPtr *o = nullptr;
_GETSAFE_OBJ(v, idx, OT_USERPOINTER,o);
(*p) = _userpointer(*o);
return SQ_OK;
@@ -666,13 +666,13 @@ SQRESULT sq_getinstanceup(HSQUIRRELVM v, SQInteger idx, SQUserPointer *p,SQUserP
SQObjectPtr &o = stack_get(v,idx);
if(type(o) != OT_INSTANCE) return sq_throwerror(v,"the object is not a class instance");
(*p) = _instance(o)->_userpointer;
if(typetag != 0) {
if(typetag != nullptr) {
SQClass *cl = _instance(o)->_class;
do{
if(cl->_typetag == typetag)
return SQ_OK;
cl = cl->_base;
}while(cl != NULL);
}while(cl != nullptr);
return sq_throwerror(v,"invalid type tag");
}
return SQ_OK;
@@ -724,7 +724,7 @@ SQRESULT sq_newslot(HSQUIRRELVM v, SQInteger idx, SQBool bstatic)
if(type(self) == OT_TABLE || type(self) == OT_CLASS) {
SQObjectPtr &key = v->GetUp(-2);
if(type(key) == OT_NULL) return sq_throwerror(v, "null is not a valid key");
v->NewSlot(self, key, v->GetUp(-1),bstatic?true:false);
v->NewSlot(self, key, v->GetUp(-1),bstatic != 0);
v->Pop(2);
}
return SQ_OK;
@@ -801,14 +801,14 @@ SQRESULT sq_setdelegate(HSQUIRRELVM v,SQInteger idx)
if(!_table(self)->SetDelegate(_table(mt))) return sq_throwerror(v, "delagate cycle");
v->Pop();}
else if(type(mt)==OT_NULL) {
_table(self)->SetDelegate(NULL); v->Pop(); }
_table(self)->SetDelegate(nullptr); v->Pop(); }
else return sq_aux_invalidtype(v,type);
break;
case OT_USERDATA:
if(type(mt)==OT_TABLE) {
_userdata(self)->SetDelegate(_table(mt)); v->Pop(); }
else if(type(mt)==OT_NULL) {
_userdata(self)->SetDelegate(NULL); v->Pop(); }
_userdata(self)->SetDelegate(nullptr); v->Pop(); }
else return sq_aux_invalidtype(v, type);
break;
default:
@@ -909,7 +909,7 @@ const SQChar *sq_getlocal(HSQUIRRELVM v,SQUnsignedInteger level,SQUnsignedIntege
}
SQVM::CallInfo &ci=v->_callsstack[lvl];
if(type(ci._closure)!=OT_CLOSURE)
return NULL;
return nullptr;
SQClosure *c=_closure(ci._closure);
SQFunctionProto *func=_funcproto(c->_function);
if(func->_noutervalues > (SQInteger)idx) {
@@ -919,7 +919,7 @@ const SQChar *sq_getlocal(HSQUIRRELVM v,SQUnsignedInteger level,SQUnsignedIntege
idx -= func->_noutervalues;
return func->GetLocal(v,stackbase,idx,(SQInteger)(ci._ip-func->_instructions)-1);
}
return NULL;
return nullptr;
}
void sq_pushobject(HSQUIRRELVM v,HSQOBJECT obj)
@@ -929,7 +929,7 @@ void sq_pushobject(HSQUIRRELVM v,HSQOBJECT obj)
void sq_resetobject(HSQOBJECT *po)
{
po->_unVal.pUserPointer=NULL;po->_type=OT_NULL;
po->_unVal.pUserPointer=nullptr;po->_type=OT_NULL;
}
SQRESULT sq_throwerror(HSQUIRRELVM v,const SQChar *err)
@@ -975,7 +975,7 @@ SQRESULT sq_call(HSQUIRRELVM v,SQInteger params,SQBool retval,SQBool raiseerror,
v->_can_suspend = suspend >= 0;
if (v->_can_suspend) v->_ops_till_suspend = suspend;
if(v->Call(v->GetUp(-(params+1)),params,v->_top-params,res,raiseerror?true:false,v->_can_suspend)){
if(v->Call(v->GetUp(-(params+1)),params,v->_top-params,res,raiseerror != 0,v->_can_suspend)){
if(!v->_suspended) {
v->Pop(params);//pop closure and args
}
@@ -1051,7 +1051,7 @@ void sq_setcompilererrorhandler(HSQUIRRELVM v,SQCOMPILERERROR f)
SQRESULT sq_writeclosure(HSQUIRRELVM v,SQWRITEFUNC w,SQUserPointer up)
{
SQObjectPtr *o = NULL;
SQObjectPtr *o = nullptr;
_GETSAFE_OBJ(v, -1, OT_CLOSURE,o);
unsigned short tag = SQ_BYTECODE_STREAM_TAG;
if(w(up,&tag,2) != 2)
@@ -1093,7 +1093,7 @@ SQInteger sq_collectgarbage(HSQUIRRELVM v)
const SQChar *sq_getfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval)
{
SQObjectPtr &self = stack_get(v,idx);
const SQChar *name = NULL;
const SQChar *name = nullptr;
if(type(self) == OT_CLOSURE) {
if(_closure(self)->_outervalues.size()>nval) {
v->Push(_closure(self)->_outervalues[nval]);
@@ -1131,7 +1131,7 @@ SQRESULT sq_setfreevariable(HSQUIRRELVM v,SQInteger idx,SQUnsignedInteger nval)
SQRESULT sq_setattributes(HSQUIRRELVM v,SQInteger idx)
{
SQObjectPtr *o = NULL;
SQObjectPtr *o = nullptr;
_GETSAFE_OBJ(v, idx, OT_CLASS,o);
SQObjectPtr &key = stack_get(v,-2);
SQObjectPtr &val = stack_get(v,-1);
@@ -1153,7 +1153,7 @@ SQRESULT sq_setattributes(HSQUIRRELVM v,SQInteger idx)
SQRESULT sq_getattributes(HSQUIRRELVM v,SQInteger idx)
{
SQObjectPtr *o = NULL;
SQObjectPtr *o = nullptr;
_GETSAFE_OBJ(v, idx, OT_CLASS,o);
SQObjectPtr &key = stack_get(v,-1);
SQObjectPtr attrs;
@@ -1173,7 +1173,7 @@ SQRESULT sq_getattributes(HSQUIRRELVM v,SQInteger idx)
SQRESULT sq_getbase(HSQUIRRELVM v,SQInteger idx)
{
SQObjectPtr *o = NULL;
SQObjectPtr *o = nullptr;
_GETSAFE_OBJ(v, idx, OT_CLASS,o);
if(_class(*o)->_base)
v->Push(SQObjectPtr(_class(*o)->_base));
@@ -1184,7 +1184,7 @@ SQRESULT sq_getbase(HSQUIRRELVM v,SQInteger idx)
SQRESULT sq_getclass(HSQUIRRELVM v,SQInteger idx)
{
SQObjectPtr *o = NULL;
SQObjectPtr *o = nullptr;
_GETSAFE_OBJ(v, idx, OT_INSTANCE,o);
v->Push(SQObjectPtr(_instance(*o)->_class));
return SQ_OK;
@@ -1192,7 +1192,7 @@ SQRESULT sq_getclass(HSQUIRRELVM v,SQInteger idx)
SQRESULT sq_createinstance(HSQUIRRELVM v,SQInteger idx)
{
SQObjectPtr *o = NULL;
SQObjectPtr *o = nullptr;
_GETSAFE_OBJ(v, idx, OT_CLASS,o);
v->Push(_class(*o)->CreateInstance());
return SQ_OK;

View File

@@ -248,29 +248,29 @@ static SQRegFunction base_funcs[]={
{"getconsttable",base_getconsttable,1, NULL},
{"setconsttable",base_setconsttable,2, NULL},
#endif
{"assert",base_assert,2, NULL},
{"print",base_print,2, NULL},
{"assert",base_assert,2, nullptr},
{"print",base_print,2, nullptr},
#ifdef EXPORT_DEFAULT_SQUIRREL_FUNCTIONS
{"compilestring",base_compilestring,-2, ".ss"},
{"newthread",base_newthread,2, ".c"},
{"suspend",base_suspend,-1, NULL},
#endif
{"array",base_array,-2, ".n"},
{"type",base_type,2, NULL},
{"type",base_type,2, nullptr},
#ifdef EXPORT_DEFAULT_SQUIRREL_FUNCTIONS
{"dummy",base_dummy,0,NULL},
#ifndef NO_GARBAGE_COLLECTOR
{"collectgarbage",base_collectgarbage,1, "t"},
#endif
#endif
{0,0,0,0}
{nullptr,nullptr,0,nullptr}
};
void sq_base_register(HSQUIRRELVM v)
{
SQInteger i=0;
sq_pushroottable(v);
while(base_funcs[i].name!=0) {
while(base_funcs[i].name!=nullptr) {
sq_pushstring(v,base_funcs[i].name,-1);
sq_newclosure(v,base_funcs[i].f,0);
sq_setnativeclosurename(v,-1,base_funcs[i].name);
@@ -415,10 +415,10 @@ SQRegFunction SQSharedState::_table_default_delegate_funcz[]={
{"rawset",table_rawset,3, "t"},
{"rawdelete",table_rawdelete,2, "t"},
{"rawin",container_rawexists,2, "t"},
{"weakref",obj_delegate_weakref,1, NULL },
{"weakref",obj_delegate_weakref,1, nullptr },
{"tostring",default_delegate_tostring,1, "."},
{"clear",obj_clear,1, "."},
{0,0,0,0}
{nullptr,nullptr,0,nullptr}
};
//ARRAY DEFAULT DELEGATE///////////////////////////////////////
@@ -624,10 +624,10 @@ SQRegFunction SQSharedState::_array_default_delegate_funcz[]={
{"reverse",array_reverse,1, "a"},
{"sort",array_sort,-1, "ac"},
{"slice",array_slice,-1, "ann"},
{"weakref",obj_delegate_weakref,1, NULL },
{"weakref",obj_delegate_weakref,1, nullptr },
{"tostring",default_delegate_tostring,1, "."},
{"clear",obj_clear,1, "."},
{0,0,0,0}
{nullptr,nullptr,0,nullptr}
};
//STRING DEFAULT DELEGATE//////////////////////////
@@ -687,8 +687,8 @@ SQRegFunction SQSharedState::_string_default_delegate_funcz[]={
{"find",string_find,-2, "s s n "},
{"tolower",string_tolower,1, "s"},
{"toupper",string_toupper,1, "s"},
{"weakref",obj_delegate_weakref,1, NULL },
{0,0,0,0}
{"weakref",obj_delegate_weakref,1, nullptr },
{nullptr,nullptr,0,nullptr}
};
//INTEGER DEFAULT DELEGATE//////////////////////////
@@ -697,8 +697,8 @@ SQRegFunction SQSharedState::_number_default_delegate_funcz[]={
{"tofloat",default_delegate_tofloat,1, "n|b"},
{"tostring",default_delegate_tostring,1, "."},
{"tochar",number_delegate_tochar,1, "n|b"},
{"weakref",obj_delegate_weakref,1, NULL },
{0,0,0,0}
{"weakref",obj_delegate_weakref,1, nullptr },
{nullptr,nullptr,0,nullptr}
};
//CLOSURE DEFAULT DELEGATE//////////////////////////
@@ -782,11 +782,11 @@ SQRegFunction SQSharedState::_closure_default_delegate_funcz[]={
{"pcall",closure_pcall,-1, "c"},
{"acall",closure_acall,2, "ca"},
{"pacall",closure_pacall,2, "ca"},
{"weakref",obj_delegate_weakref,1, NULL },
{"weakref",obj_delegate_weakref,1, nullptr },
{"tostring",default_delegate_tostring,1, "."},
{"bindenv",closure_bindenv,2, "c x|y|t"},
{"getinfos",closure_getinfos,1, "c"},
{0,0,0,0}
{nullptr,nullptr,0,nullptr}
};
//GENERATOR DEFAULT DELEGATE
@@ -803,9 +803,9 @@ static SQInteger generator_getstatus(HSQUIRRELVM v)
SQRegFunction SQSharedState::_generator_default_delegate_funcz[]={
{"getstatus",generator_getstatus,1, "g"},
{"weakref",obj_delegate_weakref,1, NULL },
{"weakref",obj_delegate_weakref,1, nullptr },
{"tostring",default_delegate_tostring,1, "."},
{0,0,0,0}
{nullptr,nullptr,0,nullptr}
};
//THREAD DEFAULT DELEGATE
@@ -889,9 +889,9 @@ SQRegFunction SQSharedState::_thread_default_delegate_funcz[] = {
{"call", thread_call, -1, "v"},
{"wakeup", thread_wakeup, -1, "v"},
{"getstatus", thread_getstatus, 1, "v"},
{"weakref",obj_delegate_weakref,1, NULL },
{"weakref",obj_delegate_weakref,1, nullptr },
{"tostring",default_delegate_tostring,1, "."},
{0,0,0,0},
{nullptr,nullptr,0,nullptr},
};
static SQInteger class_getattributes(HSQUIRRELVM v)
@@ -919,10 +919,10 @@ SQRegFunction SQSharedState::_class_default_delegate_funcz[] = {
{"getattributes", class_getattributes, 2, "y."},
{"setattributes", class_setattributes, 3, "y.."},
{"rawin",container_rawexists,2, "y"},
{"weakref",obj_delegate_weakref,1, NULL },
{"weakref",obj_delegate_weakref,1, nullptr },
{"tostring",default_delegate_tostring,1, "."},
{"instance",class_instance,1, "y"},
{0,0,0,0}
{nullptr,nullptr,0,nullptr}
};
static SQInteger instance_getclass(HSQUIRRELVM v)
@@ -935,9 +935,9 @@ static SQInteger instance_getclass(HSQUIRRELVM v)
SQRegFunction SQSharedState::_instance_default_delegate_funcz[] = {
{"getclass", instance_getclass, 1, "x"},
{"rawin",container_rawexists,2, "x"},
{"weakref",obj_delegate_weakref,1, NULL },
{"weakref",obj_delegate_weakref,1, nullptr },
{"tostring",default_delegate_tostring,1, "."},
{0,0,0,0}
{nullptr,nullptr,0,nullptr}
};
static SQInteger weakref_ref(HSQUIRRELVM v)
@@ -949,9 +949,9 @@ static SQInteger weakref_ref(HSQUIRRELVM v)
SQRegFunction SQSharedState::_weakref_default_delegate_funcz[] = {
{"ref",weakref_ref,1, "r"},
{"weakref",obj_delegate_weakref,1, NULL },
{"weakref",obj_delegate_weakref,1, nullptr },
{"tostring",default_delegate_tostring,1, "."},
{0,0,0,0}
{nullptr,nullptr,0,nullptr}
};

View File

@@ -15,8 +15,8 @@
SQClass::SQClass(SQSharedState *ss,SQClass *base)
{
_base = base;
_typetag = 0;
_hook = NULL;
_typetag = nullptr;
_hook = nullptr;
_udsize = 0;
_metamethods.resize(MT_LAST); //size it to max size
if(_base) {
@@ -34,7 +34,13 @@ SQClass::SQClass(SQSharedState *ss,SQClass *base)
void SQClass::Finalize() {
_attributes = _null_;
_defaultvalues.resize(0);
/* SQInstance's Finalize depends on the size of this sqvector, so instead of
* resizing, all SQObjectPtrs are set to "null" so it holds no references to
* other objects anymore. That way everything gets released properly. */
for (SQUnsignedInteger i = 0; i < _defaultvalues.size(); i++) {
_defaultvalues[i].val = _null_;
_defaultvalues[i].attrs = _null_;
}
_methods.resize(0);
_metamethods.resize(0);
__ObjRelease(_members);
@@ -133,8 +139,8 @@ bool SQClass::GetAttributes(const SQObjectPtr &key,SQObjectPtr &outval)
///////////////////////////////////////////////////////////////////////
void SQInstance::Init(SQSharedState *ss)
{
_userpointer = NULL;
_hook = NULL;
_userpointer = nullptr;
_hook = nullptr;
__ObjAddRef(_class);
_delegate = _class->_members;
INIT_CHAIN();
@@ -190,7 +196,7 @@ bool SQInstance::GetMetaMethod(SQVM *v,SQMetaMethod mm,SQObjectPtr &res)
bool SQInstance::InstanceOf(SQClass *trg)
{
SQClass *parent = _class;
while(parent != NULL) {
while(parent != nullptr) {
if(parent == trg)
return true;
parent = parent->_base;

View File

@@ -45,7 +45,7 @@ struct SQGenerator : public CHAINABLE_OBJ
{
enum SQGeneratorState{eRunning,eSuspended,eDead};
private:
SQGenerator(SQSharedState *ss,SQClosure *closure){_closure=closure;_state=eRunning;_ci._generator=NULL;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);}
SQGenerator(SQSharedState *ss,SQClosure *closure){_closure=closure;_state=eRunning;_ci._generator=nullptr;INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);}
public:
static SQGenerator *Create(SQSharedState *ss,SQClosure *closure){
SQGenerator *nc=(SQGenerator*)SQ_MALLOC(sizeof(SQGenerator));

View File

@@ -57,7 +57,7 @@ typedef sqvector<ExpState> ExpStateVec;
class SQCompiler
{
public:
SQCompiler(SQVM *v, SQLEXREADFUNC rg, SQUserPointer up, const SQChar* sourcename, bool raiseerror, bool lineinfo) : _token(0), _fs(NULL), _lex(_ss(v), rg, up, ThrowError, this), _debugline(0), _debugop(0)
SQCompiler(SQVM *v, SQLEXREADFUNC rg, SQUserPointer up, const SQChar* sourcename, bool raiseerror, bool lineinfo) : _token(0), _fs(nullptr), _lex(_ss(v), rg, up, ThrowError, this), _debugline(0), _debugop(0)
{
_vm=v;
_sourcename = SQString::Create(_ss(v), sourcename);
@@ -164,7 +164,7 @@ public:
_debugline = 1;
_debugop = 0;
SQFuncState funcstate(_ss(_vm), NULL,ThrowError,this);
SQFuncState funcstate(_ss(_vm), nullptr,ThrowError,this);
funcstate._name = SQString::Create(_ss(_vm), "main");
_fs = &funcstate;
_fs->AddParameter(_fs->CreateString("this"));
@@ -835,8 +835,7 @@ public:
nkeys++;
SQInteger val = _fs->PopTarget();
SQInteger key = _fs->PopTarget();
SQInteger attrs = hasattrs ? _fs->PopTarget():-1;
(void)attrs; // assert only
[[maybe_unused]] SQInteger attrs = hasattrs ? _fs->PopTarget():-1;
assert((hasattrs && attrs == key-1) || !hasattrs);
unsigned char flags = (hasattrs?NEW_SLOT_ATTRIBUTES_FLAG:0)|(isstatic?NEW_SLOT_STATIC_FLAG:0);
SQInteger table = _fs->TopTarget(); //<<BECAUSE OF THIS NO COMMON EMIT FUNC IS POSSIBLE

View File

@@ -79,7 +79,7 @@ SQInstructionDesc g_InstrDesc[]={
{"_OP_NEWSLOTA"},
{"_OP_SCOPE_END"}
};
#endif
void DumpLiteral(SQObjectPtr &o)
{
switch(type(o)){
@@ -90,6 +90,7 @@ void DumpLiteral(SQObjectPtr &o)
default: printf("(%s %p)",GetTypeName(o),(void*)_rawval(o));break; break; //shut up compiler
}
}
#endif
SQFuncState::SQFuncState(SQSharedState *ss,SQFuncState *parent,CompilerErrorFunc efunc,void *ed)
{

View File

@@ -87,7 +87,7 @@ SQLexer::SQLexer(SQSharedState *ss, SQLEXREADFUNC rg, SQUserPointer up,CompilerE
_prevtoken = -1;
_curtoken = -1;
_svalue = NULL;
_svalue = nullptr;
_nvalue = 0;
_fvalue = 0;
@@ -119,7 +119,7 @@ const SQChar *SQLexer::Tok2Str(SQInteger tok)
if(((SQInteger)_integer(val)) == tok)
return _stringval(key);
}
return NULL;
return nullptr;
}
void SQLexer::LexBlockComment()

View File

@@ -41,7 +41,7 @@ const SQChar *IdType2Name(SQObjectType type)
case _RT_INSTANCE: return "instance";
case _RT_WEAKREF: return "weakref";
default:
return NULL;
return nullptr;
}
}
@@ -101,13 +101,13 @@ SQRefCounted::~SQRefCounted()
{
if(_weakref) {
_weakref->_obj._type = OT_NULL;
_weakref->_obj._unVal.pRefCounted = NULL;
_weakref->_obj._unVal.pRefCounted = nullptr;
}
}
void SQWeakRef::Release() {
if(ISREFCOUNTED(_obj._type)) {
_obj._unVal.pRefCounted->_weakref = NULL;
_obj._unVal.pRefCounted->_weakref = nullptr;
}
sq_delete(this,SQWeakRef);
}
@@ -149,7 +149,7 @@ bool SQGenerator::Yield(SQVM *v)
for(SQInteger j = nvargs - 1; j >= 0; j--) {
_vargsstack.push_back(v->_vargsstack[vargsbase+j]);
}
_ci._generator=NULL;
_ci._generator=nullptr;
for(SQInteger i=0;i<_ci._etraps;i++) {
_etraps.push_back(v->_etraps.top());
v->_etraps.pop_back();
@@ -204,7 +204,7 @@ void SQArray::Extend(const SQArray *a){
const SQChar* SQFunctionProto::GetLocal(SQVM *vm,SQUnsignedInteger stackbase,SQUnsignedInteger nseq,SQUnsignedInteger nop)
{
SQUnsignedInteger nvars=_nlocalvarinfos;
const SQChar *res=NULL;
const SQChar *res=nullptr;
if(nvars>=nseq){
for(SQUnsignedInteger i=0;i<nvars;i++){
if(_localvarinfos[i]._start_op<=nop && _localvarinfos[i]._end_op>=nop)

View File

@@ -56,7 +56,7 @@ enum SQMetaMethod{
struct SQRefCounted
{
SQRefCounted() { _uiRef = 0; _weakref = NULL; }
SQRefCounted() { _uiRef = 0; _weakref = nullptr; }
virtual ~SQRefCounted();
SQWeakRef *GetWeakRef(SQObjectType type);
SQUnsignedInteger _uiRef;
@@ -134,7 +134,7 @@ struct SQObjectPtr : public SQObject
{
SQ_OBJECT_RAWINIT()
_type=OT_NULL;
_unVal.pUserPointer=NULL;
_unVal.pUserPointer=nullptr;
}
SQObjectPtr(const SQObjectPtr &o)
{
@@ -281,7 +281,7 @@ struct SQObjectPtr : public SQObject
tOldType = _type;
unOldVal = _unVal;
_type = OT_NULL;
_unVal.pUserPointer = NULL;
_unVal.pUserPointer = nullptr;
__Release(tOldType,unOldVal);
}
inline SQObjectPtr& operator=(SQInteger i)

View File

@@ -79,12 +79,12 @@ SQTable *CreateDefaultDelegate(SQSharedState *ss,SQRegFunction *funcz)
{
SQInteger i=0;
SQTable *t=SQTable::Create(ss,0);
while(funcz[i].name!=0){
while(funcz[i].name!=nullptr){
SQNativeClosure *nc = SQNativeClosure::Create(ss,funcz[i].f);
nc->_nparamscheck = funcz[i].nparamscheck;
nc->_name = SQString::Create(ss,funcz[i].name);
if(funcz[i].typemask && !CompileTypemask(nc->_typecheck,funcz[i].typemask))
return NULL;
return nullptr;
t->NewSlot(SQString::Create(ss,funcz[i].name),nc);
i++;
}
@@ -93,15 +93,15 @@ SQTable *CreateDefaultDelegate(SQSharedState *ss,SQRegFunction *funcz)
SQSharedState::SQSharedState()
{
_compilererrorhandler = NULL;
_printfunc = NULL;
_compilererrorhandler = nullptr;
_printfunc = nullptr;
_debuginfo = false;
_notifyallexceptions = false;
_scratchpad=NULL;
_scratchpad=nullptr;
_scratchpadsize=0;
_collectable_free_processing = false;
#ifndef NO_GARBAGE_COLLECTOR
_gc_chain=NULL;
_gc_chain=nullptr;
#endif
sq_new(_stringtable,SQStringTable);
sq_new(_metamethods,SQObjectPtrVec);
@@ -189,7 +189,7 @@ SQSharedState::~SQSharedState()
_refs_table.Finalize();
#ifndef NO_GARBAGE_COLLECTOR
SQCollectable *t = _gc_chain;
SQCollectable *nx = NULL;
SQCollectable *nx = nullptr;
if(t) {
t->_uiRef++;
while(t) {
@@ -299,7 +299,7 @@ SQInteger SQSharedState::CollectGarbage(SQVM *vm)
EnqueueMarkObject(_instance_default_delegate,queue);
EnqueueMarkObject(_weakref_default_delegate,queue);
SQCollectable *tchain=NULL;
SQCollectable *tchain=nullptr;
while (!queue.IsEmpty()) {
SQCollectable *q = queue.Pop();
@@ -309,7 +309,7 @@ SQInteger SQSharedState::CollectGarbage(SQVM *vm)
}
SQCollectable *t = _gc_chain;
SQCollectable *nx = NULL;
SQCollectable *nx = nullptr;
if(t) {
t->_uiRef++;
while(t) {
@@ -340,7 +340,7 @@ SQInteger SQSharedState::CollectGarbage(SQVM *vm)
#ifndef NO_GARBAGE_COLLECTOR
void SQCollectable::AddToChain(SQCollectable **chain,SQCollectable *c)
{
c->_prev = NULL;
c->_prev = nullptr;
c->_next = *chain;
if(*chain) (*chain)->_prev = c;
*chain = c;
@@ -352,8 +352,8 @@ void SQCollectable::RemoveFromChain(SQCollectable **chain,SQCollectable *c)
else *chain = c->_next;
if(c->_next)
c->_next->_prev = c->_prev;
c->_next = NULL;
c->_prev = NULL;
c->_next = nullptr;
c->_prev = nullptr;
}
#endif
@@ -483,16 +483,16 @@ RefTable::RefNode *RefTable::Get(SQObject &obj,SQHash &mainpos,RefNode **prev,bo
{
RefNode *ref;
mainpos = ::HashObj(obj)&(_numofslots-1);
*prev = NULL;
*prev = nullptr;
for (ref = _buckets[mainpos]; ref; ) {
if(_rawval(ref->obj) == _rawval(obj) && type(ref->obj) == type(obj))
break;
*prev = ref;
ref = ref->next;
}
if(ref == NULL && add) {
if(ref == nullptr && add) {
if(_numofslots == _slotused) {
assert(_freelist == 0);
assert(_freelist == nullptr);
Resize(_numofslots*2);
mainpos = ::HashObj(obj)&(_numofslots-1);
}
@@ -510,16 +510,16 @@ void RefTable::AllocNodes(SQUnsignedInteger size)
RefNode *temp = nodes;
SQUnsignedInteger n;
for(n = 0; n < size - 1; n++) {
bucks[n] = NULL;
bucks[n] = nullptr;
temp->refs = 0;
new (&temp->obj) SQObjectPtr;
temp->next = temp+1;
temp++;
}
bucks[n] = NULL;
bucks[n] = nullptr;
temp->refs = 0;
new (&temp->obj) SQObjectPtr;
temp->next = NULL;
temp->next = nullptr;
_freelist = nodes;
_nodes = nodes;
_buckets = bucks;
@@ -543,7 +543,7 @@ SQStringTable::SQStringTable()
SQStringTable::~SQStringTable()
{
SQ_FREE(_strings,sizeof(SQString*)*_numofslots);
_strings = NULL;
_strings = nullptr;
}
void SQStringTable::AllocNodes(SQInteger size)
@@ -580,8 +580,8 @@ SQString::SQString(const SQChar *news, SQInteger len)
_val[len] = '\0';
_len = len;
_hash = ::_hashstr(news,(size_t)len);
_next = NULL;
_sharedstate = NULL;
_next = nullptr;
_sharedstate = nullptr;
}
void SQStringTable::Resize(SQInteger size)
@@ -605,7 +605,7 @@ void SQStringTable::Resize(SQInteger size)
void SQStringTable::Remove(SQString *bs)
{
SQString *s;
SQString *prev=NULL;
SQString *prev=nullptr;
SQHash h = bs->_hash&(_numofslots - 1);
for (s = _strings[h]; s; ){

View File

@@ -18,7 +18,7 @@ SQTable::SQTable(SQSharedState *ss,SQInteger nInitialSize)
while(nInitialSize>pow2size)pow2size=pow2size<<1;
AllocNodes(pow2size);
_usednodes = 0;
_delegate = NULL;
_delegate = nullptr;
INIT_CHAIN();
ADD_TO_CHAIN(&_sharedstate->_gc_chain,this);
}
@@ -39,7 +39,7 @@ void SQTable::AllocNodes(SQInteger nSize)
_HashNode *nodes=(_HashNode *)SQ_MALLOC(sizeof(_HashNode)*nSize);
for(SQInteger i=0;i<nSize;i++){
new (&nodes[i]) _HashNode;
nodes[i].next=NULL;
nodes[i].next=nullptr;
}
_numofnodes=nSize;
_nodes=nodes;
@@ -120,7 +120,7 @@ bool SQTable::NewSlot(const SQObjectPtr &key,const SQObjectPtr &val)
if (mp > n && (othern = &_nodes[mph]) != mp){
/* yes; move colliding node into free position */
while (othern->next != mp){
assert(othern->next != NULL);
assert(othern->next != nullptr);
othern = othern->next; /* find previous */
}
othern->next = n; /* redo the chain with `n' in place of `mp' */
@@ -129,7 +129,7 @@ bool SQTable::NewSlot(const SQObjectPtr &key,const SQObjectPtr &val)
n->next = mp->next;
mp->key = _null_;
mp->val = _null_;
mp->next = NULL; /* now `mp' is free */
mp->next = nullptr; /* now `mp' is free */
}
else{
/* new node will go into free position */
@@ -141,7 +141,7 @@ bool SQTable::NewSlot(const SQObjectPtr &key,const SQObjectPtr &val)
mp->key = key;
for (;;) { /* correct `firstfree' */
if (type(_firstfree->key) == OT_NULL && _firstfree->next == NULL) {
if (type(_firstfree->key) == OT_NULL && _firstfree->next == nullptr) {
mp->val = val;
_usednodes++;
return true; /* OK; table still has a free place */
@@ -190,7 +190,7 @@ void SQTable::_ClearNodes()
void SQTable::Finalize()
{
_ClearNodes();
SetDelegate(NULL);
SetDelegate(nullptr);
}
void SQTable::Clear()

View File

@@ -27,7 +27,7 @@ struct SQTable : public SQDelegable
private:
struct _HashNode
{
_HashNode() { next = NULL; }
_HashNode() { next = nullptr; }
SQObjectPtr val;
SQObjectPtr key;
_HashNode *next;
@@ -47,14 +47,14 @@ public:
{
SQTable *newtable = (SQTable*)SQ_MALLOC(sizeof(SQTable));
new (newtable) SQTable(ss, nInitialSize);
newtable->_delegate = NULL;
newtable->_delegate = nullptr;
return newtable;
}
void Finalize() override;
SQTable *Clone();
~SQTable()
{
SetDelegate(NULL);
SetDelegate(nullptr);
REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);
for (SQInteger i = 0; i < _numofnodes; i++) _nodes[i].~_HashNode();
SQ_FREE(_nodes, _numofnodes * sizeof(_HashNode));
@@ -70,7 +70,7 @@ public:
return n;
}
}while((n = n->next));
return NULL;
return nullptr;
}
bool Get(const SQObjectPtr &key,SQObjectPtr &val);
void Remove(const SQObjectPtr &key);

View File

@@ -4,12 +4,12 @@
struct SQUserData : SQDelegable
{
SQUserData(SQSharedState *ss, SQInteger size){ _delegate = 0; _hook = NULL; INIT_CHAIN(); ADD_TO_CHAIN(&_ss(this)->_gc_chain, this); _size = size; _typetag = 0;
SQUserData(SQSharedState *ss, SQInteger size){ _delegate = nullptr; _hook = nullptr; INIT_CHAIN(); ADD_TO_CHAIN(&_ss(this)->_gc_chain, this); _size = size; _typetag = nullptr;
}
~SQUserData()
{
REMOVE_FROM_CHAIN(&_ss(this)->_gc_chain, this);
SetDelegate(NULL);
SetDelegate(nullptr);
}
static SQUserData* Create(SQSharedState *ss, SQInteger size)
{
@@ -19,7 +19,7 @@ struct SQUserData : SQDelegable
}
#ifndef NO_GARBAGE_COLLECTOR
void EnqueueMarkObjectForChildren(SQGCMarkerQueue &queue);
void Finalize(){SetDelegate(NULL);}
void Finalize(){SetDelegate(nullptr);}
#endif
void Release() {
if (_hook) _hook(_val,_size);

View File

@@ -18,7 +18,7 @@ template<typename T> class sqvector
public:
sqvector()
{
_vals = NULL;
_vals = nullptr;
_size = 0;
_allocated = 0;
}

View File

@@ -33,7 +33,7 @@ void SQVM::ClearStack(SQInteger last_top)
tOldType = o._type;
unOldVal = o._unVal;
o._type = OT_NULL;
o._unVal.pUserPointer = NULL;
o._unVal.pUserPointer = nullptr;
__Release(tOldType,unOldVal);
}
}
@@ -107,7 +107,7 @@ SQVM::SQVM(SQSharedState *ss)
_suspended_target=-1;
_suspended_root = SQFalse;
_suspended_traps=0;
_foreignptr=NULL;
_foreignptr=nullptr;
_nnativecalls=0;
_lasterror = _null_;
_errorhandler = _null_;
@@ -115,12 +115,12 @@ SQVM::SQVM(SQSharedState *ss)
_can_suspend = false;
_in_stackoverflow = false;
_ops_till_suspend = 0;
_callsstack = NULL;
_callsstack = nullptr;
_callsstacksize = 0;
_alloccallsstacksize = 0;
_top = 0;
_stackbase = 0;
ci = NULL;
ci = nullptr;
INIT_CHAIN();ADD_TO_CHAIN(&_ss(this)->_gc_chain,this);
}
@@ -379,7 +379,7 @@ bool SQVM::StartCall(SQClosure *closure,SQInteger target,SQInteger args,SQIntege
if (!tailcall) {
CallInfo lc = {};
lc._generator = NULL;
lc._generator = nullptr;
lc._etraps = 0;
lc._prevstkbase = (SQInt32) ( stackbase - _stackbase );
lc._target = (SQInt32) target;
@@ -437,7 +437,7 @@ bool SQVM::Return(SQInteger _arg0, SQInteger _arg1, SQObjectPtr &retval)
while (last_top > oldstackbase) _stack._vals[last_top--].Null();
assert(oldstackbase >= _stackbase);
return broot?true:false;
return broot != 0;
}
#define _RET_ON_FAIL(exp) { if(!exp) return false; }
@@ -557,7 +557,7 @@ bool SQVM::DELEGATE_OP(SQObjectPtr &trg,SQObjectPtr &o1,SQObjectPtr &o2)
}
break;
case OT_NULL:
_table(o1)->SetDelegate(NULL);
_table(o1)->SetDelegate(nullptr);
break;
default:
Raise_Error("using '%s' as delegate", GetTypeName(o2));
@@ -627,7 +627,7 @@ bool SQVM::GETVARGV_OP(SQObjectPtr &target,SQObjectPtr &index,CallInfo *ci)
bool SQVM::CLASS_OP(SQObjectPtr &target,SQInteger baseclass,SQInteger attributes)
{
SQClass *base = NULL;
SQClass *base = nullptr;
SQObjectPtr attrs;
if(baseclass != -1) {
if(type(_stack._vals[_stackbase+baseclass]) != OT_CLASS) { Raise_Error("trying to inherit from a %s",GetTypeName(_stack._vals[_stackbase+baseclass])); return false; }
@@ -653,7 +653,7 @@ bool SQVM::CLASS_OP(SQObjectPtr &target,SQInteger baseclass,SQInteger attributes
bool SQVM::IsEqual(SQObjectPtr &o1,SQObjectPtr &o2,bool &res)
{
if(type(o1) == type(o2)) {
res = ((_rawval(o1) == _rawval(o2)?true:false));
res = ((_rawval(o1) == _rawval(o2)));
}
else {
if(sq_isnumeric(o1) && sq_isnumeric(o2)) {
@@ -708,7 +708,7 @@ bool SQVM::Execute(SQObjectPtr &closure, SQInteger target, SQInteger nargs, SQIn
temp_reg = closure;
if(!StartCall(_closure(temp_reg), _top - nargs, nargs, stackbase, false)) {
//call the handler if there are no calls in the stack, if not relies on the previous node
if(ci == NULL) CallErrorHandler(_lasterror);
if(ci == nullptr) CallErrorHandler(_lasterror);
return false;
}
if (_funcproto(_closure(temp_reg)->_function)->_bgenerator) {
@@ -1028,7 +1028,7 @@ common_call:
case _OP_THROW: Raise_Error(TARGET); SQ_THROW();
case _OP_CLASS: _GUARD(CLASS_OP(TARGET,arg1,arg2)); continue;
case _OP_NEWSLOTA:
bool bstatic = (arg0&NEW_SLOT_STATIC_FLAG)?true:false;
bool bstatic = (arg0&NEW_SLOT_STATIC_FLAG) != 0;
if(type(STK(arg1)) == OT_CLASS) {
if(type(_class(STK(arg1))->_metamethods[MT_NEWMEMBER]) != OT_NULL ) {
Push(STK(arg1)); Push(STK(arg2)); Push(STK(arg3));
@@ -1160,7 +1160,7 @@ bool SQVM::CallNative(SQNativeClosure *nclosure,SQInteger nargs,SQInteger stackb
_top = stackbase + nargs;
CallInfo lci = {};
lci._closure = nclosure;
lci._generator = NULL;
lci._generator = nullptr;
lci._etraps = 0;
lci._prevstkbase = (SQInt32) (stackbase - _stackbase);
lci._ncalls = 1;
@@ -1471,9 +1471,7 @@ bool SQVM::DeleteSlot(const SQObjectPtr &self,const SQObjectPtr &key,SQObjectPtr
bool SQVM::Call(SQObjectPtr &closure,SQInteger nparams,SQInteger stackbase,SQObjectPtr &outres,SQBool raiseerror,SQBool can_suspend)
{
#ifdef WITH_ASSERT
SQInteger prevstackbase = _stackbase;
#endif
[[maybe_unused]] SQInteger prevstackbase = _stackbase;
switch(type(closure)) {
case OT_CLOSURE: {
assert(!can_suspend || this->_can_suspend);
@@ -1504,11 +1502,9 @@ bool SQVM::Call(SQObjectPtr &closure,SQInteger nparams,SQInteger stackbase,SQObj
default:
return false;
}
#ifdef WITH_ASSERT
if(!_suspended) {
assert(_stackbase == prevstackbase);
}
#endif
return true;
}

View File

@@ -310,6 +310,8 @@ add_files(
rail_gui.h
rail_map.h
rail_type.h
random_access_file.cpp
random_access_file_type.h
rev.h
road.cpp
road.h
@@ -337,6 +339,8 @@ add_files(
settings_gui.cpp
settings_gui.h
settings_internal.h
settings_table.h
settings_table.cpp
settings_type.h
ship.h
ship_cmd.cpp
@@ -466,6 +470,7 @@ add_files(
viewport_type.h
void_cmd.cpp
void_map.h
walltime_func.h
water.h
water_cmd.cpp
water_map.h

View File

@@ -114,7 +114,7 @@
cur_company.Restore();
InvalidateWindowData(WC_AI_DEBUG, 0, -1);
DeleteWindowById(WC_AI_SETTINGS, company);
CloseWindowById(WC_AI_SETTINGS, company);
}
/* static */ void AI::Pause(CompanyID company)
@@ -207,7 +207,7 @@
for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) {
if (_settings_game.ai_config[c] != nullptr && _settings_game.ai_config[c]->HasScript()) {
if (!_settings_game.ai_config[c]->ResetInfo(true)) {
DEBUG(script, 0, "After a reload, the AI by the name '%s' was no longer found, and removed from the list.", _settings_game.ai_config[c]->GetName());
Debug(script, 0, "After a reload, the AI by the name '{}' was no longer found, and removed from the list.", _settings_game.ai_config[c]->GetName());
_settings_game.ai_config[c]->Change(nullptr);
if (Company::IsValidAiID(c)) {
/* The code belonging to an already running AI was deleted. We can only do
@@ -224,7 +224,7 @@
}
if (_settings_newgame.ai_config[c] != nullptr && _settings_newgame.ai_config[c]->HasScript()) {
if (!_settings_newgame.ai_config[c]->ResetInfo(false)) {
DEBUG(script, 0, "After a reload, the AI by the name '%s' was no longer found, and removed from the list.", _settings_newgame.ai_config[c]->GetName());
Debug(script, 0, "After a reload, the AI by the name '{}' was no longer found, and removed from the list.", _settings_newgame.ai_config[c]->GetName());
_settings_newgame.ai_config[c]->Change(nullptr);
}
}

View File

@@ -182,7 +182,7 @@ struct AIListWindow : public Window {
}
InvalidateWindowData(WC_GAME_OPTIONS, WN_GAME_OPTIONS_AI);
InvalidateWindowClassesData(WC_AI_SETTINGS);
DeleteWindowByClass(WC_QUERY_STRING);
CloseWindowByClass(WC_QUERY_STRING);
InvalidateWindowClassesData(WC_TEXTFILE);
}
@@ -190,13 +190,13 @@ struct AIListWindow : public Window {
{
switch (widget) {
case WID_AIL_LIST: { // Select one of the AIs
int sel = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_AIL_LIST, 0, this->line_height) - 1;
int sel = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_AIL_LIST) - 1;
if (sel < (int)this->info_list->size()) {
this->selected = sel;
this->SetDirty();
if (click_count > 1) {
this->ChangeAI();
delete this;
this->Close();
}
}
break;
@@ -204,12 +204,12 @@ struct AIListWindow : public Window {
case WID_AIL_ACCEPT: {
this->ChangeAI();
delete this;
this->Close();
break;
}
case WID_AIL_CANCEL:
delete this;
this->Close();
break;
}
}
@@ -227,7 +227,7 @@ struct AIListWindow : public Window {
void OnInvalidateData(int data = 0, bool gui_scope = true) override
{
if (_game_mode == GM_NORMAL && Company::IsValidID(this->slot)) {
delete this;
this->Close();
return;
}
@@ -276,7 +276,7 @@ static WindowDesc _ai_list_desc(
*/
static void ShowAIListWindow(CompanyID slot)
{
DeleteWindowByClass(WC_AI_LIST);
CloseWindowByClass(WC_AI_LIST);
new AIListWindow(&_ai_list_desc, slot);
}
@@ -444,7 +444,7 @@ struct AISettingsWindow : public Window {
if (!this->IsEditableItem(config_item)) return;
if (this->clicked_row != num) {
DeleteChildWindows(WC_QUERY_STRING);
this->CloseChildWindows(WC_QUERY_STRING);
HideDropDownMenu(this);
this->clicked_row = num;
this->clicked_dropdown = false;
@@ -518,7 +518,7 @@ struct AISettingsWindow : public Window {
}
case WID_AIS_ACCEPT:
delete this;
this->Close();
break;
case WID_AIS_RESET:
@@ -584,7 +584,7 @@ struct AISettingsWindow : public Window {
{
this->RebuildVisibleSettings();
HideDropDownMenu(this);
DeleteChildWindows(WC_QUERY_STRING);
this->CloseChildWindows(WC_QUERY_STRING);
}
private:
@@ -628,8 +628,8 @@ static WindowDesc _ai_settings_desc(
*/
static void ShowAISettingsWindow(CompanyID slot)
{
DeleteWindowByClass(WC_AI_LIST);
DeleteWindowByClass(WC_AI_SETTINGS);
CloseWindowByClass(WC_AI_LIST);
CloseWindowByClass(WC_AI_SETTINGS);
new AISettingsWindow(&_ai_settings_desc, slot);
}
@@ -655,7 +655,7 @@ struct ScriptTextfileWindow : public TextfileWindow {
{
const char *textfile = GetConfig(slot)->GetTextfile(file_type, slot);
if (textfile == nullptr) {
delete this;
this->Close();
} else {
this->LoadTextfile(textfile, (slot == OWNER_DEITY) ? GAME_DIR : AI_DIR);
}
@@ -669,7 +669,7 @@ struct ScriptTextfileWindow : public TextfileWindow {
*/
void ShowScriptTextfileWindow(TextfileType file_type, CompanyID slot)
{
DeleteWindowById(WC_TEXTFILE, file_type);
CloseWindowById(WC_TEXTFILE, file_type);
new ScriptTextfileWindow(file_type, slot);
}
@@ -744,10 +744,11 @@ struct AIConfigWindow : public Window {
this->OnInvalidateData(0);
}
~AIConfigWindow()
void Close() override
{
DeleteWindowByClass(WC_AI_LIST);
DeleteWindowByClass(WC_AI_SETTINGS);
CloseWindowByClass(WC_AI_LIST);
CloseWindowByClass(WC_AI_SETTINGS);
this->Window::Close();
}
void SetStringParameters(int widget) const override
@@ -784,6 +785,7 @@ struct AIConfigWindow : public Window {
case WID_AIC_LIST:
this->line_height = FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM;
resize->height = this->line_height;
size->height = 8 * this->line_height;
break;
@@ -895,7 +897,7 @@ struct AIConfigWindow : public Window {
}
case WID_AIC_LIST: { // Select a slot
this->selected_slot = (CompanyID)this->vscroll->GetScrolledRowFromWidget(pt.y, this, widget, 0, this->line_height);
this->selected_slot = (CompanyID)this->vscroll->GetScrolledRowFromWidget(pt.y, this, widget);
this->InvalidateData();
if (click_count > 1 && this->selected_slot != INVALID_COMPANY) ShowAIListWindow((CompanyID)this->selected_slot);
break;
@@ -928,7 +930,7 @@ struct AIConfigWindow : public Window {
break;
case WID_AIC_CLOSE:
delete this;
this->Close();
break;
case WID_AIC_CONTENT_DOWNLOAD:
@@ -970,7 +972,7 @@ struct AIConfigWindow : public Window {
/** Open the AI config window. */
void ShowAIConfigWindow()
{
DeleteWindowByClass(WC_GAME_OPTIONS);
CloseWindowByClass(WC_GAME_OPTIONS);
new AIConfigWindow();
}
@@ -1262,7 +1264,7 @@ struct AIDebugWindow : public Window {
this->highlight_row = -1; // The highlight of one AI make little sense for another AI.
/* Close AI settings window to prevent confusion */
DeleteWindowByClass(WC_AI_SETTINGS);
CloseWindowByClass(WC_AI_SETTINGS);
this->InvalidateData(-1);

View File

@@ -25,7 +25,7 @@
*/
static bool CheckAPIVersion(const char *api_version)
{
static const std::set<std::string> versions = { "0.7", "1.0", "1.1", "1.2", "1.3", "1.4", "1.5", "1.6", "1.7", "1.8", "1.9", "1.10", "1.11" };
static const std::set<std::string> versions = { "0.7", "1.0", "1.1", "1.2", "1.3", "1.4", "1.5", "1.6", "1.7", "1.8", "1.9", "1.10", "1.11", "12" };
return versions.find(api_version) != versions.end();
}
@@ -63,7 +63,7 @@ template <> const char *GetClassName<AIInfo, ST_AI>() { return "AIInfo"; }
{
/* Get the AIInfo */
SQUserPointer instance = nullptr;
if (SQ_FAILED(sq_getinstanceup(vm, 2, &instance, 0)) || instance == nullptr) return sq_throwerror(vm, "Pass an instance of a child class of AIInfo to RegisterAI");
if (SQ_FAILED(sq_getinstanceup(vm, 2, &instance, nullptr)) || instance == nullptr) return sq_throwerror(vm, "Pass an instance of a child class of AIInfo to RegisterAI");
AIInfo *info = (AIInfo *)instance;
SQInteger res = ScriptInfo::Constructor(vm, info);
@@ -89,7 +89,7 @@ template <> const char *GetClassName<AIInfo, ST_AI>() { return "AIInfo"; }
if (info->engine->MethodExists(*info->SQ_instance, "GetAPIVersion")) {
if (!info->engine->CallStringMethodStrdup(*info->SQ_instance, "GetAPIVersion", &info->api_version, MAX_GET_OPS)) return SQ_ERROR;
if (!CheckAPIVersion(info->api_version)) {
DEBUG(script, 1, "Loading info.nut from (%s.%d): GetAPIVersion returned invalid version", info->GetName(), info->GetVersion());
Debug(script, 1, "Loading info.nut from ({}.{}): GetAPIVersion returned invalid version", info->GetName(), info->GetVersion());
return SQ_ERROR;
}
} else {
@@ -107,7 +107,7 @@ template <> const char *GetClassName<AIInfo, ST_AI>() { return "AIInfo"; }
{
/* Get the AIInfo */
SQUserPointer instance;
sq_getinstanceup(vm, 2, &instance, 0);
sq_getinstanceup(vm, 2, &instance, nullptr);
AIInfo *info = (AIInfo *)instance;
info->api_version = nullptr;

View File

@@ -66,7 +66,7 @@ AIInfo *AIScannerInfo::SelectRandomAI() const
}
if (num_random_ais == 0) {
DEBUG(script, 0, "No suitable AI found, loading 'dummy' AI.");
Debug(script, 0, "No suitable AI found, loading 'dummy' AI.");
return this->info_dummy;
}

View File

@@ -1025,7 +1025,7 @@ static bool AircraftController(Aircraft *v)
if (count == 0) return false;
/* If the plane will be a few subpixels away from the destination after
* this movement loop, start nudging him towards the exact position for
* this movement loop, start nudging it towards the exact position for
* the whole loop. Otherwise, heavily depending on the speed of the plane,
* it is possible we totally overshoot the target, causing the plane to
* make a loop, and trying again, and again, and again .. */
@@ -1786,7 +1786,7 @@ static bool AirportMove(Aircraft *v, const AirportFTAClass *apc)
{
/* error handling */
if (v->pos >= apc->nofelements) {
DEBUG(misc, 0, "[Ap] position %d is not valid for current airport. Max position is %d", v->pos, apc->nofelements-1);
Debug(misc, 0, "[Ap] position {} is not valid for current airport. Max position is {}", v->pos, apc->nofelements-1);
assert(v->pos < apc->nofelements);
}
@@ -1825,7 +1825,7 @@ static bool AirportMove(Aircraft *v, const AirportFTAClass *apc)
current = current->next;
} while (current != nullptr);
DEBUG(misc, 0, "[Ap] cannot move further on Airport! (pos %d state %d) for vehicle %d", v->pos, v->state, v->index);
Debug(misc, 0, "[Ap] cannot move further on Airport! (pos {} state {}) for vehicle {}", v->pos, v->state, v->index);
NOT_REACHED();
}

View File

@@ -84,10 +84,11 @@ struct BuildAirToolbarWindow : Window {
this->last_user_action = WIDGET_LIST_END;
}
~BuildAirToolbarWindow()
void Close() override
{
if (this->IsWidgetLowered(WID_AT_AIRPORT)) SetViewportCatchmentStation(nullptr, true);
if (_settings_client.gui.link_terraform_toolbar) DeleteWindowById(WC_SCEN_LAND_GEN, 0, false);
if (_settings_client.gui.link_terraform_toolbar) CloseWindowById(WC_SCEN_LAND_GEN, 0, false);
this->Window::Close();
}
/**
@@ -104,7 +105,7 @@ struct BuildAirToolbarWindow : Window {
WID_AT_AIRPORT,
WIDGET_LIST_END);
if (!can_build) {
DeleteWindowById(WC_BUILD_STATION, TRANSPORT_AIR);
CloseWindowById(WC_BUILD_STATION, TRANSPORT_AIR);
/* Show in the tooltip why this button is disabled. */
this->GetWidget<NWidgetCore>(WID_AT_AIRPORT)->SetToolTip(STR_TOOLBAR_DISABLED_NO_VEHICLE_AVAILABLE);
@@ -166,8 +167,8 @@ struct BuildAirToolbarWindow : Window {
this->RaiseButtons();
DeleteWindowById(WC_BUILD_STATION, TRANSPORT_AIR);
DeleteWindowById(WC_SELECT_STATION, 0);
CloseWindowById(WC_BUILD_STATION, TRANSPORT_AIR);
CloseWindowById(WC_SELECT_STATION, 0);
citymania::AbortStationPlacement();
}
@@ -227,7 +228,7 @@ Window *ShowBuildAirToolbar()
{
if (!Company::IsValidID(_local_company)) return nullptr;
DeleteWindowByClass(WC_BUILD_TOOLBAR);
CloseWindowByClass(WC_BUILD_TOOLBAR);
return AllocateWindowDescFront<BuildAirToolbarWindow>(&_air_toolbar_desc, TRANSPORT_AIR);
}
@@ -286,9 +287,10 @@ public:
if (selectFirstAirport) this->SelectFirstAvailableAirport(true);
}
virtual ~BuildAirportWindow()
void Close() override
{
DeleteWindowById(WC_SELECT_STATION, 0);
CloseWindowById(WC_SELECT_STATION, 0);
this->PickerWindowBase::Close();
}
void SetStringParameters(int widget) const override
@@ -495,7 +497,7 @@ public:
break;
case WID_AP_AIRPORT_LIST: {
int num_clicked = this->vscroll->GetPosition() + (pt.y - this->nested_array[widget]->pos_y) / this->line_height;
int num_clicked = this->vscroll->GetPosition() + (pt.y - this->GetWidget<NWidgetBase>(widget)->pos_y) / this->line_height;
if (num_clicked >= this->vscroll->GetCount()) break;
const AirportSpec *as = AirportClass::Get(_selected_airport_class)->GetSpec(num_clicked);
if (as->IsAvailable()) this->SelectOtherAirport(num_clicked);

View File

@@ -11,6 +11,7 @@
#include "command_func.h"
#include "group.h"
#include "autoreplace_base.h"
#include "core/bitmath_func.hpp"
#include "core/pool_func.hpp"
#include "safeguards.h"
@@ -64,7 +65,7 @@ void RemoveAllEngineReplacement(EngineRenewList *erl)
EngineID EngineReplacement(EngineRenewList erl, EngineID engine, GroupID group, bool *replace_when_old)
{
const EngineRenew *er = GetEngineReplacement(erl, engine, group);
if (er == nullptr && (group == DEFAULT_GROUP || (Group::IsValidID(group) && !Group::Get(group)->replace_protection))) {
if (er == nullptr && (group == DEFAULT_GROUP || (Group::IsValidID(group) && !HasBit(Group::Get(group)->flags, GroupFlags::GF_REPLACE_PROTECTION)))) {
/* We didn't find anything useful in the vehicle's own group so we will try ALL_GROUP */
er = GetEngineReplacement(erl, engine, ALL_GROUP);
}

View File

@@ -207,6 +207,7 @@ static int GetIncompatibleRefitOrderIdForAutoreplace(const Vehicle *v, EngineID
const Vehicle *u = (v->type == VEH_TRAIN) ? v->First() : v;
const OrderList *orders = u->orders.list;
if (orders == nullptr) return -1;
for (VehicleOrderID i = 0; i < orders->GetNumOrders(); i++) {
o = orders->GetOrderAt(i);
if (!o->IsRefit()) continue;
@@ -596,8 +597,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
assert(RailVehInfo(wagon->engine_type)->railveh_type == RAILVEH_WAGON);
/* Sell wagon */
CommandCost ret = DoCommand(0, wagon->index, 0, DC_EXEC, GetCmdSellVeh(wagon));
(void)ret; // assert only
[[maybe_unused]] CommandCost ret = DoCommand(0, wagon->index, 0, DC_EXEC, GetCmdSellVeh(wagon));
assert(ret.Succeeded());
new_vehs[i] = nullptr;
@@ -614,6 +614,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
/* Success ! */
if ((flags & DC_EXEC) != 0 && new_head != old_head) {
*chain = new_head;
AI::NewEvent(old_head->owner, new ScriptEventVehicleAutoReplaced(old_head->index, new_head->index));
}
/* Transfer cargo of old vehicles and sell them */
@@ -631,10 +632,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
cost.AddCost(DoCommand(0, w->index, 0, flags | DC_AUTOREPLACE, GetCmdSellVeh(w)));
if ((flags & DC_EXEC) != 0) {
old_vehs[i] = nullptr;
if (i == 0) {
AI::NewEvent(old_head->owner, new ScriptEventVehicleAutoReplaced(old_head->index, new_head->index));
old_head = nullptr;
}
if (i == 0) old_head = nullptr;
}
}
@@ -652,8 +650,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
assert(Train::From(old_head)->GetNextUnit() == nullptr);
for (int i = num_units - 1; i > 0; i--) {
CommandCost ret = CmdMoveVehicle(old_vehs[i], old_head, DC_EXEC | DC_AUTOREPLACE, false);
(void)ret; // assert only
[[maybe_unused]] CommandCost ret = CmdMoveVehicle(old_vehs[i], old_head, DC_EXEC | DC_AUTOREPLACE, false);
assert(ret.Succeeded());
}
}
@@ -717,7 +714,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
* @param text unused
* @return the cost of this operation or an error
*/
CommandCost CmdAutoreplaceVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
CommandCost CmdAutoreplaceVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text)
{
Vehicle *v = Vehicle::GetIfValid(p1);
if (v == nullptr) return CMD_ERROR;
@@ -741,6 +738,9 @@ CommandCost CmdAutoreplaceVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1
const Company *c = Company::Get(_current_company);
bool wagon_removal = c->settings.renew_keep_length;
const Group *g = Group::GetIfValid(v->group_id);
if (g != nullptr) wagon_removal = HasBit(g->flags, GroupFlags::GF_REPLACE_WAGON_REMOVAL);
/* Test whether any replacement is set, before issuing a whole lot of commands that would end in nothing changed */
Vehicle *w = v;
bool any_replacements = false;
@@ -807,7 +807,7 @@ CommandCost CmdAutoreplaceVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1
* @param text unused
* @return the cost of this operation or an error
*/
CommandCost CmdSetAutoReplace(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
CommandCost CmdSetAutoReplace(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text)
{
Company *c = Company::GetIfValid(_current_company);
if (c == nullptr) return CMD_ERROR;

View File

@@ -375,8 +375,18 @@ public:
break;
case WID_RV_TRAIN_WAGONREMOVE_TOGGLE: {
const Company *c = Company::Get(_local_company);
SetDParam(0, c->settings.renew_keep_length ? STR_CONFIG_SETTING_ON : STR_CONFIG_SETTING_OFF);
bool remove_wagon;
const Group *g = Group::GetIfValid(this->sel_group);
if (g != nullptr) {
remove_wagon = HasBit(g->flags, GroupFlags::GF_REPLACE_WAGON_REMOVAL);
SetDParam(0, STR_GROUP_NAME);
SetDParam(1, sel_group);
} else {
const Company *c = Company::Get(_local_company);
remove_wagon = c->settings.renew_keep_length;
SetDParam(0, STR_GROUP_DEFAULT_TRAINS + this->window_number);
}
SetDParam(2, remove_wagon ? STR_CONFIG_SETTING_ON : STR_CONFIG_SETTING_OFF);
break;
}
@@ -528,9 +538,16 @@ public:
}
break;
case WID_RV_TRAIN_WAGONREMOVE_TOGGLE: // toggle renew_keep_length
DoCommandP(0, GetCompanySettingIndex("company.renew_keep_length"), Company::Get(_local_company)->settings.renew_keep_length ? 0 : 1, CMD_CHANGE_COMPANY_SETTING);
case WID_RV_TRAIN_WAGONREMOVE_TOGGLE: {
const Group *g = Group::GetIfValid(this->sel_group);
if (g != nullptr) {
DoCommandP(0, this->sel_group | (GroupFlags::GF_REPLACE_WAGON_REMOVAL << 16), (HasBit(g->flags, GroupFlags::GF_REPLACE_WAGON_REMOVAL) ? 0 : 1) | (_ctrl_pressed << 1), CMD_SET_GROUP_FLAG);
} else {
// toggle renew_keep_length
DoCommandP(0, 0, Company::Get(_local_company)->settings.renew_keep_length ? 0 : 1, CMD_CHANGE_COMPANY_SETTING, nullptr, "company.renew_keep_length");
}
break;
}
case WID_RV_START_REPLACE: { // Start replacing
if (this->GetWidget<NWidgetLeaf>(widget)->ButtonHit(pt)) {
@@ -628,6 +645,20 @@ public:
}
}
bool OnTooltip(Point pt, int widget, TooltipCloseCondition close_cond) override
{
if (widget != WID_RV_TRAIN_WAGONREMOVE_TOGGLE) return false;
if (Group::IsValidID(this->sel_group)) {
uint64 params[1];
params[0] = STR_REPLACE_REMOVE_WAGON_HELP;
GuiShowTooltips(this, STR_REPLACE_REMOVE_WAGON_GROUP_HELP, 1, params, close_cond);
} else {
GuiShowTooltips(this, STR_REPLACE_REMOVE_WAGON_HELP, 0, nullptr, close_cond);
}
return true;
}
void OnResize() override
{
this->vscroll[0]->SetCapacityFromWidget(this, WID_RV_LEFT_MATRIX);
@@ -833,7 +864,7 @@ static WindowDesc _replace_vehicle_desc(
*/
void ShowReplaceGroupVehicleWindow(GroupID id_g, VehicleType vehicletype)
{
DeleteWindowById(WC_REPLACE_VEHICLE, vehicletype);
CloseWindowById(WC_REPLACE_VEHICLE, vehicletype);
WindowDesc *desc;
switch (vehicletype) {
case VEH_TRAIN: desc = &_replace_rail_vehicle_desc; break;

View File

@@ -22,8 +22,8 @@
#define fetch_metadata(name) \
item = metadata->GetItem(name, false); \
if (item == nullptr || !item->value.has_value() || item->value->empty()) { \
DEBUG(grf, 0, "Base " SET_TYPE "set detail loading: %s field missing.", name); \
DEBUG(grf, 0, " Is %s readable for the user running OpenTTD?", full_filename); \
Debug(grf, 0, "Base " SET_TYPE "set detail loading: {} field missing.", name); \
Debug(grf, 0, " Is {} readable for the user running OpenTTD?", full_filename); \
return false; \
}
@@ -74,7 +74,7 @@ bool BaseSet<T, Tnum_files, Tsearch_in_tars>::FillSetDetails(IniFile *ini, const
/* Find the filename first. */
item = files->GetItem(BaseSet<T, Tnum_files, Tsearch_in_tars>::file_names[i], false);
if (item == nullptr || (!item->value.has_value() && !allow_empty_filename)) {
DEBUG(grf, 0, "No " SET_TYPE " file for: %s (in %s)", BaseSet<T, Tnum_files, Tsearch_in_tars>::file_names[i], full_filename);
Debug(grf, 0, "No " SET_TYPE " file for: {} (in {})", BaseSet<T, Tnum_files, Tsearch_in_tars>::file_names[i], full_filename);
return false;
}
@@ -92,7 +92,7 @@ bool BaseSet<T, Tnum_files, Tsearch_in_tars>::FillSetDetails(IniFile *ini, const
/* Then find the MD5 checksum */
item = md5s->GetItem(filename, false);
if (item == nullptr || !item->value.has_value()) {
DEBUG(grf, 0, "No MD5 checksum specified for: %s (in %s)", filename, full_filename);
Debug(grf, 0, "No MD5 checksum specified for: {} (in {})", filename, full_filename);
return false;
}
const char *c = item->value->c_str();
@@ -105,7 +105,7 @@ bool BaseSet<T, Tnum_files, Tsearch_in_tars>::FillSetDetails(IniFile *ini, const
} else if ('A' <= *c && *c <= 'F') {
j = *c - 'A' + 10;
} else {
DEBUG(grf, 0, "Malformed MD5 checksum specified for: %s (in %s)", filename, full_filename);
Debug(grf, 0, "Malformed MD5 checksum specified for: {} (in {})", filename, full_filename);
return false;
}
if (i % 2 == 0) {
@@ -119,7 +119,7 @@ bool BaseSet<T, Tnum_files, Tsearch_in_tars>::FillSetDetails(IniFile *ini, const
item = origin->GetItem(filename, false);
if (item == nullptr) item = origin->GetItem("default", false);
if (item == nullptr || !item->value.has_value()) {
DEBUG(grf, 1, "No origin warning message specified for: %s", filename);
Debug(grf, 1, "No origin warning message specified for: {}", filename);
file->missing_warning = stredup("");
} else {
file->missing_warning = stredup(item->value->c_str());
@@ -136,12 +136,12 @@ bool BaseSet<T, Tnum_files, Tsearch_in_tars>::FillSetDetails(IniFile *ini, const
break;
case MD5File::CR_MISMATCH:
DEBUG(grf, 1, "MD5 checksum mismatch for: %s (in %s)", filename, full_filename);
Debug(grf, 1, "MD5 checksum mismatch for: {} (in {})", filename, full_filename);
this->found_files++;
break;
case MD5File::CR_NO_FILE:
DEBUG(grf, 1, "The file %s specified in %s is missing", filename, full_filename);
Debug(grf, 1, "The file {} specified in {} is missing", filename, full_filename);
break;
}
}
@@ -153,7 +153,7 @@ template <class Tbase_set>
bool BaseMedia<Tbase_set>::AddFile(const std::string &filename, size_t basepath_length, const std::string &tar_filename)
{
bool ret = false;
DEBUG(grf, 1, "Checking %s for base " SET_TYPE " set", filename.c_str());
Debug(grf, 1, "Checking {} for base " SET_TYPE " set", filename);
Tbase_set *set = new Tbase_set();
IniFile *ini = new IniFile();
@@ -179,7 +179,7 @@ bool BaseMedia<Tbase_set>::AddFile(const std::string &filename, size_t basepath_
/* The more complete set takes precedence over the version number. */
if ((duplicate->valid_files == set->valid_files && duplicate->version >= set->version) ||
duplicate->valid_files > set->valid_files) {
DEBUG(grf, 1, "Not adding %s (%i) as base " SET_TYPE " set (duplicate, %s)", set->name.c_str(), set->version,
Debug(grf, 1, "Not adding {} ({}) as base " SET_TYPE " set (duplicate, {})", set->name, set->version,
duplicate->valid_files > set->valid_files ? "less valid files" : "lower version");
set->next = BaseMedia<Tbase_set>::duplicate_sets;
BaseMedia<Tbase_set>::duplicate_sets = set;
@@ -195,7 +195,7 @@ bool BaseMedia<Tbase_set>::AddFile(const std::string &filename, size_t basepath_
* version number until a new game is started which isn't a big problem */
if (BaseMedia<Tbase_set>::used_set == duplicate) BaseMedia<Tbase_set>::used_set = set;
DEBUG(grf, 1, "Removing %s (%i) as base " SET_TYPE " set (duplicate, %s)", duplicate->name.c_str(), duplicate->version,
Debug(grf, 1, "Removing {} ({}) as base " SET_TYPE " set (duplicate, {})", duplicate->name, duplicate->version,
duplicate->valid_files < set->valid_files ? "less valid files" : "lower version");
duplicate->next = BaseMedia<Tbase_set>::duplicate_sets;
BaseMedia<Tbase_set>::duplicate_sets = duplicate;
@@ -209,7 +209,7 @@ bool BaseMedia<Tbase_set>::AddFile(const std::string &filename, size_t basepath_
ret = true;
}
if (ret) {
DEBUG(grf, 1, "Adding %s (%i) as base " SET_TYPE " set", set->name.c_str(), set->version);
Debug(grf, 1, "Adding {} ({}) as base " SET_TYPE " set", set->name, set->version);
}
} else {
delete set;

View File

@@ -307,7 +307,7 @@ void Blitter_32bppAnim::DrawColourMappingRect(void *dst, int width, int height,
return;
}
DEBUG(misc, 0, "32bpp blitter doesn't know how to draw this colour table ('%d')", pal);
Debug(misc, 0, "32bpp blitter doesn't know how to draw this colour table ('{}')", pal);
}
void Blitter_32bppAnim::SetPixel(void *video, int x, int y, uint8 colour)

View File

@@ -155,6 +155,7 @@ bmno_full_transparency:
if ((bt_last == BT_NONE && effective_width & 1) || bt_last == BT_ODD) {
if (src->a == 0) {
/* Complete transparency. */
} else if (src->a == 255) {
*anim = *(const uint16*) src_mv;
*dst = (src_mv->m >= PALETTE_ANIM_START) ? AdjustBrightneSSE(LookupColourInPalette(src_mv->m), src_mv->v) : *src;
@@ -197,7 +198,7 @@ bmno_full_transparency:
m_colour = r == 0 ? m_colour : cmap; \
m_colour = m != 0 ? m_colour : srcm; \
}
#ifdef _SQ64
#ifdef POINTER_IS_64BIT
uint64 srcs = _mm_cvtsi128_si64(srcABCD);
uint64 dsts;
if (animated) dsts = _mm_cvtsi128_si64(dstABCD);
@@ -379,7 +380,7 @@ bm_normal:
else Draw<BM_NORMAL, RM_WITH_SKIP, BT_ODD, true, true>(bp, zoom);
}
} else {
#ifdef _SQ64
#ifdef POINTER_IS_64BIT
if (sprite_flags & SF_TRANSLUCENT) {
if (sprite_flags & SF_NO_ANIM) Draw<BM_NORMAL, RM_WITH_MARGIN, BT_NONE, true, false>(bp, zoom);
else Draw<BM_NORMAL, RM_WITH_MARGIN, BT_NONE, true, true>(bp, zoom);

View File

@@ -105,7 +105,7 @@ void Blitter_32bppSimple::DrawColourMappingRect(void *dst, int width, int height
return;
}
DEBUG(misc, 0, "32bpp blitter doesn't know how to draw this colour table ('%d')", pal);
Debug(misc, 0, "32bpp blitter doesn't know how to draw this colour table ('{}')", pal);
}
Sprite *Blitter_32bppSimple::Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator)

View File

@@ -34,7 +34,7 @@ static inline void InsertSecondUint32(const uint32 value, __m128i &into)
static inline void LoadUint64(const uint64 value, __m128i &into)
{
#ifdef _SQ64
#ifdef POINTER_IS_64BIT
into = _mm_cvtsi64_si128(value);
#else
#if (SSE_VERSION >= 4)
@@ -297,7 +297,7 @@ inline void Blitter_32bppSSE4::Draw(const Blitter::BlitterParams *bp, ZoomLevel
m_colour = r == 0 ? m_colour : cmap; \
m_colour = m != 0 ? m_colour : srcm; \
}
#ifdef _SQ64
#ifdef POINTER_IS_64BIT
uint64 srcs = _mm_cvtsi128_si64(srcABCD);
uint64 remapped_src = 0;
CMOV_REMAP(c0, 0, srcs, mvX2);

View File

@@ -16,14 +16,14 @@
#include <utility>
template <typename SetPixelT>
void Blitter::DrawLineGeneric(int x, int y, int x2, int y2, int screen_width, int screen_height, int width, int dash, SetPixelT set_pixel)
void Blitter::DrawLineGeneric(int x1, int y1, int x2, int y2, int screen_width, int screen_height, int width, int dash, SetPixelT set_pixel)
{
int dy;
int dx;
int stepx;
int stepy;
dy = (y2 - y) * 2;
dy = (y2 - y1) * 2;
if (dy < 0) {
dy = -dy;
stepy = -1;
@@ -31,7 +31,7 @@ void Blitter::DrawLineGeneric(int x, int y, int x2, int y2, int screen_width, in
stepy = 1;
}
dx = (x2 - x) * 2;
dx = (x2 - x1) * 2;
if (dx < 0) {
dx = -dx;
stepx = -1;
@@ -41,7 +41,7 @@ void Blitter::DrawLineGeneric(int x, int y, int x2, int y2, int screen_width, in
if (dx == 0 && dy == 0) {
/* The algorithm below cannot handle this special case; make it work at least for line width 1 */
if (x >= 0 && x < screen_width && y >= 0 && y < screen_height) set_pixel(x, y);
if (x1 >= 0 && x1 < screen_width && y1 >= 0 && y1 < screen_height) set_pixel(x1, y1);
return;
}
@@ -67,14 +67,14 @@ void Blitter::DrawLineGeneric(int x, int y, int x2, int y2, int screen_width, in
int dash_count = 0;
if (dx > dy) {
if (stepx < 0) {
std::swap(x, x2);
std::swap(y, y2);
std::swap(x1, x2);
std::swap(y1, y2);
stepy = -stepy;
}
if (x2 < 0 || x >= screen_width) return;
if (x2 < 0 || x1 >= screen_width) return;
int y_low = y;
int y_high = y;
int y_low = y1;
int y_high = y1;
int frac_low = dy - frac_diff / 2;
int frac_high = dy + frac_diff / 2;
@@ -87,10 +87,10 @@ void Blitter::DrawLineGeneric(int x, int y, int x2, int y2, int screen_width, in
y_high += stepy;
}
if (x < 0) {
dash_count = (-x) % (dash + gap);
if (x1 < 0) {
dash_count = (-x1) % (dash + gap);
auto adjust_frac = [&](int64 frac, int &y_bound) -> int {
frac -= ((int64) dy) * ((int64) x);
frac -= ((int64) dy) * ((int64) x1);
if (frac >= 0) {
int quotient = frac / dx;
int remainder = frac % dx;
@@ -101,17 +101,17 @@ void Blitter::DrawLineGeneric(int x, int y, int x2, int y2, int screen_width, in
};
frac_low = adjust_frac(frac_low, y_low);
frac_high = adjust_frac(frac_high, y_high);
x = 0;
x1 = 0;
}
x2++;
if (x2 > screen_width) {
x2 = screen_width;
}
while (x != x2) {
while (x1 != x2) {
if (dash_count < dash) {
for (int y = y_low; y != y_high; y += stepy) {
if (y >= 0 && y < screen_height) set_pixel(x, y);
if (y >= 0 && y < screen_height) set_pixel(x1, y);
}
}
if (frac_low >= 0) {
@@ -122,21 +122,21 @@ void Blitter::DrawLineGeneric(int x, int y, int x2, int y2, int screen_width, in
y_high += stepy;
frac_high -= dx;
}
x++;
x1++;
frac_low += dy;
frac_high += dy;
if (++dash_count >= dash + gap) dash_count = 0;
}
} else {
if (stepy < 0) {
std::swap(x, x2);
std::swap(y, y2);
std::swap(x1, x2);
std::swap(y1, y2);
stepx = -stepx;
}
if (y2 < 0 || y >= screen_height) return;
if (y2 < 0 || y1 >= screen_height) return;
int x_low = x;
int x_high = x;
int x_low = x1;
int x_high = x1;
int frac_low = dx - frac_diff / 2;
int frac_high = dx + frac_diff / 2;
@@ -149,10 +149,10 @@ void Blitter::DrawLineGeneric(int x, int y, int x2, int y2, int screen_width, in
x_high += stepx;
}
if (y < 0) {
dash_count = (-y) % (dash + gap);
if (y1 < 0) {
dash_count = (-y1) % (dash + gap);
auto adjust_frac = [&](int64 frac, int &x_bound) -> int {
frac -= ((int64) dx) * ((int64) y);
frac -= ((int64) dx) * ((int64) y1);
if (frac >= 0) {
int quotient = frac / dy;
int remainder = frac % dy;
@@ -163,17 +163,17 @@ void Blitter::DrawLineGeneric(int x, int y, int x2, int y2, int screen_width, in
};
frac_low = adjust_frac(frac_low, x_low);
frac_high = adjust_frac(frac_high, x_high);
y = 0;
y1 = 0;
}
y2++;
if (y2 > screen_height) {
y2 = screen_height;
}
while (y != y2) {
while (y1 != y2) {
if (dash_count < dash) {
for (int x = x_low; x != x_high; x += stepx) {
if (x >= 0 && x < screen_width) set_pixel(x, y);
if (x >= 0 && x < screen_width) set_pixel(x, y1);
}
}
if (frac_low >= 0) {
@@ -184,7 +184,7 @@ void Blitter::DrawLineGeneric(int x, int y, int x2, int y2, int screen_width, in
x_high += stepx;
frac_high -= dy;
}
y++;
y1++;
frac_low += dx;
frac_high += dx;
if (++dash_count >= dash + gap) dash_count = 0;

View File

@@ -70,7 +70,7 @@ protected:
*/
blitters.insert(Blitters::value_type(this->name, this));
} else {
DEBUG(driver, 1, "Not registering blitter %s as it is not usable", name);
Debug(driver, 1, "Not registering blitter {} as it is not usable", name);
}
}
@@ -91,7 +91,7 @@ public:
}
/**
* Find the requested blitter and return his class.
* Find the requested blitter and return its class.
* @param name the blitter to select.
* @post Sets the blitter so GetCurrentBlitter() returns it too.
*/
@@ -104,7 +104,7 @@ public:
delete *GetActiveBlitter();
*GetActiveBlitter() = newb;
DEBUG(driver, 1, "Successfully %s blitter '%s'", name.empty() ? "probed" : "loaded", newb->GetName());
Debug(driver, 1, "Successfully {} blitter '{}'", name.empty() ? "probed" : "loaded", newb->GetName());
return newb;
}

View File

@@ -91,9 +91,10 @@ public:
this->InitNested(1);
}
~BootstrapErrorWindow()
void Close() override
{
_exit_game = true;
this->Window::Close();
}
void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
@@ -144,12 +145,13 @@ public:
{
}
~BootstrapContentDownloadStatusWindow()
void Close() override
{
/* If we are not set to exit the game, it means the bootstrap failed. */
if (!_exit_game) {
new BootstrapErrorWindow();
}
this->BaseNetworkContentDownloadStatusWindow::Close();
}
void OnDownloadComplete(ContentID cid) override
@@ -162,7 +164,7 @@ public:
/* _exit_game is used to break out of the outer video driver's MainLoop. */
_exit_game = true;
delete this;
this->Close();
}
};
@@ -201,9 +203,10 @@ public:
}
/** Stop listening to the content client events. */
~BootstrapAskForDownloadWindow()
void Close() override
{
_network_content_client.RemoveCallback(this);
this->Window::Close();
}
void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
@@ -264,7 +267,7 @@ public:
/* And once the meta data is received, start downloading it. */
_network_content_client.Select(ci->id);
new BootstrapContentDownloadStatusWindow();
delete this;
this->Close();
}
};

View File

@@ -254,7 +254,7 @@ public:
if (i < 9 && i < this->bridges->size()) {
/* Build the requested bridge */
this->BuildBridge(i);
delete this;
this->Close();
return ES_HANDLED;
}
return ES_NOT_HANDLED;
@@ -268,7 +268,7 @@ public:
uint i = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_BBS_BRIDGE_LIST);
if (i < this->bridges->size()) {
this->BuildBridge(i);
delete this;
this->Close();
}
break;
}
@@ -365,7 +365,7 @@ static WindowDesc _build_bridge_desc(
*/
void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transport_type, byte road_rail_type)
{
DeleteWindowByClass(WC_BUILD_BRIDGE);
CloseWindowByClass(WC_BUILD_BRIDGE);
/* Data type for the bridge.
* Bit 16,15 = transport type,

View File

@@ -1105,9 +1105,6 @@ struct BuildVehicleWindow : Window {
* So we just hide it, and enlarge the Rename button by the now vacant place. */
if (this->listview_mode) this->GetWidget<NWidgetStacked>(WID_BV_BUILD_SEL)->SetDisplayedPlane(SZSP_NONE);
/* disable renaming engines in network games if you are not the server */
this->SetWidgetDisabledState(WID_BV_RENAME, _networking && !_network_server);
NWidgetCore *widget = this->GetWidget<NWidgetCore>(WID_BV_LIST);
widget->tool_tip = STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP + type;
@@ -1194,8 +1191,7 @@ struct BuildVehicleWindow : Window {
}
/* Collect available cargo types for filtering. */
const CargoSpec *cs;
FOR_ALL_SORTED_STANDARD_CARGOSPECS(cs) {
for (const CargoSpec *cs : _sorted_standard_cargo_specs) {
this->cargo_filter[filter_items] = cs->Index();
this->cargo_filter_texts[filter_items] = cs->name;
filter_items++;
@@ -1238,7 +1234,7 @@ struct BuildVehicleWindow : Window {
if (!this->listview_mode) {
/* Query for cost and refitted capacity */
CommandCost ret = DoCommand(this->window_number, this->sel_engine | (cargo << 24), 0, DC_QUERY_COST, GetCmdBuildVeh(this->vehicle_type), nullptr);
CommandCost ret = DoCommand(this->window_number, this->sel_engine | (cargo << 24), 0, DC_QUERY_COST, GetCmdBuildVeh(this->vehicle_type));
if (ret.Succeeded()) {
this->te.cost = ret.GetCost() - e->GetCost();
this->te.capacity = _returned_refit_capacity;
@@ -1617,7 +1613,10 @@ struct BuildVehicleWindow : Window {
this->GenerateBuildList();
this->vscroll->SetCount((uint)this->eng_list.size());
this->SetWidgetsDisabledState(this->sel_engine == INVALID_ENGINE, WID_BV_SHOW_HIDE, WID_BV_BUILD, WID_BV_RENAME, WIDGET_LIST_END);
this->SetWidgetsDisabledState(this->sel_engine == INVALID_ENGINE, WID_BV_SHOW_HIDE, WID_BV_BUILD, WIDGET_LIST_END);
/* Disable renaming engines in network games if you are not the server. */
this->SetWidgetDisabledState(WID_BV_RENAME, this->sel_engine == INVALID_ENGINE || (_networking && !_network_server));
this->DrawWidgets();
@@ -1709,7 +1708,7 @@ void ShowBuildVehicleWindow(TileIndex tile, VehicleType type)
assert(IsCompanyBuildableVehicleType(type));
DeleteWindowById(WC_BUILD_VEHICLE, num);
CloseWindowById(WC_BUILD_VEHICLE, num);
new BuildVehicleWindow(&_build_vehicle_desc, tile, type);
}

View File

@@ -61,6 +61,7 @@ enum CargoType {
CT_PLASTIC = 10,
CT_FIZZY_DRINKS = 11,
NUM_ORIGINAL_CARGO = 12,
NUM_CARGO = 64, ///< Maximal number of cargo types in a game.
CT_AUTO_REFIT = 0xFD, ///< Automatically choose cargo type when doing auto refitting.

View File

@@ -17,6 +17,7 @@
#include "cargo_type.h"
#include "vehicle_type.h"
#include "core/multimap.hpp"
#include "saveload/saveload.h"
#include <list>
/** Unique identifier for a single cargo packet. */
@@ -32,7 +33,7 @@ struct GoodsEntry; // forward-declare for Stage() and RerouteStalePackets()
template <class Tinst, class Tcont> class CargoList;
class StationCargoList; // forward-declare, so we can use it in VehicleCargoList.
extern const struct SaveLoad *GetCargoPacketDesc();
extern SaveLoadTable GetCargoPacketDesc();
typedef uint32 TileOrStationID;
@@ -58,7 +59,7 @@ private:
friend class VehicleCargoList;
friend class StationCargoList;
/** We want this to be saved, right? */
friend const struct SaveLoad *GetCargoPacketDesc();
friend SaveLoadTable GetCargoPacketDesc();
public:
/** Maximum number of items in a single cargo packet. */
static const uint16 MAX_COUNT = UINT16_MAX;
@@ -304,8 +305,8 @@ public:
friend class StationCargoList;
/** The super class ought to know what it's doing. */
friend class CargoList<VehicleCargoList, CargoPacketList>;
/** The vehicles have a cargo list (and we want that saved). */
friend const struct SaveLoad *GetVehicleDescription(VehicleType vt);
/* So we can use private/protected variables in the saveload code */
friend class SlVehicleCommon;
friend class CargoShift;
friend class CargoTransfer;
@@ -455,8 +456,8 @@ protected:
public:
/** The super class ought to know what it's doing. */
friend class CargoList<StationCargoList, StationCargoPacketMap>;
/** The stations, via GoodsEntry, have a CargoList. */
friend const struct SaveLoad *GetGoodsDesc();
/* So we can use private/protected variables in the saveload code */
friend class SlStationGoods;
friend class CargoLoad;
friend class CargoTransfer;

View File

@@ -77,6 +77,28 @@ void SetupCargoForClimate(LandscapeID l)
}
}
/**
* Get the cargo ID of a default cargo, if present.
* @param l Landscape
* @param ct Default cargo type.
* @return ID number if the cargo exists, else #CT_INVALID
*/
CargoID GetDefaultCargoID(LandscapeID l, CargoType ct)
{
assert(l < lengthof(_default_climate_cargo));
if (ct == CT_INVALID) return CT_INVALID;
assert(ct < lengthof(_default_climate_cargo[0]));
CargoLabel cl = _default_climate_cargo[l][ct];
/* Bzzt: check if cl is just an index into the cargo table */
if (cl < lengthof(_default_cargo)) {
cl = _default_cargo[cl].label;
}
return GetCargoIDByLabel(cl);
}
/**
* Get the cargo ID by cargo label.
* @param cl Cargo type to get.
@@ -84,8 +106,7 @@ void SetupCargoForClimate(LandscapeID l)
*/
CargoID GetCargoIDByLabel(CargoLabel cl)
{
const CargoSpec *cs;
FOR_ALL_CARGOSPECS(cs) {
for (const CargoSpec *cs : CargoSpec::Iterate()) {
if (cs->label == cl) return cs->Index();
}
@@ -103,8 +124,7 @@ CargoID GetCargoIDByBitnum(uint8 bitnum)
{
if (bitnum == INVALID_CARGO) return CT_INVALID;
const CargoSpec *cs;
FOR_ALL_CARGOSPECS(cs) {
for (const CargoSpec *cs : CargoSpec::Iterate()) {
if (cs->bitnum == bitnum) return cs->Index();
}
@@ -129,9 +149,8 @@ SpriteID CargoSpec::GetCargoIcon() const
return sprite;
}
std::vector<const CargoSpec *> _sorted_cargo_specs; ///< Cargo specifications sorted alphabetically by name.
uint8 _sorted_standard_cargo_specs_size; ///< Number of standard cargo specifications stored in the _sorted_cargo_specs array.
std::vector<const CargoSpec *> _sorted_cargo_specs; ///< Cargo specifications sorted alphabetically by name.
span<const CargoSpec *> _sorted_standard_cargo_specs; ///< Standard cargo specifications sorted alphabetically by name.
/** Sort cargo specifications by their name. */
static bool CargoSpecNameSorter(const CargoSpec * const &a, const CargoSpec * const &b)
@@ -169,22 +188,24 @@ static bool CargoSpecClassSorter(const CargoSpec * const &a, const CargoSpec * c
void InitializeSortedCargoSpecs()
{
_sorted_cargo_specs.clear();
const CargoSpec *cargo;
/* Add each cargo spec to the list. */
FOR_ALL_CARGOSPECS(cargo) {
for (const CargoSpec *cargo : CargoSpec::Iterate()) {
_sorted_cargo_specs.push_back(cargo);
}
/* Sort cargo specifications by cargo class and name. */
std::sort(_sorted_cargo_specs.begin(), _sorted_cargo_specs.end(), &CargoSpecClassSorter);
/* Count the number of standard cargos and fill the mask. */
_standard_cargo_mask = 0;
_sorted_standard_cargo_specs_size = 0;
FOR_ALL_SORTED_CARGOSPECS(cargo) {
uint8 nb_standard_cargo = 0;
for (const auto &cargo : _sorted_cargo_specs) {
if (cargo->classes & CC_SPECIAL) break;
_sorted_standard_cargo_specs_size++;
nb_standard_cargo++;
SetBit(_standard_cargo_mask, cargo->Index());
}
/* _sorted_standard_cargo_specs is a subset of _sorted_cargo_specs. */
_sorted_standard_cargo_specs = { _sorted_cargo_specs.data(), nb_standard_cargo };
}

View File

@@ -15,6 +15,8 @@
#include "gfx_type.h"
#include "strings_type.h"
#include "landscape_type.h"
#include "core/bitmath_func.hpp"
#include "core/span_type.hpp"
#include <vector>
/** Globally unique label of a cargo type. */
@@ -59,7 +61,7 @@ struct CargoSpec {
uint8 rating_colour;
uint8 weight; ///< Weight of a single unit of this cargo type in 1/16 ton (62.5 kg).
uint16 multiplier; ///< Capacity multiplier for vehicles. (8 fractional bits)
uint32 initial_payment; ///< Initial payment rate before inflation is applied.
int32 initial_payment; ///< Initial payment rate before inflation is applied.
uint8 transit_days[2];
bool is_freight; ///< Cargo type is considered to be freight (affects train freight multiplier).
@@ -122,6 +124,49 @@ struct CargoSpec {
SpriteID GetCargoIcon() const;
/**
* Iterator to iterate all valid CargoSpec
*/
struct Iterator {
typedef CargoSpec value_type;
typedef CargoSpec *pointer;
typedef CargoSpec &reference;
typedef size_t difference_type;
typedef std::forward_iterator_tag iterator_category;
explicit Iterator(size_t index) : index(index)
{
this->ValidateIndex();
};
bool operator==(const Iterator &other) const { return this->index == other.index; }
bool operator!=(const Iterator &other) const { return !(*this == other); }
CargoSpec * operator*() const { return CargoSpec::Get(this->index); }
Iterator & operator++() { this->index++; this->ValidateIndex(); return *this; }
private:
size_t index;
void ValidateIndex() { while (this->index < CargoSpec::GetArraySize() && !(CargoSpec::Get(this->index)->IsValid())) this->index++; }
};
/*
* Iterable ensemble of all valid CargoSpec
*/
struct IterateWrapper {
size_t from;
IterateWrapper(size_t from = 0) : from(from) {}
Iterator begin() { return Iterator(this->from); }
Iterator end() { return Iterator(CargoSpec::GetArraySize()); }
bool empty() { return this->begin() == this->end(); }
};
/**
* Returns an iterable ensemble of all valid CargoSpec
* @param from index of the first CargoSpec to consider
* @return an iterable ensemble of all valid CargoSpec
*/
static IterateWrapper Iterate(size_t from = 0) { return IterateWrapper(from); }
private:
static CargoSpec array[NUM_CARGO]; ///< Array holding all CargoSpecs
@@ -134,10 +179,11 @@ extern CargoTypes _standard_cargo_mask;
void SetupCargoForClimate(LandscapeID l);
CargoID GetCargoIDByLabel(CargoLabel cl);
CargoID GetCargoIDByBitnum(uint8 bitnum);
CargoID GetDefaultCargoID(LandscapeID l, CargoType ct);
void InitializeSortedCargoSpecs();
extern std::vector<const CargoSpec *> _sorted_cargo_specs;
extern uint8 _sorted_standard_cargo_specs_size;
extern span<const CargoSpec *> _sorted_standard_cargo_specs;
/**
* Does cargo \a c have cargo class \a cc?
@@ -150,24 +196,6 @@ static inline bool IsCargoInClass(CargoID c, CargoClass cc)
return (CargoSpec::Get(c)->classes & cc) != 0;
}
#define FOR_ALL_CARGOSPECS_FROM(var, start) for (size_t cargospec_index = start; var = nullptr, cargospec_index < CargoSpec::GetArraySize(); cargospec_index++) \
if ((var = CargoSpec::Get(cargospec_index))->IsValid())
#define FOR_ALL_CARGOSPECS(var) FOR_ALL_CARGOSPECS_FROM(var, 0)
#define FOR_EACH_SET_CARGO_ID(var, cargo_bits) FOR_EACH_SET_BIT_EX(CargoID, var, CargoTypes, cargo_bits)
/**
* Loop header for iterating over cargoes, sorted by name. This includes phony cargoes like regearing cargoes.
* @param var Reference getting the cargospec.
* @see CargoSpec
*/
#define FOR_ALL_SORTED_CARGOSPECS(var) for (uint8 index = 0; index < _sorted_cargo_specs.size() && (var = _sorted_cargo_specs[index], true) ; index++)
/**
* Loop header for iterating over 'real' cargoes, sorted by name. Phony cargoes like regearing cargoes are skipped.
* @param var Reference getting the cargospec.
* @see CargoSpec
*/
#define FOR_ALL_SORTED_STANDARD_CARGOSPECS(var) for (uint8 index = 0; index < _sorted_standard_cargo_specs_size && (var = _sorted_cargo_specs[index], true); index++)
using SetCargoBitIterator = SetBitIterator<CargoID, CargoTypes>;
#endif /* CARGOTYPE_H */

View File

@@ -415,6 +415,6 @@ static WindowDesc _cheats_desc(
/** Open cheat window. */
void ShowCheatWindow()
{
DeleteWindowById(WC_CHEATS, 0);
CloseWindowById(WC_CHEATS, 0);
new CheatWindow(&_cheats_desc);
}

View File

@@ -28,12 +28,9 @@ struct Cheats {
Cheat switch_company; ///< change to another company
Cheat money; ///< get rich or poor
Cheat crossing_tunnels; ///< allow tunnels that cross each other
Cheat dummy1; ///< empty cheat (build while in pause mode)
Cheat no_jetcrash; ///< no jet will crash on small airports anymore
Cheat dummy2; ///< empty cheat (change the climate of the map)
Cheat change_date; ///< changes date ingame
Cheat setup_prod; ///< setup raw-material production in game
Cheat dummy3; ///< empty cheat (enable running el-engines on normal rail)
Cheat edit_max_hl; ///< edit the maximum heightlevel; this is a cheat because of the fact that it needs to reset NewGRF game state and doing so as a simple configuration breaks the expectation of many
};

View File

@@ -18,7 +18,7 @@
extern TileHighlightData _thd;
extern RailType _cur_railtype;
extern void GetStationLayout(byte *layout, int numtracks, int plat_len, const StationSpec *statspec);
extern void GetStationLayout(byte *layout, uint numtracks, uint plat_len, const StationSpec *statspec);
namespace citymania {
@@ -431,7 +431,7 @@ void BlueprintCopyArea(TileIndex start, TileIndex end) {
std::multimap<StationID, TileIndex> station_tiles;
std::set<StationID> stations;
TILE_AREA_LOOP(tile, ta) {
for (TileIndex tile : ta) {
TileIndexDiffC td = TileIndexToTileIndexDiffC(tile, start);
switch (GetTileType(tile)) {
case MP_STATION:
@@ -492,7 +492,7 @@ void BlueprintCopyArea(TileIndex start, TileIndex end) {
bool in_area = true;
bool sign_part = false;
std::vector<TileIndex> tiles;
TILE_AREA_LOOP(tile, sta) {
for (TileIndex tile : sta) {
if (!IsTileType(tile, MP_STATION) || GetStationIndex(tile) != sid || !IsRailStation(tile)) continue;
if (!ta.Contains(tile)) {
in_area = false;

View File

@@ -76,8 +76,7 @@ struct CargosWindow : Window {
}
case WID_CT_HEADER_CARGO:
case WID_CT_LIST: {
for (int i = 0; i < _sorted_standard_cargo_specs_size; i++) {
const CargoSpec *cs = _sorted_cargo_specs[i];
for (const CargoSpec *cs : _sorted_standard_cargo_specs) {
size->width = std::max(GetStringBoundingBox(cs->name).width + icon_space, size->width);
}
size->width = std::max(GetStringBoundingBox(STR_TOOLBAR_CARGOS_HEADER_TOTAL_MONTH).width, size->width);
@@ -94,7 +93,7 @@ struct CargosWindow : Window {
case WID_CT_AMOUNT:
case WID_CT_INCOME:
case WID_CT_LIST: {
size->height = _sorted_standard_cargo_specs_size * line_height + CT_LINESPACE + FONT_HEIGHT_NORMAL;
size->height = _sorted_standard_cargo_specs.size() * line_height + CT_LINESPACE + FONT_HEIGHT_NORMAL;
break;
}
}
@@ -103,7 +102,7 @@ struct CargosWindow : Window {
Dimension GetMaxIconSize() const {
const CargoSpec *cs;
Dimension size = {0, 0};
FOR_ALL_CARGOSPECS(cs) {
for (const CargoSpec *cs : _sorted_standard_cargo_specs) {
Dimension icon_size = GetSpriteSize(cs->GetCargoIcon());
size.width = std::max(size.width, icon_size.width);
size.height = std::max(size.height, icon_size.height);
@@ -134,8 +133,7 @@ struct CargosWindow : Window {
case WID_CT_LIST: {
int rect_x = r.left + WD_FRAMERECT_LEFT;
for (int i = 0; i < _sorted_standard_cargo_specs_size; i++) {
const CargoSpec *cs = _sorted_cargo_specs[i];
for (const CargoSpec *cs : _sorted_standard_cargo_specs) {
Dimension icon_size = GetSpriteSize(cs->GetCargoIcon());
DrawSprite(cs->GetCargoIcon(), PAL_NONE,
r.left + max_icon_size.width - icon_size.width,
@@ -156,8 +154,7 @@ struct CargosWindow : Window {
break;
}
case WID_CT_AMOUNT:
for (int i = 0; i < _sorted_standard_cargo_specs_size; i++) {
const CargoSpec *cs = _sorted_cargo_specs[i];
for (const CargoSpec *cs : _sorted_standard_cargo_specs) {
auto &economy = (this->cargoPeriod == WID_CT_OPTION_CARGO_MONTH ? c->old_economy[0] : c->cur_economy);
sum_cargo_amount += economy.delivered_cargo[cs->Index()];
SetDParam(0, economy.delivered_cargo[cs->Index()]);
@@ -173,8 +170,7 @@ struct CargosWindow : Window {
break;
case WID_CT_INCOME:
for (int i = 0; i < _sorted_standard_cargo_specs_size; i++) {
const CargoSpec *cs = _sorted_cargo_specs[i];
for (const CargoSpec *cs : _sorted_standard_cargo_specs) {
auto &economy = (this->cargoPeriod == WID_CT_OPTION_CARGO_MONTH ? c->old_economy[0] : c->cur_economy);
sum_cargo_income += economy.cm.cargo_income[cs->Index()];

View File

@@ -1,8 +1,9 @@
#include "stdafx.h"
#include "citymania/cm_commands_gui.hpp"
#include "cm_commands_gui.hpp"
#include "citymania/cm_base64.hpp"
#include "cm_base64.hpp"
#include "cm_main.hpp"
#include "core/geometry_func.hpp" //maxdim
#include "settings_type.h"
@@ -367,7 +368,8 @@ struct CommandsToolbarWindow : Window {
strecpy(ip, NOVAPOLIS_IPV4_PRIMARY, lastof(ip));
// else strecpy(ip, NOVAPOLIS_IPV4_SECONDARY, lastof(ip));
NetworkClientConnectGame(ip, (3980 + widget - CTW_NS0), COMPANY_SPECTATOR);
// FIXME
// NetworkClientConnectGame(ip, (3980 + widget - CTW_NS0), COMPANY_SPECTATOR);
}
else if (widget >= CTW_CARGO_FIRST) {
int i = widget - CTW_CARGO_FIRST;
@@ -446,7 +448,7 @@ struct CommandsToolbarWindow : Window {
void OnHundredthTick()
{
for (int i = 0; i < _sorted_standard_cargo_specs_size; i++) {
for (int i = 0; i < _sorted_standard_cargo_specs.size(); i++) {
if (this->IsWidgetLowered(i + CTW_CARGO_FIRST)) {
static int x = 0;
x++;
@@ -466,13 +468,13 @@ static NWidgetBase *MakeCargoButtons(int *biggest_index)
{
NWidgetVertical *ver = new NWidgetVertical;
for (int i = 0; i < _sorted_standard_cargo_specs_size; i++) {
for (int i = 0; i < _sorted_standard_cargo_specs.size(); i++) {
NWidgetBackground *leaf = new NWidgetBackground(WWT_PANEL, COLOUR_ORANGE, CTW_CARGO_FIRST + i, NULL);
leaf->tool_tip = STR_GRAPH_CARGO_PAYMENT_TOGGLE_CARGO;
leaf->SetFill(1, 0);
ver->Add(leaf);
}
*biggest_index = CTW_CARGO_FIRST + _sorted_standard_cargo_specs_size - 1;
*biggest_index = CTW_CARGO_FIRST + _sorted_standard_cargo_specs.size() - 1;
return ver;
}
@@ -849,7 +851,7 @@ static WindowDesc _login_window_desc(
void ShowLoginWindow()
{
IniLoginInitiate();
DeleteWindowByClass(WC_LOGIN_WINDOW);
CloseWindowByClass(WC_LOGIN_WINDOW);
AllocateWindowDescFront<LoginWindow>(&_login_window_desc, 0);
}

View File

@@ -33,7 +33,7 @@ bool _replay_started = false;
static void IConsoleHelp(const char *str)
{
IConsolePrintF(CC_WARNING, "- %s", str);
IConsolePrint(CC_WARNING, "- {}", str);
}
bool ConGameSpeed(byte argc, char *argv[]) {
@@ -66,7 +66,7 @@ bool ConExport(byte argc, char *argv[]) {
auto filename = "openttd.json";
citymania::ExportOpenttdData(filename);
IConsolePrintF(CC_DEFAULT, "Data successfully saved to %s", filename);
IConsolePrint(CC_DEFAULT, "Data successfully saved to {}", filename);
return true;
}
@@ -83,13 +83,13 @@ bool ConTreeMap(byte argc, char *argv[]) {
std::string filename = argv[1];
if (_game_mode != GM_EDITOR) {
IConsolePrintF(CC_ERROR, "This command is only available in scenario editor.");
IConsolePrint(CC_ERROR, "This command is only available in scenario editor.");
return true;
}
if (filename.size() < 4) {
IConsolePrintF(CC_ERROR, "Unknown treemap extension should be .bmp or .png.");
IConsolePrint(CC_ERROR, "Unknown treemap extension should be .bmp or .png.");
return true;
}
@@ -101,9 +101,9 @@ bool ConTreeMap(byte argc, char *argv[]) {
#endif
else {
#ifdef WITH_PNG
IConsolePrintF(CC_ERROR, "Unknown treemap extension %s, should be .bmp or .png.", ext.c_str());
IConsolePrint(CC_ERROR, "Unknown treemap extension {}, should be .bmp or .png.", ext.c_str());
#else
IConsolePrintF(CC_ERROR, "Unknown treemap extension %s, should be .bmp (game was compiled without PNG support).", ext.c_str());
IConsolePrint(CC_ERROR, "Unknown treemap extension {}, should be .bmp (game was compiled without PNG support).", ext.c_str());
#endif
return true;
}
@@ -166,9 +166,9 @@ static std::queue<FakeCommand> _fake_commands;
void MakeReplaySave() {
char *filename = str_fmt("replay_%d.sav", _replay_ticks);
if (SaveOrLoad(filename, SLO_SAVE, DFT_GAME_FILE, SAVE_DIR) != SL_OK) {
IConsolePrintF(CC_ERROR, "Replay save failed");
IConsolePrint(CC_ERROR, "Replay save failed");
} else {
IConsolePrintF(CC_DEFAULT, "Replay saved to %s", filename);
IConsolePrint(CC_DEFAULT, "Replay saved to {}", filename);
}
_replay_last_save = _replay_ticks;
}
@@ -213,7 +213,7 @@ void ExecuteFakeCommands(Date date, DateFract date_fract) {
cp.p1 = x.p1;
cp.p2 = x.p2;
cp.cmd = x.cmd;
strecpy(cp.text, x.text.c_str(), lastof(cp.text));
cp.text = x.text;
cp.company = (CompanyID)x.company_id;
cp.frame = _frame_counter_max + 1;
cp.callback = nullptr;
@@ -283,6 +283,11 @@ void LoadCommands(const std::string &filename) {
_replay_started = false;
}
bool IsReplayingCommands() {
return !_fake_commands.empty();
}
bool ConLoadCommands(byte argc, char *argv[]) {
if (argc == 0) {
IConsoleHelp("Loads a file with command queue to execute");

View File

@@ -9,6 +9,7 @@ void SkipFakeCommands(Date date, DateFract date_fract);
void SetReplaySaveInterval(uint32 interval);
void LoadCommands(const std::string &filename);
void CheckIntervalSave();
bool IsReplayingCommands();
bool ConGameSpeed(byte argc, char *argv[]);
bool ConStep(byte argc, char *argv[]);

View File

@@ -165,7 +165,7 @@ void WriteCargoSpecInfo(JsonWriter &j) {
char cargo_label[16];
bool first = true;
SetDParam(0, 123);
FOR_ALL_CARGOSPECS(cs) {
for (const CargoSpec *cs : CargoSpec::Iterate()) {
j.begin_dict();
JKV(j, cs->initial_payment);
j.kv("id", cs->bitnum);

View File

@@ -50,7 +50,7 @@ extern DiagDirection _build_depot_direction; ///< Currently selected depot direc
extern DiagDirection _road_station_picker_orientation;
extern DiagDirection _road_depot_orientation;
extern uint32 _realtime_tick;
extern void GetStationLayout(byte *layout, int numtracks, int plat_len, const StationSpec *statspec);
extern void GetStationLayout(byte *layout, uint numtracks, uint plat_len, const StationSpec *statspec);
struct RailStationGUISettings {
Axis orientation; ///< Currently selected rail station orientation
@@ -264,7 +264,7 @@ bool CanBuild(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) {
p2,
cmd,
nullptr, // callback
nullptr, // text
"", // text
true, // my_cmd
true // estimate_only
).Succeeded();
@@ -342,7 +342,7 @@ void ObjectHighlight::UpdateTiles() {
CMD_BUILD_ROAD_STOP
) ? PALETTE_TINT_WHITE : PALETTE_TINT_RED_DEEP);
TileIndex tile;
TILE_AREA_LOOP(tile, ta) {
for (TileIndex tile : ta) {
this->tiles.insert(std::make_pair(tile, ObjectTileHighlight::make_road_stop(palette, this->roadtype, this->ddir, this->is_truck)));
}
break;
@@ -962,7 +962,7 @@ static void SetStationSelectionHighlight(const TileInfo *ti, TileHighlight &th)
void CalcCBAcceptanceBorders(TileHighlight &th, TileIndex tile, SpriteID border_pal, SpriteID ground_pal) {
int tx = TileX(tile), ty = TileY(tile);
uint16 radius = _settings_client.gui.cb_distance_check;
uint16 radius = _settings_client.gui.cm_cb_distance;
bool in_zone = false;
ZoningBorder border = ZoningBorder::NONE;
_town_kdtree.FindContained(
@@ -1119,7 +1119,7 @@ TileHighlight GetTileHighlight(const TileInfo *ti) {
if (z) th.ground_pal = th.structure_pal = GetTintBySelectionColour(pal[z]);
}
if (_settings_client.gui.show_industry_forbidden_tiles &&
if (_settings_client.gui.cm_show_industry_forbidden_tiles &&
_industry_forbidden_tiles != INVALID_INDUSTRYTYPE) {
auto b = CalcTileBorders(ti->tile, [](TileIndex t) { return !CanBuildIndustryOnTileCached(_industry_forbidden_tiles, t); });
th.add_border(b.first, SPR_PALETTE_ZONING_RED);
@@ -1319,7 +1319,7 @@ void UpdateTownZoning(Town *town, uint32 prev_edge) {
recalc = false;
}
// TODO mark dirty only if zoning is on
TILE_AREA_LOOP(tile, area) {
for(TileIndex tile : area) {
uint8 group = GetTownZone(town, tile);
if (_mz[tile].town_zone != group)
@@ -1390,7 +1390,7 @@ ZoningBorder GetAnyStationCatchmentBorder(TileIndex tile) {
}
void SetIndustryForbiddenTilesHighlight(IndustryType type) {
if (_settings_client.gui.show_industry_forbidden_tiles &&
if (_settings_client.gui.cm_show_industry_forbidden_tiles &&
_industry_forbidden_tiles != type) {
MarkWholeScreenDirty();
}

View File

@@ -85,14 +85,13 @@ void UpdateModKeys(bool shift_pressed, bool ctrl_pressed, bool alt_pressed) {
_remove_mod = mod_pressed[(size_t)_settings_client.gui.cm_remove_mod];
_estimate_mod = mod_pressed[(size_t)_settings_client.gui.cm_estimate_mod];
Window *w;
if (fn_mod_prev != _fn_mod) {
FOR_ALL_WINDOWS_FROM_FRONT(w) {
for (auto w : Window::IterateFromFront()) {
if (w->CM_OnFnModStateChange() == ES_HANDLED) break;
}
}
if (remove_mod_prev != _remove_mod) {
FOR_ALL_WINDOWS_FROM_FRONT(w) {
for (auto w : Window::IterateFromFront()) {
if (w->CM_OnRemoveModStateChange() == ES_HANDLED) break;
}
}
@@ -166,7 +165,7 @@ void RailToolbar_UpdateRemoveWidgetStatus(Window *w, int widget, bool remove_act
bool RailToolbar_RemoveModChanged(Window *w, bool invert_remove, bool remove_active, bool button_clicked) {
if (w->IsWidgetDisabled(WID_RAT_REMOVE)) return false;
DeleteWindowById(WC_SELECT_STATION, 0);
CloseWindowById(WC_SELECT_STATION, 0);
for (uint i = WID_RAT_BUILD_NS; i < WID_RAT_REMOVE; i++) {
if (w->IsWidgetLowered(i)) {
auto old_active = remove_active;
@@ -248,7 +247,7 @@ void RoadToolbar_UpdateOptionWidgetStatus(Window *w, int widget, bool remove_act
bool RoadToolbar_RemoveModChanged(Window *w, bool remove_active, bool button_clicked, bool is_road) {
if (w->IsWidgetDisabled(WID_ROT_REMOVE)) return false;
DeleteWindowById(WC_SELECT_STATION, 0);
CloseWindowById(WC_SELECT_STATION, 0);
for (uint i = WID_ROT_ROAD_X; i < WID_ROT_REMOVE; i++) {
if (w->IsWidgetLowered(i)) {
auto old_active = remove_active;

View File

@@ -4,6 +4,7 @@
#include "cm_hotkeys.hpp"
#include "cm_minimap.hpp"
#include "../network/network_func.h"
#include "../window_func.h"
#include "../safeguards.h"
@@ -24,7 +25,11 @@ void SwitchToMode(SwitchMode new_mode) {
void ToggleSmallMap() {
SmallMapWindow *w = dynamic_cast<citymania::SmallMapWindow*>(FindWindowById(WC_SMALLMAP, 0));
if (w == nullptr) ShowSmallMap();
delete w;
else w->Close();
}
void NetworkClientSendChatToServer(const std::string &msg) {
NetworkClientSendChat(NETWORK_ACTION_CHAT_CLIENT, DESTTYPE_CLIENT, CLIENT_ID_SERVER, msg);
}
} // namespace citymania

View File

@@ -17,6 +17,7 @@ void Emit(const T &event) {
}
void ToggleSmallMap();
void NetworkClientSendChatToServer(const std::string &msg);
} // namespace citymania

View File

@@ -729,7 +729,7 @@ inline uint32 SmallMapWindow::GetTileColours(const TileArea &ta) const
TileIndex tile = INVALID_TILE; // Position of the most important tile.
TileType et = MP_VOID; // Effective tile type at that position.
TILE_AREA_LOOP(ti, ta) {
for(TileIndex ti : ta) {
TileType ttype = GetTileType(ti);
switch (ttype) {

View File

@@ -112,17 +112,17 @@ public:
#else
# define LANDINFOD_LEVEL 1
#endif
DEBUG(misc, LANDINFOD_LEVEL, "TILE: %#x (%i,%i)", tile, TileX(tile), TileY(tile));
DEBUG(misc, LANDINFOD_LEVEL, "type = %#x", _m[tile].type);
DEBUG(misc, LANDINFOD_LEVEL, "height = %#x", _m[tile].height);
DEBUG(misc, LANDINFOD_LEVEL, "m1 = %#x", _m[tile].m1);
DEBUG(misc, LANDINFOD_LEVEL, "m2 = %#x", _m[tile].m2);
DEBUG(misc, LANDINFOD_LEVEL, "m3 = %#x", _m[tile].m3);
DEBUG(misc, LANDINFOD_LEVEL, "m4 = %#x", _m[tile].m4);
DEBUG(misc, LANDINFOD_LEVEL, "m5 = %#x", _m[tile].m5);
DEBUG(misc, LANDINFOD_LEVEL, "m6 = %#x", _me[tile].m6);
DEBUG(misc, LANDINFOD_LEVEL, "m7 = %#x", _me[tile].m7);
DEBUG(misc, LANDINFOD_LEVEL, "m8 = %#x", _me[tile].m8);
Debug(misc, LANDINFOD_LEVEL, "TILE: %#x (%i,%i)", tile, TileX(tile), TileY(tile));
Debug(misc, LANDINFOD_LEVEL, "type = %#x", _m[tile].type);
Debug(misc, LANDINFOD_LEVEL, "height = %#x", _m[tile].height);
Debug(misc, LANDINFOD_LEVEL, "m1 = %#x", _m[tile].m1);
Debug(misc, LANDINFOD_LEVEL, "m2 = %#x", _m[tile].m2);
Debug(misc, LANDINFOD_LEVEL, "m3 = %#x", _m[tile].m3);
Debug(misc, LANDINFOD_LEVEL, "m4 = %#x", _m[tile].m4);
Debug(misc, LANDINFOD_LEVEL, "m5 = %#x", _m[tile].m5);
Debug(misc, LANDINFOD_LEVEL, "m6 = %#x", _me[tile].m6);
Debug(misc, LANDINFOD_LEVEL, "m7 = %#x", _me[tile].m7);
Debug(misc, LANDINFOD_LEVEL, "m8 = %#x", _me[tile].m8);
#undef LANDINFOD_LEVEL
}
@@ -386,7 +386,7 @@ void ShowLandInfo(TileIndex tile, TileIndex end_tile)
if (tile == last_tooltip_tile) return;
last_tooltip_tile = tile;
DeleteWindowById(WC_LAND_INFO, 0);
CloseWindowById(WC_LAND_INFO, 0);
if (tile == INVALID_TILE) return;
new LandInfoWindow(tile, end_tile);
}

View File

@@ -3,6 +3,7 @@
#include "../company_base.h"
#include "../date_func.h"
#include "../debug.h"
#include "../saveload/compat/storage_sl_compat.h"
#include "../saveload/saveload.h"
#include "../town.h"
@@ -23,7 +24,6 @@ static const SaveLoad _storage_desc[] = {
SLE_CONDVAR(PersistentStorage, grfid, SLE_UINT32, SLV_6, SL_MAX_VERSION),
SLE_CONDARR(PersistentStorage, storage, SLE_UINT32, 16, SLV_161, SLV_EXTEND_PERSISTENT_STORAGE),
SLE_CONDARR(PersistentStorage, storage, SLE_UINT32, 256, SLV_EXTEND_PERSISTENT_STORAGE, SL_MAX_VERSION),
SLE_END()
};
@@ -303,7 +303,7 @@ static void DecodeTownsCargoV1(BitIStream &bs)
for (uint i = 0; i < n_cb_cargos; i++) {
uint cargo = bs.ReadBytes(1);
if (cargo >= NUM_CARGO) {
DEBUG(sl, 0, "Invalid CargoID in CB towns cargo data (%u)", cargo);
Debug(sl, 0, "Invalid CargoID in CB towns cargo data (%u)", cargo);
return;
}
cb_cargos.push_back(cargo);
@@ -318,7 +318,7 @@ static void DecodeTownsCargoV1(BitIStream &bs)
uint town_id = bs.ReadBytes(2);
t = Town::GetIfValid(town_id);
if (!t) {
DEBUG(sl, 0, "Invalid TownID in CB towns cargo data (%u)", town_id);
Debug(sl, 0, "Invalid TownID in CB towns cargo data (%u)", town_id);
return;
}
// auto &tcb = t->cb;
@@ -351,7 +351,7 @@ static void DecodeDataV1(BitIStream &bs) {
uint town_id = bs.ReadBytes(2);
t = Town::GetIfValid(town_id);
if (!t) {
DEBUG(sl, 0, "Invalid TownID in CB towns layout errors (%u)", town_id);
Debug(sl, 0, "Invalid TownID in CB towns layout errors (%u)", town_id);
continue;
}
t->cm.hs_total = bs.ReadBytes(4);
@@ -370,18 +370,18 @@ static void DecodeDataV1(BitIStream &bs) {
static void DecodeData(u8vector &data) {
if (data.size() == 0) {
DEBUG(sl, 2, "No CityMania save data");
Debug(sl, 2, "No CityMania save data");
return;
}
DEBUG(sl, 2, "CityMania save data takes %lu bytes", data.size());
Debug(sl, 2, "CityMania save data takes %lu bytes", data.size());
BitIStream bs(data);
try {
uint version = bs.ReadBytes(2);
if (version > SAVEGAME_DATA_FORMAT_VERSION) {
DEBUG(sl, 0, "Savegame was made with newer version of client, extra save data was not loaded");
Debug(sl, 0, "Savegame was made with newer version of client, extra save data was not loaded");
return;
}
DEBUG(sl, 2, "CityMania savegame data version %u", version);
Debug(sl, 2, "CityMania savegame data version %u", version);
_last_client_version = bs.ReadBytes(2);
_settings_game.citymania.controller_type = (ControllerType)bs.ReadBytes(1);
if (version <= 1 && _settings_game.citymania.controller_type != ControllerType::GENERIC)
@@ -389,7 +389,7 @@ static void DecodeData(u8vector &data) {
int32 date = bs.ReadBytes(4);
uint32 date_fract = bs.ReadBytes(1);
if (date != _date || date_fract != _date_fract) {
DEBUG(sl, 0, "Savegame was run in unmodified client, extra save data "
Debug(sl, 0, "Savegame was run in unmodified client, extra save data "
"preserved, but may not be accurate");
}
_settings_game.citymania.game_type = (GameType)bs.ReadBytes(1);
@@ -399,7 +399,7 @@ static void DecodeData(u8vector &data) {
else DecodeDataV2(bs);
}
catch (BitIStreamUnexpectedEnd &e) {
DEBUG(sl, 0, "Invalid CityMania save data");
Debug(sl, 0, "Invalid CityMania save data");
}
}
@@ -408,8 +408,9 @@ struct FakePersistentStorage {
uint8 *storage;
};
void Save_PSAC() {
void PSACChunkHandler::Save() const {
/* Write the industries */
SlTableHeader(_storage_desc);
for (PersistentStorage *ps : PersistentStorage::Iterate()) {
if (ps->grfid == CITYMANIA_GRFID) {
continue;
@@ -420,7 +421,7 @@ void Save_PSAC() {
}
if (_game_mode == GM_EDITOR) {
DEBUG(sl, 2, "Saving scenario, skip CityMania extra data");
Debug(sl, 2, "Saving scenario, skip CityMania extra data");
return;
}
@@ -433,13 +434,12 @@ void Save_PSAC() {
u8vector data = EncodeData();
int n_chunks = (data.size() + 1023) / 1024;
data.resize(n_chunks * 1024);
DEBUG(sl, 2, "Citybuilder data takes %u bytes", (uint)data.size());
Debug(sl, 2, "Citybuilder data takes %u bytes", (uint)data.size());
FakePersistentStorage ps{CITYMANIA_GRFID, &data[0]};
static const SaveLoad _desc[] = {
SLE_CONDVAR(FakePersistentStorage, grfid, SLE_UINT32, SLV_6, SL_MAX_VERSION),
SLE_CONDARR(FakePersistentStorage, storage, SLE_UINT32, 256, SLV_EXTEND_PERSISTENT_STORAGE, SL_MAX_VERSION),
SLE_END()
};
for (int i = 0; i < n_chunks; i++, ps.storage += 1024) {
@@ -448,8 +448,7 @@ void Save_PSAC() {
}
}
void Load_PSAC()
{
void PSACChunkHandler::Load() const {
int index;
/*
@@ -461,12 +460,14 @@ void Load_PSAC()
u8vector cmdata;
uint chunk_size = IsSavegameVersionBefore(SLV_EXTEND_PERSISTENT_STORAGE) ? 64 : 1024;
const std::vector<SaveLoad> slt = SlCompatTableHeader(_storage_desc, _storage_sl_compat);
while ((index = SlIterateArray()) != -1) {
if (ps == NULL) {
assert(PersistentStorage::CanAllocateItem());
ps = new (index) PersistentStorage(0, 0, 0);
}
SlObject(ps, _storage_desc);
SlObject(ps, slt);
if (ps->grfid == CITYMANIA_GRFID) {
uint8 *data = (uint8 *)(ps->storage);

View File

@@ -1,10 +1,16 @@
#ifndef CITYMANIA_SAVELOAD_HPP
#define CITYMANIA_SAVELOAD_HPP
#include "../saveload/saveload.h"
namespace citymania {
void Save_PSAC();
void Load_PSAC();
struct PSACChunkHandler : ChunkHandler {
PSACChunkHandler() : ChunkHandler('PSAC', CH_TABLE) {}
void Load() const override;
void Save() const override;
};
} // namespace citymania

View File

@@ -289,7 +289,7 @@ static RoadBits FindRoadsToConnect(TileIndex tile, RoadType roadtype) {
}
bool CheckDriveThroughRoadStopDirection(TileArea area, RoadBits r) {
TILE_AREA_LOOP(tile, area) {
for (TileIndex tile : area) {
if (GetTileType(tile) != MP_ROAD) continue;
if (GetRoadTileType(tile) != ROAD_TILE_NORMAL) continue;
if (GetAllRoadBits(tile) & ~r) return false;
@@ -436,7 +436,7 @@ static void FindStationsAroundSelection(const TileArea &location)
Station *adjacent = nullptr;
/* Direct loop instead of FindStationsAroundTiles as we are not interested in catchment area */
TILE_AREA_LOOP(tile, ta) {
for (auto tile : ta) {
if (IsTileType(tile, MP_STATION) && GetTileOwner(tile) == _local_company) {
Station *st = Station::GetByTile(tile);
if (st == nullptr) continue;
@@ -571,7 +571,7 @@ CargoArray GetProductionAroundTiles(TileIndex tile, int w, int h, int rad)
/* Loop over all tiles to get the produced cargo of
* everything except industries */
TILE_AREA_LOOP(tile, ta) {
for(auto tile : ta) {
switch (GetTileType(tile)) {
case MP_INDUSTRY:
industries.insert(GetIndustryIndex(tile));

View File

@@ -104,9 +104,7 @@ struct LandTooltipsWindow : public Window
SetDParam(0, st->index);
size->width = std::max(GetStringBoundingBox(STR_CM_LAND_TOOLTIPS_STATION_NAME).width, size->width);
for (int i = 0; i < _sorted_standard_cargo_specs_size; i++) {
const CargoSpec *cs = _sorted_cargo_specs[i];
if(cs == NULL) continue;
for (const CargoSpec *cs : _sorted_standard_cargo_specs) {
int cargoid = cs->Index();
if (HasBit(st->goods[cargoid].status, GoodsEntry::GES_RATING)) {
size->height += line_height;
@@ -186,9 +184,7 @@ struct LandTooltipsWindow : public Window
DrawString(left, right, y, STR_CM_LAND_TOOLTIPS_STATION_NAME, TC_BLACK, SA_CENTER);
y += FONT_HEIGHT_NORMAL + 2;
for (int i = 0; i < _sorted_standard_cargo_specs_size; i++) {
const CargoSpec *cs = _sorted_cargo_specs[i];
if(cs == NULL) continue;
for (const CargoSpec *cs : _sorted_standard_cargo_specs) {
int cargoid = cs->Index();
if (HasBit(st->goods[cargoid].status, GoodsEntry::GES_RATING)) {
SetDParam(0, cs->name);
@@ -223,7 +219,7 @@ void ShowLandTooltips(TileIndex tile, Window *parent) {
last_tooltip_tile = tile;
if (tile == INVALID_TILE) {
DeleteWindowById(CM_WC_LAND_TOOLTIPS, 0);
CloseWindowById(CM_WC_LAND_TOOLTIPS, 0);
return;
}
@@ -255,7 +251,7 @@ void ShowLandTooltips(TileIndex tile, Window *parent) {
default:
break;
}
DeleteWindowById(CM_WC_LAND_TOOLTIPS, 0);
CloseWindowById(CM_WC_LAND_TOOLTIPS, 0);
if (param == 0) return;
new LandTooltipsWindow(parent, param);
@@ -504,7 +500,7 @@ public:
};
bool ShowStationRatingTooltip(Window *parent, const Station *st, const CargoSpec *cs, TooltipCloseCondition close_cond) {
DeleteWindowById(WC_STATION_RATING_TOOLTIP, 0);
CloseWindowById(WC_STATION_RATING_TOOLTIP, 0);
new StationRatingTooltipWindow(parent, st, cs, close_cond);
return true;
}

View File

@@ -3,6 +3,7 @@
#include "../stdafx.h"
#include "cm_watch_gui.hpp"
#include "cm_main.hpp"
#include "../widget_type.h"
#include "../gfx_type.h"

View File

@@ -5,6 +5,7 @@
#include "../window_gui.h"
#include "../company_base.h"
#include "../network/core/config.h"
namespace citymania {

View File

@@ -286,7 +286,7 @@ SpriteID TileZoneCheckNewCBBorders(TileIndex tile) {
//Check CB town acceptance area
SpriteID TileZoneCheckCBBorders(TileIndex tile) {
for (Town *town : Town::Iterate()) {
if (DistanceMax(town->xy, tile) <= _settings_client.gui.cb_distance_check)
if (DistanceMax(town->xy, tile) <= _settings_client.gui.cm_cb_distance)
return SPR_PALETTE_ZONING_LIGHT_BLUE;
}
return INVALID_SPRITE_ID; // no town

View File

@@ -200,7 +200,7 @@ CommandProc CmdDeleteGroup;
CommandProc CmdAddVehicleGroup;
CommandProc CmdAddSharedVehicleGroup;
CommandProc CmdRemoveAllVehiclesGroup;
CommandProc CmdSetGroupReplaceProtection;
CommandProc CmdSetGroupFlag;
CommandProc CmdSetGroupLivery;
CommandProc CmdMoveOrder;
@@ -366,7 +366,7 @@ static const Command _command_proc_table[] = {
DEF_CMD(CmdAddVehicleGroup, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_ADD_VEHICLE_GROUP
DEF_CMD(CmdAddSharedVehicleGroup, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_ADD_SHARE_VEHICLE_GROUP
DEF_CMD(CmdRemoveAllVehiclesGroup, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_REMOVE_ALL_VEHICLES_GROUP
DEF_CMD(CmdSetGroupReplaceProtection, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_SET_GROUP_REPLACE_PROTECTION
DEF_CMD(CmdSetGroupFlag, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_SET_GROUP_FLAG
DEF_CMD(CmdSetGroupLivery, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_SET_GROUP_LIVERY
DEF_CMD(CmdMoveOrder, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_MOVE_ORDER
DEF_CMD(CmdChangeTimetable, 0, CMDT_ROUTE_MANAGEMENT ), // CMD_CHANGE_TIMETABLE
@@ -472,7 +472,7 @@ CommandCost DoCommand(const CommandContainer *container, DoCommandFlag flags)
* @see CommandProc
* @return the cost
*/
CommandCost DoCommand(TileIndex tile, uint32 p1, uint32 p2, DoCommandFlag flags, uint32 cmd, const char *text)
CommandCost DoCommand(TileIndex tile, uint32 p1, uint32 p2, DoCommandFlag flags, uint32 cmd, const std::string &text)
{
CommandCost res;
@@ -565,7 +565,7 @@ bool DoCommandP(const CommandContainer *container, bool my_cmd)
* @param my_cmd indicator if the command is from a company or server (to display error messages for a user)
* @return \c true if the command succeeded, else \c false.
*/
bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback, const char *text, bool my_cmd)
bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback, const std::string &text, bool my_cmd)
{
/* Cost estimation is generally only done when the
* local user presses shift while doing something.
@@ -642,7 +642,7 @@ bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallbac
* @param estimate_only whether to give only the estimate or also execute the command
* @return the command cost of this function.
*/
CommandCost DoCommandPInternal(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback, const char *text, bool my_cmd, bool estimate_only)
CommandCost DoCommandPInternal(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback, const std::string &text, bool my_cmd, bool estimate_only)
{
/* Prevent recursion; it gives a mess over the network */
assert(_docommand_recursive == 0);
@@ -707,7 +707,7 @@ CommandCost DoCommandPInternal(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd,
if (!_networking || _generating_world || (cmd & CMD_NETWORK_COMMAND) != 0) {
/* Log the failed command as well. Just to be able to be find
* causes of desyncs due to bad command test implementations. */
DEBUG(desync, 1, "cmdf: %08x; %02x; %02x; %06x; %08x; %08x; %08x; \"%s\" (%s)", _date, _date_fract, (int)_current_company, tile, p1, p2, cmd & ~CMD_NETWORK_COMMAND, text, GetCommandName(cmd));
Debug(desync, 1, "cmdf: {:08x}; {:02x}; {:02x}; {:06x}; {:08x}; {:08x}; {:08x}; \"{}\" ({})", _date, _date_fract, (int)_current_company, tile, p1, p2, cmd & ~CMD_NETWORK_COMMAND, text, GetCommandName(cmd));
}
cur_company.Restore();
return_dcpi(res);
@@ -727,7 +727,7 @@ CommandCost DoCommandPInternal(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd,
* reset the storages as we've not executed the command. */
return_dcpi(CommandCost());
}
DEBUG(desync, 1, "cmd: %08x; %02x; %02x; %06x; %08x; %08x; %08x; \"%s\" (%s)", _date, _date_fract, (int)_current_company, tile, p1, p2, cmd & ~CMD_NETWORK_COMMAND, text, GetCommandName(cmd));
Debug(desync, 1, "cmd: {:08x}; {:02x}; {:02x}; {:06x}; {:08x}; {:08x}; {:08x}; \"{}\" ({})", _date, _date_fract, (int)_current_company, tile, p1, p2, cmd & ~CMD_NETWORK_COMMAND, text, GetCommandName(cmd));
/* Actually try and execute the command. If no cost-type is given
* use the construction one */

View File

@@ -32,15 +32,15 @@ static const CommandCost CMD_ERROR = CommandCost(INVALID_STRING_ID);
*/
#define return_cmd_error(errcode) return CommandCost(errcode);
CommandCost DoCommand(TileIndex tile, uint32 p1, uint32 p2, DoCommandFlag flags, uint32 cmd, const char *text = nullptr);
CommandCost DoCommand(TileIndex tile, uint32 p1, uint32 p2, DoCommandFlag flags, uint32 cmd, const std::string &text = {});
CommandCost DoCommand(const CommandContainer *container, DoCommandFlag flags);
bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback = nullptr, const char *text = nullptr, bool my_cmd = true);
bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback = nullptr, const std::string &text = {}, bool my_cmd = true);
bool DoCommandP(const CommandContainer *container, bool my_cmd = true);
CommandCost DoCommandPInternal(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback, const char *text, bool my_cmd, bool estimate_only);
CommandCost DoCommandPInternal(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback, const std::string &text, bool my_cmd, bool estimate_only);
void NetworkSendCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback, const char *text, CompanyID company);
void NetworkSendCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback, const std::string &text, CompanyID company);
extern Money _additional_cash_required;

View File

@@ -324,7 +324,7 @@ enum Commands {
CMD_ADD_VEHICLE_GROUP, ///< add a vehicle to a group
CMD_ADD_SHARED_VEHICLE_GROUP, ///< add all other shared vehicles to a group which are missing
CMD_REMOVE_ALL_VEHICLES_GROUP, ///< remove all vehicles from a group
CMD_SET_GROUP_REPLACE_PROTECTION, ///< set the autoreplace-protection for a group
CMD_SET_GROUP_FLAG, ///< set/clear a flag for a group
CMD_SET_GROUP_LIVERY, ///< set the livery for a group
CMD_MOVE_ORDER, ///< move an order
@@ -444,7 +444,7 @@ enum CommandPauseLevel {
* @param text Additional text
* @return The CommandCost of the command, which can be succeeded or failed.
*/
typedef CommandCost CommandProc(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text);
typedef CommandCost CommandProc(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text);
/**
* Define a command with the flags which belongs to it.
@@ -483,7 +483,7 @@ struct CommandContainer {
uint32 p2; ///< parameter p2.
uint32 cmd; ///< command being executed.
CommandCallback *callback; ///< any callback function executed upon successful completion of the command.
char text[32 * MAX_CHAR_LENGTH]; ///< possible text sent for name changes etc, in bytes including '\0'.
std::string text; ///< possible text sent for name changes etc.
};
#endif /* COMMAND_TYPE_H */

View File

@@ -101,6 +101,11 @@ struct CompanyProperties {
CompanyEconomyEntry old_economy[MAX_HISTORY_QUARTERS]; ///< Economic data of the company of the last #MAX_HISTORY_QUARTERS quarters.
byte num_valid_stat_ent; ///< Number of valid statistical entries in #old_economy.
Livery livery[LS_END];
EngineRenewList engine_renew_list; ///< Engine renewals of this company.
CompanySettings settings; ///< settings specific for each company
citymania::ext::Company cm; ///< CityMania extra company data.
// TODO: Change some of these member variables to use relevant INVALID_xxx constants
@@ -109,22 +114,19 @@ struct CompanyProperties {
face(0), money(0), money_fraction(0), current_loan(0), colour(0), block_preview(0),
location_of_HQ(0), last_build_coordinate(0), share_owners(), inaugurated_year(0),
months_of_bankruptcy(0), bankrupt_asked(0), bankrupt_timeout(0), bankrupt_value(0),
terraform_limit(0), clear_limit(0), tree_limit(0), is_ai(false) {}
terraform_limit(0), clear_limit(0), tree_limit(0), is_ai(false), engine_renew_list(nullptr) {}
};
struct Company : CompanyPool::PoolItem<&_company_pool>, CompanyProperties {
struct Company : CompanyProperties, CompanyPool::PoolItem<&_company_pool> {
Company(uint16 name_1 = 0, bool is_ai = false);
~Company();
Livery livery[LS_END];
RailTypes avail_railtypes; ///< Rail types available to this company.
RoadTypes avail_roadtypes; ///< Road types available to this company.
class AIInstance *ai_instance;
class AIInfo *ai_info;
EngineRenewList engine_renew_list; ///< Engine renewals of this company.
CompanySettings settings; ///< settings specific for each company
GroupStatistics group_all[VEH_COMPANY_END]; ///< NOSAVE: Statistics for the ALL_GROUP group.
GroupStatistics group_default[VEH_COMPANY_END]; ///< NOSAVE: Statistics for the DEFAULT_GROUP group.

View File

@@ -41,6 +41,7 @@
#include "cargo_type.h"
#include "citymania/cm_hotkeys.hpp"
#include "citymania/cm_console_cmds.hpp"
#include "safeguards.h"
@@ -70,7 +71,7 @@ Company::Company(uint16 name_1, bool is_ai)
this->clear_limit = (uint32)_settings_game.construction.clear_frame_burst << 16;
this->tree_limit = (uint32)_settings_game.construction.tree_frame_burst << 16;
for (uint j = 0; j < 4; j++) this->share_owners[j] = COMPANY_SPECTATOR;
for (uint j = 0; j < 4; j++) this->share_owners[j] = INVALID_OWNER;
InvalidateWindowData(WC_PERFORMANCE_DETAIL, 0, INVALID_COMPANY);
InvalidateWindowClassesData(WC_WATCH_COMPANY, 0);
InvalidateWindowClassesData(WC_WATCH_COMPANYA, 1);
@@ -81,7 +82,7 @@ Company::~Company()
{
if (CleaningPool()) return;
DeleteCompanyWindows(this->index);
CloseCompanyWindows(this->index);
}
/**
@@ -122,7 +123,7 @@ void SetLocalCompany(CompanyID new_company)
_current_company = _local_company = new_company;
/* Delete any construction windows... */
if (switching_company) DeleteConstructionWindows();
if (switching_company) CloseConstructionWindows();
if (switching_company) citymania::ResetEffectivveActionCounter();
/* ... and redraw the whole screen. */
@@ -384,8 +385,7 @@ set_name:;
MarkWholeScreenDirty();
if (c->is_ai) {
CompanyNewsInformation *cni = MallocT<CompanyNewsInformation>(1);
cni->FillData(c);
CompanyNewsInformation *cni = new CompanyNewsInformation(c);
SetDParam(0, STR_NEWS_COMPANY_LAUNCH_TITLE);
SetDParam(1, STR_NEWS_COMPANY_LAUNCH_DESCRIPTION);
SetDParamStr(2, cni->company_name);
@@ -579,8 +579,7 @@ Company *DoStartupNewCompany(bool is_ai, CompanyID company = INVALID_COMPANY)
GeneratePresidentName(c);
SetWindowDirty(WC_GRAPH_LEGEND, 0);
SetWindowClassesDirty(WC_CLIENT_LIST_POPUP);
SetWindowDirty(WC_CLIENT_LIST, 0);
InvalidateWindowData(WC_CLIENT_LIST, 0);
InvalidateWindowData(WC_LINKGRAPH_LEGEND, 0);
BuildOwnerLegend();
InvalidateWindowData(WC_SMALLMAP, 0, 1);
@@ -764,21 +763,19 @@ void CompaniesYearlyLoop()
* @param c the current company.
* @param other the other company (use \c nullptr if not relevant).
*/
void CompanyNewsInformation::FillData(const Company *c, const Company *other)
CompanyNewsInformation::CompanyNewsInformation(const Company *c, const Company *other)
{
SetDParam(0, c->index);
GetString(this->company_name, STR_COMPANY_NAME, lastof(this->company_name));
this->company_name = GetString(STR_COMPANY_NAME);
if (other == nullptr) {
*this->other_company_name = '\0';
} else {
if (other != nullptr) {
SetDParam(0, other->index);
GetString(this->other_company_name, STR_COMPANY_NAME, lastof(this->other_company_name));
this->other_company_name = GetString(STR_COMPANY_NAME);
c = other;
}
SetDParam(0, c->index);
GetString(this->president_name, STR_PRESIDENT_NAME_MANAGER, lastof(this->president_name));
this->president_name = GetString(STR_PRESIDENT_NAME_MANAGER);
this->colour = c->colour;
this->face = c->face;
@@ -816,7 +813,7 @@ void CompanyAdminRemove(CompanyID company_id, CompanyRemoveReason reason)
* @param text unused
* @return the cost of this operation or an error
*/
CommandCost CmdCompanyCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
CommandCost CmdCompanyCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text)
{
InvalidateWindowData(WC_COMPANY_LEAGUE, 0, 0);
CompanyID company_id = (CompanyID)GB(p1, 16, 8);
@@ -824,7 +821,7 @@ CommandCost CmdCompanyCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
switch ((CompanyCtrlAction)GB(p1, 0, 16)) {
case CCA_NEW: { // Create a new company
/* This command is only executed in a multiplayer game */
if (!_networking) return CMD_ERROR;
if (!_networking && !citymania::IsReplayingCommands()) return CMD_ERROR;
/* Has the network client a correct ClientIndex? */
if (!(flags & DC_EXEC)) return CommandCost();
@@ -833,7 +830,7 @@ CommandCost CmdCompanyCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(client_id);
/* Delete multiplayer progress bar */
DeleteWindowById(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_JOIN);
CloseWindowById(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_JOIN);
Company *c = DoStartupNewCompany(false);
@@ -852,7 +849,7 @@ CommandCost CmdCompanyCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
if (client_id == _network_own_client_id) {
assert(_local_company == COMPANY_SPECTATOR);
SetLocalCompany(c->index);
if (!StrEmpty(_settings_client.network.default_company_pass)) {
if (!_settings_client.network.default_company_pass.empty()) {
NetworkChangeCompanyPassword(_local_company, _settings_client.network.default_company_pass);
}
@@ -897,9 +894,8 @@ CommandCost CmdCompanyCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
if (!(flags & DC_EXEC)) return CommandCost();
/* Delete any open window of the company */
DeleteCompanyWindows(c->index);
CompanyNewsInformation *cni = MallocT<CompanyNewsInformation>(1);
cni->FillData(c);
CloseCompanyWindows(c->index);
CompanyNewsInformation *cni = new CompanyNewsInformation(c);
/* Show the bankrupt news */
SetDParam(0, STR_NEWS_COMPANY_BANKRUPT_TITLE);
@@ -918,6 +914,8 @@ CommandCost CmdCompanyCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
CompanyAdminRemove(c_index, (CompanyRemoveReason)reason);
if (StoryPage::GetNumItems() == 0 || Goal::GetNumItems() == 0) InvalidateWindowData(WC_MAIN_TOOLBAR, 0);
InvalidateWindowData(WC_CLIENT_LIST, 0);
break;
}
@@ -940,7 +938,7 @@ CommandCost CmdCompanyCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
* @param text unused
* @return the cost of this operation or an error
*/
CommandCost CmdSetCompanyManagerFace(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
CommandCost CmdSetCompanyManagerFace(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text)
{
CompanyManagerFace cmf = (CompanyManagerFace)p2;
@@ -964,7 +962,7 @@ CommandCost CmdSetCompanyManagerFace(TileIndex tile, DoCommandFlag flags, uint32
* @param text unused
* @return the cost of this operation or an error
*/
CommandCost CmdSetCompanyColour(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
CommandCost CmdSetCompanyColour(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text)
{
Colours colour = Extract<Colours, 0, 8>(p2);
LiveryScheme scheme = Extract<LiveryScheme, 0, 8>(p1);
@@ -1057,7 +1055,7 @@ CommandCost CmdSetCompanyColour(TileIndex tile, DoCommandFlag flags, uint32 p1,
* @param name Name to search.
* @return \c true if the name us unique (that is, not in use), else \c false.
*/
static bool IsUniqueCompanyName(const char *name)
static bool IsUniqueCompanyName(const std::string &name)
{
for (const Company *c : Company::Iterate()) {
if (!c->name.empty() && c->name == name) return false;
@@ -1075,9 +1073,9 @@ static bool IsUniqueCompanyName(const char *name)
* @param text the new name or an empty string when resetting to the default
* @return the cost of this operation or an error
*/
CommandCost CmdRenameCompany(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
CommandCost CmdRenameCompany(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text)
{
bool reset = StrEmpty(text);
bool reset = text.empty();
if (!reset) {
if (Utf8StringLength(text) >= MAX_LENGTH_COMPANY_NAME_CHARS) return CMD_ERROR;
@@ -1104,7 +1102,7 @@ CommandCost CmdRenameCompany(TileIndex tile, DoCommandFlag flags, uint32 p1, uin
* @param name Name to search.
* @return \c true if the name us unique (that is, not in use), else \c false.
*/
static bool IsUniquePresidentName(const char *name)
static bool IsUniquePresidentName(const std::string &name)
{
for (const Company *c : Company::Iterate()) {
if (!c->president_name.empty() && c->president_name == name) return false;
@@ -1122,9 +1120,9 @@ static bool IsUniquePresidentName(const char *name)
* @param text the new name or an empty string when resetting to the default
* @return the cost of this operation or an error
*/
CommandCost CmdRenamePresident(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
CommandCost CmdRenamePresident(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text)
{
bool reset = StrEmpty(text);
bool reset = text.empty();
if (!reset) {
if (Utf8StringLength(text) >= MAX_LENGTH_PRESIDENT_NAME_CHARS) return CMD_ERROR;
@@ -1140,10 +1138,7 @@ CommandCost CmdRenamePresident(TileIndex tile, DoCommandFlag flags, uint32 p1, u
c->president_name = text;
if (c->name_1 == STR_SV_UNNAMED && c->name.empty()) {
char buf[80];
seprintf(buf, lastof(buf), "%s Transport", text);
DoCommand(0, 0, 0, DC_EXEC, CMD_RENAME_COMPANY, buf);
DoCommand(0, 0, 0, DC_EXEC, CMD_RENAME_COMPANY, text + " Transport");
}
}
@@ -1210,7 +1205,7 @@ uint32 CompanyInfrastructure::GetTramTotal() const
* @param text unused
* @return the cost of this operation or an error
*/
CommandCost CmdGiveMoney(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
CommandCost CmdGiveMoney(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text)
{
if (!_settings_game.economy.give_money) return CMD_ERROR;
@@ -1229,13 +1224,11 @@ CommandCost CmdGiveMoney(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
cur_company.Restore();
if (_networking) {
char dest_company_name[MAX_LENGTH_COMPANY_NAME_CHARS * MAX_CHAR_LENGTH];
SetDParam(0, dest_company);
GetString(dest_company_name, STR_COMPANY_NAME, lastof(dest_company_name));
std::string dest_company_name = GetString(STR_COMPANY_NAME);
char from_company_name[MAX_LENGTH_COMPANY_NAME_CHARS * MAX_CHAR_LENGTH];
SetDParam(0, _current_company);
GetString(from_company_name, STR_COMPANY_NAME, lastof(from_company_name));
std::string from_company_name = GetString(STR_COMPANY_NAME);
NetworkTextMessage(NETWORK_ACTION_GIVE_MONEY, GetDrawStringCompanyColour(_current_company), false, from_company_name, dest_company_name, amount.GetCost());
}

View File

@@ -41,6 +41,7 @@
#include "widgets/company_widget.h"
#include "citymania/cm_hotkeys.hpp"
#include "citymania/cm_main.hpp"
#include "safeguards.h"
@@ -244,10 +245,10 @@ static const NWidgetPart _nested_company_finances_widgets[] = {
EndContainer(),
NWidget(NWID_SPACER), SetFill(0, 0), SetMinimalSize(30, 0),
NWidget(NWID_VERTICAL), // Vertical column with bank balance amount, loan amount, and total.
NWidget(WWT_TEXT, COLOUR_GREY, WID_CF_BALANCE_VALUE), SetDataTip(STR_NULL, STR_NULL),
NWidget(WWT_TEXT, COLOUR_GREY, WID_CF_LOAN_VALUE), SetDataTip(STR_NULL, STR_NULL),
NWidget(WWT_TEXT, COLOUR_GREY, WID_CF_BALANCE_VALUE), SetDataTip(STR_FINANCES_TOTAL_CURRENCY, STR_NULL), SetAlignment(SA_VERT_CENTER | SA_RIGHT),
NWidget(WWT_TEXT, COLOUR_GREY, WID_CF_LOAN_VALUE), SetDataTip(STR_FINANCES_TOTAL_CURRENCY, STR_NULL), SetAlignment(SA_VERT_CENTER | SA_RIGHT),
NWidget(WWT_EMPTY, COLOUR_GREY, WID_CF_LOAN_LINE), SetMinimalSize(0, 2), SetFill(1, 0),
NWidget(WWT_TEXT, COLOUR_GREY, WID_CF_TOTAL_VALUE), SetDataTip(STR_NULL, STR_NULL),
NWidget(WWT_TEXT, COLOUR_GREY, WID_CF_TOTAL_VALUE), SetDataTip(STR_FINANCES_TOTAL_CURRENCY, STR_NULL), SetAlignment(SA_VERT_CENTER | SA_RIGHT),
EndContainer(),
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_CF_SEL_MAXLOAN),
NWidget(NWID_HORIZONTAL),
@@ -294,6 +295,24 @@ struct CompanyFinancesWindow : Window {
SetDParam(1, (CompanyID)this->window_number);
break;
case WID_CF_BALANCE_VALUE: {
const Company *c = Company::Get((CompanyID)this->window_number);
SetDParam(0, c->money);
break;
}
case WID_CF_LOAN_VALUE: {
const Company *c = Company::Get((CompanyID)this->window_number);
SetDParam(0, c->current_loan);
break;
}
case WID_CF_TOTAL_VALUE: {
const Company *c = Company::Get((CompanyID)this->window_number);
SetDParam(0, c->money - c->current_loan);
break;
}
case WID_CF_MAXLOAN_VALUE:
SetDParam(0, _economy.max_loan);
break;
@@ -352,27 +371,6 @@ struct CompanyFinancesWindow : Window {
break;
}
case WID_CF_BALANCE_VALUE: {
const Company *c = Company::Get((CompanyID)this->window_number);
SetDParam(0, c->money);
DrawString(r.left, r.right, r.top, STR_FINANCES_TOTAL_CURRENCY, TC_FROMSTRING, SA_RIGHT);
break;
}
case WID_CF_LOAN_VALUE: {
const Company *c = Company::Get((CompanyID)this->window_number);
SetDParam(0, c->current_loan);
DrawString(r.left, r.right, r.top, STR_FINANCES_TOTAL_CURRENCY, TC_FROMSTRING, SA_RIGHT);
break;
}
case WID_CF_TOTAL_VALUE: {
const Company *c = Company::Get((CompanyID)this->window_number);
SetDParam(0, c->money - c->current_loan);
DrawString(r.left, r.right, r.top, STR_FINANCES_TOTAL_CURRENCY, TC_FROMSTRING, SA_RIGHT);
break;
}
case WID_CF_LOAN_LINE:
GfxFillRect(r.left, r.top, r.right, r.top, PC_BLACK);
break;
@@ -781,11 +779,11 @@ public:
case WID_SCL_PRI_COL_DROPDOWN: {
this->square = GetSpriteSize(SPR_SQUARE);
int padding = this->square.width + NWidgetScrollbar::GetVerticalDimension().width + 10;
int string_padding = this->square.width + NWidgetScrollbar::GetVerticalDimension().width + 10;
for (const StringID *id = _colour_dropdown; id != endof(_colour_dropdown); id++) {
size->width = std::max(size->width, GetStringBoundingBox(*id).width + padding);
size->width = std::max(size->width, GetStringBoundingBox(*id).width + string_padding);
}
size->width = std::max(size->width, GetStringBoundingBox(STR_COLOUR_DEFAULT).width + padding);
size->width = std::max(size->width, GetStringBoundingBox(STR_COLOUR_DEFAULT).width + string_padding);
break;
}
}
@@ -958,7 +956,7 @@ public:
break;
case WID_SCL_MATRIX: {
uint row = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_SCL_MATRIX, 0, this->line_height);
uint row = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_SCL_MATRIX);
if (row >= this->rows) return;
if (this->livery_class < LC_GROUP_RAIL) {
@@ -1202,70 +1200,82 @@ static const NWidgetPart _nested_select_company_manager_face_widgets[] = {
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 4),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_HAS_MOUSTACHE_EARRING_TEXT), SetFill(1, 0),
NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_HAS_MOUSTACHE_EARRING_TEXT), SetFill(1, 0), SetPadding(0, WD_FRAMERECT_RIGHT, 0, WD_FRAMERECT_LEFT),
SetDataTip(STR_FACE_EYECOLOUR, STR_NULL), SetTextColour(TC_GOLD), SetAlignment(SA_VERT_CENTER | SA_RIGHT),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_HAS_MOUSTACHE_EARRING), SetDataTip(STR_EMPTY, STR_FACE_MOUSTACHE_EARRING_TOOLTIP),
EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_HAS_GLASSES_TEXT), SetFill(1, 0),
NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_HAS_GLASSES_TEXT), SetFill(1, 0), SetPadding(0, WD_FRAMERECT_RIGHT, 0, WD_FRAMERECT_LEFT),
SetDataTip(STR_FACE_GLASSES, STR_NULL), SetTextColour(TC_GOLD), SetAlignment(SA_VERT_CENTER | SA_RIGHT),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_HAS_GLASSES), SetDataTip(STR_EMPTY, STR_FACE_GLASSES_TOOLTIP),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 2), SetFill(1, 0),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_HAIR_TEXT), SetFill(1, 0),
NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_HAIR_TEXT), SetFill(1, 0), SetPadding(0, WD_FRAMERECT_RIGHT, 0, WD_FRAMERECT_LEFT),
SetDataTip(STR_FACE_HAIR, STR_NULL), SetTextColour(TC_GOLD), SetAlignment(SA_VERT_CENTER | SA_RIGHT),
NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_HAIR_L), SetDataTip(AWV_DECREASE, STR_FACE_HAIR_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_HAIR), SetDataTip(STR_EMPTY, STR_FACE_HAIR_TOOLTIP),
NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_HAIR_R), SetDataTip(AWV_INCREASE, STR_FACE_HAIR_TOOLTIP),
EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_EYEBROWS_TEXT), SetFill(1, 0),
NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_EYEBROWS_TEXT), SetFill(1, 0), SetPadding(0, WD_FRAMERECT_RIGHT, 0, WD_FRAMERECT_LEFT),
SetDataTip(STR_FACE_EYEBROWS, STR_NULL), SetTextColour(TC_GOLD), SetAlignment(SA_VERT_CENTER | SA_RIGHT),
NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_EYEBROWS_L), SetDataTip(AWV_DECREASE, STR_FACE_EYEBROWS_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_EYEBROWS), SetDataTip(STR_EMPTY, STR_FACE_EYEBROWS_TOOLTIP),
NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_EYEBROWS_R), SetDataTip(AWV_INCREASE, STR_FACE_EYEBROWS_TOOLTIP),
EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_EYECOLOUR_TEXT), SetFill(1, 0),
NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_EYECOLOUR_TEXT), SetFill(1, 0), SetPadding(0, WD_FRAMERECT_RIGHT, 0, WD_FRAMERECT_LEFT),
SetDataTip(STR_FACE_EYECOLOUR, STR_NULL), SetTextColour(TC_GOLD), SetAlignment(SA_VERT_CENTER | SA_RIGHT),
NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_EYECOLOUR_L), SetDataTip(AWV_DECREASE, STR_FACE_EYECOLOUR_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_EYECOLOUR), SetDataTip(STR_EMPTY, STR_FACE_EYECOLOUR_TOOLTIP),
NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_EYECOLOUR_R), SetDataTip(AWV_INCREASE, STR_FACE_EYECOLOUR_TOOLTIP),
EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_GLASSES_TEXT), SetFill(1, 0),
NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_GLASSES_TEXT), SetFill(1, 0), SetPadding(0, WD_FRAMERECT_RIGHT, 0, WD_FRAMERECT_LEFT),
SetDataTip(STR_FACE_GLASSES, STR_NULL), SetTextColour(TC_GOLD), SetAlignment(SA_VERT_CENTER | SA_RIGHT),
NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_GLASSES_L), SetDataTip(AWV_DECREASE, STR_FACE_GLASSES_TOOLTIP_2),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_GLASSES), SetDataTip(STR_EMPTY, STR_FACE_GLASSES_TOOLTIP_2),
NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_GLASSES_R), SetDataTip(AWV_INCREASE, STR_FACE_GLASSES_TOOLTIP_2),
EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_NOSE_TEXT), SetFill(1, 0),
NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_NOSE_TEXT), SetFill(1, 0), SetPadding(0, WD_FRAMERECT_RIGHT, 0, WD_FRAMERECT_LEFT),
SetDataTip(STR_FACE_NOSE, STR_NULL), SetTextColour(TC_GOLD), SetAlignment(SA_VERT_CENTER | SA_RIGHT),
NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_NOSE_L), SetDataTip(AWV_DECREASE, STR_FACE_NOSE_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_NOSE), SetDataTip(STR_EMPTY, STR_FACE_NOSE_TOOLTIP),
NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_NOSE_R), SetDataTip(AWV_INCREASE, STR_FACE_NOSE_TOOLTIP),
EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_LIPS_MOUSTACHE_TEXT), SetFill(1, 0),
NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_LIPS_MOUSTACHE_TEXT), SetFill(1, 0), SetPadding(0, WD_FRAMERECT_RIGHT, 0, WD_FRAMERECT_LEFT),
SetDataTip(STR_FACE_MOUSTACHE, STR_NULL), SetTextColour(TC_GOLD), SetAlignment(SA_VERT_CENTER | SA_RIGHT),
NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_LIPS_MOUSTACHE_L), SetDataTip(AWV_DECREASE, STR_FACE_LIPS_MOUSTACHE_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_LIPS_MOUSTACHE), SetDataTip(STR_EMPTY, STR_FACE_LIPS_MOUSTACHE_TOOLTIP),
NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_LIPS_MOUSTACHE_R), SetDataTip(AWV_INCREASE, STR_FACE_LIPS_MOUSTACHE_TOOLTIP),
EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_CHIN_TEXT), SetFill(1, 0),
NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_CHIN_TEXT), SetFill(1, 0), SetPadding(0, WD_FRAMERECT_RIGHT, 0, WD_FRAMERECT_LEFT),
SetDataTip(STR_FACE_CHIN, STR_NULL), SetTextColour(TC_GOLD), SetAlignment(SA_VERT_CENTER | SA_RIGHT),
NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_CHIN_L), SetDataTip(AWV_DECREASE, STR_FACE_CHIN_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_CHIN), SetDataTip(STR_EMPTY, STR_FACE_CHIN_TOOLTIP),
NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_CHIN_R), SetDataTip(AWV_INCREASE, STR_FACE_CHIN_TOOLTIP),
EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_JACKET_TEXT), SetFill(1, 0),
NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_JACKET_TEXT), SetFill(1, 0), SetPadding(0, WD_FRAMERECT_RIGHT, 0, WD_FRAMERECT_LEFT),
SetDataTip(STR_FACE_JACKET, STR_NULL), SetTextColour(TC_GOLD), SetAlignment(SA_VERT_CENTER | SA_RIGHT),
NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_JACKET_L), SetDataTip(AWV_DECREASE, STR_FACE_JACKET_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_JACKET), SetDataTip(STR_EMPTY, STR_FACE_JACKET_TOOLTIP),
NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_JACKET_R), SetDataTip(AWV_INCREASE, STR_FACE_JACKET_TOOLTIP),
EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_COLLAR_TEXT), SetFill(1, 0),
NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_COLLAR_TEXT), SetFill(1, 0), SetPadding(0, WD_FRAMERECT_RIGHT, 0, WD_FRAMERECT_LEFT),
SetDataTip(STR_FACE_COLLAR, STR_NULL), SetTextColour(TC_GOLD), SetAlignment(SA_VERT_CENTER | SA_RIGHT),
NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_COLLAR_L), SetDataTip(AWV_DECREASE, STR_FACE_COLLAR_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_COLLAR), SetDataTip(STR_EMPTY, STR_FACE_COLLAR_TOOLTIP),
NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_COLLAR_R), SetDataTip(AWV_INCREASE, STR_FACE_COLLAR_TOOLTIP),
EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SCMF_TIE_EARRING_TEXT), SetFill(1, 0),
NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_TIE_EARRING_TEXT), SetFill(1, 0), SetPadding(0, WD_FRAMERECT_RIGHT, 0, WD_FRAMERECT_LEFT),
SetDataTip(STR_FACE_EARRING, STR_NULL), SetTextColour(TC_GOLD), SetAlignment(SA_VERT_CENTER | SA_RIGHT),
NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_TIE_EARRING_L), SetDataTip(AWV_DECREASE, STR_FACE_TIE_EARRING_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_TIE_EARRING), SetDataTip(STR_EMPTY, STR_FACE_TIE_EARRING_TOOLTIP),
NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_TIE_EARRING_R), SetDataTip(AWV_INCREASE, STR_FACE_TIE_EARRING_TOOLTIP),
@@ -1296,9 +1306,6 @@ class SelectCompanyManagerFaceWindow : public Window
Dimension yesno_dim; ///< Dimension of a yes/no button of a part in the advanced face window.
Dimension number_dim; ///< Dimension of a number widget of a part in the advanced face window.
static const StringID PART_TEXTS_IS_FEMALE[]; ///< Strings depending on #is_female, used to describe parts (2 entries for a part).
static const StringID PART_TEXTS[]; ///< Fixed strings to describe parts of the face.
/**
* Draw dynamic a label to the left of the button and a value in the button
*
@@ -1331,6 +1338,10 @@ class SelectCompanyManagerFaceWindow : public Window
this->ge = (GenderEthnicity)GB(this->face, _cmf_info[CMFV_GEN_ETHN].offset, _cmf_info[CMFV_GEN_ETHN].length); // get the gender and ethnicity
this->is_female = HasBit(this->ge, GENDER_FEMALE); // get the gender: 0 == male and 1 == female
this->is_moust_male = !is_female && GetCompanyManagerFaceBits(this->face, CMFV_HAS_MOUSTACHE, this->ge) != 0; // is a male face with moustache
this->GetWidget<NWidgetCore>(WID_SCMF_HAS_MOUSTACHE_EARRING_TEXT)->widget_data = this->is_female ? STR_FACE_EARRING : STR_FACE_MOUSTACHE;
this->GetWidget<NWidgetCore>(WID_SCMF_TIE_EARRING_TEXT)->widget_data = this->is_female ? STR_FACE_EARRING : STR_FACE_TIE;
this->GetWidget<NWidgetCore>(WID_SCMF_LIPS_MOUSTACHE_TEXT)->widget_data = this->is_moust_male ? STR_FACE_MOUSTACHE : STR_FACE_LIPS;
}
public:
@@ -1392,6 +1403,21 @@ public:
void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
{
switch (widget) {
case WID_SCMF_HAS_MOUSTACHE_EARRING_TEXT:
*size = maxdim(*size, GetStringBoundingBox(STR_FACE_EARRING));
*size = maxdim(*size, GetStringBoundingBox(STR_FACE_MOUSTACHE));
break;
case WID_SCMF_TIE_EARRING_TEXT:
*size = maxdim(*size, GetStringBoundingBox(STR_FACE_EARRING));
*size = maxdim(*size, GetStringBoundingBox(STR_FACE_TIE));
break;
case WID_SCMF_LIPS_MOUSTACHE_TEXT:
*size = maxdim(*size, GetStringBoundingBox(STR_FACE_LIPS));
*size = maxdim(*size, GetStringBoundingBox(STR_FACE_MOUSTACHE));
break;
case WID_SCMF_FACE: {
Dimension face_size = GetSpriteSize(SPR_GRADIENT);
size->width = std::max(size->width, face_size.width);
@@ -1399,35 +1425,6 @@ public:
break;
}
case WID_SCMF_HAS_MOUSTACHE_EARRING_TEXT:
case WID_SCMF_TIE_EARRING_TEXT: {
int offset = (widget - WID_SCMF_HAS_MOUSTACHE_EARRING_TEXT) * 2;
*size = maxdim(GetStringBoundingBox(PART_TEXTS_IS_FEMALE[offset]), GetStringBoundingBox(PART_TEXTS_IS_FEMALE[offset + 1]));
size->width += WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
size->height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
break;
}
case WID_SCMF_LIPS_MOUSTACHE_TEXT:
*size = maxdim(GetStringBoundingBox(STR_FACE_LIPS), GetStringBoundingBox(STR_FACE_MOUSTACHE));
size->width += WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
size->height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
break;
case WID_SCMF_HAS_GLASSES_TEXT:
case WID_SCMF_HAIR_TEXT:
case WID_SCMF_EYEBROWS_TEXT:
case WID_SCMF_EYECOLOUR_TEXT:
case WID_SCMF_GLASSES_TEXT:
case WID_SCMF_NOSE_TEXT:
case WID_SCMF_CHIN_TEXT:
case WID_SCMF_JACKET_TEXT:
case WID_SCMF_COLLAR_TEXT:
*size = GetStringBoundingBox(PART_TEXTS[widget - WID_SCMF_HAS_GLASSES_TEXT]);
size->width += WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
size->height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
break;
case WID_SCMF_HAS_MOUSTACHE_EARRING:
case WID_SCMF_HAS_GLASSES:
*size = this->yesno_dim;
@@ -1512,30 +1509,6 @@ public:
void DrawWidget(const Rect &r, int widget) const override
{
switch (widget) {
case WID_SCMF_HAS_MOUSTACHE_EARRING_TEXT:
case WID_SCMF_TIE_EARRING_TEXT: {
StringID str = PART_TEXTS_IS_FEMALE[(widget - WID_SCMF_HAS_MOUSTACHE_EARRING_TEXT) * 2 + this->is_female];
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, str, TC_GOLD, SA_RIGHT);
break;
}
case WID_SCMF_LIPS_MOUSTACHE_TEXT:
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, (this->is_moust_male) ? STR_FACE_MOUSTACHE : STR_FACE_LIPS, TC_GOLD, SA_RIGHT);
break;
case WID_SCMF_HAS_GLASSES_TEXT:
case WID_SCMF_HAIR_TEXT:
case WID_SCMF_EYEBROWS_TEXT:
case WID_SCMF_EYECOLOUR_TEXT:
case WID_SCMF_GLASSES_TEXT:
case WID_SCMF_NOSE_TEXT:
case WID_SCMF_CHIN_TEXT:
case WID_SCMF_JACKET_TEXT:
case WID_SCMF_COLLAR_TEXT:
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, PART_TEXTS[widget - WID_SCMF_HAS_GLASSES_TEXT], TC_GOLD, SA_RIGHT);
break;
case WID_SCMF_HAS_MOUSTACHE_EARRING:
if (this->is_female) { // Only for female faces
this->DrawFaceStringLabel(WID_SCMF_HAS_MOUSTACHE_EARRING, GetCompanyManagerFaceBits(this->face, CMFV_HAS_TIE_EARRING, this->ge), true);
@@ -1616,7 +1589,7 @@ public:
/* Cancel button */
case WID_SCMF_CANCEL:
delete this;
this->Close();
break;
/* Load button */
@@ -1723,25 +1696,6 @@ public:
}
};
/** Both text values of parts of the face that depend on the #is_female boolean value. */
const StringID SelectCompanyManagerFaceWindow::PART_TEXTS_IS_FEMALE[] = {
STR_FACE_MOUSTACHE, STR_FACE_EARRING, // WID_SCMF_HAS_MOUSTACHE_EARRING_TEXT
STR_FACE_TIE, STR_FACE_EARRING, // WID_SCMF_TIE_EARRING_TEXT
};
/** Textual names for parts of the face. */
const StringID SelectCompanyManagerFaceWindow::PART_TEXTS[] = {
STR_FACE_GLASSES, // WID_SCMF_HAS_GLASSES_TEXT
STR_FACE_HAIR, // WID_SCMF_HAIR_TEXT
STR_FACE_EYEBROWS, // WID_SCMF_EYEBROWS_TEXT
STR_FACE_EYECOLOUR, // WID_SCMF_EYECOLOUR_TEXT
STR_FACE_GLASSES, // WID_SCMF_GLASSES_TEXT
STR_FACE_NOSE, // WID_SCMF_NOSE_TEXT
STR_FACE_CHIN, // WID_SCMF_CHIN_TEXT
STR_FACE_JACKET, // WID_SCMF_JACKET_TEXT
STR_FACE_COLLAR, // WID_SCMF_COLLAR_TEXT
};
/** Company manager face selection window description */
static WindowDesc _select_company_manager_face_desc(
WDP_AUTO, "company_face", 0, 0,
@@ -1889,8 +1843,7 @@ struct CompanyInfrastructureWindow : Window
size->width = std::max(size->width, GetStringBoundingBox(STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT).width);
RailType rt;
FOR_ALL_SORTED_RAILTYPES(rt) {
for (const auto &rt : _sorted_railtypes) {
if (HasBit(this->railtypes, rt)) {
lines++;
SetDParam(0, GetRailTypeInfo(rt)->strings.name);
@@ -1912,8 +1865,7 @@ struct CompanyInfrastructureWindow : Window
size->width = std::max(size->width, GetStringBoundingBox(widget == WID_CI_ROAD_DESC ? STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT : STR_COMPANY_INFRASTRUCTURE_VIEW_TRAM_SECT).width);
RoadType rt;
FOR_ALL_SORTED_ROADTYPES(rt) {
for (const auto &rt : _sorted_roadtypes) {
if (HasBit(this->roadtypes, rt) && RoadTypeIsRoad(rt) == (widget == WID_CI_ROAD_DESC)) {
lines++;
SetDParam(0, GetRoadTypeInfo(rt)->strings.name);
@@ -2022,8 +1974,7 @@ struct CompanyInfrastructureWindow : Window
if (this->railtypes != RAILTYPES_NONE) {
/* Draw name of each valid railtype. */
RailType rt;
FOR_ALL_SORTED_RAILTYPES(rt) {
for (const auto &rt : _sorted_railtypes) {
if (HasBit(this->railtypes, rt)) {
SetDParam(0, GetRailTypeInfo(rt)->strings.name);
DrawString(r.left + offs_left, r.right - offs_right, y += FONT_HEIGHT_NORMAL, STR_WHITE_STRING);
@@ -2040,8 +1991,7 @@ struct CompanyInfrastructureWindow : Window
case WID_CI_RAIL_COUNT: {
/* Draw infrastructure count for each valid railtype. */
uint32 rail_total = c->infrastructure.GetRailTotal();
RailType rt;
FOR_ALL_SORTED_RAILTYPES(rt) {
for (const auto &rt : _sorted_railtypes) {
if (HasBit(this->railtypes, rt)) {
this->DrawCountLine(r, y, c->infrastructure.rail[rt], RailMaintenanceCost(rt, c->infrastructure.rail[rt], rail_total));
}
@@ -2057,8 +2007,7 @@ struct CompanyInfrastructureWindow : Window
DrawString(r.left, r.right, y, widget == WID_CI_ROAD_DESC ? STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT : STR_COMPANY_INFRASTRUCTURE_VIEW_TRAM_SECT);
/* Draw name of each valid roadtype. */
RoadType rt;
FOR_ALL_SORTED_ROADTYPES(rt) {
for (const auto &rt : _sorted_roadtypes) {
if (HasBit(this->roadtypes, rt) && RoadTypeIsRoad(rt) == (widget == WID_CI_ROAD_DESC)) {
SetDParam(0, GetRoadTypeInfo(rt)->strings.name);
DrawString(r.left + offs_left, r.right - offs_right, y += FONT_HEIGHT_NORMAL, STR_WHITE_STRING);
@@ -2071,8 +2020,7 @@ struct CompanyInfrastructureWindow : Window
case WID_CI_ROAD_COUNT:
case WID_CI_TRAM_COUNT: {
uint32 road_tram_total = widget == WID_CI_ROAD_COUNT ? c->infrastructure.GetRoadTotal() : c->infrastructure.GetTramTotal();
RoadType rt;
FOR_ALL_SORTED_ROADTYPES(rt) {
for (const auto &rt : _sorted_roadtypes) {
if (HasBit(this->roadtypes, rt) && RoadTypeIsRoad(rt) == (widget == WID_CI_ROAD_COUNT)) {
this->DrawCountLine(r, y, c->infrastructure.road[rt], RoadMaintenanceCost(rt, c->infrastructure.road[rt], road_tram_total));
}
@@ -2273,7 +2221,7 @@ static void ResetCallback(Window *w, bool confirmed)
CompanyID company2 = (CompanyID)w->window_number;
char msg[128];
seprintf(msg, lastof(msg), "!reset %i", company2 + 1);
NetworkClientSendChatToServer(msg);
citymania::NetworkClientSendChatToServer(msg);
}
}
@@ -2705,7 +2653,7 @@ struct CompanyWindow : Window
// this->query_widget = WID_C_MOD_COMPANY_JOIN;
char msg[128];
seprintf(msg, lastof(msg), "!move %i", company2 + 1);
NetworkClientSendChatToServer(msg);
citymania::NetworkClientSendChatToServer(msg);
MarkWholeScreenDirty();
break;
}
@@ -2721,7 +2669,7 @@ struct CompanyWindow : Window
CompanyID company2 = (CompanyID)this->window_number;
char msg[128];
seprintf(msg, lastof(msg), "!lockp %i", company2 + 1);
NetworkClientSendChatToServer(msg);
citymania::NetworkClientSendChatToServer(msg);
MarkWholeScreenDirty();
break;
}
@@ -2890,7 +2838,7 @@ struct BuyCompanyWindow : Window {
{
switch (widget) {
case WID_BC_NO:
delete this;
this->Close();
break;
case WID_BC_YES:

View File

@@ -23,7 +23,7 @@ void ShowCompanyFinances(CompanyID company);
void ShowCompany(CompanyID company);
void InvalidateCompanyWindows(const Company *c);
void DeleteCompanyWindows(CompanyID company);
void CloseCompanyWindows(CompanyID company);
void DirtyCompanyInfrastructureWindows(CompanyID company);
#endif /* COMPANY_GUI_H */

View File

@@ -24,8 +24,17 @@ static const uint ICON_TOKEN_COUNT = 20; ///< Maximum number of tokens in on
static const uint ICON_MAX_RECURSE = 10; ///< Maximum number of recursion
/* console parser */
IConsoleCmd *_iconsole_cmds; ///< list of registered commands
IConsoleAlias *_iconsole_aliases; ///< list of registered aliases
/* static */ IConsole::CommandList &IConsole::Commands()
{
static IConsole::CommandList cmds;
return cmds;
}
/* static */ IConsole::AliasList &IConsole::Aliases()
{
static IConsole::AliasList aliases;
return aliases;
}
FILE *_iconsole_output_file;
@@ -50,7 +59,7 @@ static void IConsoleWriteToLogFile(const char *string)
fwrite("\n", 1, 1, _iconsole_output_file) != 1) {
fclose(_iconsole_output_file);
_iconsole_output_file = nullptr;
IConsolePrintF(CC_DEFAULT, "cannot write to log file");
IConsolePrint(CC_ERROR, "Cannot write to console log file; closing the log file.");
}
}
}
@@ -58,7 +67,7 @@ static void IConsoleWriteToLogFile(const char *string)
bool CloseConsoleLogIfActive()
{
if (_iconsole_output_file != nullptr) {
IConsolePrintF(CC_DEFAULT, "file output complete");
IConsolePrint(CC_INFO, "Console log file closed.");
fclose(_iconsole_output_file);
_iconsole_output_file = nullptr;
return true;
@@ -79,14 +88,13 @@ void IConsoleFree()
* as well as to a logfile. If the network server is a dedicated server, all activities
* are also logged. All lines to print are added to a temporary buffer which can be
* used as a history to print them onscreen
* @param colour_code the colour of the command. Red in case of errors, etc.
* @param string the message entered or output on the console (notice, error, etc.)
* @param colour_code The colour of the command.
* @param string The message to output on the console (notice, error, etc.)
*/
void IConsolePrint(TextColour colour_code, const char *string)
void IConsolePrint(TextColour colour_code, const std::string &string)
{
assert(IsValidConsoleColour(colour_code));
char *str;
if (_redirect_console_to_client != INVALID_CLIENT_ID) {
/* Redirect the string to the client */
NetworkServerSendRcon(_redirect_console_to_client, colour_code, string);
@@ -100,9 +108,9 @@ void IConsolePrint(TextColour colour_code, const char *string)
/* Create a copy of the string, strip if of colours and invalid
* characters and (when applicable) assign it to the console buffer */
str = stredup(string);
char *str = stredup(string.c_str());
str_strip_colours(str);
str_validate(str, str + strlen(str));
StrMakeValidInPlace(str);
if (_network_dedicated) {
NetworkAdminConsole("console", str);
@@ -117,59 +125,6 @@ void IConsolePrint(TextColour colour_code, const char *string)
IConsoleGUIPrint(colour_code, str);
}
/**
* Handle the printing of text entered into the console or redirected there
* by any other means. Uses printf() style format, for more information look
* at IConsolePrint()
*/
void CDECL IConsolePrintF(TextColour colour_code, const char *format, ...)
{
assert(IsValidConsoleColour(colour_code));
va_list va;
char buf[ICON_MAX_STREAMSIZE];
va_start(va, format);
vseprintf(buf, lastof(buf), format, va);
va_end(va);
IConsolePrint(colour_code, buf);
}
/**
* It is possible to print debugging information to the console,
* which is achieved by using this function. Can only be used by
* debug() in debug.cpp. You need at least a level 2 (developer) for debugging
* messages to show up
* @param dbg debugging category
* @param string debugging message
*/
void IConsoleDebug(const char *dbg, const char *string)
{
if (_settings_client.gui.developer <= 1) return;
IConsolePrintF(CC_DEBUG, "dbg: [%s] %s", dbg, string);
}
/**
* It is possible to print warnings to the console. These are mostly
* errors or mishaps, but non-fatal. You need at least a level 1 (developer) for
* debugging messages to show up
*/
void IConsoleWarning(const char *string)
{
if (_settings_client.gui.developer == 0) return;
IConsolePrintF(CC_WARNING, "WARNING: %s", string);
}
/**
* It is possible to print error information to the console. This can include
* game errors, or errors in general you would want the user to notice
*/
void IConsoleError(const char *string)
{
IConsolePrintF(CC_ERROR, "ERROR: %s", string);
}
/**
* Change a string into its number representation. Supports
* decimal and hexadecimal numbers as well as 'on'/'off' 'true'/'false'
@@ -195,49 +150,13 @@ bool GetArgumentInteger(uint32 *value, const char *arg)
}
/**
* Add an item to an alphabetically sorted list.
* @param base first item of the list
* @param item_new the item to add
* Creates a copy of a string with underscores removed from it
* @param name String to remove the underscores from.
* @return A copy of \a name, without underscores.
*/
template<class T>
void IConsoleAddSorted(T **base, T *item_new)
static std::string RemoveUnderscores(std::string name)
{
if (*base == nullptr) {
*base = item_new;
return;
}
T *item_before = nullptr;
T *item = *base;
/* The list is alphabetically sorted, insert the new item at the correct location */
while (item != nullptr) {
if (strcmp(item->name, item_new->name) > 0) break; // insert here
item_before = item;
item = item->next;
}
if (item_before == nullptr) {
*base = item_new;
} else {
item_before->next = item_new;
}
item_new->next = item;
}
/**
* Remove underscores from a string; the string will be modified!
* @param[in,out] name String to remove the underscores from.
* @return \a name, with its contents modified.
*/
char *RemoveUnderscores(char *name)
{
char *q = name;
for (const char *p = name; *p != '\0'; p++) {
if (*p != '_') *q++ = *p;
}
*q = '\0';
name.erase(std::remove(name.begin(), name.end(), '_'), name.end());
return name;
}
@@ -246,15 +165,9 @@ char *RemoveUnderscores(char *name)
* @param name name of the command that will be used
* @param proc function that will be called upon execution of command
*/
void IConsoleCmdRegister(const char *name, IConsoleCmdProc *proc, IConsoleHook *hook)
/* static */ void IConsole::CmdRegister(const std::string &name, IConsoleCmdProc *proc, IConsoleHook *hook)
{
IConsoleCmd *item_new = MallocT<IConsoleCmd>(1);
item_new->name = RemoveUnderscores(stredup(name));
item_new->next = nullptr;
item_new->proc = proc;
item_new->hook = hook;
IConsoleAddSorted(&_iconsole_cmds, item_new);
IConsole::Commands().try_emplace(RemoveUnderscores(name), name, proc, hook);
}
/**
@@ -262,13 +175,10 @@ void IConsoleCmdRegister(const char *name, IConsoleCmdProc *proc, IConsoleHook *
* @param name command to be found
* @return return Cmdstruct of the found command, or nullptr on failure
*/
IConsoleCmd *IConsoleCmdGet(const char *name)
/* static */ IConsoleCmd *IConsole::CmdGet(const std::string &name)
{
IConsoleCmd *item;
for (item = _iconsole_cmds; item != nullptr; item = item->next) {
if (strcmp(item->name, name) == 0) return item;
}
auto item = IConsole::Commands().find(RemoveUnderscores(name));
if (item != IConsole::Commands().end()) return &item->second;
return nullptr;
}
@@ -277,22 +187,10 @@ IConsoleCmd *IConsoleCmdGet(const char *name)
* @param name name of the alias that will be used
* @param cmd name of the command that 'name' will be alias of
*/
void IConsoleAliasRegister(const char *name, const char *cmd)
/* static */ void IConsole::AliasRegister(const std::string &name, const std::string &cmd)
{
if (IConsoleAliasGet(name) != nullptr) {
IConsoleError("an alias with this name already exists; insertion aborted");
return;
}
char *new_alias = RemoveUnderscores(stredup(name));
char *cmd_aliased = stredup(cmd);
IConsoleAlias *item_new = MallocT<IConsoleAlias>(1);
item_new->next = nullptr;
item_new->cmdline = cmd_aliased;
item_new->name = new_alias;
IConsoleAddSorted(&_iconsole_aliases, item_new);
auto result = IConsole::Aliases().try_emplace(RemoveUnderscores(name), name, cmd);
if (!result.second) IConsolePrint(CC_ERROR, "An alias with the name '{}' already exists.", name);
}
/**
@@ -300,16 +198,13 @@ void IConsoleAliasRegister(const char *name, const char *cmd)
* @param name alias to be found
* @return return Aliasstruct of the found alias, or nullptr on failure
*/
IConsoleAlias *IConsoleAliasGet(const char *name)
/* static */ IConsoleAlias *IConsole::AliasGet(const std::string &name)
{
IConsoleAlias *item;
for (item = _iconsole_aliases; item != nullptr; item = item->next) {
if (strcmp(item->name, name) == 0) return item;
}
auto item = IConsole::Aliases().find(RemoveUnderscores(name));
if (item != IConsole::Aliases().end()) return &item->second;
return nullptr;
}
/**
* An alias is just another name for a command, or for more commands
* Execute it as well.
@@ -322,14 +217,14 @@ static void IConsoleAliasExec(const IConsoleAlias *alias, byte tokencount, char
char alias_buffer[ICON_MAX_STREAMSIZE] = { '\0' };
char *alias_stream = alias_buffer;
DEBUG(console, 6, "Requested command is an alias; parsing...");
Debug(console, 6, "Requested command is an alias; parsing...");
if (recurse_count > ICON_MAX_RECURSE) {
IConsoleError("Too many alias expansions, recursion limit reached. Aborting");
IConsolePrint(CC_ERROR, "Too many alias expansions, recursion limit reached.");
return;
}
for (const char *cmdptr = alias->cmdline; *cmdptr != '\0'; cmdptr++) {
for (const char *cmdptr = alias->cmdline.c_str(); *cmdptr != '\0'; cmdptr++) {
switch (*cmdptr) {
case '\'': // ' will double for ""
alias_stream = strecpy(alias_stream, "\"", lastof(alias_buffer));
@@ -371,8 +266,8 @@ static void IConsoleAliasExec(const IConsoleAlias *alias, byte tokencount, char
int param = *cmdptr - 'A';
if (param < 0 || param >= tokencount) {
IConsoleError("too many or wrong amount of parameters passed to alias, aborting");
IConsolePrintF(CC_WARNING, "Usage of alias '%s': %s", alias->name, alias->cmdline);
IConsolePrint(CC_ERROR, "Too many or wrong amount of parameters passed to alias.");
IConsolePrint(CC_HELP, "Usage of alias '{}': '{}'.", alias->name, alias->cmdline);
return;
}
@@ -391,7 +286,7 @@ static void IConsoleAliasExec(const IConsoleAlias *alias, byte tokencount, char
}
if (alias_stream >= lastof(alias_buffer) - 1) {
IConsoleError("Requested alias execution would overflow execution buffer");
IConsolePrint(CC_ERROR, "Requested alias execution would overflow execution buffer.");
return;
}
}
@@ -417,13 +312,12 @@ void IConsoleCmdExec(const char *cmdstr, const uint recurse_count)
for (cmdptr = cmdstr; *cmdptr != '\0'; cmdptr++) {
if (!IsValidChar(*cmdptr, CS_ALPHANUMERAL)) {
IConsoleError("command contains malformed characters, aborting");
IConsolePrintF(CC_ERROR, "ERROR: command was: '%s'", cmdstr);
IConsolePrint(CC_ERROR, "Command '{}' contains malformed characters.", cmdstr);
return;
}
}
DEBUG(console, 4, "Executing cmdline: '%s'", cmdstr);
Debug(console, 4, "Executing cmdline: '{}'", cmdstr);
memset(&tokens, 0, sizeof(tokens));
memset(&tokenstream, 0, sizeof(tokenstream));
@@ -433,7 +327,7 @@ void IConsoleCmdExec(const char *cmdstr, const uint recurse_count)
* of characters in our stream or the max amount of tokens we can handle */
for (cmdptr = cmdstr, t_index = 0, tstream_i = 0; *cmdptr != '\0'; cmdptr++) {
if (tstream_i >= lengthof(tokenstream)) {
IConsoleError("command line too long");
IConsolePrint(CC_ERROR, "Command line too long.");
return;
}
@@ -454,7 +348,7 @@ void IConsoleCmdExec(const char *cmdstr, const uint recurse_count)
longtoken = !longtoken;
if (!foundtoken) {
if (t_index >= lengthof(tokens)) {
IConsoleError("command line too long");
IConsolePrint(CC_ERROR, "Command line too long.");
return;
}
tokens[t_index++] = &tokenstream[tstream_i];
@@ -472,7 +366,7 @@ void IConsoleCmdExec(const char *cmdstr, const uint recurse_count)
if (!foundtoken) {
if (t_index >= lengthof(tokens)) {
IConsoleError("command line too long");
IConsolePrint(CC_ERROR, "Command line too long.");
return;
}
tokens[t_index++] = &tokenstream[tstream_i - 1];
@@ -483,7 +377,7 @@ void IConsoleCmdExec(const char *cmdstr, const uint recurse_count)
}
for (uint i = 0; i < lengthof(tokens) && tokens[i] != nullptr; i++) {
DEBUG(console, 8, "Token %d is: '%s'", i, tokens[i]);
Debug(console, 8, "Token {} is: '{}'", i, tokens[i]);
}
if (StrEmpty(tokens[0])) return; // don't execute empty commands
@@ -491,8 +385,7 @@ void IConsoleCmdExec(const char *cmdstr, const uint recurse_count)
* First try commands, then aliases. Execute
* the found action taking into account its hooking code
*/
RemoveUnderscores(tokens[0]);
IConsoleCmd *cmd = IConsoleCmdGet(tokens[0]);
IConsoleCmd *cmd = IConsole::CmdGet(tokens[0]);
if (cmd != nullptr) {
ConsoleHookResult chr = (cmd->hook == nullptr ? CHR_ALLOW : cmd->hook(true));
switch (chr) {
@@ -508,11 +401,11 @@ void IConsoleCmdExec(const char *cmdstr, const uint recurse_count)
}
t_index--;
IConsoleAlias *alias = IConsoleAliasGet(tokens[0]);
IConsoleAlias *alias = IConsole::AliasGet(tokens[0]);
if (alias != nullptr) {
IConsoleAliasExec(alias, t_index, &tokens[1], recurse_count + 1);
return;
}
IConsoleError("command not found");
IConsolePrint(CC_ERROR, "Command '{}' not found.", tokens[0]);
}

File diff suppressed because it is too large Load Diff

View File

@@ -11,6 +11,7 @@
#define CONSOLE_FUNC_H
#include "console_type.h"
#include "3rdparty/fmt/format.h"
/* console modes */
extern IConsoleModes _iconsole_mode;
@@ -21,11 +22,29 @@ void IConsoleFree();
void IConsoleClose();
/* console output */
void IConsolePrint(TextColour colour_code, const char *string);
void CDECL IConsolePrintF(TextColour colour_code, const char *format, ...) WARN_FORMAT(2, 3);
void IConsoleDebug(const char *dbg, const char *string);
void IConsoleWarning(const char *string);
void IConsoleError(const char *string);
void IConsolePrint(TextColour colour_code, const std::string &string);
/**
* Handle the printing of text entered into the console or redirected there
* by any other means. Text can be redirected to other clients in a network game
* as well as to a logfile. If the network server is a dedicated server, all activities
* are also logged. All lines to print are added to a temporary buffer which can be
* used as a history to print them onscreen
* @param colour_code The colour of the command.
* @param format_string The formatting string to tell what to do with the remaining arguments.
* @param first_arg The first argument to the format.
* @param other_args The other arguments to the format.
* @tparam T The type of formatting parameter.
* @tparam A The type of the first argument.
* @tparam Args The types of the other arguments.
*/
template <typename T, typename A, typename ... Args>
static inline void IConsolePrint(TextColour colour_code, const T &format, A first_arg, Args&&... other_args)
{
/* The separate first_arg argument is added to aid overloading.
* Otherwise the calls that do no need formatting will still use this function. */
IConsolePrint(colour_code, fmt::format(format, first_arg, other_args...));
}
/* Parser */
void IConsoleCmdExec(const char *cmdstr, const uint recurse_count = 0);

View File

@@ -185,10 +185,11 @@ struct IConsoleWindow : Window
ResizeWindow(this, _screen.width, _screen.height / 3);
}
~IConsoleWindow()
void Close() override
{
_iconsole_mode = ICONSOLE_CLOSED;
VideoDriver::GetInstance()->EditBoxLostFocus();
this->Window::Close();
}
/**
@@ -286,7 +287,7 @@ struct IConsoleWindow : Window
/* We always want the ] at the left side; we always force these strings to be left
* aligned anyway. So enforce this in all cases by adding a left-to-right marker,
* otherwise it will be drawn at the wrong side with right-to-left texts. */
IConsolePrintF(CC_COMMAND, LRM "] %s", _iconsole_cmdline.buf);
IConsolePrint(CC_COMMAND, LRM "] {}", _iconsole_cmdline.buf);
const char *cmd = IConsoleHistoryAdd(_iconsole_cmdline.buf);
IConsoleClearCommand();
@@ -398,10 +399,10 @@ void IConsoleGUIInit()
IConsoleLine::Reset();
memset(_iconsole_history, 0, sizeof(_iconsole_history));
IConsolePrintF(CC_WARNING, "OpenTTD Game Console Revision 7 - %s", _openttd_revision);
IConsolePrint(CC_WHITE, "------------------------------------");
IConsolePrint(CC_WHITE, "use \"help\" for more information");
IConsolePrint(CC_WHITE, "");
IConsolePrint(TC_LIGHT_BLUE, "OpenTTD Game Console Revision 7 - {}", _openttd_revision);
IConsolePrint(CC_WHITE, "------------------------------------");
IConsolePrint(CC_WHITE, "use \"help\" for more information.");
IConsolePrint(CC_WHITE, "");
IConsoleClearCommand();
}
@@ -442,7 +443,7 @@ void IConsoleSwitch()
break;
case ICONSOLE_OPENED: case ICONSOLE_FULL:
DeleteWindowById(WC_CONSOLE, 0);
CloseWindowById(WC_CONSOLE, 0);
break;
}

View File

@@ -11,6 +11,7 @@
#define CONSOLE_INTERNAL_H
#include "gfx_type.h"
#include <map>
static const uint ICON_CMDLN_SIZE = 1024; ///< maximum length of a typed in command
static const uint ICON_MAX_STREAMSIZE = 2048; ///< maximum length of a totally expanded command
@@ -28,14 +29,14 @@ enum ConsoleHookResult {
* effect they produce are carried out. The arguments to the commands
* are given to them, each input word separated by a double-quote (") is an argument
* If you want to handle multiple words as one, enclose them in double-quotes
* eg. 'say "hello sexy boy"'
* eg. 'say "hello everybody"'
*/
typedef bool IConsoleCmdProc(byte argc, char *argv[]);
typedef ConsoleHookResult IConsoleHook(bool echo);
struct IConsoleCmd {
char *name; ///< name of command
IConsoleCmd *next; ///< next command in list
IConsoleCmd(const std::string &name, IConsoleCmdProc *proc, IConsoleHook *hook) : name(name), proc(proc), hook(hook) {}
std::string name; ///< name of command
IConsoleCmdProc *proc; ///< process executed when command is typed
IConsoleHook *hook; ///< any special trigger action that needs executing
};
@@ -53,25 +54,31 @@ struct IConsoleCmd {
* - ";" allows for combining commands (see example 'ng')
*/
struct IConsoleAlias {
char *name; ///< name of the alias
IConsoleAlias *next; ///< next alias in list
IConsoleAlias(const std::string &name, const std::string &cmdline) : name(name), cmdline(cmdline) {}
char *cmdline; ///< command(s) that is/are being aliased
std::string name; ///< name of the alias
std::string cmdline; ///< command(s) that is/are being aliased
};
/* console parser */
extern IConsoleCmd *_iconsole_cmds; ///< List of registered commands.
extern IConsoleAlias *_iconsole_aliases; ///< List of registered aliases.
struct IConsole
{
typedef std::map<std::string, IConsoleCmd> CommandList;
typedef std::map<std::string, IConsoleAlias> AliasList;
/* console parser */
static CommandList &Commands();
static AliasList &Aliases();
/* Commands */
static void CmdRegister(const std::string &name, IConsoleCmdProc *proc, IConsoleHook *hook = nullptr);
static IConsoleCmd *CmdGet(const std::string &name);
static void AliasRegister(const std::string &name, const std::string &cmd);
static IConsoleAlias *AliasGet(const std::string &name);
};
/* console functions */
void IConsoleClearBuffer();
/* Commands */
void IConsoleCmdRegister(const char *name, IConsoleCmdProc *proc, IConsoleHook *hook = nullptr);
void IConsoleAliasRegister(const char *name, const char *cmd);
IConsoleCmd *IConsoleCmdGet(const char *name);
IConsoleAlias *IConsoleAliasGet(const char *name);
/* console std lib (register ingame commands/aliases) */
void IConsoleStdLibRegister();
@@ -81,6 +88,5 @@ bool GetArgumentInteger(uint32 *value, const char *arg);
void IConsoleGUIInit();
void IConsoleGUIFree();
void IConsoleGUIPrint(TextColour colour_code, char *string);
char *RemoveUnderscores(char *name);
#endif /* CONSOLE_INTERNAL_H */

View File

@@ -23,6 +23,7 @@ enum IConsoleModes {
static const TextColour CC_DEFAULT = TC_SILVER; ///< Default colour of the console.
static const TextColour CC_ERROR = TC_RED; ///< Colour for error lines.
static const TextColour CC_WARNING = TC_LIGHT_BLUE; ///< Colour for warning lines.
static const TextColour CC_HELP = TC_LIGHT_BLUE; ///< Colour for help lines.
static const TextColour CC_INFO = TC_YELLOW; ///< Colour for information lines.
static const TextColour CC_DEBUG = TC_LIGHT_BROWN; ///< Colour for debug output.
static const TextColour CC_COMMAND = TC_GOLD; ///< Colour for the console's commands.

View File

@@ -51,7 +51,7 @@ struct Backup {
{
/* We cannot assert here, as missing restoration is 'normal' when exceptions are thrown.
* Exceptions are especially used to abort world generation. */
DEBUG(misc, 0, "%s:%d: Backed-up value was not restored!", this->file, this->line);
Debug(misc, 0, "{}:{}: Backed-up value was not restored!", this->file, this->line);
this->Restore();
}
}

View File

@@ -320,45 +320,55 @@ static inline T ROR(const T x, const uint8 n)
return (T)(x >> n | x << (sizeof(x) * 8 - n));
}
/**
* Do an operation for each set bit in a value.
*
* This macros is used to do an operation for each set
* bit in a variable. The second parameter is a
* variable that is used as the bit position counter.
* The fourth parameter is an expression of the bits
* we need to iterate over. This expression will be
* evaluated once.
*
* @param Tbitpos_type Type of the position counter variable.
* @param bitpos_var The position counter variable.
* @param Tbitset_type Type of the bitset value.
* @param bitset_value The bitset value which we check for bits.
*
* @see FOR_EACH_SET_BIT
*/
#define FOR_EACH_SET_BIT_EX(Tbitpos_type, bitpos_var, Tbitset_type, bitset_value) \
for ( \
Tbitset_type ___FESBE_bits = (bitpos_var = (Tbitpos_type)0, bitset_value); \
___FESBE_bits != (Tbitset_type)0; \
___FESBE_bits = (Tbitset_type)(___FESBE_bits >> 1), bitpos_var++ \
) \
if ((___FESBE_bits & 1) != 0)
/**
* Iterable ensemble of each set bit in a value.
* @tparam Tbitpos Type of the position variable.
* @tparam Tbitset Type of the bitset value.
*/
template <typename Tbitpos = uint, typename Tbitset = uint>
struct SetBitIterator {
struct Iterator {
typedef Tbitpos value_type;
typedef value_type *pointer;
typedef value_type &reference;
typedef size_t difference_type;
typedef std::forward_iterator_tag iterator_category;
/**
* Do an operation for each set set bit in a value.
*
* This macros is used to do an operation for each set
* bit in a variable. The first parameter is a variable
* that is used as the bit position counter.
* The second parameter is an expression of the bits
* we need to iterate over. This expression will be
* evaluated once.
*
* @param bitpos_var The position counter variable.
* @param bitset_value The value which we check for set bits.
*/
#define FOR_EACH_SET_BIT(bitpos_var, bitset_value) FOR_EACH_SET_BIT_EX(uint, bitpos_var, uint, bitset_value)
explicit Iterator(Tbitset bitset) : bitset(bitset), bitpos(static_cast<Tbitpos>(0))
{
this->Validate();
}
bool operator==(const Iterator &other) const
{
return this->bitset == other.bitset && (this->bitset == 0 || this->bitpos == other.bitpos);
}
bool operator!=(const Iterator &other) const { return !(*this == other); }
Tbitpos operator*() const { return this->bitpos; }
Iterator & operator++() { this->Next(); this->Validate(); return *this; }
private:
Tbitset bitset;
Tbitpos bitpos;
void Validate()
{
while (this->bitset != 0 && (this->bitset & 1) == 0) this->Next();
}
void Next()
{
this->bitset = static_cast<Tbitset>(this->bitset >> 1);
this->bitpos++;
}
};
SetBitIterator(Tbitset bitset) : bitset(bitset) {}
Iterator begin() { return Iterator(this->bitset); }
Iterator end() { return Iterator(static_cast<Tbitset>(0)); }
bool empty() { return this->begin() == this->end(); }
private:
Tbitset bitset;
};
#if defined(__APPLE__)
/* Make endian swapping use Apple's macros to increase speed

View File

@@ -62,10 +62,4 @@ struct PointDimension {
int height;
};
/** A pair of two integers */
struct Pair {
int a;
int b;
};
#endif /* GEOMETRY_TYPE_HPP */

View File

@@ -274,7 +274,7 @@ class Kdtree {
}
template <typename Outputter>
void FindContainedRecursive(CoordT p1[2], CoordT p2[2], size_t node_idx, int level, Outputter outputter) const
void FindContainedRecursive(CoordT p1[2], CoordT p2[2], size_t node_idx, int level, const Outputter &outputter) const
{
/* Dimension index of current level */
int dim = level % 2;
@@ -458,7 +458,7 @@ public:
* @param outputter Callback used to return values from the search.
*/
template <typename Outputter>
void FindContained(CoordT x1, CoordT y1, CoordT x2, CoordT y2, Outputter outputter) const
void FindContained(CoordT x1, CoordT y1, CoordT x2, CoordT y2, const Outputter &outputter) const
{
assert(x1 < x2);
assert(y1 < y2);

View File

@@ -12,60 +12,97 @@
#include "math_func.hpp"
#include <limits>
#ifdef __has_builtin
# if __has_builtin(__builtin_add_overflow) && __has_builtin(__builtin_sub_overflow) && __has_builtin(__builtin_mul_overflow)
# define HAS_OVERFLOW_BUILTINS
# endif
#endif
/**
* Overflow safe template for integers, i.e. integers that will never overflow
* you multiply the maximum value with 2, or add 2, or subtract something from
* the minimum value, etc.
* @param T the type these integers are stored with.
* @param T_MAX the maximum value for the integers.
* @param T_MIN the minimum value for the integers.
*/
template <class T, T T_MAX, T T_MIN>
template <class T>
class OverflowSafeInt
{
private:
static constexpr T T_MAX = std::numeric_limits<T>::max();
static constexpr T T_MIN = std::numeric_limits<T>::min();
/** The non-overflow safe backend to store the value in. */
T m_value;
public:
OverflowSafeInt() : m_value(0) { }
constexpr OverflowSafeInt() : m_value(0) { }
OverflowSafeInt(const OverflowSafeInt& other) { this->m_value = other.m_value; }
OverflowSafeInt(const int64 int_) { this->m_value = int_; }
constexpr OverflowSafeInt(const OverflowSafeInt& other) : m_value(other.m_value) { }
constexpr OverflowSafeInt(const int64 int_) : m_value(int_) { }
inline OverflowSafeInt& operator = (const OverflowSafeInt& other) { this->m_value = other.m_value; return *this; }
inline constexpr OverflowSafeInt& operator = (const OverflowSafeInt& other) { this->m_value = other.m_value; return *this; }
inline OverflowSafeInt operator - () const { return OverflowSafeInt(-this->m_value); }
inline constexpr OverflowSafeInt operator - () const { return OverflowSafeInt(this->m_value == T_MIN ? T_MAX : -this->m_value); }
/**
* Safe implementation of addition.
* @param other the amount to add
* @note when the addition would yield more than T_MAX (or less than T_MIN),
* it will be T_MAX (respectively T_MIN).
* @note when the addition would yield more than T_MAX, it will be T_MAX.
*/
inline OverflowSafeInt& operator += (const OverflowSafeInt& other)
inline constexpr OverflowSafeInt& operator += (const OverflowSafeInt& other)
{
if ((T_MAX - abs(other.m_value)) < abs(this->m_value) &&
(this->m_value < 0) == (other.m_value < 0)) {
this->m_value = (this->m_value < 0) ? T_MIN : T_MAX ;
#ifdef HAS_OVERFLOW_BUILTINS
if (unlikely(__builtin_add_overflow(this->m_value, other.m_value, &this->m_value))) {
this->m_value = (other.m_value < 0) ? T_MIN : T_MAX;
}
#else
if (this->m_value > 0 && other.m_value > 0 && (T_MAX - other.m_value) < this->m_value) {
this->m_value = T_MAX;
} else if (this->m_value < 0 && other.m_value < 0 && (this->m_value == T_MIN || other.m_value == T_MIN || ((T_MAX + this->m_value) + other.m_value < (T_MIN + T_MAX)))) {
this->m_value = T_MIN;
} else {
this->m_value += other.m_value;
}
#endif
return *this;
}
/* Operators for addition and subtraction */
inline OverflowSafeInt operator + (const OverflowSafeInt& other) const { OverflowSafeInt result = *this; result += other; return result; }
inline OverflowSafeInt operator + (const int other) const { OverflowSafeInt result = *this; result += (int64)other; return result; }
inline OverflowSafeInt operator + (const uint other) const { OverflowSafeInt result = *this; result += (int64)other; return result; }
inline OverflowSafeInt& operator -= (const OverflowSafeInt& other) { return *this += (-other); }
inline OverflowSafeInt operator - (const OverflowSafeInt& other) const { OverflowSafeInt result = *this; result -= other; return result; }
inline OverflowSafeInt operator - (const int other) const { OverflowSafeInt result = *this; result -= (int64)other; return result; }
inline OverflowSafeInt operator - (const uint other) const { OverflowSafeInt result = *this; result -= (int64)other; return result; }
/**
* Safe implementation of subtraction.
* @param other the amount to subtract
* @note when the subtraction would yield less than T_MIN, it will be T_MIN.
*/
inline constexpr OverflowSafeInt& operator -= (const OverflowSafeInt& other)
{
#ifdef HAS_OVERFLOW_BUILTINS
if (unlikely(__builtin_sub_overflow(this->m_value, other.m_value, &this->m_value))) {
this->m_value = (other.m_value < 0) ? T_MAX : T_MIN;
}
#else
if (this->m_value > 0 && other.m_value < 0 && (T_MAX + other.m_value) < this->m_value) {
this->m_value = T_MAX;
} else if (this->m_value < 0 && other.m_value > 0 && (T_MAX + this->m_value) < (T_MIN + T_MAX) + other.m_value) {
this->m_value = T_MIN;
} else {
this->m_value -= other.m_value;
}
#endif
return *this;
}
inline OverflowSafeInt& operator ++ () { return *this += 1; }
inline OverflowSafeInt& operator -- () { return *this += -1; }
inline OverflowSafeInt operator ++ (int) { OverflowSafeInt org = *this; *this += 1; return org; }
inline OverflowSafeInt operator -- (int) { OverflowSafeInt org = *this; *this += -1; return org; }
/* Operators for addition and subtraction. */
inline constexpr OverflowSafeInt operator + (const OverflowSafeInt& other) const { OverflowSafeInt result = *this; result += other; return result; }
inline constexpr OverflowSafeInt operator + (const int other) const { OverflowSafeInt result = *this; result += (int64)other; return result; }
inline constexpr OverflowSafeInt operator + (const uint other) const { OverflowSafeInt result = *this; result += (int64)other; return result; }
inline constexpr OverflowSafeInt operator - (const OverflowSafeInt& other) const { OverflowSafeInt result = *this; result -= other; return result; }
inline constexpr OverflowSafeInt operator - (const int other) const { OverflowSafeInt result = *this; result -= (int64)other; return result; }
inline constexpr OverflowSafeInt operator - (const uint other) const { OverflowSafeInt result = *this; result -= (int64)other; return result; }
inline constexpr OverflowSafeInt& operator ++ () { return *this += 1; }
inline constexpr OverflowSafeInt& operator -- () { return *this += -1; }
inline constexpr OverflowSafeInt operator ++ (int) { OverflowSafeInt org = *this; *this += 1; return org; }
inline constexpr OverflowSafeInt operator -- (int) { OverflowSafeInt org = *this; *this += -1; return org; }
/**
* Safe implementation of multiplication.
@@ -73,83 +110,107 @@ public:
* @note when the multiplication would yield more than T_MAX (or less than T_MIN),
* it will be T_MAX (respectively T_MIN).
*/
inline OverflowSafeInt& operator *= (const int factor)
inline constexpr OverflowSafeInt& operator *= (const int factor)
{
if (factor != 0 && (T_MAX / abs(factor)) < abs(this->m_value)) {
this->m_value = ((this->m_value < 0) == (factor < 0)) ? T_MAX : T_MIN ;
} else {
this->m_value *= factor ;
#ifdef HAS_OVERFLOW_BUILTINS
const bool is_result_positive = (this->m_value < 0) == (factor < 0); // -ve * -ve == +ve
if (unlikely(__builtin_mul_overflow(this->m_value, factor, &this->m_value))) {
this->m_value = is_result_positive ? T_MAX : T_MIN;
}
#else
if (factor == -1) {
this->m_value = (this->m_value == T_MIN) ? T_MAX : -this->m_value;
} else if (factor > 0 && this->m_value > 0 && (T_MAX / factor) < this->m_value) {
this->m_value = T_MAX;
} else if (factor > 0 && this->m_value < 0 && (T_MIN / factor) > this->m_value) {
this->m_value = T_MIN;
} else if (factor < 0 && this->m_value > 0 && (T_MIN / factor) < this->m_value) {
this->m_value = T_MIN;
} else if (factor < 0 && this->m_value < 0 && (T_MAX / factor) > this->m_value) {
this->m_value = T_MAX;
} else {
this->m_value *= factor;
}
#endif
return *this;
}
/* Operators for multiplication */
inline OverflowSafeInt operator * (const int64 factor) const { OverflowSafeInt result = *this; result *= factor; return result; }
inline OverflowSafeInt operator * (const int factor) const { OverflowSafeInt result = *this; result *= (int64)factor; return result; }
inline OverflowSafeInt operator * (const uint factor) const { OverflowSafeInt result = *this; result *= (int64)factor; return result; }
inline OverflowSafeInt operator * (const uint16 factor) const { OverflowSafeInt result = *this; result *= (int64)factor; return result; }
inline OverflowSafeInt operator * (const byte factor) const { OverflowSafeInt result = *this; result *= (int64)factor; return result; }
/* Operators for multiplication. */
inline constexpr OverflowSafeInt operator * (const int64 factor) const { OverflowSafeInt result = *this; result *= factor; return result; }
inline constexpr OverflowSafeInt operator * (const int factor) const { OverflowSafeInt result = *this; result *= (int64)factor; return result; }
inline constexpr OverflowSafeInt operator * (const uint factor) const { OverflowSafeInt result = *this; result *= (int64)factor; return result; }
inline constexpr OverflowSafeInt operator * (const uint16 factor) const { OverflowSafeInt result = *this; result *= (int64)factor; return result; }
inline constexpr OverflowSafeInt operator * (const byte factor) const { OverflowSafeInt result = *this; result *= (int64)factor; return result; }
/* Operators for division */
inline OverflowSafeInt& operator /= (const int64 divisor) { this->m_value /= divisor; return *this; }
inline OverflowSafeInt operator / (const OverflowSafeInt& divisor) const { OverflowSafeInt result = *this; result /= divisor.m_value; return result; }
inline OverflowSafeInt operator / (const int divisor) const { OverflowSafeInt result = *this; result /= divisor; return result; }
inline OverflowSafeInt operator / (const uint divisor) const { OverflowSafeInt result = *this; result /= (int)divisor; return result; }
/* Operators for division. */
inline constexpr OverflowSafeInt& operator /= (const int64 divisor) { this->m_value /= divisor; return *this; }
inline constexpr OverflowSafeInt operator / (const OverflowSafeInt& divisor) const { OverflowSafeInt result = *this; result /= divisor.m_value; return result; }
inline constexpr OverflowSafeInt operator / (const int divisor) const { OverflowSafeInt result = *this; result /= divisor; return result; }
inline constexpr OverflowSafeInt operator / (const uint divisor) const { OverflowSafeInt result = *this; result /= (int)divisor; return result; }
/* Operators for modulo */
inline OverflowSafeInt& operator %= (const int divisor) { this->m_value %= divisor; return *this; }
inline OverflowSafeInt operator % (const int divisor) const { OverflowSafeInt result = *this; result %= divisor; return result; }
inline constexpr OverflowSafeInt& operator %= (const int divisor) { this->m_value %= divisor; return *this; }
inline constexpr OverflowSafeInt operator % (const int divisor) const { OverflowSafeInt result = *this; result %= divisor; return result; }
/* Operators for shifting */
inline OverflowSafeInt& operator <<= (const int shift) { this->m_value <<= shift; return *this; }
inline OverflowSafeInt operator << (const int shift) const { OverflowSafeInt result = *this; result <<= shift; return result; }
inline OverflowSafeInt& operator >>= (const int shift) { this->m_value >>= shift; return *this; }
inline OverflowSafeInt operator >> (const int shift) const { OverflowSafeInt result = *this; result >>= shift; return result; }
/* Operators for shifting. */
inline constexpr OverflowSafeInt& operator <<= (const int shift) { this->m_value <<= shift; return *this; }
inline constexpr OverflowSafeInt operator << (const int shift) const { OverflowSafeInt result = *this; result <<= shift; return result; }
inline constexpr OverflowSafeInt& operator >>= (const int shift) { this->m_value >>= shift; return *this; }
inline constexpr OverflowSafeInt operator >> (const int shift) const { OverflowSafeInt result = *this; result >>= shift; return result; }
/* Operators for (in)equality when comparing overflow safe ints */
inline bool operator == (const OverflowSafeInt& other) const { return this->m_value == other.m_value; }
inline bool operator != (const OverflowSafeInt& other) const { return !(*this == other); }
inline bool operator > (const OverflowSafeInt& other) const { return this->m_value > other.m_value; }
inline bool operator >= (const OverflowSafeInt& other) const { return this->m_value >= other.m_value; }
inline bool operator < (const OverflowSafeInt& other) const { return !(*this >= other); }
inline bool operator <= (const OverflowSafeInt& other) const { return !(*this > other); }
/* Operators for (in)equality when comparing overflow safe ints. */
inline constexpr bool operator == (const OverflowSafeInt& other) const { return this->m_value == other.m_value; }
inline constexpr bool operator != (const OverflowSafeInt& other) const { return !(*this == other); }
inline constexpr bool operator > (const OverflowSafeInt& other) const { return this->m_value > other.m_value; }
inline constexpr bool operator >= (const OverflowSafeInt& other) const { return this->m_value >= other.m_value; }
inline constexpr bool operator < (const OverflowSafeInt& other) const { return !(*this >= other); }
inline constexpr bool operator <= (const OverflowSafeInt& other) const { return !(*this > other); }
/* Operators for (in)equality when comparing non-overflow safe ints */
inline bool operator == (const int other) const { return this->m_value == other; }
inline bool operator != (const int other) const { return !(*this == other); }
inline bool operator > (const int other) const { return this->m_value > other; }
inline bool operator >= (const int other) const { return this->m_value >= other; }
inline bool operator < (const int other) const { return !(*this >= other); }
inline bool operator <= (const int other) const { return !(*this > other); }
/* Operators for (in)equality when comparing non-overflow safe ints. */
inline constexpr bool operator == (const int other) const { return this->m_value == other; }
inline constexpr bool operator != (const int other) const { return !(*this == other); }
inline constexpr bool operator > (const int other) const { return this->m_value > other; }
inline constexpr bool operator >= (const int other) const { return this->m_value >= other; }
inline constexpr bool operator < (const int other) const { return !(*this >= other); }
inline constexpr bool operator <= (const int other) const { return !(*this > other); }
inline operator int64 () const { return this->m_value; }
inline constexpr operator int64 () const { return this->m_value; }
};
/* Sometimes we got int64 operator OverflowSafeInt instead of vice versa. Handle that properly */
template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator + (int64 a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return b + a; }
template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator - (int64 a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return -b + a; }
template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator * (int64 a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return b * a; }
template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator / (int64 a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return (OverflowSafeInt<T, T_MAX, T_MIN>)a / (int)b; }
/* Sometimes we got int operator OverflowSafeInt instead of vice versa. Handle that properly */
template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator + (int a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return b + a; }
template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator - (int a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return -b + a; }
template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator * (int a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return b * a; }
template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator / (int a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return (OverflowSafeInt<T, T_MAX, T_MIN>)a / (int)b; }
/* Sometimes we got int64 operator OverflowSafeInt instead of vice versa. Handle that properly. */
template <class T> inline constexpr OverflowSafeInt<T> operator + (const int64 a, const OverflowSafeInt<T> b) { return b + a; }
template <class T> inline constexpr OverflowSafeInt<T> operator - (const int64 a, const OverflowSafeInt<T> b) { return -b + a; }
template <class T> inline constexpr OverflowSafeInt<T> operator * (const int64 a, const OverflowSafeInt<T> b) { return b * a; }
template <class T> inline constexpr OverflowSafeInt<T> operator / (const int64 a, const OverflowSafeInt<T> b) { return (OverflowSafeInt<T>)a / (int)b; }
/* Sometimes we got uint operator OverflowSafeInt instead of vice versa. Handle that properly */
template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator + (uint a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return b + a; }
template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator - (uint a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return -b + a; }
template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator * (uint a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return b * a; }
template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator / (uint a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return (OverflowSafeInt<T, T_MAX, T_MIN>)a / (int)b; }
/* Sometimes we got int operator OverflowSafeInt instead of vice versa. Handle that properly. */
template <class T> inline constexpr OverflowSafeInt<T> operator + (const int a, const OverflowSafeInt<T> b) { return b + a; }
template <class T> inline constexpr OverflowSafeInt<T> operator - (const int a, const OverflowSafeInt<T> b) { return -b + a; }
template <class T> inline constexpr OverflowSafeInt<T> operator * (const int a, const OverflowSafeInt<T> b) { return b * a; }
template <class T> inline constexpr OverflowSafeInt<T> operator / (const int a, const OverflowSafeInt<T> b) { return (OverflowSafeInt<T>)a / (int)b; }
/* Sometimes we got byte operator OverflowSafeInt instead of vice versa. Handle that properly */
template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator + (byte a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return b + (uint)a; }
template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator - (byte a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return -b + (uint)a; }
template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator * (byte a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return b * (uint)a; }
template <class T, int64 T_MAX, int64 T_MIN> inline OverflowSafeInt<T, T_MAX, T_MIN> operator / (byte a, OverflowSafeInt<T, T_MAX, T_MIN> b) { return (OverflowSafeInt<T, T_MAX, T_MIN>)a / (int)b; }
/* Sometimes we got uint operator OverflowSafeInt instead of vice versa. Handle that properly. */
template <class T> inline constexpr OverflowSafeInt<T> operator + (const uint a, const OverflowSafeInt<T> b) { return b + a; }
template <class T> inline constexpr OverflowSafeInt<T> operator - (const uint a, const OverflowSafeInt<T> b) { return -b + a; }
template <class T> inline constexpr OverflowSafeInt<T> operator * (const uint a, const OverflowSafeInt<T> b) { return b * a; }
template <class T> inline constexpr OverflowSafeInt<T> operator / (const uint a, const OverflowSafeInt<T> b) { return (OverflowSafeInt<T>)a / (int)b; }
typedef OverflowSafeInt<int64, INT64_MAX, INT64_MIN> OverflowSafeInt64;
typedef OverflowSafeInt<int32, INT32_MAX, INT32_MIN> OverflowSafeInt32;
/* Sometimes we got byte operator OverflowSafeInt instead of vice versa. Handle that properly. */
template <class T> inline constexpr OverflowSafeInt<T> operator + (const byte a, const OverflowSafeInt<T> b) { return b + (uint)a; }
template <class T> inline constexpr OverflowSafeInt<T> operator - (const byte a, const OverflowSafeInt<T> b) { return -b + (uint)a; }
template <class T> inline constexpr OverflowSafeInt<T> operator * (const byte a, const OverflowSafeInt<T> b) { return b * (uint)a; }
template <class T> inline constexpr OverflowSafeInt<T> operator / (const byte a, const OverflowSafeInt<T> b) { return (OverflowSafeInt<T>)a / (int)b; }
typedef OverflowSafeInt<int64> OverflowSafeInt64;
typedef OverflowSafeInt<int32> OverflowSafeInt32;
/* Some basic "unit tests". Also has the bonus of confirming that constexpr is working. */
static_assert(OverflowSafeInt32(INT32_MIN) - 1 == OverflowSafeInt32(INT32_MIN));
static_assert(OverflowSafeInt32(INT32_MAX) + 1 == OverflowSafeInt32(INT32_MAX));
static_assert(OverflowSafeInt32(INT32_MAX) * 2 == OverflowSafeInt32(INT32_MAX));
static_assert(OverflowSafeInt32(INT32_MIN) * 2 == OverflowSafeInt32(INT32_MIN));
#undef HAS_OVERFLOW_BUILTINS
#endif /* OVERFLOWSAFE_TYPE_HPP */

View File

@@ -33,9 +33,9 @@ DEFINE_POOL_METHOD(inline)::Pool(const char *name) :
first_free(0),
first_unused(0),
items(0),
#ifdef OTTD_ASSERT
#ifdef WITH_ASSERT
checked(0),
#endif /* OTTD_ASSERT */
#endif /* WITH_ASSERT */
cleaning(false),
data(nullptr),
alloc_cache(nullptr)
@@ -133,10 +133,10 @@ DEFINE_POOL_METHOD(void *)::GetNew(size_t size)
{
size_t index = this->FindFirstFree();
#ifdef OTTD_ASSERT
#ifdef WITH_ASSERT
assert(this->checked != 0);
this->checked--;
#endif /* OTTD_ASSERT */
#endif /* WITH_ASSERT */
if (index == NO_FREE_ITEM) {
error("%s: no more free items", this->name);
}

View File

@@ -90,9 +90,9 @@ struct Pool : PoolBase {
size_t first_free; ///< No item with index lower than this is free (doesn't say anything about this one!)
size_t first_unused; ///< This and all higher indexes are free (doesn't say anything about first_unused-1 !)
size_t items; ///< Number of used indexes (non-nullptr)
#ifdef OTTD_ASSERT
#ifdef WITH_ASSERT
size_t checked; ///< Number of items we checked for
#endif /* OTTD_ASSERT */
#endif /* WITH_ASSERT */
bool cleaning; ///< True if cleaning pool (deleting all items)
Titem **data; ///< Pointer to array of pointers to Titem
@@ -130,9 +130,9 @@ struct Pool : PoolBase {
inline bool CanAllocate(size_t n = 1)
{
bool ret = this->items <= Tmax_size - n;
#ifdef OTTD_ASSERT
#ifdef WITH_ASSERT
this->checked = ret ? n : 0;
#endif /* OTTD_ASSERT */
#endif /* WITH_ASSERT */
return ret;
}
@@ -160,7 +160,11 @@ struct Pool : PoolBase {
private:
size_t index;
void ValidateIndex() { while (this->index < T::GetPoolSize() && !(T::IsValidID(this->index))) this->index++; }
void ValidateIndex()
{
while (this->index < T::GetPoolSize() && !(T::IsValidID(this->index))) this->index++;
if (this->index >= T::GetPoolSize()) this->index = T::Pool::MAX_SIZE;
}
};
/*
@@ -172,7 +176,7 @@ struct Pool : PoolBase {
size_t from;
IterateWrapper(size_t from = 0) : from(from) {}
PoolIterator<T> begin() { return PoolIterator<T>(this->from); }
PoolIterator<T> end() { return PoolIterator<T>(T::GetPoolSize()); }
PoolIterator<T> end() { return PoolIterator<T>(T::Pool::MAX_SIZE); }
bool empty() { return this->begin() == this->end(); }
};
@@ -201,7 +205,11 @@ struct Pool : PoolBase {
private:
size_t index;
F filter;
void ValidateIndex() { while (this->index < T::GetPoolSize() && !(T::IsValidID(this->index) && this->filter(this->index))) this->index++; }
void ValidateIndex()
{
while (this->index < T::GetPoolSize() && !(T::IsValidID(this->index) && this->filter(this->index))) this->index++;
if (this->index >= T::GetPoolSize()) this->index = T::Pool::MAX_SIZE;
}
};
/*
@@ -214,7 +222,7 @@ struct Pool : PoolBase {
F filter;
IterateWrapperFiltered(size_t from, F filter) : from(from), filter(filter) {}
PoolIteratorFiltered<T, F> begin() { return PoolIteratorFiltered<T, F>(this->from, this->filter); }
PoolIteratorFiltered<T, F> end() { return PoolIteratorFiltered<T, F>(T::GetPoolSize(), this->filter); }
PoolIteratorFiltered<T, F> end() { return PoolIteratorFiltered<T, F>(T::Pool::MAX_SIZE, this->filter); }
bool empty() { return this->begin() == this->end(); }
};

View File

@@ -72,7 +72,7 @@ void SetRandomSeed(uint32 seed)
uint32 DoRandom(int line, const char *file)
{
if (_networking && (!_network_server || (NetworkClientSocket::IsValidID(0) && NetworkClientSocket::Get(0)->status != NetworkClientSocket::STATUS_INACTIVE))) {
DEBUG(random, 0, "%08x; %02x; %04x; %02x; %s:%d", _date, _date_fract, _frame_counter, (byte)_current_company, file, line);
Debug(random, 0, "{:08x}; {:02x}; {:04x}; {:02x}; {}:{}", _date, _date_fract, _frame_counter, (byte)_current_company, file, line);
}
return _random.Next();

100
src/core/span_type.hpp Normal file
View File

@@ -0,0 +1,100 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file span_type.hpp Minimized implementation of C++20 std::span. */
#ifndef CORE_SPAN_TYPE_HPP
#define CORE_SPAN_TYPE_HPP
/* This is a partial copy/paste from https://github.com/gsl-lite/gsl-lite/blob/master/include/gsl/gsl-lite.hpp */
/* Template to check if a template variable defines size() and data(). */
template <class, class = void>
struct has_size_and_data : std::false_type{};
template <class C>
struct has_size_and_data
<
C, std::void_t<
decltype(std::size(std::declval<C>())),
decltype(std::data(std::declval<C>()))>
> : std::true_type{};
/* Template to check if two elements are compatible. */
template <class, class, class = void>
struct is_compatible_element : std::false_type {};
template <class C, class E>
struct is_compatible_element
<
C, E, std::void_t<
decltype(std::data(std::declval<C>())),
typename std::remove_pointer<decltype(std::data( std::declval<C&>()))>::type(*)[]>
> : std::is_convertible<typename std::remove_pointer<decltype(std::data(std::declval<C&>()))>::type(*)[], E(*)[]>{};
/* Template to check if a container is compatible. gsl-lite also includes is_array and is_std_array, but as we don't use them, they are omitted. */
template <class C, class E>
struct is_compatible_container : std::bool_constant
<
has_size_and_data<C>::value
&& is_compatible_element<C,E>::value
>{};
/**
* A trimmed down version of what std::span will be in C++20.
*
* It is fully forwards compatible, so if this codebase switches to C++20,
* all "span" instances can be replaced by "std::span" without loss of
* functionality.
*
* Currently it only supports basic functionality:
* - size() and friends
* - begin() and friends
*
* It is meant to simplify function parameters, where we only want to walk
* a continuous list.
*/
template<class T>
class span {
public:
typedef T element_type;
typedef typename std::remove_cv< T >::type value_type;
typedef T &reference;
typedef T *pointer;
typedef const T &const_reference;
typedef const T *const_pointer;
typedef pointer iterator;
typedef const_pointer const_iterator;
typedef size_t size_type;
typedef std::ptrdiff_t difference_type;
constexpr span() noexcept : first(nullptr), last(nullptr) {}
constexpr span(pointer data_in, size_t size_in) : first(data_in), last(data_in + size_in) {}
template<class Container, typename std::enable_if<(is_compatible_container<Container, element_type>::value), int>::type = 0>
constexpr span(Container &list) noexcept : first(std::data(list)), last(std::data(list) + std::size(list)) {}
template<class Container, typename std::enable_if<(std::is_const<element_type>::value && is_compatible_container<Container, element_type>::value), int>::type = 0>
constexpr span(const Container &list) noexcept : first(std::data(list)), last(std::data(list) + std::size(list)) {}
constexpr size_t size() const noexcept { return static_cast<size_t>( last - first ); }
constexpr std::ptrdiff_t ssize() const noexcept { return static_cast<std::ptrdiff_t>( last - first ); }
constexpr bool empty() const noexcept { return size() == 0; }
constexpr iterator begin() const noexcept { return iterator(first); }
constexpr iterator end() const noexcept { return iterator(last); }
constexpr const_iterator cbegin() const noexcept { return const_iterator(first); }
constexpr const_iterator cend() const noexcept { return const_iterator(last); }
private:
pointer first;
pointer last;
};
#endif /* CORE_SPAN_TYPE_HPP */

View File

@@ -32,8 +32,7 @@
#include "game/game_info.hpp"
#include "company_base.h"
#include "company_func.h"
#include <time.h>
#include "walltime_func.h"
#ifdef WITH_ALLEGRO
# include <allegro.h>
@@ -130,7 +129,7 @@ char *CrashLog::LogOpenTTDVersion(char *buffer, const char *last) const
_openttd_revision,
_openttd_revision_modified,
_openttd_newgrf_version,
#ifdef _SQ64
#ifdef POINTER_IS_64BIT
64,
#else
32,
@@ -340,9 +339,9 @@ char *CrashLog::LogRecentNews(char *buffer, const char *last) const
*/
char *CrashLog::FillCrashLog(char *buffer, const char *last) const
{
time_t cur_time = time(nullptr);
buffer += seprintf(buffer, last, "*** OpenTTD Crash Report ***\n\n");
buffer += seprintf(buffer, last, "*** OpenTTD Crash Report ***\nCityMania patched client http://citymania.org\nPlease, unless you encounter this bug with unpatched OpenTTD version, report bug to CityMania team\n\n");
buffer += seprintf(buffer, last, "Crash at: %s", asctime(gmtime(&cur_time)));
buffer += UTCTime::Format(buffer, last, "Crash at: %Y-%m-%d %H:%M:%S (UTC)\n");
YearMonthDay ymd;
ConvertDateToYMD(_date, &ymd);

View File

@@ -70,11 +70,11 @@ enum Currencies {
/** Specification of a currency. */
struct CurrencySpec {
uint16 rate;
char separator[8];
Year to_euro; ///< %Year of switching to the Euro. May also be #CF_NOEURO or #CF_ISEURO.
char prefix[16];
char suffix[16];
uint16 rate; ///< The conversion rate compared to the base currency.
std::string separator; ///< The thousands separator for this currency.
Year to_euro; ///< %Year of switching to the Euro. May also be #CF_NOEURO or #CF_ISEURO.
std::string prefix; ///< Prefix to apply when formatting money in this currency.
std::string suffix; ///< Suffix to apply when formatting money in this currency.
/**
* The currency symbol is represented by two possible values, prefix and suffix
* Usage of one or the other is determined by #symbol_pos.
@@ -89,11 +89,9 @@ struct CurrencySpec {
CurrencySpec() = default;
CurrencySpec(uint16 rate, const char *separator, Year to_euro, const char *prefix, const char *suffix, byte symbol_pos, StringID name) : rate(rate), to_euro(to_euro), symbol_pos(symbol_pos), name(name)
CurrencySpec(uint16 rate, const char *separator, Year to_euro, const char *prefix, const char *suffix, byte symbol_pos, StringID name) :
rate(rate), separator(separator), to_euro(to_euro), prefix(prefix), suffix(suffix), symbol_pos(symbol_pos), name(name)
{
strecpy(this->separator, separator, lastof(this->separator));
strecpy(this->prefix, prefix, lastof(this->prefix));
strecpy(this->suffix, suffix, lastof(this->suffix));
}
};

View File

@@ -147,7 +147,7 @@ struct SetDateWindow : Window {
case WID_SD_SET_DATE:
if (this->callback != nullptr) this->callback(this, ConvertYMDToDate(this->date.year, this->date.month, this->date.day));
delete this;
this->Close();
break;
}
}
@@ -212,6 +212,6 @@ static WindowDesc _set_date_desc(
*/
void ShowSetDateWindow(Window *parent, int window_number, Date initial_date, Year min_year, Year max_year, SetDateCallback *callback)
{
DeleteWindowByClass(WC_SET_DATE);
CloseWindowByClass(WC_SET_DATE);
new SetDateWindow(&_set_date_desc, window_number, parent, initial_date, min_year, max_year, callback);
}

View File

@@ -28,6 +28,7 @@ typedef uint8 Day; ///< Type for the day of the month, note: 1 based, first d
static const int DAY_TICKS = 74; ///< ticks per day
static const int DAYS_IN_YEAR = 365; ///< days per year
static const int DAYS_IN_LEAP_YEAR = 366; ///< sometimes, you need one day more...
static const int MONTHS_IN_YEAR = 12; ///< months per year
static const int STATION_RATING_TICKS = 185; ///< cycle duration for updating station rating
static const int STATION_ACCEPTANCE_TICKS = 250; ///< cycle duration for updating station acceptance

View File

@@ -19,7 +19,7 @@
#include "os/windows/win32.h"
#endif
#include <time.h>
#include "walltime_func.h"
#include "network/network_admin.h"
SOCKET _debug_socket = INVALID_SOCKET;
@@ -100,67 +100,41 @@ char *DumpDebugFacilityNames(char *buf, char *last)
/**
* Internal function for outputting the debug line.
* @param dbg Debug category.
* @param buf Text line to output.
* @param level Debug category.
* @param message The message to output.
*/
static void debug_print(const char *dbg, const char *buf)
void DebugPrint(const char *level, const std::string &message)
{
if (_debug_socket != INVALID_SOCKET) {
char buf2[1024 + 32];
seprintf(buf2, lastof(buf2), "%sdbg: [%s] %s\n", GetLogPrefix(), dbg, buf);
std::string msg = fmt::format("{}dbg: [{}] {}\n", GetLogPrefix(), level, message);
/* Sending out an error when this fails would be nice, however... the error
* would have to be send over this failing socket which won't work. */
send(_debug_socket, buf2, (int)strlen(buf2), 0);
send(_debug_socket, msg.c_str(), (int)msg.size(), 0);
return;
}
if (strcmp(dbg, "desync") == 0) {
if (strcmp(level, "desync") == 0) {
static FILE *f = FioFOpenFile("commands-out.log", "wb", AUTOSAVE_DIR);
if (f == nullptr) return;
fprintf(f, "%s%s\n", GetLogPrefix(), buf);
fprintf(f, "%s%s\n", GetLogPrefix(), message.c_str());
fflush(f);
#ifdef RANDOM_DEBUG
} else if (strcmp(dbg, "random") == 0) {
} else if (strcmp(level, "random") == 0) {
static FILE *f = FioFOpenFile("random-out.log", "wb", AUTOSAVE_DIR);
if (f == nullptr) return;
fprintf(f, "%s\n", buf);
fprintf(f, "%s\n", message.c_str());
fflush(f);
#endif
} else {
char buffer[512];
seprintf(buffer, lastof(buffer), "%sdbg: [%s] %s\n", GetLogPrefix(), dbg, buf);
#if defined(_WIN32)
wchar_t system_buf[512];
convert_to_fs(buffer, system_buf, lengthof(system_buf), true);
_fputts(system_buf, stderr);
#else
fputs(buffer, stderr);
#endif
NetworkAdminConsole(dbg, buf);
IConsoleDebug(dbg, buf);
std::string msg = fmt::format("{}dbg: [{}] {}\n", GetLogPrefix(), level, message);
fputs(msg.c_str(), stderr);
NetworkAdminConsole(level, message);
if (_settings_client.gui.developer >= 2) IConsolePrint(CC_DEBUG, "dbg: [{}] {}", level, message);
}
}
/**
* Output a debug line.
* @note Do not call directly, use the #DEBUG macro instead.
* @param dbg Debug category.
* @param format Text string a la printf, with optional arguments.
*/
void CDECL debug(const char *dbg, const char *format, ...)
{
char buf[1024];
va_list va;
va_start(va, format);
vseprintf(buf, lastof(buf), format, va);
va_end(va);
debug_print(dbg, buf);
}
/**
* Set debugging levels by parsing the text in \a s.
* For setting individual levels a string like \c "net=3,grf=6" should be used.
@@ -248,8 +222,7 @@ const char *GetLogPrefix()
{
static char _log_prefix[24];
if (_settings_client.gui.show_date_in_logs) {
time_t cur_time = time(nullptr);
strftime(_log_prefix, sizeof(_log_prefix), "[%Y-%m-%d %H:%M:%S] ", localtime(&cur_time));
LocalTime::Format(_log_prefix, lastof(_log_prefix), "[%Y-%m-%d %H:%M:%S] ");
} else {
*_log_prefix = '\0';
}

View File

@@ -12,9 +12,10 @@
#include "cpu.h"
#include <chrono>
#include "3rdparty/fmt/format.h"
/* Debugging messages policy:
* These should be the severities used for direct DEBUG() calls
* These should be the severities used for direct Debug() calls
* maximum debugging level should be 10 if really deep, deep
* debugging is needed.
* (there is room for exceptions, but you have to have a good cause):
@@ -28,11 +29,13 @@
*/
/**
* Output a line of debugging information.
* @param name Category
* @param level Debugging level, higher levels means more detailed information.
* Ouptut a line of debugging information.
* @param name The category of debug information.
* @param level The maximum debug level this message should be shown at. When the debug level for this category is set lower, then the message will not be shown.
* @param format_string The formatting string of the message.
*/
#define DEBUG(name, level, ...) if ((level) == 0 || _debug_ ## name ## _level >= (level)) debug(#name, __VA_ARGS__)
#define Debug(name, level, format_string, ...) if ((level) == 0 || _debug_ ## name ## _level >= (level)) DebugPrint(#name, fmt::format(FMT_STRING(format_string), ## __VA_ARGS__))
void DebugPrint(const char *level, const std::string &message);
extern int _debug_driver_level;
extern int _debug_grf_level;
@@ -53,8 +56,6 @@ extern int _debug_console_level;
extern int _debug_random_level;
#endif
void CDECL debug(const char *dbg, const char *format, ...) WARN_FORMAT(2, 3);
char *DumpDebugFacilityNames(char *buf, char *last);
void SetDebugString(const char *s);
const char *GetDebugString();
@@ -94,7 +95,7 @@ const char *GetDebugString();
#define TOC(str, count)\
_sum_ += ottd_rdtsc() - _xxx_;\
if (++_i_ == count) {\
DEBUG(misc, 0, "[%s] " OTTD_PRINTF64 " [avg: %.1f]", str, _sum_, _sum_/(double)_i_);\
Debug(misc, 0, "[{}] {} [avg: {:.1f}]", str, _sum_, _sum_/(double)_i_);\
_i_ = 0;\
_sum_ = 0;\
}\
@@ -109,7 +110,7 @@ const char *GetDebugString();
#define TOCC(str, _count_)\
_sum_ += (std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now() - _start_)).count();\
if (++_i_ == _count_) {\
DEBUG(misc, 0, "[%s] " OTTD_PRINTF64 " us [avg: %.1f us]", str, _sum_, _sum_/(double)_i_);\
Debug(misc, 0, "[{}] {} us [avg: {:.1f} us]", str, _sum_, _sum_/(double)_i_);\
_i_ = 0;\
_sum_ = 0;\
}\

View File

@@ -41,9 +41,9 @@ Depot::~Depot()
RemoveOrderFromAllVehicles(OT_GOTO_DEPOT, this->index);
/* Delete the depot-window */
DeleteWindowById(WC_VEHICLE_DEPOT, this->xy);
CloseWindowById(WC_VEHICLE_DEPOT, this->xy);
/* Delete the depot list */
VehicleType vt = GetDepotVehicleType(this->xy);
DeleteWindowById(GetWindowClassForVehicleType(vt), VehicleListIdentifier(VL_DEPOT_LIST, vt, GetTileOwner(this->xy), this->index).Pack());
CloseWindowById(GetWindowClassForVehicleType(vt), VehicleListIdentifier(VL_DEPOT_LIST, vt, GetTileOwner(this->xy), this->index).Pack());
}

View File

@@ -26,7 +26,7 @@
* @param name The name to check.
* @return True if there is no depot with the given name.
*/
static bool IsUniqueDepotName(const char *name)
static bool IsUniqueDepotName(const std::string &name)
{
for (const Depot *d : Depot::Iterate()) {
if (!d->name.empty() && d->name == name) return false;
@@ -44,7 +44,7 @@ static bool IsUniqueDepotName(const char *name)
* @param text the new name or an empty string when resetting to the default
* @return the cost of this operation or an error
*/
CommandCost CmdRenameDepot(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
CommandCost CmdRenameDepot(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const std::string &text)
{
Depot *d = Depot::GetIfValid(p1);
if (d == nullptr) return CMD_ERROR;
@@ -52,7 +52,7 @@ CommandCost CmdRenameDepot(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3
CommandCost ret = CheckTileOwnership(d->xy);
if (ret.Failed()) return ret;
bool reset = StrEmpty(text);
bool reset = text.empty();
if (!reset) {
if (Utf8StringLength(text) >= MAX_LENGTH_DEPOT_NAME_CHARS) return CMD_ERROR;

View File

@@ -268,11 +268,12 @@ struct DepotWindow : Window {
OrderBackup::Reset();
}
~DepotWindow()
void Close() override
{
DeleteWindowById(WC_BUILD_VEHICLE, this->window_number);
DeleteWindowById(GetWindowClassForVehicleType(this->type), VehicleListIdentifier(VL_DEPOT_LIST, this->type, this->owner, this->GetDepotIndex()).Pack(), false);
CloseWindowById(WC_BUILD_VEHICLE, this->window_number);
CloseWindowById(GetWindowClassForVehicleType(this->type), VehicleListIdentifier(VL_DEPOT_LIST, this->type, this->owner, this->GetDepotIndex()).Pack(), false);
OrderBackup::Reset(this->window_number);
this->Window::Close();
}
/**
@@ -304,16 +305,9 @@ struct DepotWindow : Window {
this->sel, EIT_IN_DEPOT, free_wagon ? 0 : this->hscroll->GetPosition(), this->vehicle_over);
/* Length of consist in tiles with 1 fractional digit (rounded up) */
if (_settings_client.gui.old_depot_train_length_calc) {
SetDParam(0, CeilDiv(u->gcache.cached_total_length, 8));
SetDParam(1, 1);
DrawString(rtl ? left + WD_FRAMERECT_LEFT : right - this->count_width, rtl ? left + this->count_width : right - WD_FRAMERECT_RIGHT, y + (this->resize.step_height - FONT_HEIGHT_SMALL) / 2, STR_TINY_BLACK_COMA, TC_FROMSTRING, SA_RIGHT); // Draw the counter
}
else {
SetDParam(0, CeilDiv(u->gcache.cached_total_length * 10, TILE_SIZE));
SetDParam(1, 1);
DrawString(rtl ? left + WD_FRAMERECT_LEFT : right - this->count_width, rtl ? left + this->count_width : right - WD_FRAMERECT_RIGHT, y + (this->resize.step_height - FONT_HEIGHT_SMALL) / 2, STR_TINY_BLACK_DECIMAL, TC_FROMSTRING, SA_RIGHT); // Draw the counter
}
SetDParam(0, CeilDiv(u->gcache.cached_total_length * 10, TILE_SIZE));
SetDParam(1, 1);
DrawString(rtl ? left + WD_FRAMERECT_LEFT : right - this->count_width, rtl ? left + this->count_width : right - WD_FRAMERECT_RIGHT, y + (this->resize.step_height - FONT_HEIGHT_SMALL) / 2, STR_TINY_BLACK_DECIMAL, TC_FROMSTRING, SA_RIGHT); // Draw the counter
break;
}
@@ -379,11 +373,11 @@ struct DepotWindow : Window {
uint16 rows_in_display = wid->current_y / wid->resize_y;
uint16 num = this->vscroll->GetPosition() * this->num_columns;
uint num = this->vscroll->GetPosition() * this->num_columns;
uint maxval = static_cast<uint>(std::min<size_t>(this->vehicle_list.size(), num + (rows_in_display * this->num_columns)));
int y;
for (y = r.top + 1; num < maxval; y += this->resize.step_height) { // Draw the rows
for (byte i = 0; i < this->num_columns && num < maxval; i++, num++) {
for (uint i = 0; i < this->num_columns && num < maxval; i++, num++) {
/* Draw all vehicles in the current row */
const Vehicle *v = this->vehicle_list[num];
if (this->num_columns == 1) {
@@ -1035,7 +1029,7 @@ struct DepotWindow : Window {
this->RaiseWidget(WID_D_SELL);
this->SetWidgetDirty(WID_D_SELL);
}
if (this->nested_array[WID_D_SELL] != nullptr && !this->IsWidgetDisabled(WID_D_SELL_CHAIN)) {
if (this->GetWidget<NWidgetBase>(WID_D_SELL) != nullptr && !this->IsWidgetDisabled(WID_D_SELL_CHAIN)) {
this->RaiseWidget(WID_D_SELL_CHAIN);
this->SetWidgetDirty(WID_D_SELL_CHAIN);
}

View File

@@ -104,10 +104,11 @@ struct BuildDocksToolbarWindow : Window {
if (_settings_client.gui.link_terraform_toolbar) ShowTerraformToolbar(this);
}
~BuildDocksToolbarWindow()
void Close() override
{
if (_game_mode == GM_NORMAL && this->IsWidgetLowered(WID_DT_STATION)) SetViewportCatchmentStation(nullptr, true);
if (_settings_client.gui.link_terraform_toolbar) DeleteWindowById(WC_SCEN_LAND_GEN, 0, false);
if (_settings_client.gui.link_terraform_toolbar) CloseWindowById(WC_SCEN_LAND_GEN, 0, false);
this->Window::Close();
}
/**
@@ -126,8 +127,8 @@ struct BuildDocksToolbarWindow : Window {
WID_DT_BUOY,
WIDGET_LIST_END);
if (!can_build) {
DeleteWindowById(WC_BUILD_STATION, TRANSPORT_WATER);
DeleteWindowById(WC_BUILD_DEPOT, TRANSPORT_WATER);
CloseWindowById(WC_BUILD_STATION, TRANSPORT_WATER);
CloseWindowById(WC_BUILD_DEPOT, TRANSPORT_WATER);
}
if (_game_mode != GM_EDITOR) {
@@ -173,7 +174,7 @@ struct BuildDocksToolbarWindow : Window {
case WID_DT_RIVER: // Build river button (in scenario editor)
if (_game_mode != GM_EDITOR) return;
HandlePlacePushButton(this, WID_DT_RIVER, SPR_CURSOR_RIVER, HT_RECT, CM_DDSP_BUILD_RIVER);
HandlePlacePushButton(this, WID_DT_RIVER, SPR_CURSOR_RIVER, HT_RECT | HT_DIAGONAL, CM_DDSP_BUILD_RIVER);
break;
case WID_DT_BUILD_AQUEDUCT: // Build aqueduct button
@@ -202,7 +203,7 @@ struct BuildDocksToolbarWindow : Window {
case WID_DT_DEPOT: // Build depot button
DoCommandP(tile, _ship_depot_direction, 0, CMD_BUILD_SHIP_DEPOT | CMD_MSG(STR_ERROR_CAN_T_BUILD_SHIP_DEPOT), CcBuildDocks);
if (citymania::_fn_mod == _settings_client.gui.persistent_depottools)
if (citymania::_fn_mod == _settings_client.gui.cm_keep_depot_tools)
ResetObjectToPlace();
break;
@@ -258,7 +259,7 @@ struct BuildDocksToolbarWindow : Window {
DoCommandP(end_tile, start_tile, (_game_mode == GM_EDITOR && citymania::_fn_mod) ? WATER_CLASS_SEA : WATER_CLASS_CANAL, CMD_BUILD_CANAL | CMD_MSG(STR_ERROR_CAN_T_BUILD_CANALS), CcPlaySound_CONSTRUCTION_WATER);
break;
case DDSP_CREATE_RIVER:
DoCommandP(end_tile, start_tile, WATER_CLASS_RIVER, CMD_BUILD_CANAL | CMD_MSG(STR_ERROR_CAN_T_PLACE_RIVERS), CcPlaySound_CONSTRUCTION_WATER);
DoCommandP(end_tile, start_tile, WATER_CLASS_RIVER | (_ctrl_pressed ? 1 << 2 : 0), CMD_BUILD_CANAL | CMD_MSG(STR_ERROR_CAN_T_PLACE_RIVERS), CcPlaySound_CONSTRUCTION_WATER);
break;
default: break;
@@ -272,11 +273,11 @@ struct BuildDocksToolbarWindow : Window {
this->RaiseButtons();
DeleteWindowById(WC_BUILD_STATION, TRANSPORT_WATER);
DeleteWindowById(WC_BUILD_DEPOT, TRANSPORT_WATER);
DeleteWindowById(WC_SELECT_STATION, 0);
DeleteWindowByClass(WC_BUILD_BRIDGE);
CloseWindowById(WC_BUILD_STATION, TRANSPORT_WATER);
CloseWindowById(WC_BUILD_DEPOT, TRANSPORT_WATER);
CloseWindowById(WC_SELECT_STATION, 0);
CloseWindowByClass(WC_BUILD_BRIDGE);
citymania::AbortStationPlacement();
}
@@ -371,7 +372,7 @@ Window *ShowBuildDocksToolbar()
{
if (!Company::IsValidID(_local_company)) return nullptr;
DeleteWindowByClass(WC_BUILD_TOOLBAR);
CloseWindowByClass(WC_BUILD_TOOLBAR);
return AllocateWindowDescFront<BuildDocksToolbarWindow>(&_build_docks_toolbar_desc, TRANSPORT_WATER);
}
@@ -429,9 +430,10 @@ public:
this->LowerWidget(_settings_client.gui.station_show_coverage + BDSW_LT_OFF);
}
virtual ~BuildDocksStationWindow()
void Close() override
{
DeleteWindowById(WC_SELECT_STATION, 0);
CloseWindowById(WC_SELECT_STATION, 0);
this->PickerWindowBase::Close();
}
void OnPaint() override

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