13 Aug 14, 11:28PM
(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
[SELECT ALL] 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.