From 09a8e0c174a432c8e37c2ebcd699f895a1d3ea0f Mon Sep 17 00:00:00 2001 From: sauerbraten Date: Mon, 30 Nov 2020 11:51:57 +0100 Subject: [PATCH] svn r6456 (2020 edition) --- .gitignore | 1 + src/engine/3dgui.cpp | 6 +- src/engine/command.cpp | 200 +++++++++++++++++++++++++++++++++++---- src/engine/octaedit.cpp | 8 ++ src/engine/rendergl.cpp | 33 +++---- src/engine/world.cpp | 1 + src/fpsgame/client.cpp | 7 +- src/fpsgame/entities.cpp | 4 +- src/fpsgame/fps.cpp | 13 +-- src/fpsgame/monster.cpp | 2 +- src/fpsgame/server.cpp | 8 +- src/rpggame/rpg.cpp | 2 +- src/rpggame/rpgobj.h | 2 +- src/shared/command.h | 2 +- src/shared/iengine.h | 8 ++ src/shared/igame.h | 2 +- 16 files changed, 245 insertions(+), 54 deletions(-) diff --git a/.gitignore b/.gitignore index 3b5cfca..b283f73 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ src/**/*.a src/**/*.gch src/**/*.o +src/**/*.orig src/sauer_client src/sauer_server patch_drafts diff --git a/src/engine/3dgui.cpp b/src/engine/3dgui.cpp index 4bbee1e..f1f6ef2 100644 --- a/src/engine/3dgui.cpp +++ b/src/engine/3dgui.cpp @@ -335,7 +335,7 @@ struct gui : g3d_gui int x1 = int(floor(screenw*(xi*scale.x+origin.x))), y1 = int(floor(screenh*(1 - ((yi+ys)*scale.y+origin.y)))), x2 = int(ceil(screenw*((xi+xs)*scale.x+origin.x))), y2 = int(ceil(screenh*(1 - (yi*scale.y+origin.y)))); glDisable(GL_BLEND); - modelpreview::start(x1, y1, x2-x1, y2-y1, overlaid); + modelpreview::start(x1, y1, x2-x1, y2-y1, overlaid!=NULL); game::renderplayerpreview(model, team, weap); modelpreview::end(); hudshader->set(); @@ -381,7 +381,7 @@ struct gui : g3d_gui int x1 = int(floor(screenw*(xi*scale.x+origin.x))), y1 = int(floor(screenh*(1 - ((yi+ys)*scale.y+origin.y)))), x2 = int(ceil(screenw*((xi+xs)*scale.x+origin.x))), y2 = int(ceil(screenh*(1 - (yi*scale.y+origin.y)))); glDisable(GL_BLEND); - modelpreview::start(x1, y1, x2-x1, y2-y1, overlaid); + modelpreview::start(x1, y1, x2-x1, y2-y1, overlaid!=NULL); model *m = loadmodel(name); if(m) { @@ -438,7 +438,7 @@ struct gui : g3d_gui int x1 = int(floor(screenw*(xi*scale.x+origin.x))), y1 = int(floor(screenh*(1 - ((yi+ys)*scale.y+origin.y)))), x2 = int(ceil(screenw*((xi+xs)*scale.x+origin.x))), y2 = int(ceil(screenh*(1 - (yi*scale.y+origin.y)))); glDisable(GL_BLEND); - modelpreview::start(x1, y1, x2-x1, y2-y1, overlaid); + modelpreview::start(x1, y1, x2-x1, y2-y1, overlaid!=NULL); previewprefab(prefab, color); modelpreview::end(); hudshader->set(); diff --git a/src/engine/command.cpp b/src/engine/command.cpp index 477a051..45e82f1 100644 --- a/src/engine/command.cpp +++ b/src/engine/command.cpp @@ -630,6 +630,17 @@ void setvarchecked(ident *id, int val) } } +static inline void setvarchecked(ident *id, tagval *args, int numargs) +{ + int val = forceint(args[0]); + if(id->flags&IDF_HEX && numargs > 1) + { + val = (val << 16) | (forceint(args[1])<<8); + if(numargs > 2) val |= forceint(args[2]); + } + setvarchecked(id, val); +} + float clampfvar(ident *id, float val, float minval, float maxval) { if(val < minval) val = minval; @@ -676,21 +687,53 @@ void setsvarchecked(ident *id, const char *val) } } +ICOMMAND(set, "rt", (ident *id, tagval *v), +{ + switch(id->type) + { + case ID_ALIAS: + if(id->index < MAXARGS) setarg(*id, *v); else setalias(*id, *v); + v->type = VAL_NULL; + break; + case ID_VAR: + setvarchecked(id, forceint(*v)); + break; + case ID_FVAR: + setfvarchecked(id, forcefloat(*v)); + break; + case ID_SVAR: + setsvarchecked(id, forcestr(*v)); + break; + case ID_COMMAND: + if(id->flags&IDF_EMUVAR) + { + tagval arg; + arg.setint(execute(id, NULL, 0, true) ? 0 : 1); + execute(id, &arg, 1, false); + break; + } + default: + debugcode("cannot redefine builtin %s with an alias", id->name); + break; + } +}); + bool addcommand(const char *name, identfun fun, const char *args) { uint argmask = 0; - int numargs = 0; + int numargs = 0, flags = 0; bool limit = true; for(const char *fmt = args; *fmt; fmt++) switch(*fmt) { case 'i': case 'b': case 'f': case 't': case 'N': case 'D': if(numargs < MAXARGS) numargs++; break; - case 's': case 'e': case 'r': case '$': if(numargs < MAXARGS) { argmask |= 1< MAXCOMARGS) fatal("builtin %s declared with too many args: %d", name, numargs); - addident(ident(ID_COMMAND, name, args, argmask, numargs, (void *)fun)); + addident(ident(ID_COMMAND, name, args, argmask, numargs, (void *)fun, flags)); return false; } @@ -1325,13 +1368,36 @@ static void compilestatements(vector &code, const char *&p, int rettype, i if(idname) { id = newident(idname, IDF_UNKNOWN); - if(!id || id->type != ID_ALIAS) { compilestr(code, idname, idlen, true); id = NULL; } + if(id) switch(id->type) + { + case ID_ALIAS: + if(!(more = compilearg(code, p, VAL_ANY))) compilestr(code); + code.add((id->index < MAXARGS ? CODE_ALIASARG : CODE_ALIAS)|(id->index<<8)); + goto endcommand; + case ID_VAR: + if(!(more = compilearg(code, p, VAL_INT))) compileint(code); + code.add(CODE_IVAR1|(id->index<<8)); + goto endcommand; + case ID_FVAR: + if(!(more = compilearg(code, p, VAL_FLOAT))) compilefloat(code); + code.add(CODE_FVAR1|(id->index<<8)); + goto endcommand; + case ID_SVAR: + if(!(more = compilearg(code, p, VAL_STR))) compilestr(code); + code.add(CODE_SVAR1|(id->index<<8)); + goto endcommand; + case ID_COMMAND: + if(id->flags&IDF_EMUVAR) goto compilecommand; + break; + } + compilestr(code, idname, idlen, true); delete[] idname; } if(!(more = compilearg(code, p, VAL_ANY))) compilestr(code); - code.add(id && idname ? (id->index < MAXARGS ? CODE_ALIASARG : CODE_ALIAS)|(id->index<<8) : CODE_ALIASU); + code.add(CODE_ALIASU); goto endstatement; } + compilecommand: numargs = 0; if(!idname) { @@ -1432,6 +1498,7 @@ static void compilestatements(vector &code, const char *&p, int rettype, i } break; } + endcommand: delete[] idname; } endstatement: @@ -1540,6 +1607,17 @@ void printsvar(ident *id, const char *s) conoutf(CON_INFO, id->index, strchr(s, '"') ? "%s = [%s]" : "%s = \"%s\"", id->name, s); } +template +static void printvar(ident *id, int type, V &val) +{ + switch(type) + { + case VAL_INT: printvar(id, val.getint()); break; + case VAL_FLOAT: printfvar(id, val.getfloat()); break; + default: printsvar(id, val.getstr()); break; + } +} + void printvar(ident *id) { switch(id->type) @@ -1547,8 +1625,19 @@ void printvar(ident *id) case ID_VAR: printvar(id, *id->storage.i); break; case ID_FVAR: printfvar(id, *id->storage.f); break; case ID_SVAR: printsvar(id, *id->storage.s); break; + case ID_ALIAS: printvar(id, id->valtype, *id); break; + case ID_COMMAND: + if(id->flags&IDF_EMUVAR) + { + tagval result; + executeret(id, NULL, 0, true, result); + printvar(id, result.type, result); + freearg(result); + } + break; } } +ICOMMAND(printvar, "r", (ident *id), printvar(id)); typedef void (__cdecl *comfun)(); typedef void (__cdecl *comfun1)(void *); @@ -2046,17 +2135,7 @@ static const uint *runcode(const uint *code, tagval &result) goto exit; } case ID_VAR: - if(numargs <= 1) printvar(id); - else - { - int val = forceint(args[1]); - if(id->flags&IDF_HEX && numargs > 2) - { - val = (val << 16) | (forceint(args[2])<<8); - if(numargs > 3) val |= forceint(args[3]); - } - setvarchecked(id, val); - } + if(numargs <= 1) printvar(id); else setvarchecked(id, &args[1], numargs-1); goto forceresult; case ID_FVAR: if(numargs <= 1) printvar(id); else setfvarchecked(id, forcefloat(args[1])); @@ -2095,6 +2174,50 @@ void executeret(const char *p, tagval &result) if(int(code[0]) >= 0x100) code.disown(); } +void executeret(ident *id, tagval *args, int numargs, bool lookup, tagval &result) +{ + result.setnull(); + ++rundepth; + tagval *prevret = commandret; + commandret = &result; + if(rundepth > MAXRUNDEPTH) debugcode("exceeded recursion limit"); + else if(id) switch(id->type) + { + default: + if(!id->fun) break; + // fall-through + case ID_COMMAND: + if(numargs < id->numargs) + { + tagval buf[MAXARGS]; + memcpy(buf, args, numargs*sizeof(tagval)); + callcommand(id, buf, numargs, lookup); + } + else callcommand(id, args, numargs, lookup); + numargs = 0; + break; + case ID_VAR: + if(numargs <= 0) printvar(id); else setvarchecked(id, args, numargs); + break; + case ID_FVAR: + if(numargs <= 0) printvar(id); else setfvarchecked(id, forcefloat(args[0])); + break; + case ID_SVAR: + if(numargs <= 0) printvar(id); else setsvarchecked(id, forcestr(args[0])); + break; + case ID_ALIAS: + if(id->index < MAXARGS && !(aliasstack->usedargs&(1<index))) break; + if(id->valtype==VAL_NULL) break; + #define op RET_NULL + CALLALIAS(0); + #undef op + break; + } + freeargs(args, numargs, 0); + commandret = prevret; + --rundepth; +} + char *executestr(const uint *code) { tagval result; @@ -2113,6 +2236,21 @@ char *executestr(const char *p) return result.s; } +char *executestr(ident *id, tagval *args, int numargs, bool lookup) +{ + tagval result; + executeret(id, args, numargs, lookup, result); + if(result.type == VAL_NULL) return NULL; + forcestr(result); + return result.s; +} + +char *execidentstr(const char *name, bool lookup) +{ + ident *id = idents.access(name); + return id ? executestr(id, NULL, 0, lookup) : NULL; +} + int execute(const uint *code) { tagval result; @@ -2135,6 +2273,21 @@ int execute(const char *p) return i; } +int execute(ident *id, tagval *args, int numargs, bool lookup) +{ + tagval result; + executeret(id, args, numargs, lookup, result); + int i = result.getint(); + freearg(result); + return i; +} + +int execident(const char *name, int noid, bool lookup) +{ + ident *id = idents.access(name); + return id ? execute(id, NULL, 0, lookup) : noid; +} + static inline bool getbool(const char *s) { switch(s[0]) @@ -2193,6 +2346,21 @@ bool executebool(const char *p) return b; } +bool executebool(ident *id, tagval *args, int numargs, bool lookup) +{ + tagval result; + executeret(id, args, numargs, lookup, result); + bool b = getbool(result); + freearg(result); + return b; +} + +bool execidentbool(const char *name, bool noid, bool lookup) +{ + ident *id = idents.access(name); + return id ? executebool(id, NULL, 0, lookup) : noid; +} + bool execfile(const char *cfgfile, bool msg) { string s; diff --git a/src/engine/octaedit.cpp b/src/engine/octaedit.cpp index 669fb0e..7197cd4 100644 --- a/src/engine/octaedit.cpp +++ b/src/engine/octaedit.cpp @@ -2877,6 +2877,14 @@ void showtexgui(int *n) // 0/noargs = toggle, 1 = on, other = off - will autoclose if too far away or exit editmode COMMAND(showtexgui, "i"); +bool cleartexgui() +{ + if(!gui.menuon) return false; + gui.showtextures(false); + return true; +} +ICOMMAND(cleartexgui, "", (), intret(cleartexgui() ? 1 : 0)); + void rendertexturepanel(int w, int h) { if((texpaneltimer -= curtime)>0 && editmode) diff --git a/src/engine/rendergl.cpp b/src/engine/rendergl.cpp index c70d102..6049951 100644 --- a/src/engine/rendergl.cpp +++ b/src/engine/rendergl.cpp @@ -2066,6 +2066,12 @@ void drawdamagescreen(int w, int h) hudquad(0, 0, w, h); } +void cleardamagescreen() +{ + damageblendmillis = 0; + loopi(8) damagedirs[i] = 0; +} + VAR(hidestats, 0, 0, 1); VAR(hidehud, 0, 0, 1); @@ -2306,8 +2312,7 @@ void gl_drawhud() abovehud -= FONTH; draw_textf("cube %s%d%s", FONTH/2, abovehud, selchildcount<0 ? "1/" : "", abs(selchildcount), showmat && selchildmat > 0 ? getmaterialdesc(selchildmat, ": ") : ""); - char *editinfo = executestr("edithud"); - if(editinfo) + if(char *editinfo = execidentstr("edithud")) { if(editinfo[0]) { @@ -2320,23 +2325,19 @@ void gl_drawhud() DELETEA(editinfo); } } - else if(identexists("gamehud")) + else if(char *gameinfo = execidentstr("gamehud")) { - char *gameinfo = executestr("gamehud"); - if(gameinfo) + if(gameinfo[0]) { - if(gameinfo[0]) - { - int tw, th; - text_bounds(gameinfo, tw, th); - th += FONTH-1; th -= th%FONTH; - roffset += max(th, FONTH); - draw_text(gameinfo, conw-max(5*FONTH, 2*FONTH+tw), conh-FONTH/2-roffset); - } - DELETEA(gameinfo); + int tw, th; + text_bounds(gameinfo, tw, th); + th += FONTH-1; th -= th%FONTH; + roffset += max(th, FONTH); + draw_text(gameinfo, conw-max(5*FONTH, 2*FONTH+tw), conh-FONTH/2-roffset); } - } - + DELETEA(gameinfo); + } + pophudmatrix(); } diff --git a/src/engine/world.cpp b/src/engine/world.cpp index f82ec2d..fcf64c2 100644 --- a/src/engine/world.cpp +++ b/src/engine/world.cpp @@ -1226,6 +1226,7 @@ void resetmap() clearslots(); clearparticles(); cleardecals(); + cleardamagescreen(); clearsleep(); cancelsel(); pruneundos(); diff --git a/src/fpsgame/client.cpp b/src/fpsgame/client.cpp index 2937a51..d9a7924 100644 --- a/src/fpsgame/client.cpp +++ b/src/fpsgame/client.cpp @@ -267,9 +267,7 @@ namespace game conoutf(CON_ERROR, "editing in multiplayer requires coop edit mode (1)"); return false; } - if(identexists("allowedittoggle") && !execute("allowedittoggle")) - return false; - return true; + return execidentbool("allowedittoggle", true); } void edittoggled(bool on) @@ -1799,8 +1797,7 @@ namespace game demoplayback = on!=0; player1->clientnum = getint(p); gamepaused = false; - const char *alias = on ? "demostart" : "demoend"; - if(identexists(alias)) execute(alias); + execident(on ? "demostart" : "demoend"); break; } diff --git a/src/fpsgame/entities.cpp b/src/fpsgame/entities.cpp index 8e18b8a..c35a0d1 100644 --- a/src/fpsgame/entities.cpp +++ b/src/fpsgame/entities.cpp @@ -299,7 +299,7 @@ namespace entities if(e->attr3 > 0) { defformatstring(hookname, "can_teleport_%d", e->attr3); - if(identexists(hookname) && !execute(hookname)) break; + if(!execidentbool(hookname, true)) break; } d->lastpickup = e->type; d->lastpickupmillis = lastmillis; @@ -514,7 +514,7 @@ namespace entities if(identexists(aliasname)) { triggerstate = state; - execute(aliasname); + execident(aliasname); } } diff --git a/src/fpsgame/fps.cpp b/src/fpsgame/fps.cpp index 78bbe03..1f558a7 100644 --- a/src/fpsgame/fps.cpp +++ b/src/fpsgame/fps.cpp @@ -145,10 +145,11 @@ namespace game } } - bool allowthirdperson() + bool allowthirdperson(bool msg) { - return !multiplayer(false) || player1->state==CS_SPECTATOR || player1->state==CS_EDITING || m_edit; + return player1->state==CS_SPECTATOR || player1->state==CS_EDITING || m_edit || !multiplayer(msg); } + ICOMMAND(allowthirdperson, "b", (int *msg), intret(allowthirdperson(*msg!=0) ? 1 : 0)); bool detachcamera() { @@ -526,7 +527,7 @@ namespace game showscores(true); disablezoom(); - if(identexists("intermission")) execute("intermission"); + execident("intermission"); } } @@ -657,12 +658,12 @@ namespace game disablezoom(); lasthit = 0; - if(identexists("mapstart")) execute("mapstart"); + execident("mapstart"); } void loadingmap(const char *name) { - if(identexists("playsong")) execute("playsong"); + execident("playsong"); } void startmap(const char *name) // called just after a map load @@ -1309,7 +1310,7 @@ namespace game void loadconfigs() { - if(identexists("playsong")) execute("playsong"); + execident("playsong"); execfile("auth.cfg", false); } diff --git a/src/fpsgame/monster.cpp b/src/fpsgame/monster.cpp index 0c044e6..e0790d3 100644 --- a/src/fpsgame/monster.cpp +++ b/src/fpsgame/monster.cpp @@ -257,7 +257,7 @@ namespace game gibeffect(max(-health, 0), vel, this); defformatstring(id, "monster_dead_%d", tag); - if(identexists(id)) execute(id); + execident(id); } else { diff --git a/src/fpsgame/server.cpp b/src/fpsgame/server.cpp index 46a5a8e..fb02c5e 100644 --- a/src/fpsgame/server.cpp +++ b/src/fpsgame/server.cpp @@ -1304,7 +1304,13 @@ namespace server gamemillis = offset; readdemo(); } - if(gamemillis > prevmillis && !interm) sendf(-1, 1, "ri2", N_TIMEUP, max((gamelimit - gamemillis)/1000, 1)); + if(gamemillis > prevmillis) + { + if(!interm) sendf(-1, 1, "ri2", N_TIMEUP, max((gamelimit - gamemillis)/1000, 1)); +#ifndef STANDALONE + cleardamagescreen(); +#endif + } } ICOMMAND(seekdemo, "sN$", (char *t, int *numargs, ident *id), diff --git a/src/rpggame/rpg.cpp b/src/rpggame/rpg.cpp index f86e57c..bb30422 100644 --- a/src/rpggame/rpg.cpp +++ b/src/rpggame/rpg.cpp @@ -236,7 +236,7 @@ namespace game { } - bool allowthirdperson() + bool allowthirdperson(bool msg) { return true; } diff --git a/src/rpggame/rpgobj.h b/src/rpggame/rpgobj.h index 1ce29a5..ce026b5 100644 --- a/src/rpggame/rpgobj.h +++ b/src/rpggame/rpgobj.h @@ -72,7 +72,7 @@ struct rpgobj : g3d_callback, stats { DELETEP(inventory); defformatstring(aliasname, "spawn_%s", name); - if(identexists(aliasname)) execute(aliasname); + execident(aliasname); } void decontain() diff --git a/src/shared/command.h b/src/shared/command.h index f5a34ff..475e492 100644 --- a/src/shared/command.h +++ b/src/shared/command.h @@ -40,7 +40,7 @@ enum enum { ID_VAR, ID_FVAR, ID_SVAR, ID_COMMAND, ID_ALIAS, ID_LOCAL }; -enum { IDF_PERSIST = 1<<0, IDF_OVERRIDE = 1<<1, IDF_HEX = 1<<2, IDF_READONLY = 1<<3, IDF_OVERRIDDEN = 1<<4, IDF_UNKNOWN = 1<<5, IDF_ARG = 1<<6 }; +enum { IDF_PERSIST = 1<<0, IDF_OVERRIDE = 1<<1, IDF_HEX = 1<<2, IDF_READONLY = 1<<3, IDF_OVERRIDDEN = 1<<4, IDF_UNKNOWN = 1<<5, IDF_ARG = 1<<6, IDF_EMUVAR = 1<<7 }; struct ident; diff --git a/src/shared/iengine.h b/src/shared/iengine.h index fd7cb80..32b1957 100644 --- a/src/shared/iengine.h +++ b/src/shared/iengine.h @@ -145,12 +145,19 @@ extern void keepcode(uint *p); extern void freecode(uint *p); extern void executeret(const uint *code, tagval &result = *commandret); extern void executeret(const char *p, tagval &result = *commandret); +extern void executeret(ident *id, tagval *args, int numargs, bool lookup = false, tagval &result = *commandret); extern char *executestr(const uint *code); extern char *executestr(const char *p); +extern char *executestr(ident *id, tagval *args, int numargs, bool lookup = false); +extern char *execidentstr(const char *name, bool lookup = false); extern int execute(const uint *code); extern int execute(const char *p); +extern int execute(ident *id, tagval *args, int numargs, bool lookup = false); +extern int execident(const char *name, int noid = 0, bool lookup = false); extern bool executebool(const uint *code); extern bool executebool(const char *p); +extern bool executebool(ident *id, tagval *args, int numargs, bool lookup = false); +extern bool execidentbool(const char *name, bool noid = false, bool lookup = false); extern bool execfile(const char *cfgfile, bool msg = true); extern void alias(const char *name, const char *action); extern void alias(const char *name, tagval &v); @@ -298,6 +305,7 @@ extern vec calcmodelpreviewpos(const vec &radius, float &yaw); extern void damageblend(int n); extern void damagecompass(int n, const vec &loc); +extern void cleardamagescreen(); extern vec minimapcenter, minimapradius, minimapscale; extern void bindminimap(); diff --git a/src/shared/igame.h b/src/shared/igame.h index 311d286..113ca17 100644 --- a/src/shared/igame.h +++ b/src/shared/igame.h @@ -84,7 +84,7 @@ namespace game extern int selectcrosshair(vec &color); extern void lighteffects(dynent *d, vec &color, vec &dir); extern void setupcamera(); - extern bool allowthirdperson(); + extern bool allowthirdperson(bool msg = false); extern bool detachcamera(); extern bool collidecamera(); extern void adddynlights();