mirror of
https://github.com/1dot13/source.git
synced 2026-07-22 13:40:22 +02:00
* More unused stuff removal
delete:
- giant 'metaheaders' (JA2 All.h, Laptop All.h, etc), preferring to add #includes directly where needed
- unused ExceptionHandling and DbMan translation units
- unused WizShare.h, Bitmap.h, trle.h, video_private.h headers
* remove mentions from vc proj files too
* remove preprocessor conditionals for unused definitions
find . -iname '*.h' -o -iname '*.cpp' -exec unifdef.exe -m -UPRECOMPILED_HEADERS -UJA2_PRECOMPILED_HEADERS -UWIZ8_PRECOMPILED_HEADERS -UPRECOMPILEDHEADERS {} ';'
then manually fixed a couple files the tool errored out on
* yes, the comments too
as title
462 lines
12 KiB
C++
462 lines
12 KiB
C++
#include "builddefines.h"
|
|
|
|
#ifdef JA2EDITOR
|
|
|
|
#include "types.h"
|
|
#include "Cursor Modes.h"
|
|
#include "renderworld.h"
|
|
#include "random.h"
|
|
#include "worldman.h"
|
|
#include "interface.h"
|
|
#include "Isometric Utils.h"
|
|
#include "editscreen.h"
|
|
#include "EditorDefines.h"
|
|
#include "input.h"
|
|
#include "english.h"
|
|
#include "Editor Taskbar Utils.h"
|
|
#include "Overhead.h"
|
|
#include "EditorMercs.h"
|
|
#include "EditorBuildings.h"
|
|
|
|
#include "Text.h"
|
|
|
|
BOOLEAN fValidCursor = FALSE;
|
|
BOOLEAN fAnchored = FALSE;
|
|
BOOLEAN gfBrushEnabled = TRUE;
|
|
UINT16 gusSelectionWidth = 1, gusPreserveSelectionWidth = 1;
|
|
UINT16 gusSelectionType = SMALLSELECTION;
|
|
UINT16 gusSelectionDensity = 2;
|
|
UINT16 gusSavedSelectionType = SMALLSELECTION;
|
|
UINT16 gusSavedBuildingSelectionType = AREASELECTION;
|
|
extern INT16 sGridX; // symbol already declared globally in editscreen.cpp (jonathanl)
|
|
extern INT16 sGridY; // symbol already declared globally in editscreen.cpp (jonathanl)
|
|
INT32 sBadMarker = -1;
|
|
|
|
//STR16 wszSelType[6]= { L"Small", L"Medium", L"Large", L"XLarge", L"Width: xx", L"Area" };
|
|
|
|
BOOLEAN gfAllowRightButtonSelections = FALSE;
|
|
BOOLEAN gfCurrentSelectionWithRightButton = FALSE;
|
|
|
|
void DrawBuildingLayout( INT32 iMapIndex );
|
|
void RemoveBuildingLayout();
|
|
|
|
void ValidateSelectionRegionBoundaries();
|
|
void ForceAreaSelectionWidth();
|
|
BOOLEAN HandleAreaSelection();
|
|
void EnsureSelectionType();
|
|
|
|
BOOLEAN gfUsingOffset;
|
|
|
|
//Based on the density level setting and the selection type, this test will
|
|
//randomly choose TRUE or FALSE to reflect the *odds*.
|
|
BOOLEAN PerformDensityTest()
|
|
{
|
|
if( Random(100) < gusSelectionDensity )
|
|
return TRUE;
|
|
return FALSE;
|
|
}
|
|
|
|
void IncreaseSelectionDensity()
|
|
{
|
|
if( gusSelectionDensity == 100 )
|
|
gusSelectionDensity = 2;
|
|
else if( gusSelectionDensity == 2 )
|
|
gusSelectionDensity = 5;
|
|
else if( gusSelectionDensity == 5 )
|
|
gusSelectionDensity = 10;
|
|
else
|
|
gusSelectionDensity += 10;
|
|
}
|
|
|
|
void DecreaseSelectionDensity()
|
|
{
|
|
if( gusSelectionDensity == 10 )
|
|
gusSelectionDensity = 5;
|
|
else if( gusSelectionDensity == 5 )
|
|
gusSelectionDensity = 2;
|
|
else if( gusSelectionDensity == 2 )
|
|
gusSelectionDensity = 100;
|
|
else
|
|
gusSelectionDensity -= 10;
|
|
}
|
|
|
|
void RemoveCursors()
|
|
{
|
|
if((gSelectRegion.iRight + gSelectRegion.iBottom * WORLD_COLS) >= WORLD_MAX)//dnl ch43 280909 Prevent CTD when world size is changed
|
|
return;
|
|
INT32 x, y, iMapIndex;
|
|
if( gpBuildingLayoutList )
|
|
{
|
|
RemoveBuildingLayout();
|
|
}
|
|
Assert( gSelectRegion.iTop >= 0 && gSelectRegion.iTop <= gSelectRegion.iBottom );
|
|
Assert( gSelectRegion.iLeft >= 0 && gSelectRegion.iLeft <= gSelectRegion.iRight );
|
|
for( y = gSelectRegion.iTop; y <= gSelectRegion.iBottom; y++ )
|
|
{
|
|
for( x = gSelectRegion.iLeft; x <= gSelectRegion.iRight; x++ )
|
|
{
|
|
LEVELNODE* pNode;
|
|
iMapIndex = y * WORLD_COLS + x;
|
|
if( gfUsingOffset )
|
|
iMapIndex += ROOF_OFFSET;
|
|
pNode = gpWorldLevelData[ iMapIndex ].pTopmostHead;
|
|
while( pNode )
|
|
{
|
|
if( pNode->usIndex == FIRSTPOINTERS1 || pNode->usIndex == FIRSTPOINTERS5 || pNode->usIndex == BADMARKER1 )
|
|
{
|
|
RemoveTopmost( iMapIndex, pNode->usIndex );
|
|
break;
|
|
}
|
|
pNode = pNode->pNext;
|
|
}
|
|
}
|
|
}
|
|
fValidCursor = FALSE;
|
|
gfUsingOffset = FALSE;
|
|
}
|
|
|
|
void RemoveBadMarker()
|
|
{
|
|
LEVELNODE *pNode;
|
|
if( sBadMarker < 0 )
|
|
return;
|
|
pNode = gpWorldLevelData[ sBadMarker ].pTopmostHead;
|
|
while( pNode )
|
|
{
|
|
if( pNode->usIndex == BADMARKER1 )
|
|
{
|
|
RemoveTopmost( sBadMarker, pNode->usIndex );
|
|
sBadMarker = -1;
|
|
break;
|
|
}
|
|
pNode = pNode->pNext;
|
|
}
|
|
}
|
|
|
|
void UpdateCursorAreas()
|
|
{
|
|
INT32 x, y, iMapIndex;
|
|
|
|
RemoveCursors();
|
|
|
|
EnsureSelectionType();
|
|
|
|
//Determine if the mouse is currently in the world.
|
|
if( gViewportRegion.uiFlags & MSYS_MOUSE_IN_AREA && GetMouseXY( &sGridX, &sGridY ) )
|
|
{
|
|
iMapIndex = MAPROWCOLTOPOS( sGridY, sGridX );
|
|
if( gpBuildingLayoutList )
|
|
{
|
|
gSelectRegion.iLeft = gSelectRegion.iRight = sGridX;
|
|
gSelectRegion.iTop = gSelectRegion.iBottom = sGridY;
|
|
fValidCursor = TRUE;
|
|
DrawBuildingLayout( iMapIndex );
|
|
}
|
|
else switch( gusSelectionType )
|
|
{
|
|
case SMALLSELECTION:
|
|
gSelectRegion.iLeft = gSelectRegion.iRight = sGridX;
|
|
gSelectRegion.iTop = gSelectRegion.iBottom = sGridY;
|
|
fValidCursor = TRUE;
|
|
break;
|
|
case MEDIUMSELECTION:
|
|
case LARGESELECTION:
|
|
case XLARGESELECTION:
|
|
//The mouse mode value reflects the size of the cursor.
|
|
gSelectRegion.iTop = sGridY - gusSelectionType;
|
|
gSelectRegion.iBottom = sGridY + gusSelectionType;
|
|
gSelectRegion.iLeft = sGridX - gusSelectionType;
|
|
gSelectRegion.iRight = sGridX + gusSelectionType;
|
|
ValidateSelectionRegionBoundaries();
|
|
fValidCursor = TRUE;
|
|
break;
|
|
case LINESELECTION:
|
|
fValidCursor = HandleAreaSelection();
|
|
ForceAreaSelectionWidth();
|
|
ValidateSelectionRegionBoundaries();
|
|
break;
|
|
case AREASELECTION:
|
|
fValidCursor = HandleAreaSelection();
|
|
break;
|
|
}
|
|
}
|
|
//Draw all of the area cursors here.
|
|
if( fValidCursor )
|
|
{
|
|
if( gfRoofPlacement || iDrawMode == DRAW_MODE_ENEMY || iDrawMode == DRAW_MODE_CREATURE ||
|
|
iDrawMode == DRAW_MODE_REBEL || iDrawMode == DRAW_MODE_CIVILIAN ||
|
|
iDrawMode == DRAW_MODE_SCHEDULEACTION )
|
|
{
|
|
iMapIndex = gSelectRegion.iTop * WORLD_COLS + gSelectRegion.iLeft;
|
|
|
|
if( !IsLocationSittable( iMapIndex, gfRoofPlacement ) && iDrawMode != DRAW_MODE_SCHEDULEACTION ||
|
|
!IsLocationSittableExcludingPeople( iMapIndex, gfRoofPlacement ) && iDrawMode == DRAW_MODE_SCHEDULEACTION )
|
|
{
|
|
if( sBadMarker != iMapIndex )
|
|
{
|
|
RemoveBadMarker();
|
|
if( gfRoofPlacement && FlatRoofAboveGridNo( iMapIndex ) )
|
|
{
|
|
AddTopmostToTail( iMapIndex + ROOF_OFFSET, BADMARKER1 );
|
|
sBadMarker = iMapIndex + ROOF_OFFSET;
|
|
gfUsingOffset = TRUE;
|
|
}
|
|
else
|
|
{
|
|
AddTopmostToTail( (iMapIndex), BADMARKER1 );
|
|
sBadMarker = iMapIndex;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
RemoveBadMarker();
|
|
if( gfRoofPlacement && FlatRoofAboveGridNo( iMapIndex ) )
|
|
{
|
|
AddTopmostToTail( iMapIndex + ROOF_OFFSET, FIRSTPOINTERS5 );
|
|
gfUsingOffset = TRUE;
|
|
}
|
|
else
|
|
AddTopmostToTail( iMapIndex, FIRSTPOINTERS1 );
|
|
}
|
|
}
|
|
else for( y = gSelectRegion.iTop; y <= gSelectRegion.iBottom; y++ )
|
|
{
|
|
for( x = gSelectRegion.iLeft; x <= gSelectRegion.iRight; x++ )
|
|
{
|
|
iMapIndex = y * WORLD_COLS + x;
|
|
AddTopmostToTail( iMapIndex, FIRSTPOINTERS1 );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void ForceAreaSelectionWidth()
|
|
{
|
|
UINT16 gusDecSelWidth;
|
|
|
|
//If the anchor isn't set, we don't want to force the size yet.
|
|
if( !fAnchored )
|
|
return;
|
|
|
|
gusDecSelWidth = gusSelectionWidth - 1;
|
|
|
|
//compare the region with the anchor and determine if we are going to force size via
|
|
//height or width depending on the cursor distance from the anchor.
|
|
if( abs( sGridX - gSelectAnchor.iX ) < abs( sGridY - gSelectAnchor.iY ) )
|
|
{ //restrict the x axis
|
|
if( sGridX < gSelectAnchor.iX )
|
|
{ //to the left
|
|
gSelectRegion.iLeft = gSelectAnchor.iX - gusDecSelWidth;
|
|
gSelectRegion.iRight = gSelectAnchor.iX;
|
|
}
|
|
else
|
|
{ //to the right
|
|
gSelectRegion.iLeft = gSelectAnchor.iX;
|
|
gSelectRegion.iRight = gSelectAnchor.iX + gusDecSelWidth;
|
|
}
|
|
}
|
|
else
|
|
{ //restrict the y axis
|
|
if( sGridY < gSelectAnchor.iY )
|
|
{ //to the upper
|
|
gSelectRegion.iTop = gSelectAnchor.iY - gusDecSelWidth;
|
|
gSelectRegion.iBottom = gSelectAnchor.iY;
|
|
}
|
|
else
|
|
{ //to the lower
|
|
gSelectRegion.iBottom = gSelectAnchor.iY + gusDecSelWidth;
|
|
gSelectRegion.iTop = gSelectAnchor.iY;
|
|
}
|
|
}
|
|
}
|
|
|
|
BOOLEAN HandleAreaSelection()
|
|
{
|
|
//When the user releases the left button, then clear and process the area.
|
|
if( fAnchored )
|
|
{
|
|
if( !gfLeftButtonState && !gfCurrentSelectionWithRightButton ||
|
|
!gfRightButtonState && gfCurrentSelectionWithRightButton )
|
|
{
|
|
fAnchored = FALSE;
|
|
ProcessAreaSelection( (BOOLEAN)!gfCurrentSelectionWithRightButton );
|
|
gfCurrentSelectionWithRightButton = FALSE;
|
|
return FALSE;
|
|
}
|
|
}
|
|
//When the user first clicks, anchor the area.
|
|
if( !fAnchored )
|
|
{
|
|
if( gfLeftButtonState || gfRightButtonState && gfAllowRightButtonSelections )
|
|
{
|
|
if( gfRightButtonState && !gfLeftButtonState )
|
|
gfCurrentSelectionWithRightButton = TRUE;
|
|
else
|
|
gfCurrentSelectionWithRightButton = FALSE;
|
|
fAnchored = TRUE;
|
|
gSelectAnchor.iX = sGridX;
|
|
gSelectAnchor.iY = sGridY;
|
|
gSelectRegion.iLeft = gSelectRegion.iRight = sGridX;
|
|
gSelectRegion.iTop = gSelectRegion.iBottom = sGridY;
|
|
return TRUE;
|
|
}
|
|
}
|
|
//If no anchoring, then we are really dealing with a single cursor,
|
|
//until the user clicks and holds the mouse button to anchor the cursor.
|
|
if( !fAnchored )
|
|
{
|
|
gSelectRegion.iLeft = gSelectRegion.iRight = sGridX;
|
|
gSelectRegion.iTop = gSelectRegion.iBottom = sGridY;
|
|
return TRUE;
|
|
}
|
|
//Base the area from the anchor to the current mouse position.
|
|
if ( sGridX <= gSelectAnchor.iX )
|
|
{
|
|
gSelectRegion.iLeft = sGridX;
|
|
gSelectRegion.iRight = gSelectAnchor.iX;
|
|
}
|
|
else
|
|
{
|
|
gSelectRegion.iRight = sGridX;
|
|
gSelectRegion.iLeft = gSelectAnchor.iX;
|
|
}
|
|
if ( sGridY <= gSelectAnchor.iY )
|
|
{
|
|
gSelectRegion.iTop = sGridY;
|
|
gSelectRegion.iBottom = gSelectAnchor.iY;
|
|
}
|
|
else
|
|
{
|
|
gSelectRegion.iBottom = sGridY;
|
|
gSelectRegion.iTop = gSelectAnchor.iY;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
//dnl ch43 280909
|
|
void ValidateSelectionRegionBoundaries()
|
|
{
|
|
gSelectRegion.iLeft = max(min(WORLD_COLS-1, gSelectRegion.iLeft), 0);
|
|
gSelectRegion.iRight = max(min(WORLD_COLS-1, gSelectRegion.iRight), 0);
|
|
gSelectRegion.iTop = max(min(WORLD_ROWS-1, gSelectRegion.iTop), 0);
|
|
gSelectRegion.iBottom = max(min(WORLD_ROWS-1, gSelectRegion.iBottom), 0);
|
|
}
|
|
|
|
void EnsureSelectionType()
|
|
{
|
|
BOOLEAN fPrevBrushEnabledState = gfBrushEnabled;
|
|
|
|
//At time of writing, the only drawing mode supporting right mouse button
|
|
//area selections is the cave drawing mode.
|
|
gfAllowRightButtonSelections = ( iDrawMode == DRAW_MODE_CAVES );
|
|
|
|
//if we are erasing, we have more flexibility with the drawing modes.
|
|
if( iDrawMode >= DRAW_MODE_ERASE )
|
|
{
|
|
//erase modes supporting any cursor mode
|
|
gusSavedSelectionType = gusSelectionType;
|
|
gusSelectionWidth = gusPreserveSelectionWidth;
|
|
gfBrushEnabled = TRUE;
|
|
}
|
|
else switch( iDrawMode )
|
|
{ //regular modes
|
|
case DRAW_MODE_SAW_ROOM:
|
|
case DRAW_MODE_ROOM:
|
|
case DRAW_MODE_CAVES:
|
|
gusSavedBuildingSelectionType = gusSelectionType;
|
|
gusSelectionWidth = gusPreserveSelectionWidth;
|
|
gfBrushEnabled = TRUE;
|
|
break;
|
|
case DRAW_MODE_SLANTED_ROOF:
|
|
gusSelectionType = LINESELECTION;
|
|
gusSelectionWidth = 8;
|
|
gfBrushEnabled = FALSE;
|
|
break;
|
|
case DRAW_MODE_EXITGRID:
|
|
case DRAW_MODE_ROOMNUM:
|
|
case DRAW_MODE_FLOORS:
|
|
case DRAW_MODE_GROUND:
|
|
case DRAW_MODE_OSTRUCTS:
|
|
case DRAW_MODE_OSTRUCTS1:
|
|
case DRAW_MODE_OSTRUCTS2:
|
|
case DRAW_MODE_DEBRIS:
|
|
//supports all modes
|
|
gusSavedSelectionType = gusSelectionType;
|
|
gusSelectionWidth = gusPreserveSelectionWidth;
|
|
gfBrushEnabled = TRUE;
|
|
break;
|
|
default:
|
|
gusSelectionType = SMALLSELECTION;
|
|
gusSelectionWidth = gusPreserveSelectionWidth;
|
|
gfBrushEnabled = FALSE;
|
|
break;
|
|
}
|
|
|
|
if( gfBrushEnabled != fPrevBrushEnabledState )
|
|
{
|
|
if( gfBrushEnabled )
|
|
{
|
|
EnableEditorButton( TERRAIN_CYCLE_BRUSHSIZE );
|
|
EnableEditorButton( BUILDING_CYCLE_BRUSHSIZE );
|
|
EnableEditorButton( MAPINFO_CYCLE_BRUSHSIZE );
|
|
}
|
|
else
|
|
{
|
|
DisableEditorButton( TERRAIN_CYCLE_BRUSHSIZE );
|
|
DisableEditorButton( BUILDING_CYCLE_BRUSHSIZE );
|
|
DisableEditorButton( MAPINFO_CYCLE_BRUSHSIZE );
|
|
}
|
|
}
|
|
}
|
|
|
|
void DrawBuildingLayout( INT32 iMapIndex )
|
|
{
|
|
BUILDINGLAYOUTNODE *curr;
|
|
INT32 iOffset;
|
|
LEVELNODE* pNode;
|
|
BOOLEAN fAdd;
|
|
iOffset = iMapIndex - gsBuildingLayoutAnchorGridNo;
|
|
curr = gpBuildingLayoutList;
|
|
while( curr )
|
|
{
|
|
iMapIndex = curr->sGridNo + iOffset;
|
|
if( iMapIndex > 0 && iMapIndex < WORLD_MAX )
|
|
{
|
|
fAdd = TRUE;
|
|
pNode = gpWorldLevelData[ iMapIndex ].pTopmostHead;
|
|
while( pNode )
|
|
{
|
|
if( pNode->usIndex == FIRSTPOINTERS1 )
|
|
{
|
|
fAdd = FALSE;
|
|
break;
|
|
}
|
|
pNode = pNode->pNext;
|
|
}
|
|
if( fAdd )
|
|
AddTopmostToTail( iMapIndex, FIRSTPOINTERS1 );
|
|
}
|
|
curr = curr->next;
|
|
}
|
|
}
|
|
|
|
void RemoveBuildingLayout()
|
|
{
|
|
BUILDINGLAYOUTNODE *curr;
|
|
INT32 iOffset;
|
|
INT32 iMapIndex;
|
|
iMapIndex = gSelectRegion.iLeft + gSelectRegion.iTop * WORLD_COLS;
|
|
iOffset = iMapIndex - gsBuildingLayoutAnchorGridNo;
|
|
curr = gpBuildingLayoutList;
|
|
while( curr )
|
|
{
|
|
iMapIndex = curr->sGridNo + iOffset;
|
|
if( iMapIndex > 0 && iMapIndex < WORLD_MAX )
|
|
RemoveTopmost( iMapIndex, FIRSTPOINTERS1 );
|
|
curr = curr->next;
|
|
}
|
|
}
|
|
|
|
#endif
|