[Download] 1.2 Mapping Client
#14
(13 Aug 14, 11:28PM)Felix-The-Ghost Wrote:
(14 Jun 14, 02:23AM)+f0r3v3r+ Wrote:
(13 Jun 14, 03:39PM)Music Wrote: Why don't you just release the source code?
^ This

Diff - based on 1.2.0.2 source

Code:
--- audiomanager.cpp Tue Oct 22 13:57:19 2013 +++ audiomanager.cpp Wed Apr 02 17:25:06 2014 @@ -554,7 +554,7 @@ // main audio update routine void audiomanager::updateaudio() -{ +{ if(nosound) return; alcSuspendContext(context); // don't process sounds while we mess around @@ -606,7 +606,7 @@ { entity &e = ents[i]; vec o(e.x, e.y, e.z); - if(e.type!=SOUND) continue; + if(e.type!=SOUND) continue; int sound = e.attr1; int radius = e.attr2; --- clientgame.cpp Tue Oct 22 13:57:19 2013 +++ clientgame.cpp Fri Apr 11 14:43:34 2014 @@ -1116,10 +1116,13 @@ COMMAND(showmapstats, ""); VARP(showmodedescriptions, 0, 1, 1); -extern bool canceldownloads; +extern bool canceldownloads; + +extern bool lockselent; void startmap(const char *name, bool reset) // called just after a map load -{ +{ + lockselent = false; canceldownloads = false; copystring(clientmap, name); sendmapidenttoserver = true; --- cube.h Sat Nov 09 17:56:31 2013 +++ cube.h Mon May 19 23:38:03 2014 @@ -43,7 +43,8 @@ extern vector<int> eh_ents; // edithide entities extern vec worldpos, camup, camright, camdir; // current target of the crosshair in the world extern int lastmillis, totalmillis, nextmillis; // last time -extern int curtime; // current frame time +extern int curtime; // current frame time +extern int globalfps; extern int interm; extern int gamemode, nextmode; extern int gamespeed; --- editing.cpp Tue Oct 22 13:57:16 2013 +++ editing.cpp Sat Jun 07 00:41:10 2014 @@ -3,12 +3,20 @@ #include "cube.h" bool editmode = false; + +int globalfps = 0; // the current selections, used by almost all editing commands // invariant: all code assumes that these are kept inside MINBORD distance of the edge of the map // => selections are checked when they are made or when the world is reloaded -vector<block> sels; +VAR(cleanedit, 0, 0, 1); +COMMANDF(togglecleanedit, "", () {cleanedit = !cleanedit;}); + +COMMANDF(clearrecenttex, "", () {loopk(3) loopi(256) hdr.texlists[k][i] = i;}); + +vector<block> sels; +vector<block> s_sels; //saved selections #define loopselxy(sel, b) { makeundo(sel); loop(x,(sel).xs) loop(y,(sel).ys) { sqr *s = S((sel).x+x, (sel).y+y); b; } remip(sel); } #define loopselsxy(b) { loopv(sels) loopselxy(sels[i], b); } @@ -70,6 +78,20 @@ } return !editmode; } + +void savesel() +{ + s_sels = sels; +} + +void reselect() +{ + sels = s_sels; +} + +COMMAND (savesel, ""); +COMMAND (reselect, ""); + inline bool selset() { @@ -81,6 +103,48 @@ if(!selset()) conoutf("no selection"); return !selset(); } + +const char *entcolor(int index) // helper function for editinfo() +{ + entity &e = ents[index]; + + switch(e.type) + { + case 2: // playerstart + if (e.attr2 == 0) // CLA + return "3"; + + else if (e.attr2 == 1) // RVSF + return "1"; + + else return "J"; // FFA + + case 3: case 4: case 5: case 9: return "9"; // pistol clip, ammobox, grenade, akimbo + case 6: case 7: case 8: return "H"; // health pack, helmet, armor + case 10: return "T"; // mapmodel + + case 12: return "M"; // ladder + + case 13: // ctf-flag + if (e.attr2 == 0) // CLA + return "3"; + + else if (e.attr2 == 1) // RVSF + return "1"; + break; + + case 14: return "P"; // sound + + case 15: return "2"; // clip + case 16: return "X"; // plclip + + default: + return "5"; // white + } + return "5"; // white +} + +extern bool lockselent; char *editinfo() { @@ -88,14 +152,43 @@ if(!editmode) return NULL; int e = closestent(); if(e<0) return NULL; - entity &c = ents[e]; + entity &c = ents[e]; + string selinfo = "no selection"; - if(selset()) formatstring(selinfo)("selection = (%d, %d)", (sels.last()).xs, (sels.last()).ys); - formatstring(info)("closest entity = %s (%d, %d, %d, %d), %s", entnames[c.type], c.attr1, c.attr2, c.attr3, c.attr4, selinfo); + if(selset()) formatstring(selinfo)("selection = (%d, %d)", (sels.last()).xs, (sels.last()).ys); + + string fileinfo = ""; + switch (c.type) + { + case SOUND: + if (mapsounds.inrange(c.attr1)) + formatstring(fileinfo)("\n%s", mapsounds[c.attr1].buf->name); + else + formatstring(fileinfo)("\n\f7unregistered sound\f5"); + break; + + case MAPMODEL: + { + mapmodelinfo &mmi = getmminfo(c.attr2); + if (&mmi) + formatstring(fileinfo)("\n%s", mmi.name); + else + formatstring(fileinfo)("\n\f7unregistered mapmodel\f5"); + } + break; + + default: + break; + } + + if (!lockselent) + formatstring(info)("closest entity:\n\f%s%s\f5 (%d, %d, %d, %d), %s %s", entcolor(e), entnames[c.type], c.attr1, c.attr2, c.attr3, c.attr4, selinfo, fileinfo); + else + formatstring(info)("selected entity:\n\f%s%s\f5 (%d, %d, %d, %d), %s %s", entcolor(e), entnames[c.type], c.attr1, c.attr2, c.attr3, c.attr4, selinfo, fileinfo); + return info; } - #define EDITSEL if(noteditmode("EDITSEL") || noselection()) return #define EDITSELMP if(noteditmode("EDITSELMP") || noselection() || multiplayer()) return #define EDITMP if(noteditmode("EDITMP") || multiplayer()) return @@ -150,87 +243,182 @@ // VC8 optimizer screws up rendering somehow if this is an actual function #define sheight(s,t,z) (!flrceil ? (s->type==FHF ? s->floor-t->vdelta/4.0f : (float)s->floor) : (s->type==CHF ? s->ceil+t->vdelta/4.0f : (float)s->ceil)) - -void cursorupdate() // called every frame from hud -{ - flrceil = ((int)(camera1->pitch>=0))*2; - int cyaw = ((int) camera1->yaw) % 180; - editaxis = editmode ? (fabs(camera1->pitch) > 65 ? 13 : (cyaw < 45 || cyaw > 135 ? 12 : 11)) : 0; - - volatile float x = worldpos.x; // volatile needed to prevent msvc7 optimizer bug? - volatile float y = worldpos.y; - volatile float z = worldpos.z; - - cx = (int)x; - cy = (int)y; - - if(OUTBORD(cx, cy)) return; - sqr *s = S(cx,cy); - - if(fabs(sheight(s,s,z)-z)>1) // selected wall - { - x += x>camera1->o.x ? 0.5f : -0.5f; // find right wall cube - y += y>camera1->o.y ? 0.5f : -0.5f; - - cx = (int)x; - cy = (int)y; - - if(OUTBORD(cx, cy)) return; - } - - if(dragging) { makesel(false); }; - - const int GRIDSIZE = 5; - const float GRIDW = 0.5f; - const float GRID8 = 2.0f; - const float GRIDS = 2.0f; - const int GRIDM = 0x7; - - // render editing grid - - if(showgrid) - { - for(int ix = cx-GRIDSIZE; ix<=cx+GRIDSIZE; ix++) for(int iy = cy-GRIDSIZE; iy<=cy+GRIDSIZE; iy++) - { - - if(OUTBORD(ix, iy)) continue; - sqr *s = S(ix,iy); - if(SOLID(s)) continue; - float h1 = sheight(s, s, z); - float h2 = sheight(s, SWS(s,1,0,sfactor), z); - float h3 = sheight(s, SWS(s,1,1,sfactor), z); - float h4 = sheight(s, SWS(s,0,1,sfactor), z); - if(s->tag) linestyle(GRIDW, 0xFF, 0x40, 0x40); - else if(s->type==FHF || s->type==CHF) linestyle(GRIDW, 0x80, 0xFF, 0x80); - else linestyle(GRIDW, 0x80, 0x80, 0x80); - block b = { ix, iy, 1, 1 }; - box(b, h1, h2, h3, h4); - linestyle(GRID8, 0x40, 0x40, 0xFF); - if(!(ix&GRIDM)) line(ix, iy, h1, ix, iy+1, h4); - if(!((ix+1)&GRIDM)) line(ix+1, iy, h2, ix+1, iy+1, h3); - if(!(iy&GRIDM)) line(ix, iy, h1, ix+1, iy, h2); - if(!((iy+1)&GRIDM)) line(ix, iy+1, h4, ix+1, iy+1, h3); - } - - if(!SOLID(s)) - { - float ih = sheight(s, s, z); - linestyle(GRIDS, 0xFF, 0xFF, 0xFF); - block b = { cx, cy, 1, 1 }; - box(b, ih, sheight(s, SWS(s,1,0,sfactor), z), sheight(s, SWS(s,1,1,sfactor), z), sheight(s, SWS(s,0,1,sfactor), z)); - linestyle(GRIDS, 0xFF, 0x00, 0x00); - dot(cx, cy, ih); - ch = (int)ih; - } - } - - if(selset()) - { - linestyle(GRIDS, 0xFF, 0x40, 0x40); - loopv(sels) box(sels[i], (float)sels[i].h, (float)sels[i].h, (float)sels[i].h, (float)sels[i].h); - } - - glLineWidth(1); + +int gridalpha = 255; +int delay = 128; +float old_p, old_y; + +void cursorupdate() // called every frame from hud +{ + if (old_p != camera1->pitch || old_y != camera1->yaw) + {gridalpha = 255; delay = 128;} + else + { + delay -= ((255 / globalfps) + 1 ); + if (delay < 0) delay = 0; + + if (!delay) + gridalpha -= ((gridalpha * 3 / globalfps) + 1 ); + + if (gridalpha < 0) + gridalpha = 0; + } + + if (!gridalpha) + return; + + old_p = camera1->pitch; + old_y = camera1->yaw; + + flrceil = ((int)(camera1->pitch>=0))*2; + int cyaw = ((int) camera1->yaw) % 180; + editaxis = editmode ? (fabs(camera1->pitch) > 65 ? 13 : (cyaw < 45 || cyaw > 135 ? 12 : 11)) : 0; + + volatile float x = worldpos.x; // volatile needed to prevent msvc7 optimizer bug? + volatile float y = worldpos.y; + volatile float z = worldpos.z; + + cx = (int)x; + cy = (int)y; + + if (OUTBORD(cx, cy)) return; + sqr *s = S(cx,cy); + + if(fabs(sheight(s,s,z)-z)>1) // selected wall + { + x += x>camera1->o.x ? 0.5f : -0.5f; // find right wall cube + y += y>camera1->o.y ? 0.5f : -0.5f; + + cx = (int)x; + cy = (int)y; + + if(OUTBORD(cx, cy)) return; + } + + if(dragging) { makesel(false); }; + + const int GRIDSIZE = 5; + const float GRIDW = 0.5f; + const float GRID8 = 2.0f; + const float GRIDS = 2.0f; + const int GRIDM = 0x7; + + // render editing grid + + glEnable(GL_BLEND); + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + for(int ix = cx-GRIDSIZE; ix<=cx+GRIDSIZE; ix++) for(int iy = cy-GRIDSIZE; iy<=cy+GRIDSIZE; iy++) + { + if(OUTBORD(ix, iy)) continue; + sqr *s = S(ix,iy); + + //if(SOLID(s)) continue; + + float h1 = sheight(s, s, z); + float h2 = sheight(s, SWS(s,1,0,sfactor), z); + float h3 = sheight(s, SWS(s,1,1,sfactor), z); + float h4 = sheight(s, SWS(s,0,1,sfactor), z); + + /** "Tag" cube style **/ + + if(s->tag) + { + glLineWidth(GRIDW); + glColor4ub(0x40, 0x40, 0xFF, (unsigned char)gridalpha); + } + + /** Heightfield Style **/ + + else if(s->type==FHF || s->type==CHF) + { + glLineWidth(GRIDW); + glColor4ub(0x80, 0xFF, 0x80, (unsigned char)gridalpha); //green + } + + /** Solid cube style **/ + + else if(SOLID(s)) + { + glLineWidth(GRID8); + glColor4ub(0xAB, 0x40, 0xFE, (unsigned char)gridalpha); //purple + } + + /** Normal cube style **/ + + else + { + glLineWidth(GRIDW); + glColor4ub(0x80, 0x80, 0x80, (unsigned char)gridalpha); //grey + } + + /** Actually drawing the grid **/ + + block b = { ix, iy, 1, 1 }; //set destination coordinates to draw to + box(b, h1, h2, h3, h4); //draw + + /** The repeating 8 x 8 grid **/ + + /* Choosing color **/ + + int temp = 255 - ((255-gridalpha)*3/2); //the thicker blue appears more opaque than other lines + if (temp < 0) temp = 0; + + glLineWidth(GRID8); + glColor4ub(0x40, 0x40, 0xFF, (unsigned char)temp); //blue + + /* Drawing lines on this grid */ + + if(!(ix&GRIDM)) + line(ix, iy, h1, ix, iy+1, h4); + + if(!((ix+1)&GRIDM)) + line(ix+1, iy, h2, ix+1, iy+1, h3); + + if(!(iy&GRIDM)) + line(ix, iy, h1, ix+1, iy, h2); + + if(!((iy+1)&GRIDM)) + line(ix, iy+1, h4, ix+1, iy+1, h3); + } + + /** Draw white square around cube cursor is over **/ + + + float ih = sheight(s, s, z); + { + glLineWidth(GRIDS); + glColor4ub(0xFF, 0xFF, 0xFF, (unsigned char)gridalpha); //white + } + + block b = { cx, cy, 1, 1 }; + box(b, ih, sheight(s, SWS(s,1,0,sfactor), z), sheight(s, SWS(s,1,1,sfactor), z), sheight(s, SWS(s,0,1,sfactor), z)); + + /** And the orienting little square in the corner **/ + + glLineWidth(GRIDS); + glColor4ub(0xFF, 0x00, 0x00, (unsigned char)gridalpha); //red + dot(cx, cy, ih); + + ch = (int)ih; //updates height of selection box (the red boxes) to the correct height + + /** Draw selection(s) **/ + + if(selset()) + { + /* Choosing color */ + + glLineWidth(GRIDS); + glColor4ub(0xFF, 0x40, 0x40, (unsigned char)gridalpha); //red + + /* Drawing */ + + loopv(sels) //for each selection + box(sels[i], (float)sels[i].h, (float)sels[i].h, (float)sels[i].h, (float)sels[i].h); + } + + glDisable(GL_BLEND); + glLineWidth(1); } vector<block *> undos; // unlimited undo @@ -308,6 +496,44 @@ remipmore(sel); } } + + +void paste_half() +{ + if(noteditmode("EDITSEL") || noselection()) return; + + if(!copybuffers.length()) { conoutf("nothing to paste"); return; } + + loopv(sels) + { + block &sel = sels[i]; + int selx = sel.x; + int sely = sel.y; + + loopvj(copybuffers) + { + block *copyblock = copybuffers[j]; + int dx = copyblock->x - copybuffers[0]->x, dy = copyblock->y - copybuffers[0]->y; + + sel.xs = copyblock->xs; + sel.ys = copyblock->ys; + sel.x = selx + dx; + sel.y = sely + dy; + + if(!correctsel(sel) || sel.xs!=copyblock->xs || sel.ys!=copyblock->ys) { conoutf("incorrect selection"); return; } + makeundo(sel); + + if (flrceil == 0) + halfblockpaste(*copyblock, sel.x, sel.y, true); + else + halfblockpaste(*copyblock, sel.x, sel.y, false); + } + + remipmore(sel); + } +} + +COMMAND(paste_half, ""); // Count the walls of type "type" contained in the current selection void countwalls(int *type) @@ -338,6 +564,46 @@ } } } + +int getcurtex(const char* pos, const char* x, const char* y); //prototype + +void tex2front(const char* pos) +{ + if (noselection()) + return; + + int t = -1; //type (position) + + if (strcmp(pos, "FLOOR") == 0) t = 0; + else if (strcmp(pos, "WALL") == 0) t = 1; + else if (strcmp(pos, "UPWALL") == 0) t = 3; + else if (strcmp(pos, "CEIL") == 0) t = 2; + else + { + conoutf("\f9ERROR: \f5invalid position argument"); + return; + } + + if (t == 3) t = 1; //walls + + int key = getcurtex(pos, "", ""); + //conoutf("Key is texture slot %i", key); + //conoutf("Searching edit texture lists for match..."); + + loopi(255) + { + if (hdr.texlists[t][i] == key) + { + //conoutf("Match found in position: %i", i); + curedittex[t] = i; + break; + } + } + + tofronttex(); +} + +COMMAND (tex2front, "s"); void editdrag(bool isdown) { @@ -454,6 +720,1002 @@ addmsg(SV_EDITT, "ri6", sels[i].x, sels[i].y, sels[i].xs, sels[i].ys, type, t); } } + +int expandsel(int s) //makes all selections collections of 1 x 1 selections +{ + int count = 0; //number of cubes in selections to remove + + int stop = sels.length(); + int removed = 0; + + for (int i = 0; i < stop; i++) + { + for (int y = sels[i].y; y < sels[i].y + sels[i].ys; y++) //y loop + for (int x = sels[i].x; x < sels[i].x + sels[i].xs; x++) //x loop + { + addselection(x, y, 1, 1, sels[i].h); + + if (i >= stop - s) //selections to remove + count++; + } + + sels.remove(i); + i--; + stop--; + removed++; + } + + + return count; +} + +void compress_sel(int s) //combines adjacent selections (1 x 1 selections only) +{ + EDITSEL; + + int min_x = 0; + int min_y = 0; + + int max_x = 0; + int max_y = 0; + int max_h = 0; + + int x; + int y; + int h; + + /** Initialize selections map **/ + + loopv(sels) + { + if (i == 0) //initialize bounds + { + min_x = sels[i].x + sels[i].xs; + max_x = sels[i].x + sels[i].xs; + min_y = sels[i].y + sels[i].ys; + max_y = sels[i].y + sels[i].ys; + max_h = sels[i].h; + } + + x = sels[i].x + sels[i].xs; + y = sels[i].y + sels[i].ys; + h = sels[i].h; + + if (x < min_x) min_x = x; + + if (x > max_x) max_x = x; + + if (y < min_y) min_y = y; + + if (y > max_y) max_y = y; + + if (h > max_h) max_h = h; + } + + bool cubemap [2 + (max_y - min_y)][2 + (max_x - min_x)]; + memset(cubemap, false, sizeof(cubemap)); + + for(int i = 0; i<sels.length(); i++) + { + if (i < sels.length()-s) + cubemap[sels[i].y + sels[i].ys - min_y] [sels[i].x + sels[i].xs - min_x] = true; + else + cubemap[sels[i].y + sels[i].ys - min_y] [sels[i].x + sels[i].xs - min_x] = false; + } + + /** reselect rows of cubes according to map **/ + + resetselections(); + + int slice_start; //first cube in a horizontal selection slice + + for (y = 0; y < (max_y - min_y) + 1; y++) + { + slice_start = -1; + + for (x = 0; x < (max_x - min_x) + 1; x++) + { + if (cubemap[y][x]) + { + if (slice_start < 0) + slice_start = x; + } + else + { + if (slice_start > -1) + addselection(min_x + slice_start - 1, min_y + y - 1, x - slice_start, 1, max_h); + + slice_start = -1; + continue; + } + + if ((x + 1 >= (max_x - min_x) + 1) && slice_start > -1) + addselection(min_x + slice_start - 1, min_y + y - 1, x - slice_start + 1, 1, max_h); + } + } + + /** combine rows of equal length vertically adjacent to each other **/ + + int y2; + + loopv (sels) //i loop + loopvj (sels) //j loop + { + if (sels[i].x == sels[j].x) //same x coordinate + if (sels[i].y == sels[j].y + sels[j].ys || sels[j].y == sels[i].y + sels[i].ys) //vertically adjacent + if (sels[i].xs == sels[j].xs) //same length + { + min_y = sels[i].y; + max_y = sels[i].y + sels[i].ys; + max_h = sels[i].h; + + y = sels[j].y; + y2 = sels[j].y + sels[j].ys; + h = sels[j].h; + + if (y < min_y) min_y = y; + if (y > max_y) max_y = y; + if (y2 < min_y) min_y = y2; + if (y2 > max_y) max_y = y2; + if (h > max_h) max_h = h; + + addselection(sels[i].x, min_y, sels[i].xs, max_y - min_y, max_h); + + sels.remove(i); + + if (i < j) //if deleting i offset j + sels.remove(j - 1); + else + sels.remove(j); + + i = 0; + break; //exit this j loop, go to next j loop, of i loop + } + } +} + +void fixselh () +{ + bool fc; + + if (flrceil == 0) fc = false; //floor + else fc = true; + + sqr *s1; + sqr *s2; + + loopv (sels) + { + s1 = S(sels[i].x, sels[i].y); + s2 = S(sels[i].x + sels[i].xs - 1, sels[i].y + sels[i].ys - 1); + + if(!fc) //finding max floor height + { + if (s1->floor > s2->floor) + sels[i].h = s1->floor; + else + sels[i].h = s2->floor; + } + else //finding max ceiling height + { + if (s1->ceil > s2->ceil) + sels[i].h = s1->ceil; + else + sels[i].h = s2->ceil; + } + } +} + +/** expand selections and select only selections matching argument keys **/ + +void filter_sel(const char* type, char* v1, char* v2, char* v3, char* v4, char* v5, char* v6, char* v7) +{ + EDITSEL; + + /** Process filter type **/ + + int filter_type = 0; + + if (strcmp(type, "FLOOR_T") == 0) filter_type = 1; + if (strcmp(type, "WALL_T") == 0) filter_type = 2; + if (strcmp(type, "UPWALL_T") == 0) filter_type = 3; + if (strcmp(type, "CEIL_T") == 0) filter_type = 4; + if (strcmp(type, "FLOOR_H") == 0) filter_type = 5; + if (strcmp(type, "CEIL_H") == 0) filter_type = 6; + if (strcmp(type, "DISSOLVE") == 0) filter_type = 7; + if (strcmp(type, "SOLID") == 0) filter_type = 8; + if (strcmp(type, "HEIGHTFIELD") == 0) filter_type = 9; + if (strcmp(type, "CORNER") == 0) filter_type = 10; + if (strcmp(type, "SPACE") == 0) filter_type = 11; + if (strcmp(type, "SUBTRACT") == 0) filter_type = 12; + if (strcmp(type, "MERGE") == 0) filter_type = 13; + + if (filter_type == 0) + { + conoutf("\f9ERROR: \f5invalid filter type"); + return; + } + + /** Count value arguments **/ + + int num_v = 0; + + if (strcmp(v1, "") != 0) num_v++; + + if (strcmp(v2, "") != 0) num_v++; + + if (strcmp(v3, "") != 0) num_v++; + + if (strcmp(v4, "") != 0) num_v++; + + if (strcmp(v5, "") != 0) num_v++; + + if (strcmp(v6, "") != 0) num_v++; + + if (strcmp(v7, "") != 0) num_v++; + + if (num_v < 1 && filter_type != 12 && filter_type != 13) + { + conoutf("\f9ERROR: \f5this filter requires at least one key value"); + return; + } + + int v [num_v]; + + if (num_v > 0) v[0] = atoi(v1); + if (num_v > 1) v[1] = atoi(v2); + if (num_v > 2) v[2] = atoi(v3); + if (num_v > 3) v[3] = atoi(v4); + if (num_v > 4) v[4] = atoi(v5); + if (num_v > 5) v[5] = atoi(v6); + if (num_v > 6) v[6] = atoi(v7); + + int count = 0; + + if (strcmp(v1, "") != 0) + count = expandsel(v[0]); //expand selections to 1 x 1 selections + else + count = expandsel(1); + + /** filter selection(s) */ + + bool match; //match found + + loopv(sels) + { + sqr *s = S((sels[i]).x, (sels[i]).y); + match = false; + + switch(filter_type) + { + case 1: //floor texture + loopj (num_v) + { + if (s->ftex == v[j]) + { + match = true; + break; + } + } + + //no match by end of iteration + + if (!match) + { + sels.remove(i); + i--; + } + + break; + + case 2: //wall texture + loopj (num_v) + { + if (s->wtex == v[j]) + { + match = true; + break; + } + } + + //no match by end of iteration + + if (!match) + { + sels.remove(i); + i--; + } + + break; + + case 3: // upper wall texture + loopj (num_v) + { + if (s->utex == v[j]) + { + match = true; + break; + } + } + + //no match by end of iteration + + if (!match) + { + sels.remove(i); + i--; + } + + break; + + case 4: //ceiling texture + loopj (num_v) + { + if (s->ctex == v[j]) + { + match = true; + break; + } + } + + //no match by end of iteration + + if (!match) + { + sels.remove(i); + i--; + } + + break; + + case 5: //floor height + loopj (num_v) + { + if (s->floor == v[j]) + { + match = true; + break; + } + } + + //no match by end of iteration + + if (!match) + { + sels.remove(i); + i--; + } + + break; + + case 6: //ceiling height + loopj (num_v) + { + if (s->ceil == v[j]) + { + match = true; + break; + } + } + + //no match by end of iteration + + if (!match) + { + sels.remove(i); + i--; + } + + break; + + case 7: //dissolve + if (1 + rand()%99 < v[0]) //frequency + { + sels.remove(i); + i--; + } + break; + + case 8: //solid + if (v[0] < 1) //if / if not + { + if (s->type == SOLID) + { + sels.remove(i); + i--; + } + } + else if (s->type != SOLID) + { + sels.remove(i); + i--; + } + break; + + case 9: //heightfield + if (v[0] < 1) //if / if not + { + if (s->type == FHF || s->type == CHF) + { + sels.remove(i); + i--; + } + } + else if (s->type != FHF && s->type != CHF) + { + sels.remove(i); + i--; + } + break; + + case 10: //corner + if (v[0] < 1) //if / if not + { + if (s->type == CORNER) + { + sels.remove(i); + i--; + } + } + else if (s->type != CORNER) + { + sels.remove(i); + i--; + } + break; + + case 11: //space + if (v[0] < 1) //if / if not + { + if (s->type == SPACE) + { + sels.remove(i); + i--; + } + } + else if (s->type != SPACE) + { + sels.remove(i); + i--; + } + break; + + default: + break; + } + } + + if (!sels.empty()) //if there is a selection to simplify + { + if (filter_type == 12 && count > 0) //remove + compress_sel(count); + else + compress_sel(0); + } + + fixselh(); +} + +COMMAND (filter_sel, "ssssssss"); + +extern float Mh; + +void select_all() +{ + resetselections(); + addselection(mapdims[0] - 1, mapdims[1] - 1, mapdims[2] - mapdims[0] + 3, mapdims[3] - mapdims[1] + 3, Mh); +} + +COMMAND (select_all, ""); + +struct Slot +{ + string name; + float scale; + Texture *tex; + bool loaded; +}; + +extern vector<Slot> slots; + +void texname(const char* pos) +{ + if (noselection()) + { + result("first make a selection"); + return; + } + + sqr *s = 0; //cube + int t = -1; //type + + /** get type to check **/ + + if (strcmp(pos, "FLOOR") == 0) t = 0; + else if (strcmp(pos, "WALL") == 0) t = 1; + else if (strcmp(pos, "UPWALL") == 0) t = 2; + else if (strcmp(pos, "CEIL") == 0) t = 3; + else + { + conoutf("\f9ERROR: \f5invalid position argument"); + result("-1"); + return; + } + + s = S((sels[sels.length() - 1]).x, (sels[sels.length() - 1]).y); + + if (!s) + { + result("error"); + return; + } + + switch (t) + { + case 0: + result(slots[s->ftex].tex->name); + break; + + case 1: + result(slots[s->wtex].tex->name); + break; + + case 2: + result(slots[s->utex].tex->name); + break; + + case 3: + result(slots[s->ctex].tex->name); + break; + + default: + result("error"); + } +} + +COMMAND(texname, "s"); + +int getcurtex(const char* pos, const char* x, const char* y) //returns index of texture slot +{ + /** Count arguments **/ + int num_args = 0; + + if (strcmp(pos, "") != 0) + num_args++; + + if (strcmp(x, "") != 0) + num_args++; + + if (strcmp(y, "") != 0) + num_args++; + + if (num_args == 1) //working from selection + { + if (noselection()) + { + result("-1"); + return -1; + } + } + + if (num_args == 2) + { + conoutf("\f9ERROR: \f5missing Y argument"); + result("-1"); + return -1; + } + + /**/ + + sqr *s = 0; //cube + int t = -1; //type + + /** get type to check **/ + + if (strcmp(pos, "FLOOR") == 0) t = 0; + else if (strcmp(pos, "WALL") == 0) t = 1; + else if (strcmp(pos, "UPWALL") == 0) t = 2; + else if (strcmp(pos, "CEIL") == 0) t = 3; + else + { + conoutf("\f9ERROR: \f5invalid position argument"); + result("-1"); + return -1; + } + + /**/ + + int X = atoi(x); + int Y = atoi(y); + + switch (num_args) + { + case 1: + s = S((sels[sels.length() - 1]).x, (sels[sels.length() - 1]).y); + break; + + case 3: + if (OUTBORD(X, Y)) + { + conoutf("\f9ERROR: \f5coordinates out of bounds"); + result("-1"); + return -1; + } + s = S(X, Y); + break; + + default: + result("-1"); + return -1; + } + + string buf = ""; + + switch (t) + { + case 0: + concatformatstring(buf, "%d ", s->ftex); + result(buf); + return s->ftex; + + case 1: + concatformatstring(buf, "%d ", s->wtex); + result(buf); + return s->wtex; + + case 2: + concatformatstring(buf, "%d ", s->utex); + result(buf); + return s->utex; + + case 3: + concatformatstring(buf, "%d ", s->ctex); + result(buf); + return s->ctex; + + default: + result("-1"); + return -1; + } + + result("-1"); + return -1; +} + +void curtex(const char* pos, const char* x, const char* y) //prints texture slot info +{ + /** Count arguments **/ + + int num_args = 0; + + if (strcmp(pos, "") != 0) + num_args++; + + if (strcmp(x, "") != 0) + num_args++; + + if (strcmp(y, "") != 0) + num_args++; + + if (num_args < 2) //working from selection + { + if (noselection()) + return; + } + + if (num_args == 2) + { + conoutf("\f9ERROR: \f5missing Y argument"); + return; + } + + /**/ + + sqr *s = 0; //cube + int t = -1; //type + + /** get type to check **/ + + if (strcmp(pos, "FLOOR") == 0) t = 0; + else if (strcmp(pos, "WALL") == 0) t = 1; + else if (strcmp(pos, "UPWALL") == 0) t = 2; + else if (strcmp(pos, "CEIL") == 0) t = 3; + else if (strcmp(pos, "ALL") == 0 || num_args == 0) t = 4; + else + { + conoutf("\f9ERROR: \f5invalid position argument"); + return; + } + + /**/ + + int X = atoi(x); + int Y = atoi(y); + + switch (num_args) + { + case 0: + case 1: + s = S((sels[sels.length() - 1]).x, (sels[sels.length() - 1]).y); + break; + + case 3: + + if (OUTBORD(X, Y)) + { + conoutf("\f9ERROR: \f5coordinates out of bounds"); + return; + } + s = S(X, Y); + break; + + default: + return; + } + + switch (t) + { + case 0: + conoutf("The \fPfloor \f5texture of this cube is slot number \fN%i", s->ftex); + conoutf("\fM--------------------------------------------------------------"); + break; + + case 1: + conoutf("The \fPwall \f5texture of this cube is slot number \fN%i", s->wtex); + conoutf("\fM--------------------------------------------------------------"); + break; + + case 2: + conoutf("The \fPupper wall \f5texture of this cube is slot number \fN%i", s->utex); + conoutf("\fM--------------------------------------------------------------"); + break; + + case 3: + conoutf("The \fPceiling \f5texture of this cube is slot number \fN%i", s->ctex); + conoutf("\fM--------------------------------------------------------------"); + break; + + case 4: + conoutf("The \fPfloor \f5texture of this cube is slot number \fN%i", s->ftex); + conoutf("The \fPwall \f5texture of this cube is slot number \fN%i", s->wtex); + conoutf("The \fPupper wall \f5texture of this cube is slot number \fN%i", s->utex); + conoutf("The \fPceiling \f5texture of this cube is slot number \fN%i", s->ctex); + conoutf("\fM--------------------------------------------------------------"); + + default: + return; + } +} + +COMMAND(curtex, "sss"); +COMMAND(getcurtex, "sss"); + +int getcurheight(const char* pos, const char* x, const char* y) //returns height of cubes +{ + /** Count arguments **/ + int num_args = 0; + + if (strcmp(pos, "") != 0) + num_args++; + + if (strcmp(x, "") != 0) + num_args++; + + if (strcmp(y, "") != 0) + num_args++; + + if (num_args < 2) //working from selection + { + if (noselection()) + { + result("-255"); + return -255; + } + + if (num_args == 0) + { + conoutf("\f9ERROR: \f5getcurheight cannot be called with no arguments"); + result("-255"); + return -255; + } + } + + if (num_args == 2) + { + conoutf("\f9ERROR: \f5missing Y argument"); + result("-255"); + return -255; + } + + /**/ + + sqr *s = 0; //cube + int p = -1; //position + + /** get type to check **/ + + if (strcmp(pos, "FLOOR") == 0) p = 0; + else if (strcmp(pos, "CEIL") == 0) p = 1; + else + { + conoutf("\f9ERROR: \f5invalid position argument"); + result("-255"); + return -255; + } + + /** Grab cube **/ + + int X = atoi(x); + int Y = atoi(y); + + switch (num_args) + { + case 1: + s = S((sels[sels.length() - 1]).x, (sels[sels.length() - 1]).y); + break; + + case 3: + if (OUTBORD(X, Y)) + { + conoutf("\f9ERROR: \f5coordinates out of bounds"); + result("-255"); + return -255; + } + s = S(X, Y); + break; + + default: + result("-255"); + return -255; + } + + /** get height **/ + + string buf = ""; + + switch (p) + { + case 0: + concatformatstring(buf, "%d ", s->floor); + result(buf); + return s->floor; + + case 1: + concatformatstring(buf, "%d ", s->ceil); + result(buf); + return s->ceil; + + default: + result("-255"); + return -255; + } + + result("-255"); + return -255; +} + +void curheight(const char* pos, const char* x, const char* y) //prints height of cubes +{ + /** Count arguments **/ + int num_args = 0; + + if (strcmp(pos, "") != 0) + num_args++; + + if (strcmp(x, "") != 0) + num_args++; + + if (strcmp(y, "") != 0) + num_args++; + + if (num_args < 2) //working from selection + { + if (noselection()) + return; + } + + if (num_args == 2) + { + conoutf("\f9ERROR: \f5missing Y argument"); + return; + } + + /**/ + + sqr *s = 0; //cube + int p = -1; //position + + /** get type to check **/ + + if (strcmp(pos, "FLOOR") == 0) p = 0; + else if (strcmp(pos, "CEIL") == 0) p = 1; + else if (num_args == 0 || strcmp(pos, "BOTH") == 0) p = 2; + else + { + conoutf("\f9ERROR: \f5invalid position argument"); + return; + } + + /** Grab cube **/ + + int X = atoi(x); + int Y = atoi(y); + + switch (num_args) + { + case 0: + case 1: + s = S((sels[sels.length() - 1]).x, (sels[sels.length() - 1]).y); + break; + + case 3: + if (OUTBORD(X, Y)) + { + conoutf("\f9ERROR: \f5coordinates out of bounds"); + return; + } + s = S(X, Y); + break; + + default: + return; + } + + /** get height **/ + + switch (p) + { + case 0: + conoutf("The \fPfloor \f5height of this cube is \fN%i", s->floor); + conoutf("\fM--------------------------------------------------------------"); + break; + + case 1: + conoutf("The \fPceiling \f5height of this cube is \fN%i", s->ceil); + conoutf("\fM--------------------------------------------------------------"); + break; + + case 2: + conoutf("The \fPfloor \f5height of this cube is \fN%i", s->floor); + conoutf("The \fPceiling \f5height of this cube is \fN%i", s->ceil); + conoutf("\fM--------------------------------------------------------------"); + + default: + return; + } +} + +COMMAND(getcurheight, "sss"); +COMMAND(curheight, "sss"); + +void undo_sel(char* n) //removes last selection +{ + if (sels.empty()) + { + conoutf("no selections to remove"); + return; + } + + int num; + + if (strcmp(n, "") != 0) num = atoi(n); + else + num = 1; + + while (num > 0) + { + if (sels.empty()) + { + conoutf("no more selections to remove"); + return; + } + + sels.pop(); + num--; + } +} + +COMMAND (undo_sel, "s"); void replace() { @@ -528,6 +1790,42 @@ } COMMAND(equalize, "i"); + +void equalize_sels(int *flr) //equalizes *all* sels instead of *each* sel +{ + bool isfloor = *flr==0; + EDITSEL; + + int hi = 0; + int low = 0; + + loopv(sels) //collect min/max info + { + block &sel = sels[i]; + + loopselxy(sel, + { + if(s->floor<low) low = s->floor; + if(s->ceil>hi) hi = s->ceil; + }); + } + + loopv(sels) //height asignments + { + block &sel = sels[i]; + + loopselxy(sel, + { + if(isfloor) s->floor = low; else s->ceil = hi; + if(s->floor>=s->ceil) s->floor = s->ceil-1; + }); + + addmsg(SV_EDITE, "ri5", sel.x, sel.y, sel.xs, sel.ys, isfloor); + } + +} + +COMMAND(equalize_sels, "i"); void setvdeltaxy(int delta, block &sel) { --- entities.cpp Tue Oct 22 13:57:16 2013 +++ entities.cpp Fri May 23 02:52:06 2014 @@ -3,7 +3,9 @@ #include "cube.h" VAR(showclips, 0, 1, 1); -VAR(showmodelclipping, 0, 0, 1); +VAR(showmodelclipping, 0, 0, 1); + +extern bool cleanedit; vector<entity> ents; vector<int> eh_ents; // edithide entities @@ -26,7 +28,10 @@ } void renderclip(entity &e) -{ +{ + if (cleanedit) + return; + float xradius = max(float(e.attr2), 0.1f), yradius = max(float(e.attr3), 0.1f); vec bbmin(e.x - xradius, e.y - yradius, float(S(e.x, e.y)->floor+e.attr1)), bbmax(e.x + xradius, e.y + yradius, bbmin.z + max(float(e.attr4), 0.1f)); @@ -124,7 +129,10 @@ COMMAND(seteditshow, "s"); void renderentarrow(const entity &e, const vec &dir, float radius) -{ +{ + if (cleanedit) + return; + if(radius <= 0) return; float arrowsize = min(radius/8, 0.5f); vec epos(e.x, e.y, e.z); @@ -153,11 +161,13 @@ glEnable(GL_CULL_FACE); glEnable(GL_TEXTURE_2D); } + +extern int globalfps; void renderentities() { int closest = editmode ? closestent() : -1; - if(editmode && !reflecting && !refracting && !stenciling) + if(editmode && !reflecting && !refracting && !stenciling && !cleanedit) { static int lastsparkle = 0; if(lastmillis - lastsparkle >= 20) @@ -174,29 +184,49 @@ vec v(e.x, e.y, e.z); if(vec(v).sub(camera1->o).dot(camdir) < 0) continue; //particle_splash(i == closest ? PART_ELIGHT : PART_ECLOSEST, 2, 40, v); - int sc = PART_ECARROT; // "carrot" (orange) - entity slot currently unused, possibly "reserved" + int sc = PART_ELIGHT; if(i==closest) { - sc = PART_ECLOSEST; // blue - } - else switch(e.type) + sc = PART_ECLOSEST; // smoke + particle_splash(PART_ECLOSEST, 1, 80, v); + } + + switch(e.type) { - case LIGHT : sc = PART_ELIGHT; break; // white - case PLAYERSTART: sc = PART_ESPAWN; break; // green + case LIGHT : sc = PART_ELIGHT; break; // white + + case PLAYERSTART: + if (e.attr2 == 0) + {sc = PART_RED; break;} // CLA + else if (e.attr2 == 1) + {sc = PART_BLUE; break;} // RVSF + else + sc = PART_GREEN; break; // FFA + case I_CLIPS: - case I_AMMO: - case I_GRENADE: sc = PART_EAMMO; break; // red + case I_AMMO: + case I_AKIMBO: + case I_GRENADE: sc = PART_EAMMO; break; // orange case I_HEALTH: case I_HELMET: - case I_ARMOUR: - case I_AKIMBO: sc = PART_EPICKUP; break; // yellow - case MAPMODEL: - case SOUND: sc = PART_EMODEL; break; // magenta - case LADDER: - case CLIP: - case PLCLIP: sc = PART_ELADDER; break; // grey - case CTF_FLAG: sc = PART_EFLAG; break; // turquoise - default: break; + case I_ARMOUR: sc = PART_EPICKUP; break; // yellow + case MAPMODEL: sc = PART_EMODEL; break; // magenta + case LADDER: sc = PART_ELADDER; break; // grey + + case CLIP: sc = PART_CLIP; break; // yellow (color of the clip) + case PLCLIP: sc = PART_PLCLIP; break; // magenta (color of the clip) + + case CTF_FLAG: + if (e.attr2 == 0) // CLA + {sc = PART_RED; break;} + else if (e.attr2 == 1) // RVSF + {sc = PART_BLUE; break;} + else + {sc = PART_ELIGHT; break;} + + default: break; + + case SOUND: sc = 22; break; // cyan } //particle_splash(sc, i==closest?6:2, i==closest?120:40, v); particle_splash(sc, 2, 40, v); @@ -240,8 +270,14 @@ switch(e.type) { case PLAYERSTART: - { - glColor3f(0, 1, 1); + { + if (e.attr2 == 0) + glColor3f(1, 0, 0); // CLA + else if (e.attr2 == 1) + glColor3f(0, 0, 1); // RVSF + else + glColor3f(0, 1, 0); // FFA + vec dir; vecfromyawpitch(e.attr1, 0, -1, 0, dir); renderentarrow(e, dir, 4); --- main.cpp Tue Oct 29 04:33:15 2013 +++ main.cpp Mon May 19 23:38:43 2014 @@ -1280,7 +1280,9 @@ serverslice(0); if(elapsed) fps = (1000.0f/elapsed+fps*10)/11; // avoid DIV-by-0 - frames++; + frames++; + + globalfps = fps; audiomgr.updateaudio(); @@ -1322,4 +1324,4 @@ } VAR(version, 1, AC_VERSION, 0); -VAR(protocol, 1, PROTOCOL_VERSION, 0); \ No newline at end of file +VAR(protocol, 1, PROTOCOL_VERSION, 0); --- Makefile Sat Nov 09 18:12:11 2013 +++ Makefile Wed Apr 16 20:37:19 2014 @@ -1,6 +1,12 @@ -CXXFLAGS= -O3 -fomit-frame-pointer -CXX=clang++ # Use clang++, as g++ optimizations cause crashes... -override CXXFLAGS+= -Wall -fsigned-char + + +CXXFLAGS= -O3 -fomit-frame-pointer -Wno-unused-variable +ifneq (,$(findstring MINGW,$(PLATFORM))) + CXXFLAGS+= -Wall -fsigned-char +else + CXX=clang++ # Use clang++, as g++ optimizations cause crashes... + override CXXFLAGS+= -Wall -fsigned-char +endif PLATFORM= $(shell uname -s) PLATFORM_PREFIX=native @@ -392,3 +398,4 @@ master-standalone.o: cube.h platform.h tools.h geom.h model.h protocol.h master-standalone.o: sound.h weapon.h entity.h world.h i18n.h command.h master-standalone.o: varray.h vote.h console.h protos.h + --- physics.cpp Tue Oct 22 13:57:19 2013 +++ physics.cpp Thu May 22 20:37:00 2014 @@ -474,7 +474,7 @@ } } - if(timeinair > 200 && !pl->timeinair) + if(timeinair > 200 && !pl->timeinair && !water) { int sound = timeinair > 800 ? S_HARDLAND : S_SOFTLAND; if(pl->state!=CS_DEAD) --- protos.h Sat Nov 09 13:48:58 2013 +++ protos.h Fri May 23 02:52:10 2014 @@ -496,7 +496,8 @@ extern void removedynlights(physent *owner); extern block *blockcopy(const block &b); extern void blockpaste(const block &b, int bx, int by, bool light); -extern void blockpaste(const block &b); +extern void blockpaste(const block &b); +extern void halfblockpaste(const block &b, int bx, int by, bool floor); extern void freeblock(block *&b); // worldrender @@ -626,7 +627,7 @@ { PART_SPARK = 0, PART_SMOKE, - PART_ECLOSEST, + PART_BLUE, PART_BLOOD, PART_DEMOTRACK, PART_FIREBALL, @@ -637,13 +638,16 @@ PART_HUDMUZZLEFLASH, PART_MUZZLEFLASH, PART_ELIGHT, - PART_ESPAWN, - PART_EAMMO, + PART_GREEN, + PART_RED, PART_EPICKUP, PART_EMODEL, - PART_ECARROT, + PART_EAMMO, PART_ELADDER, - PART_EFLAG + PART_ECLOSEST, + PART_SOUND = 22, + PART_CLIP, + PART_PLCLIP }; extern void particleinit(); --- renderhud.cpp Tue Oct 22 13:57:19 2013 +++ renderhud.cpp Sat Jun 07 00:20:51 2014 @@ -1,6 +1,8 @@ // renderhud.cpp: HUD rendering #include "cube.h" + +extern bool cleanedit; void drawicon(Texture *tex, float x, float y, float s, int col, int row, float ts) { @@ -278,7 +280,10 @@ COMMAND(loadcrosshair, "ss"); void drawcrosshair(playerent *p, int n, color *c, float size) -{ +{ + if (cleanedit && editmode) + return; + Texture *crosshair = crosshairs[n]; if(!crosshair) { @@ -890,7 +895,22 @@ char *infostr = editinfo(); int commandh = 1570 + FONTH; if(command) commandh -= rendercommand(20, 1570, VIRTW); - else if(infostr) draw_text(infostr, 20, 1570); + + else if(infostr) + { + if (cleanedit) + { + glPushMatrix(); + glLoadIdentity(); + glOrtho(0, VIRTW*2, VIRTH*2, 0, -1, 1); + glScalef(1.0, 1.0, 1.0); //set scale + draw_text(infostr, 48, VIRTH*2 -4*FONTH); + glPopMatrix(); + } + else + draw_text(infostr, 20, 1570); + } + else if(targetplayer && showtargetname) draw_text(colorname(targetplayer), 20, 1570); glLoadIdentity(); glOrtho(0, VIRTW*2, VIRTH*2, 0, -1, 1); --- renderparticles.cpp Tue Oct 22 13:57:19 2013 +++ renderparticles.cpp Fri May 23 02:58:31 2014 @@ -184,7 +184,7 @@ } } -#define MAXPARTYPES 22 +#define MAXPARTYPES 25 struct particle { vec o, d; int fade, type; int millis; particle *next; }; particle *parlist[MAXPARTYPES], *parempty = NULL; @@ -252,7 +252,7 @@ { { PT_PART, 0.4f, 0.4f, 0.4f, 2, 0, 0.06f }, // yellow: sparks { PT_PART, 1.0f, 1.0f, 1.0f, 20, 1, 0.15f }, // grey: small smoke - { PT_PART, 0.0f, 0.0f, 1.0f, 20, 0, 0.08f }, // blue: edit mode closest ent + { PT_PART, 0.0f, 0.0f, 1.0f, 20, 0, 0.08f }, // blue: used for RVSF related entities { PT_BLOOD, 0.5f, 0.0f, 0.0f, 1, 4, 0.3f }, // red: blood spats { PT_PART, 1.0f, 0.1f, 0.1f, 0, 1, 0.2f }, // red: demotrack { PT_FIREBALL, 1.0f, 0.5f, 0.5f, 0, 2, 7.0f }, // explosion fireball @@ -264,16 +264,19 @@ { PT_HUDFLASH, 1.0f, 1.0f, 1.0f, 0, 6, 0.7f }, // hudgun muzzle flash { PT_FLASH, 1.0f, 1.0f, 1.0f, 0, 6, 0.7f }, // muzzle flash { PT_PART, 1.0f, 1.0f, 1.0f, 20, 0, 0.08f }, // white: edit mode ent type : light - { PT_PART, 0.0f, 1.0f, 0.0f, 20, 0, 0.08f }, // green: edit mode ent type : spawn - { PT_PART, 1.0f, 0.0f, 0.0f, 20, 0, 0.08f }, // red: edit mode ent type : ammo - { PT_PART, 1.0f, 1.0f, 0.0f, 20, 0, 0.08f }, // yellow: edit mode ent type : pickup - { PT_PART, 1.0f, 0.0f, 1.0f, 20, 0, 0.08f }, // magenta: edit mode ent type : model, sound - { PT_PART, 1.0f, 0.5f, 0.2f, 20, 0, 0.08f }, // orange: edit mode ent type : "carrot" - { PT_PART, 0.5f, 0.5f, 0.5f, 20, 0, 0.08f }, // grey: edit mode ent type : ladder, (pl)clip - { PT_PART, 0.0f, 1.0f, 1.0f, 20, 0, 0.08f }, // turquoise: edit mode ent type : CTF-flag + { PT_PART, 0.0f, 1.0f, 0.0f, 20, 0, 0.08f }, // green: edit mode ent type : FFA spawn + { PT_PART, 1.0f, 0.0f, 0.0f, 20, 0, 0.08f }, // red: used for CLA related entities + { PT_PART, 0.78f, 1.0f, 0.33f, 20, 0, 0.08f }, // yellow-green: edit mode ent type : pickup + { PT_PART, 0.6f, 0.3f, 0.9f, 20, 0, 0.08f }, // purple: edit mode ent type : mapmodel + { PT_PART, 1.0f, 0.5f, 0.2f, 20, 0, 0.08f }, // orange: edit mode ent type : ammo + { PT_PART, 0.7f, 1.0f, 1.0f, 20, 0, 0.08f }, // bright cyan: edit mode ent type : ladder, + { PT_PART, 0.45f, 0.45f, 0.45f, 20, 1, 0.2f }, // smoke effect: closest/selected entity // 2011jun18 : shotty decals { PT_BULLETHOLE, 0.2f, 0.2f, 1.0f, 0, 3, 0.1f }, // hole decal M - { PT_BULLETHOLE, 0.2f, 1.0f, 0.2f, 0, 3, 0.1f }, // hole decal C + { PT_BULLETHOLE, 0.2f, 1.0f, 0.2f, 0, 3, 0.1f }, // hole decal C + { PT_PART, 0.0f, 1.0f, 1.0f, 20, 0, 0.08f }, // cyan: edit mode ent type: sound + { PT_PART, 1.0f, 1.0f, 0.0f, 20, 0, 0.08f }, // yellow: edit mode ent type: clip + { PT_PART, 1.0f, 0.0f, 1.0f, 20, 0, 0.08f } // magenta: edit mode ent type: plclip }; VAR(particlesize, 20, 100, 500); --- tools.h Tue Oct 22 13:57:19 2013 +++ tools.h Wed Apr 02 10:50:08 2014 @@ -424,7 +424,7 @@ T &pop() { return buf[--ulen]; } T &last() { return buf[ulen-1]; } - void drop() { buf[--ulen].~T(); } + void drop() { buf[--ulen].~T();} bool empty() const { return ulen==0; } int capacity() const { return alen; } --- world.cpp Tue Oct 22 13:57:19 2013 +++ world.cpp Tue May 20 19:12:15 2014 @@ -127,10 +127,24 @@ COMMAND(nextclosestent, ""); COMMAND(closestenttype, "s"); + +int active_ent = -1; +bool locking_ent = false, lockselent = false; + +COMMANDF(togglelockselent, "", (void) { active_ent = -1; lockselent = !lockselent; if (lockselent) locking_ent = true;}); int closestent() // used for delent and edit mode ent display { - if(noteditmode("closestent")) return -1; + if(noteditmode("closestent")) return -1; + + if (lockselent && !locking_ent && active_ent != -1) + { + if (ents[active_ent].type != NOTUSED) + return active_ent; + else + lockselent = false; + } + int best = -1, bcnt = 0; float bdist = 99999; loopj(3) @@ -150,7 +164,15 @@ { if(ents[best].x == e.x && ents[best].y == e.y && ents[best].z == e.z) { - if(j == 2 && bcnt == clentsel) return i; + if(j == 2 && bcnt == clentsel) + { + if (locking_ent) + { + active_ent = i; + locking_ent = false; + } + return i; + } bcnt++; } } @@ -162,7 +184,14 @@ } if(best < 0 || bcnt == 1) break; if(bcnt) clentsel %= bcnt; - } + } + + if (locking_ent) + { + active_ent = best; + locking_ent = false; + } + return best; } @@ -173,7 +202,16 @@ entity &e = ents[n]; switch(prop) { - case 0: e.attr1 += amount; break; + case 0: + if (e.type == MAPMODEL) + { + e.attr1 += amount*16; + while (e.attr1 > 360) e.attr1 -= 360; + while (e.attr1 < 0) e.attr1 += 360; + } + else e.attr1 += amount; + break; + case 1: e.attr2 += amount; break; case 2: e.attr3 += amount; break; case 3: e.attr4 += amount; break; @@ -371,6 +409,26 @@ } COMMANDF(scalelights, "ii", (int *f, int *i) { scalelights(*f, *i); }); + +void scalelight(int f, int intens) +{ + entity &e = ents[closestent()]; + if(e.type!=LIGHT) return; + + e.attr1 = e.attr1*f/100; + if(e.attr1<2) e.attr1 = 2; + if(e.attr1>32) e.attr1 = 32; + + if(intens) + { + scalecomp(e.attr2, intens); + scalecomp(e.attr3, intens); + scalecomp(e.attr4, intens); + } + calclight(); +} + +COMMANDF(scalelight, "ii", (int *f, int *i) { scalelight(*f, *i); }); int findentity(int type, int index) { --- worldlight.cpp Tue Oct 22 13:57:19 2013 +++ worldlight.cpp Fri Apr 11 15:30:00 2014 @@ -369,6 +369,49 @@ { blockpaste(b, b.x, b.y, false); } + +void halfblockpaste(const block &b, int bx, int by, bool floor) +{ + const sqr *q = (const sqr *)((&b)+1); + for(int y = by; y<b.ys+by; y++) + for(int x = bx; x<b.xs+bx; x++) + { + if (q->type == SOLID || q->type == CORNER || + //don't override heightfields with space unnessesarily + (q->type == SPACE && ((floor && S(x,y)->type != CHF) || (!floor && S(x,y)->type != FHF)))) + + S(x,y)->type = q->type; + + if (floor || q->type == SOLID) + { + if (q->type == FHF || + S(x-1,y)->type == FHF || + S(x,y-1)->type == FHF || + S(x-1,y-1)->type == FHF) + // + {S(x,y)->type = q->type; S(x,y)->vdelta = q->vdelta;} + + S(x,y)->floor = q->floor; + S(x,y)->wtex = q->wtex; + S(x,y)->ftex = q->ftex; + } + else + { + if (q->type == CHF || + S(x-1,y)->type == CHF || + S(x,y-1)->type == CHF || + S(x-1,y-1)->type == CHF) + // + {S(x,y)->type = q->type; S(x,y)->vdelta = q->vdelta;} + + S(x,y)->ceil = q->ceil; + S(x,y)->utex = q->utex; + S(x,y)->ctex = q->ctex; + } + + q++; + } +} void freeblock(block *&b) {

Linux and Mac ports needed.
Why don't you just fork it on github?
Thanks given by:


Messages In This Thread
RE: [Download] 1.2 Mapping Client - by PhaNtom - 08 Jun 14, 09:02PM
RE: [Download] 1.2 Mapping Client - by MCS - 09 Jun 14, 02:38AM
RE: [Download] 1.2 Mapping Client - by MPx - 10 Jun 14, 01:35AM
RE: [Download] 1.2 Mapping Client - by PhaNtom - 10 Jun 14, 02:22AM
RE: [Download] 1.2 Mapping Client - by RKTnoob - 10 Jun 14, 01:40PM
RE: [Download] 1.2 Mapping Client - by Alien - 11 Jun 14, 07:34PM
RE: [Download] 1.2 Mapping Client - by Mousikos - 16 Aug 14, 11:19AM
RE: [Download] 1.2 Mapping Client - by PhaNtom - 22 Aug 14, 01:39PM