From 4dc54e22b59237325d12ff818ff5cf0dc5522862 Mon Sep 17 00:00:00 2001 From: ac-stef Date: Fri, 16 Sep 2016 02:22:08 +0200 Subject: [PATCH] allow more edit commands in coop edit The edit protocol now allows the following commands in multiplayer: arch, slope, edittag, edittagclip, selectionrotate, selectionflip also: mapenlarge has been limited to size 10 in multiplayer entitiy undelete in multiplayer has been fixed SV_EDITS, SV_EDITD and SV_EDITE are to be cleaned up with a protocol bump DOCREF arch slope edittag edittagclip selectionrotate selectionflip --- source/src/clients2c.cpp | 51 +++++++++++++++------- source/src/editing.cpp | 91 +++++++++++++++++++++++++++------------- source/src/protocol.cpp | 2 +- source/src/protocol.h | 4 +- source/src/protos.h | 5 ++- source/src/server.cpp | 2 +- source/src/server.h | 2 +- source/src/world.cpp | 3 ++ 8 files changed, 111 insertions(+), 49 deletions(-) diff --git a/source/src/clients2c.cpp b/source/src/clients2c.cpp index ee5bad28..0e23d260 100644 --- a/source/src/clients2c.cpp +++ b/source/src/clients2c.cpp @@ -911,25 +911,46 @@ void parsemessages(int cn, playerent *d, ucharbuf &p, bool demo = false) break; } - case SV_EDITH: // coop editing messages, should be extended to include all possible editing ops - case SV_EDITT: - case SV_EDITS: - case SV_EDITD: - case SV_EDITE: + case SV_EDITXY: // coop editing messages, should be extended to include all possible editing ops { + int cmd = getint(p); int x = getint(p); int y = getint(p); int xs = getint(p); int ys = getint(p); - int v = getint(p); - block b = { x, y, xs, ys }; - switch(type) + int a1 = getint(p); + int a2 = getint(p); + if(!OUTBORD(x,y) && xs > 0 && ys > 0 && !OUTBORD(x + xs-1, y + ys - 1)) { - case SV_EDITH: editheightxy(v!=0, getint(p), b); break; - case SV_EDITT: edittexxy(v, getint(p), b); break; - case SV_EDITS: edittypexy(v, b); break; - case SV_EDITD: setvdeltaxy(v, b); break; - case SV_EDITE: editequalisexy(v!=0, b); break; + block b = { x, y, xs, ys }; + switch(cmd) + { + case EDITXY_HEIGHT: editheightxy(a1 != 0, a2, b); break; + case EDITXY_TEX: edittexxy(a1, a2, b); break; + case EDITXY_TYPE: edittypexy(a1, b); break; + case EDITXY_VDELTA: setvdeltaxy(a1, b); break; + case EDITXY_EQUALISE: editequalisexy(a1 != 0, b); break; + case EDITXY_TAG: edittagxy(a1, a2, b); break; + case EDITXY_SLOPE: slopexy(a1, a2, b); break; + case EDITXY_FLIPROT: selfliprotate(b, a1); break; + } + } + break; + } + + case SV_EDITARCH: + { + int av[50]; // MAXARCHVERT, hardcoded + int x = getint(p); + int y = getint(p); + int xs = getint(p); + int ys = getint(p); + int a1 = getint(p); + loopi(50) av[i] = getint(p); + if(!OUTBORD(x,y) && xs > 0 && ys > 0 && !OUTBORD(x + xs-1, y + ys - 1)) + { + block b = { x, y, xs, ys }; + archxy(a1, av, b); } break; } @@ -937,8 +958,8 @@ void parsemessages(int cn, playerent *d, ucharbuf &p, bool demo = false) case SV_NEWMAP: { int size = getint(p); - if(size>=0) empty_world(size, true); - else empty_world(-1, true); + if(size < 0 && sfactor > 9) break; // don't enlarge over 10 in MP + empty_world(size, true); if(d && d!=player1) conoutf(size>=0 ? "%s started a new map of size %d" : "%s enlarged the map to size %d", colorname(d), sfactor); break; diff --git a/source/src/editing.cpp b/source/src/editing.cpp index 0357e267..dde5acb8 100644 --- a/source/src/editing.cpp +++ b/source/src/editing.cpp @@ -689,7 +689,7 @@ void editheight(int *flr, int *amount) loopv(sels) { editheightxy(isfloor, *amount, sels[i]); - addmsg(SV_EDITH, "ri6", sels[i].x, sels[i].y, sels[i].xs, sels[i].ys, isfloor, *amount); + addmsg(SV_EDITXY, "ri7", EDITXY_HEIGHT, sels[i].x, sels[i].y, sels[i].xs, sels[i].ys, isfloor, *amount); } } @@ -765,7 +765,7 @@ void edittex(int *type, int *dir) loopv(sels) { edittexxy(*type, t, sels[i]); - addmsg(SV_EDITT, "ri6", sels[i].x, sels[i].y, sels[i].xs, sels[i].ys, *type, t); + addmsg(SV_EDITXY, "ri7", EDITXY_TEX, sels[i].x, sels[i].y, sels[i].xs, sels[i].ys, *type, t, 0); } unsavededits++; lastedittex = lastmillis; @@ -791,7 +791,7 @@ void settex(int *texture, int *type) loopv(sels) { edittexxy(*type, t, sels[i]); - addmsg(SV_EDITT, "ri6", sels[i].x, sels[i].y, sels[i].xs, sels[i].ys, *type, t); + addmsg(SV_EDITXY, "ri7", EDITXY_TEX, sels[i].x, sels[i].y, sels[i].xs, sels[i].ys, *type, t, 0); } unsavededits++; } @@ -833,7 +833,7 @@ void edittype(int type) else { edittypexy(type, sel); - addmsg(SV_EDITS, "ri5", sel.x, sel.y, sel.xs, sel.ys, type); + addmsg(SV_EDITXY, "ri7", EDITXY_TYPE, sel.x, sel.y, sel.xs, sel.ys, type, 0); } } } @@ -869,7 +869,7 @@ void equalize(int *flr) { block &sel = sels[i]; editequalisexy(isfloor, sel); - addmsg(SV_EDITE, "ri5", sel.x, sel.y, sel.xs, sel.ys, isfloor); + addmsg(SV_EDITXY, "ri7", EDITXY_EQUALISE, sel.x, sel.y, sel.xs, sel.ys, isfloor, 0); } } COMMAND(equalize, "i"); @@ -886,7 +886,7 @@ void setvdelta(int *delta) loopv(sels) { setvdeltaxy(*delta, sels[i]); - addmsg(SV_EDITD, "ri5", sels[i].x, sels[i].y, sels[i].xs, sels[i].ys, *delta); + addmsg(SV_EDITXY, "ri7", EDITXY_VDELTA, sels[i].x, sels[i].y, sels[i].xs, sels[i].ys, *delta, 0); } } COMMANDN(vdelta, setvdelta, "i"); @@ -907,9 +907,18 @@ void archvertex(int *span, int *vert, int *delta) } COMMAND(archvertex, "iii"); +void archxy(int sidedelta, int *averts, block &sel) +{ + loopselxy(sel, s->vdelta = + sel.xs>sel.ys + ? (averts[x] + (y==0 || y==sel.ys-1 ? sidedelta : 0)) + : (averts[y] + (x==0 || x==sel.xs-1 ? sidedelta : 0))); + remipmore(sel); +} + void arch(int *sidedelta) { - EDITSELMP; + EDITSEL; loopv(sels) { block &sel = sels[i]; @@ -917,28 +926,32 @@ void arch(int *sidedelta) sel.ys++; if(sel.xs>MAXARCHVERT) sel.xs = MAXARCHVERT; if(sel.ys>MAXARCHVERT) sel.ys = MAXARCHVERT; - loopselxy(sel, s->vdelta = - sel.xs>sel.ys - ? (archverts[sel.xs-1][x] + (y==0 || y==sel.ys-1 ? *sidedelta : 0)) - : (archverts[sel.ys-1][y] + (x==0 || x==sel.xs-1 ? *sidedelta : 0))); - remipmore(sel); + int *averts = sel.xs > sel.ys ? &archverts[sel.xs-1][0] : &archverts[sel.ys-1][0]; + addmsg(SV_EDITARCH, "ri5v", sel.x, sel.y, sel.xs, sel.ys, *sidedelta, MAXARCHVERT, averts); + archxy(*sidedelta, averts, sel); // (changes xs and ys) } } COMMAND(arch, "i"); +void slopexy(int xd, int yd, block &sel) +{ + int off = 0; + if(xd < 0) off -= xd * sel.xs; + if(yd < 0) off -= yd * sel.ys; + sel.xs++; + sel.ys++; + loopselxy(sel, s->vdelta = xd * x + yd * y + off); + remipmore(sel); +} + void slope(int *xd, int *yd) { - EDITSELMP; + EDITSEL; loopv(sels) { block &sel = sels[i]; - int off = 0; - if(*xd < 0) off -= *xd * sel.xs; - if(*yd < 0) off -= *yd * sel.ys; - sel.xs++; - sel.ys++; - loopselxy(sel, s->vdelta = *xd * x + *yd * y + off); - remipmore(sel); + addmsg(SV_EDITXY, "ri7", EDITXY_SLOPE, sel.x, sel.y, sel.xs, sel.ys, *xd, *yd); + slopexy(*xd, *yd, sel); // (changes xs and ys) } } COMMAND(slope, "ii"); @@ -971,10 +984,19 @@ VARF(fullbright, 0, 0, 1, else calclight(); ); +void edittagxy(int orv, int andv, block &sel) +{ + loopselxy(sel, s->tag = (s->tag & andv) | orv); +} + void edittag(int *tag) { - EDITSELMP; - loopselsxy(s->tag = *tag); + EDITSEL; + loopv(sels) + { + edittagxy(*tag, 0, sels[i]); + addmsg(SV_EDITXY, "ri7", EDITXY_TAG, sels[i].x, sels[i].y, sels[i].xs, sels[i].ys, *tag, 0); + } } COMMAND(edittag, "i"); @@ -984,8 +1006,12 @@ void edittagclip(char *tag) if(tolower(*tag) == 'n') nt = 0; // "none", "nil, "nop" else if(!strncasecmp(tag, "pl", 2)) nt = TAGPLCLIP; // "playerclip", "plclip", "pl" else if(isalpha(*tag)) nt = TAGCLIP; // "clip", "all", "full", "hippo" - EDITSELMP; - loopselsxy(s->tag = (s->tag & TAGTRIGGERMASK) | nt); + EDITSEL; + loopv(sels) + { + edittagxy(nt, TAGTRIGGERMASK, sels[i]); + addmsg(SV_EDITXY, "ri7", EDITXY_TAG, sels[i].x, sels[i].y, sels[i].xs, sels[i].ys, nt, TAGTRIGGERMASK); + } } COMMAND(edittagclip, "s"); @@ -1068,23 +1094,32 @@ void selfliprotate(block &sel, int dir) void selectionrotate(int *dir) { - EDITSELMP; + EDITSEL; *dir &= 3; if(!*dir) return; loopv(sels) { block &sel = sels[i]; - if(sel.xs == sel.ys || *dir == 2) selfliprotate(sel, *dir); + if(sel.xs == sel.ys || *dir == 2) + { + selfliprotate(sel, *dir); + addmsg(SV_EDITXY, "ri7", EDITXY_FLIPROT, sel.x, sel.y, sel.xs, sel.ys, *dir, 0); + } } } COMMAND(selectionrotate, "i"); void selectionflip(char *axis) { - EDITSELMP; + EDITSEL; char c = toupper(*axis); if(c != 'X' && c != 'Y') return; - loopv(sels) selfliprotate(sels[i], c == 'X' ? 11 : 12); + int dir = c == 'X' ? 11 : 12; + loopv(sels) + { + selfliprotate(sels[i], dir); + addmsg(SV_EDITXY, "ri7", EDITXY_FLIPROT, sels[i].x, sels[i].y, sels[i].xs, sels[i].ys, dir, 0); + } } COMMAND(selectionflip, "s"); diff --git a/source/src/protocol.cpp b/source/src/protocol.cpp index faf578f2..2a582cd6 100644 --- a/source/src/protocol.cpp +++ b/source/src/protocol.cpp @@ -337,7 +337,7 @@ static const int msgsizes[] = // size inclusive message token, 0 f SV_DISCSCORES, 0, SV_TIMEUP, 3, SV_EDITENT, 13, SV_ITEMACC, 2, SV_MAPCHANGE, 0, SV_ITEMSPAWN, 2, SV_ITEMPICKUP, 2, SV_PING, 2, SV_PONG, 2, SV_CLIENTPING, 2, SV_GAMEMODE, 2, - SV_EDITMODE, 2, SV_EDITH, 7, SV_EDITT, 7, SV_EDITS, 6, SV_EDITD, 6, SV_EDITE, 6, SV_NEWMAP, 2, + SV_EDITMODE, 2, SV_EDITXY, 8, SV_EDITARCH, 56, SV_EDITS, 6, SV_EDITD, 6, SV_EDITE, 6, SV_NEWMAP, 2, SV_SENDMAP, 0, SV_RECVMAP, 1, SV_REMOVEMAP, 0, SV_SERVMSG, 0, SV_ITEMLIST, 0, SV_WEAPCHANGE, 2, SV_PRIMARYWEAP, 2, SV_FLAGACTION, 3, SV_FLAGINFO, 0, SV_FLAGMSG, 0, SV_FLAGCNT, 3, diff --git a/source/src/protocol.h b/source/src/protocol.h index b03db516..5e2b139c 100644 --- a/source/src/protocol.h +++ b/source/src/protocol.h @@ -29,7 +29,7 @@ enum SV_DISCSCORES, SV_TIMEUP, SV_EDITENT, SV_ITEMACC, SV_MAPCHANGE, SV_ITEMSPAWN, SV_ITEMPICKUP, SV_PING, SV_PONG, SV_CLIENTPING, SV_GAMEMODE, - SV_EDITMODE, SV_EDITH, SV_EDITT, SV_EDITS, SV_EDITD, SV_EDITE, SV_NEWMAP, + SV_EDITMODE, SV_EDITXY, SV_EDITARCH, SV_EDITS, SV_EDITD, SV_EDITE, SV_NEWMAP, SV_SENDMAP, SV_RECVMAP, SV_REMOVEMAP, SV_SERVMSG, SV_ITEMLIST, SV_WEAPCHANGE, SV_PRIMARYWEAP, SV_FLAGACTION, SV_FLAGINFO, SV_FLAGMSG, SV_FLAGCNT, @@ -66,7 +66,7 @@ enum { FTR_INFO = 0, FTR_PLAYERWISH, FTR_AUTOTEAM, FTR_SILENTFORCE, FTR_NUM }; / enum { SP_OK = 0, SP_REFILLMATCH, SP_OK_NUM, SP_WRONGMAP, SP_SPECT, SP_NUM }; // spawn permission ( 9) return false; if(factor == -2 && !worldbordercheck(ssize/4 + MINBORD, ssize/4 + MINBORD, ssize/4 + MINBORD, ssize/4 + MINBORD, 0, 0)) { conoutf("map does not fit into smaller world"); return false; } block *ow = NULL, be = { 0, 0, ssize, ssize }, bs = { ssize/4, ssize/4, ssize/2, ssize/2 }; int oldfactor = sfactor;