diff --git a/source/src/clientgame.cpp b/source/src/clientgame.cpp index 4c8442d8..fd350a51 100644 --- a/source/src/clientgame.cpp +++ b/source/src/clientgame.cpp @@ -658,6 +658,16 @@ float nearestenemy(vec place, int team) else return nearestenemydist; } +void gotoplayerstart(playerent *d, entity *e) +{ + d->o.x = e->x; + d->o.y = e->y; + d->o.z = e->z; + d->yaw = e->attr1; + d->pitch = 0; + d->roll = 0; +} + void findplayerstart(playerent *d, bool mapcenter, int arenaspawn) { int r = fixspawn-->0 ? 4 : rnd(10)+1; @@ -693,12 +703,7 @@ void findplayerstart(playerent *d, bool mapcenter, int arenaspawn) if(e) { - d->o.x = e->x; - d->o.y = e->y; - d->o.z = e->z; - d->yaw = e->attr1; - d->pitch = 0; - d->roll = 0; + gotoplayerstart(d, e); } else { diff --git a/source/src/protos.h b/source/src/protos.h index 5b2dceb1..4d9e4020 100644 --- a/source/src/protos.h +++ b/source/src/protos.h @@ -436,6 +436,7 @@ extern void flagidle(int flag); extern void flagmsg(int flag, int message, int actor, int flagtime); extern void arenarespawn(); extern bool tryrespawn(); +extern void gotoplayerstart(playerent *d, entity *e); extern void findplayerstart(playerent *d, bool mapcenter = false, int arenaspawn = -1); extern void serveropcommand(int cmd, int arg1); extern void refreshsopmenu(void *menu, bool init); diff --git a/source/src/world.cpp b/source/src/world.cpp index 817db875..ae27dbc1 100644 --- a/source/src/world.cpp +++ b/source/src/world.cpp @@ -399,13 +399,7 @@ void nextplayerstart(int *type) cycle = findentity(PLAYERSTART, cycle + 1, *type); if(cycle >= 0) { - entity &e = ents[cycle]; - player1->o.x = e.x; - player1->o.y = e.y; - player1->o.z = e.z; - player1->yaw = e.attr1; - player1->pitch = 0; - player1->roll = 0; + gotoplayerstart(player1, &ents[cycle]); entinmap(player1); } } diff --git a/source/src/worldio.cpp b/source/src/worldio.cpp index 4f3ae6e3..e765e06a 100644 --- a/source/src/worldio.cpp +++ b/source/src/worldio.cpp @@ -277,8 +277,8 @@ struct headerextra }; vector headerextras; -enum { HX_UNUSED = 0, HX_MAPINFO, HX_MODEINFO, HX_ARTIST, HX_EDITUNDO, HX_CONFIG, HX_NUM, HX_TYPEMASK = 0x3f, HX_FLAG_PERSIST = 0x40 }; -const char *hx_names[] = { "unused", "mapinfo", "modeinfo", "artist", "editundo", "config", "unknown" }; +enum { HX_UNUSED = 0, HX_MAPINFO, HX_MODEINFO, HX_ARTIST, HX_EDITUNDO, HX_CONFIG, HX_VANTAGEPOINT, HX_NUM, HX_TYPEMASK = 0x3f, HX_FLAG_PERSIST = 0x40 }; +const char *hx_names[] = { "unused", "mapinfo", "modeinfo", "artist", "editundo", "config", "vantage point", "unknown" }; #define addhxpacket(p, len, flags, buffer) { if(p.length() + len < MAXHEADEREXTRA) { putuint(p, len); putuint(p, flags); p.put(buffer, len); } } #define hx_name(t) hx_names[min((t) & HX_TYPEMASK, int(HX_NUM))] @@ -402,6 +402,51 @@ void extractconfigfile() } COMMAND(extractconfigfile, ""); +bool clearvantagepoint() +{ + bool yep = false; + for(int n; (n = findheaderextra(HX_VANTAGEPOINT)) >= 0; yep = true) deleteheaderextra(n); + unsavededits++; + return yep; +} +COMMANDF(clearvantagepoint, "", () { if(!noteditmode("clearvantagepoint") && !multiplayer() && clearvantagepoint()) conoutf("cleared vantage point"); }); + +void setvantagepoint() +{ + if(noteditmode("setvantagepoint") || multiplayer()) return; + clearvantagepoint(); + short p[5]; + storeposition(p); + vector buf; + loopi(5) putint(buf, p[i]); + headerextras.add(new headerextra(buf.length(), HX_VANTAGEPOINT|HX_FLAG_PERSIST, buf.getbuf())); + conoutf("vantage point set"); +} +COMMAND(setvantagepoint, ""); + +bool gotovantagepoint() +{ + short p[5]; + int n = findheaderextra(HX_VANTAGEPOINT); + if(n >= 0) + { + ucharbuf q(headerextras[n]->data, headerextras[n]->len); + loopi(5) p[i] = getint(q); + restoreposition(p); + physent d = *player1; + d.radius = d.eyeheight = d.maxeyeheight = d.aboveeye = 0.1; + if(collide(&d, false)) n = -1; // don't use out-of-map vantage points + } + if(n < 0) // if there is no vantage point set, we go to the first playerstart instead + { + int s = findentity(PLAYERSTART, 0); + if(ents.inrange(s)) gotoplayerstart(player1, &ents[s]); + entinmap(player1); + } + return n >= 0; +} +COMMANDF(gotovantagepoint, "", () { if(editmode) gotovantagepoint(); }); + VAR(advancemaprevision, 1, 1, 100); VARP(mapbackupsonsave, 0, 1, 1);