MCPcopy Create free account
hub / github.com/assaultcube/AC / transformclipentities

Function transformclipentities

source/src/editing.cpp:1393–1447  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1391COMMAND(selectionwalk, "sss");
1392
1393void transformclipentities() // transforms all clip entities to tag clips, if they are big enough (so, that no player could be above or below them)
1394{ // (hardcoded factor ENTSCALE10 for attr1 and ENTSCALE5 for attr2-4)
1395 EDITMP("transformclipentities");
1396 int total = 0, thisrun, bonus = 5;
1397 do
1398 {
1399 thisrun = 0;
1400 loopv(ents)
1401 {
1402 entity &e = ents[i];
1403 if((e.type == CLIP || e.type == PLCLIP) && e.attr2 / ENTSCALE5 && e.attr3 / ENTSCALE5 && e.attr4 / ENTSCALE5)
1404 {
1405 int allowedspace = e.type == CLIP ? 1 : 4;
1406 int clipmask = e.type == CLIP ? TAGCLIP : TAGPLCLIP;
1407 int i2 = e.attr2 / ENTSCALE5, i3 = e.attr3 / ENTSCALE5; // floor values
1408 int r2 = (e.attr2 % ENTSCALE5) > 0, r3 = (e.attr3 % ENTSCALE5) > 0; // fractions
1409 int x1i = e.x - i2, x2i = e.x + i2 - 1, y1i = e.y - i3, y2i = e.y + i3 - 1; // inner rectangle (fully covered cubes)
1410 int x1o = x1i - r2, x2o = x2i + r2, y1o = y1i - r3, y2o = y2i + r3; // outer rectangle (partially covered cubes)
1411 float z1 = S(e.x, e.y)->floor + float(e.attr1) / ENTSCALE10, z2 = z1 + float(e.attr4) / ENTSCALE5;
1412 bool bigenough = true, nodelete = false;
1413 for(int xx = x1o; xx <= x2o; xx++) for(int yy = y1o; yy <= y2o; yy++) // loop over outer rectangle to check, if a clip has the required height
1414 {
1415 if(OUTBORD(xx,yy) || SOLID(S(xx,yy))) continue;
1416 bool inner = xx >= x1i && xx <= x2i && yy >= y1i && yy <= y2i; // flag: xx|yy is inner rectangle
1417 sqr *s[4] = { S(xx, yy), S(xx + 1, yy), S(xx, yy + 1), S(xx + 1, yy + 1) };
1418 int vdeltamax = 0;
1419 loopj(4) if(s[j]->vdelta > vdeltamax) vdeltamax = s[j]->vdelta;
1420 int floor = s[0]->floor - (s[0]->type == FHF ? (vdeltamax + 3) / 4 : 0),
1421 ceil = s[0]->ceil + (s[0]->type == CHF ? (vdeltamax + 3) / 4 : 0);
1422 bool alreadytagged = (s[0]->tag & (TAGCLIP | clipmask)) != 0;
1423 if((z1 - floor > allowedspace || ceil - z2 > allowedspace) && !alreadytagged) bigenough = false;
1424 if(!inner && !alreadytagged) nodelete = true; // fractional part of the clip would not be covered: entity can not be deleted
1425 }
1426 if(bigenough)
1427 {
1428 for(int xx = x1i; xx <= x2i; xx++) for(int yy = y1i; yy <= y2i; yy++) // only convert inner rectangle to tag clips
1429 {
1430 if(!OUTBORD(xx,yy) && !SOLID(S(xx,yy))) S(xx, yy)->tag |= clipmask;
1431 }
1432 if(!nodelete)
1433 {
1434 deleted_ents.add(e);
1435 e.type = NOTUSED; // only delete entity, if it is now fully covered in tag clips
1436 thisrun++;
1437 }
1438 }
1439 }
1440 }
1441 total += thisrun;
1442 }
1443 while(thisrun || bonus-- > 0);
1444 loopi(ssize) loopj(ssize) { sqr *s = S(i,j); if(s->tag & TAGCLIP) s->tag &= ~TAGPLCLIP; }
1445 conoutf("changed %d clip entities to tagged clip areas", total);
1446 if(total) unsavededits++;
1447}
1448
1449COMMAND(transformclipentities, "");
1450

Callers

nothing calls this directly

Calls 2

loopiFunction · 0.70
conoutfFunction · 0.70

Tested by

no test coverage detected