add undelete for entities

BACKSPACE in combination with editmeta (LCTRL) now undeletes the last
deleted entity. BACKSPACE in combination with editmeta2 (LSHIFT) brings
up the menu "deleted entities".

The edit menu now has a submenu "deleted entities" which lists all
deleted entities and undeletes the selected one.

undelent [<index>]
  If no index is specified, the last deleted entity is restored. If an
  index is given, the specified entity from the list of deleted entities
  is restored.

getdeletedentities
  Returns a list of deleted entities. Each line contains the entity type,
  the position and all seven attributes.

unlistdeletedentity [<which>]
  If <which> is a number, the specified entry from the list of deleted
  entities gets removed. If <which> is "all", the whole list of deleted
  entities gets deleted. If <which> is "last" the last deleted entity is
  removed from the list of deleted entities.
  Returns the number of entities on the list of deleted entities (even if
  the parameter <which> was unknown or not specified).

DOCREF undelent getdeletedentities unlistdeletedentity
This commit is contained in:
ac-stef
2015-05-27 15:47:05 +02:00
parent ee18d192eb
commit 95680b699c
8 changed files with 103 additions and 14 deletions
+29
View File
@@ -13,6 +13,8 @@ menuitem (_ [Map operations...]) [ showmenu [Map operations] ]
menuitem [Map config operations...] [ showmenu [Map config operations] ]
menuitem (_ [Bots...]) [ showmenu [Creating bot waypoints] ]
menuitem (_ [Settings...]) [ showmenu [Editing settings] ]
menuitem [Deleted entities] [ showmenu "deleted entities" ]
menuitem (_ Help?) [ echo (yellow) (_ [Please read the AssaultCube README which has a detailed guide on mapediting...]) ]
tempalias tmp_cradius 12
@@ -287,6 +289,33 @@ menuitemcheckbox (_ [Enable auto save map: ]) "$autosavemap" [ autosavemap = $ar
menuitemslider (_ [Time between auto saves (in minutes): ]) 2 60 "(div $timeBetAutoSaves 60000)" 1 [] [ timeBetAutoSaves = (* $arg1 60000) ]
menuitemtextinput (_ [Make a map backup (.BAK) every: ]) "$numAutoSaveBackups" [ numAutoSaveBackups = $arg1 ] [ if (! $showedBAKinfo) [ echo This setting effects the number of autosavemaps between making a map backup file. "(.BAK)"; showedBAKinfo = 1 ] ] 4
// deleted entities
newmenu "deleted entities"
menuinit __rebuilddeletedentitymenu
tempalias __rebuilddeletedentitymenu [
delmenu "deleted entities"
newmenu "deleted entities"
if (unlistdeletedentity) [
push i 0
looplist (getdeletedentities) [type x y z a1 a2 a3 a4 a5 a6 a7] [
push desc (concat $type (concatword "[" $x "|" $y "|" $z "]") (concatword "(" $a1 ", " $a2 ", " $a3 ", " $a4 ", " $a5 ", " $a6 ", " $a7 ")"))
if (strcmp $type mapmodel) [desc = (concat $desc (mapmodelslotname $a2))]
if (&& $editing (strcmp $type sound)) [desc = (concat $desc (at (editmapsoundslot $a1) 0))]
if $editing [
menuitem (pop desc) (concat gotoposition $x $y $z $a1 0 ";" undelent $i)
][
menuitem (pop desc) -1
]
+= i 1
]
pop i
menuitem "\f3clear this list" "unlistdeletedentity all"
] [
menuitem "no deleted entities" -1
]
]
//Mapmodels
newmenu Mapmodels
menuinit __rebuildmapmodelmenus
+1 -1
View File
@@ -30,7 +30,7 @@ bind MOUSE3 weapon
bind MOUSE4 key_universaldelta_plus
bind MOUSE5 key_universaldelta_minus
bind BACKSPACE dropflag
editbind BACKSPACE delent
editbind BACKSPACE [if $editmeta2down [showmenu "deleted entities" ; menuselection "deleted entities" (- (unlistdeletedentity) 1)] [if $editmetakeydown undelent delent]]
bind TAB key_showscores
bind CLEAR []
bind RETURN []
+1
View File
@@ -866,6 +866,7 @@ void deletemapsoundslot(int *n, char *opt) // delete mapsound slot - only if unu
entity &e = ents[i];
if(e.attr1 == *n)
{ // delete entity
deleted_ents.add(e);
deletesoundentity(e);
memset(&e, 0, sizeof(persistent_entity));
e.type = NOTUSED;
+1
View File
@@ -1084,6 +1084,7 @@ void resetmap(bool mrproper)
cleardynlights();
pruneundos();
changedents.setsize(0);
deleted_ents.setsize(0);
particlereset();
if(mrproper)
{
+1
View File
@@ -1045,6 +1045,7 @@ void transformclipentities() // transforms all clip entities to tag clips, if t
}
if(!nodelete)
{
deleted_ents.add(e);
e.type = NOTUSED; // only delete entity, if it is now fully covered in tag clips
thisrun++;
}
+3 -2
View File
@@ -486,11 +486,12 @@ extern void remip(const block &b, int level = 0);
extern void remipmore(const block &b, int level = 0);
extern int closestent();
extern void deletesoundentity(entity &e);
extern int findtype(char *what);
extern int findtype(const char *what);
extern int findentity(int type, int index = 0);
extern int findentity(int type, int index, uchar attr2);
extern void newentity(int index, int x, int y, int z, char *what, float v1, float v2, float v3, float v4);
extern void newentity(int index, int x, int y, int z, const char *what, float v1, float v2, float v3, float v4);
extern void mapmrproper(bool manual);
extern vector<persistent_entity> deleted_ents;
// worldlight
extern int lastcalclight;
+1
View File
@@ -166,6 +166,7 @@ void deletemapmodelslot(int *n, char *opt) // delete mapmodel slot - only if unu
entity &e = ents[i];
if(e.attr2 == *n)
{ // delete entity
deleted_ents.add(e);
memset(&e, 0, sizeof(persistent_entity));
e.type = NOTUSED;
deld++;
+66 -11
View File
@@ -249,21 +249,19 @@ void deletesoundentity(entity &e)
if(loc) loc->drop();
}
vector<persistent_entity> deleted_ents;
void delent()
{
int n = closestent();
if(n<0) { conoutf("no more entities"); return; }
syncentchanges(true);
int t = ents[n].type;
conoutf("%s entity deleted", entnames[t]);
conoutf("%s entity deleted", entnames[t % MAXENTTYPES]);
entity &e = ents[n];
if (t == SOUND) //stop playing sound
{
deletesoundentity(e);
}
if(t == SOUND) deletesoundentity(e); //stop playing sound
deleted_ents.add(e);
ents[n].type = NOTUSED;
addmsg(SV_EDITENT, "ri9i3", n, NOTUSED, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
@@ -273,15 +271,66 @@ void delent()
}
unsavededits++;
}
COMMAND(delent, "");
int findtype(char *what)
void undelent(char *index)
{
if(noteditmode("undelent")) return;
if(!deleted_ents.length()) { conoutf("no more entities to undelete"); return; }
int n = isdigit(*index) ? strtol(index, NULL, 0) : deleted_ents.length() - 1;
if(deleted_ents.inrange(n))
{
persistent_entity e = deleted_ents.remove(n);
int t = e.type < MAXENTTYPES ? e.type : NOTUSED;
if(OUTBORD(e.x, e.y)) conoutf("failed to undelete %s entity (coordinates outside map borders)", entnames[t]);
else
{
newentity(-1, e.x, e.y, e.z, entnames[t], float(e.attr1) / entscale[t][0], float(e.attr2) / entscale[t][1], float(e.attr3) / entscale[t][2], float(e.attr4) / entscale[t][3]);
*((persistent_entity *) &ents.last()) = e;
conoutf("%s entity undeleted", entnames[t]);
}
}
}
COMMAND(undelent, "s");
void getdeletedentities()
{
vector<char> res;
loopv(deleted_ents)
{
persistent_entity &e = deleted_ents[i];
int t = e.type < MAXENTTYPES ? e.type : NOTUSED;
#define AA(x) floatstr(float(e.attr##x) / entscale[t][x - 1], true)
cvecprintf(res,"%s %d %d %d %s %s %s %s %s %s %s\n", entnames[e.type], e.x, e.y, e.z, AA(1), AA(2), AA(3), AA(4), AA(5), AA(6), AA(7));
#undef AA
}
if(res.length()) res.last() = '\0';
else res.add('\0');
result(res.getbuf());
}
COMMAND(getdeletedentities, "");
void unlistdeletedentity(char *which)
{
if(!strcasecmp(which, "all")) deleted_ents.setsize(0);
else if(!strcasecmp(which, "last")) deleted_ents.pop();
else if(isdigit(*which))
{
int n = strtol(which, NULL, 0);
if(deleted_ents.inrange(n)) deleted_ents.remove(n);
}
intret(deleted_ents.length());
}
COMMAND(unlistdeletedentity, "s");
int findtype(const char *what)
{
int t = getlistindex(what, entnames, true, NOTUSED);
if(t == NOTUSED) conoutf("unknown entity type \"%s\"", what);
return t;
}
void newentity(int index, int x, int y, int z, char *what, float v1f, float v2f, float v3f, float v4f) // add an entity or overwrite an existing one
void newentity(int index, int x, int y, int z, const char *what, float v1f, float v2f, float v3f, float v4f) // add an entity or overwrite an existing one
{
int type = findtype(what);
if(type == NOTUSED) return;
@@ -354,7 +403,13 @@ void clearents(char *name)
loopv(ents)
{
entity &e = ents[i];
if(e.type==type) { e.type = NOTUSED; found = true; }
if(e.type == type)
{
if(type == SOUND) deletesoundentity(e);
deleted_ents.add(e);
e.type = NOTUSED;
found = true;
}
}
switch(type)
{
@@ -375,6 +430,7 @@ void deleteentity(char *ns)
int t = e.type;
if(t == SOUND) deletesoundentity(e);
conoutf("deleted entity #%d (%s)", n, entnames[e.type]);
deleted_ents.add(e);
memset(&e, 0, sizeof(persistent_entity));
e.type = NOTUSED;
if(t == LIGHT) calclight();
@@ -688,7 +744,6 @@ COMMAND(mapenlarge, "");
COMMAND(mapshrink, "");
COMMAND(newmap, "i");
COMMANDN(recalc, calclight, "");
COMMAND(delent, "");
void countperfectmips(int mip, int xx, int yy, int bs, int *stats)
{