Advertisement
lucasgautheron

multiple selections support

Sep 11th, 2011
117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 19.35 KB | None | 0 0
  1. Index: config/resetbinds.cfg
  2. ===================================================================
  3. --- config/resetbinds.cfg   (revision 6646)
  4. +++ config/resetbinds.cfg   (working copy)
  5. @@ -158,6 +158,8 @@
  6.  bind LSHIFT "crouch"
  7.  bind RCTRL "jump"
  8.  bind LCTRL "jump"
  9. +editbind RCTRL " "
  10. +editbind LCTRL " "
  11.  bind RALT ""
  12.  bind LALT "showscores 0; toggleshowmap"
  13.  bind RMETA ""
  14. Index: source/src/bot/bot_waypoint.cpp
  15. ===================================================================
  16. --- source/src/bot/bot_waypoint.cpp (revision 6646)
  17. +++ source/src/bot/bot_waypoint.cpp (working copy)
  18. @@ -19,8 +19,9 @@
  19.  #endif
  20.  
  21.  VAR(xhairwpsel, 0, 1, 1);
  22. -extern block sel;
  23. -#define curselection (xhairwpsel ? vec(sel.x, sel.y, S(sel.x, sel.y)->floor+2.0f) : vec(player1->o.x, player1->o.y, player1->o.z))
  24. +// FIXME: multiple selections support ?
  25. +extern vector<block> sels;
  26. +#define curselection (xhairwpsel ? vec(sels.last().x, sels.last().y, S(sels.last().x, sels.last().y)->floor+2.0f) : vec(player1->o.x, player1->o.y, player1->o.z))
  27.  
  28.  // Waypoint class begin
  29.  
  30. Index: source/src/editing.cpp
  31. ===================================================================
  32. --- source/src/editing.cpp  (revision 6646)
  33. +++ source/src/editing.cpp  (working copy)
  34. @@ -7,18 +7,17 @@
  35.  // the current selection, used by almost all editing commands
  36.  // invariant: all code assumes that these are kept inside MINBORD distance of the edge of the map
  37.  
  38. -block sel =
  39. -{
  40. -    variable("selx",  0, 0, 4096, &sel.x,  NULL, false),
  41. -    variable("sely",  0, 0, 4096, &sel.y,  NULL, false),
  42. -    variable("selxs", 0, 0, 4096, &sel.xs, NULL, false),
  43. -    variable("selys", 0, 0, 4096, &sel.ys, NULL, false),
  44. -};
  45. +vector<block> sels;
  46.  
  47. -int selh = 0;
  48. -bool selset = false;
  49. +#define SEL_ATTR(attr) { string buf; loopv(sels) { concatformatstring(buf, "%d ", sels[i].attr); } result(buf); }
  50. +COMMANDF(selx, ARG_NONE, (void) { SEL_ATTR(x); });
  51. +COMMANDF(sely, ARG_NONE, (void) { SEL_ATTR(y); });
  52. +COMMANDF(selxs, ARG_NONE, (void) { SEL_ATTR(xs); });
  53. +COMMANDF(selys, ARG_NONE, (void) { SEL_ATTR(ys); });
  54. +#undef SEL_ATTR
  55.  
  56. -#define loopselxy(b) { makeundo(); loop(x,sel.xs) loop(y,sel.ys) { sqr *s = S(sel.x+x, sel.y+y); b; } remip(sel); }
  57. +#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); }
  58. +#define loopselsxy(b) { loopv(sels) loopselxy(sels[i], b); }
  59.  
  60.  int cx, cy, ch;
  61.  
  62. @@ -46,7 +45,6 @@
  63.          player1->attacking = false;
  64.      }
  65.      keyrepeat(editmode);
  66. -    selset = false;
  67.      editing = editmode ? 1 : 0;
  68.      player1->state = editing ? CS_EDITING : CS_ALIVE;
  69.      if(editing && player1->onladder) player1->onladder = false;
  70. @@ -58,29 +56,17 @@
  71.  
  72.  COMMAND(edittoggle, ARG_NONE);
  73.  
  74. -char *editinfo()
  75. +bool correctsel(block &s)                                       // ensures above invariant
  76.  {
  77. -    static string info;
  78. -    if(!editmode) return NULL;
  79. -    int e = closestent();
  80. -    if(e<0) return NULL;
  81. -    entity &c = ents[e];
  82. -    formatstring(info)("closest entity = %s (%d, %d, %d, %d), selection = (%d, %d)", entnames[c.type], c.attr1, c.attr2, c.attr3, c.attr4, sel.xs, sel.ys);
  83. -    return info;
  84. +    int bsize = ssize - MINBORD;
  85. +    if(s.xs+s.x>bsize) s.xs = bsize-s.x;
  86. +    if(s.ys+s.y>bsize) s.ys = bsize-s.y;
  87. +    if(s.xs<=0 || s.ys<=0) return false;
  88. +    else return !OUTBORD(s.x, s.y);
  89.  }
  90.  
  91. -void correctsel()                                       // ensures above invariant
  92. -{
  93. -    selset = !OUTBORD(sel.x, sel.y);
  94. -    int bsize = ssize-MINBORD;
  95. -    if(sel.xs+sel.x>bsize) sel.xs = bsize-sel.x;
  96. -    if(sel.ys+sel.y>bsize) sel.ys = bsize-sel.y;
  97. -    if(sel.xs<=0 || sel.ys<=0) selset = false;
  98. -}
  99. -
  100.  bool noteditmode(const char* func)
  101.  {
  102. -    correctsel();
  103.      if(!editmode)
  104.      {
  105.          if(func && func[0]!='\0') conoutf("\f4[\f3%s\f4]\f5 is only allowed in edit mode", func);
  106. @@ -89,31 +75,77 @@
  107.      return !editmode;
  108.  }
  109.  
  110. +inline bool selset()
  111. +{
  112. +    return (sels.length() > 0);
  113. +}
  114. +
  115.  bool noselection()
  116.  {
  117. -    if(!selset) conoutf("no selection");
  118. -    return !selset;
  119. +    if(!selset()) conoutf("no selection");
  120. +    return !selset();
  121.  }
  122.  
  123. +char *editinfo()
  124. +{
  125. +    static string info;
  126. +    if(!editmode) return NULL;
  127. +    int e = closestent();
  128. +    if(e<0) return NULL;
  129. +    entity &c = ents[e];
  130. +    string selinfo = "no selection";
  131. +    if(selset()) formatstring(selinfo)("selection = (%d, %d)", (sels.last()).xs, (sels.last()).ys);
  132. +    formatstring(info)("closest entity = %s (%d, %d, %d, %d), %s", entnames[c.type], c.attr1, c.attr2, c.attr3, c.attr4, selinfo);
  133. +    return info;
  134. +}
  135. +
  136. +
  137.  #define EDITSEL   if(noteditmode("EDITSEL") || noselection()) return
  138.  #define EDITSELMP if(noteditmode("EDITSELMP") || noselection() || multiplayer()) return
  139.  #define EDITMP    if(noteditmode("EDITMP") || multiplayer()) return
  140.  
  141. +// multiple sels
  142. +
  143. +// add a selection to the list
  144. +void addselection(int x, int y, int xs, int ys, int h)
  145. +{
  146. +    block &s = sels.add();
  147. +    s.x = x; s.y = y; s.xs = xs; s.ys = ys; s.h = h;
  148. +    if(!correctsel(s)) { sels.drop(); }
  149. +}
  150. +
  151. +// reset all selections
  152. +void resetselections()
  153. +{
  154. +    sels.shrink(0);
  155. +}
  156. +
  157. +// reset all invalid selections
  158. +void checkselections()
  159. +{
  160. +    loopv(sels) if(!correctsel(sels[i])) sels.remove(i);
  161. +}
  162. +
  163. +// selection from cubescript
  164.  void selectpos(int x, int y, int xs, int ys)
  165.  {
  166. -    block s = { x, y, xs, ys };
  167. -    sel = s;
  168. -    selh = 0;
  169. -    correctsel();
  170. +    resetselections();
  171. +    addselection(x, y, xs, ys, 0);
  172.  }
  173.  
  174. -void makesel()
  175. +// update current selection, or add a new one
  176. +void makesel(bool isnew)
  177.  {
  178. -    block s = { min(lastx,cx), min(lasty,cy), abs(lastx-cx)+1, abs(lasty-cy)+1 };
  179. -    sel = s;
  180. -    selh = max(lasth,ch);
  181. -    correctsel();
  182. -    if(selset) rtex = *S(sel.x, sel.y);
  183. +    if(isnew) addselection(min(lastx, cx), min(lasty, cy), abs(lastx-cx)+1, abs(lasty-cy)+1, max(lasth, ch));
  184. +    else
  185. +    {
  186. +        block &cursel = sels.last();
  187. +        cursel.x = min(lastx, cx); cursel.y = min(lasty, cy);
  188. +        cursel.xs = abs(lastx-cx)+1; cursel.ys = abs(lasty-cy)+1;
  189. +        cursel.h = max(lasth, ch);
  190. +        correctsel(cursel);
  191. +    }
  192. +    if(selset()) rtex = *S((sels.last()).x, (sels.last()).y);
  193.  }
  194.  
  195.  VAR(flrceil,0,0,2);
  196. @@ -149,7 +181,7 @@
  197.          if(OUTBORD(cx, cy)) return;
  198.      }
  199.  
  200. -    if(dragging) makesel();
  201. +    if(dragging) { makesel(false); };
  202.  
  203.      const int GRIDSIZE = 5;
  204.      const float GRIDW = 0.5f;
  205. @@ -192,10 +224,10 @@
  206.          ch = (int)ih;
  207.      }
  208.  
  209. -    if(selset)
  210. +    if(selset())
  211.      {
  212.          linestyle(GRIDS, 0xFF, 0x40, 0x40);
  213. -        box(sel, (float)selh, (float)selh, (float)selh, (float)selh);
  214. +        loopv(sels) box(sels[i], (float)sels[i].h, (float)sels[i].h, (float)sels[i].h, (float)sels[i].h);
  215.      }
  216.  
  217.      glLineWidth(1);
  218. @@ -214,7 +246,7 @@
  219.      }
  220.  }
  221.  
  222. -void makeundo()
  223. +void makeundo(block &sel)
  224.  {
  225.      undos.add(blockcopy(sel));
  226.      pruneundos(undomegs<<20);
  227. @@ -229,27 +261,51 @@
  228.      freeblock(p);
  229.  }
  230.  
  231. -block *copybuf = NULL;
  232. +vector<block *> copybuffers;
  233.  
  234. +void resetcopybuffers()
  235. +{
  236. +    loopv(copybuffers) freeblock(copybuffers[i]);
  237. +    copybuffers.shrink(0);
  238. +}
  239. +
  240.  void copy()
  241.  {
  242.      EDITSELMP;
  243. -    freeblock(copybuf);
  244. -    copybuf = blockcopy(sel);
  245. +    resetcopybuffers();
  246. +    loopv(sels)
  247. +    {
  248. +        block *b = blockcopy(sels[i]);
  249. +        copybuffers.add(b);
  250. +    }
  251. +        
  252.  }
  253.  
  254.  void paste()
  255.  {
  256. -    EDITMP;
  257. -    if(!copybuf) { conoutf("nothing to paste"); return; }
  258. -    sel.xs = copybuf->xs;
  259. -    sel.ys = copybuf->ys;
  260. -    correctsel();
  261. -    if(!selset || sel.xs!=copybuf->xs || sel.ys!=copybuf->ys) { conoutf("incorrect selection"); return; }
  262. -    makeundo();
  263. -    copybuf->x = sel.x;
  264. -    copybuf->y = sel.y;
  265. -    blockpaste(*copybuf);
  266. +    EDITSELMP;
  267. +    if(!copybuffers.length()) { conoutf("nothing to paste"); return; }
  268. +
  269. +    loopv(sels)
  270. +    {
  271. +        block &sel = sels[i];
  272. +        int selx = sel.x;
  273. +        int sely = sel.y;
  274. +
  275. +        loopvj(copybuffers)
  276. +        {
  277. +            block *copyblock = copybuffers[j];
  278. +            int dx = copyblock->x - copybuffers[0]->x, dy = copyblock->y - copybuffers[0]->y;
  279. +
  280. +            sel.xs = copyblock->xs;
  281. +            sel.ys = copyblock->ys;
  282. +            sel.x = selx + dx;
  283. +            sel.y = sely + dy;
  284. +            if(!correctsel(sel) || sel.xs!=copyblock->xs || sel.ys!=copyblock->ys) { conoutf("incorrect selection"); return; }
  285. +            makeundo(sel);
  286. +            blockpaste(*copyblock, sel.x, sel.y);
  287. +        }
  288. +    }
  289.  }
  290.  
  291.  // Count the walls of type "type" contained in the current selection
  292. @@ -262,7 +318,7 @@
  293.          conoutf("invalid type");
  294.          return 0;
  295.      }
  296. -    loopselxy(if(s->type==type) counter++)
  297. +    loopselsxy(if(s->type==type) counter++)
  298.      return counter;
  299.  }
  300.  
  301. @@ -289,10 +345,14 @@
  302.          lastx = cx;
  303.          lasty = cy;
  304.          lasth = ch;
  305. -        selset = false;
  306.          tofronttex();
  307. +
  308. +        extern vector<keym> keyms;
  309. +        bool ctrlpressed = false;
  310. +        loopv(keyms) if(keyms[i].pressed && (keyms[i].code == SDLK_RCTRL || keyms[i].code == SDLK_LCTRL)) ctrlpressed = true;
  311. +        if(!ctrlpressed) resetselections();
  312.      }
  313. -    makesel();
  314. +    makesel(isdown);
  315.  }
  316.  
  317.  // the core editing function. all the *xy functions perform the core operations
  318. @@ -301,7 +361,7 @@
  319.  
  320.  void editheightxy(bool isfloor, int amount, block &sel)
  321.  {
  322. -    loopselxy(if(isfloor)
  323. +    loopselxy(sel, if(isfloor)
  324.      {
  325.          s->floor += amount;
  326.          if(s->floor>=s->ceil) s->floor = s->ceil-1;
  327. @@ -317,8 +377,11 @@
  328.  {
  329.      EDITSEL;
  330.      bool isfloor = flr==0;
  331. -    editheightxy(isfloor, amount, sel);
  332. -    addmsg(SV_EDITH, "ri6", sel.x, sel.y, sel.xs, sel.ys, isfloor, amount);
  333. +    loopv(sels)
  334. +    {
  335. +        editheightxy(isfloor, amount, sels[i]);
  336. +        addmsg(SV_EDITH, "ri6", sels[i].x, sels[i].y, sels[i].xs, sels[i].ys, isfloor, amount);
  337. +    }
  338.  }
  339.  
  340.  COMMAND(editheight, ARG_2INT);
  341. @@ -327,7 +390,7 @@
  342.  
  343.  void edittexxy(int type, int t, block &sel)
  344.  {
  345. -    loopselxy(switch(type)
  346. +    loopselxy(sel, switch(type)
  347.      {
  348.          case 0: s->ftex = t; break;
  349.          case 1: s->wtex = t; break;
  350. @@ -346,8 +409,11 @@
  351.      i = i<0 ? 0 : i+dir;
  352.      curedittex[atype] = i = min(max(i, 0), 255);
  353.      int t = lasttex = hdr.texlists[atype][i];
  354. -    edittexxy(type, t, sel);
  355. -    addmsg(SV_EDITT, "ri6", sel.x, sel.y, sel.xs, sel.ys, type, t);
  356. +    loopv(sels)
  357. +    {
  358. +        edittexxy(type, t, sels[i]);
  359. +        addmsg(SV_EDITT, "ri6", sels[i].x, sels[i].y, sels[i].xs, sels[i].ys, type, t);
  360. +    }
  361.  }
  362.  
  363.  void settex(int texture, int type)
  364. @@ -366,8 +432,11 @@
  365.          conoutf("invalid/unavaible texture");
  366.          return;
  367.      }
  368. -    edittexxy(type, t, sel);
  369. -    addmsg(SV_EDITT, "ri6", sel.x, sel.y, sel.xs, sel.ys, type, t);
  370. +    loopv(sels)
  371. +    {
  372. +        edittexxy(type, t, sels[i]);
  373. +        addmsg(SV_EDITT, "ri6", sels[i].x, sels[i].y, sels[i].xs, sels[i].ys, type, t);
  374. +    }
  375.  }
  376.  
  377.  void replace()
  378. @@ -390,17 +459,21 @@
  379.  
  380.  void edittypexy(int type, block &sel)
  381.  {
  382. -    loopselxy(s->type = type);
  383. +    loopselxy(sel, s->type = type);
  384.  }
  385.  
  386.  void edittype(int type)
  387.  {
  388.      EDITSEL;
  389. -    if(type==CORNER && (sel.xs!=sel.ys || sel.xs==3 || (sel.xs>4 && sel.xs!=8)
  390. -                   || sel.x&~-sel.xs || sel.y&~-sel.ys))
  391. -                   { conoutf("corner selection must be power of 2 aligned"); return; }
  392. -    edittypexy(type, sel);
  393. -    addmsg(SV_EDITS, "ri5", sel.x, sel.y, sel.xs, sel.ys, type);
  394. +    loopv(sels)
  395. +    {
  396. +        block &sel = sels[i];
  397. +        if(type==CORNER && (sel.xs!=sel.ys || sel.xs==3 || (sel.xs>4 && sel.xs!=8)
  398. +                       || sel.x&~-sel.xs || sel.y&~-sel.ys))
  399. +                       { conoutf("corner selection must be power of 2 aligned"); return; }
  400. +        edittypexy(type, sel);
  401. +        addmsg(SV_EDITS, "ri5", sel.x, sel.y, sel.xs, sel.ys, type);
  402. +    }
  403.  }
  404.  
  405.  void heightfield(int t) { edittype(t==0 ? FHF : CHF); }
  406. @@ -414,12 +487,12 @@
  407.  void editequalisexy(bool isfloor, block &sel)
  408.  {
  409.      int low = 127, hi = -128;
  410. -    loopselxy(
  411. +    loopselxy(sel,
  412.      {
  413.          if(s->floor<low) low = s->floor;
  414.          if(s->ceil>hi) hi = s->ceil;
  415.      });
  416. -    loopselxy(
  417. +    loopselxy(sel,
  418.      {
  419.          if(isfloor) s->floor = low; else s->ceil = hi;
  420.          if(s->floor>=s->ceil) s->floor = s->ceil-1;
  421. @@ -430,23 +503,30 @@
  422.  {
  423.      bool isfloor = flr==0;
  424.      EDITSEL;
  425. -    editequalisexy(isfloor, sel);
  426. -    addmsg(SV_EDITE, "ri5", sel.x, sel.y, sel.xs, sel.ys, isfloor);
  427. +    loopv(sels)
  428. +    {
  429. +        block &sel = sels[i];
  430. +        editequalisexy(isfloor, sel);
  431. +        addmsg(SV_EDITE, "ri5", sel.x, sel.y, sel.xs, sel.ys, isfloor);
  432. +    }
  433.  }
  434.  
  435.  COMMAND(equalize, ARG_1INT);
  436.  
  437.  void setvdeltaxy(int delta, block &sel)
  438.  {
  439. -    loopselxy(s->vdelta = max(s->vdelta+delta, 0));
  440. +    loopselxy(sel, s->vdelta = max(s->vdelta+delta, 0));
  441.      remipmore(sel);
  442.  }
  443.  
  444.  void setvdelta(int delta)
  445.  {
  446.      EDITSEL;
  447. -    setvdeltaxy(delta, sel);
  448. -    addmsg(SV_EDITD, "ri5", sel.x, sel.y, sel.xs, sel.ys, delta);
  449. +    loopv(sels)
  450. +    {
  451. +        setvdeltaxy(delta, sels[i]);
  452. +        addmsg(SV_EDITD, "ri5", sels[i].x, sels[i].y, sels[i].xs, sels[i].ys, delta);
  453. +    }
  454.  }
  455.  
  456.  const int MAXARCHVERT = 50;
  457. @@ -467,43 +547,55 @@
  458.  void arch(int sidedelta, int _a)
  459.  {
  460.      EDITSELMP;
  461. -    sel.xs++;
  462. -    sel.ys++;
  463. -    if(sel.xs>MAXARCHVERT) sel.xs = MAXARCHVERT;
  464. -    if(sel.ys>MAXARCHVERT) sel.ys = MAXARCHVERT;
  465. -    loopselxy(s->vdelta =
  466. -        sel.xs>sel.ys
  467. -            ? (archverts[sel.xs-1][x] + (y==0 || y==sel.ys-1 ? sidedelta : 0))
  468. -            : (archverts[sel.ys-1][y] + (x==0 || x==sel.xs-1 ? sidedelta : 0)));
  469. -    remipmore(sel);
  470. +    loopv(sels)
  471. +    {
  472. +        block &sel = sels[i];
  473. +        sel.xs++;
  474. +        sel.ys++;
  475. +        if(sel.xs>MAXARCHVERT) sel.xs = MAXARCHVERT;
  476. +        if(sel.ys>MAXARCHVERT) sel.ys = MAXARCHVERT;
  477. +        loopselxy(sel, s->vdelta =
  478. +            sel.xs>sel.ys
  479. +                ? (archverts[sel.xs-1][x] + (y==0 || y==sel.ys-1 ? sidedelta : 0))
  480. +                : (archverts[sel.ys-1][y] + (x==0 || x==sel.xs-1 ? sidedelta : 0)));
  481. +        remipmore(sel);
  482. +    }
  483.  }
  484.  
  485.  void slope(int xd, int yd)
  486.  {
  487.      EDITSELMP;
  488. -    int off = 0;
  489. -    if(xd<0) off -= xd*sel.xs;
  490. -    if(yd<0) off -= yd*sel.ys;
  491. -    sel.xs++;
  492. -    sel.ys++;
  493. -    loopselxy(s->vdelta = xd*x+yd*y+off);
  494. -    remipmore(sel);
  495. +    loopv(sels)
  496. +    {
  497. +        block &sel = sels[i];
  498. +        int off = 0;
  499. +        if(xd<0) off -= xd*sel.xs;
  500. +        if(yd<0) off -= yd*sel.ys;
  501. +        sel.xs++;
  502. +        sel.ys++;
  503. +        loopselxy(sel, s->vdelta = xd*x+yd*y+off);
  504. +        remipmore(sel);
  505. +    }
  506.  }
  507.  
  508.  void perlin(int scale, int seed, int psize)
  509.  {
  510.      EDITSELMP;
  511. -    sel.xs++;
  512. -    sel.ys++;
  513. -    makeundo();
  514. -    sel.xs--;
  515. -    sel.ys--;
  516. -    perlinarea(sel, scale, seed, psize);
  517. -    sel.xs++;
  518. -    sel.ys++;
  519. -    remipmore(sel);
  520. -    sel.xs--;
  521. -    sel.ys--;
  522. +    loopv(sels)
  523. +    {
  524. +        block &sel = sels[i];
  525. +        sel.xs++;
  526. +        sel.ys++;
  527. +        makeundo(sel);
  528. +        sel.xs--;
  529. +        sel.ys--;
  530. +        perlinarea(sel, scale, seed, psize);
  531. +        sel.xs++;
  532. +        sel.ys++;
  533. +        remipmore(sel);
  534. +        sel.xs--;
  535. +        sel.ys--;
  536. +    }
  537.  }
  538.  
  539.  VARF(fullbright, 0, 0, 1,
  540. @@ -518,13 +610,13 @@
  541.  void edittag(int tag)
  542.  {
  543.      EDITSELMP;
  544. -    loopselxy(s->tag = tag);
  545. +    loopselsxy(s->tag = tag);
  546.  }
  547.  
  548.  void newent(char *what, char *a1, char *a2, char *a3, char *a4)
  549.  {
  550.      EDITSEL;
  551. -    newentity(-1, sel.x, sel.y, (int)camera1->o.z, what, ATOI(a1), ATOI(a2), ATOI(a3), ATOI(a4));
  552. +    loopv(sels) newentity(-1, sels[i].x, sels[i].y, (int)camera1->o.z, what, ATOI(a1), ATOI(a2), ATOI(a3), ATOI(a4));
  553.  }
  554.  
  555.  void movemap(int xo, int yo, int zo) // move whole map
  556. @@ -566,9 +658,9 @@
  557.      resetmap(false);
  558.  }
  559.  
  560. -void selfliprotate(int dir)
  561. +void selfliprotate(block &sel, int dir)
  562.  {
  563. -    makeundo();
  564. +    makeundo(sel);
  565.      block *org = blockcopy(sel);
  566.      const sqr *q = (const sqr *)(org + 1);
  567.      int x1 = sel.x, x2 = sel.x + sel.xs - 1, y1 = sel.y, y2 = sel.y + sel.ys - 1, x, y;
  568. @@ -600,19 +692,21 @@
  569.      dir %= 4;
  570.      if(dir < 0) dir += 4;
  571.      if(!dir) return;
  572. -    if(sel.xs != sel.ys) dir = 2;
  573. -    selfliprotate(dir);
  574. +    loopv(sels)
  575. +    {
  576. +        block &sel = sels[i];
  577. +        if(sel.xs != sel.ys) dir = 2;
  578. +        selfliprotate(sel, dir);
  579. +    }
  580.  }
  581.  
  582.  void selectionflip(char *axis)
  583.  {
  584.      EDITSELMP;
  585.      if(!axis || !*axis) return;
  586. -    switch(toupper(*axis))
  587. -    {
  588. -        case 'X': selfliprotate(11); break;
  589. -        case 'Y': selfliprotate(12); break;
  590. -    }
  591. +    char c = toupper(*axis);
  592. +    if(c != 'X' && c != 'Y') return;
  593. +    loopv(sels) selfliprotate(sels[i], c == 'X' ? 11 : 12);
  594.  }
  595.  
  596.  COMMANDN(select, selectpos, ARG_4INT);
  597. Index: source/src/protos.h
  598. ===================================================================
  599. --- source/src/protos.h (revision 6646)
  600. +++ source/src/protos.h (working copy)
  601. @@ -472,6 +472,7 @@
  602.  extern void cleardynlights();
  603.  extern void removedynlights(physent *owner);
  604.  extern block *blockcopy(const block &b);
  605. +extern void blockpaste(const block &b, int bx, int by);
  606.  extern void blockpaste(const block &b);
  607.  extern void freeblock(block *&b);
  608.  
  609. @@ -554,6 +555,7 @@
  610.  extern void toggleedit(bool force = false);
  611.  extern char *editinfo();
  612.  extern void editdrag(bool isdown);
  613. +extern void checkselections();
  614.  extern void setvdeltaxy(int delta, block &sel);
  615.  extern void editequalisexy(bool isfloor, block &sel);
  616.  extern void edittypexy(int type, block &sel);
  617. Index: source/src/world.cpp
  618. ===================================================================
  619. --- source/src/world.cpp    (revision 6646)
  620. +++ source/src/world.cpp    (working copy)
  621. @@ -442,6 +442,8 @@
  622.          sqrdefault(S(x,y));
  623.      }
  624.  
  625. +    checkselections(); // assert no selection became invalid
  626. +
  627.      strncpy(hdr.head, "ACMP", 4);
  628.      hdr.version = MAPVERSION;
  629.      hdr.headersize = sizeof(header);
  630. @@ -471,7 +473,7 @@
  631.          loopi(sizeof(hdr.reserved)/sizeof(hdr.reserved[0])) hdr.reserved[i] = 0;
  632.          loopk(3) loopi(256) hdr.texlists[k][i] = i;
  633.          ents.shrink(0);
  634. -        block b = { 8, 8, ssize-16, ssize-16 };
  635. +        block b = { 8, 8, ssize-16, ssize - 16};
  636.          edittypexy(SPACE, b);
  637.      }
  638.  
  639. Index: source/src/world.h
  640. ===================================================================
  641. --- source/src/world.h  (revision 6646)
  642. +++ source/src/world.h  (working copy)
  643. @@ -130,7 +130,7 @@
  644.  #define MAXHHITS 6000
  645.  #define MINFF 2500
  646.  
  647. -struct block { int x, y, xs, ys; };
  648. +struct block { int x, y, xs, ys, h; };
  649.  
  650.  // vertex array format
  651.  
  652. Index: source/src/worldlight.cpp
  653. ===================================================================
  654. --- source/src/worldlight.cpp   (revision 6646)
  655. +++ source/src/worldlight.cpp   (working copy)
  656. @@ -337,13 +337,18 @@
  657.      return b;
  658.  }
  659.  
  660. -void blockpaste(const block &b)
  661. +void blockpaste(const block &b, int bx, int by)
  662.  {
  663.      const sqr *q = (const sqr *)((&b)+1);
  664. -    for(int y = b.y; y<b.ys+b.y; y++) for(int x = b.x; x<b.xs+b.x; x++) *S(x,y) = *q++;
  665. +    for(int y = by; y<b.ys+by; y++) for(int x = bx; x<b.xs+bx; x++) *S(x,y) = *q++;
  666.      remipmore(b);
  667.  }
  668.  
  669. +void blockpaste(const block &b)
  670. +{
  671. +    blockpaste(b, b.x, b.y);
  672. +}
  673. +
  674.  void freeblock(block *&b)
  675.  {
  676.      if(b) { delete[] (uchar *)b; b = NULL; }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement