Booster's Lab - It's Pretty Good Now

Mar 2, 2013 at 4:10 AM
Administrator
Forum Administrator
"Life begins and ends with Nu."
Join Date: Jul 15, 2007
Location: Australia
Posts: 6205
Age: 37
Would it be possible for BL to allow the exporting of Vanilla CS (PC) format mapdata?
It's difficult for me to explain to someone else how to do this via a hex editor when mapdata can be all over the place depending on what editor was used, so a way to streamline this process would be very much appreciated.
 
Mar 2, 2013 at 10:42 AM
Lvl 1
Forum Moderator
"Life begins and ends with Nu."
Join Date: May 28, 2008
Location: PMMM MMO
Posts: 3713
Age: 30
Hey noxid, you should enable zooming with the scroll wheel (even if not as default, as an optional setting). Also you should make said zooming zoom in/out centered about the mouse cursor.
 
Mar 2, 2013 at 11:05 PM
Administrator
Forum Administrator
"Life begins and ends with Nu."
Join Date: Jul 15, 2007
Location: Australia
Posts: 6205
Age: 37
GIRakaCHEEZER said:
Hey noxid, you should enable zooming with the scroll wheel (even if not as default, as an optional setting). Also you should make said zooming zoom in/out centered about the mouse cursor.
CTRL+MOUSEWHEEL is better. I would naturally expect CTRL+MOUSEWHEEL to zoom and for MOUSEWHEEL by itself to scroll, as the natural behaviour of the mousewheel is just that, to scroll. I know for a fact that all major desktop browsers support CTRL+MOUSEWHEEL for zooming.

On that subject is it possible to make it so that holding down on the mouse wheel does not count as a left click?
 
Mar 7, 2013 at 9:38 PM
Hey.
"In Soviet Russia, graves keep YOU!"
Join Date: Oct 20, 2010
Location: Within the hearts of all
Posts: 691
Age: 102
Is this editor stable enough to use seriously at this point? I wanted to have this confirmed before I try it out.
 
Mar 7, 2013 at 9:57 PM
Professional Whatever
"Life begins and ends with Nu."
Join Date: Jan 13, 2011
Location: Lasagna
Posts: 4485
There's some glitches but it won't probably kill your game probably. I use it with my mods.
 
Mar 8, 2013 at 1:16 AM
Hey.
"In Soviet Russia, graves keep YOU!"
Join Date: Oct 20, 2010
Location: Within the hearts of all
Posts: 691
Age: 102
Cool, I'll check it out then.
 
Mar 10, 2013 at 10:35 PM
Senior Member
"I, Ikachan. The Life and Documentary of the OrigiNAL SQuiD."
Join Date: Oct 29, 2012
Location: England
Posts: 178
Age: 24
Cool, I'm definitely going to use Booster's Lab when porting my mod to CS+. I figured out how to get the mods to appear in the CS+ start menu under the challenges tab, the only problem was actually putting my mod there. Thanks, Noixd, once BL leaves Beta I will definitely make a permanent switch from CE to BL.
 
Mar 11, 2013 at 5:17 AM
In my body, in my head
Forum Moderator
"Life begins and ends with Nu."
Join Date: Aug 28, 2009
Location: The Purple Zone
Posts: 5998
ok control-scroll zoom will be implemented in the next release. At the moment it doesn't do a super job of focusing on the mouse but if you're lucky I'll be able to fix that. I swear there are gonna be more ways to zoom in and out than anything else, next you'll have me make it controllable by wiggling your ass in front of a webcam or something.
Export mapdata will produce a 2nd file "csmap.bin" which contains vanilla-format mapdata, alongside the currently produced "stage.tbl" which contains CS+ format (hopefully).

I probably won't update it again until a 0.3.0.0 or greater release which will contain an at least somewhat functional hack dialog. Unsure how long this will take, depends on my workload etc. etc.

note to self making new maps doesn't detect name collisions (it should)
 
Mar 11, 2013 at 6:20 AM
Administrator
Forum Administrator
"Life begins and ends with Nu."
Join Date: Jul 15, 2007
Location: Australia
Posts: 6205
Age: 37
Noxid said:
I swear there are gonna be more ways to zoom in and out than anything else, next you'll have me make it controllable by wiggling your ass in front of a webcam or something.
Nonsense. Ass wiggling should be used for scrolling the map pane. :p
 
Mar 14, 2013 at 5:16 AM
In my body, in my head
Forum Moderator
"Life begins and ends with Nu."
Join Date: Aug 28, 2009
Location: The Purple Zone
Posts: 5998
GIR said I should post this code snippet so you all can see what an amazing programmer I am and how I stop at nothing to ensure that you have the most efficient, stable, well-written software money can't buy.
Code:
		@Override
		public void mouseReleased(MouseEvent eve) {
			int mapX = dataHolder.getMapX();
			int mapY = dataHolder.getMapY();
			Point mousePoint = eve.getPoint();
			int viewScale = (int) (EditorApp.DEFAULT_TILE_SIZE * EditorApp.mapScale);
			int cursorX, cursorY;
			
			//do nothing if we are editing the line layer
			if (parent.getActiveLayer() == 4)
				return;
			if (eve.isPopupTrigger()) {
				//this needs to be copied to isRelease
				cursorX = mousePoint.x / viewScale;
				cursorY = mousePoint.y / viewScale;
				popup_tilescript.setAction(
						new TilescriptAction(mapX, mapY, tilePen.getI(0, 0), 
								parent.getActiveLayer()));
				popup_tilescript.setText("generate CMP for (" + cursorX + "," + cursorY + ")");
				popup_tra.setAction(new TraScriptAction(cursorX, cursorY, dataHolder.getMapNumber()));
				popup_tra.setText("make <TRA to this spot");
				popup.show(eve.getComponent(), eve.getX(), eve.getY());
				return;
			}			
			if ((eve.getModifiersEx() & MouseEvent.BUTTON3_DOWN_MASK) != 0)
				return; //do nothing if right mouse button
			if (dragging) {
				//setCursor(null);
				return;
			}
			byte[][] oldDat;
			byte[][] newDat;
			Rectangle newCursorRect;
			int w, h;
			//Graphics2D g2d = (Graphics2D)((MapPane)eve.getSource()).getGraphics();
			switch (parent.getDrawMode()) {
			case EditorApp.DRAWMODE_RECT:
				if (selW < 0)
					cursorX = baseX + selW + 1;
				else
					cursorX = baseX;
				//absolutize to make calculations easy
				//(it no longer needs to be updated until next click)
				selW = Math.abs(selW);
				if (selH < 0)
					cursorY = baseY + selH + 1;
				else
					cursorY = baseY;
				//see above
				selH = Math.abs(selH);
				int tmpx = tilePen.dx;
				int tmpY = tilePen.dy;
				tilePen.dx = 0;
				tilePen.dy = 0;
				//capture the previous state
				oldDat = new byte[selW][selH];
				for (int dx = 0; dx < selW; dx++) {
					for (int dy = 0; dy < selH; dy++) {
						oldDat[dx][dy] = dataHolder.getTileB(cursorX + dx, cursorY + dy, parent.getActiveLayer());
					}
				}
				//draw over it
				for (int dx = 0; dx < selW; dx += tilePen.getW()) {
					for (int dy = 0; dy < selH; dy += tilePen.getH()) {
						drawPen(cursorX + dx, cursorY + dy, cursorX + selW, cursorY + selH);
					}
				}
				//capture the new state
				newDat = new byte[selW][selH];
				for (int dx = 0; dx < selW; dx++) {
					for (int dy = 0; dy < selH; dy++) {
						newDat[dx][dy] = dataHolder.getTileB(cursorX + dx, cursorY + dy, parent.getActiveLayer());
					}
				}
				redrawTiles(cursorX, cursorY, selW, selH);
				tilePen.dx = tmpx;
				tilePen.dy = tmpY;
				selW = 1;
				selH = 1;
				dataHolder.addEdit(dataHolder.new MapEdit(cursorX, cursorY, oldDat, newDat, parent.getActiveLayer()));
				break;
			case EditorApp.DRAWMODE_COPY:
				if (selW < 0)
					cursorX = baseX + selW + 1;
				else
					cursorX = baseX;
				//absolutize to make calculations easy
				//(it no longer needs to be updated until next click)
				selW = Math.abs(selW);
				if (selH < 0)
					cursorY = baseY + selH + 1;
				else
					cursorY = baseY;
				//see above
				selH = Math.abs(selH);
				
				//create a pen
				tilePen = new TileBuffer();
				tilePen.dx = baseX - cursorX;
				tilePen.dy = baseY - cursorY;
				tilePen.data = new byte[selW][selH];
				for (int x = 0; x < selW; x++) {
					for (int y = 0; y < selH; y++) {
						tilePen.data[x][y] = dataHolder.getTileB(cursorX + x, cursorY + y, parent.getActiveLayer());
					}
				}
				redrawTiles(cursorX, cursorY, selW, selH);
				preview.repaint();
				selW = 1;
				selH = 1;
				break;
			case EditorApp.DRAWMODE_FILL:
				int currentX = mousePoint.x / viewScale;
				int currentY = mousePoint.y / viewScale;
				if (currentX >= mapX)
					currentX = mapX-1;
				if (currentX < 0)
					currentX = 0;
				if (currentY >= mapY)
					currentY = mapY-1;
				if (currentY < 0)
					currentY = 0;
				Rectangle tracker = new Rectangle(currentX, currentY, 0, 0);
				fillPen(currentX, 
						currentY, 
						0, 
						0, 
						dataHolder.getTileB(currentX, currentY, parent.getActiveLayer()), 
						tracker);
				//System.out.println(tracker);
				tracker.width += 1;
				tracker.height += 1;
				redrawTiles(tracker.x, tracker.y,
						tracker.x + tracker.width,
						tracker.height + tracker.y);

				//oldCursorRect = new Rectangle(lastX - tilePen.dx, lastY - tilePen.dy, tilePen.getW(), tilePen.getH());
				newCursorRect = new Rectangle(currentX - tilePen.dx, currentY - tilePen.dy, tilePen.getW(), tilePen.getH());
				//put the cursor back
				moveCursor(newCursorRect);
				oldDat = new byte[tracker.width][tracker.height];
				for (int dx = 0; dx < tracker.width; dx++) {
					for (int dy = 0; dy < tracker.height; dy++) {
						oldDat[dx][dy] = prevLayerState[tracker.x + dx][tracker.y + dy];
					}
				}
				//capture the new state
				newDat = new byte[tracker.width][tracker.height];
				for (int dx = 0; dx < tracker.width; dx++) {
					for (int dy = 0; dy < tracker.height; dy++) {
						newDat[dx][dy] = dataHolder.getTileB(tracker.x + dx, tracker.y + dy, parent.getActiveLayer());
					}
				}
				//create the edit
				dataHolder.addEdit(dataHolder.new MapEdit(tracker.x, tracker.y, 
						oldDat, newDat, parent.getActiveLayer()));
				break;
			case EditorApp.DRAWMODE_REPLACE:
				currentX = eve.getX() / viewScale;
				currentY = eve.getY() / viewScale;
				if (currentX >= mapX)
					currentX = mapX-1;
				if (currentX < 0)
					currentX = 0;
				if (currentY >= mapY)
					currentY = mapY-1;
				if (currentY < 0)
					currentY = 0;
				Rectangle r = replacePen(currentX, currentY);
				r.width += 1;
				r.height += 1;
				redrawTiles(r.x, r.y, r.width, r.height);
				//put the cursor back
				//oldCursorRect = new Rectangle(lastX - tilePen.dx, lastY - tilePen.dy, tilePen.getW(), tilePen.getH());
				newCursorRect = new Rectangle(currentX - tilePen.dx, currentY - tilePen.dy, tilePen.getW(), tilePen.getH());
				moveCursor(newCursorRect);

				w = r.width - r.x;
				h = r.height - r.y;
				oldDat = new byte[w][h];
				for (int dx = 0; dx < w; dx++) {
					for (int dy = 0; dy < h; dy++) {
						oldDat[dx][dy] = prevLayerState[r.x + dx][r.y + dy];
					}
				}
				//capture the new state
				newDat = new byte[w][h];
				for (int dx = 0; dx < w; dx++) {
					for (int dy = 0; dy < h; dy++) {
						newDat[dx][dy] = dataHolder.getTileB(r.x + dx, r.y + dy, parent.getActiveLayer());
					}
				}
				//create the edit
				dataHolder.addEdit(dataHolder.new MapEdit(r.x, r.y, oldDat, 
						newDat, parent.getActiveLayer()));
				break;
			case EditorApp.DRAWMODE_DRAW:
				//capture the previous state
				if (selW > mapX)
					selW = mapX;
				if (selH > mapY)
					selH = mapY;
				w = selW - baseX;
				h = selH - baseY;
				oldDat = new byte[w][h];
				for (int dx = 0; dx < w; dx++) {
					for (int dy = 0; dy < h; dy++) {
						oldDat[dx][dy] = prevLayerState
								[baseX + dx - tilePen.dx][baseY + dy - tilePen.dy];
					}
				}
				//capture the new state
				newDat = new byte[w][h];
				for (int dx = 0; dx < w; dx++) {
					for (int dy = 0; dy < h; dy++) {
						newDat[dx][dy] = dataHolder.getTileB(
								baseX + dx - tilePen.dx, 
								baseY + dy - tilePen.dy, 
								parent.getActiveLayer());
					}
				}
				//create the edit
				dataHolder.addEdit(dataHolder.new MapEdit(baseX - tilePen.dx, baseY - tilePen.dy, oldDat, 
						newDat, parent.getActiveLayer()));
				break;
			default:
				break;
			}
		}

fun fact: this represents about 1.75% of the current BL codebase
 
Mar 16, 2013 at 12:15 AM
Administrator
Forum Administrator
"Life begins and ends with Nu."
Join Date: Jul 15, 2007
Location: Australia
Posts: 6205
Age: 37
Just an idea for the future, not now obviously, but a way to load a maplist and edit maps entities and tsc by loading the data directory directly (bypassing the executable entirely) might be beneficial down the line when you start work on making BL cross-platform. This way BL can have limited support for all ports regardless of if it supports them directly or not.
 
Mar 16, 2013 at 2:37 AM
In my body, in my head
Forum Moderator
"Life begins and ends with Nu."
Join Date: Aug 28, 2009
Location: The Purple Zone
Posts: 5998
Well

it sort of does that now and sort of doesn't. Currently it does support a few different project setups, that being CS+-like (external mapdata in the data directory) and CS-like (mapdata in the exe) as well as pxm-only. I've been reticent to enable editing w/o having the mapdata there because there is kind of a fair bit of important information in the mapdata itself, so it would be difficult to set up right and you wouldn't even be able to change the tilesets of a map and stuff. So for that, single-map loading/editing is maybe the best I can give.
I think I could find the mapdata in the mac version but as for that I have no idea what you're supposed to load / would have access to on a mac. A .app folder? the .dmg? it's all so foreign to me.
 
Mar 16, 2013 at 12:50 PM
Administrator
Forum Administrator
"Life begins and ends with Nu."
Join Date: Jul 15, 2007
Location: Australia
Posts: 6205
Age: 37
Dear god I'm an idiot. Please ignore that idea.

Though I do have information on the mac format.

The .dmg is more or less a Mac-specific file packaging format, like .zip and the like.
Well that's not what the format was originally intended for but that's what nakiwo used it for.

Doukutsu.app is a folder in reality. Though opening the .app folder rather than the main executable binary would be the safest option.

Save file names can be edited here:
Doukutsu.app\Contents\Info.plist
Doukutsu.app\Contents\Resources\Info.plist

It's an XML-ish plain text format. Look for key "CFBundleIdentifier" and modify the paired string to your needs. All save files are saved in the same folder, so a way to set this from the editor would prevent conflict.

Data Folder:
Doukutsu.app\Contents\Resources\data\

Executable:
Doukutsu.app\Contents\MacOS\Doukutsu

The mapdata is at $9FD40 and $1467A0 in the executable, one for PowerPC Macs and another for Intel Macs. The format is different to CSPC and the two sets of mapdata have different byte orders to each other.
This only applies to the universal binary mind you. I know little about the PowerPC-only binary but I doubt anyone really uses it these days.

However I don't know how to break the map limitation.

Here's a copy of the files to mess around with (.zip instead of .dmg):
http://www.mediafire.com/?58401hfxeu8muqo

Here's cultr1's old anti-(C)Pixel .bmp hack, so you can run file comparisons if you want:
http://www.mediafire.com/?we63ym18f1gep6c

I had information on mac weapon data, but I can't remember where I put it.
 
Mar 26, 2013 at 6:35 PM
Indie game enthusiast
"What is a man!? A miserable pile of secrets! But enough talk, have at you!"
Join Date: Apr 18, 2006
Location: Forever wandering the tower...!
Posts: 1776
Is there currently a way while map editing : to use Copy to grab something on one tab, switch tabs, and paste it elsewhere?
I tend to build unconnected areas on a construction map, and then start putting them together on other maps later...
 
Mar 28, 2013 at 1:34 AM
In my body, in my head
Forum Moderator
"Life begins and ends with Nu."
Join Date: Aug 28, 2009
Location: The Purple Zone
Posts: 5998
Currently: No, but may try to come up with a solution for that, time permitting.
 
Mar 28, 2013 at 8:27 PM
In my body, in my head
Forum Moderator
"Life begins and ends with Nu."
Join Date: Aug 28, 2009
Location: The Purple Zone
Posts: 5998
Oops :p
No doubt I've missed a thing or two in the entity list, thanks for pointing it out; I'll have it fixed in the next release.
 
May 3, 2013 at 3:07 PM
The TideWalker
Modding Community Discord Founder
"That dog!"
Join Date: Apr 5, 2013
Location: In my mind and of my body.
Posts: 1638
Age: 25

Could Something like this be incoreperated in the near future?



[attachment=382:Booster_com1.png]





It should be spell proof with or without a <FAC command similar to this.



[attachment=383:Booster_1.PNG]





The only tricky part it getting it to render the correct face from the template.








 
May 3, 2013 at 7:22 PM
Been here way too long...
"What're YOU lookin' at?"
Join Date: Jan 21, 2007
Location:
Posts: 1111
Actually rather than do that, why not have one of the script-view types show simply a text-box graphic under the script window with whatever selected <MSG area shown inside it? It seems to already determine the number of characters afterward anyway, so it's not like you "can't" do it.

Then plop the most recent <FAC (if any) into the message window. Or have some checkbox toggle between the face offset and not.
 
Top