CaveEditor again (beta, maybe alpha)

Jul 21, 2009 at 1:36 AM
Vanished.
Bobomb says: "I need a hug!"
Join Date: Apr 5, 2008
Location:
Posts: 776
Or an option for Expert / Noob mode? ;)
 
Jul 21, 2009 at 1:52 AM
Administrator
Forum Administrator
"Life begins and ends with Nu."
Join Date: Jul 15, 2007
Location: Australia
Posts: 6223
Age: 39
Pronouns: he/him
Schokobecher said:
Or an option for Expert / Noob mode? ;)
No. The problem with noobs (as opposed to newbs) it that the have no capacity for learning or figuring anything out themselves.

Newb mode is fine (maybe little ? icons that explain what each thing does when you roll over them so that you don't need separate "modes"), but noob mode sounds painful.
 
Jul 21, 2009 at 2:24 AM
Been here way too long...
"Ha! Ha! Ha! Mega Man is no match for my Mimiga Man!"
Join Date: Jun 22, 2008
Location:
Posts: 251
An undo stack would be awesome, although I understand they are rather hard to implement, and would need a fairly significant rewrite for a lot of the map editing functions. (I've been poking around in the source a bit, although this is the first time I've really read someone else's code, and I must say I'm awful at it. Not to mention that I don't know that much C++ in the first place)
 
Jul 21, 2009 at 2:53 AM
Level 73 Procrastinator
"Life begins and ends with Nu."
Join Date: Apr 6, 2009
Location: Forgotten Tower
Posts: 2052
Undo...

Man, I'd kill for an undo function...
;);
 
Jul 21, 2009 at 4:02 AM
Been here way too long...
"Ha! Ha! Ha! Mega Man is no match for my Mimiga Man!"
Join Date: Jun 22, 2008
Location:
Posts: 251
dooey100 said:
An undo stack would be awesome, although I understand they are rather hard to implement, and would need a fairly significant rewrite for a lot of the map editing functions. (I've been poking around in the source a bit, although this is the first time I've really read someone else's code, and I must say I'm awful at it. Not to mention that I don't know that much C++ in the first place)

Hmmm, this got me thinking about easy ways to implement an undo stack, and since I've done all this thinking, I might as well post the results here. I don't know how much programming experience you have, Wistil, but it is almost certainly more then mine, so feel free to ignore this.

First, have a "change the map" function, which, as well as changing the map tile in location X, also writes the location and previous value to an undo stack. (and increases the stack pointer and all that other stuff needing stacks). Calling the "undo" function "pops" the last value off the stack, changing it back to what it was before, and decrementing the stack pointer. But what about functions that change multiple tiles? You could have a value you can put on the stack after each function that changes multiple tiles, and then when you press undo, it keeps "poping" values off the stack until it reaches this value.[/ramble]
 
Jul 21, 2009 at 4:27 AM
Hoxtilicious
"Life begins and ends with Nu."
Join Date: Dec 30, 2005
Location: Germany
Posts: 3218
Age: 33
Pronouns: he/him
Why don't you use classes for a undo function?
 
Jul 21, 2009 at 4:39 AM
Administrator
Forum Administrator
"Life begins and ends with Nu."
Join Date: Jul 15, 2007
Location: Australia
Posts: 6223
Age: 39
Pronouns: he/him
dooey100 said:
Hmmm, this got me thinking about easy ways to implement an undo stack, and since I've done all this thinking, I might as well post the results here. I don't know how much programming experience you have, Wistil, but it is almost certainly more then mine, so feel free to ignore this.

First, have a "change the map" function, which, as well as changing the map tile in location X, also writes the location and previous value to an undo stack. (and increases the stack pointer and all that other stuff needing stacks). Calling the "undo" function "pops" the last value off the stack, changing it back to what it was before, and decrementing the stack pointer. But what about functions that change multiple tiles? You could have a value you can put on the stack after each function that changes multiple tiles, and then when you press undo, it keeps "poping" values off the stack until it reaches this value.[/ramble]
Creating a stack would be easy. Limiting the number of undos to the stack would also be easy. The hard part is writing every action to the stack with enough information to undo these actions, using this information to revert whatever you are working on to it's previous state with minimal consumption of resources, and writing specific code for each situation it is required for. Tile changed? Tile change undo code. Script changed? Text change undo code.

@Wistil: How did I do? ;)
 
Jul 21, 2009 at 4:53 AM
Been here way too long...
"Ha! Ha! Ha! Mega Man is no match for my Mimiga Man!"
Join Date: Jun 22, 2008
Location:
Posts: 251
I was assuming each major area of the editor would have its own stack. EG the map editor would have a stack, the entity editor would have a stack, and the script editor would have a stack (although having a stack seems less necessary for scripting)

Also you wouldn't need new functions for undos, as its always just the opposite of whatever was done. Deleted an entity here? Undo = create an entity. Create an entity? Undo = delete the entity. Change a map tile? Undo = change a map tile ;)

To limit the memory usage, limit the stack size. Yeah, that means you can only undo so far, but almost every program I've seen can only undo so far. (The sole exception being Paint.net)
 
Jul 21, 2009 at 4:55 AM
Hoxtilicious
"Life begins and ends with Nu."
Join Date: Dec 30, 2005
Location: Germany
Posts: 3218
Age: 33
Pronouns: he/him
It's way easier.

Why don't you use classes for a undo function?

I don't know if you're familar with Basic but it shouldn't be too hard to figure out:

Code:
[color=#7F7F7F]Public Class[/COLOR] MapUndo
    [color=#7F7F7F]Public[/COLOR] Tiles()() [color=#7F7F7F]As Byte[/COLOR]

    [color=#7F7F7F]Public Sub New[/COLOR]([color=#7F7F7F]ByVal[/COLOR] SourceTiles()()[color=#7F7F7F] As Byte[/COLOR])
        Tiles()() = SourceTiles()()
    [color=#7F7F7F]End Sub[/COLOR]

    [color=#7F7F7F]ReadOnly Property[/COLOR] Width() [color=#7F7F7F]As UInt32[/COLOR]
        [color=#7F7F7F]Get[/COLOR]
            [color=#7F7F7F]Return[/COLOR] Tiles.GetUpperBound(0)
        [color=#7F7F7F]End Get[/COLOR]
    [color=#7F7F7F]End Property[/COLOR]

    [color=#7F7F7F]ReadOnly Property[/COLOR] Height() [color=#7F7F7F]As UInt32[/COLOR]
        [color=#7F7F7F]Get[/COLOR]
            [color=#7F7F7F]Return[/COLOR] Tiles.GetUpperBound(1)
        [color=#7F7F7F]End Get[/COLOR]
   [color=#7F7F7F]End Property[/COLOR]

[color=#7F7F7F]End Class[/COLOR]

Code:
[color=#7F7F7F]Public Const[/COLOR] UndoSize [color=#7F7F7F]As Byte[/COLOR] = 16
[color=#7F7F7F]Public[/COLOR] MapBackup(UndoSize) [color=#7F7F7F]As[/COLOR] MapUndo

[color=#7F7F7F]Public Sub[/COLOR] InsertBackup([color=#7F7F7F]ByVal[/COLOR] SourceTiles()() [color=#7F7F7F]As Byte[/COLOR])

    [color=#7F7F7F]Dim[/COLOR] Count [color=#7F7F7F]As Byte[/COLOR]

    [color=#7F7F7F]If[/COLOR] MapBackup(UndoSize) <> [color=#7F7F7F]Null[/COLOR]
        [color=#7F7F7F]For[/COLOR] Count = UndoSize - 1 [color=#7F7F7F]To[/COLOR] 0 [color=#7F7F7F]Step[/COLOR] -1
            MapBackup(Count + 1) = MapBackup(Count)
        [color=#7F7F7F]Next[/COLOR]
        MapBackup(0) = [color=#7F7F7F]New[/COLOR] MapUndo(SourceTiles()())
    [color=#7F7F7F]Else[/COLOR]
        [color=#7F7F7F]For[/COLOR] Count = 0 [color=#7F7F7F]To[/COLOR] UndoSize
            [color=#7F7F7F]If[/COLOR] MapBackup(Count) = [color=#7F7F7F]Null[/COLOR],
                MapBackup(Count) = [color=#7F7F7F]New[/COLOR] MapUndo(SourceTiles()())
            [color=#7F7F7F]End If[/COLOR]
        [color=#7F7F7F]Next[/COLOR]
    [color=#7F7F7F]End If[/COLOR]

[color=#7F7F7F]End Sub[/COLOR]

There you go ;)
That's all your undo function will need. It just backups all the tiles.

Edit: If you only want to have special tiles being backuped and not the whole map you could create a class for that too.
Then you just will have a bunch of arrays of that class.
Like:

Code:
[color=#7F7F7F]Public Class[/COLOR] MapTiles
    [color=#7F7F7F]Public[/COLOR] X [color=#7F7F7F]As UShort[/COLOR]
    [color=#7F7F7F]Public[/COLOR] Y [color=#7F7F7F]As UShort[/COLOR]
    [color=#7F7F7F]Public[/COLOR] Type [color=#7F7F7F]As Byte[/COLOR]

    [color=#7F7F7F]Public Sub New[/COLOR]([color=#7F7F7F]ByVal[/COLOR] XPos[color=#7F7F7F] As UShort[/COLOR], [color=#7F7F7F]ByVal[/COLOR] YPos[color=#7F7F7F] As UShort[/COLOR], [color=#7F7F7F]ByVal[/COLOR] TileType[color=#7F7F7F] As Byte[/COLOR])
        X = XPos
        Y = YPos
        Type = TileType
    [color=#7F7F7F]End Sub[/COLOR]

[color=#7F7F7F]End Class[/COLOR]
 
Jul 21, 2009 at 5:44 AM
Hoxtilicious
"Life begins and ends with Nu."
Join Date: Dec 30, 2005
Location: Germany
Posts: 3218
Age: 33
Pronouns: he/him
dooey100 said:
Easier it may be, but memory efficient it is not ;)

Which might not even be a problem, but I had more fun doing it my way anyway. :p

With the "MapTiles" class it's memory efficient enough :p
Plus it's a rather clean method.
 
Jul 21, 2009 at 7:21 AM
Administrator
Forum Administrator
"Life begins and ends with Nu."
Join Date: Jul 15, 2007
Location: Australia
Posts: 6223
Age: 39
Pronouns: he/him
S. P. Gardebiter said:
That's all your undo function will need. It just backups all the tiles.
After every single change? Isn't that somewhat inefficient?
 
Jul 21, 2009 at 4:04 PM
Hoxtilicious
"Life begins and ends with Nu."
Join Date: Dec 30, 2005
Location: Germany
Posts: 3218
Age: 33
Pronouns: he/him
andwhyisit said:
After every single change? Isn't that somewhat inefficient?

That was one example, I have posted another example. -.-
Why does noone read my edits? ;)
 
Jul 21, 2009 at 4:44 PM
Vanished.
Bobomb says: "I need a hug!"
Join Date: Apr 5, 2008
Location:
Posts: 776
andwhyisit said:
No. The problem with noobs (as opposed to newbs) it that the have no capacity for learning or figuring anything out themselves.

Newb mode is fine (maybe little ? icons that explain what each thing does when you roll over them so that you don't need separate "modes"), but noob mode sounds painful.

I meant it like:
Normal (warnings, not all editing tools visible (like ASM and stuff))
Advanced (Everything visible, less warning, more powerful)

Not everyone wants to mess around with ASM.
They want quick and easy editing.
 
Jul 21, 2009 at 7:25 PM
In front of a computer
"Man, if only I had an apple..."
Join Date: Mar 1, 2008
Location: Grasstown
Posts: 1435
Mr. Fist said:
Maybe an Empty Map feature?
Just click on it from a menu and the map turns into a black space devoid of entities or solid ground.
No, just add a Delete All Entities function. If you want to erase all the tiles, you can use the existing Fill function (at least, I think it already exists?).

dooey100 said:
An undo stack would be awesome, although I understand they are rather hard to implement, and would need a fairly significant rewrite for a lot of the map editing functions.
I'm not sure I agree with it being a stack, though. I've thought a little about a way to implement an undo list. The idea was to have an UndoList class (which would probably have only a single instance) containing an std::list (a doubly-linked list, in case you're unfamiliar with the STL) and an iterator pointing to the current element (an iterator is a pointer or a class that behaves like one; if you didn't use the STL you'd probably just use a pointer). If you haven't undone anything since your last action, the iterator would point at a null entry indicating the end of the list.

The list elements would be pointers to an abstract UndoAction class. The UndoAction class would need two pure virtual method, undoAction() and redoAction(). When you choose "Undo" from the menu, the list pointer would be decremented, and then the undoAction() method would be called on the pointee. When you choose "Redo" from the menu, the redoAction() method would be called on the pointee, and then the pointer would be incremented. And when you do an action that can be undone, everything on the list from the current pointer to the end is deleted, the new action is inserted at the end, and the pointer is incremented.

Then all you would have to do is create classes that inherit from UndoAction for every type of action that you want to be able to undo.

dooey100 said:
I was assuming each major area of the editor would have its own stack. EG the map editor would have a stack, the entity editor would have a stack, and the script editor would have a stack (although having a stack seems less necessary for scripting)
Uh... I don't think I like this idea. I could accept the potential usefulness of a separate undo list for the script editor, but I think there should be a single list for anything else.

dooey100 said:
Also you wouldn't need new functions for undos, as its always just the opposite of whatever was done. Deleted an entity here? Undo = create an entity. Create an entity? Undo = delete the entity. Change a map tile? Undo = change a map tile :p
Creating an entity is not necessarily the action to take when undoing a delete entity action. If the structure storing an entity is complex enough, it would probably be better to not delete it at all, but simply store a pointer to it in the undo action.

However, if it's very simple (like a POD type with only a few elements) it wouldn't make much of a difference. In that case, copy the entity, then delete it. Undoing would still be a different action from creating a new entity, though.

dooey100 said:
To limit the memory usage, limit the stack size. Yeah, that means you can only undo so far, but almost every program I've seen can only undo so far. (The sole exception being Paint.net)
That's not the sole exception. There are plenty of programs that support an unlimited undo list. Some of them allow you to choose the limit.

S. P. Gardebiter said:
It's way easier.

Why don't you use classes for a undo function?
As you can see, I quite agree. I'll even post the code I wrote for this (for a different program, but it work just as well here). Note that this code is still incomplete and untested.

Code:
[color=#7F7F7F]// undo.h[/COLOR]
[color=#7F7F7F]#include[/COLOR] <list>

[color=#7F7F7F]class[/COLOR] cAction {
[color=#7F7F7F]public[/COLOR]:
    [color=#7F7F7F]virtual void[/COLOR] undo() = 0; [color=#7F7F7F]// undoes this action if it has not already been undone[/COLOR]
    [color=#7F7F7F]virtual void[/COLOR] redo() = 0; [color=#7F7F7F]// redoes this action if it has been undone[/COLOR]
    [color=#7F7F7F]virtual bool[/COLOR] isDone() = 0; [color=#7F7F7F]// checks to see whether the action has been undone; returns false if it has[/COLOR]
    [color=#7F7F7F]virtual[/COLOR] [color=#7F7F7F]std[/COLOR]::[color=#7F7F7F]string[/COLOR] getActionName() = 0; [color=#7F7F7F]// returns the name of this action for display in the Edit menu[/COLOR]
    [color=#7F7F7F]virtual[/COLOR] ~cAction();
};

[color=#7F7F7F]class[/COLOR] cUndoList {
    [color=#7F7F7F]std[/COLOR]::[color=#7F7F7F]list[/COLOR]<cAction*> theList;
    [color=#7F7F7F]std[/COLOR]::[color=#7F7F7F]list[/COLOR]<cAction*>::[color=#7F7F7F]iterator[/COLOR] cur, lastSave;
    [color=#7F7F7F]std[/COLOR]::[color=#7F7F7F]size_t[/COLOR] num_actions;
[color=#7F7F7F]public[/COLOR]:
    cUndoList();
    [color=#7F7F7F]void[/COLOR] undo(); [color=#7F7F7F]// undoes the current action and decrements the cur pointer[/COLOR]
    [color=#7F7F7F]void[/COLOR] redo(); [color=#7F7F7F]// increments the cur pointer and redoes the current action[/COLOR]
    [color=#7F7F7F]void[/COLOR] save(); [color=#7F7F7F]// sets the last saved action to the current action[/COLOR]
    [color=#7F7F7F]void[/COLOR] revert(); [color=#7F7F7F]// undoes all actions back to (but excluding) the last saved action[/COLOR]
    [color=#7F7F7F]void[/COLOR] add(cAction* what);
    [color=#7F7F7F]static[/COLOR] [color=#7F7F7F]std[/COLOR]::[color=#7F7F7F]size_t[/COLOR] maxUndoSize;
};

[color=#7F7F7F]// undo.cpp[/COLOR]

[color=#7F7F7F]#include[/COLOR] "undo.h"

cUndoList::cUndoList(){
    lastSave = cur = theList.[color=#7F7F7F]begin[/COLOR]();
}

[color=#7F7F7F]std[/COLOR]::[color=#7F7F7F]size_t[/COLOR] cUndoList::maxUndoSize = 0;

[color=#7F7F7F]// TODO: These functions should have error checking to ensure they do not access an out of bounds action; basically, if cur == theList.[color=#7F7F7F]end[/COLOR](), then there are no more actions to redo[/COLOR]
[color=#7F7F7F]void[/COLOR] cUndoList::undo(){
    cur--;
    (*cur)->undo();
}

[color=#7F7F7F]void[/COLOR] cUndoList::redo(){
    (*cur)->redo();
    cur++;
}

[color=#7F7F7F]void[/COLOR] cUndoList::save(){
    lastSave = cur;
}

[color=#7F7F7F]void[/COLOR] cUndoList::revert(){
    [color=#7F7F7F]while[/COLOR](cur != lastSave) undo();
}

[color=#7F7F7F]void[/COLOR] cUndoList::add(cAction* what){
    theList.[color=#7F7F7F]push_back[/COLOR](what);
    num_actions++;
    [color=#7F7F7F]while[/COLOR](num_actions > maxUndoSize)
        theList.[color=#7F7F7F]pop_front[/COLOR](), num_actions--;
}

Schokobecher said:
I meant it like:
Normal (warnings, not all editing tools visible (like ASM and stuff))
Advanced (Everything visible, less warning, more powerful)
If you're going to do that, why not allow the user to pick and choose which warnings are suppressed and which editing tools are available?
 
Jul 21, 2009 at 7:50 PM
Vanished.
Bobomb says: "I need a hug!"
Join Date: Apr 5, 2008
Location:
Posts: 776
If you're going to do that, why not allow the user to pick and choose which warnings are suppressed and which editing tools are available?
That would be the next level :)
I see you got my point.
 
Jul 22, 2009 at 5:31 AM
Lvl 1
Forum Moderator
"Life begins and ends with Nu."
Join Date: May 28, 2008
Location: PMMM MMO
Posts: 3713
Age: 32
Was finally able to dl the newest version and... =D

The tile-type overlay display isn't working, and when I load scripts it doesn't load the commands. I think the executable is not loading the .txt and that .png file for some reason. Here's some pics.
p19997-0-2vbu988.jpg


I'm running xp, service pack 2 btw. At work though they force me to use a Vista =(.
 
Jul 22, 2009 at 5:43 AM
Been here way too long...
"Ha! Ha! Ha! Mega Man is no match for my Mimiga Man!"
Join Date: Jun 22, 2008
Location:
Posts: 251
I also have a bug to report: When changing the script editor to a very large script, the is a lot of lag and the cursor jumps back and forth between the pointer and the hourglass (Vista SP2)

Also, it would be nice if the was a warning if you are changing scripts that there are unsaved changes, because I keep changing to a different script without saving, and loosing all the stuff I added. Which I guess is a holdover from SW, where you can have as many scripts open as you want at one time.
 
Jul 23, 2009 at 1:35 AM
Cold Agony of Resolute Vacuum
"Heavy swords for sale. Suitable for most RPG Protagonists. Apply now!"
Join Date: Jan 1, 2008
Location: Elsewhere
Posts: 1973
GIRakaCHEEZER said:
Was finally able to dl the newest version and... =D

The tile-type overlay display isn't working, and when I load scripts it doesn't load the commands. I think the executable is not loading the .txt and that .png file for some reason. Here's some pics.
p19997-0-2vbu988.jpg


I'm running xp, service pack 2 btw. At work though they force me to use a Vista =(.

Ditto the tile-type overlay, 'cept I'm on SP 3, as well as a minor bug I inadvertantly discovered:
When viewing the NPC data, it will crash if you try to view an entity past 371.
While I'm sure there is a good reason for this (Eg. They don't exist...), a warning dialogue (Ie. End of Entity List! Return to beginning? Y/N) might be an idea.

@ Gir: Make sure you have the CE_TSC_Info.txt file in the directory.
And if you've made any changes to it, make sure that there is no blank lines near the top, or attempts to include comments with a "<" or something.
 
Jul 23, 2009 at 2:47 AM
Lvl 1
Forum Moderator
"Life begins and ends with Nu."
Join Date: May 28, 2008
Location: PMMM MMO
Posts: 3713
Age: 32
DragonBoots said:

@ Gir: Make sure you have the CE_TSC_Info.txt file in the directory.
And if you've made any changes to it, make sure that there is no blank lines near the top, or attempts to include comments with a "<" or something.

Actually I solved this error, it was because I pinned CE to the start menu and was running it from there. Putting a shortcut to CE in the startup menu solved the problem with TSC codes, as well as running it from it's folder directory.
 
Back
Top