Original Source for 1.13 Mod High Resolution version from 12/06/05

git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@21 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
lalien
2006-04-19 11:32:51 +00:00
commit e54aeb96aa
790 changed files with 741287 additions and 0 deletions
+267
View File
@@ -0,0 +1,267 @@
#include "BuildDefines.h"
#ifdef JA2EDITOR
#ifndef __BUTTON_DEFINES_H
#define __BUTTON_DEFINES_H
enum
{
//Main Editor tabs
TAB_TERRAIN, FIRST_EDITORTAB_BUTTON = TAB_TERRAIN,
TAB_BUILDINGS,
TAB_ITEMS,
TAB_MERCS,
TAB_MAPINFO,
TAB_OPTIONS, LAST_EDITORTAB_BUTTON = TAB_OPTIONS,
//Terrain menu
TERRAIN_FGROUND_TEXTURES, FIRST_TERRAIN_BUTTON = TERRAIN_FGROUND_TEXTURES,
TERRAIN_BGROUND_TEXTURES,
TERRAIN_PLACE_CLIFFS,
TERRAIN_PLACE_ROADS,
TERRAIN_PLACE_DEBRIS,
TERRAIN_FILL_AREA,
TERRAIN_PLACE_TREES,
TERRAIN_PLACE_ROCKS,
TERRAIN_PLACE_MISC,
TERRAIN_TOGGLE_ERASEMODE,
TERRAIN_CYCLE_BRUSHSIZE,
TERRAIN_RAISE_DENSITY,
TERRAIN_LOWER_DENSITY,
TERRAIN_UNDO, LAST_TERRAIN_BUTTON = TERRAIN_UNDO,
//Buildings menu
BUILDING_PLACE_WALLS, FIRST_BUILDINGS_BUTTON = BUILDING_PLACE_WALLS,
BUILDING_PLACE_DOORS,
BUILDING_PLACE_WINDOWS,
BUILDING_PLACE_ROOFS,
BUILDING_PLACE_BROKEN_WALLS,
BUILDING_PLACE_FURNITURE,
BUILDING_PLACE_DECALS,
BUILDING_PLACE_TOILETS,
BUILDING_PLACE_FLOORS,
BUILDING_SMART_WALLS,
BUILDING_SMART_DOORS,
BUILDING_SMART_WINDOWS,
BUILDING_SMART_BROKEN_WALLS,
BUILDING_DOORKEY,
BUILDING_NEW_ROOM,
BUILDING_SAW_ROOM,
BUILDING_NEW_ROOF,
BUILDING_KILL_BUILDING,
BUILDING_COPY_BUILDING,
BUILDING_MOVE_BUILDING,
BUILDING_CAVE_DRAWING,
BUILDING_DRAW_ROOMNUM,
BUILDING_ERASE_ROOMNUM,
BUILDING_TOGGLE_ERASEMODE,
BUILDING_UNDO,
BUILDING_CYCLE_BRUSHSIZE,
BUILDING_TOGGLE_ROOF_VIEW,
BUILDING_TOGGLE_WALL_VIEW,
BUILDING_TOGGLE_INFO_VIEW, LAST_BUILDINGS_BUTTON = BUILDING_TOGGLE_INFO_VIEW,
//Items menu
ITEMS_WEAPONS, FIRST_ITEMS_BUTTON = ITEMS_WEAPONS,
ITEMS_AMMO,
ITEMS_ARMOUR,
ITEMS_EXPLOSIVES,
ITEMS_EQUIPMENT1,
ITEMS_EQUIPMENT2,
ITEMS_EQUIPMENT3,
ITEMS_TRIGGERS,
ITEMS_KEYS,
ITEMS_LEFTSCROLL,
ITEMS_RIGHTSCROLL, LAST_ITEMS_BUTTON = ITEMS_RIGHTSCROLL,
//MapInfo menu
MAPINFO_ADD_LIGHT1_SOURCE, FIRST_MAPINFO_BUTTON = MAPINFO_ADD_LIGHT1_SOURCE,
MAPINFO_LIGHT_PANEL,
MAPINFO_PRIMETIME_LIGHT,
MAPINFO_NIGHTTIME_LIGHT,
MAPINFO_24HOUR_LIGHT,
MAPINFO_TOGGLE_FAKE_LIGHTS,
MAPINFO_TOGGLE_ERASEMODE,
MAPINFO_DRAW_EXITGRIDS,
MAPINFO_CYCLE_BRUSHSIZE,
MAPINFO_UNDO,
MAPINFO_RADIO_PANEL,
MAPINFO_RADIO_NORMAL,
MAPINFO_RADIO_BASEMENT,
MAPINFO_RADIO_CAVES,
MAPINFO_NORTH_POINT,
MAPINFO_WEST_POINT,
MAPINFO_EAST_POINT,
MAPINFO_SOUTH_POINT,
MAPINFO_CENTER_POINT,
MAPINFO_ISOLATED_POINT, LAST_MAPINFO_BUTTON = MAPINFO_ISOLATED_POINT,
//Options menu
OPTIONS_NEW_MAP, FIRST_OPTIONS_BUTTON = OPTIONS_NEW_MAP,
OPTIONS_NEW_BASEMENT,
OPTIONS_NEW_CAVES,
OPTIONS_LOAD_MAP,
OPTIONS_SAVE_MAP,
OPTIONS_CHANGE_TILESET,
OPTIONS_LEAVE_EDITOR,
OPTIONS_QUIT_GAME, LAST_OPTIONS_BUTTON = OPTIONS_QUIT_GAME,
//Mercs menu
MERCS_PLAYER, FIRST_MERCS_BUTTON = MERCS_PLAYER,
MERCS_ENEMY,
MERCS_CREATURE,
MERCS_REBEL,
MERCS_CIVILIAN,
MERCS_PLAYERTOGGLE,
MERCS_ENEMYTOGGLE,
MERCS_CREATURETOGGLE,
MERCS_REBELTOGGLE,
MERCS_CIVILIANTOGGLE,
MERCS_1,
MERCS_DETAILEDCHECKBOX,
MERCS_GENERAL,
MERCS_ATTRIBUTES,
MERCS_INVENTORY,
MERCS_APPEARANCE,
MERCS_PROFILE,
MERCS_SCHEDULE,
MERCS_GLOWSCHEDULE,
MERCS_DELETE,
MERCS_NEXT,
MERCS_PRIORITYEXISTANCE_CHECKBOX,
MERCS_HASKEYS_CHECKBOX,
MERCS_ORDERS_STATIONARY,
MERCS_ORDERS_ONGUARD,
MERCS_ORDERS_CLOSEPATROL,
MERCS_ORDERS_FARPATROL,
MERCS_ORDERS_POINTPATROL,
MERCS_ORDERS_ONCALL,
MERCS_ORDERS_SEEKENEMY,
MERCS_ORDERS_RNDPTPATROL,
MERCS_ATTITUDE_DEFENSIVE,
MERCS_ATTITUDE_BRAVESOLO,
MERCS_ATTITUDE_BRAVEAID,
MERCS_ATTITUDE_CUNNINGSOLO,
MERCS_ATTITUDE_CUNNINGAID,
MERCS_ATTITUDE_AGGRESSIVE,
MERCS_DIRECTION_N,
MERCS_DIRECTION_NE,
MERCS_DIRECTION_E,
MERCS_DIRECTION_SE,
MERCS_DIRECTION_S,
MERCS_DIRECTION_SW,
MERCS_DIRECTION_W,
MERCS_DIRECTION_NW,
MERCS_DIRECTION_FIND,
MERCS_EQUIPMENT_BAD,
MERCS_EQUIPMENT_POOR,
MERCS_EQUIPMENT_AVERAGE,
MERCS_EQUIPMENT_GOOD,
MERCS_EQUIPMENT_GREAT,
MERCS_ATTRIBUTES_BAD,
MERCS_ATTRIBUTES_POOR,
MERCS_ATTRIBUTES_AVERAGE,
MERCS_ATTRIBUTES_GOOD,
MERCS_ATTRIBUTES_GREAT,
MERCS_ARMY_CODE,
MERCS_ADMIN_CODE,
MERCS_ELITE_CODE,
MERCS_CIVILIAN_GROUP,
MERCS_TOGGLECOLOR_BUTTON,
MERCS_HAIRCOLOR_DOWN,
MERCS_HAIRCOLOR_UP,
MERCS_SKINCOLOR_DOWN,
MERCS_SKINCOLOR_UP,
MERCS_VESTCOLOR_DOWN,
MERCS_VESTCOLOR_UP,
MERCS_PANTCOLOR_DOWN,
MERCS_PANTCOLOR_UP,
MERCS_BODYTYPE_DOWN,
MERCS_BODYTYPE_UP,
MERCS_SCHEDULE_ACTION1,
MERCS_SCHEDULE_ACTION2,
MERCS_SCHEDULE_ACTION3,
MERCS_SCHEDULE_ACTION4,
MERCS_SCHEDULE_VARIANCE1,
MERCS_SCHEDULE_VARIANCE2,
MERCS_SCHEDULE_VARIANCE3,
MERCS_SCHEDULE_VARIANCE4,
MERCS_SCHEDULE_DATA1A,
MERCS_SCHEDULE_DATA2A,
MERCS_SCHEDULE_DATA3A,
MERCS_SCHEDULE_DATA4A,
MERCS_SCHEDULE_DATA1B,
MERCS_SCHEDULE_DATA2B,
MERCS_SCHEDULE_DATA3B,
MERCS_SCHEDULE_DATA4B,
MERCS_SCHEDULE_CLEAR,
MERCS_HEAD_SLOT,
MERCS_BODY_SLOT,
MERCS_LEGS_SLOT,
MERCS_LEFTHAND_SLOT,
MERCS_RIGHTHAND_SLOT,
MERCS_PACK1_SLOT,
MERCS_PACK2_SLOT,
MERCS_PACK3_SLOT,
MERCS_PACK4_SLOT, LAST_MERCS_BUTTON = MERCS_PACK4_SLOT,
ITEMSTATS_PANEL, FIRST_ITEMSTATS_BUTTON = ITEMSTATS_PANEL,
ITEMSTATS_HIDDEN_BTN,
ITEMSTATS_DELETE_BTN, LAST_ITEMSTATS_BUTTON = ITEMSTATS_DELETE_BTN,
NUMBER_EDITOR_BUTTONS,
};
#define FIRST_MERCS_TEAMMODE_BUTTON MERCS_PLAYER
#define LAST_MERCS_TEAMMODE_BUTTON MERCS_CIVILIANTOGGLE
#define FIRST_MERCS_BASICMODE_BUTTON MERCS_1
#define LAST_MERCS_BASICMODE_BUTTON MERCS_DETAILEDCHECKBOX
#define FIRST_MERCS_PRIORITYMODE_BUTTON MERCS_GENERAL
#define LAST_MERCS_PRIORITYMODE_BUTTON MERCS_SCHEDULE
#define FIRST_MERCS_GENERAL_BUTTON MERCS_PRIORITYEXISTANCE_CHECKBOX
#define LAST_MERCS_GENERAL_BUTTON LAST_MERCS_COLORCODE_BUTTON
#define FIRST_MERCS_ORDERS_BUTTON MERCS_ORDERS_STATIONARY
#define LAST_MERCS_ORDERS_BUTTON MERCS_ORDERS_RNDPTPATROL
#define FIRST_MERCS_ATTITUDE_BUTTON MERCS_ATTITUDE_DEFENSIVE
#define LAST_MERCS_ATTITUDE_BUTTON MERCS_ATTITUDE_AGGRESSIVE
#define FIRST_MERCS_DIRECTION_BUTTON MERCS_DIRECTION_N
#define LAST_MERCS_DIRECTION_BUTTON MERCS_DIRECTION_FIND
#define FIRST_MERCS_REL_EQUIPMENT_BUTTON MERCS_EQUIPMENT_BAD
#define LAST_MERCS_REL_EQUIPMENT_BUTTON MERCS_EQUIPMENT_GREAT
#define FIRST_MERCS_REL_ATTRIBUTE_BUTTON MERCS_ATTRIBUTES_BAD
#define LAST_MERCS_REL_ATTRIBUTE_BUTTON MERCS_ATTRIBUTES_GREAT
#define FIRST_MERCS_COLORCODE_BUTTON MERCS_ARMY_CODE
#define LAST_MERCS_COLORCODE_BUTTON MERCS_ELITE_CODE
#define FIRST_MERCS_COLORMODE_BUTTON MERCS_TOGGLECOLOR_BUTTON
#define LAST_MERCS_COLORMODE_BUTTON MERCS_BODYTYPE_UP
#define FIRST_MERCS_COLOR_BUTTON MERCS_HAIRCOLOR_DOWN
#define LAST_MERCS_COLOR_BUTTON MERCS_PANTCOLOR_UP
#define FIRST_MERCS_BODYTYPE_BUTTON MERCS_BODYTYPE_DOWN
#define LAST_MERCS_BODYTYPE_BUTTON MERCS_BODYTYPE_UP
#define FIRST_MERCS_INVENTORY_BUTTON MERCS_HEAD_SLOT
#define LAST_MERCS_INVENTORY_BUTTON MERCS_PACK4_SLOT
#define FIRST_MERCS_GETITEM_BUTTON FIRST_ITEMS_BUTTON
#define LAST_MERCS_GETITEM_BUTTON LAST_ITEMS_BUTTON
#define FIRST_MERCS_SCHEDULE_BUTTON MERCS_SCHEDULE_ACTION1
#define LAST_MERCS_SCHEDULE_BUTTON MERCS_SCHEDULE_CLEAR
#endif
#endif
+464
View File
@@ -0,0 +1,464 @@
#ifdef PRECOMPILEDHEADERS
#include "Editor All.h"
#else
#include "builddefines.h"
#endif
#ifdef JA2EDITOR
#ifndef PRECOMPILEDHEADERS
#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"
#endif
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)
INT16 sBadMarker = -1;
UINT16 *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();
//Used for offseting cursor to show that it is on the roof rather than on the ground.
//This can be conveniently executed by moving the cursor up and right 3 gridnos for a
//total of -483 -(160*3)-(1*3)
#define ROOF_OFFSET (-483)
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()
{
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 )
{
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( 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 = (INT16)(iMapIndex + ROOF_OFFSET );
}
else
{
AddTopmostToTail( (iMapIndex), BADMARKER1 );
sBadMarker = (INT16)(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;
}
void ValidateSelectionRegionBoundaries()
{
gSelectRegion.iLeft = max( min( 159, gSelectRegion.iLeft ), 0 );
gSelectRegion.iRight = max( min( 159, gSelectRegion.iRight ), 0 );
gSelectRegion.iTop = max( min( 159, gSelectRegion.iTop ), 0 );
gSelectRegion.iBottom = max( min( 159, 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
+38
View File
@@ -0,0 +1,38 @@
#include "BuildDefines.h"
#ifdef JA2EDITOR
#ifndef __CURSOR_MODES_H
#define __CURSOR_MODES_H
enum
{
SMALLSELECTION, // 1x1
MEDIUMSELECTION, // 3x3
LARGESELECTION, // 5x5
XLARGESELECTION, // 7x7
LINESELECTION, // v or h line with a specified width
AREASELECTION, // user controlled area
NUMSELECTIONTYPES
};
extern UINT16 gusSelectionType;
extern UINT16 gusSelectionWidth;
extern UINT16 gusPreserveSelectionWidth;
extern UINT16 gusSelectionDensity;
extern UINT16 gusSavedSelectionType;
extern UINT16 gusSavedBuildingSelectionType;
BOOLEAN PerformDensityTest();
void SetDrawingMode( INT32 iMode );
void UpdateCursorAreas();
void IncreaseSelectionDensity();
void DecreaseSelectionDensity();
void RemoveCursors();
extern UINT16 *wszSelType[6];
extern BOOLEAN gfCurrentSelectionWithRightButton;
#endif
#endif
+127
View File
@@ -0,0 +1,127 @@
#include "BuildDefines.h"
#ifndef __EDITOR_ALL_H
#define __EDITOR_ALL_H
#ifdef JA2EDITOR
#pragma message("GENERATED PCH FOR EDITOR PROJECT.")
//external
#include "types.h"
#include <stdio.h>
#include <windows.h>
#include "Action Items.h"
#include "Button System.h"
#include "debug.h"
#include "english.h"
#include "environment.h"
#include "Exit Grids.h"
#include "font.h"
#include "Font Control.h"
#include "Keys.h"
#include "input.h"
#include "interface.h"
#include "Interface Items.h"
#include "Isometric Utils.h"
#include "interface panels.h"
#include "lighting.h"
#include "Map Information.h"
#include "mousesystem.h"
#include "Overhead.h"
#include "Overhead map.h"
#include "overhead types.h"
#include "pits.h"
#include "random.h"
#include "Render Fun.h"
#include "Render Dirty.h"
#include "renderworld.h"
#include "Simple Render Utils.h"
#include "Soldier Create.h"
#include "Soldier Find.h"
#include "sysutil.h"
#include "Text.h"
#include "Text Input.h"
#include "tiledef.h"
#include "utilities.h"
#include "video.h"
#include "vobject.h"
#include "vobject_blitters.h"
#include "vsurface.h"
#include "wcheck.h"
#include "weapons.h"
#include "wordwrap.h"
#include "WorldDat.h"
#include "worlddef.h"
#include "World Items.h"
#include "worldman.h"
#include "line.h"
#include "Animation Data.h"
#include "Animation Control.h"
#include "Soldier Init List.h"
#include "StrategicMap.h"
#include "Soldier Add.h"
#include "Soldier Control.h"
#include "soldier profile type.h"
#include "Soldier Profile.h"
#include "Inventory Choosing.h"
#include "Scheduling.h"
#include "Timer Control.h"
#include "sgp.h"
#include "screenids.h"
#include "Sys Globals.h"
#include "Interactive Tiles.h"
#include "Handle UI.h"
#include "Event Pump.h"
#include "message.h"
#include "Game Clock.h"
#include "Game Init.h"
#include "Map Edgepoints.h"
#include "Music Control.h"
#include <memory.h>
#include "Item Types.h"
#include "Items.h"
#include "Handle Items.h"
#include "Animated ProgressBar.h"
#include "gameloop.h"
#include <stdlib.h>
#include "Structure Internals.h"
#include "Cursors.h"
#include "FileMan.h"
#include "Summary Info.h"
#include "time.h"
#include "structure wrap.h"
#include "MessageBoxScreen.h"
#include "GameSettings.h"
//internal
#include "Cursor Modes.h"
#include "edit_sys.h"
#include "Editor Callback Prototypes.h"
#include "Editor Modes.h"
#include "Editor Taskbar Creation.h"
#include "Editor Taskbar Utils.h"
#include "Editor Undo.h"
#include "EditorBuildings.h"
#include "EditorDefines.h"
#include "EditorItems.h"
#include "EditorMapInfo.h"
#include "EditorMercs.h"
#include "EditorTerrain.h"
#include "editscreen.h"
#include "Item Statistics.h"
#include "LoadScreen.h"
#include "messagebox.h"
#include "newsmooth.h"
#include "popupmenu.h"
#include "Road Smoothing.h"
#include "Sector Summary.h"
#include "selectwin.h"
#include "SmartMethod.h"
#include "smooth.h"
#include "Smoothing Utils.h"
#endif
#endif
+157
View File
@@ -0,0 +1,157 @@
#include "BuildDefines.h"
#ifdef JA2EDITOR
#ifndef __EDITOR_CALLBACK_PROTOTYPES_H
#define __EDITOR_CALLBACK_PROTOTYPES_H
// Editor Tabs
void TaskTerrainCallback(GUI_BUTTON *btn,INT32 reason);
void TaskBuildingCallback(GUI_BUTTON *btn,INT32 reason);
void TaskItemsCallback(GUI_BUTTON *btn,INT32 reason);
void TaskMercsCallback(GUI_BUTTON *btn,INT32 reason);
void TaskMapInfoCallback(GUI_BUTTON *btn,INT32 reason);
void TaskOptionsCallback(GUI_BUTTON *btn,INT32 reason);
// Options Tab Callbacks
void BtnLoadCallback(GUI_BUTTON *btn,INT32 reason);
void BtnSaveCallback(GUI_BUTTON *btn,INT32 reason);
void BtnCancelCallback(GUI_BUTTON *btn,INT32 reason);
void BtnQuitCallback( GUI_BUTTON *btn, INT32 reason );
void BtnNewMapCallback(GUI_BUTTON *btn,INT32 reason);
void BtnNewBasementCallback( GUI_BUTTON *btn, INT32 reason );
void BtnNewCavesCallback( GUI_BUTTON *btn, INT32 reason );
void BtnChangeTilesetCallback(GUI_BUTTON *btn,INT32 reason);
// Mercs Tab Callbacks
void MercsTogglePlayers( GUI_BUTTON *btn, INT32 reason );
void MercsToggleEnemies( GUI_BUTTON *btn, INT32 reason );
void MercsToggleCreatures( GUI_BUTTON *btn, INT32 reason );
void MercsToggleRebels( GUI_BUTTON *btn, INT32 reason );
void MercsToggleCivilians( GUI_BUTTON *btn, INT32 reason );
void MercsPlayerTeamCallback(GUI_BUTTON *btn,INT32 reason);
void MercsEnemyTeamCallback(GUI_BUTTON *btn,INT32 reason);
void MercsCreatureTeamCallback(GUI_BUTTON *btn,INT32 reason);
void MercsRebelTeamCallback(GUI_BUTTON *btn,INT32 reason);
void MercsCivilianTeamCallback(GUI_BUTTON *btn,INT32 reason);
void MercsDetailedPlacementCallback( GUI_BUTTON *btn, INT32 reason );
void MercsPriorityExistanceCallback( GUI_BUTTON *btn, INT32 reason );
void MercsHasKeysCallback( GUI_BUTTON *btn, INT32 reason );
void MercsNextCallback( GUI_BUTTON *btn, INT32 reason );
void MercsDeleteCallback( GUI_BUTTON *btn, INT32 reason );
void MercsGeneralModeCallback( GUI_BUTTON *btn, INT32 reason );
void MercsAttributesModeCallback( GUI_BUTTON *btn, INT32 reason );
void MercsInventoryModeCallback( GUI_BUTTON *btn, INT32 reason );
void MercsAppearanceModeCallback( GUI_BUTTON *btn, INT32 reason );
void MercsProfileModeCallback( GUI_BUTTON *btn, INT32 reason );
void MercsScheduleModeCallback( GUI_BUTTON *btn, INT32 reason );
void MercsSetEnemyColorCodeCallback( GUI_BUTTON *btn, INT32 reason );
void MercsSetOrdersCallback( GUI_BUTTON *btn, INT32 reason );
void MercsSetAttitudeCallback( GUI_BUTTON *btn, INT32 reason );
void MercsDirectionSetCallback( GUI_BUTTON *btn, INT32 reason );
void MercsFindSelectedMercCallback( GUI_BUTTON *btn, INT32 reason );
void MercsSetRelativeEquipmentCallback( GUI_BUTTON *btn, INT32 reason );
void MercsSetRelativeAttributesCallback( GUI_BUTTON *btn, INT32 reason );
void MercsToggleColorModeCallback( GUI_BUTTON *btn, INT32 reason );
void MercsSetColorsCallback( GUI_BUTTON *btn, INT32 reason );
void MercsSetBodyTypeCallback( GUI_BUTTON *btn, INT32 reason );
void MercsInventorySlotCallback( GUI_BUTTON *btn, INT32 reason );
void MouseMovedInMercRegion( MOUSE_REGION *reg, INT32 reason );
void MouseClickedInMercRegion( MOUSE_REGION *reg, INT32 reason );
void MercsCivilianGroupCallback( GUI_BUTTON *btn, INT32 reason );
void MercsScheduleAction1Callback( GUI_BUTTON *btn, INT32 reason );
void MercsScheduleAction2Callback( GUI_BUTTON *btn, INT32 reason );
void MercsScheduleAction3Callback( GUI_BUTTON *btn, INT32 reason );
void MercsScheduleAction4Callback( GUI_BUTTON *btn, INT32 reason );
void MercsScheduleData1ACallback( GUI_BUTTON *btn, INT32 reason );
void MercsScheduleData1BCallback( GUI_BUTTON *btn, INT32 reason );
void MercsScheduleData2ACallback( GUI_BUTTON *btn, INT32 reason );
void MercsScheduleData2BCallback( GUI_BUTTON *btn, INT32 reason );
void MercsScheduleData3ACallback( GUI_BUTTON *btn, INT32 reason );
void MercsScheduleData3BCallback( GUI_BUTTON *btn, INT32 reason );
void MercsScheduleData4ACallback( GUI_BUTTON *btn, INT32 reason );
void MercsScheduleData4BCallback( GUI_BUTTON *btn, INT32 reason );
void MercsScheduleClearCallback( GUI_BUTTON *btn, INT32 reason );
void MercsScheduleToggleVariance1Callback( GUI_BUTTON *btn, INT32 reason );
void MercsScheduleToggleVariance2Callback( GUI_BUTTON *btn, INT32 reason );
void MercsScheduleToggleVariance3Callback( GUI_BUTTON *btn, INT32 reason );
void MercsScheduleToggleVariance4Callback( GUI_BUTTON *btn, INT32 reason );
// Terrain Tab Callbacks
void BtnLandRaiseCallback(GUI_BUTTON *btn,INT32 reason);
void BtnLandLowerCallback(GUI_BUTTON *btn,INT32 reason);
void BtnIncBrushDensityCallback(GUI_BUTTON *btn,INT32 reason);
void BtnDecBrushDensityCallback(GUI_BUTTON *btn,INT32 reason);
void BtnFgGrndCallback(GUI_BUTTON *btn,INT32 reason);
void BtnBkGrndCallback(GUI_BUTTON *btn,INT32 reason);
void BtnObjectCallback(GUI_BUTTON *btn,INT32 reason);
void BtnBanksCallback(GUI_BUTTON *btn,INT32 reason);
void BtnRoadsCallback(GUI_BUTTON *btn,INT32 reason);
void BtnDebrisCallback(GUI_BUTTON *btn,INT32 reason);
void BtnBrushCallback(GUI_BUTTON *btn,INT32 reason);
void BtnObject1Callback(GUI_BUTTON *btn,INT32 reason);
void BtnObject2Callback(GUI_BUTTON *btn,INT32 reason);
void BtnFillCallback(GUI_BUTTON *btn,INT32 reason);
void TerrainTileButtonRegionCallback(MOUSE_REGION *reg,INT32 reason);
// Items Tab Callbacks
void ItemsWeaponsCallback(GUI_BUTTON *btn,INT32 reason);
void ItemsAmmoCallback(GUI_BUTTON *btn,INT32 reason);
void ItemsArmourCallback(GUI_BUTTON *btn,INT32 reason);
void ItemsExplosivesCallback(GUI_BUTTON *btn,INT32 reason);
void ItemsEquipment1Callback(GUI_BUTTON *btn,INT32 reason);
void ItemsEquipment2Callback(GUI_BUTTON *btn,INT32 reason);
void ItemsEquipment3Callback(GUI_BUTTON *btn,INT32 reason);
void ItemsTriggersCallback(GUI_BUTTON *btn,INT32 reason);
void ItemsKeysCallback(GUI_BUTTON *btn, INT32 reason);
void ItemsLeftScrollCallback(GUI_BUTTON *btn, INT32 reason);
void ItemsRightScrollCallback(GUI_BUTTON *btn, INT32 reason);
void MouseMovedInItemsRegion(MOUSE_REGION *reg, INT32 reason);
void MouseClickedInItemsRegion(MOUSE_REGION *reg, INT32 reason);
// MapInfo Callbacks
void BtnFakeLightCallback(GUI_BUTTON *btn,INT32 reason);
void MapInfoPrimeTimeRadioCallback( GUI_BUTTON *btn, INT32 reason );
void MapInfoNightTimeRadioCallback( GUI_BUTTON *btn, INT32 reason );
void MapInfo24HourTimeRadioCallback( GUI_BUTTON *btn, INT32 reason );
void BtnDrawLightsCallback(GUI_BUTTON *btn,INT32 reason);
void MapInfoDrawExitGridCallback( GUI_BUTTON *btn, INT32 reason );
void MapInfoEntryPointsCallback( GUI_BUTTON *btn, INT32 reason );
void MapInfoNormalRadioCallback( GUI_BUTTON *btn, INT32 reason );
void MapInfoBasementRadioCallback( GUI_BUTTON *btn, INT32 reason );
void MapInfoCavesRadioCallback( GUI_BUTTON *btn, INT32 reason );
// Building callbacks
void BuildingWallCallback( GUI_BUTTON *btn, INT32 reason );
void BuildingDoorCallback(GUI_BUTTON *btn, INT32 reason);
void BuildingWindowCallback(GUI_BUTTON *btn, INT32 reason);
void BuildingRoofCallback(GUI_BUTTON *btn, INT32 reason);
void BuildingCrackWallCallback( GUI_BUTTON *btn, INT32 reason );
void BuildingFurnitureCallback(GUI_BUTTON *btn, INT32 reason);
void BuildingDecalCallback(GUI_BUTTON *btn, INT32 reason);
void BuildingFloorCallback(GUI_BUTTON *btn, INT32 reason);
void BuildingToiletCallback(GUI_BUTTON *btn, INT32 reason);
void BuildingSmartWallCallback( GUI_BUTTON *btn, INT32 reason );
void BuildingSmartDoorCallback(GUI_BUTTON *btn, INT32 reason);
void BuildingSmartWindowCallback(GUI_BUTTON *btn, INT32 reason);
void BuildingSmartCrackWallCallback(GUI_BUTTON *btn, INT32 reason);
void BuildingDoorKeyCallback(GUI_BUTTON *btn, INT32 reason );
void BuildingNewRoomCallback(GUI_BUTTON *btn, INT32 reason);
void BuildingNewRoofCallback(GUI_BUTTON *btn, INT32 reason );
void BuildingSawRoomCallback( GUI_BUTTON *btn, INT32 reason );
void BuildingKillBuildingCallback(GUI_BUTTON *btn, INT32 reason);
void BuildingCopyBuildingCallback(GUI_BUTTON *btn, INT32 reason);
void BuildingMoveBuildingCallback(GUI_BUTTON *btn, INT32 reason);
void BuildingCaveDrawingCallback(GUI_BUTTON *btn, INT32 reason);
void BuildingDrawRoomNumCallback(GUI_BUTTON *btn, INT32 reason);
void BuildingEraseRoomNumCallback( GUI_BUTTON *btn, INT32 reason );
void BuildingToggleRoofViewCallback(GUI_BUTTON *btn,INT32 reason);
void BuildingToggleWallViewCallback(GUI_BUTTON *btn,INT32 reason);
void BuildingToggleInfoViewCallback(GUI_BUTTON *btn,INT32 reason);
// ItemStats Callbacks
void ItemStatsToggleHideCallback( GUI_BUTTON *btn, INT32 reason );
void ItemStatsDeleteCallback( GUI_BUTTON *btn, INT32 reason );
// Various Callbacks
void BtnUndoCallback(GUI_BUTTON *btn,INT32 reason);
void BtnEraseCallback(GUI_BUTTON *btn,INT32 reason);
#endif
#endif
File diff suppressed because it is too large Load Diff
+395
View File
@@ -0,0 +1,395 @@
#ifdef PRECOMPILEDHEADERS
#include "Editor All.h"
#else
#include "builddefines.h"
#endif
#ifdef JA2EDITOR
#ifndef PRECOMPILEDHEADERS
#include "types.h"
#include "Editor Modes.h"
#include "Editor Taskbar Utils.h"
#include "EditorDefines.h"
#include "EditorItems.h"
#include "EditorBuildings.h"
#include "EditorTerrain.h"
#include "Cursor Modes.h"
#include "Map Information.h"
#include "editscreen.h"
#include "selectwin.h"
#include "environment.h"
#include "worlddef.h"
#include "Exit Grids.h"
#include "Worldman.h"
#endif
BOOLEAN gfShowExitGrids = FALSE;
void SetEditorItemsTaskbarMode( UINT16 usNewMode )
{
UnclickEditorButtons( ITEMS_WEAPONS, ITEMS_KEYS );
switch( usNewMode )
{
case ITEMS_WEAPONS:
ClickEditorButton( ITEMS_WEAPONS );
iEditorToolbarState = TBAR_MODE_ITEM_WEAPONS;
break;
case ITEMS_AMMO:
ClickEditorButton( ITEMS_AMMO );
iEditorToolbarState = TBAR_MODE_ITEM_AMMO;
break;
case ITEMS_ARMOUR:
ClickEditorButton( ITEMS_ARMOUR );
iEditorToolbarState = TBAR_MODE_ITEM_ARMOUR;
break;
case ITEMS_EXPLOSIVES:
ClickEditorButton( ITEMS_EXPLOSIVES );
iEditorToolbarState = TBAR_MODE_ITEM_EXPLOSIVES;
break;
case ITEMS_EQUIPMENT1:
ClickEditorButton( ITEMS_EQUIPMENT1 );
iEditorToolbarState = TBAR_MODE_ITEM_EQUIPMENT1;
break;
case ITEMS_EQUIPMENT2:
ClickEditorButton( ITEMS_EQUIPMENT2 );
iEditorToolbarState = TBAR_MODE_ITEM_EQUIPMENT2;
break;
case ITEMS_EQUIPMENT3:
ClickEditorButton( ITEMS_EQUIPMENT3 );
iEditorToolbarState = TBAR_MODE_ITEM_EQUIPMENT3;
break;
case ITEMS_TRIGGERS:
ClickEditorButton( ITEMS_TRIGGERS );
iEditorToolbarState = TBAR_MODE_ITEM_TRIGGERS;
break;
case ITEMS_KEYS:
ClickEditorButton( ITEMS_KEYS );
iEditorToolbarState = TBAR_MODE_ITEM_KEYS;
break;
}
}
#define NO_EFFECT 2
void SetEditorBuildingTaskbarMode( UINT16 usNewMode )
{
BOOLEAN fNewGroup = FALSE;
BOOLEAN fNewRoofs, fNewWalls, fNewRoomInfo;
if( usNewMode == usCurrentMode )
{
ClickEditorButton( usNewMode );
return;
}
usCurrentMode = usNewMode;
//Unclick all of the building section buttons first -- except the view modes.
UnclickEditorButton( BUILDING_PLACE_WALLS );
UnclickEditorButton( BUILDING_PLACE_DOORS );
UnclickEditorButton( BUILDING_PLACE_WINDOWS );
UnclickEditorButton( BUILDING_PLACE_ROOFS );
UnclickEditorButton( BUILDING_PLACE_BROKEN_WALLS );
UnclickEditorButton( BUILDING_PLACE_FURNITURE );
UnclickEditorButton( BUILDING_PLACE_DECALS );
UnclickEditorButton( BUILDING_PLACE_FLOORS );
UnclickEditorButton( BUILDING_PLACE_TOILETS );
UnclickEditorButton( BUILDING_SMART_WALLS );
UnclickEditorButton( BUILDING_SMART_DOORS );
UnclickEditorButton( BUILDING_SMART_WINDOWS );
UnclickEditorButton( BUILDING_SMART_BROKEN_WALLS );
UnclickEditorButton( BUILDING_DOORKEY );
UnclickEditorButton( BUILDING_NEW_ROOM );
UnclickEditorButton( BUILDING_NEW_ROOF );
UnclickEditorButton( BUILDING_CAVE_DRAWING );
UnclickEditorButton( BUILDING_SAW_ROOM );
UnclickEditorButton( BUILDING_KILL_BUILDING );
UnclickEditorButton( BUILDING_COPY_BUILDING );
UnclickEditorButton( BUILDING_MOVE_BUILDING );
UnclickEditorButton( BUILDING_DRAW_ROOMNUM );
ClickEditorButton( usNewMode );
gfRenderDrawingMode = TRUE;
//Clicking on certain buttons will automatically activate/deactive certain views.
switch( usNewMode )
{
case BUILDING_KILL_BUILDING://Show everything
fNewWalls = TRUE;
fNewRoofs = TRUE;
fNewRoomInfo = TRUE;
break;
case BUILDING_NEW_ROOF:
case BUILDING_PLACE_ROOFS:
fNewWalls = TRUE;
fNewRoofs = TRUE;
fNewRoomInfo = FALSE;
break;
case BUILDING_DRAW_ROOMNUM: //Show room info
case BUILDING_ERASE_ROOMNUM: //Show room info
fNewWalls = NO_EFFECT;
fNewRoofs = gfBasement ? TRUE : FALSE;
fNewRoomInfo = TRUE;
break;
case BUILDING_PLACE_DOORS:
case BUILDING_PLACE_WINDOWS:
case BUILDING_PLACE_WALLS:
case BUILDING_PLACE_BROKEN_WALLS:
case BUILDING_PLACE_FLOORS:
case BUILDING_PLACE_TOILETS:
case BUILDING_PLACE_FURNITURE:
case BUILDING_PLACE_DECALS:
case BUILDING_SMART_WALLS:
case BUILDING_SMART_DOORS:
case BUILDING_SMART_WINDOWS:
case BUILDING_SMART_BROKEN_WALLS:
case BUILDING_DOORKEY:
case BUILDING_SAW_ROOM:
case BUILDING_NEW_ROOM:
case BUILDING_COPY_BUILDING:
case BUILDING_MOVE_BUILDING:
case BUILDING_CAVE_DRAWING:
fNewRoofs = gfBasement ? TRUE : FALSE;
fNewWalls = TRUE;
fNewRoomInfo = FALSE;
if( usNewMode == BUILDING_PLACE_FLOORS )
gusSelectionType = gusSavedSelectionType;
break;
default:
return;
}
UnclickEditorButton( BUILDING_TOGGLE_INFO_VIEW );
if( fNewWalls != NO_EFFECT && fNewWalls != fBuildingShowWalls )
{
if( fNewWalls )
ClickEditorButton( BUILDING_TOGGLE_WALL_VIEW );
else
UnclickEditorButton( BUILDING_TOGGLE_WALL_VIEW );
fBuildingShowWalls = fNewWalls;
UpdateWallsView();
}
if( fNewRoofs != NO_EFFECT && fNewRoofs != fBuildingShowRoofs )
{
if( fNewRoofs )
ClickEditorButton( BUILDING_TOGGLE_ROOF_VIEW );
else
UnclickEditorButton( BUILDING_TOGGLE_ROOF_VIEW );
fBuildingShowRoofs = fNewRoofs;
UpdateRoofsView();
}
if( fNewRoomInfo != NO_EFFECT && fNewRoomInfo != fBuildingShowRoomInfo )
{
if( fNewRoomInfo )
ClickEditorButton( BUILDING_TOGGLE_INFO_VIEW );
else
UnclickEditorButton( BUILDING_TOGGLE_INFO_VIEW );
fBuildingShowRoomInfo = fNewRoomInfo;
gfRenderWorld = TRUE;
}
}
void SetEditorTerrainTaskbarMode( UINT16 usNewMode )
{
UnclickEditorButton( TERRAIN_FGROUND_TEXTURES );
UnclickEditorButton( TERRAIN_BGROUND_TEXTURES );
UnclickEditorButton( TERRAIN_PLACE_CLIFFS );
UnclickEditorButton( TERRAIN_PLACE_DEBRIS );
UnclickEditorButton( TERRAIN_PLACE_TREES );
UnclickEditorButton( TERRAIN_PLACE_ROCKS );
UnclickEditorButton( TERRAIN_PLACE_MISC );
UnclickEditorButton( TERRAIN_FILL_AREA );
TerrainTileDrawMode=0;
gfRenderDrawingMode = TRUE;
switch( usNewMode )
{
case TERRAIN_FGROUND_TEXTURES:
TerrainTileDrawMode = TERRAIN_TILES_FOREGROUND;
ClickEditorButton( TERRAIN_FGROUND_TEXTURES );
iDrawMode = DRAW_MODE_GROUND;
gusSelectionType = gusSavedSelectionType;
break;
case TERRAIN_BGROUND_TEXTURES:
TerrainTileDrawMode = TERRAIN_TILES_BACKGROUND;
ClickEditorButton( TERRAIN_BGROUND_TEXTURES );
iDrawMode = DRAW_MODE_NEW_GROUND;
break;
case TERRAIN_PLACE_CLIFFS:
ClickEditorButton( TERRAIN_PLACE_CLIFFS );
iDrawMode = DRAW_MODE_BANKS;
break;
case TERRAIN_PLACE_ROADS:
ClickEditorButton( TERRAIN_PLACE_ROADS );
iDrawMode = DRAW_MODE_ROADS;
break;
case TERRAIN_PLACE_DEBRIS:
ClickEditorButton( TERRAIN_PLACE_DEBRIS );
iDrawMode = DRAW_MODE_DEBRIS;
gusSelectionType = gusSavedSelectionType;
break;
case TERRAIN_PLACE_TREES:
ClickEditorButton( TERRAIN_PLACE_TREES );
iDrawMode = DRAW_MODE_OSTRUCTS;
gusSelectionType = gusSavedSelectionType;
break;
case TERRAIN_PLACE_ROCKS:
ClickEditorButton( TERRAIN_PLACE_ROCKS );
iDrawMode = DRAW_MODE_OSTRUCTS1;
gusSelectionType = gusSavedSelectionType;
break;
case TERRAIN_PLACE_MISC:
ClickEditorButton( TERRAIN_PLACE_MISC );
iDrawMode = DRAW_MODE_OSTRUCTS2;
gusSelectionType = gusSavedSelectionType;
break;
case TERRAIN_FILL_AREA:
ClickEditorButton( TERRAIN_FILL_AREA );
iDrawMode = DRAW_MODE_FILL_AREA + DRAW_MODE_GROUND;
TerrainTileDrawMode=1;
break;
}
}
void ShowExitGrids()
{
UINT16 i;
LEVELNODE *pLevelNode;
if( gfShowExitGrids )
return;
gfShowExitGrids = TRUE;
for( i = 0; i < WORLD_MAX; i++ )
{
if( GetExitGridLevelNode( i, &pLevelNode ) )
{
AddTopmostToTail( i, FIRSTPOINTERS8 );
}
}
}
void HideExitGrids()
{
UINT16 i;
LEVELNODE *pLevelNode;
if( !gfShowExitGrids )
return;
gfShowExitGrids = FALSE;
for( i = 0; i < WORLD_MAX; i++ )
{
if( GetExitGridLevelNode( i, &pLevelNode ) )
{
pLevelNode = gpWorldLevelData[ i ].pTopmostHead;
while( pLevelNode )
{
if( pLevelNode->usIndex == FIRSTPOINTERS8 )
{
RemoveTopmost( i, pLevelNode->usIndex );
break;
}
pLevelNode = pLevelNode->pNext;
}
}
}
}
void SetEditorMapInfoTaskbarMode( UINT16 usNewMode )
{
BOOLEAN fShowExitGrids = FALSE;
UnclickEditorButton( MAPINFO_ADD_LIGHT1_SOURCE );
UnclickEditorButton( MAPINFO_DRAW_EXITGRIDS );
UnclickEditorButton( MAPINFO_NORTH_POINT );
UnclickEditorButton( MAPINFO_WEST_POINT );
UnclickEditorButton( MAPINFO_CENTER_POINT );
UnclickEditorButton( MAPINFO_EAST_POINT );
UnclickEditorButton( MAPINFO_SOUTH_POINT );
UnclickEditorButton( MAPINFO_ISOLATED_POINT );
ClickEditorButton( usNewMode );
switch( usNewMode )
{
case MAPINFO_ADD_LIGHT1_SOURCE:
iDrawMode = DRAW_MODE_LIGHT;
break;
case MAPINFO_DRAW_EXITGRIDS:
iDrawMode = DRAW_MODE_EXITGRID;
gusSelectionType = gusSavedSelectionType;
fShowExitGrids = TRUE;
break;
case MAPINFO_NORTH_POINT:
iDrawMode = DRAW_MODE_NORTHPOINT;
break;
case MAPINFO_WEST_POINT:
iDrawMode = DRAW_MODE_WESTPOINT;
break;
case MAPINFO_EAST_POINT:
iDrawMode = DRAW_MODE_EASTPOINT;
break;
case MAPINFO_SOUTH_POINT:
iDrawMode = DRAW_MODE_SOUTHPOINT;
break;
case MAPINFO_CENTER_POINT:
iDrawMode = DRAW_MODE_CENTERPOINT;
break;
case MAPINFO_ISOLATED_POINT:
iDrawMode = DRAW_MODE_ISOLATEDPOINT;
break;
case MAPINFO_RADIO_NORMAL:
SetEditorSmoothingMode( SMOOTHING_NORMAL );
gfRenderTaskbar = TRUE;
break;
case MAPINFO_RADIO_BASEMENT:
SetEditorSmoothingMode( SMOOTHING_BASEMENT );
gfRenderTaskbar = TRUE;
break;
case MAPINFO_RADIO_CAVES:
SetEditorSmoothingMode( SMOOTHING_CAVES );
gfRenderTaskbar = TRUE;
break;
}
if( fShowExitGrids )
{
ShowExitGrids();
}
else
{
HideExitGrids();
}
}
void SetEditorSmoothingMode( UINT8 ubNewMode )
{
UnclickEditorButtons( MAPINFO_RADIO_NORMAL, MAPINFO_RADIO_CAVES );
if( iCurrentTaskbar == TASK_BUILDINGS )
HideEditorButtons( BUILDING_NEW_ROOM, BUILDING_CAVE_DRAWING );
gfBasement = FALSE;
gfCaves = FALSE;
gMapInformation.ubEditorSmoothingType = SMOOTHING_NORMAL;
switch( ubNewMode )
{
case SMOOTHING_NORMAL:
ClickEditorButton( MAPINFO_RADIO_NORMAL );
if( iCurrentTaskbar == TASK_BUILDINGS )
ShowEditorButtons( BUILDING_NEW_ROOM, BUILDING_MOVE_BUILDING );
EnableEditorButtons( BUILDING_SMART_WALLS, BUILDING_SMART_BROKEN_WALLS );
break;
case SMOOTHING_BASEMENT:
gfBasement = TRUE;
ClickEditorButton( MAPINFO_RADIO_BASEMENT );
if( iCurrentTaskbar == TASK_BUILDINGS )
ShowEditorButtons( BUILDING_NEW_ROOM, BUILDING_KILL_BUILDING );
EnableEditorButtons( BUILDING_SMART_WALLS, BUILDING_SMART_BROKEN_WALLS );
break;
case SMOOTHING_CAVES:
gfCaves = TRUE;
ClickEditorButton( MAPINFO_RADIO_CAVES );
if( iCurrentTaskbar == TASK_BUILDINGS )
ShowEditorButton( BUILDING_CAVE_DRAWING );
DisableEditorButtons( BUILDING_SMART_WALLS, BUILDING_SMART_BROKEN_WALLS );
break;
default:
AssertMsg( 0, "Attempting to set an illegal smoothing mode." );
break;
}
gMapInformation.ubEditorSmoothingType = ubNewMode;
}
#endif
+17
View File
@@ -0,0 +1,17 @@
#include "BuildDefines.h"
#ifdef JA2EDITOR
#ifndef __EDITOR_MODES_H
#define __EDITOR_MODES_H
void SetEditorItemsTaskbarMode( UINT16 usNewMode );
void SetEditorBuildingTaskbarMode( UINT16 usNewMode );
void SetEditorTerrainTaskbarMode( UINT16 usNewMode );
void SetEditorMapInfoTaskbarMode( UINT16 usNewMode );
void SetEditorSmoothingMode( UINT8 ubNewMode );
void ShowExitGrids();
void HideExitGrids();
#endif
#endif
+809
View File
@@ -0,0 +1,809 @@
#ifdef PRECOMPILEDHEADERS
#include "Editor All.h"
#else
#include "builddefines.h"
#endif
#ifdef JA2EDITOR
#ifndef PRECOMPILEDHEADERS
//sgp
#include "Button System.h"
#include "Font Control.h"
#include "debug.h"
//editor
#include "EditorDefines.h"
#include "Editor Callback Prototypes.h"
#include "Editor Taskbar Utils.h"
#include "EditorMercs.h"
#include "EditorMapInfo.h"
//tactical
#include "Soldier Create.h"
#include "overhead types.h"
#endif
//Category tabs of the editor buttons
void InitEditorTerrainToolbar();
void InitEditorBuildingsToolbar();
void InitEditorItemsToolbar();
void InitEditorMercsToolbar();
void InitEditorMapInfoToolbar();
void InitEditorOptionsToolbar();
void InitEditorItemStatsButtons();
void InitEditorItemStatsButtons()
{
iEditorButton[ ITEMSTATS_PANEL ] =
CreateTextButton( 0, 0, 0, 0, BUTTON_USE_DEFAULT, 480, 361, 160, 99, BUTTON_TOGGLE,
MSYS_PRIORITY_NORMAL, BUTTON_NO_CALLBACK, BUTTON_NO_CALLBACK );
SpecifyDisabledButtonStyle( iEditorButton[ ITEMSTATS_PANEL ], DISABLED_STYLE_NONE );
DisableButton( iEditorButton[ ITEMSTATS_PANEL ] );
iEditorButton[ ITEMSTATS_HIDDEN_BTN ] =
CreateCheckBoxButton( 485, 365, "EDITOR//SmCheckbox.sti", MSYS_PRIORITY_NORMAL, ItemStatsToggleHideCallback );
iEditorButton[ ITEMSTATS_DELETE_BTN ] =
CreateTextButton( L"Delete", FONT10ARIAL, FONT_RED, FONT_BLACK, BUTTON_USE_DEFAULT,
600, 441, 36, 16, BUTTON_NO_TOGGLE, MSYS_PRIORITY_NORMAL+1, DEFAULT_MOVE_CALLBACK, ItemStatsDeleteCallback );
}
void InitEditorMercsToolbar()
{
INT16 TempString[30];
UINT16 *FaceDirs[8] = {L"north",L"northeast",L"east",L"southeast",L"south",L"southwest",L"west",L"northwest"};
INT32 x;
iEditorButton[ MERCS_PLAYERTOGGLE ] =
CreateCheckBoxButton( 4, 362, "EDITOR//SmCheckbox.sti", MSYS_PRIORITY_NORMAL, MercsTogglePlayers );
if( gfShowPlayers )
ClickEditorButton( MERCS_PLAYERTOGGLE );
SetButtonFastHelpText( iEditorButton[ MERCS_PLAYERTOGGLE ], L"Toggle viewing of players");
DisableButton( iEditorButton[ MERCS_PLAYERTOGGLE ] );
iEditorButton[ MERCS_ENEMYTOGGLE ] =
CreateCheckBoxButton( 4, 382, "EDITOR//SmCheckbox.sti", MSYS_PRIORITY_NORMAL, MercsToggleEnemies );
if( gfShowEnemies )
ClickEditorButton( MERCS_ENEMYTOGGLE );
SetButtonFastHelpText( iEditorButton[ MERCS_ENEMYTOGGLE ], L"Toggle viewing of enemies");
iEditorButton[ MERCS_CREATURETOGGLE ] =
CreateCheckBoxButton( 4, 402, "EDITOR//SmCheckbox.sti", MSYS_PRIORITY_NORMAL, MercsToggleCreatures );
if( gfShowCreatures )
ClickEditorButton( MERCS_CREATURETOGGLE );
SetButtonFastHelpText( iEditorButton[ MERCS_CREATURETOGGLE ], L"Toggle viewing of creatures");
iEditorButton[ MERCS_REBELTOGGLE ] =
CreateCheckBoxButton( 4, 422, "EDITOR//SmCheckbox.sti", MSYS_PRIORITY_NORMAL, MercsToggleRebels );
if( gfShowRebels )
ClickEditorButton( MERCS_REBELTOGGLE );
SetButtonFastHelpText( iEditorButton[ MERCS_REBELTOGGLE ], L"Toggle viewing of rebels");
iEditorButton[ MERCS_CIVILIANTOGGLE ] =
CreateCheckBoxButton( 4, 442, "EDITOR//SmCheckbox.sti", MSYS_PRIORITY_NORMAL, MercsToggleCivilians );
if( gfShowCivilians )
ClickEditorButton( MERCS_CIVILIANTOGGLE );
SetButtonFastHelpText( iEditorButton[ MERCS_CIVILIANTOGGLE ], L"Toggle viewing of civilians");
iEditorButton[MERCS_PLAYER] =
CreateTextButton( L"Player",(UINT16)BLOCKFONT, 165, FONT_BLACK, BUTTON_USE_DEFAULT,
20, 362, 78, 19, BUTTON_TOGGLE, MSYS_PRIORITY_NORMAL, DEFAULT_MOVE_CALLBACK,
MercsPlayerTeamCallback );
SpecifyButtonDownTextColors( iEditorButton[MERCS_PLAYER], FONT_YELLOW, FONT_BLACK );
DisableButton( iEditorButton[MERCS_PLAYER] );
iEditorButton[MERCS_ENEMY] =
CreateTextButton( L"Enemy",(UINT16)BLOCKFONT, 165, FONT_BLACK, BUTTON_USE_DEFAULT,
20, 382, 78, 19, BUTTON_TOGGLE, MSYS_PRIORITY_NORMAL, DEFAULT_MOVE_CALLBACK,
MercsEnemyTeamCallback );
SpecifyButtonDownTextColors( iEditorButton[MERCS_ENEMY], FONT_YELLOW, FONT_BLACK );
iEditorButton[MERCS_CREATURE] =
CreateTextButton( L"Creature",(UINT16)BLOCKFONT, 165, FONT_BLACK, BUTTON_USE_DEFAULT,
20, 402, 78, 19, BUTTON_TOGGLE, MSYS_PRIORITY_NORMAL, DEFAULT_MOVE_CALLBACK,
MercsCreatureTeamCallback );
SpecifyButtonDownTextColors( iEditorButton[MERCS_CREATURE], FONT_YELLOW, FONT_BLACK );
iEditorButton[MERCS_REBEL] =
CreateTextButton( L"Rebels",(UINT16)BLOCKFONT, 165, FONT_BLACK, BUTTON_USE_DEFAULT,
20, 422, 78, 19, BUTTON_TOGGLE, MSYS_PRIORITY_NORMAL, DEFAULT_MOVE_CALLBACK,
MercsRebelTeamCallback );
SpecifyButtonDownTextColors( iEditorButton[MERCS_REBEL], FONT_YELLOW, FONT_BLACK );
iEditorButton[MERCS_CIVILIAN] =
CreateTextButton( L"Civilian",(UINT16)BLOCKFONT, 165, FONT_BLACK, BUTTON_USE_DEFAULT,
20, 442, 78, 19, BUTTON_TOGGLE, MSYS_PRIORITY_NORMAL, DEFAULT_MOVE_CALLBACK,
MercsCivilianTeamCallback );
SpecifyButtonDownTextColors( iEditorButton[MERCS_CIVILIAN], FONT_YELLOW, FONT_BLACK );
iEditorButton[ MERCS_1 ] =
CreateTextButton( L"DETAILED PLACEMENT", SMALLCOMPFONT, FONT_ORANGE, 60, BUTTON_USE_DEFAULT,
100, 362, 68, 20, BUTTON_TOGGLE,
MSYS_PRIORITY_NORMAL, BUTTON_NO_CALLBACK, BUTTON_NO_CALLBACK );
DisableButton( iEditorButton[ MERCS_1 ] );
SpecifyDisabledButtonStyle( iEditorButton[ MERCS_1 ], DISABLED_STYLE_NONE );
SpecifyButtonTextOffsets( iEditorButton[ MERCS_1 ], 20, 4, FALSE );
SpecifyButtonTextWrappedWidth( iEditorButton[ MERCS_1 ], 46 );
iEditorButton[ MERCS_DETAILEDCHECKBOX ] =
CreateCheckBoxButton( 103, 365, "EDITOR//checkbox.sti", MSYS_PRIORITY_NORMAL, MercsDetailedPlacementCallback );
iEditorButton[ MERCS_GENERAL ] =
CreateEasyToggleButton( 100, 382, "EDITOR//MercGeneral.sti", MercsGeneralModeCallback );
SetButtonFastHelpText( iEditorButton[ MERCS_GENERAL ], L"General information mode");
iEditorButton[ MERCS_APPEARANCE ] =
CreateEasyToggleButton( 134, 382, "EDITOR//MercAppearance.sti", MercsAppearanceModeCallback );
SetButtonFastHelpText( iEditorButton[ MERCS_APPEARANCE ], L"Physical appearance mode");
iEditorButton[ MERCS_ATTRIBUTES ] =
CreateEasyToggleButton( 100, 408, "EDITOR//MercAttributes.sti", MercsAttributesModeCallback );
SetButtonFastHelpText( iEditorButton[ MERCS_ATTRIBUTES ], L"Attributes mode");
iEditorButton[ MERCS_INVENTORY ] =
CreateEasyToggleButton( 134, 408, "EDITOR//MercInventory.sti", MercsInventoryModeCallback );
SetButtonFastHelpText( iEditorButton[ MERCS_INVENTORY ], L"Inventory mode");
iEditorButton[ MERCS_PROFILE ] =
CreateEasyToggleButton( 100, 434, "EDITOR//MercProfile.sti", MercsProfileModeCallback );
SetButtonFastHelpText( iEditorButton[ MERCS_PROFILE ], L"Profile ID mode");
iEditorButton[ MERCS_SCHEDULE ] =
CreateEasyToggleButton( 134, 434, "EDITOR//MercSchedule.sti", MercsScheduleModeCallback );
SetButtonFastHelpText( iEditorButton[ MERCS_SCHEDULE ], L"Schedule mode");
//Workaround for identical buttons.
MSYS_SetBtnUserData( iEditorButton[ MERCS_SCHEDULE ], 3, 0xffffffff );
iEditorButton[ MERCS_GLOWSCHEDULE ] =
CreateEasyToggleButton( 134, 434, "EDITOR//MercGlowSchedule.sti", MercsScheduleModeCallback );
SetButtonFastHelpText( iEditorButton[ MERCS_GLOWSCHEDULE ], L"Schedule mode");
HideEditorButton( MERCS_GLOWSCHEDULE );
iEditorButton[ MERCS_DELETE ] =
CreateTextButton( L"DELETE", (UINT16)SMALLCOMPFONT, FONT_DKBLUE, FONT_BLACK, BUTTON_USE_DEFAULT,
600, 362, 40, 20, BUTTON_NO_TOGGLE, MSYS_PRIORITY_NORMAL, DEFAULT_MOVE_CALLBACK,
MercsDeleteCallback );
SetButtonFastHelpText( iEditorButton[ MERCS_DELETE ], L"Delete currently selected merc (DEL).");
iEditorButton[ MERCS_NEXT ] =
CreateTextButton( L"NEXT", (UINT16)SMALLCOMPFONT, FONT_DKBLUE, FONT_BLACK, BUTTON_USE_DEFAULT,
600, 382, 40, 20, BUTTON_NO_TOGGLE, MSYS_PRIORITY_NORMAL, DEFAULT_MOVE_CALLBACK,
MercsNextCallback );
SetButtonFastHelpText( iEditorButton[ MERCS_NEXT ], L"Find next merc (SPACE).");
//Priority Existance
iEditorButton[ MERCS_PRIORITYEXISTANCE_CHECKBOX ] =
CreateCheckBoxButton( 170, 365, "EDITOR//checkbox.sti", MSYS_PRIORITY_NORMAL, MercsPriorityExistanceCallback );
SetButtonFastHelpText( iEditorButton[ MERCS_PRIORITYEXISTANCE_CHECKBOX ], L"Toggle priority existance" );
//If merc has keys
iEditorButton[ MERCS_HASKEYS_CHECKBOX ] =
CreateCheckBoxButton( 170, 390, "EDITOR//checkbox.sti", MSYS_PRIORITY_NORMAL, MercsHasKeysCallback );
SetButtonFastHelpText( iEditorButton[ MERCS_HASKEYS_CHECKBOX ], L"Toggle whether or not placement has/naccess to all doors." );
//Orders
iEditorButton[ MERCS_ORDERS_STATIONARY ] =
CreateTextButton( L"STATIONARY", (UINT16)SMALLCOMPFONT, FONT_GRAY2, FONT_BLACK, BUTTON_USE_DEFAULT,
200, 368, 70, 12, BUTTON_TOGGLE, MSYS_PRIORITY_NORMAL, DEFAULT_MOVE_CALLBACK,
MercsSetOrdersCallback );
iEditorButton[ MERCS_ORDERS_ONGUARD] =
CreateTextButton( L"ON GUARD", (UINT16)SMALLCOMPFONT, FONT_GRAY2, FONT_BLACK, BUTTON_USE_DEFAULT,
200, 380, 70, 12, BUTTON_TOGGLE, MSYS_PRIORITY_NORMAL, DEFAULT_MOVE_CALLBACK,
MercsSetOrdersCallback );
iEditorButton[ MERCS_ORDERS_ONCALL ] =
CreateTextButton( L"ON CALL", (UINT16)SMALLCOMPFONT, FONT_GRAY2, FONT_BLACK, BUTTON_USE_DEFAULT,
200, 392, 70, 12, BUTTON_TOGGLE, MSYS_PRIORITY_NORMAL, DEFAULT_MOVE_CALLBACK,
MercsSetOrdersCallback );
iEditorButton[ MERCS_ORDERS_SEEKENEMY ] =
CreateTextButton( L"SEEK ENEMY", (UINT16)SMALLCOMPFONT, FONT_GRAY2, FONT_BLACK, BUTTON_USE_DEFAULT,
200, 404, 70, 12, BUTTON_TOGGLE, MSYS_PRIORITY_NORMAL, DEFAULT_MOVE_CALLBACK,
MercsSetOrdersCallback );
iEditorButton[ MERCS_ORDERS_CLOSEPATROL ] =
CreateTextButton( L"CLOSE PATROL", (UINT16)SMALLCOMPFONT, FONT_GRAY2, FONT_BLACK, BUTTON_USE_DEFAULT,
270, 368, 70, 12, BUTTON_TOGGLE, MSYS_PRIORITY_NORMAL, DEFAULT_MOVE_CALLBACK,
MercsSetOrdersCallback );
iEditorButton[ MERCS_ORDERS_FARPATROL ] =
CreateTextButton( L"FAR PATROL", (UINT16)SMALLCOMPFONT, FONT_GRAY2, FONT_BLACK, BUTTON_USE_DEFAULT,
270, 380, 70, 12, BUTTON_TOGGLE, MSYS_PRIORITY_NORMAL, DEFAULT_MOVE_CALLBACK,
MercsSetOrdersCallback );
iEditorButton[ MERCS_ORDERS_POINTPATROL ] =
CreateTextButton( L"POINT PATROL", (UINT16)SMALLCOMPFONT, FONT_GRAY2, FONT_BLACK, BUTTON_USE_DEFAULT,
270, 392, 70, 12, BUTTON_TOGGLE, MSYS_PRIORITY_NORMAL, DEFAULT_MOVE_CALLBACK,
MercsSetOrdersCallback );
iEditorButton[ MERCS_ORDERS_RNDPTPATROL ] =
CreateTextButton( L"RND PT PATROL", (UINT16)SMALLCOMPFONT, FONT_GRAY2, FONT_BLACK, BUTTON_USE_DEFAULT,
270, 404, 70, 12, BUTTON_TOGGLE, MSYS_PRIORITY_NORMAL, DEFAULT_MOVE_CALLBACK,
MercsSetOrdersCallback );
for ( x = 0; x < 8; x++ )
{
MSYS_SetBtnUserData( iEditorButton[ FIRST_MERCS_ORDERS_BUTTON + x ], 0, x);
}
//Attitudes
iEditorButton[ MERCS_ATTITUDE_DEFENSIVE ] =
CreateTextButton( L"DEFENSIVE", (UINT16)SMALLCOMPFONT, FONT_GRAY4, FONT_BLACK, BUTTON_USE_DEFAULT,
200, 424, 70, 12, BUTTON_TOGGLE, MSYS_PRIORITY_NORMAL, DEFAULT_MOVE_CALLBACK,
MercsSetAttitudeCallback );
iEditorButton[ MERCS_ATTITUDE_BRAVESOLO ] =
CreateTextButton( L"BRAVE SOLO", (UINT16)SMALLCOMPFONT, FONT_GRAY4, FONT_BLACK, BUTTON_USE_DEFAULT,
200, 436, 70, 12, BUTTON_TOGGLE, MSYS_PRIORITY_NORMAL, DEFAULT_MOVE_CALLBACK,
MercsSetAttitudeCallback );
iEditorButton[ MERCS_ATTITUDE_BRAVEAID ] =
CreateTextButton( L"BRAVE AID", (UINT16)SMALLCOMPFONT, FONT_GRAY4, FONT_BLACK, BUTTON_USE_DEFAULT,
200, 448, 70, 12, BUTTON_TOGGLE, MSYS_PRIORITY_NORMAL, DEFAULT_MOVE_CALLBACK,
MercsSetAttitudeCallback );
iEditorButton[ MERCS_ATTITUDE_AGGRESSIVE ] =
CreateTextButton( L"AGGRESSIVE", (UINT16)SMALLCOMPFONT, FONT_GRAY4, FONT_BLACK, BUTTON_USE_DEFAULT,
270, 424, 70, 12, BUTTON_TOGGLE, MSYS_PRIORITY_NORMAL, DEFAULT_MOVE_CALLBACK,
MercsSetAttitudeCallback );
iEditorButton[ MERCS_ATTITUDE_CUNNINGSOLO ] =
CreateTextButton( L"CUNNING SOLO", (UINT16)SMALLCOMPFONT, FONT_GRAY4, FONT_BLACK, BUTTON_USE_DEFAULT,
270, 436, 70, 12, BUTTON_TOGGLE, MSYS_PRIORITY_NORMAL, DEFAULT_MOVE_CALLBACK,
MercsSetAttitudeCallback );
iEditorButton[ MERCS_ATTITUDE_CUNNINGAID ] =
CreateTextButton( L"CUNNING AID", (UINT16)SMALLCOMPFONT, FONT_GRAY4, FONT_BLACK, BUTTON_USE_DEFAULT,
270, 448, 70, 12, BUTTON_TOGGLE, MSYS_PRIORITY_NORMAL, DEFAULT_MOVE_CALLBACK,
MercsSetAttitudeCallback );
for ( x = 0; x < 6; x++ )
{
MSYS_SetBtnUserData( iEditorButton[ FIRST_MERCS_ATTITUDE_BUTTON + x ], 0, x);
}
iEditorButton[ MERCS_DIRECTION_W ] =
CreateIconButton((INT16)giEditMercDirectionIcons[0], 7, BUTTON_USE_DEFAULT,
360, 365, 30, 30, BUTTON_TOGGLE, MSYS_PRIORITY_NORMAL + 1, DEFAULT_MOVE_CALLBACK, MercsDirectionSetCallback );
iEditorButton[ MERCS_DIRECTION_NW ] =
CreateIconButton((INT16)giEditMercDirectionIcons[0], 0, BUTTON_USE_DEFAULT,
390, 365, 30, 30, BUTTON_TOGGLE, MSYS_PRIORITY_NORMAL + 1, DEFAULT_MOVE_CALLBACK, MercsDirectionSetCallback );
iEditorButton[ MERCS_DIRECTION_N ] =
CreateIconButton((INT16)giEditMercDirectionIcons[0], 1, BUTTON_USE_DEFAULT,
420, 365, 30, 30, BUTTON_TOGGLE, MSYS_PRIORITY_NORMAL + 1, DEFAULT_MOVE_CALLBACK, MercsDirectionSetCallback );
iEditorButton[ MERCS_DIRECTION_NE] =
CreateIconButton((INT16)giEditMercDirectionIcons[0], 2, BUTTON_USE_DEFAULT,
420, 395, 30, 30, BUTTON_TOGGLE, MSYS_PRIORITY_NORMAL + 1, DEFAULT_MOVE_CALLBACK, MercsDirectionSetCallback );
iEditorButton[ MERCS_DIRECTION_E ] =
CreateIconButton((INT16)giEditMercDirectionIcons[0], 3, BUTTON_USE_DEFAULT,
420, 425, 30, 30, BUTTON_TOGGLE, MSYS_PRIORITY_NORMAL + 1, DEFAULT_MOVE_CALLBACK, MercsDirectionSetCallback );
iEditorButton[ MERCS_DIRECTION_SE ] =
CreateIconButton((INT16)giEditMercDirectionIcons[0], 4, BUTTON_USE_DEFAULT,
390, 425, 30, 30, BUTTON_TOGGLE, MSYS_PRIORITY_NORMAL + 1, DEFAULT_MOVE_CALLBACK, MercsDirectionSetCallback );
iEditorButton[ MERCS_DIRECTION_S ] =
CreateIconButton((INT16)giEditMercDirectionIcons[0], 5, BUTTON_USE_DEFAULT,
360, 425, 30, 30, BUTTON_TOGGLE, MSYS_PRIORITY_NORMAL + 1, DEFAULT_MOVE_CALLBACK, MercsDirectionSetCallback );
iEditorButton[ MERCS_DIRECTION_SW ] =
CreateIconButton((INT16)giEditMercDirectionIcons[0], 6, BUTTON_USE_DEFAULT,
360, 395, 30, 30, BUTTON_TOGGLE, MSYS_PRIORITY_NORMAL + 1, DEFAULT_MOVE_CALLBACK, MercsDirectionSetCallback );
for ( x = 0; x < 8; x++ )
{
swprintf( (wchar_t *)TempString, (wchar_t *)L"Set merc to face %s", FaceDirs[x] );
SetButtonFastHelpText( iEditorButton[ FIRST_MERCS_DIRECTION_BUTTON + x ], (UINT16 *) TempString );
MSYS_SetBtnUserData( iEditorButton[ FIRST_MERCS_DIRECTION_BUTTON + x ], 0, x);
}
iEditorButton[ MERCS_DIRECTION_FIND ] =
CreateTextButton( L"Find", (INT16)FONT12POINT1, FONT_MCOLOR_BLACK, FONT_BLACK, BUTTON_USE_DEFAULT,
390, 395, 30, 30, BUTTON_NO_TOGGLE, MSYS_PRIORITY_NORMAL + 1, DEFAULT_MOVE_CALLBACK, MercsFindSelectedMercCallback );
SetButtonFastHelpText( iEditorButton[ MERCS_DIRECTION_FIND] , L"Find selected merc" );
iEditorButton[ MERCS_EQUIPMENT_BAD ] =
CreateTextButton( L"BAD", (INT16)SMALLCOMPFONT, FONT_GRAY1, FONT_BLACK, BUTTON_USE_DEFAULT,
480, 385, 40, 15, BUTTON_TOGGLE, MSYS_PRIORITY_NORMAL, DEFAULT_MOVE_CALLBACK, MercsSetRelativeEquipmentCallback );
SpecifyButtonDownTextColors( iEditorButton[ MERCS_EQUIPMENT_BAD ], FONT_LTRED, FONT_BLACK );
iEditorButton[ MERCS_EQUIPMENT_POOR ] =
CreateTextButton( L"POOR", (INT16)SMALLCOMPFONT, FONT_GRAY1, FONT_BLACK, BUTTON_USE_DEFAULT,
480, 400, 40, 15, BUTTON_TOGGLE, MSYS_PRIORITY_NORMAL, DEFAULT_MOVE_CALLBACK, MercsSetRelativeEquipmentCallback );
SpecifyButtonDownTextColors( iEditorButton[ MERCS_EQUIPMENT_POOR ], FONT_ORANGE, FONT_BLACK );
iEditorButton[ MERCS_EQUIPMENT_AVERAGE ] =
CreateTextButton( L"AVERAGE", (INT16)SMALLCOMPFONT, FONT_GRAY1, FONT_BLACK, BUTTON_USE_DEFAULT,
480, 415, 40, 15, BUTTON_TOGGLE, MSYS_PRIORITY_NORMAL, DEFAULT_MOVE_CALLBACK, MercsSetRelativeEquipmentCallback );
SpecifyButtonDownTextColors( iEditorButton[ MERCS_EQUIPMENT_AVERAGE ], FONT_YELLOW, FONT_BLACK );
iEditorButton[ MERCS_EQUIPMENT_GOOD ] =
CreateTextButton( L"GOOD", (INT16)SMALLCOMPFONT, FONT_GRAY1, FONT_BLACK, BUTTON_USE_DEFAULT,
480, 430, 40, 15, BUTTON_TOGGLE, MSYS_PRIORITY_NORMAL, DEFAULT_MOVE_CALLBACK, MercsSetRelativeEquipmentCallback );
SpecifyButtonDownTextColors( iEditorButton[ MERCS_EQUIPMENT_GOOD ], FONT_LTGREEN, FONT_BLACK );
iEditorButton[ MERCS_EQUIPMENT_GREAT ] =
CreateTextButton( L"GREAT", (INT16)SMALLCOMPFONT, FONT_GRAY1, FONT_BLACK, BUTTON_USE_DEFAULT,
480, 445, 40, 15, BUTTON_TOGGLE, MSYS_PRIORITY_NORMAL, DEFAULT_MOVE_CALLBACK, MercsSetRelativeEquipmentCallback );
SpecifyButtonDownTextColors( iEditorButton[ MERCS_EQUIPMENT_GREAT ], FONT_LTBLUE, FONT_BLACK );
for ( x = 0; x < 5; x++ )
{
MSYS_SetBtnUserData( iEditorButton[ FIRST_MERCS_REL_EQUIPMENT_BUTTON + x ], 0, x);
}
iEditorButton[ MERCS_ATTRIBUTES_BAD ] =
CreateTextButton( L"BAD", (INT16)SMALLCOMPFONT, FONT_GRAY1, FONT_BLACK, BUTTON_USE_DEFAULT,
530, 385, 40, 15, BUTTON_TOGGLE, MSYS_PRIORITY_NORMAL, DEFAULT_MOVE_CALLBACK, MercsSetRelativeAttributesCallback );
SpecifyButtonDownTextColors( iEditorButton[ MERCS_ATTRIBUTES_BAD ], FONT_LTRED, FONT_BLACK );
iEditorButton[ MERCS_ATTRIBUTES_POOR ] =
CreateTextButton( L"POOR", (INT16)SMALLCOMPFONT, FONT_GRAY1, FONT_BLACK, BUTTON_USE_DEFAULT,
530, 400, 40, 15, BUTTON_TOGGLE, MSYS_PRIORITY_NORMAL, DEFAULT_MOVE_CALLBACK, MercsSetRelativeAttributesCallback );
SpecifyButtonDownTextColors( iEditorButton[ MERCS_ATTRIBUTES_POOR ], FONT_ORANGE, FONT_BLACK );
iEditorButton[ MERCS_ATTRIBUTES_AVERAGE ] =
CreateTextButton( L"AVERAGE", (INT16)SMALLCOMPFONT, FONT_GRAY1, FONT_BLACK, BUTTON_USE_DEFAULT,
530, 415, 40, 15, BUTTON_TOGGLE, MSYS_PRIORITY_NORMAL, DEFAULT_MOVE_CALLBACK, MercsSetRelativeAttributesCallback );
SpecifyButtonDownTextColors( iEditorButton[ MERCS_ATTRIBUTES_AVERAGE ], FONT_YELLOW, FONT_BLACK );
iEditorButton[ MERCS_ATTRIBUTES_GOOD ] =
CreateTextButton( L"GOOD", (INT16)SMALLCOMPFONT, FONT_GRAY1, FONT_BLACK, BUTTON_USE_DEFAULT,
530, 430, 40, 15, BUTTON_TOGGLE, MSYS_PRIORITY_NORMAL, DEFAULT_MOVE_CALLBACK, MercsSetRelativeAttributesCallback );
SpecifyButtonDownTextColors( iEditorButton[ MERCS_ATTRIBUTES_GOOD ], FONT_LTGREEN, FONT_BLACK );
iEditorButton[ MERCS_ATTRIBUTES_GREAT ] =
CreateTextButton( L"GREAT", (INT16)SMALLCOMPFONT, FONT_GRAY1, FONT_BLACK, BUTTON_USE_DEFAULT,
530, 445, 40, 15, BUTTON_TOGGLE, MSYS_PRIORITY_NORMAL, DEFAULT_MOVE_CALLBACK, MercsSetRelativeAttributesCallback );
SpecifyButtonDownTextColors( iEditorButton[ MERCS_ATTRIBUTES_GREAT ], FONT_LTBLUE, FONT_BLACK );
for( x = 0; x < 5; x++ )
MSYS_SetBtnUserData( iEditorButton[ FIRST_MERCS_REL_ATTRIBUTE_BUTTON + x ], 0, x);
iEditorButton[ MERCS_ARMY_CODE ] =
CreateCheckBoxButton( 575, 410, "EDITOR//radiobutton.sti", MSYS_PRIORITY_NORMAL, MercsSetEnemyColorCodeCallback );
MSYS_SetBtnUserData( iEditorButton[ MERCS_ARMY_CODE ], 0, SOLDIER_CLASS_ARMY );
iEditorButton[ MERCS_ADMIN_CODE ] =
CreateCheckBoxButton( 575, 424, "EDITOR//radiobutton.sti", MSYS_PRIORITY_NORMAL, MercsSetEnemyColorCodeCallback );
MSYS_SetBtnUserData( iEditorButton[ MERCS_ADMIN_CODE ], 0, SOLDIER_CLASS_ADMINISTRATOR );
iEditorButton[ MERCS_ELITE_CODE ] =
CreateCheckBoxButton( 575, 438, "EDITOR//radiobutton.sti", MSYS_PRIORITY_NORMAL, MercsSetEnemyColorCodeCallback );
MSYS_SetBtnUserData( iEditorButton[ MERCS_ELITE_CODE ], 0, SOLDIER_CLASS_ELITE );
iEditorButton[ MERCS_CIVILIAN_GROUP ] =
CreateTextButton( gszCivGroupNames[0], (INT16)SMALLCOMPFONT, FONT_YELLOW, FONT_BLACK, BUTTON_USE_DEFAULT,
574, 410, 60, 25, BUTTON_TOGGLE, MSYS_PRIORITY_NORMAL, DEFAULT_MOVE_CALLBACK, MercsCivilianGroupCallback );
iEditorButton[ MERCS_TOGGLECOLOR_BUTTON ] =
CreateCheckBoxButton( 180, 364, "EDITOR//checkbox.sti", MSYS_PRIORITY_NORMAL, MercsToggleColorModeCallback );
iEditorButton[MERCS_HAIRCOLOR_DOWN] =
CreateEasyNoToggleButton( 200,364,"EDITOR//leftarrow.sti", MercsSetColorsCallback );
iEditorButton[MERCS_HAIRCOLOR_UP] =
CreateEasyNoToggleButton( 360,364,"EDITOR//rightarrow.sti", MercsSetColorsCallback );
iEditorButton[MERCS_SKINCOLOR_DOWN] =
CreateEasyNoToggleButton( 200,388,"EDITOR//leftarrow.sti", MercsSetColorsCallback );
iEditorButton[MERCS_SKINCOLOR_UP] =
CreateEasyNoToggleButton( 360,388,"EDITOR//rightarrow.sti", MercsSetColorsCallback );
iEditorButton[MERCS_VESTCOLOR_DOWN] =
CreateEasyNoToggleButton( 200,412,"EDITOR//leftarrow.sti", MercsSetColorsCallback );
iEditorButton[MERCS_VESTCOLOR_UP] =
CreateEasyNoToggleButton( 360,412,"EDITOR//rightarrow.sti", MercsSetColorsCallback );
iEditorButton[MERCS_PANTCOLOR_DOWN] =
CreateEasyNoToggleButton( 200,436,"EDITOR//leftarrow.sti", MercsSetColorsCallback );
iEditorButton[MERCS_PANTCOLOR_UP] =
CreateEasyNoToggleButton( 360,436,"EDITOR//rightarrow.sti", MercsSetColorsCallback );
for ( x = FIRST_MERCS_COLOR_BUTTON; x < LAST_MERCS_COLOR_BUTTON; x+=2 )
{
SetButtonFastHelpText( iEditorButton[x], L"Previous color set" );
SetButtonFastHelpText( iEditorButton[x + 1], L"Next color set" );
DisableButton( iEditorButton[ x ] );
DisableButton( iEditorButton[ x + 1 ] );
}
iEditorButton[MERCS_BODYTYPE_DOWN] =
CreateEasyNoToggleButton( 460,364,"EDITOR//leftarrow.sti", MercsSetBodyTypeCallback );
SetButtonFastHelpText( iEditorButton[ MERCS_BODYTYPE_DOWN ], L"Previous body type");
iEditorButton[MERCS_BODYTYPE_UP] =
CreateEasyNoToggleButton( 560,364,"EDITOR//rightarrow.sti", MercsSetBodyTypeCallback );
SetButtonFastHelpText( iEditorButton[ MERCS_BODYTYPE_UP ], L"Next body type");
iEditorButton[ MERCS_SCHEDULE_VARIANCE1 ] =
CreateCheckBoxButton( 309, 375, "EDITOR//SmCheckBox.sti", MSYS_PRIORITY_NORMAL, MercsScheduleToggleVariance1Callback );
SetButtonFastHelpText( iEditorButton[ MERCS_SCHEDULE_VARIANCE1 ], L"Toggle time variance (+ or - 15 minutes)");
iEditorButton[ MERCS_SCHEDULE_VARIANCE2 ] =
CreateCheckBoxButton( 309, 396, "EDITOR//SmCheckBox.sti", MSYS_PRIORITY_NORMAL, MercsScheduleToggleVariance2Callback );
SetButtonFastHelpText( iEditorButton[ MERCS_SCHEDULE_VARIANCE2 ], L"Toggle time variance (+ or - 15 minutes)");
iEditorButton[ MERCS_SCHEDULE_VARIANCE3 ] =
CreateCheckBoxButton( 309, 417, "EDITOR//SmCheckBox.sti", MSYS_PRIORITY_NORMAL, MercsScheduleToggleVariance3Callback );
SetButtonFastHelpText( iEditorButton[ MERCS_SCHEDULE_VARIANCE3 ], L"Toggle time variance (+ or - 15 minutes)");
iEditorButton[ MERCS_SCHEDULE_VARIANCE4 ] =
CreateCheckBoxButton( 309, 438, "EDITOR//SmCheckBox.sti", MSYS_PRIORITY_NORMAL, MercsScheduleToggleVariance4Callback );
SetButtonFastHelpText( iEditorButton[ MERCS_SCHEDULE_VARIANCE4 ], L"Toggle time variance (+ or - 15 minutes)");
iEditorButton[ MERCS_SCHEDULE_ACTION1 ] =
CreateTextButton( L"No action", FONT10ARIAL, FONT_YELLOW, FONT_BLACK, BUTTON_USE_DEFAULT,
186, 373, 77, 16, BUTTON_NO_TOGGLE, MSYS_PRIORITY_NORMAL, DEFAULT_MOVE_CALLBACK, MercsScheduleAction1Callback );
iEditorButton[ MERCS_SCHEDULE_ACTION2 ] =
CreateTextButton( L"No action", FONT10ARIAL, FONT_YELLOW, FONT_BLACK, BUTTON_USE_DEFAULT,
186, 394, 77, 16, BUTTON_NO_TOGGLE, MSYS_PRIORITY_NORMAL, DEFAULT_MOVE_CALLBACK, MercsScheduleAction2Callback );
iEditorButton[ MERCS_SCHEDULE_ACTION3 ] =
CreateTextButton( L"No action", FONT10ARIAL, FONT_YELLOW, FONT_BLACK, BUTTON_USE_DEFAULT,
186, 415, 77, 16, BUTTON_NO_TOGGLE, MSYS_PRIORITY_NORMAL, DEFAULT_MOVE_CALLBACK, MercsScheduleAction3Callback );
iEditorButton[ MERCS_SCHEDULE_ACTION4 ] =
CreateTextButton( L"No action", FONT10ARIAL, FONT_YELLOW, FONT_BLACK, BUTTON_USE_DEFAULT,
186, 436, 77, 16, BUTTON_NO_TOGGLE, MSYS_PRIORITY_NORMAL, DEFAULT_MOVE_CALLBACK, MercsScheduleAction4Callback );
iEditorButton[ MERCS_SCHEDULE_DATA1A ] =
CreateTextButton( L"", FONT10ARIAL, FONT_YELLOW, FONT_BLACK, BUTTON_USE_DEFAULT,
331, 373, 40, 16, BUTTON_NO_TOGGLE, MSYS_PRIORITY_NORMAL, DEFAULT_MOVE_CALLBACK, MercsScheduleData1ACallback );
iEditorButton[ MERCS_SCHEDULE_DATA1B ] =
CreateTextButton( L"", FONT10ARIAL, FONT_YELLOW, FONT_BLACK, BUTTON_USE_DEFAULT,
381, 373, 40, 16, BUTTON_NO_TOGGLE, MSYS_PRIORITY_NORMAL, DEFAULT_MOVE_CALLBACK, MercsScheduleData1BCallback );
iEditorButton[ MERCS_SCHEDULE_DATA2A ] =
CreateTextButton( L"", FONT10ARIAL, FONT_YELLOW, FONT_BLACK, BUTTON_USE_DEFAULT,
331, 394, 40, 16, BUTTON_NO_TOGGLE, MSYS_PRIORITY_NORMAL, DEFAULT_MOVE_CALLBACK, MercsScheduleData2ACallback );
iEditorButton[ MERCS_SCHEDULE_DATA2B ] =
CreateTextButton( L"", FONT10ARIAL, FONT_YELLOW, FONT_BLACK, BUTTON_USE_DEFAULT,
381, 394, 40, 16, BUTTON_NO_TOGGLE, MSYS_PRIORITY_NORMAL, DEFAULT_MOVE_CALLBACK, MercsScheduleData2BCallback );
iEditorButton[ MERCS_SCHEDULE_DATA3A ] =
CreateTextButton( L"", FONT10ARIAL, FONT_YELLOW, FONT_BLACK, BUTTON_USE_DEFAULT,
331, 415, 40, 16, BUTTON_NO_TOGGLE, MSYS_PRIORITY_NORMAL, DEFAULT_MOVE_CALLBACK, MercsScheduleData3ACallback );
iEditorButton[ MERCS_SCHEDULE_DATA3B ] =
CreateTextButton( L"", FONT10ARIAL, FONT_YELLOW, FONT_BLACK, BUTTON_USE_DEFAULT,
381, 415, 40, 16, BUTTON_NO_TOGGLE, MSYS_PRIORITY_NORMAL, DEFAULT_MOVE_CALLBACK, MercsScheduleData3BCallback );
iEditorButton[ MERCS_SCHEDULE_DATA4A ] =
CreateTextButton( L"", FONT10ARIAL, FONT_YELLOW, FONT_BLACK, BUTTON_USE_DEFAULT,
331, 436, 40, 16, BUTTON_NO_TOGGLE, MSYS_PRIORITY_NORMAL, DEFAULT_MOVE_CALLBACK, MercsScheduleData4ACallback );
iEditorButton[ MERCS_SCHEDULE_DATA4B ] =
CreateTextButton( L"", FONT10ARIAL, FONT_YELLOW, FONT_BLACK, BUTTON_USE_DEFAULT,
381, 436, 40, 16, BUTTON_NO_TOGGLE, MSYS_PRIORITY_NORMAL, DEFAULT_MOVE_CALLBACK, MercsScheduleData4BCallback );
iEditorButton[ MERCS_SCHEDULE_CLEAR ] =
CreateTextButton( L"Clear Schedule", FONT10ARIAL, FONT_YELLOW, FONT_BLACK, BUTTON_USE_DEFAULT,
516, 362, 77, 16, BUTTON_NO_TOGGLE, MSYS_PRIORITY_NORMAL, DEFAULT_MOVE_CALLBACK, MercsScheduleClearCallback );
HideEditorButtons( MERCS_SCHEDULE_DATA1A, MERCS_SCHEDULE_DATA4B );
iEditorButton[ MERCS_HEAD_SLOT ] =
CreateCheckBoxButton( MERCPANEL_X+61, MERCPANEL_Y+0, "EDITOR//smCheckbox.sti", MSYS_PRIORITY_NORMAL+1, MercsInventorySlotCallback );
MSYS_SetBtnUserData( iEditorButton[ MERCS_HEAD_SLOT ], 0, HELMETPOS );
iEditorButton[ MERCS_BODY_SLOT ] =
CreateCheckBoxButton( MERCPANEL_X+61, MERCPANEL_Y+22, "EDITOR//smCheckbox.sti", MSYS_PRIORITY_NORMAL+1, MercsInventorySlotCallback );
MSYS_SetBtnUserData( iEditorButton[ MERCS_BODY_SLOT ], 0, VESTPOS );
iEditorButton[ MERCS_LEGS_SLOT ] =
CreateCheckBoxButton( MERCPANEL_X+62, MERCPANEL_Y+73, "EDITOR//smCheckbox.sti", MSYS_PRIORITY_NORMAL+1, MercsInventorySlotCallback );
MSYS_SetBtnUserData( iEditorButton[ MERCS_LEGS_SLOT ], 0, LEGPOS );
iEditorButton[ MERCS_LEFTHAND_SLOT ] =
CreateCheckBoxButton( MERCPANEL_X+12, MERCPANEL_Y+43, "EDITOR//smCheckbox.sti", MSYS_PRIORITY_NORMAL+1, MercsInventorySlotCallback );
MSYS_SetBtnUserData( iEditorButton[ MERCS_LEFTHAND_SLOT ], 0, HANDPOS );
iEditorButton[ MERCS_RIGHTHAND_SLOT ] =
CreateCheckBoxButton( MERCPANEL_X+90, MERCPANEL_Y+42, "EDITOR//smCheckbox.sti", MSYS_PRIORITY_NORMAL+1, MercsInventorySlotCallback );
MSYS_SetBtnUserData( iEditorButton[ MERCS_RIGHTHAND_SLOT ], 0, SECONDHANDPOS );
iEditorButton[ MERCS_PACK1_SLOT ] =
CreateCheckBoxButton( MERCPANEL_X+166, MERCPANEL_Y+6, "EDITOR//smCheckbox.sti", MSYS_PRIORITY_NORMAL+1, MercsInventorySlotCallback );
MSYS_SetBtnUserData( iEditorButton[ MERCS_PACK1_SLOT ], 0, BIGPOCK1POS );
iEditorButton[ MERCS_PACK2_SLOT ] =
CreateCheckBoxButton( MERCPANEL_X+166, MERCPANEL_Y+29, "EDITOR//smCheckbox.sti", MSYS_PRIORITY_NORMAL+1, MercsInventorySlotCallback );
MSYS_SetBtnUserData( iEditorButton[ MERCS_PACK2_SLOT ], 0, BIGPOCK2POS );
iEditorButton[ MERCS_PACK3_SLOT ] =
CreateCheckBoxButton( MERCPANEL_X+166, MERCPANEL_Y+52, "EDITOR//smCheckbox.sti", MSYS_PRIORITY_NORMAL+1, MercsInventorySlotCallback );
MSYS_SetBtnUserData( iEditorButton[ MERCS_PACK3_SLOT ], 0, BIGPOCK3POS );
iEditorButton[ MERCS_PACK4_SLOT ] =
CreateCheckBoxButton( MERCPANEL_X+166, MERCPANEL_Y+75, "EDITOR//smCheckbox.sti", MSYS_PRIORITY_NORMAL+1, MercsInventorySlotCallback );
MSYS_SetBtnUserData( iEditorButton[ MERCS_PACK4_SLOT ], 0, BIGPOCK4POS );
}
void InitEditorBuildingsToolbar()
{
iEditorButton[BUILDING_TOGGLE_ROOF_VIEW] =
CreateTextButton(L"ROOFS",(UINT16)SMALLCOMPFONT, FONT_YELLOW, FONT_BLACK, BUTTON_USE_DEFAULT,
110, 400, 50, 15, BUTTON_TOGGLE,MSYS_PRIORITY_NORMAL,BUTTON_NO_CALLBACK,
BuildingToggleRoofViewCallback);
iEditorButton[BUILDING_TOGGLE_WALL_VIEW] =
CreateTextButton(L"WALLS",(UINT16)SMALLCOMPFONT, FONT_YELLOW, FONT_BLACK, BUTTON_USE_DEFAULT,
110, 415, 50, 15, BUTTON_TOGGLE,MSYS_PRIORITY_NORMAL,BUTTON_NO_CALLBACK,
BuildingToggleWallViewCallback);
iEditorButton[BUILDING_TOGGLE_INFO_VIEW] =
CreateTextButton(L"ROOM INFO",(UINT16)SMALLCOMPFONT, FONT_YELLOW, FONT_BLACK, BUTTON_USE_DEFAULT,
110, 430, 50, 15, BUTTON_TOGGLE,MSYS_PRIORITY_NORMAL,BUTTON_NO_CALLBACK,
BuildingToggleInfoViewCallback);
//Selection method buttons
iEditorButton[BUILDING_PLACE_WALLS] =
CreateEasyToggleButton( 180,370,"EDITOR//wall.sti", BuildingWallCallback);
//SetButtonFastHelpText(iEditorButton[BUILDING_PLACE_WALLS],L"Place walls using selection method");
SetButtonFastHelpText(iEditorButton[BUILDING_PLACE_WALLS],
L"Place walls using selection method\nPlace walls using selection method\nPlace walls using selection method\nPlace walls using selection method\nPlace walls using selection method\nPlace walls using selection method\nPlace walls using selection method\nPlace walls using selection method\nPlace walls using selection method\nPlace walls using selection method\nPlace walls using selection method\nPlace walls using selection method\nPlace walls using selection method\nPlace walls using selection method\n");
iEditorButton[BUILDING_PLACE_DOORS] =
CreateEasyToggleButton( 210,370,"EDITOR//door.sti", BuildingDoorCallback);
SetButtonFastHelpText(iEditorButton[BUILDING_PLACE_DOORS],L"Place doors using selection method");
iEditorButton[BUILDING_PLACE_ROOFS] =
CreateEasyToggleButton( 240,370,"EDITOR//roof.sti", BuildingRoofCallback);
SetButtonFastHelpText(iEditorButton[BUILDING_PLACE_ROOFS],L"Place roofs using selection method");
iEditorButton[BUILDING_PLACE_WINDOWS] =
CreateEasyToggleButton( 180,400,"EDITOR//window.sti", BuildingWindowCallback);
SetButtonFastHelpText(iEditorButton[BUILDING_PLACE_WINDOWS],L"Place windows using selection method");
iEditorButton[BUILDING_PLACE_BROKEN_WALLS] =
CreateEasyToggleButton( 210,400,"EDITOR//crackwall.sti", BuildingCrackWallCallback);
SetButtonFastHelpText(iEditorButton[BUILDING_PLACE_BROKEN_WALLS],L"Place damaged walls using selection method.");
iEditorButton[BUILDING_PLACE_FURNITURE] =
CreateEasyToggleButton( 240,400,"EDITOR//decor.sti", BuildingFurnitureCallback);
SetButtonFastHelpText(iEditorButton[BUILDING_PLACE_FURNITURE],L"Place furniture using selection method");
iEditorButton[BUILDING_PLACE_DECALS] =
CreateEasyToggleButton( 180,430,"EDITOR//decal.sti", BuildingDecalCallback);
SetButtonFastHelpText(iEditorButton[BUILDING_PLACE_DECALS],L"Place wall decals using selection method");
iEditorButton[BUILDING_PLACE_FLOORS] =
CreateEasyToggleButton( 210,430,"EDITOR//floor.sti", BuildingFloorCallback);
SetButtonFastHelpText(iEditorButton[BUILDING_PLACE_FLOORS],L"Place floors using selection method");
iEditorButton[BUILDING_PLACE_TOILETS] =
CreateEasyToggleButton( 240,430,"EDITOR//toilet.sti", BuildingToiletCallback);
SetButtonFastHelpText(iEditorButton[BUILDING_PLACE_TOILETS],L"Place generic furniture using selection method");
//Smart method buttons
iEditorButton[BUILDING_SMART_WALLS] =
CreateEasyToggleButton( 290,370,"EDITOR//wall.sti", BuildingSmartWallCallback);
SetButtonFastHelpText(iEditorButton[BUILDING_SMART_WALLS],L"Place walls using smart method");
iEditorButton[BUILDING_SMART_DOORS] =
CreateEasyToggleButton( 320,370,"EDITOR//door.sti", BuildingSmartDoorCallback);
SetButtonFastHelpText(iEditorButton[BUILDING_SMART_DOORS],L"Place doors using smart method");
iEditorButton[BUILDING_SMART_WINDOWS] =
CreateEasyToggleButton( 290,400,"EDITOR//window.sti", BuildingSmartWindowCallback);
SetButtonFastHelpText(iEditorButton[BUILDING_SMART_WINDOWS],L"Place windows using smart method");
iEditorButton[BUILDING_SMART_BROKEN_WALLS] =
CreateEasyToggleButton( 320,400,"EDITOR//crackwall.sti", BuildingSmartCrackWallCallback);
SetButtonFastHelpText(iEditorButton[BUILDING_SMART_BROKEN_WALLS],L"Place damaged walls using smart method");
iEditorButton[BUILDING_DOORKEY] =
CreateEasyToggleButton( 290, 430,"EDITOR//key.sti", BuildingDoorKeyCallback);
SetButtonFastHelpText(iEditorButton[BUILDING_DOORKEY], L"Lock or trap existing doors" );
iEditorButton[BUILDING_NEW_ROOM] =
CreateEasyToggleButton( 370,370,"EDITOR//newroom.sti", BuildingNewRoomCallback);
SetButtonFastHelpText(iEditorButton[BUILDING_NEW_ROOM],L"Add a new room");
iEditorButton[BUILDING_CAVE_DRAWING] =
CreateEasyToggleButton( 370,370,"EDITOR//caves.sti", BuildingCaveDrawingCallback);
SetButtonFastHelpText(iEditorButton[BUILDING_CAVE_DRAWING],L"Edit cave walls.");
iEditorButton[BUILDING_SAW_ROOM] =
CreateEasyToggleButton( 370,400,"EDITOR//sawroom.sti", BuildingSawRoomCallback);
SetButtonFastHelpText(iEditorButton[BUILDING_SAW_ROOM],L"Remove an area from existing building.");
iEditorButton[BUILDING_KILL_BUILDING] =
CreateEasyToggleButton( 370,430,"EDITOR//delroom.sti", BuildingKillBuildingCallback);
SetButtonFastHelpText(iEditorButton[BUILDING_KILL_BUILDING],L"Remove a building");
iEditorButton[BUILDING_NEW_ROOF] =
CreateEasyToggleButton( 400,430,"EDITOR//newroof.sti", BuildingNewRoofCallback);
SetButtonFastHelpText(iEditorButton[BUILDING_NEW_ROOF],L"Add/replace building's roof with new flat roof.");
iEditorButton[BUILDING_COPY_BUILDING] =
CreateEasyToggleButton( 430,430,"EDITOR//copyroom.sti", BuildingCopyBuildingCallback);
SetButtonFastHelpText(iEditorButton[BUILDING_COPY_BUILDING],L"Copy a building");
iEditorButton[BUILDING_MOVE_BUILDING] =
CreateEasyToggleButton( 460,430,"EDITOR//moveroom.sti", BuildingMoveBuildingCallback);
SetButtonFastHelpText(iEditorButton[BUILDING_MOVE_BUILDING],L"Move a building");
iEditorButton[BUILDING_DRAW_ROOMNUM] =
CreateEasyToggleButton( 410,370,"EDITOR//addTileRoom.sti", BuildingDrawRoomNumCallback);
SetButtonFastHelpText(iEditorButton[BUILDING_DRAW_ROOMNUM],L"Draw room number");
iEditorButton[BUILDING_ERASE_ROOMNUM] =
CreateEasyToggleButton( 440,370,"EDITOR//killTileRoom.sti", BuildingEraseRoomNumCallback);
SetButtonFastHelpText(iEditorButton[BUILDING_ERASE_ROOMNUM],L"Erase room numbers");
iEditorButton[BUILDING_TOGGLE_ERASEMODE] =
CreateEasyToggleButton( 500,400,"EDITOR//eraser.sti", BtnEraseCallback);
SetButtonFastHelpText(iEditorButton[BUILDING_TOGGLE_ERASEMODE],L"Toggle erase mode");
iEditorButton[BUILDING_UNDO] =
CreateEasyNoToggleButton( 530,400,"EDITOR//undo.sti", BtnUndoCallback);
SetButtonFastHelpText(iEditorButton[BUILDING_UNDO],L"Undo last change");
iEditorButton[BUILDING_CYCLE_BRUSHSIZE] =
CreateEasyNoToggleButton( 500,430,"EDITOR//paint.sti",BtnBrushCallback);
SetButtonFastHelpText( iEditorButton[ BUILDING_CYCLE_BRUSHSIZE ], L"Cycle brush size");
}
void InitEditorItemsToolbar()
{
SetFontForeground( FONT_MCOLOR_LTRED );
iEditorButton[ITEMS_WEAPONS] =
CreateTextButton(L"Weapons",(UINT16)BLOCKFONT, FONT_MCOLOR_DKWHITE, FONT_BLACK, BUTTON_USE_DEFAULT,
100, 440, 59, 20, BUTTON_TOGGLE,MSYS_PRIORITY_NORMAL,DEFAULT_MOVE_CALLBACK,
ItemsWeaponsCallback);
iEditorButton[ITEMS_AMMO] =
CreateTextButton(L"Ammo",(UINT16)BLOCKFONT, FONT_MCOLOR_DKWHITE, FONT_BLACK, BUTTON_USE_DEFAULT,
159, 440, 40, 20, BUTTON_TOGGLE,MSYS_PRIORITY_NORMAL,DEFAULT_MOVE_CALLBACK,
ItemsAmmoCallback);
iEditorButton[ITEMS_ARMOUR] =
CreateTextButton(L"Armour",(UINT16)BLOCKFONT, FONT_MCOLOR_DKWHITE, FONT_BLACK, BUTTON_USE_DEFAULT,
199, 440, 52, 20, BUTTON_TOGGLE,MSYS_PRIORITY_NORMAL,DEFAULT_MOVE_CALLBACK,
ItemsArmourCallback);
iEditorButton[ITEMS_EXPLOSIVES] =
CreateTextButton(L"Explosives",(UINT16)BLOCKFONT, FONT_MCOLOR_DKWHITE, FONT_BLACK, BUTTON_USE_DEFAULT,
251, 440, 69, 20, BUTTON_TOGGLE,MSYS_PRIORITY_NORMAL,DEFAULT_MOVE_CALLBACK,
ItemsExplosivesCallback);
iEditorButton[ITEMS_EQUIPMENT1] =
CreateTextButton(L"E1",(UINT16)BLOCKFONT, FONT_MCOLOR_DKWHITE, FONT_BLACK, BUTTON_USE_DEFAULT,
320, 440, 21, 20, BUTTON_TOGGLE,MSYS_PRIORITY_NORMAL,DEFAULT_MOVE_CALLBACK,
ItemsEquipment1Callback);
iEditorButton[ITEMS_EQUIPMENT2] =
CreateTextButton(L"E2",(UINT16)BLOCKFONT, FONT_MCOLOR_DKWHITE, FONT_BLACK, BUTTON_USE_DEFAULT,
341, 440, 21, 20, BUTTON_TOGGLE,MSYS_PRIORITY_NORMAL,DEFAULT_MOVE_CALLBACK,
ItemsEquipment2Callback);
iEditorButton[ITEMS_EQUIPMENT3] =
CreateTextButton(L"E3",(UINT16)BLOCKFONT, FONT_MCOLOR_DKWHITE, FONT_BLACK, BUTTON_USE_DEFAULT,
362, 440, 21, 20, BUTTON_TOGGLE,MSYS_PRIORITY_NORMAL,DEFAULT_MOVE_CALLBACK,
ItemsEquipment3Callback);
iEditorButton[ITEMS_TRIGGERS] =
CreateTextButton( L"Triggers",(UINT16)BLOCKFONT, FONT_MCOLOR_DKWHITE, FONT_BLACK, BUTTON_USE_DEFAULT,
383, 440, 59, 20, BUTTON_TOGGLE,MSYS_PRIORITY_NORMAL,DEFAULT_MOVE_CALLBACK,
ItemsTriggersCallback );
iEditorButton[ITEMS_KEYS] =
CreateTextButton( L"Keys",(UINT16)BLOCKFONT, FONT_MCOLOR_DKWHITE, FONT_BLACK, BUTTON_USE_DEFAULT,
442, 440, 38, 20, BUTTON_TOGGLE,MSYS_PRIORITY_NORMAL,DEFAULT_MOVE_CALLBACK,
ItemsKeysCallback );
iEditorButton[ITEMS_LEFTSCROLL] =
CreateEasyNoToggleButton( 1,361,"EDITOR//leftscroll.sti", ItemsLeftScrollCallback);
iEditorButton[ITEMS_RIGHTSCROLL] =
CreateEasyNoToggleButton( 50,361,"EDITOR//rightscroll.sti", ItemsRightScrollCallback);
}
void InitEditorMapInfoToolbar()
{
iEditorButton[MAPINFO_ADD_LIGHT1_SOURCE] =
CreateEasyToggleButton( 10, 362, "EDITOR//light.sti", BtnDrawLightsCallback );
SetButtonFastHelpText(iEditorButton[MAPINFO_ADD_LIGHT1_SOURCE],L"Add ambient light source");
iEditorButton[ MAPINFO_LIGHT_PANEL ] =
CreateTextButton( 0, 0, 0, 0, BUTTON_USE_DEFAULT, 45, 362, 60, 50, BUTTON_TOGGLE, MSYS_PRIORITY_NORMAL, BUTTON_NO_CALLBACK, BUTTON_NO_CALLBACK );
SpecifyDisabledButtonStyle( iEditorButton[ MAPINFO_LIGHT_PANEL ], DISABLED_STYLE_NONE );
DisableButton( iEditorButton[ MAPINFO_LIGHT_PANEL ] );
iEditorButton[ MAPINFO_PRIMETIME_LIGHT ] =
CreateCheckBoxButton( 48, 365, "EDITOR//radiobutton.sti", MSYS_PRIORITY_NORMAL, MapInfoPrimeTimeRadioCallback );
iEditorButton[ MAPINFO_NIGHTTIME_LIGHT ] =
CreateCheckBoxButton( 48, 380, "EDITOR//radiobutton.sti", MSYS_PRIORITY_NORMAL, MapInfoNightTimeRadioCallback );
iEditorButton[ MAPINFO_24HOUR_LIGHT ] =
CreateCheckBoxButton( 48, 395, "EDITOR//radiobutton.sti", MSYS_PRIORITY_NORMAL, MapInfo24HourTimeRadioCallback );
ClickEditorButton( gbDefaultLightType + MAPINFO_PRIMETIME_LIGHT );
iEditorButton[MAPINFO_TOGGLE_FAKE_LIGHTS] =
CreateEasyToggleButton( 120, 362, "EDITOR//fakelight.sti", BtnFakeLightCallback );
SetButtonFastHelpText(iEditorButton[MAPINFO_TOGGLE_FAKE_LIGHTS], L"Toggle fake ambient lights.");
iEditorButton[ MAPINFO_RADIO_PANEL ] =
CreateTextButton( 0, 0, 0, 0, BUTTON_USE_DEFAULT, 207, 362, 70, 50, BUTTON_TOGGLE, MSYS_PRIORITY_NORMAL, BUTTON_NO_CALLBACK, BUTTON_NO_CALLBACK );
SpecifyDisabledButtonStyle( iEditorButton[ MAPINFO_RADIO_PANEL ], DISABLED_STYLE_NONE );
DisableButton( iEditorButton[ MAPINFO_RADIO_PANEL ] );
iEditorButton[ MAPINFO_RADIO_NORMAL ] =
CreateCheckBoxButton( 210, 365, "EDITOR//radiobutton.sti", MSYS_PRIORITY_NORMAL, MapInfoNormalRadioCallback );
iEditorButton[ MAPINFO_RADIO_BASEMENT ] =
CreateCheckBoxButton( 210, 380, "EDITOR//radiobutton.sti", MSYS_PRIORITY_NORMAL, MapInfoBasementRadioCallback );
iEditorButton[ MAPINFO_RADIO_CAVES ] =
CreateCheckBoxButton( 210, 395, "EDITOR//radiobutton.sti", MSYS_PRIORITY_NORMAL, MapInfoCavesRadioCallback );
iEditorButton[MAPINFO_DRAW_EXITGRIDS] =
CreateEasyToggleButton( 305, 372, "EDITOR//exitgridbut.sti", MapInfoDrawExitGridCallback );
SetButtonFastHelpText(iEditorButton[MAPINFO_DRAW_EXITGRIDS],L"Add exit grids (r-clk to query existing).");
iEditorButton[MAPINFO_CYCLE_BRUSHSIZE] =
CreateEasyNoToggleButton( 420, 430, "EDITOR//paint.sti", BtnBrushCallback );
SetButtonFastHelpText(iEditorButton[MAPINFO_CYCLE_BRUSHSIZE],L"Cycle brush size");
iEditorButton[MAPINFO_UNDO] =
CreateEasyNoToggleButton( 510, 430, "EDITOR//undo.sti", BtnUndoCallback );
SetButtonFastHelpText(iEditorButton[MAPINFO_UNDO],L"Undo last change");
iEditorButton[MAPINFO_TOGGLE_ERASEMODE] =
CreateEasyToggleButton( 540, 430, "EDITOR//eraser.sti", BtnEraseCallback);
SetButtonFastHelpText(iEditorButton[MAPINFO_TOGGLE_ERASEMODE],L"Toggle erase mode");
iEditorButton[ MAPINFO_NORTH_POINT ] =
CreateEasyToggleButton( 540, 365, "EDITOR//north.sti", MapInfoEntryPointsCallback);
SetButtonFastHelpText( iEditorButton[ MAPINFO_NORTH_POINT ], L"Specify north point for validation purposes.");
iEditorButton[ MAPINFO_WEST_POINT ] =
CreateEasyToggleButton( 525, 386, "EDITOR//west.sti", MapInfoEntryPointsCallback);
SetButtonFastHelpText( iEditorButton[ MAPINFO_WEST_POINT ], L"Specify west point for validation purposes.");
iEditorButton[ MAPINFO_EAST_POINT ] =
CreateEasyToggleButton( 555, 386, "EDITOR//east.sti", MapInfoEntryPointsCallback);
SetButtonFastHelpText( iEditorButton[ MAPINFO_EAST_POINT ], L"Specify east point for validation purposes.");
iEditorButton[ MAPINFO_SOUTH_POINT ] =
CreateEasyToggleButton( 540, 407, "EDITOR//south.sti", MapInfoEntryPointsCallback);
SetButtonFastHelpText( iEditorButton[ MAPINFO_SOUTH_POINT ], L"Specify south point for validation purposes.");
iEditorButton[ MAPINFO_CENTER_POINT ] =
CreateEasyToggleButton( 590, 375, "EDITOR//center.sti", MapInfoEntryPointsCallback);
SetButtonFastHelpText( iEditorButton[ MAPINFO_CENTER_POINT ], L"Specify center point for validation purposes.");
iEditorButton[ MAPINFO_ISOLATED_POINT ] =
CreateEasyToggleButton( 590, 396, "EDITOR//isolated.sti", MapInfoEntryPointsCallback);
SetButtonFastHelpText( iEditorButton[ MAPINFO_ISOLATED_POINT ], L"Specify isolated point for validation purposes.");
}
void InitEditorOptionsToolbar()
{
iEditorButton[OPTIONS_NEW_MAP] =
CreateEasyNoToggleButton( 71,401,"EDITOR//new.sti", BtnNewMapCallback);
SetButtonFastHelpText(iEditorButton[OPTIONS_NEW_MAP],L"New map");
iEditorButton[OPTIONS_NEW_BASEMENT] =
CreateEasyNoToggleButton( 101,401,"EDITOR//new.sti", BtnNewBasementCallback);
SetButtonFastHelpText(iEditorButton[OPTIONS_NEW_BASEMENT],L"New basement");
iEditorButton[OPTIONS_NEW_CAVES] =
CreateEasyNoToggleButton( 131,401,"EDITOR//new.sti", BtnNewCavesCallback);
SetButtonFastHelpText(iEditorButton[OPTIONS_NEW_CAVES],L"New cave level");
iEditorButton[OPTIONS_SAVE_MAP] =
CreateEasyNoToggleButton( 161,401,"EDITOR//save.sti", BtnSaveCallback);
SetButtonFastHelpText(iEditorButton[OPTIONS_SAVE_MAP],L"Save map");
iEditorButton[OPTIONS_LOAD_MAP] =
CreateEasyNoToggleButton( 191,401,"EDITOR//load.sti", BtnLoadCallback);
SetButtonFastHelpText(iEditorButton[OPTIONS_LOAD_MAP],L"Load map");
iEditorButton[OPTIONS_CHANGE_TILESET] =
CreateEasyNoToggleButton( 221,401,"EDITOR//tileset.sti", BtnChangeTilesetCallback);
SetButtonFastHelpText(iEditorButton[OPTIONS_CHANGE_TILESET],L"Select tileset");
iEditorButton[OPTIONS_LEAVE_EDITOR] =
CreateEasyNoToggleButton( 251,401,"EDITOR//cancel.sti", BtnCancelCallback);
SetButtonFastHelpText(iEditorButton[OPTIONS_LEAVE_EDITOR],L"Leave Editor mode");
iEditorButton[OPTIONS_QUIT_GAME] =
CreateEasyNoToggleButton( 281,401,"EDITOR//cancel.sti", BtnQuitCallback);
SetButtonFastHelpText(iEditorButton[OPTIONS_QUIT_GAME],L"Exit game.");
}
void InitEditorTerrainToolbar()
{
iEditorButton[TERRAIN_FGROUND_TEXTURES] =
CreateEasyToggleButton( 100,400,"EDITOR//downgrid.sti", BtnFgGrndCallback);
SetButtonFastHelpText(iEditorButton[TERRAIN_FGROUND_TEXTURES],L"Draw ground textures");
iEditorButton[TERRAIN_BGROUND_TEXTURES] =
CreateEasyToggleButton( 130,400,"EDITOR//upgrid.sti", BtnBkGrndCallback);
SetButtonFastHelpText(iEditorButton[TERRAIN_BGROUND_TEXTURES],L"Set map ground textures");
iEditorButton[TERRAIN_PLACE_CLIFFS] =
CreateEasyToggleButton( 160,400,"EDITOR//banks.sti", BtnBanksCallback);
SetButtonFastHelpText(iEditorButton[TERRAIN_PLACE_CLIFFS],L"Place banks and cliffs");
iEditorButton[TERRAIN_PLACE_ROADS] =
CreateEasyToggleButton( 190,400,"EDITOR//road.sti", BtnRoadsCallback);
SetButtonFastHelpText(iEditorButton[TERRAIN_PLACE_ROADS],L"Draw roads");
iEditorButton[TERRAIN_PLACE_DEBRIS] =
CreateEasyToggleButton( 220,400,"EDITOR//debris.sti", BtnDebrisCallback);
SetButtonFastHelpText(iEditorButton[TERRAIN_PLACE_DEBRIS],L"Draw debris");
iEditorButton[TERRAIN_PLACE_TREES] =
CreateEasyToggleButton( 250,400,"EDITOR//tree.sti", BtnObjectCallback);
SetButtonFastHelpText(iEditorButton[TERRAIN_PLACE_TREES],L"Place trees & bushes");
iEditorButton[TERRAIN_PLACE_ROCKS] =
CreateEasyToggleButton( 280,400,"EDITOR//num1.sti", BtnObject1Callback);
SetButtonFastHelpText(iEditorButton[TERRAIN_PLACE_ROCKS],L"Place rocks");
iEditorButton[TERRAIN_PLACE_MISC] =
CreateEasyToggleButton( 310,400,"EDITOR//num2.sti", BtnObject2Callback);
SetButtonFastHelpText(iEditorButton[TERRAIN_PLACE_MISC],L"Place barrels & other junk");
iEditorButton[TERRAIN_FILL_AREA] =
CreateEasyToggleButton( 100,430,"EDITOR//fill.sti", BtnFillCallback);
SetButtonFastHelpText(iEditorButton[TERRAIN_FILL_AREA],L"Fill area");
iEditorButton[TERRAIN_UNDO] =
CreateEasyNoToggleButton( 130,430,"EDITOR//undo.sti", BtnUndoCallback);
SetButtonFastHelpText(iEditorButton[TERRAIN_UNDO],L"Undo last change");
iEditorButton[TERRAIN_TOGGLE_ERASEMODE] =
CreateEasyToggleButton( 160,430,"EDITOR//eraser.sti", BtnEraseCallback);
SetButtonFastHelpText(iEditorButton[TERRAIN_TOGGLE_ERASEMODE],L"Toggle erase mode");
iEditorButton[TERRAIN_CYCLE_BRUSHSIZE] =
CreateEasyNoToggleButton( 190,430,"EDITOR//paint.sti", BtnBrushCallback);
SetButtonFastHelpText(iEditorButton[TERRAIN_CYCLE_BRUSHSIZE],L"Cycle brush size");
iEditorButton[TERRAIN_RAISE_DENSITY] =
CreateEasyNoToggleButton( 280,430,"EDITOR//uparrow.sti", BtnIncBrushDensityCallback);
SetButtonFastHelpText(iEditorButton[TERRAIN_RAISE_DENSITY],L"Raise brush density");
iEditorButton[TERRAIN_LOWER_DENSITY] =
CreateEasyNoToggleButton( 350,430,"EDITOR//downarrow.sti", BtnDecBrushDensityCallback);
SetButtonFastHelpText(iEditorButton[TERRAIN_LOWER_DENSITY],L"Lower brush density");
}
void CreateEditorTaskbarInternal()
{
//Create the tabs for the editor taskbar
iEditorButton[ TAB_TERRAIN ] =
CreateTextButton(L"Terrain", (UINT16)SMALLFONT1, FONT_LTKHAKI, FONT_DKKHAKI, BUTTON_USE_DEFAULT,
100, 460, 90, 20, BUTTON_TOGGLE,MSYS_PRIORITY_HIGH,BUTTON_NO_CALLBACK,
TaskTerrainCallback);
SpecifyButtonDownTextColors( iEditorButton[TAB_TERRAIN], FONT_YELLOW, FONT_ORANGE );
iEditorButton[ TAB_BUILDINGS ] =
CreateTextButton(L"Buildings", (UINT16)SMALLFONT1, FONT_LTKHAKI, FONT_DKKHAKI, BUTTON_USE_DEFAULT,
190, 460, 90, 20, BUTTON_TOGGLE,MSYS_PRIORITY_HIGH,BUTTON_NO_CALLBACK,
TaskBuildingCallback);
SpecifyButtonDownTextColors( iEditorButton[TAB_BUILDINGS], FONT_YELLOW, FONT_ORANGE );
iEditorButton[ TAB_ITEMS ] =
CreateTextButton(L"Items", (UINT16)SMALLFONT1, FONT_LTKHAKI, FONT_DKKHAKI, BUTTON_USE_DEFAULT,
280, 460, 90, 20, BUTTON_TOGGLE,MSYS_PRIORITY_HIGH,BUTTON_NO_CALLBACK,
TaskItemsCallback);
SpecifyButtonDownTextColors( iEditorButton[TAB_ITEMS], FONT_YELLOW, FONT_ORANGE );
iEditorButton[ TAB_MERCS ] =
CreateTextButton(L"Mercs", (UINT16)SMALLFONT1, FONT_LTKHAKI, FONT_DKKHAKI, BUTTON_USE_DEFAULT,
370, 460, 90, 20, BUTTON_TOGGLE,MSYS_PRIORITY_HIGH,BUTTON_NO_CALLBACK,
TaskMercsCallback);
SpecifyButtonDownTextColors( iEditorButton[TAB_MERCS], FONT_YELLOW, FONT_ORANGE );
iEditorButton[ TAB_MAPINFO ] =
CreateTextButton(L"Map Info", (UINT16)SMALLFONT1, FONT_LTKHAKI, FONT_DKKHAKI, BUTTON_USE_DEFAULT,
460, 460, 90, 20, BUTTON_TOGGLE,MSYS_PRIORITY_HIGH,BUTTON_NO_CALLBACK,
TaskMapInfoCallback);
SpecifyButtonDownTextColors( iEditorButton[TAB_MAPINFO], FONT_YELLOW, FONT_ORANGE );
iEditorButton[ TAB_OPTIONS ] =
CreateTextButton(L"Options", (UINT16)SMALLFONT1, FONT_LTKHAKI, FONT_DKKHAKI, BUTTON_USE_DEFAULT,
550, 460, 90, 20, BUTTON_TOGGLE,MSYS_PRIORITY_HIGH,BUTTON_NO_CALLBACK,
TaskOptionsCallback);
SpecifyButtonDownTextColors( iEditorButton[TAB_OPTIONS], FONT_YELLOW, FONT_ORANGE );
//Create the buttons within each tab.
InitEditorTerrainToolbar();
InitEditorBuildingsToolbar();
InitEditorItemsToolbar();
InitEditorMercsToolbar();
InitEditorMapInfoToolbar();
InitEditorOptionsToolbar();
InitEditorItemStatsButtons();
}
#endif
+10
View File
@@ -0,0 +1,10 @@
#include "BuildDefines.h"
#ifdef JA2EDITOR
#ifndef __EDITOR_TASKBAR_CREATION_H
#define __EDITOR_TASKBAR_CREATION_H
void CreateEditorTaskbarInternal();
#endif
#endif
+984
View File
@@ -0,0 +1,984 @@
#ifdef PRECOMPILEDHEADERS
#include "Editor All.h"
#else
#include "builddefines.h"
#endif
#ifdef JA2EDITOR
#ifndef PRECOMPILEDHEADERS
#include <stdio.h>
#include "types.h"
#include "mousesystem.h"
#include "Button System.h"
#include "Font Control.h"
#include "Isometric Utils.h"
#include "WorldDat.h"
#include "Render Dirty.h"
#include "sysutil.h"
#include "wordwrap.h"
#include "environment.h"
#include "Interface Items.h"
#include "Soldier Find.h"
#include "World Items.h"
#include "Text.h"
#include "Overhead map.h"
#include "Cursor Modes.h"
#include "editscreen.h"
#include "EditorTerrain.h"
#include "Cursor Modes.h"
#include "EditorItems.h"
#include "EditorMercs.h"
#include "EditorBuildings.h"
#include "EditorMapInfo.h"
#include "EditorDefines.h"
#include "Editor Taskbar Utils.h"
#include "Editor Taskbar Creation.h"
#include "Editor Callback Prototypes.h"
#include "Editor Modes.h"
#include "Text Input.h"
#include "Item Statistics.h"
#include "Map Information.h"
#include "Sector Summary.h"
#include "Item Statistics.h"
#include "pits.h"
#include "Soldier Find.h"
#include "lighting.h"
#include "Keys.h"
#endif
void RenderEditorInfo();
extern ITEM_POOL *gpItemPool;
//editor icon storage vars
INT32 giEditMercDirectionIcons[2];
UINT32 guiMercInventoryPanel;
UINT32 guiOmertaMap;
UINT32 guiMercInvPanelBuffers[9];
UINT32 guiMercTempBuffer;
INT32 giEditMercImage[2];
UINT32 guiExclamation;
UINT32 guiKeyImage;
//editor Mouseregion storage vars
MOUSE_REGION TerrainTileButtonRegion[ NUM_TERRAIN_TILE_REGIONS ];
MOUSE_REGION ItemsRegion;
MOUSE_REGION MercRegion;
MOUSE_REGION EditorRegion;
void EnableEditorRegion( INT8 bRegionID )
{
switch( bRegionID )
{
case BASE_TERRAIN_TILE_REGION_ID:
case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8:
MSYS_EnableRegion( &TerrainTileButtonRegion[ bRegionID ] );
break;
case ITEM_REGION_ID:
MSYS_EnableRegion( &ItemsRegion );
break;
case MERC_REGION_ID:
MSYS_EnableRegion( &MercRegion );
break;
}
}
void DisableEditorRegion( INT8 bRegionID )
{
switch( bRegionID )
{
case BASE_TERRAIN_TILE_REGION_ID:
case 1: case 2: case 3: case 4: case 5: case 6: case 7:
MSYS_DisableRegion( &TerrainTileButtonRegion[ bRegionID ] );
break;
case ITEM_REGION_ID:
MSYS_DisableRegion( &ItemsRegion );
break;
case MERC_REGION_ID:
MSYS_DisableRegion( &MercRegion );
break;
}
}
void RemoveEditorRegions()
{
INT32 x;
MSYS_RemoveRegion( &EditorRegion );
for(x = BASE_TERRAIN_TILE_REGION_ID; x < NUM_TERRAIN_TILE_REGIONS; x++ )
{
MSYS_RemoveRegion( &TerrainTileButtonRegion[ x ] );
}
MSYS_RemoveRegion( &ItemsRegion );
MSYS_RemoveRegion( &MercRegion );
}
void InitEditorRegions()
{
INT32 x;
//By doing this, all of the buttons underneath are blanketed and can't be used anymore.
//Any new buttons will cover this up as well. Think of it as a barrier between the editor buttons,
//and the game's interface panel buttons and regions.
MSYS_DefineRegion( &EditorRegion, 0, 360, 640, 480, MSYS_PRIORITY_NORMAL, 0, MSYS_NO_CALLBACK, MSYS_NO_CALLBACK );
//Create the regions for the terrain tile selections
for( x = 0; x < NUM_TERRAIN_TILE_REGIONS; x++ )
{
MSYS_DefineRegion(&TerrainTileButtonRegion[x],(INT16)(261+x*42),369,(INT16)(303+x*42),391,
MSYS_PRIORITY_NORMAL, 0, MSYS_NO_CALLBACK,(MOUSE_CALLBACK)TerrainTileButtonRegionCallback);
MSYS_SetRegionUserData( &TerrainTileButtonRegion[x], 0, x );
MSYS_DisableRegion( &TerrainTileButtonRegion[x] );
}
gfShowTerrainTileButtons=FALSE;
//Create the region for the items selection window.
MSYS_DefineRegion( &ItemsRegion, 100, 360, 540, 440, MSYS_PRIORITY_NORMAL, 0,
(MOUSE_CALLBACK)MouseMovedInItemsRegion, (MOUSE_CALLBACK)MouseClickedInItemsRegion );
MSYS_DisableRegion( &ItemsRegion );
//Create the region for the merc inventory panel.
MSYS_DefineRegion( &MercRegion, 175, 361, 450, 460, MSYS_PRIORITY_NORMAL, 0,
MouseMovedInMercRegion, MouseClickedInMercRegion );
MSYS_DisableRegion( &MercRegion );
}
void LoadEditorImages()
{
VOBJECT_DESC VObjectDesc;
//Set up the merc inventory panel
VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE;
sprintf( VObjectDesc.ImageFile, "EDITOR\\InvPanel.sti" );
if( !AddVideoObject( &VObjectDesc, &guiMercInventoryPanel ) )
AssertMsg( 0, "Failed to load data\\editor\\InvPanel.sti" );
//Set up small omerta map
sprintf( VObjectDesc.ImageFile, "EDITOR\\omerta.sti" );
if( !AddVideoObject( &VObjectDesc, &guiOmertaMap ) )
AssertMsg( 0, "Failed to load data\\editor\\omerta.sti" );
//Set up the merc directional buttons.
giEditMercDirectionIcons[0] = LoadGenericButtonIcon("EDITOR//arrowsoff.sti");
giEditMercDirectionIcons[1] = LoadGenericButtonIcon("EDITOR//arrowson.sti");
giEditMercImage[0] = LoadButtonImage("EDITOR\\leftarrow.sti",0,1,2,3,4);
giEditMercImage[1] = LoadButtonImage("EDITOR\\rightarrow.sti",0,1,2,3,4);
sprintf( VObjectDesc.ImageFile, "EDITOR\\Exclamation.sti" );
if( !AddVideoObject( &VObjectDesc, &guiExclamation ) )
AssertMsg( 0, "Failed to load data\\editor\\Exclamation.sti" );
sprintf( VObjectDesc.ImageFile, "EDITOR\\KeyImage.sti" );
if( !AddVideoObject( &VObjectDesc, &guiKeyImage ) )
AssertMsg( 0, "Failed to load data\\editor\\KeyImage.sti" );
}
void DeleteEditorImages()
{
//The merc inventory panel
DeleteVideoObjectFromIndex( guiMercInventoryPanel );
DeleteVideoObjectFromIndex( guiOmertaMap );
//The merc directional buttons
UnloadGenericButtonIcon( (INT16)giEditMercDirectionIcons[0] );
UnloadGenericButtonIcon( (INT16)giEditMercDirectionIcons[1] );
UnloadButtonImage( giEditMercImage[0] );
UnloadButtonImage( giEditMercImage[1] );
}
void CreateEditorBuffers()
{
INT32 i;
VSURFACE_DESC vs_desc;
UINT16 usUselessWidth, usUselessHeight;
UINT8 ubBitDepth;
//create buffer for the transition slot for merc items. This slot contains the newly
//selected item graphic in it's inventory size version. This buffer is then scaled down
//into the associated merc inventory panel slot buffer which is approximately 20% smaller.
GetCurrentVideoSettings( &usUselessWidth, &usUselessHeight, &ubBitDepth );
vs_desc.fCreateFlags = VSURFACE_CREATE_DEFAULT | VSURFACE_SYSTEM_MEM_USAGE;
vs_desc.usWidth = 60;
vs_desc.usHeight = 25;
vs_desc.ubBitDepth = ubBitDepth;
if( !AddVideoSurface( &vs_desc, &guiMercTempBuffer ) )
AssertMsg( 0, "Failed to allocate memory for merc tempitem buffer." );
//create the nine buffers for the merc's inventory slots.
vs_desc.usHeight = MERCINV_SLOT_HEIGHT;
for( i = 0; i < 9; i++ )
{
vs_desc.usWidth = i<3 ? MERCINV_SMSLOT_WIDTH : MERCINV_LGSLOT_WIDTH;
if( !AddVideoSurface( &vs_desc, &guiMercInvPanelBuffers[i] ) )
AssertMsg( 0, "Failed to allocate memory for merc item[] buffers." );
}
}
void DeleteEditorBuffers()
{
INT32 i;
DeleteVideoSurfaceFromIndex( guiMercTempBuffer );
for( i = 0; i < 9; i++ )
{
DeleteVideoSurfaceFromIndex( guiMercInvPanelBuffers[ i ] );
}
}
void ShowEditorToolbar( INT32 iNewTaskMode )
{
switch( iNewTaskMode )
{
case TASK_TERRAIN: ShowEditorButtons( FIRST_TERRAIN_BUTTON, LAST_TERRAIN_BUTTON ); break;
case TASK_BUILDINGS: ShowEditorButtons( FIRST_BUILDINGS_BUTTON, LAST_BUILDINGS_BUTTON ); break;
case TASK_ITEMS: ShowEditorButtons( FIRST_ITEMS_BUTTON, LAST_ITEMS_BUTTON ); break;
case TASK_MERCS: ShowEditorButtons( FIRST_MERCS_TEAMMODE_BUTTON, LAST_MERCS_TEAMMODE_BUTTON ); break;
case TASK_MAPINFO: ShowEditorButtons( FIRST_MAPINFO_BUTTON, LAST_MAPINFO_BUTTON ); break;
case TASK_OPTIONS: ShowEditorButtons( FIRST_OPTIONS_BUTTON, LAST_OPTIONS_BUTTON ); break;
default: return;
}
}
void HideEditorToolbar( INT32 iOldTaskMode )
{
INT32 i, iStart, iEnd;
switch( iOldTaskMode )
{
case TASK_TERRAIN: iStart = FIRST_TERRAIN_BUTTON; iEnd = LAST_TERRAIN_BUTTON; break;
case TASK_BUILDINGS: iStart = FIRST_BUILDINGS_BUTTON; iEnd = LAST_BUILDINGS_BUTTON; break;
case TASK_ITEMS: iStart = FIRST_ITEMS_BUTTON; iEnd = LAST_ITEMS_BUTTON; break;
case TASK_MERCS: iStart = FIRST_MERCS_BUTTON; iEnd = LAST_MERCS_BUTTON; break;
case TASK_MAPINFO: iStart = FIRST_MAPINFO_BUTTON; iEnd = LAST_MAPINFO_BUTTON; break;
case TASK_OPTIONS: iStart = FIRST_OPTIONS_BUTTON; iEnd = LAST_OPTIONS_BUTTON; break;
default: return;
}
for( i = iStart; i <= iEnd; i++ )
{
HideButton( iEditorButton[ i ] );
UnclickEditorButton( i );
}
}
void CreateEditorTaskbar()
{
InitEditorRegions();
LoadEditorImages();
CreateEditorBuffers();
CreateEditorTaskbarInternal();
HideItemStatsPanel();
}
void DeleteEditorTaskbar()
{
INT32 x;
iOldTaskMode = iCurrentTaskbar;
for( x = 0; x < NUMBER_EDITOR_BUTTONS; x++ )
RemoveButton( iEditorButton[ x ] );
RemoveEditorRegions();
DeleteEditorImages();
DeleteEditorBuffers();
}
void DoTaskbar(void)
{
if(!iTaskMode || iTaskMode == iCurrentTaskbar )
{
return;
}
gfRenderTaskbar = TRUE;
HideEditorToolbar( iCurrentTaskbar );
//Special code when exiting previous editor tab
switch( iCurrentTaskbar )
{
case TASK_TERRAIN:
UnclickEditorButton( TAB_TERRAIN );
HideTerrainTileButtons();
break;
case TASK_BUILDINGS:
UnclickEditorButton( TAB_BUILDINGS );
KillTextInputMode();
break;
case TASK_ITEMS:
UnclickEditorButton( TAB_ITEMS );
HideItemStatsPanel();
if( eInfo.fActive )
ClearEditorItemsInfo();
gfShowPits = FALSE;
RemoveAllPits();
break;
case TASK_MERCS:
UnclickEditorButton( TAB_MERCS );
IndicateSelectedMerc( SELECT_NO_MERC );
SetMercEditingMode( MERC_NOMODE );
break;
case TASK_MAPINFO:
UnclickEditorButton( TAB_MAPINFO );
ExtractAndUpdateMapInfo();
KillTextInputMode();
HideExitGrids();
break;
case TASK_OPTIONS:
UnclickEditorButton( TAB_OPTIONS );
break;
}
//Setup the new tab mode
iCurrentTaskbar = iTaskMode;
ShowEditorToolbar( iTaskMode );
iTaskMode = TASK_NONE;
//Special code when entering a new editor tab
switch( iCurrentTaskbar )
{
case TASK_MERCS:
ClickEditorButton( TAB_MERCS );
ClickEditorButton( MERCS_ENEMY);
iDrawMode = DRAW_MODE_ENEMY;
SetMercEditingMode( MERC_TEAMMODE );
fBuildingShowRoofs = FALSE;
UpdateRoofsView();
break;
case TASK_TERRAIN:
ClickEditorButton( TAB_TERRAIN );
ShowTerrainTileButtons();
SetEditorTerrainTaskbarMode( TERRAIN_FGROUND_TEXTURES );
break;
case TASK_BUILDINGS:
ClickEditorButton( TAB_BUILDINGS );
if(fBuildingShowRoofs)
ClickEditorButton( BUILDING_TOGGLE_ROOF_VIEW );
if(fBuildingShowWalls)
ClickEditorButton( BUILDING_TOGGLE_WALL_VIEW );
if(fBuildingShowRoomInfo)
ClickEditorButton( BUILDING_TOGGLE_INFO_VIEW );
if( gfCaves )
{
ClickEditorButton( BUILDING_CAVE_DRAWING );
iDrawMode = DRAW_MODE_CAVES;
}
else
{
ClickEditorButton( BUILDING_NEW_ROOM );
iDrawMode = DRAW_MODE_ROOM;
}
TerrainTileDrawMode = TERRAIN_TILES_BRETS_STRANGEMODE;
SetEditorSmoothingMode( gMapInformation.ubEditorSmoothingType );
gusSelectionType = gusSavedBuildingSelectionType;
SetupTextInputForBuildings();
break;
case TASK_ITEMS:
SetFont( FONT10ARIAL );
SetFontForeground( FONT_YELLOW );
ClickEditorButton( TAB_ITEMS );
ClickEditorButton( ITEMS_WEAPONS + eInfo.uiItemType - TBAR_MODE_ITEM_WEAPONS );
InitEditorItemsInfo( eInfo.uiItemType );
ShowItemStatsPanel();
gfShowPits = TRUE;
AddAllPits();
iDrawMode = DRAW_MODE_PLACE_ITEM;
break;
case TASK_MAPINFO:
ClickEditorButton( TAB_MAPINFO );
if ( gfFakeLights )
ClickEditorButton( MAPINFO_TOGGLE_FAKE_LIGHTS );
ClickEditorButton( MAPINFO_ADD_LIGHT1_SOURCE );
iDrawMode = DRAW_MODE_LIGHT;
TerrainTileDrawMode = TERRAIN_TILES_BRETS_STRANGEMODE;
SetupTextInputForMapInfo();
break;
case TASK_OPTIONS:
ClickEditorButton( TAB_OPTIONS );
TerrainTileDrawMode = TERRAIN_TILES_NODRAW;
break;
}
}
//Disables the task bar, but leaves it on screen. Used when a selection window is up.
void DisableEditorTaskbar(void)
{
INT32 x;
for(x = 0; x < NUMBER_EDITOR_BUTTONS; x++ )
DisableButton( iEditorButton[ x ] );
}
void EnableEditorTaskbar(void)
{
INT32 x;
for(x = 0; x < NUMBER_EDITOR_BUTTONS; x++ )
EnableButton( iEditorButton[ x ] );
//Keep permanent buttons disabled.
DisableButton( iEditorButton[ MERCS_1 ] );
DisableButton( iEditorButton[ MAPINFO_LIGHT_PANEL ] );
DisableButton( iEditorButton[ MAPINFO_RADIO_PANEL ] );
DisableButton( iEditorButton[ ITEMSTATS_PANEL ] );
DisableButton( iEditorButton[ MERCS_PLAYERTOGGLE ] );
DisableButton( iEditorButton[ MERCS_PLAYER ] );
if( iCurrentTaskbar == TASK_ITEMS )
DetermineItemsScrolling();
}
//A specialized mprint function that'll restore the editor panel underneath the
//string before rendering the string. This is obviously only useful for drawing text
//in the editor taskbar.
void mprintfEditor(INT16 x, INT16 y, UINT16 *pFontString, ...)
{
va_list argptr;
wchar_t string[512];
UINT16 uiStringLength, uiStringHeight;
Assert( pFontString != NULL );
va_start( argptr, pFontString ); // Set up variable argument pointer
vswprintf( string, pFontString, argptr); // process gprintf string (get output str)
va_end( argptr );
uiStringLength = StringPixLength( string, FontDefault );
uiStringHeight = GetFontHeight( FontDefault );
ClearTaskbarRegion( x, y, (INT16)(x+uiStringLength), (INT16)(y+uiStringHeight) );
mprintf( x, y, string );
}
void ClearTaskbarRegion( INT16 sLeft, INT16 sTop, INT16 sRight, INT16 sBottom )
{
ColorFillVideoSurfaceArea( ButtonDestBuffer, sLeft, sTop, sRight, sBottom, gusEditorTaskbarColor );
if( !sLeft )
{
ColorFillVideoSurfaceArea( ButtonDestBuffer, 0, sTop, 1, sBottom, gusEditorTaskbarHiColor );
sLeft++;
}
if( sTop == 360 )
{
ColorFillVideoSurfaceArea( ButtonDestBuffer, sLeft, 360, sRight, 361, gusEditorTaskbarHiColor );
sTop++;
}
if( sBottom == 480 )
ColorFillVideoSurfaceArea( ButtonDestBuffer, sLeft, 479, sRight, 480, gusEditorTaskbarLoColor );
if( sRight == 640 )
ColorFillVideoSurfaceArea( ButtonDestBuffer, 639, sTop, 640, sBottom, gusEditorTaskbarLoColor );
InvalidateRegion( sLeft, sTop, sRight, sBottom );
}
//Kris:
//This is a new function which duplicates the older "yellow info boxes" that
//are common throughout the editor. This draws the yellow box with the indentation
//look.
void DrawEditorInfoBox( UINT16 *str, UINT32 uiFont, UINT16 x, UINT16 y, UINT16 w, UINT16 h )
{
UINT16 usFillColorDark, usFillColorLight, usFillColorBack;
UINT16 x2, y2;
UINT16 usStrWidth;
x2 = x + w;
y2 = y + h;
usFillColorDark = Get16BPPColor(FROMRGB(24, 61, 81));
usFillColorLight = Get16BPPColor(FROMRGB(136, 138, 135));
usFillColorBack = Get16BPPColor(FROMRGB(250, 240, 188));
ColorFillVideoSurfaceArea(ButtonDestBuffer, x, y, x2, y2, usFillColorDark);
ColorFillVideoSurfaceArea(ButtonDestBuffer, x + 1, y + 1, x2, y2, usFillColorLight);
ColorFillVideoSurfaceArea(ButtonDestBuffer, x + 1, y + 1, x2 - 1, y2 - 1, usFillColorBack);
usStrWidth = StringPixLength( str, uiFont );
if( usStrWidth > w )
{ //the string is too long, so use the wrapped method
y += 1;
DisplayWrappedString( x, y, w, 2, uiFont, FONT_BLACK, str, FONT_BLACK, TRUE, CENTER_JUSTIFIED );
return;
}
//center the string vertically and horizontally.
SetFont( uiFont );
SetFontForeground( FONT_BLACK );
SetFontShadow( FONT_BLACK );
x += (w - (UINT16)StringPixLength( str, uiFont )) / 2;
y += (h - (UINT16)GetFontHeight( uiFont)) / 2;
mprintf( x, y, L"%s", str );
InvalidateRegion( x, y, x2, y2 );
}
void ClickEditorButton( INT32 iEditorButtonID )
{
GUI_BUTTON *butn;
if ( iEditorButtonID < 0 || iEditorButtonID >= NUMBER_EDITOR_BUTTONS )
return;
if ( iEditorButton[ iEditorButtonID ] != -1 )
{
butn = ButtonList[ iEditorButton[ iEditorButtonID ] ];
if( butn )
butn->uiFlags |= BUTTON_CLICKED_ON;
}
}
void UnclickEditorButton( INT32 iEditorButtonID )
{
GUI_BUTTON *butn;
if ( iEditorButtonID < 0 || iEditorButtonID >= NUMBER_EDITOR_BUTTONS )
return;
if ( iEditorButton[ iEditorButtonID ] != -1 )
{
butn = ButtonList[ iEditorButton[ iEditorButtonID ] ];
if( butn )
butn->uiFlags &= (~BUTTON_CLICKED_ON);
}
}
void HideEditorButton( INT32 iEditorButtonID )
{
HideButton( iEditorButton[ iEditorButtonID ] );
}
void ShowEditorButton( INT32 iEditorButtonID )
{
ShowButton( iEditorButton[ iEditorButtonID ] );
}
void DisableEditorButton( INT32 iEditorButtonID )
{
DisableButton( iEditorButton[ iEditorButtonID ] );
}
void EnableEditorButton( INT32 iEditorButtonID )
{
EnableButton( iEditorButton[ iEditorButtonID ] );
}
void ClickEditorButtons( INT32 iFirstEditorButtonID, INT32 iLastEditorButtonID )
{
INT32 i;
GUI_BUTTON *b;
for( i = iFirstEditorButtonID; i <= iLastEditorButtonID; i++ )
{
Assert( iEditorButton[ i ] != -1 );
b = ButtonList[ iEditorButton[ i ] ];
Assert( b );
b->uiFlags |= BUTTON_CLICKED_ON;
}
}
void UnclickEditorButtons( INT32 iFirstEditorButtonID, INT32 iLastEditorButtonID )
{
INT32 i;
GUI_BUTTON *b;
for( i = iFirstEditorButtonID; i <= iLastEditorButtonID; i++ )
{
Assert( iEditorButton[ i ] != -1 );
b = ButtonList[ iEditorButton[ i ] ];
Assert( b );
b->uiFlags &= (~BUTTON_CLICKED_ON);
}
}
void HideEditorButtons( INT32 iFirstEditorButtonID, INT32 iLastEditorButtonID )
{
INT32 i;
for( i = iFirstEditorButtonID; i <= iLastEditorButtonID; i++ )
HideButton( iEditorButton[ i ] );
}
void ShowEditorButtons( INT32 iFirstEditorButtonID, INT32 iLastEditorButtonID )
{
INT32 i;
for( i = iFirstEditorButtonID; i <= iLastEditorButtonID; i++ )
ShowButton( iEditorButton[ i ] );
}
void DisableEditorButtons( INT32 iFirstEditorButtonID, INT32 iLastEditorButtonID )
{
INT32 i;
for( i = iFirstEditorButtonID; i <= iLastEditorButtonID; i++ )
DisableButton( iEditorButton[ i ] );
}
void EnableEditorButtons( INT32 iFirstEditorButtonID, INT32 iLastEditorButtonID )
{
INT32 i;
for( i = iFirstEditorButtonID; i <= iLastEditorButtonID; i++ )
EnableButton( iEditorButton[ i ] );
}
void RenderMapEntryPointsAndLights()
{
INT16 sGridNo;
INT16 sScreenX, sScreenY;
INT32 i;
if( gfSummaryWindowActive )
return;
SetFont( FONT10ARIAL );
SetFontForeground( FONT_YELLOW );
SetFontShadow( FONT_NEARBLACK );
sGridNo = gMapInformation.sNorthGridNo;
if( sGridNo != -1 )
{
GetGridNoScreenPos( sGridNo, 0, &sScreenX, &sScreenY );
if( sScreenY >= -20 && sScreenY < 340 && sScreenX >= -40 && sScreenX < 640 )
{
DisplayWrappedString( sScreenX, (INT16)(sScreenY-5), 40, 2, FONT10ARIAL, FONT_YELLOW, L"North Entry Point", FONT_BLACK, TRUE, CENTER_JUSTIFIED );
}
}
sGridNo = gMapInformation.sWestGridNo;
if( sGridNo != -1 )
{
GetGridNoScreenPos( sGridNo, 0, &sScreenX, &sScreenY );
if( sScreenY >= -20 && sScreenY < 340 && sScreenX >= -40 && sScreenX < 640 )
{
DisplayWrappedString( sScreenX, (INT16)(sScreenY-5), 40, 2, FONT10ARIAL, FONT_YELLOW, L"West Entry Point", FONT_BLACK, TRUE, CENTER_JUSTIFIED );
}
}
sGridNo = gMapInformation.sEastGridNo;
if( sGridNo != -1 )
{
GetGridNoScreenPos( sGridNo, 0, &sScreenX, &sScreenY );
if( sScreenY >= -20 && sScreenY < 340 && sScreenX >= -40 && sScreenX < 640 )
{
DisplayWrappedString( sScreenX, (INT16)(sScreenY-5), 40, 2, FONT10ARIAL, FONT_YELLOW, L"East Entry Point", FONT_BLACK, TRUE, CENTER_JUSTIFIED );
}
}
sGridNo = gMapInformation.sSouthGridNo;
if( sGridNo != -1 )
{
GetGridNoScreenPos( sGridNo, 0, &sScreenX, &sScreenY );
if( sScreenY >= -20 && sScreenY < 340 && sScreenX >= -40 && sScreenX < 640 )
{
DisplayWrappedString( sScreenX, (INT16)(sScreenY-5), 40, 2, FONT10ARIAL, FONT_YELLOW, L"South Entry Point", FONT_BLACK, TRUE, CENTER_JUSTIFIED );
}
}
sGridNo = gMapInformation.sCenterGridNo;
if( sGridNo != -1 )
{
GetGridNoScreenPos( sGridNo, 0, &sScreenX, &sScreenY );
if( sScreenY >= -20 && sScreenY < 340 && sScreenX >= -40 && sScreenX < 640 )
{
DisplayWrappedString( sScreenX, (INT16)(sScreenY-5), 40, 2, FONT10ARIAL, FONT_YELLOW, L"Center Entry Point", FONT_BLACK, TRUE, CENTER_JUSTIFIED );
}
}
sGridNo = gMapInformation.sIsolatedGridNo;
if( sGridNo != -1 )
{
GetGridNoScreenPos( sGridNo, 0, &sScreenX, &sScreenY );
if( sScreenY >= -20 && sScreenY < 340 && sScreenX >= -40 && sScreenX < 640 )
{
DisplayWrappedString( sScreenX, (INT16)(sScreenY-5), 40, 2, FONT10ARIAL, FONT_YELLOW, L"Isolated Entry Point", FONT_BLACK, TRUE, CENTER_JUSTIFIED );
}
}
//Do the lights now.
for( i = 0; i < MAX_LIGHT_SPRITES; i++ )
{
if( LightSprites[ i ].uiFlags & LIGHT_SPR_ACTIVE )
{
sGridNo = LightSprites[ i ].iY * WORLD_COLS + LightSprites[ i ].iX;
GetGridNoScreenPos( sGridNo, 0, &sScreenX, &sScreenY );
if( sScreenY >= -50 && sScreenY < 300 && sScreenX >= -40 && sScreenX < 640 )
{
if( LightSprites[ i ].uiFlags & LIGHT_PRIMETIME )
DisplayWrappedString( sScreenX, (INT16)(sScreenY-5), 50, 2, FONT10ARIAL, FONT_ORANGE, L"Prime", FONT_BLACK, TRUE, CENTER_JUSTIFIED );
else if( LightSprites[ i ].uiFlags & LIGHT_NIGHTTIME )
DisplayWrappedString( sScreenX, (INT16)(sScreenY-5), 50, 2, FONT10ARIAL, FONT_RED, L"Night", FONT_BLACK, TRUE, CENTER_JUSTIFIED );
else
DisplayWrappedString( sScreenX, (INT16)(sScreenY-5), 50, 2, FONT10ARIAL, FONT_YELLOW, L"24Hour", FONT_BLACK, TRUE, CENTER_JUSTIFIED );
}
}
}
}
void BuildTriggerName( OBJECTTYPE *pItem, UINT16 *szItemName )
{
if( pItem->usItem == SWITCH )
{
if( pItem->bFrequency == PANIC_FREQUENCY )
swprintf( szItemName, L"Panic Trigger1" );
else if( pItem->bFrequency == PANIC_FREQUENCY_2 )
swprintf( szItemName, L"Panic Trigger2" );
else if( pItem->bFrequency == PANIC_FREQUENCY_3 )
swprintf( szItemName, L"Panic Trigger3" );
else
swprintf( szItemName, L"Trigger%d", pItem->bFrequency - 50 );
}
else
{ //action item
if( pItem->bDetonatorType == BOMB_PRESSURE )
swprintf( szItemName, L"Pressure Action" );
else if( pItem->bFrequency == PANIC_FREQUENCY )
swprintf( szItemName, L"Panic Action1" );
else if( pItem->bFrequency == PANIC_FREQUENCY_2 )
swprintf( szItemName, L"Panic Action2" );
else if( pItem->bFrequency == PANIC_FREQUENCY_3 )
swprintf( szItemName, L"Panic Action3" );
else
swprintf( szItemName, L"Action%d", pItem->bFrequency - 50 );
}
}
void RenderDoorLockInfo()
{
INT16 i, xp, yp;
INT16 sScreenX, sScreenY;
UINT16 str[ 50 ];
for( i = 0; i < gubNumDoors; i++ )
{
GetGridNoScreenPos( DoorTable[ i ].sGridNo, 0, &sScreenX, &sScreenY );
if( sScreenY > 390 )
continue;
if( DoorTable[ i ].ubLockID != 255 )
swprintf( str, L"%S", LockTable[ DoorTable[ i ].ubLockID ].ubEditorName );
else
swprintf( str, L"No Lock ID" );
xp = sScreenX - 10;
yp = sScreenY - 40;
DisplayWrappedString( xp, yp, 60, 2, FONT10ARIAL, FONT_LTKHAKI, str, FONT_BLACK, TRUE, CENTER_JUSTIFIED );
if( DoorTable[ i ].ubTrapID )
{
SetFont( FONT10ARIAL );
SetFontForeground( FONT_RED );
SetFontShadow( FONT_NEARBLACK );
switch( DoorTable[ i ].ubTrapID )
{
case EXPLOSION:
swprintf( str, L"Explosion Trap" );
break;
case ELECTRIC:
swprintf( str, L"Electric Trap" );
break;
case SIREN:
swprintf( str, L"Siren Trap" );
break;
case SILENT_ALARM:
swprintf( str, L"Silent Alarm" );
break;
case SUPER_ELECTRIC:
swprintf( str, L"Super Electric Trap" );
break;
}
xp = sScreenX + 20 - StringPixLength( str, FONT10ARIAL ) / 2;
yp = sScreenY;
mprintf( xp, yp, str );
swprintf( str, L"Trap Level %d", DoorTable[ i ].ubTrapLevel );
xp = sScreenX + 20 - StringPixLength( str, FONT10ARIAL ) / 2;
mprintf( xp, yp+10, str );
}
}
}
void RenderSelectedItemBlownUp()
{
UINT32 uiVideoObjectIndex;
HVOBJECT hVObject;
INT16 sScreenX, sScreenY, xp, yp;
ITEM_POOL *pItemPool;
UINT16 szItemName[ SIZE_ITEM_NAME ];
INT32 i;
INT16 sWidth, sHeight, sOffsetX, sOffsetY;
GetGridNoScreenPos( gsItemGridNo, 0, &sScreenX, &sScreenY );
if( sScreenY > 340 )
return;
//Display the enlarged item graphic
uiVideoObjectIndex = GetInterfaceGraphicForItem( &Item[ gpItem->usItem ] );
GetVideoObject( &hVObject, uiVideoObjectIndex );
sWidth = hVObject->pETRLEObject[ Item[ gpItem->usItem ].ubGraphicNum ].usWidth;
sOffsetX = hVObject->pETRLEObject[ Item[ gpItem->usItem ].ubGraphicNum ].sOffsetX;
xp = sScreenX + (40 - sWidth - sOffsetX*2) / 2;
sHeight = hVObject->pETRLEObject[ Item[ gpItem->usItem ].ubGraphicNum ].usHeight;
sOffsetY = hVObject->pETRLEObject[ Item[ gpItem->usItem ].ubGraphicNum ].sOffsetY;
yp = sScreenY + (20 - sHeight - sOffsetY*2) / 2;
BltVideoObjectOutlineFromIndex( FRAME_BUFFER, uiVideoObjectIndex, Item[ gpItem->usItem ].ubGraphicNum, xp, yp, Get16BPPColor(FROMRGB(0, 140, 170)), TRUE );
//Display the item name above it
SetFont( FONT10ARIAL );
SetFontForeground( FONT_YELLOW );
SetFontShadow( FONT_NEARBLACK );
if( gpItem->usItem == ACTION_ITEM || gpItem->usItem == SWITCH )
{
BuildTriggerName( gpItem, szItemName );
}
else if( Item[ gpItem->usItem ].usItemClass == IC_KEY )
{
swprintf( szItemName, L"%S", LockTable[ gpItem->ubKeyID ].ubEditorName );
}
else
{
LoadItemInfo( gpItem->usItem, szItemName, NULL );
}
xp = sScreenX - (StringPixLength( szItemName, FONT10ARIAL ) - 40) / 2;
yp -= 10;
mprintf( xp, yp, szItemName );
if( gpItem->usItem == ACTION_ITEM )
{
UINT16 *pStr;
pStr = GetActionItemName( gpItem );
xp = sScreenX - (StringPixLength( pStr, FONT10ARIALBOLD ) - 40) / 2;
yp += 10;
SetFont( FONT10ARIALBOLD );
SetFontForeground( FONT_LTKHAKI );
mprintf( xp, yp, pStr );
SetFontForeground( FONT_YELLOW );
}
//Count the number of items in the current pool, and display that.
i = 0;
GetItemPool( gsItemGridNo, &pItemPool, 0 );
Assert( pItemPool );
while( pItemPool )
{
i++;
pItemPool = pItemPool->pNext;
}
xp = sScreenX;
yp = sScreenY + 10;
mprintf( xp, yp, L"%d", i );
//If the item is hidden, render a blinking H (just like DG)
if( gWorldItems[ gpItemPool->iItemIndex ].bVisible == HIDDEN_ITEM ||
gWorldItems[ gpItemPool->iItemIndex ].bVisible == BURIED )
{
SetFont( FONT10ARIALBOLD );
if( GetJA2Clock() % 1000 > 500 )
{
SetFontForeground( 249 );
}
mprintf( sScreenX + 16, sScreenY + 7, L"H" );
InvalidateRegion( sScreenX + 16, sScreenY + 7, sScreenX + 24, sScreenY + 27 );
}
}
void RenderEditorInfo( )
{
wchar_t FPSText[ 50 ];
static INT32 iSpewWarning = 0;
INT16 iMapIndex;
SetFont( FONT12POINT1 );
SetFontForeground( FONT_BLACK );
SetFontBackground( FONT_BLACK );
//Display the mapindex position
if( GetMouseMapPos( &iMapIndex ) )
swprintf( FPSText, L" (%d) ", iMapIndex );
else
swprintf( FPSText, L" " );
mprintfEditor( (UINT16)(50-StringPixLength( FPSText, FONT12POINT1 )/2), 463, FPSText );
switch( iCurrentTaskbar )
{
case TASK_OPTIONS:
if( !gfWorldLoaded || giCurrentTilesetID < 0 )
mprintf( 260, 445, L"No map currently loaded." );
else
mprintf( 260, 445, L"File: %S, Current Tileset: %s",
gubFilename, gTilesets[ giCurrentTilesetID ].zName );
break;
case TASK_TERRAIN:
if( gusSelectionType == LINESELECTION )
swprintf( wszSelType[LINESELECTION], L"Width: %d", gusSelectionWidth );
DrawEditorInfoBox( wszSelType[gusSelectionType], FONT12POINT1, 220, 430, 60, 30 );
swprintf( FPSText, L"%d%%", gusSelectionDensity );
DrawEditorInfoBox( FPSText, FONT12POINT1, 310, 430, 40, 30 );
break;
case TASK_ITEMS:
RenderEditorItemsInfo();
UpdateItemStatsPanel();
break;
case TASK_BUILDINGS:
UpdateBuildingsInfo();
if( gusSelectionType == LINESELECTION )
swprintf( wszSelType[LINESELECTION], L"Width: %d", gusSelectionWidth );
DrawEditorInfoBox( wszSelType[gusSelectionType], FONT12POINT1, 530, 430, 60, 30 );
break;
case TASK_MERCS:
UpdateMercsInfo();
break;
case TASK_MAPINFO:
UpdateMapInfo();
if( gusSelectionType == LINESELECTION )
swprintf( wszSelType[LINESELECTION], L"Width: %d", gusSelectionWidth );
DrawEditorInfoBox( wszSelType[gusSelectionType], FONT12POINT1, 440, 430, 60, 30 );
break;
}
}
//This is in ButtonSystem.c as a hack. Because we need to save the buffer whenever we do a full
//taskbar render, we need to draw the buttons without hilites, hence this flag. This flag is
//always true in ButtonSystem.c, so it won't effect anything else.
extern BOOLEAN gfGotoGridNoUI;
void ProcessEditorRendering()
{
BOOLEAN fSaveBuffer = FALSE;
if( gfRenderTaskbar ) //do a full taskbar render.
{
ClearTaskbarRegion( 0, 360, 640, 480 );
RenderTerrainTileButtons();
MarkButtonsDirty();
gfRenderTaskbar = FALSE;
fSaveBuffer = TRUE;
gfRenderDrawingMode = TRUE;
gfRenderHilights = FALSE;
gfRenderMercInfo = TRUE;
}
if( gfRenderDrawingMode )
{
if( iCurrentTaskbar == TASK_BUILDINGS || iCurrentTaskbar == TASK_TERRAIN || iCurrentTaskbar == TASK_ITEMS )
{
ShowCurrentDrawingMode();
gfRenderDrawingMode = FALSE;
}
}
//render dynamically changed buttons only
RenderButtons( );
if( gfSummaryWindowActive )
RenderSummaryWindow();
else if( !gfGotoGridNoUI && !InOverheadMap() )
RenderMercStrings();
if( gfEditingDoor )
RenderDoorEditingWindow();
if( TextInputMode() )
RenderAllTextFields();
RenderEditorInfo();
if( !gfSummaryWindowActive && !gfGotoGridNoUI && !InOverheadMap() )
{
if( gpItem && gsItemGridNo != -1 )
RenderSelectedItemBlownUp();
if( iCurrentTaskbar == TASK_MAPINFO )
RenderMapEntryPointsAndLights();
if( iDrawMode == DRAW_MODE_PLACE_ITEM && eInfo.uiItemType == TBAR_MODE_ITEM_KEYS ||
iDrawMode == DRAW_MODE_DOORKEYS )
RenderDoorLockInfo();
}
if( fSaveBuffer )
BlitBufferToBuffer( FRAME_BUFFER, guiSAVEBUFFER, 0, 360, 640, 120 );
//Make sure this is TRUE at all times.
//It is set to false when before we save the buffer, so the buttons don't get
//rendered with hilites, in case the mouse is over one.
gfRenderHilights = TRUE;
RenderButtonsFastHelp();
}
#endif
+70
View File
@@ -0,0 +1,70 @@
#include "BuildDefines.h"
#ifdef JA2EDITOR
#ifndef __EDITOR_TASKBAR_UTILS_H
#define __EDITOR_TASKBAR_UTILS_H
//These are utilities that are used within the editor. This function absorbs the expensive
//compile time of the SGP dependencies, while allowing the other editor files to hook into it
//without paying, so to speak.
enum
{
GUI_CLEAR_EVENT,
GUI_LCLICK_EVENT,
GUI_RCLICK_EVENT,
GUI_MOVE_EVENT
};
//Taskbar manipulation functions
void DoTaskbar(void);
void ProcessEditorRendering();
void EnableEditorTaskbar();
void DisableEditorTaskbar();
void CreateEditorTaskbar();
void DeleteEditorTaskbar();
//Button manipulation functions
void ClickEditorButton( INT32 iEditorButtonID );
void UnclickEditorButton( INT32 iEditorButtonID );
void HideEditorButton( INT32 iEditorButtonID );
void ShowEditorButton( INT32 iEditorButtonID );
void DisableEditorButton( INT32 iEditorButtonID );
void EnableEditorButton( INT32 iEditorButtonID );
void ClickEditorButtons( INT32 iFirstEditorButtonID, INT32 iLastEditorButtonID );
void UnclickEditorButtons( INT32 iFirstEditorButtonID, INT32 iLastEditorButtonID );
void HideEditorButtons( INT32 iFirstEditorButtonID, INT32 iLastEditorButtonID );
void ShowEditorButtons( INT32 iFirstEditorButtonID, INT32 iLastEditorButtonID );
void DisableEditorButtons( INT32 iFirstEditorButtonID, INT32 iLastEditorButtonID );
void EnableEditorButtons( INT32 iFirstEditorButtonID, INT32 iLastEditorButtonID );
//Region Utils
#define NUM_TERRAIN_TILE_REGIONS 9
enum{
BASE_TERRAIN_TILE_REGION_ID,
ITEM_REGION_ID = NUM_TERRAIN_TILE_REGIONS,
MERC_REGION_ID,
};
void EnableEditorRegion( INT8 bRegionID );
void DisableEditorRegion( INT8 bRegionID );
//Rendering Utils
void mprintfEditor(INT16 x, INT16 y, UINT16 *pFontString, ...);
void ClearTaskbarRegion( INT16 sLeft, INT16 sTop, INT16 sRight, INT16 sBottom );
void DrawEditorInfoBox( UINT16 *str, UINT32 uiFont, UINT16 x, UINT16 y, UINT16 w, UINT16 h );
extern INT32 giEditMercDirectionIcons[2];
extern UINT32 guiMercInventoryPanel;
extern UINT32 guiOmertaMap;
extern UINT32 guiExclamation;
extern UINT32 guiKeyImage;
extern UINT32 guiMercInvPanelBuffers[9];
extern UINT32 guiMercTempBuffer;
extern INT32 giEditMercImage[2];
#endif
#endif
+999
View File
@@ -0,0 +1,999 @@
#ifdef PRECOMPILEDHEADERS
#include "Editor All.h"
#else
#include "builddefines.h"
#endif
#ifdef JA2EDITOR
#ifndef PRECOMPILEDHEADERS
#include "worlddef.h"
#include "worldman.h"
#include "smooth.h"
#include "input.h"
#include "debug.h"
#include "Isometric Utils.h"
#include "editscreen.h"
#include "Editor Undo.h"
#include "Render Fun.h" //for access to gubWorldRoomInfo;
#include "Cursor Modes.h"
#include "Exit Grids.h"
#endif
/*
Kris -- Notes on how the undo code works:
At the bottom of the hierarchy, we need to determine the state of the undo command. The idea
is that we want to separate undo commands by separating them by new mouse clicks. By holding a mouse
down and painting various objects in the world would all constitute a single undo command. As soon as
the mouse is release, then a new undo command is setup. So, to automate this, there is a call every
frame to DetermineUndoState().
At the next level, there is a binary tree that keeps track of what map indices have been backup up in
the current undo command. The whole reason to maintain this list, is to avoid multiple map elements of
the same map index from being saved. In the outer code, everytime something is changed, a call to
AddToUndoList() is called, so there are many cases (especially with building/terrain smoothing) that the
same mapindex is added to the undo list. This is also completely transparent, and doesn't need to be
maintained.
In the outer code, there are several calls to AddToUndoList( iMapIndex ). This function basically looks
in the binary tree for an existing entry, and if there isn't, then the entire mapelement is saved (with
the exception of the merc level ). Lights are also supported, but there is a totally different methodology
for accomplishing this. The equivalent function is AddLightToUndoList( iMapIndex ). In this case, only the
light is saved, along with internal maintanance of several flags.
The actual mapelement copy code, is very complex. The mapelement is copied in parallel with a new one which
has to allocate several nodes of several types because a mapelement contains over a dozen separate lists, and
all of them need to be saved. The structure information of certain mapelements may be multitiled and must
also save the affected gridno's as well. This is also done internally. Basically, your call to
AddToUndoList() for any particular gridno, may actually save several entries (like for a car which could be 6+
tiles)
MERCS
Mercs are not supported in the undo code. Because they are so dynamic, and stats could change, they could
move, etc., it doesn't need to be in the undo code. The editor has its own way of dealing with mercs which
doesn't use the undo methodology.
*/
BOOLEAN gfUndoEnabled = FALSE;
void EnableUndo()
{
gfUndoEnabled = TRUE;
}
void DisableUndo()
{
gfUndoEnabled = FALSE;
}
// undo node data element
typedef struct
{
INT32 iMapIndex;
MAP_ELEMENT *pMapTile;
BOOLEAN fLightSaved; //determines that a light has been saved
UINT8 ubLightRadius; //the radius of the light to build if undo is called
UINT8 ubLightID; //only applies if a light was saved.
UINT8 ubRoomNum;
} undo_struct;
// Undo stack node
typedef struct TAG_undo_stack
{
INT32 iCmdCount;
undo_struct *pData;
struct TAG_undo_stack *pNext;
INT32 iUndoType;
} undo_stack;
undo_stack *gpTileUndoStack = NULL;
// Map tile element manipulation functions
BOOLEAN CopyMapElementFromWorld( MAP_ELEMENT *pMapTile, INT32 iMapIndex );
BOOLEAN SwapMapElementWithWorld( INT32 iDestMapTileIndex, MAP_ELEMENT *pMapTile );
// Undo structure functions
BOOLEAN DeleteTopStackNode( void );
undo_stack *DeleteThisStackNode( undo_stack *pThisNode );
BOOLEAN DeleteStackNodeContents( undo_stack *pCurrent );
BOOLEAN AddToUndoListCmd( INT32 iMapIndex, INT32 iCmdCount );
void CropStackToMaxLength( INT32 iMaxCmds );
void SmoothUndoMapTileTerrain( INT32 iWorldTile, MAP_ELEMENT *pUndoTile );
BOOLEAN fNewUndoCmd = TRUE;
BOOLEAN gfIgnoreUndoCmdsForLights = FALSE;
//New pre-undo binary tree stuff
//With this, new undo commands will not duplicate saves in the same command. This will
//increase speed, and save memory.
typedef struct MapIndexBinaryTree
{
struct MapIndexBinaryTree *left, *right;
UINT16 usMapIndex;
}MapIndexBinaryTree;
MapIndexBinaryTree *top = NULL;
void ClearUndoMapIndexTree();
BOOLEAN AddMapIndexToTree( UINT16 usMapIndex );
void CheckMapIndexForMultiTileStructures( UINT16 usMapIndex );
void CheckForMultiTilesInTreeAndAddToUndoList( MapIndexBinaryTree *node );
//Recursively deletes all nodes below the node passed including itself.
void DeleteTreeNode( MapIndexBinaryTree **node )
{
if( (*node)->left )
DeleteTreeNode( &((*node)->left) );
if( (*node)->right )
DeleteTreeNode( &((*node)->right) );
MemFree( *node );
*node = NULL;
}
//Recursively delete all nodes (from the top down).
void ClearUndoMapIndexTree()
{
if( top )
DeleteTreeNode( &top );
}
BOOLEAN AddMapIndexToTree( UINT16 usMapIndex )
{
MapIndexBinaryTree *curr, *parent;
if( !top )
{
top = (MapIndexBinaryTree*)MemAlloc( sizeof( MapIndexBinaryTree ) );
Assert( top );
top->usMapIndex = usMapIndex;
top->left = NULL;
top->right = NULL;
return TRUE;
}
curr = top;
parent = NULL;
//Traverse down the tree and attempt to find a matching mapindex.
//If one is encountered, then we fail, and don't add the mapindex to the
//tree.
while( curr )
{
parent = curr;
if( curr->usMapIndex == usMapIndex ) //found a match, so stop
return FALSE;
//if the mapIndex is < node's mapIndex, then go left, else right
curr = ( usMapIndex < curr->usMapIndex ) ? curr->left : curr->right;
}
//if we made it this far, then curr is null and parent is pointing
//directly above.
//Create the new node and fill in the information.
curr = (MapIndexBinaryTree*)MemAlloc( sizeof( MapIndexBinaryTree ) );
Assert( curr );
curr->usMapIndex = usMapIndex;
curr->left = NULL;
curr->right = NULL;
//Now link the new node to the parent.
if( curr->usMapIndex < parent->usMapIndex )
parent->left = curr;
else
parent->right = curr;
return TRUE;
}
//*************************************************************************
//
// Start of Undo code
//
//*************************************************************************
BOOLEAN DeleteTopStackNode( void )
{
undo_stack *pCurrent;
pCurrent = gpTileUndoStack;
DeleteStackNodeContents( pCurrent );
// Remove node from stack, and free it's memory
gpTileUndoStack = gpTileUndoStack->pNext;
MemFree( pCurrent );
return( TRUE );
}
undo_stack *DeleteThisStackNode( undo_stack *pThisNode )
{
undo_stack *pCurrent;
undo_stack *pNextNode;
pCurrent = pThisNode;
pNextNode = pThisNode->pNext;
// Remove node from stack, and free it's memory
DeleteStackNodeContents( pCurrent );
MemFree( pCurrent );
return( pNextNode );
}
BOOLEAN DeleteStackNodeContents( undo_stack *pCurrent )
{
undo_struct *pData;
MAP_ELEMENT *pMapTile;
LEVELNODE *pLandNode;
LEVELNODE *pObjectNode;
LEVELNODE *pStructNode;
LEVELNODE *pShadowNode;
LEVELNODE *pMercNode;
LEVELNODE *pTopmostNode;
LEVELNODE *pRoofNode;
LEVELNODE *pOnRoofNode;
STRUCTURE *pStructureNode;
pData = pCurrent->pData;
pMapTile = pData->pMapTile;
if( !pMapTile )
return TRUE; //light was saved -- mapelement wasn't saved.
// Free the memory associated with the map tile liked lists
pLandNode = pMapTile->pLandHead;
while ( pLandNode != NULL )
{
pMapTile->pLandHead = pLandNode->pNext;
MemFree( pLandNode );
pLandNode = pMapTile->pLandHead;
}
pObjectNode = pMapTile->pObjectHead;
while ( pObjectNode != NULL )
{
pMapTile->pObjectHead = pObjectNode->pNext;
MemFree( pObjectNode );
pObjectNode = pMapTile->pObjectHead;
}
pStructNode = pMapTile->pStructHead;
while ( pStructNode != NULL )
{
pMapTile->pStructHead = pStructNode->pNext;
MemFree( pStructNode );
pStructNode = pMapTile->pStructHead;
}
pShadowNode = pMapTile->pShadowHead;
while ( pShadowNode != NULL )
{
pMapTile->pShadowHead = pShadowNode->pNext;
MemFree( pShadowNode );
pShadowNode = pMapTile->pShadowHead;
}
pMercNode = pMapTile->pMercHead;
while ( pMercNode != NULL )
{
pMapTile->pMercHead = pMercNode->pNext;
MemFree( pMercNode );
pMercNode = pMapTile->pMercHead;
}
pRoofNode = pMapTile->pRoofHead;
while ( pRoofNode != NULL )
{
pMapTile->pRoofHead = pRoofNode->pNext;
MemFree( pRoofNode );
pRoofNode = pMapTile->pRoofHead;
}
pOnRoofNode = pMapTile->pOnRoofHead;
while ( pOnRoofNode != NULL )
{
pMapTile->pOnRoofHead = pOnRoofNode->pNext;
MemFree( pOnRoofNode );
pOnRoofNode = pMapTile->pOnRoofHead;
}
pTopmostNode = pMapTile->pTopmostHead;
while ( pTopmostNode != NULL )
{
pMapTile->pTopmostHead = pTopmostNode->pNext;
MemFree( pTopmostNode );
pTopmostNode = pMapTile->pTopmostHead;
}
pStructureNode = pMapTile->pStructureHead;
while( pStructureNode )
{
pMapTile->pStructureHead = pStructureNode->pNext;
if( pStructureNode->usStructureID > INVALID_STRUCTURE_ID )
{ //Okay to delete the structure data -- otherwise, this would be
//merc structure data that we DON'T want to delete, because the merc node
//that hasn't been modified will still use this structure data!
MemFree( pStructureNode );
}
pStructureNode = pMapTile->pStructureHead;
}
// Free the map tile structure itself
MemFree( pMapTile );
// Free the undo struct
MemFree( pData );
return( TRUE );
}
void CropStackToMaxLength( INT32 iMaxCmds )
{
INT32 iCmdCount;
undo_stack *pCurrent;
iCmdCount = 0;
pCurrent = gpTileUndoStack;
// If stack is empty, leave
if ( pCurrent == NULL )
return;
while ( (iCmdCount <= (iMaxCmds - 1)) && (pCurrent != NULL) )
{
if ( pCurrent->iCmdCount == 1 )
iCmdCount++;
pCurrent = pCurrent->pNext;
}
// If the max number of commands was reached, and there is something
// to crop, from the rest of the stack, remove it.
if ( (iCmdCount >= iMaxCmds) && pCurrent != NULL )
{
while ( pCurrent->pNext != NULL )
pCurrent->pNext = DeleteThisStackNode( pCurrent->pNext );
}
}
//We are adding a light to the undo list. We won't save the mapelement, nor will
//we validate the gridno in the binary tree. This works differently than a mapelement,
//because lights work on a different system. By setting the fLightSaved flag to TRUE,
//this will handle the way the undo command is handled. If there is no lightradius in
//our saved light, then we intend on erasing the light upon undo execution, otherwise, we
//save the light radius and light ID, so that we place it during undo execution.
void AddLightToUndoList( INT32 iMapIndex, INT32 iLightRadius, UINT8 ubLightID )
{
undo_stack *pNode;
undo_struct *pUndoInfo;
if( !gfUndoEnabled )
return;
//When executing an undo command (by adding a light or removing one), that command
//actually tries to add it to the undo list. So we wrap the execution of the undo
//command by temporarily setting this flag, so it'll ignore, and not place a new undo
//command. When finished, the flag is cleared, and lights are again allowed to be saved
//in the undo list.
if( gfIgnoreUndoCmdsForLights )
return;
pNode = (undo_stack*)MemAlloc( sizeof( undo_stack ) );
if( !pNode )
return;
pUndoInfo = (undo_struct *)MemAlloc( sizeof( undo_struct ) );
if( !pUndoInfo )
{
MemFree( pNode );
return;
}
pUndoInfo->fLightSaved = TRUE;
//if ubLightRadius is 0, then we don't need to save the light information because we
//will erase it when it comes time to execute the undo command.
pUndoInfo->ubLightRadius = (UINT8)iLightRadius;
pUndoInfo->ubLightID = ubLightID;
pUndoInfo->iMapIndex = iMapIndex;
pUndoInfo->pMapTile = NULL;
//Add to undo stack
pNode->iCmdCount = 1;
pNode->pData = pUndoInfo;
pNode->pNext = gpTileUndoStack;
gpTileUndoStack = pNode;
CropStackToMaxLength( MAX_UNDO_COMMAND_LENGTH );
}
BOOLEAN AddToUndoList( INT32 iMapIndex )
{
static INT32 iCount = 1;
if( !gfUndoEnabled )
return FALSE;
if ( fNewUndoCmd )
{
iCount = 0;
fNewUndoCmd = FALSE;
}
//Check to see if the tile in question is even on the visible map, then
//if that is true, then check to make sure we don't already have the mapindex
//saved in the new binary tree (which only holds unique mapindex values).
if( GridNoOnVisibleWorldTile( (INT16)iMapIndex ) && AddMapIndexToTree( (UINT16)iMapIndex ) )
{
if( AddToUndoListCmd( iMapIndex, ++iCount ) )
return TRUE;
iCount--;
}
return FALSE;
}
BOOLEAN AddToUndoListCmd( INT32 iMapIndex, INT32 iCmdCount )
{
undo_stack *pNode;
undo_struct *pUndoInfo;
MAP_ELEMENT *pData;
STRUCTURE *pStructure;
INT32 iCoveredMapIndex;
UINT8 ubLoop;
if ( (pNode = (undo_stack *)MemAlloc(sizeof( undo_stack )) ) == NULL )
{
return( FALSE );
}
if ( (pUndoInfo = (undo_struct *)MemAlloc(sizeof( undo_struct )) ) == NULL )
{
MemFree( pNode );
return( FALSE );
}
if ( (pData = (MAP_ELEMENT *)MemAlloc(sizeof( MAP_ELEMENT )) ) == NULL )
{
MemFree( pNode );
MemFree( pUndoInfo );
return( FALSE );
}
// Init map element struct
pData->pLandHead = pData->pLandStart = NULL;
pData->pObjectHead = NULL;
pData->pStructHead = NULL;
pData->pShadowHead = NULL;
pData->pMercHead = NULL;
pData->pRoofHead = NULL;
pData->pOnRoofHead = NULL;
pData->pTopmostHead = NULL;
pData->pStructureHead = pData->pStructureTail = NULL;
pData->sHeight = 0;
// Copy the world map's tile
if ( CopyMapElementFromWorld( pData, iMapIndex ) == FALSE )
{
MemFree( pNode );
MemFree( pUndoInfo );
MemFree( pData );
return( FALSE );
}
// copy the room number information (it's not in the mapelement structure)
pUndoInfo->ubRoomNum = gubWorldRoomInfo[ iMapIndex ];
pUndoInfo->fLightSaved = FALSE;
pUndoInfo->ubLightRadius = 0;
pUndoInfo->ubLightID = 0;
pUndoInfo->pMapTile = pData;
pUndoInfo->iMapIndex = iMapIndex;
pNode->pData = pUndoInfo;
pNode->iCmdCount = iCmdCount;
pNode->pNext = gpTileUndoStack;
gpTileUndoStack = pNode;
// loop through pData->pStructureHead list
// for each structure
// find the base tile
// reference the db structure
// if number of tiles > 1
// add all covered tiles to undo list
pStructure = pData->pStructureHead;
while (pStructure)
{
for (ubLoop = 1; ubLoop < pStructure->pDBStructureRef->pDBStructure->ubNumberOfTiles; ubLoop++)
{
// this loop won't execute for single-tile structures; for multi-tile structures, we have to
// add to the undo list all the other tiles covered by the structure
iCoveredMapIndex = pStructure->sBaseGridNo + pStructure->pDBStructureRef->ppTile[ubLoop]->sPosRelToBase;
AddToUndoList( iCoveredMapIndex );
}
pStructure = pStructure->pNext;
}
CropStackToMaxLength( MAX_UNDO_COMMAND_LENGTH );
return( TRUE );
}
void CheckMapIndexForMultiTileStructures( UINT16 usMapIndex )
{
STRUCTURE * pStructure;
UINT8 ubLoop;
INT32 iCoveredMapIndex;
pStructure = gpWorldLevelData[usMapIndex].pStructureHead;
while (pStructure)
{
if (pStructure->pDBStructureRef->pDBStructure->ubNumberOfTiles > 1)
{
for (ubLoop = 0; ubLoop < pStructure->pDBStructureRef->pDBStructure->ubNumberOfTiles; ubLoop++)
{
// for multi-tile structures we have to add, to the undo list, all the other tiles covered by the structure
if (pStructure->fFlags & STRUCTURE_BASE_TILE)
{
iCoveredMapIndex = usMapIndex + pStructure->pDBStructureRef->ppTile[ubLoop]->sPosRelToBase;
}
else
{
iCoveredMapIndex = pStructure->sBaseGridNo + pStructure->pDBStructureRef->ppTile[ubLoop]->sPosRelToBase;
}
AddToUndoList( iCoveredMapIndex );
}
}
pStructure = pStructure->pNext;
}
}
void CheckForMultiTilesInTreeAndAddToUndoList( MapIndexBinaryTree *node )
{
CheckMapIndexForMultiTileStructures( node->usMapIndex );
if( node->left )
CheckForMultiTilesInTreeAndAddToUndoList( node->left );
if( node->right )
CheckForMultiTilesInTreeAndAddToUndoList( node->right );
}
BOOLEAN RemoveAllFromUndoList( void )
{
ClearUndoMapIndexTree();
while ( gpTileUndoStack != NULL )
DeleteTopStackNode();
return( TRUE );
}
BOOLEAN ExecuteUndoList( void )
{
INT32 iCmdCount, iCurCount;
INT32 iUndoMapIndex;
BOOLEAN fExitGrid;
if( !gfUndoEnabled )
return FALSE;
// Is there something on the undo stack?
if ( gpTileUndoStack == NULL )
return( TRUE );
// Get number of stack entries for this command (top node will tell this)
iCmdCount = gpTileUndoStack->iCmdCount;
// Execute each stack node in command, and remove each from stack.
iCurCount = 0;
while ( (iCurCount < iCmdCount) && (gpTileUndoStack != NULL) )
{
iUndoMapIndex = gpTileUndoStack->pData->iMapIndex;
// Find which map tile we are to "undo"
if( gpTileUndoStack->pData->fLightSaved )
{ //We saved a light, so delete that light
INT16 sX, sY;
//Turn on this flag so that the following code, when executed, doesn't attempt to
//add lights to the undo list. That would cause problems...
gfIgnoreUndoCmdsForLights = TRUE;
ConvertGridNoToXY( (INT16)iUndoMapIndex, &sX, &sY );
if( !gpTileUndoStack->pData->ubLightRadius )
RemoveLight( sX, sY );
else
PlaceLight( gpTileUndoStack->pData->ubLightRadius, sX, sY, gpTileUndoStack->pData->ubLightID );
//Turn off the flag so lights can again be added to the undo list.
gfIgnoreUndoCmdsForLights = FALSE;
}
else
{ // We execute the undo command node by simply swapping the contents
// of the undo's MAP_ELEMENT with the world's element.
fExitGrid = ExitGridAtGridNo( (UINT16)iUndoMapIndex );
SwapMapElementWithWorld( iUndoMapIndex, gpTileUndoStack->pData->pMapTile );
// copy the room number information back
gubWorldRoomInfo[ iUndoMapIndex ] = gpTileUndoStack->pData->ubRoomNum;
// Now we smooth out the changes...
//SmoothUndoMapTileTerrain( iUndoMapIndex, gpTileUndoStack->pData->pMapTile );
SmoothAllTerrainTypeRadius( iUndoMapIndex, 1, TRUE );
}
// ...trash the top element of the stack...
DeleteTopStackNode( );
// ...and bump the command counter up by 1
iCurCount++;
//Kris:
//The new cursor system is somehow interfering with the undo stuff. When
//an undo is called, the item is erased, but a cursor is added! I'm quickly
//hacking around this by erasing all cursors here.
RemoveAllTopmostsOfTypeRange( iUndoMapIndex, FIRSTPOINTERS, FIRSTPOINTERS );
if( fExitGrid && !ExitGridAtGridNo( (UINT16)iUndoMapIndex ) )
{ //An exitgrid has been removed, so get rid of the associated indicator.
RemoveTopmost( (UINT16)iUndoMapIndex, FIRSTPOINTERS8 );
}
else if( !fExitGrid && ExitGridAtGridNo( (UINT16)iUndoMapIndex ) )
{ //An exitgrid has been added, so add the associated indicator
AddTopmostToTail( (UINT16)iUndoMapIndex, FIRSTPOINTERS8 );
}
}
return( TRUE );
}
void SmoothUndoMapTileTerrain( INT32 iWorldTile, MAP_ELEMENT *pUndoTile )
{
LEVELNODE *pWorldLand;
LEVELNODE *pUndoLand;
LEVELNODE *pLand;
LEVELNODE *pWLand;
UINT32 uiCheckType, uiWCheckType;
BOOLEAN fFound;
pUndoLand = pUndoTile->pLandHead;
pWorldLand = gpWorldLevelData[ iWorldTile ].pLandHead;
if ( pUndoLand == NULL )
{
// nothing in the old tile, so smooth the entire land in world's tile
pLand = gpWorldLevelData[ iWorldTile ].pLandHead;
while( pLand != NULL )
{
GetTileType( pLand->usIndex, &uiCheckType );
SmoothTerrainRadius( iWorldTile, uiCheckType, 1, TRUE );
pLand = pLand->pNext;
}
}
else if ( gpWorldLevelData[ iWorldTile ].pLandHead == NULL )
{
// Nothing in world's tile, so smooth out the land in the old tile.
pLand = pUndoLand;
while( pLand != NULL )
{
GetTileType( pLand->usIndex, &uiCheckType );
SmoothTerrainRadius( iWorldTile, uiCheckType, 1, TRUE );
pLand = pLand->pNext;
}
}
else
{
pLand = pUndoLand;
while( pLand != NULL )
{
GetTileType( pLand->usIndex, &uiCheckType);
fFound = FALSE;
pWLand = pWorldLand;
while( pWLand != NULL && !fFound )
{
GetTileType( pWLand->usIndex, &uiWCheckType);
if ( uiCheckType == uiWCheckType )
fFound = TRUE;
pWLand = pWLand->pNext;
}
if ( !fFound )
SmoothTerrainRadius( iWorldTile, uiCheckType, 1, TRUE );
pLand = pLand->pNext;
}
pWLand = pWorldLand;
while( pWLand != NULL )
{
GetTileType( pWLand->usIndex, &uiWCheckType);
fFound = FALSE;
pLand = pUndoLand;
while( pLand != NULL && !fFound )
{
GetTileType( pLand->usIndex, &uiCheckType);
if ( uiCheckType == uiWCheckType )
fFound = TRUE;
pLand = pLand->pNext;
}
if ( !fFound )
SmoothTerrainRadius( iWorldTile, uiWCheckType, 1, TRUE );
pWLand = pWLand->pNext;
}
}
}
//Because of the potentially huge amounts of memory that can be allocated due to the inefficient
//undo methods coded by Bret, it is feasible that it could fail. Instead of using assertions to
//terminate the program, destroy the memory allocated thusfar.
void DeleteMapElementContentsAfterCreationFail( MAP_ELEMENT *pNewMapElement )
{
LEVELNODE *pLevelNode;
STRUCTURE *pStructure;
INT32 x;
for( x = 0; x < 9; x++ )
{
if( x == 1 )
continue;
pLevelNode = pNewMapElement->pLevelNodes[ x ];
while( pLevelNode )
{
LEVELNODE *temp;
temp = pLevelNode;
pLevelNode = pLevelNode->pNext;
MemFree( temp );
}
}
pStructure = pNewMapElement->pStructureHead;
while( pStructure )
{
STRUCTURE *temp;
temp = pStructure;
pStructure = pStructure->pNext;
MemFree( temp );
}
}
/*
union
{
struct TAG_level_node *pPrevNode; // FOR LAND, GOING BACKWARDS POINTER
ITEM_POOL *pItemPool; // ITEM POOLS
STRUCTURE *pStructureData; // STRUCTURE DATA
INT32 iPhysicsObjectID; // ID FOR PHYSICS ITEM
INT32 uiAPCost; // FOR AP DISPLAY
}; // ( 4 byte union )
union
{
struct
{
UINT16 usIndex; // TILE DATABASE INDEX
INT16 sCurrentFrame; // Stuff for animated tiles for a given tile location ( doors, etc )
};
struct
{
SOLDIERTYPE *pSoldier; // POINTER TO SOLDIER
};
}; // ( 4 byte union )
*/
BOOLEAN CopyMapElementFromWorld( MAP_ELEMENT *pNewMapElement, INT32 iMapIndex )
{
MAP_ELEMENT *pOldMapElement;
LEVELNODE *pOldLevelNode;
LEVELNODE *pLevelNode;
LEVELNODE *pNewLevelNode;
LEVELNODE *tail;
INT32 x;
STRUCTURE *pOldStructure;
//Get a pointer to the current map index
pOldMapElement = &gpWorldLevelData[ iMapIndex ];
//Save the structure information from the mapelement
pOldStructure = pOldMapElement->pStructureHead;
if( pOldStructure )
{
STRUCTURE *pNewStructure;
STRUCTURE *pStructure;
STRUCTURE *tail;
tail = NULL;
pNewStructure = NULL;
while( pOldStructure )
{
pStructure = (STRUCTURE*)MemAlloc( sizeof( STRUCTURE ) );
if( !pStructure )
{
DeleteMapElementContentsAfterCreationFail( pNewMapElement );
return FALSE;
}
if( !tail )
{ //first node in structure list
tail = pStructure;
*tail = *pOldStructure;
tail->pPrev = NULL;
tail->pNext = NULL;
}
else
{ //add to the end of the levelnode list
tail->pNext = pStructure;
*pStructure = *pOldStructure;
pStructure->pPrev = tail;
pStructure->pNext = NULL;
tail = tail->pNext;
}
//place the new node inside of the new map element
if( !pNewStructure )
{
pNewMapElement->pStructureHead = pStructure;
pNewStructure = pStructure;
}
else
{
pNewStructure->pNext = pStructure;
pNewStructure = pNewStructure->pNext;
}
pOldStructure = pOldStructure->pNext;
}
if( tail )
{
pNewMapElement->pStructureTail = tail;
}
}
//For each of the 9 levelnodes, save each one
//except for levelnode[1] which is a pointer to the first land to render.
for( x = 0; x < 9; x++ )
{
if( x == 1 || x == 5 ) //skip the pLandStart and pMercLevel LEVELNODES
continue;
tail = NULL;
pOldLevelNode = pOldMapElement->pLevelNodes[ x ];
pNewLevelNode = NULL;
while( pOldLevelNode )
{
//copy the level node
pLevelNode = ( LEVELNODE* )MemAlloc( sizeof( LEVELNODE ) );
if( !pLevelNode )
{
DeleteMapElementContentsAfterCreationFail( pNewMapElement );
return FALSE;
}
if( !tail )
{ //first node in levelnode list
tail = pLevelNode;
*tail = *pOldLevelNode;
if( !x ) //land layer only
tail->pPrevNode = NULL;
tail->pNext = NULL;
}
else
{ //add to the end of the levelnode list
tail->pNext = pLevelNode;
*pLevelNode = *pOldLevelNode;
if( !x ) //land layer only
pLevelNode->pPrevNode = tail;
pLevelNode->pNext = NULL;
tail = tail->pNext;
}
//place the new node inside of the new map element
if( !pNewLevelNode )
{
pNewMapElement->pLevelNodes[ x ] = pLevelNode;
pNewLevelNode = pLevelNode;
}
else
{
pNewLevelNode->pNext = pLevelNode;
pNewLevelNode = pNewLevelNode->pNext;
}
//Handle levelnode layer specific stuff
switch( x )
{
case 0: //LAND LAYER
if( pOldLevelNode == pOldMapElement->pLandStart )
{ //set the new landstart to point to the new levelnode.
pNewMapElement->pLandStart = pNewLevelNode;
}
break;
case 2: //OBJECT LAYER
if( pOldLevelNode->pItemPool )
{ //save the item pool?
//pNewLevelNode->pItemPool = (ITEM_POOL*)MemAlloc( sizeof( ITEM_POOL ) );
}
break;
case 3: //STRUCT LAYER
case 6: //ROOF LAYER
case 7: //ON ROOF LAYER
if( pOldLevelNode->pStructureData )
{ //make sure the structuredata pointer points to the parallel structure
STRUCTURE *pOld, *pNew;
//both lists are exactly the same size and contain the same information,
//but the addresses are different. We will traverse the old list until
//we find the match, then
pOld = pOldMapElement->pStructureHead;
pNew = pNewMapElement->pStructureHead;
while( pOld )
{
Assert( pNew );
if( pOld == pOldLevelNode->pStructureData )
{
pNewLevelNode->pStructureData = pNew;
break;
}
pOld = pOld->pNext;
pNew = pNew->pNext;
}
//Kris:
//If this assert should fail, that means there is something wrong with
//the preservation of the structure data within the mapelement.
if( pOld != pOldLevelNode->pStructureData )
{
//OUCH!!! THIS IS HAPPENING. DISABLED IT FOR LINDA'S SAKE
Assert( 1 );
}
}
break;
}
//Done, go to next node in this level
pOldLevelNode = pOldLevelNode->pNext;
}
//Done, go to next level
}
//Save the rest of the information in the mapelement.
pNewMapElement->uiFlags = pOldMapElement->uiFlags;
pNewMapElement->sSumRealLights[0] = pOldMapElement->sSumRealLights[0];
pNewMapElement->sSumRealLights[1] = pOldMapElement->sSumRealLights[1];
pNewMapElement->sHeight = pOldMapElement->sHeight;
pNewMapElement->ubTerrainID = pOldMapElement->ubTerrainID;
pNewMapElement->ubReservedSoldierID = pOldMapElement->ubReservedSoldierID;
return TRUE;
}
BOOLEAN SwapMapElementWithWorld( INT32 iMapIndex, MAP_ELEMENT *pUndoMapElement )
{
MAP_ELEMENT *pCurrentMapElement;
MAP_ELEMENT TempMapElement;
pCurrentMapElement = &gpWorldLevelData[ iMapIndex ];
//Transfer the merc level node from the current world to the undo mapelement
//that will replace it. We do this, because mercs aren't associated with
//undo commands.
pUndoMapElement->pMercHead = gpWorldLevelData[ iMapIndex ].pMercHead;
gpWorldLevelData[ iMapIndex ].pMercHead = NULL;
//Swap the mapelements
TempMapElement = *pCurrentMapElement;
*pCurrentMapElement = *pUndoMapElement;
*pUndoMapElement = TempMapElement;
return ( TRUE );
}
void DetermineUndoState()
{
// Reset the undo command mode if we released the left button.
if( !fNewUndoCmd )
{
if( !gfLeftButtonState && !gfCurrentSelectionWithRightButton ||
!gfRightButtonState && gfCurrentSelectionWithRightButton )
{
//Clear the mapindex binary tree list, and set up flag for new undo command.
fNewUndoCmd = TRUE;
ClearUndoMapIndexTree();
}
}
}
#endif
+22
View File
@@ -0,0 +1,22 @@
#include "BuildDefines.h"
#ifdef JA2EDITOR
#ifndef __EDITOR_UNDO_H
#define __EDITOR_UNDO_H
BOOLEAN AddToUndoList( INT32 iMapIndex );
void AddLightToUndoList( INT32 iMapIndex, INT32 iLightRadius, UINT8 ubLightID );
BOOLEAN RemoveAllFromUndoList();
BOOLEAN ExecuteUndoList();
void EnableUndo();
void DisableUndo();
void DetermineUndoState();
// Undo command flags
#define MAX_UNDO_COMMAND_LENGTH 10
#endif
#endif
+147
View File
@@ -0,0 +1,147 @@
# Microsoft Developer Studio Generated Dependency File, included by Editor.mak
".\Cursor Modes.cpp" : \
"..\builddefines.h"\
"..\Language Defines.h"\
".\Editor All.h"\
.\edit_sys.cpp : \
"..\builddefines.h"\
"..\Language Defines.h"\
".\Editor All.h"\
".\Editor Callbacks.cpp" : \
"..\builddefines.h"\
"..\Language Defines.h"\
".\Editor All.h"\
".\Editor Modes.cpp" : \
"..\builddefines.h"\
"..\Language Defines.h"\
".\Editor All.h"\
".\Editor Taskbar Creation.cpp" : \
"..\builddefines.h"\
"..\Language Defines.h"\
".\Editor All.h"\
".\Editor Taskbar Utils.cpp" : \
"..\builddefines.h"\
"..\Language Defines.h"\
".\Editor All.h"\
".\Editor Undo.cpp" : \
"..\builddefines.h"\
"..\Language Defines.h"\
".\Editor All.h"\
.\EditorBuildings.cpp : \
"..\builddefines.h"\
"..\Language Defines.h"\
".\Editor All.h"\
.\EditorItems.cpp : \
"..\builddefines.h"\
"..\Language Defines.h"\
".\Editor All.h"\
.\EditorMapInfo.cpp : \
"..\builddefines.h"\
"..\Language Defines.h"\
".\Editor All.h"\
.\EditorMercs.cpp : \
"..\builddefines.h"\
"..\Language Defines.h"\
".\Editor All.h"\
.\EditorTerrain.cpp : \
"..\builddefines.h"\
"..\Language Defines.h"\
".\Editor All.h"\
.\editscreen.cpp : \
"..\builddefines.h"\
"..\Language Defines.h"\
"..\screenids.h"\
".\Editor All.h"\
".\Item Statistics.cpp" : \
"..\builddefines.h"\
"..\Language Defines.h"\
".\Editor All.h"\
.\LoadScreen.cpp : \
"..\builddefines.h"\
"..\Language Defines.h"\
"..\screenids.h"\
".\Editor All.h"\
.\messagebox.cpp : \
"..\builddefines.h"\
"..\Language Defines.h"\
".\Editor All.h"\
.\newsmooth.cpp : \
"..\builddefines.h"\
"..\Language Defines.h"\
".\Editor All.h"\
.\popupmenu.cpp : \
"..\builddefines.h"\
"..\Language Defines.h"\
".\Editor All.h"\
".\Road Smoothing.cpp" : \
"..\builddefines.h"\
"..\Language Defines.h"\
".\Editor All.h"\
".\Sector Summary.cpp" : \
"..\builddefines.h"\
"..\Language Defines.h"\
".\Editor All.h"\
.\selectwin.cpp : \
"..\builddefines.h"\
"..\Language Defines.h"\
".\Editor All.h"\
.\SmartMethod.cpp : \
"..\builddefines.h"\
"..\Language Defines.h"\
".\Editor All.h"\
.\smooth.cpp : \
"..\builddefines.h"\
"..\Language Defines.h"\
".\Editor All.h"\
".\Smoothing Utils.cpp" : \
"..\builddefines.h"\
"..\Language Defines.h"\
".\Editor All.h"\
+450
View File
@@ -0,0 +1,450 @@
# Microsoft Developer Studio Project File - Name="Editor" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Static Library" 0x0104
CFG=Editor - Win32 Demo Bounds Checker
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "Editor.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "Editor.mak" CFG="Editor - Win32 Demo Bounds Checker"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "Editor - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "Editor - Win32 Debug" (based on "Win32 (x86) Static Library")
!MESSAGE "Editor - Win32 Release with Debug Info" (based on "Win32 (x86) Static Library")
!MESSAGE "Editor - Win32 Bounds Checker" (based on "Win32 (x86) Static Library")
!MESSAGE "Editor - Win32 Debug Demo" (based on "Win32 (x86) Static Library")
!MESSAGE "Editor - Win32 Release Demo" (based on "Win32 (x86) Static Library")
!MESSAGE "Editor - Win32 Demo Release with Debug Info" (based on "Win32 (x86) Static Library")
!MESSAGE "Editor - Win32 Demo Bounds Checker" (based on "Win32 (x86) Static Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""$/Jagged Alliance 2/Development/Programming/Jagged Alliance 2/Build", AVAAAAAA"
# PROP Scc_LocalPath "..\..\..\ja2\build"
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "Editor - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c
# ADD CPP /nologo /MT /W3 /GX /O2 /Ob2 /I "..\Standard Gaming Platform" /I "..\TileEngine" /I "..\\" /I "..\Tactical" /I "..\Utils" /I "..\tacticalai" /I "..\strategic" /I "..\Laptop" /I ".\\" /D "PRECOMPILEDHEADERS" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "JA2" /D "XML_STATIC" /D "CINTERFACE" /FR /YX"Editor All.h" /FD /c
# ADD BASE RSC /l 0x409
# ADD RSC /l 0x409
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "Editor - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c
# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "..\Standard Gaming Platform" /I "..\TileEngine" /I "..\\" /I "..\Tactical" /I "..\Utils" /I "..\tacticalai" /I "..\strategic" /I "..\Laptop" /I ".\\" /D "PRECOMPILEDHEADERS" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "JA2" /D "_VTUNE_PROFILING" /D "XML_STATIC" /D "CINTERFACE" /FR /YX"Editor All.h" /FD /c
# ADD BASE RSC /l 0x409
# ADD RSC /l 0x409
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "Editor - Win32 Release with Debug Info"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Editor__"
# PROP BASE Intermediate_Dir "Editor__"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release with Debug"
# PROP Intermediate_Dir "Release with Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "\Standard Gaming Platform" /I "\ja2\Build" /I "\ja2\Build\TileEngine" /I "\ja2\Build\Utils" /I "\ja2\build\TacticalAI" /I "\ja2\build\Communications" /I "\ja2\build\Tactical" /I "\ja2\build\strategic" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "JA2" /YX /FD /c
# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\Standard Gaming Platform" /I "..\\" /I "..\TileEngine" /I "..\Utils" /I "..\TacticalAI" /I "..\Tactical" /I "..\strategic" /I ".\\" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "JA2" /D "PRECOMPILEDHEADERS" /D "_VTUNE_PROFILING" /D "XML_STATIC" /D "CINTERFACE" /FR /YX"Editor All.h" /FD /c
# ADD BASE RSC /l 0x409
# ADD RSC /l 0x409
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "Editor - Win32 Bounds Checker"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Editor_1"
# PROP BASE Intermediate_Dir "Editor_1"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Bounds Checker"
# PROP Intermediate_Dir "Bounds Checker"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /GX /Z7 /Od /I "\Standard Gaming Platform" /I "\ja2\Build" /I "\ja2\Build\TileEngine" /I "\ja2\Build\Utils" /I "\ja2\build\TacticalAI" /I "\ja2\build\Communications" /I "\ja2\build\Tactical" /I "\ja2\build\strategic" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "JA2" /FR /YX /FD /c
# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "\Standard Gaming Platform" /I "\ja2\Build" /I "\ja2\Build\TileEngine" /I "\ja2\Build\Utils" /I "\ja2\build\TacticalAI" /I "\ja2\build\Communications" /I "\ja2\build\Tactical" /I "\ja2\build\strategic" /D "_DEBUG" /D "BOUNDS_CHECKER" /D "WIN32" /D "_WINDOWS" /D "JA2" /D "PRECOMPILEDHEADERS" /D "_VTUNE_PROFILING" /FR /YX"Editor All.h" /FD /c
# ADD BASE RSC /l 0x409
# ADD RSC /l 0x409
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "Editor - Win32 Debug Demo"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Editor_0"
# PROP BASE Intermediate_Dir "Editor_0"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug Demo"
# PROP Intermediate_Dir "Debug Demo"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /GX /Z7 /Od /I "\Standard Gaming Platform" /I "\ja2\Build" /I "\ja2\Build\TileEngine" /I "\ja2\Build\Utils" /I "\ja2\build\TacticalAI" /I "\ja2\build\Communications" /I "\ja2\build\Tactical" /I "\ja2\build\strategic" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "JA2" /FR /YX /FD /c
# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "\Standard Gaming Platform" /I "\ja2\Build" /I "\ja2\Build\TileEngine" /I "\ja2\Build\Utils" /I "\ja2\build\TacticalAI" /I "\ja2\build\Communications" /I "\ja2\build\Tactical" /I "\ja2\build\strategic" /D "JA2DEMO" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "JA2" /D "PRECOMPILEDHEADERS" /FR /YX"Editor All.h" /FD /c
# ADD BASE RSC /l 0x409
# ADD RSC /l 0x409
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "Editor - Win32 Release Demo"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Editor_2"
# PROP BASE Intermediate_Dir "Editor_2"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release Demo"
# PROP Intermediate_Dir "Release Demo"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "\Standard Gaming Platform" /I "\ja2\Build" /I "\ja2\Build\TileEngine" /I "\ja2\Build\Utils" /I "\ja2\build\TacticalAI" /I "\ja2\build\Communications" /I "\ja2\build\Tactical" /I "\ja2\build\strategic" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "JA2" /FR /YX /FD /c
# ADD CPP /nologo /MT /W3 /GX /O2 /I "\Standard Gaming Platform" /I "\ja2\Build" /I "\ja2\Build\TileEngine" /I "\ja2\Build\Utils" /I "\ja2\build\TacticalAI" /I "\ja2\build\Communications" /I "\ja2\build\Tactical" /I "\ja2\build\strategic" /D "NDEBUG" /D "JA2DEMO" /D "WIN32" /D "_WINDOWS" /D "JA2" /D "PRECOMPILEDHEADERS" /FR /YX"Editor All.h" /FD /c
# ADD BASE RSC /l 0x409
# ADD RSC /l 0x409
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "Editor - Win32 Demo Release with Debug Info"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Editor_3"
# PROP BASE Intermediate_Dir "Editor_3"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Demo Release with Debug"
# PROP Intermediate_Dir "Demo Release with Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /I "\Standard Gaming Platform" /I "\ja2\Build" /I "\ja2\Build\TileEngine" /I "\ja2\Build\Utils" /I "\ja2\build\TacticalAI" /I "\ja2\build\Communications" /I "\ja2\build\Tactical" /I "\ja2\build\strategic" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "JA2" /FR /YX /FD /c
# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\Standard Gaming Platform" /I "..\\" /I "..\TileEngine" /I "..\Utils" /I "..\TacticalAI" /I "..\Tactical" /I "..\strategic" /I ".\\" /D "NDEBUG" /D "JA2DEMO" /D "WIN32" /D "_WINDOWS" /D "JA2" /D "PRECOMPILEDHEADERS" /D "XML_STATIC" /D "CINTERFACE" /FR /YX"Editor All.h" /FD /c
# ADD BASE RSC /l 0x409
# ADD RSC /l 0x409
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "Editor - Win32 Demo Bounds Checker"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Editor_4"
# PROP BASE Intermediate_Dir "Editor_4"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Demo Bounds Checker"
# PROP Intermediate_Dir "Demo Bounds Checker"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /GX /Z7 /Od /I "\Standard Gaming Platform" /I "\ja2\Build" /I "\ja2\Build\TileEngine" /I "\ja2\Build\Utils" /I "\ja2\build\TacticalAI" /I "\ja2\build\Communications" /I "\ja2\build\Tactical" /I "\ja2\build\strategic" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "JA2" /D "BOUNDS_CHECKER" /FR /YX /FD /c
# ADD CPP /nologo /MTd /W3 /GX /Z7 /Od /I "\Standard Gaming Platform" /I "\ja2\Build" /I "\ja2\Build\TileEngine" /I "\ja2\Build\Utils" /I "\ja2\build\TacticalAI" /I "\ja2\build\Communications" /I "\ja2\build\Tactical" /I "\ja2\build\strategic" /D "_DEBUG" /D "BOUNDS_CHECKER" /D "JA2DEMO" /D "WIN32" /D "_WINDOWS" /D "JA2" /D "PRECOMPILEDHEADERS" /FR /YX"Editor All.h" /FD /c
# ADD BASE RSC /l 0x409
# ADD RSC /l 0x409
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ENDIF
# Begin Target
# Name "Editor - Win32 Release"
# Name "Editor - Win32 Debug"
# Name "Editor - Win32 Release with Debug Info"
# Name "Editor - Win32 Bounds Checker"
# Name "Editor - Win32 Debug Demo"
# Name "Editor - Win32 Release Demo"
# Name "Editor - Win32 Demo Release with Debug Info"
# Name "Editor - Win32 Demo Bounds Checker"
# Begin Group "Source Files"
# PROP Default_Filter ""
# Begin Source File
SOURCE=".\Cursor Modes.cpp"
# End Source File
# Begin Source File
SOURCE=.\edit_sys.cpp
# End Source File
# Begin Source File
SOURCE=".\Editor Callbacks.cpp"
# End Source File
# Begin Source File
SOURCE=".\Editor Modes.cpp"
# End Source File
# Begin Source File
SOURCE=".\Editor Taskbar Creation.cpp"
# End Source File
# Begin Source File
SOURCE=".\Editor Taskbar Utils.cpp"
# End Source File
# Begin Source File
SOURCE=".\Editor Undo.cpp"
# End Source File
# Begin Source File
SOURCE=.\EditorBuildings.cpp
# End Source File
# Begin Source File
SOURCE=.\EditorItems.cpp
# End Source File
# Begin Source File
SOURCE=.\EditorMapInfo.cpp
# End Source File
# Begin Source File
SOURCE=.\EditorMercs.cpp
# End Source File
# Begin Source File
SOURCE=.\EditorTerrain.cpp
# End Source File
# Begin Source File
SOURCE=.\editscreen.cpp
# End Source File
# Begin Source File
SOURCE=".\Item Statistics.cpp"
# End Source File
# Begin Source File
SOURCE=.\LoadScreen.cpp
# End Source File
# Begin Source File
SOURCE=.\messagebox.cpp
# End Source File
# Begin Source File
SOURCE=.\newsmooth.cpp
# End Source File
# Begin Source File
SOURCE=.\popupmenu.cpp
# End Source File
# Begin Source File
SOURCE=".\Road Smoothing.cpp"
# End Source File
# Begin Source File
SOURCE=".\Sector Summary.cpp"
# End Source File
# Begin Source File
SOURCE=.\selectwin.cpp
# End Source File
# Begin Source File
SOURCE=.\SmartMethod.cpp
# End Source File
# Begin Source File
SOURCE=.\smooth.cpp
# End Source File
# Begin Source File
SOURCE=".\Smoothing Utils.cpp"
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter ""
# Begin Source File
SOURCE=".\Button Defines.h"
# End Source File
# Begin Source File
SOURCE=".\Cursor Modes.h"
# End Source File
# Begin Source File
SOURCE=.\edit_sys.h
# End Source File
# Begin Source File
SOURCE=".\Editor All.h"
# End Source File
# Begin Source File
SOURCE=".\Editor Callback Prototypes.h"
# End Source File
# Begin Source File
SOURCE=".\Editor Modes.h"
# End Source File
# Begin Source File
SOURCE=".\Editor Taskbar Creation.h"
# End Source File
# Begin Source File
SOURCE=".\Editor Taskbar Utils.h"
# End Source File
# Begin Source File
SOURCE=".\Editor Undo.h"
# End Source File
# Begin Source File
SOURCE=.\EditorBuildings.h
# End Source File
# Begin Source File
SOURCE=.\EditorDefines.h
# End Source File
# Begin Source File
SOURCE=.\EditorItems.h
# End Source File
# Begin Source File
SOURCE=.\EditorMapInfo.h
# End Source File
# Begin Source File
SOURCE=.\EditorMercs.h
# End Source File
# Begin Source File
SOURCE=.\EditorTerrain.h
# End Source File
# Begin Source File
SOURCE=.\editscreen.h
# End Source File
# Begin Source File
SOURCE=".\Item Statistics.h"
# End Source File
# Begin Source File
SOURCE=.\LoadScreen.h
# End Source File
# Begin Source File
SOURCE=.\messagebox.h
# End Source File
# Begin Source File
SOURCE=.\newsmooth.h
# End Source File
# Begin Source File
SOURCE=.\popupmenu.h
# End Source File
# Begin Source File
SOURCE=".\Road Smoothing.h"
# End Source File
# Begin Source File
SOURCE=".\Sector Summary.h"
# End Source File
# Begin Source File
SOURCE=.\selectwin.h
# End Source File
# Begin Source File
SOURCE=.\SmartMethod.h
# End Source File
# Begin Source File
SOURCE=.\smooth.h
# End Source File
# Begin Source File
SOURCE=".\Smoothing Utils.h"
# End Source File
# Begin Source File
SOURCE=".\Summary Info.h"
# End Source File
# End Group
# End Target
# End Project
+1274
View File
File diff suppressed because it is too large Load Diff
+2321
View File
File diff suppressed because it is too large Load Diff
+765
View File
@@ -0,0 +1,765 @@
#ifdef PRECOMPILEDHEADERS
#include "Editor All.h"
#else
#include "builddefines.h"
#endif
#ifdef JA2EDITOR
#ifndef PRECOMPILEDHEADERS
#include "tiledef.h"
#include "edit_sys.h"
#include "sysutil.h"
#include "Font Control.h"
#include "renderworld.h" //ClearRenderFlags();
#include "worldman.h" //HideStructOfGivenType()
#include "EditorDefines.h"
#include "EditorBuildings.h"
#include "EditorTerrain.h" //for access to TerrainTileDrawMode
#include "Render Fun.h"
#include "newsmooth.h"
#include "Editor Undo.h"
#include "Editor Taskbar Utils.h"
#include "Editor Modes.h"
#include "Smoothing Utils.h"
#include "Text Input.h"
#include "keys.h"
#include "environment.h"
#include "selectwin.h"
#include "Simple Render Utils.h"
#endif
BOOLEAN fBuildingShowRoofs, fBuildingShowWalls, fBuildingShowRoomInfo;
UINT16 usCurrentMode;
UINT8 gubCurrRoomNumber;
UINT8 gubMaxRoomNumber;
BOOLEAN gfEditingDoor;
//BEGINNNING OF BUILDING INITIALIZATION FUNCTIONS
void GameInitEditorBuildingInfo()
{
fBuildingShowRoofs = TRUE;
fBuildingShowWalls = TRUE;
fBuildingShowRoomInfo = FALSE;
usCurrentMode = BUILDING_PLACE_WALLS;
gubCurrRoomNumber = gubMaxRoomNumber = 1;
}
//BEGINNING OF BUILDING UTILITY FUNCTIONS
void UpdateRoofsView()
{
INT32 x;
UINT16 usType;
for ( x = 0; x < WORLD_MAX; x++ )
{
for ( usType = FIRSTROOF; usType <= LASTSLANTROOF; usType++ )
{
HideStructOfGivenType( x, usType, (BOOLEAN)(!fBuildingShowRoofs) );
}
}
gfRenderWorld = TRUE;
}
void UpdateWallsView()
{
INT32 cnt;
for ( cnt = 0; cnt < WORLD_MAX; cnt++ )
{
if ( fBuildingShowWalls )
{
RemoveWallLevelnodeFlags( (INT16)cnt, LEVELNODE_HIDDEN );
}
else
{
SetWallLevelnodeFlags( (INT16)cnt, LEVELNODE_HIDDEN );
}
}
gfRenderWorld = TRUE;
}
void UpdateBuildingsInfo()
{
//print the headers on top of the columns
SetFont( SMALLCOMPFONT );
SetFontForeground( FONT_RED );
mprintfEditor( 112, 362, L"TOGGLE");
mprintfEditor( 114, 372, L"VIEWS");
SetFontForeground( FONT_YELLOW );
mprintfEditor( 185, 362, L"SELECTION METHOD");
SetFontForeground( FONT_LTGREEN );
mprintfEditor( 290, 362, L"SMART METHOD");
SetFontForeground( FONT_LTBLUE );
mprintfEditor( 390, 362, L"BUILDING METHOD");
SetFontForeground( FONT_GRAY2 );
mprintfEditor( 437, 404, L"Room#" );
}
//Uses a recursive method to elimate adjacent tiles of structure information.
//The code will attempt to delete the current mapindex, then search using this method:
//1) if there isn't structure info here, return.
//2) if there is structure info here, delete it now.
//3) KillBuilding at x-1, y.
//4) KillBuilding at x , y-1.
//5) KillBuilding at x+1, y.
//6) KillBuilding at x , y+1.
void KillBuilding( UINT32 iMapIndex )
{
BOOLEAN fFound = FALSE;
if( !gfBasement )
fFound |= RemoveAllRoofsOfTypeRange( iMapIndex, FIRSTTEXTURE, LASTITEM );
fFound |= RemoveAllLandsOfTypeRange( iMapIndex, FIRSTFLOOR, LASTFLOOR );
EraseBuilding( iMapIndex );
gubWorldRoomInfo[ iMapIndex ] = 0;
if( !fFound )
{
if( gfBasement )
RebuildRoof( iMapIndex, 0 );
return;
}
if( GridNoOnVisibleWorldTile( (UINT16)( iMapIndex - WORLD_COLS ) ) )
KillBuilding( iMapIndex - WORLD_COLS );
if( GridNoOnVisibleWorldTile( (UINT16)( iMapIndex + WORLD_COLS ) ) )
KillBuilding( iMapIndex + WORLD_COLS );
if( GridNoOnVisibleWorldTile( (UINT16)( iMapIndex + 1 ) ) )
KillBuilding( iMapIndex + 1 );
if( GridNoOnVisibleWorldTile( (UINT16)( iMapIndex - 1 ) ) )
KillBuilding( iMapIndex - 1 );
if( gfBasement )
RebuildRoof( iMapIndex, 0 );
}
BUILDINGLAYOUTNODE *gpBuildingLayoutList = NULL;
INT16 gsBuildingLayoutAnchorGridNo = -1;
extern void RemoveBuildingLayout();
void DeleteBuildingLayout()
{
BUILDINGLAYOUTNODE *curr;
//Erases the cursors associated with them.
RemoveBuildingLayout();
while( gpBuildingLayoutList )
{
curr = gpBuildingLayoutList;
gpBuildingLayoutList = gpBuildingLayoutList->next;
MemFree( curr );
}
gpBuildingLayoutList = NULL;
gsBuildingLayoutAnchorGridNo = -1;
}
void BuildLayout( INT32 iMapIndex, INT32 iOffset )
{
BUILDINGLAYOUTNODE *curr;
//First, validate the gridno
iMapIndex += iOffset;
if( iMapIndex < 0 && iMapIndex >= WORLD_COLS*WORLD_ROWS )
return;
//Now, check if there is a building here
if( !BuildingAtGridNo( iMapIndex ) )
{
if( iOffset == 1 && !BuildingAtGridNo( iMapIndex - 1 ) )
return;
if( iOffset == WORLD_COLS && !BuildingAtGridNo( iMapIndex - WORLD_COLS ) )
return;
if( iOffset == -1 && !GetVerticalWall( iMapIndex ) )
return;
if( iOffset == -WORLD_COLS && !GetHorizontalWall( iMapIndex ) )
return;
}
//Now, check to make sure this gridno hasn't already been processed.
curr = gpBuildingLayoutList;
while( curr )
{
if( (INT16)iMapIndex == curr->sGridNo )
return;
curr = curr->next;
}
//Good, it hasn't, so process it and add it to the head of the list.
curr = (BUILDINGLAYOUTNODE*)MemAlloc( sizeof( BUILDINGLAYOUTNODE ) );
Assert( curr );
curr->sGridNo = (INT16)iMapIndex;
curr->next = gpBuildingLayoutList;
gpBuildingLayoutList = curr;
//Use recursion to process the remainder.
BuildLayout( iMapIndex, -WORLD_COLS );
BuildLayout( iMapIndex, -1 );
BuildLayout( iMapIndex, 1 );
BuildLayout( iMapIndex, WORLD_COLS );
}
//The first step is copying a building. After that, it either must be pasted or moved.
void CopyBuilding( INT32 iMapIndex )
{
AssertMsg( !gpBuildingLayoutList, "Error: Attempting to copy building multiple times." );
//First step is to determine if we have a building in the area that we click. If not, do nothing.
if( !BuildingAtGridNo( iMapIndex ) )
return;
//Okay, a building does exist here to some undetermined capacity.
//Allocate the basic structure, then calculate the layout. The head node is
gpBuildingLayoutList = (BUILDINGLAYOUTNODE*)MemAlloc( sizeof( BUILDINGLAYOUTNODE ) );
Assert( gpBuildingLayoutList );
gpBuildingLayoutList->sGridNo = (INT16)iMapIndex;
gpBuildingLayoutList->next = NULL;
//Set the anchor point for this building -- this is where the user clicked.
gsBuildingLayoutAnchorGridNo = (INT16)iMapIndex;
//Now, recursively expand out while adding unique gridnos to our list. The recursion will
//terminate when complete.
BuildLayout( iMapIndex, -WORLD_COLS );
BuildLayout( iMapIndex, -1 );
BuildLayout( iMapIndex, 1 );
BuildLayout( iMapIndex, WORLD_COLS );
//We have our layout. Now depending on the mode, we will either move the building or
//copy it. The layout automatically gets deleted as soon as the user releases the mouse
//button.
}
//depending on the offset, we will either sort in increasing order, or decreasing order.
//This will prevent overlapping problems.
void SortBuildingLayout( INT32 iMapIndex )
{
BUILDINGLAYOUTNODE *head, *curr, *prev, *prevBest, *best;
INT32 iBestIndex;
head = NULL;
if( iMapIndex < gsBuildingLayoutAnchorGridNo )
{ //Forward sort (in increasing order)
while( gpBuildingLayoutList )
{
iBestIndex = -1;
curr = gpBuildingLayoutList;
prev = NULL;
while( curr )
{
if( iBestIndex < curr->sGridNo )
{
iBestIndex = curr->sGridNo;
prevBest = prev;
best = curr;
}
prev = curr;
curr = curr->next;
}
//detach node from real list
if( prevBest )
prevBest->next = best->next;
if( best == gpBuildingLayoutList )
gpBuildingLayoutList = gpBuildingLayoutList->next;
//insert node into temp sorted list
best->next = head;
head = best;
}
}
else
{ //Reverse sort (in decreasing order)
while( gpBuildingLayoutList )
{
iBestIndex = 100000;
curr = gpBuildingLayoutList;
prev = NULL;
while( curr )
{
if( iBestIndex > curr->sGridNo )
{
iBestIndex = curr->sGridNo;
prevBest = prev;
best = curr;
}
prev = curr;
curr = curr->next;
}
//detach node from real list
if( prevBest )
prevBest->next = best->next;
if( best == gpBuildingLayoutList )
gpBuildingLayoutList = gpBuildingLayoutList->next;
//insert node into temp sorted list
best->next = head;
head = best;
}
}
//Now assign the newly sorted list back to the real list.
gpBuildingLayoutList = head;
}
void PasteMapElementToNewMapElement( INT32 iSrcGridNo, INT32 iDstGridNo )
{
MAP_ELEMENT *pSrcMapElement;
LEVELNODE *pNode;
UINT16 usType;
DeleteStuffFromMapTile( iDstGridNo );
DeleteAllLandLayers( iDstGridNo );
//Get a pointer to the src mapelement
pSrcMapElement = &gpWorldLevelData[ iSrcGridNo ];
//Go through each levelnode, and paste the info into the new gridno
pNode = pSrcMapElement->pLandHead;
while( pNode )
{
if( pNode == pSrcMapElement->pLandStart )
gpWorldLevelData[ iDstGridNo ].pLandStart = AddLandToTail( iDstGridNo, pNode->usIndex );
else
AddLandToTail( iDstGridNo, pNode->usIndex );
pNode = pNode->pNext;
}
pNode = pSrcMapElement->pObjectHead;
while( pNode )
{
AddObjectToTail( iDstGridNo, pNode->usIndex );
pNode = pNode->pNext;
}
pNode = pSrcMapElement->pStructHead;
while( pNode )
{
AddStructToTail( iDstGridNo, pNode->usIndex );
pNode = pNode->pNext;
}
pNode = pSrcMapElement->pShadowHead;
while( pNode )
{
AddShadowToTail( iDstGridNo, pNode->usIndex );
pNode = pNode->pNext;
}
pNode = pSrcMapElement->pRoofHead;
while( pNode )
{
AddRoofToTail( iDstGridNo, pNode->usIndex );
pNode = pNode->pNext;
}
pNode = pSrcMapElement->pOnRoofHead;
while( pNode )
{
AddOnRoofToTail( iDstGridNo, pNode->usIndex );
pNode = pNode->pNext;
}
pNode = pSrcMapElement->pTopmostHead;
while( pNode )
{
if( pNode->usIndex != FIRSTPOINTERS1 )
AddTopmostToTail( iDstGridNo, pNode->usIndex );
pNode = pNode->pNext;
}
for ( usType = FIRSTROOF; usType <= LASTSLANTROOF; usType++ )
{
HideStructOfGivenType( iDstGridNo, usType, (BOOLEAN)(!fBuildingShowRoofs) );
}
}
void MoveBuilding( INT32 iMapIndex )
{
BUILDINGLAYOUTNODE *curr;
INT32 iOffset;
if( !gpBuildingLayoutList )
return;
SortBuildingLayout( iMapIndex );
iOffset = iMapIndex - gsBuildingLayoutAnchorGridNo;
//First time, set the undo gridnos to everything effected.
curr = gpBuildingLayoutList;
while( curr )
{
AddToUndoList( curr->sGridNo );
AddToUndoList( curr->sGridNo + iOffset );
curr = curr->next;
}
//Now, move the building
curr = gpBuildingLayoutList;
while( curr )
{
PasteMapElementToNewMapElement( curr->sGridNo, curr->sGridNo + iOffset );
DeleteStuffFromMapTile( curr->sGridNo );
curr = curr->next;
}
MarkWorldDirty();
}
void PasteBuilding( INT32 iMapIndex )
{
BUILDINGLAYOUTNODE *curr;
INT32 iOffset;
if( !gpBuildingLayoutList )
return;
SortBuildingLayout( iMapIndex );
iOffset = iMapIndex - gsBuildingLayoutAnchorGridNo;
curr = gpBuildingLayoutList;
//First time, set the undo gridnos to everything effected.
while( curr )
{
AddToUndoList( curr->sGridNo );
AddToUndoList( curr->sGridNo + iOffset );
curr = curr->next;
}
//Now, paste the building (no smoothing)
curr = gpBuildingLayoutList;
while( curr )
{
PasteMapElementToNewMapElement( curr->sGridNo, curr->sGridNo + iOffset );
curr = curr->next;
}
MarkWorldDirty();
}
typedef struct ROOFNODE
{
INT32 iMapIndex;
struct ROOFNODE *next;
}ROOFNODE;
ROOFNODE *gpRoofList = NULL;
void ReplaceRoof( INT32 iMapIndex, UINT16 usRoofType )
{
ROOFNODE *curr;
//First, validate the gridno
if( iMapIndex < 0 && iMapIndex >= WORLD_COLS*WORLD_ROWS )
return;
//Now, check if there is a floor here
if( !FloorAtGridNo( iMapIndex ) )
return;
//Now, check to make sure this gridno hasn't already been processed.
curr = gpRoofList;
while( curr )
{
if( iMapIndex == curr->iMapIndex )
return;
curr = curr->next;
}
//Good, it hasn't, so process it and add it to the head of the list.
curr = (ROOFNODE*)MemAlloc( sizeof( ROOFNODE ) );
Assert( curr );
curr->iMapIndex = iMapIndex;
curr->next = gpRoofList;
gpRoofList = curr;
RebuildRoofUsingFloorInfo( iMapIndex, usRoofType );
//Use recursion to process the remainder.
ReplaceRoof( iMapIndex - WORLD_COLS, usRoofType );
ReplaceRoof( iMapIndex + WORLD_COLS, usRoofType );
ReplaceRoof( iMapIndex - 1, usRoofType );
ReplaceRoof( iMapIndex + 1, usRoofType );
}
void ReplaceBuildingWithNewRoof( INT32 iMapIndex )
{
UINT16 usRoofType;
ROOFNODE *curr;
//Not in normal editor mode, then can't do it.
if( gfBasement || gfCaves )
return;
//if we don't have a floor here, then we can't replace the roof!
if( !FloorAtGridNo( iMapIndex ) )
return;
//Extract the selected roof type.
usRoofType = (UINT16)SelSingleNewRoof[ iCurBank ].uiObject;
//now start building a linked list of all nodes visited -- start the first node.
gpRoofList = (ROOFNODE*)MemAlloc( sizeof( ROOFNODE ) );
Assert( gpRoofList );
gpRoofList->iMapIndex = iMapIndex;
gpRoofList->next = 0;
RebuildRoofUsingFloorInfo( iMapIndex, usRoofType );
//Use recursion to process the remainder.
ReplaceRoof( iMapIndex - WORLD_COLS, usRoofType );
ReplaceRoof( iMapIndex + WORLD_COLS, usRoofType );
ReplaceRoof( iMapIndex - 1, usRoofType );
ReplaceRoof( iMapIndex + 1, usRoofType );
//Done, so delete the list.
while( gpRoofList )
{
curr = gpRoofList;
gpRoofList = gpRoofList->next;
MemFree( curr );
}
gpRoofList = NULL;
}
//internal door editing vars.
INT32 iDoorMapIndex = 0;
enum{
DOOR_BACKGROUND,
DOOR_OKAY,
DOOR_CANCEL,
DOOR_LOCKED,
NUM_DOOR_BUTTONS
};
INT32 iDoorButton[ NUM_DOOR_BUTTONS ];
MOUSE_REGION DoorRegion;
void DoorOkayCallback( GUI_BUTTON *btn, INT32 reason );
void DoorCancelCallback( GUI_BUTTON *btn, INT32 reason );
void DoorToggleLockedCallback( GUI_BUTTON *btn, INT32 reason );
extern BOOLEAN OpenableAtGridNo( UINT32 iMapIndex );
void InitDoorEditing( INT32 iMapIndex )
{
DOOR *pDoor;
if( !DoorAtGridNo( iMapIndex ) && !OpenableAtGridNo( iMapIndex ) )
return;
gfEditingDoor = TRUE;
iDoorMapIndex = iMapIndex;
DisableEditorTaskbar();
MSYS_DefineRegion( &DoorRegion, 0, 0, 640, 480, MSYS_PRIORITY_HIGH-2, 0, MSYS_NO_CALLBACK, MSYS_NO_CALLBACK );
iDoorButton[ DOOR_BACKGROUND ] =
CreateTextButton( 0, 0, 0, 0, BUTTON_USE_DEFAULT, 200, 130, 240, 100, BUTTON_TOGGLE, MSYS_PRIORITY_HIGH - 1,
BUTTON_NO_CALLBACK, BUTTON_NO_CALLBACK );
DisableButton( iDoorButton[ DOOR_BACKGROUND ] );
SpecifyDisabledButtonStyle( iDoorButton[ DOOR_BACKGROUND ], DISABLED_STYLE_NONE );
iDoorButton[ DOOR_OKAY ] =
CreateTextButton(L"Okay", FONT12POINT1, FONT_BLACK, FONT_BLACK, BUTTON_USE_DEFAULT,
330, 195, 50, 30, BUTTON_TOGGLE, MSYS_PRIORITY_HIGH, DEFAULT_MOVE_CALLBACK,
DoorOkayCallback );
iDoorButton[ DOOR_CANCEL ] =
CreateTextButton(L"Cancel", FONT12POINT1, FONT_BLACK, FONT_BLACK, BUTTON_USE_DEFAULT,
385, 195, 50, 30, BUTTON_TOGGLE, MSYS_PRIORITY_HIGH, DEFAULT_MOVE_CALLBACK,
DoorCancelCallback );
InitTextInputModeWithScheme( DEFAULT_SCHEME );
AddTextInputField( 210, 155, 25, 16, MSYS_PRIORITY_HIGH, L"0", 3, INPUTTYPE_NUMERICSTRICT );
AddTextInputField( 210, 175, 25, 16, MSYS_PRIORITY_HIGH, L"0", 2, INPUTTYPE_NUMERICSTRICT );
AddTextInputField( 210, 195, 25, 16, MSYS_PRIORITY_HIGH, L"0", 2, INPUTTYPE_NUMERICSTRICT );
iDoorButton[ DOOR_LOCKED ] =
CreateCheckBoxButton( 210, 215, "EDITOR//SmCheckbox.sti", MSYS_PRIORITY_HIGH, DoorToggleLockedCallback );
pDoor = FindDoorInfoAtGridNo( iDoorMapIndex );
if( pDoor )
{
if( pDoor->fLocked )
{
ButtonList[ iDoorButton[ DOOR_LOCKED ] ]->uiFlags |= BUTTON_CLICKED_ON;
}
SetInputFieldStringWithNumericStrictValue( 0, pDoor->ubLockID );
SetInputFieldStringWithNumericStrictValue( 1, pDoor->ubTrapID );
SetInputFieldStringWithNumericStrictValue( 2, pDoor->ubTrapLevel );
}
else
{
ButtonList[ iDoorButton[ DOOR_LOCKED ] ]->uiFlags |= BUTTON_CLICKED_ON;
}
}
void ExtractAndUpdateDoorInfo()
{
LEVELNODE* pNode;
INT32 num;
DOOR door;
BOOLEAN fCursor = FALSE;
BOOLEAN fCursorExists = FALSE;
memset( &door, 0, sizeof( DOOR ) );
door.sGridNo = (INT16)iDoorMapIndex;
num = min( GetNumericStrictValueFromField( 0 ), NUM_LOCKS-1 );
door.ubLockID = (UINT8)num;
SetInputFieldStringWithNumericStrictValue( 0, num );
if( num >= 0 )
fCursor = TRUE;
num = min( max( GetNumericStrictValueFromField( 1 ), 0 ), 10 );
door.ubTrapID = (UINT8)num;
SetInputFieldStringWithNumericStrictValue( 1, num );
if( num )
fCursor = TRUE;
num = min( max( GetNumericStrictValueFromField( 2 ), 0 ), 20 );
if( door.ubTrapID && !num )
num = 1; //Can't have a trap without a traplevel!
door.ubTrapLevel = (UINT8)num;
SetInputFieldStringWithNumericStrictValue( 2, num );
if( num )
fCursor = TRUE;
if( ButtonList[ iDoorButton[ DOOR_LOCKED ] ]->uiFlags & BUTTON_CLICKED_ON )
{
door.fLocked = TRUE;
}
else
{
door.fLocked = FALSE;
}
//Find out if we have a rotating key cursor (we will either add one or remove one)
pNode = gpWorldLevelData[ iDoorMapIndex ].pTopmostHead;
while( pNode )
{
if( pNode->usIndex == ROTATINGKEY1 )
{
fCursorExists = TRUE;
break;
}
pNode = pNode->pNext;
}
if( fCursor )
{ //we have a valid door, so add it (or replace existing)
if( !fCursorExists )
AddTopmostToHead( iDoorMapIndex, ROTATINGKEY1 );
//If the door already exists, the new information will replace it.
AddDoorInfoToTable( &door );
}
else
{ //if a door exists here, remove it.
if( fCursorExists )
RemoveAllTopmostsOfTypeRange( iDoorMapIndex, ROTATINGKEY, ROTATINGKEY );
RemoveDoorInfoFromTable( iDoorMapIndex );
}
}
void FindNextLockedDoor()
{
DOOR *pDoor;
INT32 i;
for( i = iDoorMapIndex + 1; i < WORLD_MAX; i++ )
{
pDoor = FindDoorInfoAtGridNo( i );
if( pDoor )
{
CenterScreenAtMapIndex( i );
iDoorMapIndex = i;
return;
}
}
for( i = 0; i <= iDoorMapIndex; i++ )
{
pDoor = FindDoorInfoAtGridNo( i );
if( pDoor )
{
CenterScreenAtMapIndex( i );
iDoorMapIndex = i;
return;
}
}
}
void RenderDoorEditingWindow()
{
InvalidateRegion( 200, 130, 440, 230 );
SetFont( FONT10ARIAL );
SetFontForeground( FONT_YELLOW );
SetFontShadow( FONT_NEARBLACK );
SetFontBackground( 0 );
mprintf( 210, 140, L"Editing lock attributes at map index %d.", iDoorMapIndex );
SetFontForeground( FONT_GRAY2 );
mprintf( 238, 160, L"Lock ID" );
mprintf( 238, 180, L"Trap Type" );
mprintf( 238, 200, L"Trap Level" );
mprintf( 238, 218, L"Locked" );
}
void KillDoorEditing()
{
INT32 i;
EnableEditorTaskbar();
MSYS_RemoveRegion( &DoorRegion );
for( i = 0; i < NUM_DOOR_BUTTONS; i++ )
RemoveButton( iDoorButton[ i ] );
gfEditingDoor = FALSE;
KillTextInputMode();
}
void DoorOkayCallback( GUI_BUTTON *btn, INT32 reason )
{
if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
{
ExtractAndUpdateDoorInfo();
KillDoorEditing();
}
}
void DoorCancelCallback( GUI_BUTTON *btn, INT32 reason )
{
if( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
{
KillDoorEditing();
}
}
void DoorToggleLockedCallback( GUI_BUTTON *btn, INT32 reason )
{
//handled in ExtractAndUpdateDoorInfo();
}
void AddLockedDoorCursors()
{
DOOR *pDoor;
INT i;
for( i = 0; i < gubNumDoors; i++ )
{
pDoor = &DoorTable[ i ];
AddTopmostToHead( pDoor->sGridNo, ROTATINGKEY1 );
}
}
void RemoveLockedDoorCursors()
{
DOOR *pDoor;
INT i;
LEVELNODE* pNode;
LEVELNODE* pTemp;
for( i = 0; i < gubNumDoors; i++ )
{
pDoor = &DoorTable[ i ];
pNode = gpWorldLevelData[ pDoor->sGridNo ].pTopmostHead;
while( pNode )
{
if( pNode->usIndex == ROTATINGKEY1 )
{
pTemp = pNode;
pNode = pNode->pNext;
RemoveTopmost( pDoor->sGridNo, pTemp->usIndex );
}
else
pNode = pNode->pNext;
}
}
}
void SetupTextInputForBuildings()
{
UINT16 str[4];
InitTextInputModeWithScheme( DEFAULT_SCHEME );
AddUserInputField( NULL ); //just so we can use short cut keys while not typing.
swprintf( str, L"%d", gubMaxRoomNumber );
AddTextInputField( 410, 400, 25, 15, MSYS_PRIORITY_NORMAL, str, 3, INPUTTYPE_NUMERICSTRICT );
}
void ExtractAndUpdateBuildingInfo()
{
UINT16 str[4];
INT32 temp;
//extract light1 colors
temp = min( GetNumericStrictValueFromField( 1 ), 255 );
if( temp != -1 )
{
gubCurrRoomNumber = (UINT8)temp;
}
else
{
gubCurrRoomNumber = 0;
}
swprintf( str, L"%d", gubCurrRoomNumber );
SetInputFieldStringWith16BitString( 1, str );
SetActiveField( 0 );
}
#endif
+67
View File
@@ -0,0 +1,67 @@
#include "BuildDefines.h"
#ifdef JA2EDITOR
#ifndef __EDITORBUILDINGS_H
#define __EDITORBUILDINGS_H
#include "video.h"
#include "vobject_blitters.h"
extern BOOLEAN fBuildingShowRoofs, fBuildingShowWalls, fBuildingShowRoomInfo;
extern UINT8 gubCurrRoomNumber;
extern UINT8 gubMaxRoomNumber;
void SetupTextInputForBuildings();
void ExtractAndUpdateBuildingInfo();
//Initialization routines
void GameInitEditorBuildingInfo();
void InitEditorBuildingsToolbar();
//Selection method callbacks
//Building utility functions
void UpdateBuildingsInfo();
void KillBuilding( UINT32 iMapIndex );
typedef struct BUILDINGLAYOUTNODE
{
struct BUILDINGLAYOUTNODE *next;
INT16 sGridNo;
}BUILDINGLAYOUTNODE;
extern BUILDINGLAYOUTNODE *gpBuildingLayoutList;
extern INT16 gsBuildingLayoutAnchorGridNo;
//The first step is copying a building. After that, it either must be pasted or moved.
void CopyBuilding( INT32 iMapIndex );
void MoveBuilding( INT32 iMapIndex );
void PasteBuilding( INT32 iMapIndex );
void DeleteBuildingLayout();
void ReplaceBuildingWithNewRoof( INT32 iMapIndex );
void UpdateWallsView();
void UpdateRoofsView();
void InitDoorEditing( INT32 iMapIndex );
void ExtractAndUpdateDoorInfo();
void KillDoorEditing();
void RenderDoorEditingWindow();
void AddLockedDoorCursors();
void RemoveLockedDoorCursors();
void FindNextLockedDoor();
extern BOOLEAN gfEditingDoor;
extern UINT16 usCurrentMode;
#endif
#endif
+264
View File
@@ -0,0 +1,264 @@
#include "BuildDefines.h"
#ifdef JA2EDITOR
#ifndef __EDITORDEFINES_H
#define __EDITORDEFINES_H
#include "Types.h"
#include "Button Defines.h"
enum
{
TBAR_MODE_NONE,
TBAR_MODE_DRAW,
TBAR_MODE_ERASE,
TBAR_MODE_UNDO,
TBAR_MODE_EXIT_EDIT,
TBAR_MODE_QUIT_GAME,
TBAR_MODE_NEW_MAP,
TBAR_MODE_SAVE,
TBAR_MODE_LOAD,
TBAR_MODE_SET_BGRND,
TBAR_MODE_CHANGE_BRUSH,
TBAR_MODE_ERASE_OFF,
TBAR_MODE_FILL_AREA,
TBAR_MODE_FILL_AREA_OFF,
TBAR_MODE_DRAW_DEBRIS,
TBAR_MODE_DRAW_BANKS,
TBAR_MODE_DRAW_MERC,
TBAR_MODE_DRAW_NPC1,
TBAR_MODE_DRAW_NPC2,
TBAR_MODE_DRAW_NPC3,
TBAR_MODE_DRAW_NPC4,
TBAR_MODE_DRAW_OSTRUCTS,
TBAR_MODE_DRAW_OSTRUCTS1,
TBAR_MODE_DRAW_OSTRUCTS2,
TBAR_MODE_GET_WALL,
TBAR_MODE_GET_DOOR,
TBAR_MODE_GET_WINDOW,
TBAR_MODE_GET_ROOF,
TBAR_MODE_GET_BROKEN_WALL,
TBAR_MODE_GET_DECOR,
TBAR_MODE_GET_DECAL,
TBAR_MODE_GET_FLOOR,
TBAR_MODE_GET_TOILET,
TBAR_MODE_GET_OSTRUCTS,
TBAR_MODE_GET_OSTRUCTS1,
TBAR_MODE_GET_OSTRUCTS2,
TBAR_MODE_GET_FGRND_TILE,
TBAR_MODE_GET_BGRND_TILE,
TBAR_MODE_GET_DEBRIS,
TBAR_MODE_GET_BANKS,
TBAR_MODE_GET_ROADS,
TBAR_MODE_GET_ROOM,
TBAR_MODE_GET_NEW_ROOF,
TBAR_MODE_GET_TILE_TO_ROOM,
TBAR_MODE_CHANGE_TILESET,
TBAR_MODE_CIVILIAN_GROUP,
TBAR_MODE_FAKE_LIGHTING,
TBAR_MODE_LIGHT_UP,
TBAR_MODE_LIGHT_DWN,
TBAR_MODE_DEC_DIFF,
TBAR_MODE_INC_DIFF,
TBAR_MODE_RAISE_LAND,
TBAR_MODE_LOWER_LAND,
TBAR_MODE_DENS_UP,
TBAR_MODE_DENS_DWN,
TBAR_MODE_MAKE_NEW_ROOM,
TBAR_MODE_ITEM_WEAPONS,
TBAR_MODE_ITEM_AMMO,
TBAR_MODE_ITEM_ARMOUR,
TBAR_MODE_ITEM_EXPLOSIVES,
TBAR_MODE_ITEM_EQUIPMENT1,
TBAR_MODE_ITEM_EQUIPMENT2,
TBAR_MODE_ITEM_EQUIPMENT3,
TBAR_MODE_ITEM_TRIGGERS,
TBAR_MODE_ITEM_KEYS,
};
enum
{
TASK_NONE,
TASK_TERRAIN,
TASK_BUILDINGS,
TASK_ITEMS,
TASK_MERCS,
TASK_MAPINFO,
TASK_OPTIONS
};
enum
{
ACTION_NULL,
ACTION_SUB_INDEX_UP,
ACTION_SUB_INDEX_DWN,
ACTION_SET_NEW_BACKGROUND,
ACTION_EXIT_EDITOR,
ACTION_QUIT_GAME,
ACTION_NEXT_FGRND,
ACTION_SWITCH_SCRN,
ACTION_NEXT_LEVEL,
ACTION_NEXT_WALL,
ACTION_FILL_AREA,
ACTION_NEXT_DEBRIS,
ACTION_NEXT_DECAL,
ACTION_CHANGE_ELEV,
ACTION_PREV_SELECTIONTYPE,
ACTION_NEXT_SELECTIONTYPE,
ACTION_SET_FNAME,
ACTION_SAVE_MAP,
ACTION_LOAD_MAP,
ACTION_UNDO,
ACTION_NEXT_BANK,
ACTION_NEXT_ROAD,
ACTION_NEXT_CLIFF,
ACTION_SHADE_UP,
ACTION_SHADE_DWN,
ACTION_WALL_PASTE1,
ACTION_WALL_PASTE2,
ACTION_NEXT_STRUCT,
ACTION_GET_ROOM,
ACTION_NEW_MAP,
//using the selection method for getting objects for buildings
ACTION_GET_WALL,
ACTION_GET_DOOR,
ACTION_GET_WINDOW,
ACTION_GET_ROOF,
ACTION_GET_BROKEN_WALL,
ACTION_GET_DECOR,
ACTION_GET_DECAL,
ACTION_GET_FLOOR,
ACTION_GET_TOILET,
ACTION_GET_NEW_ROOF,
ACTION_SET_MERC,
ACTION_QUICK_ERASE,
ACTION_HELPSCREEN,
ACTION_NEXT_STRUCT1,
ACTION_NEXT_STRUCT2,
ACTION_DRAW_BADMERC,
ACTION_EDIT_BADMERC,
ACTION_DRAW_GOODMERC,
ACTION_EDIT_GOODMERC,
ACTION_RAISE_LAND,
ACTION_LOWER_LAND,
ACTION_SET_WAYPOINT,
ACTION_ERASE_WAYPOINT,
ACTION_DENSITY_UP,
ACTION_DENSITY_DOWN,
ACTION_COPY_MERC_PLACEMENT,
ACTION_PASTE_MERC_PLACEMENT,
};
enum
{
DRAW_MODE_NOTHING,
//Terrain
DRAW_MODE_GROUND,
DRAW_MODE_NEW_GROUND,
DRAW_MODE_DEBRIS,
DRAW_MODE_BANKS,
DRAW_MODE_ROADS,
DRAW_MODE_OSTRUCTS,
DRAW_MODE_OSTRUCTS1,
DRAW_MODE_OSTRUCTS2,
//Selection method for buildings
DRAW_MODE_WALLS,
DRAW_MODE_DOORS,
DRAW_MODE_WINDOWS,
DRAW_MODE_ROOFS,
DRAW_MODE_NEWROOF,
DRAW_MODE_BROKEN_WALLS,
DRAW_MODE_DECOR,
DRAW_MODE_DECALS,
DRAW_MODE_FLOORS,
//Smart method for buildings
DRAW_MODE_SMART_WALLS,
DRAW_MODE_SMART_WINDOWS,
DRAW_MODE_SMART_DOORS,
DRAW_MODE_SMART_BROKEN_WALLS,
DRAW_MODE_DOORKEYS,
//Other stuff
DRAW_MODE_TOILET,
DRAW_MODE_ROOM,
DRAW_MODE_SAW_ROOM,
DRAW_MODE_ROOMNUM,
DRAW_MODE_CAVES,
DRAW_MODE_SLANTED_ROOF,
DRAW_MODE_KILL_BUILDING,
DRAW_MODE_COPY_BUILDING,
DRAW_MODE_MOVE_BUILDING,
DRAW_MODE_SHOW_TILESET,
DRAW_MODE_LIGHT,
DRAW_MODE_PLAYER,
DRAW_MODE_ENEMY,
DRAW_MODE_CREATURE,
DRAW_MODE_REBEL,
DRAW_MODE_CIVILIAN,
DRAW_MODE_SCHEDULEACTION,
DRAW_MODE_SCHEDULECONFIRM,
DRAW_MODE_EXITGRID,
DRAW_MODE_EXITGRID_QUEUE,
DRAW_MODE_NORTHPOINT,
DRAW_MODE_WESTPOINT,
DRAW_MODE_EASTPOINT,
DRAW_MODE_SOUTHPOINT,
DRAW_MODE_CENTERPOINT,
DRAW_MODE_ISOLATEDPOINT,
DRAW_MODE_PLACE_ITEM,
DRAW_MODE_SELECT_BRUSH = 200,
DRAW_MODE_FILL_AREA,
DRAW_MODE_UNDO,
DRAW_MODE_ERASE = 1000
};
extern INT32 iEditorButton[NUMBER_EDITOR_BUTTONS];
extern INT32 iEditorToolbarState;
extern INT32 iDrawMode;
extern INT32 iCurrentAction;
extern INT32 iActionParam;
extern INT32 iEditAction;
extern UINT16 gusLightLevel;
extern UINT16 gusLightLevelPercentage;
extern INT16 gsLightRadius;
extern BOOLEAN gfRenderWorld;
extern BOOLEAN gfRenderTaskbar;
extern BOOLEAN gfShowTerrainTileButtons;
extern BOOLEAN gfRenderDrawingMode;
extern BOOLEAN gfPendingBasement;
extern BOOLEAN gfPendingCaves;
//When in merc-inventory mode, this flag is set when the user wishes to get an item, which requires hooking
//into the item editing features. It is defined here, so editoritems can get access to this mode which makes
//certain special cases.
extern BOOLEAN gfMercGetItem;
//When actually editing item statistics, this value will be set, for the purposes of rendering, input, etc.
extern BOOLEAN gfShowItemStatsPanel;
#define MERCPANEL_X 177
#define MERCPANEL_Y 361
#endif
#endif
File diff suppressed because it is too large Load Diff
+69
View File
@@ -0,0 +1,69 @@
#include "BuildDefines.h"
#ifdef JA2EDITOR
#ifndef __EDITORITEMS_H
#define __EDITORITEMS_H
typedef struct{
BOOLEAN fGameInit; //Used for initializing save variables the first time.
//This flag is initialize at
BOOLEAN fKill; //flagged for deallocation.
BOOLEAN fActive; //currently active
UINT16 *pusItemIndex; //a dynamic array of Item indices
UINT32 uiBuffer; //index of buffer
UINT32 uiItemType; //Weapons, ammo, armour, explosives, equipment
INT16 sWidth, sHeight; //width and height of buffer
INT16 sNumItems; //total number of items in the current class of item.
INT16 sSelItemIndex; //currently selected item index.
INT16 sHilitedItemIndex;
INT16 sScrollIndex; //current scroll index (0 is far left, 1 is next tile to the right, ...)
INT16 sSaveSelWeaponsIndex, sSaveSelAmmoIndex, sSaveSelArmourIndex, sSaveSelExplosivesIndex,
sSaveSelEquipment1Index, sSaveSelEquipment2Index, sSaveSelEquipment3Index,
sSaveSelTriggersIndex, sSaveSelKeysIndex;
INT16 sSaveWeaponsScrollIndex, sSaveAmmoScrollIndex, sSaveArmourScrollIndex, sSaveExplosivesScrollIndex,
sSaveEquipment1ScrollIndex, sSaveEquipment2ScrollIndex, sSaveEquipment3ScrollIndex,
sSaveTriggersScrollIndex, sSaveKeysScrollIndex;
INT16 sNumWeapons, sNumAmmo, sNumArmour, sNumExplosives, sNumEquipment1, sNumEquipment2, sNumEquipment3,
sNumTriggers, sNumKeys;
}EditorItemsInfo;
extern EditorItemsInfo eInfo;
void InitEditorItemsToolbar();
void EntryInitEditorItemsInfo();
void InitEditorItemsInfo(UINT32 uiItemType);
void RenderEditorItemsInfo();
void ClearEditorItemsInfo();
void DisplayItemStatistics();
void DetermineItemsScrolling();
//User actions
void AddSelectedItemToWorld( INT16 sGridNo );
void HandleRightClickOnItem( INT16 sGridNo );
void DeleteSelectedItem();
void ShowSelectedItem();
void HideSelectedItem();
void SelectNextItemPool();
void SelectNextItemInPool();
void SelectPrevItemInPool();
void KillItemPoolList();
void BuildItemPoolList();
void HideItemCursor( INT32 iMapIndex );
void ShowItemCursor( INT32 iMapIndex );
void SetEditorItemsTaskbarMode( UINT16 usNewMode );
void HandleItemsPanel( UINT16 usScreenX, UINT16 usScreenY, INT8 bEvent );
extern INT32 giDefaultExistChance;
#endif
#endif
+300
View File
@@ -0,0 +1,300 @@
#ifdef PRECOMPILEDHEADERS
#include "Editor All.h"
#else
#include "builddefines.h"
#endif
#ifdef JA2EDITOR
#ifndef PRECOMPILEDHEADERS
#include <windows.h>
#include "tiledef.h"
#include "edit_sys.h"
#include "vsurface.h"
#include "vobject.h"
#include "mousesystem.h"
#include "Button System.h"
#include "wcheck.h"
#include "vsurface.h"
#include "line.h"
#include "input.h"
#include "sysutil.h"
#include "font.h"
#include "Font Control.h"
#include "editscreen.h"
#include "selectwin.h"
#include "video.h"
#include "vobject_blitters.h"
#include "interface panels.h"
#include "interface items.h"
#include "utilities.h"
#include "World Items.h"
#include "worldman.h"
#include "overhead.h" //GetSoldier
#include "renderworld.h"
#include "Animation Data.h"
#include "Animation Control.h"
#include "lighting.h"
#include "EditorDefines.h"
#include "EditorMercs.h"
#include "EditorTerrain.h" //for access to TerrainTileDrawMode
#include "Soldier Create.h" //The stuff that connects the editor generated information
#include "Soldier Init List.h"
#include "strategicmap.h"
#include "Soldier Add.h"
#include "Soldier Control.h"
#include "Soldier Profile Type.h"
#include "Soldier Profile.h"
#include "Text Input.h"
#include "Random.h"
#include "wordwrap.h"
#include "EditorItems.h"
#include "Editor Taskbar Utils.h"
#include "Exit Grids.h"
#include "Editor Undo.h"
#include "Item Statistics.h"
#include "Map Information.h"
#include "EditorMapInfo.h"
#include "environment.h"
#include "Simple Render Utils.h"
#endif
INT8 gbDefaultLightType = PRIMETIME_LIGHT;
SGPPaletteEntry gEditorLightColor;
BOOLEAN gfEditorForceShadeTableRebuild = FALSE;
void SetupTextInputForMapInfo()
{
UINT16 str[10];
InitTextInputModeWithScheme( DEFAULT_SCHEME );
AddUserInputField( NULL ); //just so we can use short cut keys while not typing.
//light rgb fields
swprintf( str, L"%d", gEditorLightColor.peRed );
AddTextInputField( 10, 394, 25, 18, MSYS_PRIORITY_NORMAL, str, 3, INPUTTYPE_NUMERICSTRICT );
swprintf( str, L"%d", gEditorLightColor.peGreen );
AddTextInputField( 10, 414, 25, 18, MSYS_PRIORITY_NORMAL, str, 3, INPUTTYPE_NUMERICSTRICT );
swprintf( str, L"%d", gEditorLightColor.peBlue );
AddTextInputField( 10, 434, 25, 18, MSYS_PRIORITY_NORMAL, str, 3, INPUTTYPE_NUMERICSTRICT );
swprintf( str, L"%d", gsLightRadius );
AddTextInputField( 120, 394, 25, 18, MSYS_PRIORITY_NORMAL, str, 3, INPUTTYPE_NUMERICSTRICT );
swprintf( str, L"%d", gusLightLevel );
AddTextInputField( 120, 414, 25, 18, MSYS_PRIORITY_NORMAL, str, 2, INPUTTYPE_NUMERICSTRICT );
//Scroll restriction ID
if( !gMapInformation.ubRestrictedScrollID )
swprintf( str, L"" );
else
swprintf( str, L"%d", gMapInformation.ubRestrictedScrollID );
AddTextInputField( 210, 420, 30, 20, MSYS_PRIORITY_NORMAL, str, 2, INPUTTYPE_NUMERICSTRICT );
//exit grid input fields
swprintf( str, L"%c%d", gExitGrid.ubGotoSectorY + 'A' - 1, gExitGrid.ubGotoSectorX );
AddTextInputField( 338, 363, 30, 18, MSYS_PRIORITY_NORMAL, str, 3, INPUTTYPE_EXCLUSIVE_COORDINATE );
swprintf( str, L"%d", gExitGrid.ubGotoSectorZ );
AddTextInputField( 338, 383, 30, 18, MSYS_PRIORITY_NORMAL, str, 1, INPUTTYPE_NUMERICSTRICT );
swprintf( str, L"%d", gExitGrid.usGridNo );
AddTextInputField( 338, 403, 40, 18, MSYS_PRIORITY_NORMAL, str, 5, INPUTTYPE_NUMERICSTRICT );
}
void UpdateMapInfo()
{
SetFont( FONT10ARIAL );
SetFontShadow( FONT_NEARBLACK );
SetFontForeground( FONT_RED );
mprintf( 38, 399, L"R");
SetFontForeground( FONT_GREEN );
mprintf( 38, 419, L"G");
SetFontForeground( FONT_DKBLUE );
mprintf( 38, 439, L"B");
SetFontForeground( FONT_YELLOW );
mprintf( 65, 369, L"Prime" );
mprintf( 65, 382, L"Night" );
mprintf( 65, 397, L"24Hrs" );
SetFontForeground( FONT_YELLOW );
mprintf( 148, 399, L"Radius");
if( !gfBasement && !gfCaves )
SetFontForeground( FONT_DKYELLOW );
mprintf( 148, 414, L"Underground" );
mprintf( 148, 423, L"Light Level" );
SetFontForeground( FONT_YELLOW );
mprintf( 230, 369, L"Outdoors" );
mprintf( 230, 384, L"Basement" );
mprintf( 230, 399, L"Caves" );
SetFontForeground( FONT_ORANGE );
mprintf( 250, 420, L"Restricted" );
mprintf( 250, 430, L"Scroll ID" );
SetFontForeground( FONT_YELLOW );
mprintf( 368, 363, L"Destination");
mprintf( 368, 372, L"Sector" );
mprintf( 368, 383, L"Destination");
mprintf( 368, 392, L"Bsmt. Level" );
mprintf( 378, 403, L"Dest." );
mprintf( 378, 412, L"GridNo" );
SetFontForeground( FONT_RED );
}
void UpdateMapInfoFields()
{
UINT16 str[10];
//Update the text fields to reflect the validated values.
//light rgb fields
swprintf( str, L"%d", gEditorLightColor.peRed );
SetInputFieldStringWith16BitString( 1, str );
swprintf( str, L"%d", gEditorLightColor.peGreen );
SetInputFieldStringWith16BitString( 2, str );
swprintf( str, L"%d", gEditorLightColor.peBlue );
SetInputFieldStringWith16BitString( 3, str );
swprintf( str, L"%d", gsLightRadius );
SetInputFieldStringWith16BitString( 4, str );
swprintf( str, L"%d", gusLightLevel );
SetInputFieldStringWith16BitString( 5, str );
if( !gMapInformation.ubRestrictedScrollID )
swprintf( str, L"" );
else
swprintf( str, L"%d", gMapInformation.ubRestrictedScrollID );
SetInputFieldStringWith16BitString( 6, str );
ApplyNewExitGridValuesToTextFields();
}
void ExtractAndUpdateMapInfo()
{
UINT16 str[10];
INT32 temp;
BOOLEAN fUpdateLight1 = FALSE;
//extract light1 colors
temp = min( GetNumericStrictValueFromField( 1 ), 255 );
if( temp != -1 && temp != gEditorLightColor.peRed )
{
fUpdateLight1 = TRUE;
gEditorLightColor.peRed = (UINT8)temp;
}
temp = min( GetNumericStrictValueFromField( 2 ), 255 );
if( temp != -1 && temp != gEditorLightColor.peGreen )
{
fUpdateLight1 = TRUE;
gEditorLightColor.peGreen = (UINT8)temp;
}
temp = min( GetNumericStrictValueFromField( 3 ), 255 );
if( temp != -1 && temp != gEditorLightColor.peBlue )
{
fUpdateLight1 = TRUE;
gEditorLightColor.peBlue = (UINT8)temp;
}
if( fUpdateLight1 )
{
gfEditorForceShadeTableRebuild = TRUE;
LightSetColors( &gEditorLightColor, 1 );
gfEditorForceShadeTableRebuild = FALSE;
}
//extract radius
temp = max( min( GetNumericStrictValueFromField( 4 ), 8 ), 1 );
if( temp != -1 )
gsLightRadius = (INT16)temp;
temp = max( min( GetNumericStrictValueFromField( 5 ), 15 ), 1 );
if( temp != -1 && temp != gusLightLevel )
{
gusLightLevel = (UINT16)temp;
gfRenderWorld = TRUE;
ubAmbientLightLevel = (UINT8)(EDITOR_LIGHT_MAX - gusLightLevel);
LightSetBaseLevel( ubAmbientLightLevel );
LightSpriteRenderAll();
}
temp = (INT8)GetNumericStrictValueFromField( 6 );
if( temp == -1 )
gMapInformation.ubRestrictedScrollID = 0;
else
gMapInformation.ubRestrictedScrollID = (UINT8)temp;
//set up fields for exitgrid information
Get16BitStringFromField( 7, str );
if( str[0] >= 'a' && str[0] <= 'z' )
str[0] -= 32; //uppercase it!
if( str[0] >= 'A' && str[0] <= 'Z' &&
str[1] >= '0' && str[1] <= '9' )
{ //only update, if coordinate is valid.
gExitGrid.ubGotoSectorY = (UINT8)(str[0] - 'A' + 1);
gExitGrid.ubGotoSectorX = (UINT8)(str[1] - '0');
if( str[2] >= '0' && str[2] <= '9' )
gExitGrid.ubGotoSectorX = (UINT8)(gExitGrid.ubGotoSectorX * 10 + str[2] - '0' );
gExitGrid.ubGotoSectorX = (UINT8)max( min( gExitGrid.ubGotoSectorX, 16 ), 1 );
gExitGrid.ubGotoSectorY = (UINT8)max( min( gExitGrid.ubGotoSectorY, 16 ), 1 );
}
gExitGrid.ubGotoSectorZ = (UINT8)max( min( GetNumericStrictValueFromField( 8 ), 3 ), 0 );
gExitGrid.usGridNo = (UINT16)max( min( GetNumericStrictValueFromField( 9 ), 25600 ), 0 );
UpdateMapInfoFields();
}
BOOLEAN ApplyNewExitGridValuesToTextFields()
{
UINT16 str[10];
//exit grid input fields
if( iCurrentTaskbar != TASK_MAPINFO )
return FALSE;
swprintf( str, L"%c%d", gExitGrid.ubGotoSectorY + 'A' - 1, gExitGrid.ubGotoSectorX );
SetInputFieldStringWith16BitString( 7, str );
swprintf( str, L"%d", gExitGrid.ubGotoSectorZ );
SetInputFieldStringWith16BitString( 8, str );
swprintf( str, L"%d", gExitGrid.usGridNo );
SetInputFieldStringWith16BitString( 9, str );
SetActiveField( 0 );
return TRUE;
}
UINT16 usCurrentExitGridNo = 0;
void LocateNextExitGrid()
{
EXITGRID ExitGrid;
UINT16 i;
for( i = usCurrentExitGridNo + 1; i < WORLD_MAX; i++ )
{
if( GetExitGrid( i, &ExitGrid ) )
{
usCurrentExitGridNo = i;
CenterScreenAtMapIndex( i );
return;
}
}
for( i = 0; i < usCurrentExitGridNo; i++ )
{
if( GetExitGrid( i, &ExitGrid ) )
{
usCurrentExitGridNo = i;
CenterScreenAtMapIndex( i );
return;
}
}
}
void ChangeLightDefault( INT8 bLightType )
{
UnclickEditorButton( MAPINFO_PRIMETIME_LIGHT + gbDefaultLightType );
gbDefaultLightType = bLightType;
ClickEditorButton( MAPINFO_PRIMETIME_LIGHT + gbDefaultLightType );
}
#endif
+35
View File
@@ -0,0 +1,35 @@
#include "BuildDefines.h"
#ifdef JA2EDITOR
#ifndef __EDITORMAPINFO_H
#define __EDITORMAPINFO_H
void SetupTextInputForMapInfo();
void UpdateMapInfo();
void ExtractAndUpdateMapInfo();
BOOLEAN ApplyNewExitGridValuesToTextFields();
void UpdateMapInfoFields();
extern SGPPaletteEntry gEditorLightColor;
extern BOOLEAN gfEditorForceShadeTableRebuild;
void LocateNextExitGrid();
enum
{
PRIMETIME_LIGHT,
NIGHTTIME_LIGHT,
ALWAYSON_LIGHT
};
void ChangeLightDefault( INT8 bLightType );
extern INT8 gbDefaultLightType;
#endif
#endif
File diff suppressed because it is too large Load Diff
+156
View File
@@ -0,0 +1,156 @@
#include "BuildDefines.h"
#ifdef JA2EDITOR
#ifndef __EDITORMERCS_H
#define __EDITORMERCS_H
//Merc editing modes. These are used to determine which buttons to show and hide.
enum
{
MERC_NOMODE, //used for shutting down mercs tab, to extract any changed information
MERC_GETITEMMODE, //when selecting a specific piece of inventory from inventorymode
MERC_TEAMMODE, //selecting a team with no merc selected.
MERC_BASICMODE, //basic placement mode
MERC_GENERALMODE, //detailed placement mode for general information and NPC info
MERC_ATTRIBUTEMODE, //detailed placement mode for specifying attributes
MERC_INVENTORYMODE, //detailed placement mode for specifying inventory
MERC_APPEARANCEMODE, //detailed placement mode for specifying appearance
MERC_PROFILEMODE, //specifying a valid profile index will generate the merc automatically.
MERC_SCHEDULEMODE, //specifying a schedule for that particular individual
};
extern UINT8 gubCurrMercMode, gubPrevMercMode;
#define EDIT_NUM_COLORS 4
#define EDIT_COLOR_HEAD 0
#define EDIT_COLOR_PANTS 1
#define EDIT_COLOR_SKIN 2
#define EDIT_COLOR_VEST 3
#define EDIT_MERC_NONE 0
#define EDIT_MERC_DEC_STAT 1
#define EDIT_MERC_INC_STAT 2
#define EDIT_MERC_PREV_ORDER 3
#define EDIT_MERC_NEXT_ORDER 4
#define EDIT_MERC_PREV_ATT 5
#define EDIT_MERC_NEXT_ATT 6
#define EDIT_MERC_SET_DIR 7
#define EDIT_MERC_FIND 8
#define EDIT_MERC_DONE 9
#define EDIT_MERC_TO_COLOR 10
#define EDIT_MERC_TO_STATS 11
#define EDIT_MERC_PREV_COLOR 12
#define EDIT_MERC_NEXT_COLOR 13
#define NUM_MERC_BUTTONS 40
#define NUM_DIFF_LVLS 5
extern UINT16 *zDiffNames[NUM_DIFF_LVLS];
extern INT16 sCurBaseDiff;
extern INT16 gsSelectedMercID;
extern INT16 gsSelectedMercGridNo;
extern UINT8 gubCurrMercMode;
enum _ForUseWithIndicateSelectedMerc
{
SELECT_NEXT_CREATURE = -7,
SELECT_NEXT_REBEL = -6,
SELECT_NEXT_CIV = -5,
SELECT_NEXT_ENEMY = -4,
SELECT_NEXT_TEAMMATE = -3,
SELECT_NEXT_MERC = -2,
SELECT_NO_MERC = -1
// >= 0 select merc with matching ID
};
void IndicateSelectedMerc( INT16 sID );
void GameInitEditorMercsInfo();
void GameShutdownEditorMercsInfo();
void EntryInitEditorMercsInfo();
void UpdateMercsInfo();
void ProcessMercEditing();
void AddMercToWorld( INT32 iMapIndex );
void HandleRightClickOnMerc( INT32 iMapIndex );
void SetMercEditingMode( UINT8 ubNewMode );
void ResetAllMercPositions();
void EraseMercWaypoint();
void AddMercWaypoint( UINT32 iMapIndex );
void SetEnemyColorCode( UINT8 ubColorCode );
void SpecifyEntryPoint( UINT32 iMapIndex );
//Modify stats of current soldiers
void SetMercOrders( INT8 bOrders );
void SetMercAttitude( INT8 bAttitude );
void SetMercDirection( INT8 bDirection );
void SetMercRelativeEquipment( INT8 bLevel );
void SetMercRelativeAttributes( INT8 bLevel );
void DeleteSelectedMerc();
void CreateEditMercWindow( void );
void DisplayEditMercWindow( void );
INT32 IsMercHere( INT32 iMapIndex );
void ExtractCurrentMercModeInfo( BOOLEAN fKillTextInputMode );
void SetMercEditability( BOOLEAN fEditable );
void HandleMercInventoryPanel( INT16 sX, INT16 sY, INT8 bEvent );
extern UINT16 gusMercsNewItemIndex;
extern BOOLEAN gfRenderMercInfo;
void ChangeCivGroup( UINT8 ubNewCivGroup );
#define MERCINV_LGSLOT_WIDTH 48
#define MERCINV_SMSLOT_WIDTH 24
#define MERCINV_SLOT_HEIGHT 18
extern BOOLEAN gfRoofPlacement;
extern void SetEnemyDroppableStatus( UINT32 uiSlot, BOOLEAN fDroppable );
void RenderMercStrings();
extern BOOLEAN gfShowPlayers;
extern BOOLEAN gfShowEnemies;
extern BOOLEAN gfShowCreatures;
extern BOOLEAN gfShowRebels;
extern BOOLEAN gfShowCivilians;
void SetMercTeamVisibility( INT8 bTeam, BOOLEAN fVisible );
extern UINT8 gubCurrentScheduleActionIndex;
extern BOOLEAN gfSingleAction;
extern BOOLEAN gfUseScheduleData2;
void UpdateScheduleAction( UINT8 ubNewAction );
void FindScheduleGridNo( UINT8 ubScheduleData );
void ClearCurrentSchedule();
void CancelCurrentScheduleAction();
void RegisterCurrentScheduleAction( INT32 iMapIndex );
void StartScheduleAction();
void InitDetailedPlacementForMerc();
void KillDetailedPlacementForMerc();
void CopyMercPlacement( INT32 iMapIndex );
void PasteMercPlacement( INT32 iMapIndex );
#endif
#endif
+284
View File
@@ -0,0 +1,284 @@
#ifdef PRECOMPILEDHEADERS
#include "Editor All.h"
#else
#include "builddefines.h"
#endif
#ifdef JA2EDITOR
#ifndef PRECOMPILEDHEADERS
#include <windows.h>
#include "tiledef.h"
#include "edit_sys.h"
#include "vsurface.h"
#include "vobject.h"
#include "mousesystem.h"
#include "Button System.h"
#include "wcheck.h"
#include "vsurface.h"
#include "input.h"
#include "sysutil.h"
#include "font.h"
#include "Font Control.h"
#include "editscreen.h"
#include "selectwin.h"
#include "video.h"
#include "vobject_blitters.h"
#include "interface panels.h"
#include "utilities.h"
#include "World Items.h"
#include "EditorDefines.h"
#include "EditorTerrain.h"
#include "Editor Taskbar Utils.h"
#include "Cursor Modes.h"
#include "english.h"
#endif
BOOLEAN gfShowTerrainTileButtons;
UINT8 ubTerrainTileButtonWeight[NUM_TERRAIN_TILE_REGIONS];
UINT16 usTotalWeight;
BOOLEAN fPrevShowTerrainTileButtons = TRUE;
BOOLEAN fUseTerrainWeights = FALSE;
INT32 TerrainTileSelected = 0, TerrainForegroundTile, TerrainBackgroundTile;
INT32 TerrainTileDrawMode = TERRAIN_TILES_NODRAW;
void EntryInitEditorTerrainInfo()
{
//ResetTerrainTileWeights();
if( !fUseTerrainWeights )
{
ResetTerrainTileWeights();
}
}
void ResetTerrainTileWeights()
{
INT8 x;
for( x=0; x < NUM_TERRAIN_TILE_REGIONS; x++ )
{
ubTerrainTileButtonWeight[x] = 0;
}
usTotalWeight = 0;
fUseTerrainWeights = FALSE;
gfRenderTaskbar = TRUE;
}
void HideTerrainTileButtons()
{
INT8 x;
if( gfShowTerrainTileButtons )
{
for( x = BASE_TERRAIN_TILE_REGION_ID; x < NUM_TERRAIN_TILE_REGIONS; x++ )
{
DisableEditorRegion( x );
}
gfShowTerrainTileButtons=FALSE;
}
}
void ShowTerrainTileButtons()
{
INT8 x;
if( !gfShowTerrainTileButtons )
{
for( x = BASE_TERRAIN_TILE_REGION_ID; x < NUM_TERRAIN_TILE_REGIONS; x++ )
{
EnableEditorRegion( x );
}
gfShowTerrainTileButtons=TRUE;
}
}
void RenderTerrainTileButtons()
{
// If needed, display the ground tile images
if(gfShowTerrainTileButtons)
{
UINT16 usFillColorDark, usFillColorLight, usFillColorRed;
UINT16 x, usX, usX2, usY, usY2;
usFillColorDark = Get16BPPColor(FROMRGB(24, 61, 81));
usFillColorLight = Get16BPPColor(FROMRGB(136, 138, 135));
usFillColorRed = Get16BPPColor(FROMRGB(255, 0, 0));
usY = 369;
usY2 = 391;
SetFont( SMALLCOMPFONT );
SetFontForeground( FONT_YELLOW );
for( x = 0; x < NUM_TERRAIN_TILE_REGIONS; x++ )
{
usX = 261 + (x * 42);
usX2 = usX + 42;
if ( x == CurrentPaste && !fUseTerrainWeights )
{
ColorFillVideoSurfaceArea(ButtonDestBuffer , usX, usY, usX2, usY2, usFillColorRed);
}
else
{
ColorFillVideoSurfaceArea(ButtonDestBuffer, usX, usY, usX2, usY2, usFillColorDark);
ColorFillVideoSurfaceArea(ButtonDestBuffer, usX + 1, usY + 1, usX2, usY2, usFillColorLight);
}
ColorFillVideoSurfaceArea(ButtonDestBuffer, usX + 1, usY + 1, usX2 - 1, usY2 - 1, 0);
SetObjectShade( gTileDatabase[gTileTypeStartIndex[x]].hTileSurface, DEFAULT_SHADE_LEVEL );
BltVideoObject(ButtonDestBuffer, gTileDatabase[gTileTypeStartIndex[x]].hTileSurface, 0, (usX + 1), (usY + 1),
VO_BLT_SRCTRANSPARENCY, NULL);
if( fUseTerrainWeights )
{
mprintf( usX+2, usY+2, L"%d", ubTerrainTileButtonWeight[ x ] );
}
}
}
}
//This callback is used for each of the terrain tile buttons. The userData[0] field
//contains the terrain button's index value.
void TerrainTileButtonRegionCallback(MOUSE_REGION *reg,INT32 reason)
{
if(reason & MSYS_CALLBACK_REASON_LBUTTON_UP)
{
gfRenderTaskbar = TRUE;
TerrainTileSelected = MSYS_GetRegionUserData(reg,0);
if(TerrainTileDrawMode == TERRAIN_TILES_FOREGROUND )
{
TerrainForegroundTile = TerrainTileSelected;
CurrentPaste = (UINT16)TerrainForegroundTile;
//iEditorToolbarState = TBAR_MODE_DRAW;
if( _KeyDown( SHIFT ) )
{
fUseTerrainWeights = TRUE;
}
if( fUseTerrainWeights )
{
//SHIFT+LEFTCLICK adds weight to the selected terrain tile.
if( ubTerrainTileButtonWeight[ TerrainTileSelected ] < 10 )
{
ubTerrainTileButtonWeight[ TerrainTileSelected ]++;
usTotalWeight++;
}
}
else
{ //Regular LEFTCLICK selects only that terrain tile.
//When total weight is 0, then the only selected tile is drawn.
ResetTerrainTileWeights();
}
}
else if(TerrainTileDrawMode == TERRAIN_TILES_BACKGROUND )
{
TerrainBackgroundTile = TerrainTileSelected;
iEditorToolbarState = TBAR_MODE_SET_BGRND;
}
}
if(reason & MSYS_CALLBACK_REASON_RBUTTON_UP)
{
gfRenderTaskbar = TRUE;
TerrainTileSelected = MSYS_GetRegionUserData( reg, 0 );
if(TerrainTileDrawMode == TERRAIN_TILES_FOREGROUND )
{
TerrainForegroundTile = TerrainTileSelected;
iEditorToolbarState = TBAR_MODE_DRAW;
if( ubTerrainTileButtonWeight[ TerrainTileSelected ] )
{
ubTerrainTileButtonWeight[ TerrainTileSelected ]--;
usTotalWeight--;
}
}
}
}
void ChooseWeightedTerrainTile()
{
UINT16 x, usWeight;
INT16 sRandomNum;
if(!usTotalWeight)
{ //Not in the weighted mode. CurrentPaste will already contain the selected tile.
return;
}
sRandomNum = rand() % usTotalWeight;
x = NUM_TERRAIN_TILE_REGIONS;
for( x = 0; x < NUM_TERRAIN_TILE_REGIONS; x++ )
{
usWeight = ubTerrainTileButtonWeight[ x ];
sRandomNum -= usWeight;
if( sRandomNum <= 0 && usWeight )
{
CurrentPaste = x;
return;
}
}
}
UINT32 guiSearchType;
// TODO: change this variable name if not too time consuming (jonathanl)
extern UINT32 count; // symbol exist already in gamescreen.cpp, this is a REALLY bad global symbol name!!! (jonathanl)
UINT32 maxCount=0, calls=0;
void Fill( INT32 x, INT32 y )
{
INT32 iMapIndex;
UINT32 uiCheckType;
count++;
calls++;
if( count > maxCount )
maxCount = count;
iMapIndex = y * WORLD_COLS + x;
if( !GridNoOnVisibleWorldTile( (INT16)iMapIndex ) )
{
count--;
return;
}
GetTileType( gpWorldLevelData[ iMapIndex ].pLandHead->usIndex , &uiCheckType );
if( guiSearchType == uiCheckType )
PasteTextureCommon( iMapIndex );
else
{
count--;
return;
}
if( y > 0 )
Fill( x, y-1 );
if( y < WORLD_ROWS - 1 )
Fill( x, y+1 );
if( x > 0 )
Fill( x-1, y );
if( x < WORLD_COLS - 1 )
Fill( x+1, y );
count--;
}
void TerrainFill( UINT32 iMapIndex )
{
INT16 sX, sY;
//determine what we should be looking for to replace...
GetTileType( gpWorldLevelData[ iMapIndex ].pLandHead->usIndex, &guiSearchType );
//check terminating conditions
if( guiSearchType == CurrentPaste )
return;
ConvertGridNoToXY( (INT16)iMapIndex, &sX, &sY );
count = 0;
Fill( sX, sY );
}
#endif
+43
View File
@@ -0,0 +1,43 @@
#include "BuildDefines.h"
#ifdef JA2EDITOR
#ifndef __EDITORTERRAIN_H
#define __EDITORTERRAIN_H
#define TERRAIN_TILES_NODRAW 0
#define TERRAIN_TILES_FOREGROUND 1
#define TERRAIN_TILES_BACKGROUND 2
//Andrew, could you figure out what the hell mode this is???
//It somehow links terrain tiles with lights and buildings.
#define TERRAIN_TILES_BRETS_STRANGEMODE 3
//Soon to be added to an editor struct
extern UINT16 usTotalWeight;
extern BOOLEAN fPrevShowTerrainTileButtons;
extern BOOLEAN fUseTerrainWeights;
extern INT32 TerrainTileSelected, TerrainForegroundTile,TerrainBackgroundTile;
extern INT32 TerrainTileDrawMode;
void EntryInitEditorTerrainInfo();
void InitEditorTerrainToolbar();
void CreateTerrainTileButtons();
void DeleteTerrainTileButtons();
void RenderTerrainTileButtons();
void ResetTerrainTileWeights();
void ShowTerrainTileButtons();
void HideTerrainTileButtons();
void ChooseWeightedTerrainTile();
void TerrainFill( UINT32 iMapIndex );
#endif
#endif
File diff suppressed because it is too large Load Diff
+97
View File
@@ -0,0 +1,97 @@
#include "BuildDefines.h"
#ifdef JA2EDITOR
#ifndef __ITEM_STATISTICS_H
#define __ITEM_STATISTICS_H
#include "Item Types.h"
//Handles the dynamic changing of text input fields and button modes depending on the currently edited
//item. Both the merc's inventory panel, and the items tab use the same code to accomplish this.
//Set if we are editing items from the items tab. Otherwise, it is assumed that we are
//editing items from the merc's inventory panel.
extern BOOLEAN gfItemEditingMode;
//Set if we need to update the panel.
extern BOOLEAN gfRenderItemStatsPanel;
void SpecifyItemToEdit( OBJECTTYPE *pItem, INT32 iMapIndex );
void ShowItemStatsPanel();
void HideItemStatsPanel();
void EnableItemStatsPanel();
void DisableItemStatsPanel();
//called from the taskbar renderer.
void UpdateItemStatsPanel();
enum
{
ITEMSTATS_APPLY,
ITEMSTATS_CANCEL,
ITEMSTATS_DEFAULT,
ITEMSTATS_DELETE,
ITEMSTATS_HIDE,
ITEMSTATS_SHOW,
};
void ExecuteItemStatsCmd( UINT8 ubAction );
extern OBJECTTYPE *gpItem;
extern INT16 gsItemGridNo;
//enumerations for all of the different action items. Used by the popup menu for
//changing the type of action item. When modified, an equivalent text array must be
//changed as well.
enum
{
ACTIONITEM_TRIP_KLAXON,
ACTIONITEM_FLARE,
ACTIONITEM_TEARGAS,
ACTIONITEM_STUN,
ACTIONITEM_SMOKE,
ACTIONITEM_MUSTARD,
ACTIONITEM_MINE,
ACTIONITEM_OPEN,
ACTIONITEM_CLOSE,
ACTIONITEM_SMPIT,
ACTIONITEM_LGPIT,
ACTIONITEM_SMALL, //grenade
ACTIONITEM_MEDIUM, //TNT
ACTIONITEM_LARGE, //C4
ACTIONITEM_TOGGLE_DOOR,
ACTIONITEM_TOGGLE_ACTION1,
ACTIONITEM_TOGGLE_ACTION2,
ACTIONITEM_TOGGLE_ACTION3,
ACTIONITEM_TOGGLE_ACTION4,
ACTIONITEM_ENTER_BROTHEL,
ACTIONITEM_EXIT_BROTHEL,
ACTIONITEM_KINGPIN_ALARM,
ACTIONITEM_SEX,
ACTIONITEM_REVEAL_ROOM,
ACTIONITEM_LOCAL_ALARM,
ACTIONITEM_GLOBAL_ALARM,
ACTIONITEM_KLAXON,
ACTIONITEM_UNLOCK_DOOR,
ACTIONITEM_TOGGLE_LOCK,
ACTIONITEM_UNTRAP_DOOR,
ACTIONITEM_TOGGLE_PRESSURE_ITEMS,
ACTIONITEM_MUSEUM_ALARM,
ACTIONITEM_BLOODCAT_ALARM,
ACTIONITEM_BIG_TEAR_GAS,
NUM_ACTIONITEMS
};
extern UINT16 gszActionItemDesc[ NUM_ACTIONITEMS ][ 30 ];
//Returns a pointer to one of the above string array.
extern UINT16* GetActionItemName( OBJECTTYPE *pItem );
//Called by the popup menu, when a selection is made.
extern void UpdateActionItem( INT8 bActionItemIndex );
//Changes an action item into the type specified by the ACTIONITEM enumeration.
extern void ChangeActionItem( OBJECTTYPE *pItem, INT8 bActionItemIndex );
extern INT8 gbActionItemIndex;
extern INT8 gbDefaultBombTrapLevel;
extern void SetOwnershipGroup( UINT8 ubNewGroup );
#endif
#endif
File diff suppressed because it is too large Load Diff
+60
View File
@@ -0,0 +1,60 @@
#include "BuildDefines.h"
#include "Fileman.h"
#ifdef JA2EDITOR
#ifndef _JA2_LOAD_SCREEN_
#define _JA2_LOAD_SCREEN_
typedef struct _FDLG_LIST_TAG
{
GETFILESTRUCT FileInfo;
struct _FDLG_LIST_TAG *pNext;
struct _FDLG_LIST_TAG *pPrev;
} FDLG_LIST;
extern FDLG_LIST *AddToFDlgList(FDLG_LIST *pList, GETFILESTRUCT *pInfo);
extern void TrashFDlgList(FDLG_LIST *pList);
extern INT32 iFDlgState;
extern INT32 iFDlgSelectedSlot;
extern BOOLEAN gfAskForName;
extern BOOLEAN gfCreatedFDlg;
extern BOOLEAN gfDestroyFDlg;
UINT32 WaitForFileName( void );
void RemoveFileDialog(void);
void CreateFileDialog( UINT16 *zTitle );
void SelectFileDialogYPos( UINT16 usRelativeYPos );
void BuildFilenameWithCoordinate();
void BuildCoordinateWithFilename();
BOOLEAN ExtractFilenameFromFields();
BOOLEAN ValidCoordinate();
BOOLEAN ValidFilename();
BOOLEAN ExternalLoadMap( UINT16 *szFilename );
BOOLEAN ExternalSaveMap( UINT16 *szFilename );
extern BOOLEAN gfErrorCatch;
extern UINT16 gzErrorCatchString[ 256 ];
#endif
#endif
+450
View File
@@ -0,0 +1,450 @@
#ifdef PRECOMPILEDHEADERS
#include "Editor All.h"
#else
#include "builddefines.h"
#endif
#ifdef JA2EDITOR
#ifndef PRECOMPILEDHEADERS
#include "types.h"
#include "Road Smoothing.h"
#include "tiledat.h"
#include "worlddef.h"
#include "worldman.h"
#endif
typedef struct MACROSTRUCT
{
INT16 sMacroID;
INT16 sOffset;
}MACROSTRUCT;
//road macros
//These define the macros for the 32 road pieces. The column contains the macro ID and
//the second contains the gridno offset from the anchor position (where the user clicks in the world to
//place the road). The actual index of the array refers to the offset from ROADPIECE001.
MACROSTRUCT gRoadMacros[] =
{
//left 1
{L1, -2 },
{L1, -162 },
{L1, -322 },
{L1, -1 },
{L1, -161 },
{L1, -321 },
{L1, 0 },
{L1, -160 },
{L1, -320 },
//right 1
{R1, -2 },
{R1, -162 },
{R1, -322 },
{R1, -1 },
{R1, -161 },
{R1, -321 },
{R1, 0 },
{R1, -160 },
{R1, -320 },
//bottom 1
{B1, -2 },
{B1, -162 },
{B1, -322 },
{B1, -1 },
{B1, -161 },
{B1, -321 },
{B1, 0 },
{B1, -160 },
{B1, -320 },
//top 1
{T1, -2 },
{T1, -162 },
{T1, -322 },
{T1, -1 },
{T1, -161 },
{T1, -321 },
{T1, 0 },
{T1, -160 },
{T1, -320 },
//top half of top-right corner
{TTR, -4 },
{TTR, -164 },
{TTR, -324 },
{TTR, -3 },
{TTR, -163 },
{TTR, -323 },
{TTR, -2 },
{TTR, -162 },
{TTR, -1 },
{TTR, -161 },
{TTR, 0 },
//bottom half of top-right corner
{BTR, -5 },
{BTR, -165 },
{BTR, -325 },
{BTR, -4 }, //50
{BTR, -164 },
{BTR, -324 },
{BTR, -3 },
{BTR, -163 },
{BTR, -323 },
{BTR, -2 },
{BTR, -162 },
{BTR, -322 },
{BTR, -1 },
{BTR, -161 },
{BTR, -321 },
{BTR, 0 },
{BTR, -160 },
//left half of bottom-left corner
{LBL, -322 },
{LBL, -482 },
{LBL, -642 },
{LBL, -161 },
{LBL, -321 },
{LBL, -481 },
{LBL, -641 },
{LBL, 0 },
{LBL, -160 },
{LBL, -320 },
{LBL, -480 },
{LBL, -640 },
//right half of bottom-left corner
{RBL, -162 },
{RBL, -322 },
{RBL, -482 },
{RBL, -642 },
{RBL, -802 },
{RBL, -1 },
{RBL, -161 },
{RBL, -321 },
{RBL, -481 },
{RBL, -641 },
{RBL, -801 },
{RBL, 0 },
{RBL, -160 },
{RBL, -320 },
{RBL, -480 },
{RBL, -640 },
{RBL, -800 },
//left half of the top-left corner
{LTL, -2 },
{LTL, -162 },
{LTL, -322 },
{LTL, -1 },
{LTL, -161 },
{LTL, -321 },
{LTL, -481 },
{LTL, 0 }, //100
{LTL, -160 },
{LTL, -320 },
{LTL, -480 },
{LTL, -640 },
//right half of top-left corner
{RTL, -2 },
{RTL, -162 },
{RTL, -322 },
{RTL, -482 },
{RTL, -642 },
{RTL, -802 },
{RTL, -1 },
{RTL, -161 },
{RTL, -321 },
{RTL, -481 },
{RTL, -641 },
{RTL, -801 },
{RTL, 0 },
{RTL, -160 },
{RTL, -320 },
{RTL, -480 },
{RTL, -640 },
{RTL, -800 },
//right half of top-left corner
{RBR, 159 },
{RBR, -1 },
{RBR, -161 },
{RBR, -321 },
{RBR, -481 },
{RBR, -641 },
{RBR, 0 },
{RBR, -160 },
{RBR, -320 },
{RBR, -480 },
{RBR, -640 },
{RBR, -159 },
{RBR, -319 },
{RBR, -479 },
{RBR, -639 },
//right half of top-left corner
{LBR, 158 },
{LBR, -2 },
{LBR, -162 },
{LBR, -322 },
{LBR, -482 },
{LBR, -642 },
{LBR, 159 },
{LBR, -1 },
{LBR, -161 },
{LBR, -321 },
{LBR, -481 },
{LBR, -641 },
{LBR, 160 }, //150
{LBR, 0 },
{LBR, -160 },
{LBR, -320 },
{LBR, -480 },
{LBR, -640 },
//left 2
{L2, -2 },
{L2, -162 },
{L2, -322 },
{L2, -1 },
{L2, -161 },
{L2, -321 },
{L2, 0 },
{L2, -160 },
{L2, -320 },
//right 2
{R2, -2 },
{R2, -162 },
{R2, -322 },
{R2, -1 },
{R2, -161 },
{R2, -321 },
{R2, 0 },
{R2, -160 },
{R2, -320 },
//left 3
{L3, -2 },
{L3, -162 },
{L3, -322 },
{L3, -1 },
{L3, -161 },
{L3, -321 },
{L3, 0 },
{L3, -160 },
{L3, -320 },
//right 3
{R3, -2 },
{R3, -162 },
{R3, -322 },
{R3, -1 },
{R3, -161 },
{R3, -321 },
{R3, 0 },
{R3, -160 },
{R3, -320 },
//bottom 2
{B2, -2 },
{B2, -162 },
{B2, -322 },
{B2, -1 },
{B2, -161 },
{B2, -321 },
{B2, 0 },
{B2, -160 },
{B2, -320 }, //200
//top 2
{T2, -2 },
{T2, -162 },
{T2, -322 },
{T2, -1 },
{T2, -161 },
{T2, -321 },
{T2, 0 },
{T2, -160 },
{T2, -320 },
//bottom 3
{B3, -2 },
{B3, -162 },
{B3, -322 },
{B3, -1 },
{B3, -161 },
{B3, -321 },
{B3, 0 },
{B3, -160 },
{B3, -320 },
//top 3
{T3, -2 },
{T3, -162 },
{T3, -322 },
{T3, -1 },
{T3, -161 },
{T3, -321 },
{T3, 0 },
{T3, -160 },
{T3, -320 },
//bottom interior
{BI, -2 },
{BI, -162 },
{BI, -322 },
{BI, -1 },
{BI, -161 },
{BI, -321 },
{BI, 0 },
{BI, -160 },
{BI, -320 },
//left interior
{LI, -2 },
{LI, -162 },
{LI, -322 },
{LI, -1 },
{LI, -161 },
{LI, -321 },
{LI, 0 },
{LI, -160 },
{LI, -320 },
//top interior
{TI, -2 },
{TI, -162 },
{TI, -322 },
{TI, -1 },
{TI, -161 }, //250
{TI, -321 },
{TI, 0 },
{TI, -160 },
{TI, -320 },
//right interior
{RI, -2 }, //0
{RI, -162 },
{RI, -322 },
{RI, -1 },
{RI, -161 },
{RI, -321 },
{RI, 0 },
{RI, -160 },
{RI, -320 },
//left 4
{L4, -2 },
{L4, -162 },
{L4, -322 },
{L4, -1 },
{L4, -161 },
{L4, -321 },
{L4, 0 },
{L4, -160 },
{L4, -320 },
//right 4
{R4, -2 },
{R4, -162 },
{R4, -322 },
{R4, -1 },
{R4, -161 },
{R4, -321 },
{R4, 0 },
{R4, -160 },
{R4, -320 },
//bottom 4
{B4, -2 },
{B4, -162 },
{B4, -322 },
{B4, -1 },
{B4, -161 },
{B4, -321 },
{B4, 0 },
{B4, -160 },
{B4, -320 },
//top 4
{T4, -2 },
{T4, -162 },
{T4, -322 },
{T4, -1 },
{T4, -161 },
{T4, -321 },
{T4, 0 },
{T4, -160 },
{T4, -320 },
//right edge (end of road)
{RE, 0 },
{RE, -160 },
{RE, -320 },
//left edge
{LE, 0 },
{LE, -160 },
{LE, -320 },
//bottom edge
{BE, -2 },
{BE, -1 },
{BE, 0 },
//top edge
{TE, -2 },
{TE, -1 },
{TE, 0 }
};
INT16 gsRoadMacroStartIndex[ NUM_ROAD_MACROS ];
//A simple optimization function that calculates the first index in the large database for
//the particular macro ID.
void InitializeRoadMacros()
{
INT16 i, end;
INT16 sMacro = 0;
end = sizeof( gRoadMacros ) / 4;
for( i = 0; i < end; i++ )
{
if( i >= sizeof( gRoadMacros ) / sizeof( MACROSTRUCT ) )
{
i = i;
}
if( gRoadMacros[ i ].sMacroID == sMacro )
{
gsRoadMacroStartIndex[ sMacro ] = i;
sMacro++;
}
}
// i = ROADPIECES001;
}
//Road macros vary in size from 3 gridnos to 18 gridnos. Using the anchor gridno based off of the original
//road system, this function will place the new macro (consisting of multiple road pieces in multiple
//gridnos).
void PlaceRoadMacroAtGridNo( INT32 iMapIndex, INT32 iMacroID )
{
INT32 i;
UINT16 usTileIndex;
i = gsRoadMacroStartIndex[ iMacroID ];
while( gRoadMacros[ i ].sMacroID == iMacroID )
{
AddToUndoList( iMapIndex + gRoadMacros[ i ].sOffset );
RemoveAllObjectsOfTypeRange( i, ROADPIECES, ROADPIECES );
GetTileIndexFromTypeSubIndex( ROADPIECES, (UINT16)(i+1) , &usTileIndex );
AddObjectToHead( iMapIndex + gRoadMacros[ i ].sOffset, usTileIndex );
i++;
}
}
//The old road system used multi-tiled roads as a single image. The new road system has taken these large
//pieces and chopped them up into single tiled images (to mitigate lighting problems). Some of the larger
//road pieces turned into 18 smaller pieces. So this function will go analyse the world, and replaces any
//locations containing the original road tile information, delete it, and replace it by inserting it's
//equivalent macro.
void ReplaceObsoleteRoads()
{
INT32 i;
INT32 iMacro;
LEVELNODE *pObject;
BOOLEAN fRoadExistsAtGridNo;
for( i = 0; i < WORLD_MAX; i++ )
{
pObject = gpWorldLevelData[ i ].pObjectHead;
fRoadExistsAtGridNo = FALSE;
while( pObject )
{
if( pObject->usIndex >= FIRSTROAD1 && pObject->usIndex <= FIRSTROAD32 )
{
fRoadExistsAtGridNo = TRUE;
iMacro = pObject->usIndex - FIRSTROAD1;
PlaceRoadMacroAtGridNo( i, iMacro );
}
pObject = pObject->pNext;
}
if( fRoadExistsAtGridNo )
{
RemoveAllObjectsOfTypeRange( i, FIRSTROAD, FIRSTROAD );
}
}
}
#endif
+64
View File
@@ -0,0 +1,64 @@
#include "BuildDefines.h"
#ifdef JA2EDITOR
#ifndef __ROAD_SMOOTHING_H
#define __ROAD_SMOOTHING_H
//There are the 32 macro definitions that make up all of the road pieces. These enumerations
//match up exactly to the previous road system order of graphics (FIRSTROAD1 - FIRSTROAD32)
enum
{
L1, //left 1 -- this is a left straight-away edge
R1, //right 1
B1, //bottom 1
T1, //top 1
TTR, //top top-right corner piece (the top part of the top-right corner)
BTR, //bottom top-right corner piece (the bottom part of the top-right corner)
LBL, //left bottom-left corner piece
RBL, //right bottom-left corner piece
LTL, //left top-left corner piece
RTL, //right top-left corner piece
RBR, //right bottom-right corner piece
LBR, //left bottom-right corner piece
L2, //left 2 (variation of the left 1)
R2, //right 2
L3, //left 3
R3, //right 3
B2, //bottom 2
T2, //top 2
B3, //bottom 3
T3, //top 3
BI, //bottom intersection (piece connecting bottom to right)
LI, //left intersection (piece connecting left to bottom )
TI, //top intersection (piece connecting top to left)
RI, //right intersection (piece connection right to top)
L4, //left 4
R4, //right 4
B4, //bottom 4
T4, //top 4
RE, //right edge (end of road)
LE, //left edge
BE, //bottom edge
TE, //top edge
NUM_ROAD_MACROS
};
//The old road system used multi-tiled roads as a single image. The new road system has taken these large
//pieces and chopped them up into single tiled images (to mitigate lighting problems). Some of the larger
//road pieces turned into 18 smaller pieces. So this function will go analyse the world, and replaces any
//locations containing the original road tile information, delete it, and replace it by inserting it's
//equivalent macro.
void ReplaceObsoleteRoads();
//Road macros vary in size from 3 gridnos to 18 gridnos. Using the anchor gridno based off of the original
//road system, this function will place the new macro (consisting of multiple road pieces in multiple
//gridnos).
void PlaceRoadMacroAtGridNo( INT32 iMapIndex, INT32 iMacroID );
void InitializeRoadMacros();
#endif
#endif
File diff suppressed because it is too large Load Diff
+35
View File
@@ -0,0 +1,35 @@
#include "BuildDefines.h"
#ifdef JA2EDITOR
#ifndef __SECTOR_SUMMARY_H
#define __SECTOR_SUMMARY_H
//This function can be very time consuming as it loads every map file with a valid
//coordinate name, analyses it, and builds a new global summary file.
void CreateGlobalSummary();
void CreateSummaryWindow();
void ReleaseSummaryWindow();
void DestroySummaryWindow();
void RenderSummaryWindow();
void LoadWorldInfo();
void UpdateSectorSummary( UINT16 *gszFilename, BOOLEAN fUpdate );
void SaveGlobalSummary();
void LoadGlobalSummary();
extern BOOLEAN gfGlobalSummaryExists;
extern BOOLEAN gfSummaryWindowActive;
extern BOOLEAN gSectorExists[16][16];
extern UINT16 gusNumEntriesWithOutdatedOrNoSummaryInfo;
extern BOOLEAN gfUpdateSummaryInfo;
extern UINT8 GetCurrentSummaryVersion();
#endif
#endif
+628
View File
@@ -0,0 +1,628 @@
#ifdef PRECOMPILEDHEADERS
#include "Editor All.h"
#else
#include "builddefines.h"
#endif
#ifdef JA2EDITOR
#ifndef PRECOMPILEDHEADERS
#include "worlddef.h" //LEVELNODE def
#include "worldman.h" //ReplaceStructIndex
#include "SmartMethod.h"
#include "Smoothing Utils.h"
#include "Editor Undo.h"
#endif
UINT8 gubDoorUIValue = 0;
UINT8 gubWindowUIValue = 0;
UINT8 gubWallUIValue = FIRSTWALL;
UINT8 gubBrokenWallUIValue = 0;
void CalcSmartWallDefault( UINT16 *pusObjIndex, UINT16 *pusUseIndex )
{
*pusUseIndex = 0;
*pusObjIndex = gubWallUIValue;
}
void CalcSmartDoorDefault( UINT16 *pusObjIndex, UINT16 *pusUseIndex )
{
*pusUseIndex = 4 * ( gubDoorUIValue % 2 ); //open or closed -- odd or even
*pusObjIndex = FIRSTDOOR + gubDoorUIValue / 2;
}
void CalcSmartWindowDefault( UINT16 *pusObjIndex, UINT16 *pusUseIndex )
{
*pusUseIndex = 44 + gubWindowUIValue; //first exterior top right oriented window
*pusObjIndex = FIRSTWALL;
}
void CalcSmartBrokenWallDefault( UINT16 *pusObjIndex, UINT16 *pusUseIndex )
{
switch( gubBrokenWallUIValue )
{
case 0:case 1: *pusUseIndex = 49 + gubBrokenWallUIValue; break;
case 3: *pusUseIndex = 62; break;
case 4: *pusUseIndex = 64; break;
}
*pusObjIndex = FIRSTWALL;
}
UINT16 CalcSmartWindowIndex( UINT16 usWallOrientation )
{
return (UINT16)(33 + usWallOrientation*3 + gubWindowUIValue);
}
UINT16 CalcSmartDoorIndex( UINT16 usWallOrientation )
{
//convert the orientation values as the graphics are in reverse order
//orientation values: INSIDE_TOP_LEFT=1, INSIDE_TOP_RIGHT=2, OUTSIDE_TOP_LEFT=3, OUTSIDE_TOP_RIGHT=4
//door graphics order: INSIDE_TOP_LEFT=15, INSIDE_TOP_RIGHT=10, OUTSIDE_TOP_LEFT=5, OUTSIDE_TOP_RIGHT=0
usWallOrientation = (4 - usWallOrientation) * 5;
//4 * (gubDoorUIValue%2) evaluates to +4 if the door is open, 0 if closed
return (UINT16)( 1 + usWallOrientation + 4 * (gubDoorUIValue % 2) );
}
UINT16 CalcSmartDoorType()
{
return (UINT16)( FIRSTDOOR + gubDoorUIValue / 2 );
}
UINT16 CalcSmartBrokenWallIndex( UINT16 usWallOrientation )
{
if( gubBrokenWallUIValue == 2 ) //the hole in the wall
return 0xffff;
if( gubBrokenWallUIValue < 2 ) //broken walls
{
//convert the orientation value as the graphics are in a different order.
//orientation values: INSIDE_TOP_LEFT=1, INSIDE_TOP_RIGHT=2, OUTSIDE_TOP_LEFT=3, OUTSIDE_TOP_RIGHT=4
// 4 6 8 10
//door graphics order: INSIDE_TOP_LEFT=4, INSIDE_TOP_RIGHT=6, OUTSIDE_TOP_LEFT=0, OUTSIDE_TOP_RIGHT=2
usWallOrientation = usWallOrientation * 2 + 2;
usWallOrientation -= usWallOrientation > 6 ? 8 : 0;
return (UINT16)( usWallOrientation + 48 + gubBrokenWallUIValue );
}
//cracked and smudged walls
//convert the orientation value as the graphics are in a different order.
//orientation values: INSIDE_TOP_LEFT=1, INSIDE_TOP_RIGHT=2, OUTSIDE_TOP_LEFT=3, OUTSIDE_TOP_RIGHT=4
//door graphics order: INSIDE_TOP_LEFT=1, INSIDE_TOP_RIGHT=2, OUTSIDE_TOP_LEFT=5, OUTSIDE_TOP_RIGHT=6
usWallOrientation += usWallOrientation > 1 ? 2 : 0;
usWallOrientation += gubBrokenWallUIValue == 4 ? 2 : 0; //smudged type which is 2 index values higher.
return (UINT16)( usWallOrientation + 57 );
}
void IncSmartWallUIValue()
{
gubWallUIValue += gubWallUIValue < LASTWALL ? 1 : -3;
}
void DecSmartWallUIValue()
{
gubWallUIValue -= gubWallUIValue > FIRSTWALL ? 1 : -3;
}
void IncSmartDoorUIValue()
{
gubDoorUIValue += gubDoorUIValue < 7 ? 1 : -7;
}
void DecSmartDoorUIValue()
{
gubDoorUIValue -= gubDoorUIValue > 0 ? 1 : -7;
}
void IncSmartWindowUIValue()
{
gubWindowUIValue += gubWindowUIValue < 2 ? 1 : -2;
}
void DecSmartWindowUIValue()
{
gubWindowUIValue -= gubWindowUIValue > 0 ? 1 : -2;
}
void IncSmartBrokenWallUIValue()
{
gubBrokenWallUIValue += gubBrokenWallUIValue < 4 ? 1 : -4;
}
void DecSmartBrokenWallUIValue()
{
gubBrokenWallUIValue -= gubBrokenWallUIValue > 0 ? 1 : -4;
}
BOOLEAN CalcWallInfoUsingSmartMethod( UINT32 iMapIndex, UINT16 *pusWallType, UINT16 *pusIndex )
{
return FALSE;
}
BOOLEAN CalcDoorInfoUsingSmartMethod( UINT32 iMapIndex, UINT16 *pusDoorType, UINT16 *pusIndex )
{
LEVELNODE *pWall = NULL;
UINT16 usWallOrientation;
pWall = GetVerticalWall( iMapIndex );
if( pWall )
{
GetWallOrientation( pWall->usIndex, &usWallOrientation );
*pusIndex = CalcSmartDoorIndex( usWallOrientation ) - 1;
*pusDoorType = CalcSmartDoorType();
return TRUE;
}
pWall = GetHorizontalWall( iMapIndex );
if( pWall )
{
GetWallOrientation( pWall->usIndex, &usWallOrientation );
*pusIndex = CalcSmartDoorIndex( usWallOrientation ) - 1;
*pusDoorType = CalcSmartDoorType();
return TRUE;
}
return FALSE;
}
BOOLEAN CalcWindowInfoUsingSmartMethod( UINT32 iMapIndex, UINT16 *pusWallType, UINT16 *pusIndex )
{
LEVELNODE *pWall = NULL;
UINT32 uiTileType;
UINT16 usWallOrientation;
pWall = GetVerticalWall( iMapIndex );
if( pWall )
{
GetTileType( pWall->usIndex, &uiTileType );
*pusWallType = (UINT16)uiTileType;
if( uiTileType >= FIRSTDOOR && uiTileType <= LASTDOOR )
{
//We want to be able to replace doors with a window, however, the doors do not
//contain the wall type, so we have to search for the nearest wall to extract it.
*pusWallType = SearchForWallType( iMapIndex );
}
GetWallOrientation( pWall->usIndex, &usWallOrientation );
*pusIndex = CalcSmartWindowIndex( usWallOrientation ) - 1;
return TRUE;
}
pWall = GetHorizontalWall( iMapIndex );
if( pWall )
{
GetTileType( pWall->usIndex, &uiTileType );
*pusWallType = (UINT16)uiTileType;
if( uiTileType >= FIRSTDOOR && uiTileType <= LASTDOOR )
{
//We want to be able to replace doors with a window, however, the doors do not
//contain the wall type, so we have to search for the nearest wall to extract it.
*pusWallType = SearchForWallType( iMapIndex );
}
GetWallOrientation( pWall->usIndex, &usWallOrientation );
*pusIndex = CalcSmartWindowIndex( usWallOrientation ) - 1;
return TRUE;
}
return FALSE;
}
BOOLEAN CalcBrokenWallInfoUsingSmartMethod( UINT32 iMapIndex, UINT16 *pusWallType, UINT16 *pusIndex )
{
LEVELNODE *pWall = NULL;
UINT32 uiTileType;
UINT16 usWallOrientation;
if( gubBrokenWallUIValue == 2 ) //the hole in the wall
{
*pusWallType = 0xffff;
*pusIndex = 0xffff; //but it won't draw it.
return TRUE;
}
pWall = GetVerticalWall( iMapIndex );
if( pWall )
{
GetTileType( pWall->usIndex, &uiTileType );
*pusWallType = (UINT16)uiTileType;
if( uiTileType >= FIRSTDOOR && uiTileType <= LASTDOOR )
{
//We want to be able to replace doors with a walltype, however, the doors do not
//contain the wall type, so we have to search for the nearest wall to extract it.
*pusWallType = SearchForWallType( iMapIndex );
}
GetWallOrientation( pWall->usIndex, &usWallOrientation );
*pusIndex = CalcSmartBrokenWallIndex( usWallOrientation ) - 1;
return TRUE;
}
pWall = GetHorizontalWall( iMapIndex );
if( pWall )
{
GetTileType( pWall->usIndex, &uiTileType );
*pusWallType = (UINT16)uiTileType;
if( uiTileType >= FIRSTDOOR && uiTileType <= LASTDOOR )
{
//We want to be able to replace doors with a walltype, however, the doors do not
//contain the wall type, so we have to search for the nearest wall to extract it.
*pusWallType = SearchForWallType( iMapIndex );
}
GetWallOrientation( pWall->usIndex, &usWallOrientation );
*pusIndex = CalcSmartBrokenWallIndex( usWallOrientation ) - 1;
return TRUE;
}
return FALSE;
}
//This is a very difficult function to document properly. The reason being is that it is sooo
//subliminal by nature. I have thought up of priorities and choose the best piece to draw based
//on the surrounding conditions. Here are the priorities which are referenced below via comments:
//A) If there is currently a bottom piece and a right piece, immediately exit.
//B) We are currently over a bottom piece. Now, we don't automatically want to draw a right piece here
// for multiple reasons. First, the UI will be too quick and place bottom and right pieces for every
// place the user clicks, which isn't what we want. Therefore, we look to see if there is a right
// piece in the y-1 gridno. It would then make sense to place a right piece down here. Regardless,
// if we encounter a bottom piece here, we will exit.
//C) This is the counterpart to B, but we are looking at a current right piece, and are determining if
// we should place a bottom piece based on another bottom piece existing in the x-1 gridno.
//D) Now, we analyse the neighboring tiles and determine the orientations that would add weight to the
// current tile either towards drawing a horizontal piece or a vertical piece.
//E) Now that we have the information, we give the highest priority to any weights that match the current
// wall piece type selected by the user. Based on that, we will only consider the best match of the
// type and use it. If there are no matches on type, we continue.
//F) We failed to find weights matching the current wall type, but before we give up using the user's wall
// type, there are two more cases. When there is a bottom wall in the y+1 position or a right wall in
// the x+1 position. If there are matching walls, there, then we draw two pieces to connect the current
// gridno with the respective position.
void PasteSmartWall( UINT32 iMapIndex )
{
static BOOLEAN fWallAlone = FALSE;
static UINT32 iAloneMapIndex = 0x8000;
UINT16 usWallType;
//These are the counters for the walls of each type
UINT16 usNumV[4]={0,0,0,0}; //vertical wall weights
UINT16 usNumH[4]={0,0,0,0}; //horizontal wall weights
//*A* See above documentation
if( GetVerticalWall( iMapIndex ) && GetHorizontalWall( iMapIndex ) )
return;
//*B* See above documentation
usWallType = GetHorizontalWallType( iMapIndex );
if( usWallType )
{
if( usWallType == gubWallUIValue )
{
usWallType = GetVerticalWallType( iMapIndex - WORLD_COLS );
if( usWallType == gubWallUIValue )
{
if( FloorAtGridNo( iMapIndex + 1 ) )
BuildWallPiece( iMapIndex, EXTERIOR_RIGHT, gubWallUIValue );
else
BuildWallPiece( iMapIndex, INTERIOR_RIGHT, gubWallUIValue );
return;
}
usWallType = GetHorizontalWallType( iMapIndex - WORLD_COLS );
if( usWallType == gubWallUIValue )
{
if( FloorAtGridNo( iMapIndex + 1 ) )
{
BuildWallPiece( iMapIndex, EXTERIOR_RIGHT, gubWallUIValue );
if( !GetHorizontalWall( iMapIndex - WORLD_COLS + 1 ) )
ChangeVerticalWall( iMapIndex, INTERIOR_EXTENDED );
}
else
{
BuildWallPiece( iMapIndex, INTERIOR_RIGHT, gubWallUIValue );
if( !GetHorizontalWall( iMapIndex - WORLD_COLS + 1 ) )
ChangeVerticalWall( iMapIndex, EXTERIOR_EXTENDED );
}
}
}
return;
}
//*C* See above documentation
usWallType = GetVerticalWallType( iMapIndex );
if( usWallType )
{
if( usWallType == gubWallUIValue )
{
usWallType = GetHorizontalWallType( iMapIndex - 1 );
if( usWallType == gubWallUIValue )
{
if( FloorAtGridNo( iMapIndex + WORLD_COLS ) )
BuildWallPiece( iMapIndex, EXTERIOR_BOTTOM, gubWallUIValue );
else
BuildWallPiece( iMapIndex, INTERIOR_BOTTOM, gubWallUIValue );
}
}
return;
}
//*D* See above documentation
//Evaluate left adjacent tile
if( usWallType = GetVerticalWallType( iMapIndex - 1 ) )
usNumH[ usWallType - FIRSTWALL ]++;
if( usWallType = GetHorizontalWallType( iMapIndex - 1 ) )
usNumH[ usWallType - FIRSTWALL ]++;
//Evaluate right adjacent tile
if( usWallType = GetHorizontalWallType( iMapIndex + 1 ) )
usNumH[ usWallType - FIRSTWALL ]++;
//Evaluate upper adjacent tile
if( usWallType = GetVerticalWallType( iMapIndex - WORLD_COLS ) )
usNumV[ usWallType - FIRSTWALL ]++;
if( usWallType = GetHorizontalWallType( iMapIndex - WORLD_COLS ) )
usNumV[ usWallType - FIRSTWALL ]++;
//Evaluate lower adjacent tile
if( usWallType = GetVerticalWallType( iMapIndex + WORLD_COLS ) )
usNumV[ usWallType - FIRSTWALL ]++;
//*E* See above documentation
if( usNumV[gubWallUIValue - FIRSTWALL] | usNumH[gubWallUIValue - FIRSTWALL] )
{
if( usNumV[gubWallUIValue - FIRSTWALL] >= usNumH[gubWallUIValue - FIRSTWALL] )
{
if( FloorAtGridNo( iMapIndex + 1 ) )
{ //inside
BuildWallPiece( iMapIndex, EXTERIOR_RIGHT, gubWallUIValue );
//Change to extended piece if it is a new top right corner to cover the end part.
if( GetHorizontalWall( iMapIndex - WORLD_COLS ) && !GetHorizontalWall( iMapIndex - WORLD_COLS + 1 )
&& !GetVerticalWall( iMapIndex - WORLD_COLS ) )
ChangeVerticalWall( iMapIndex, INTERIOR_EXTENDED );
else if( GetHorizontalWall( iMapIndex - WORLD_COLS ) && !GetHorizontalWall( iMapIndex - WORLD_COLS - 1 )
&& !GetVerticalWall( iMapIndex - WORLD_COLS - 1 ) )
{
ChangeVerticalWall( iMapIndex, INTERIOR_EXTENDED );
EraseHorizontalWall( iMapIndex - WORLD_COLS );
}
}
else
{ //outside
BuildWallPiece( iMapIndex, INTERIOR_RIGHT, gubWallUIValue );
if( GetHorizontalWall( iMapIndex - WORLD_COLS ) && !GetHorizontalWall( iMapIndex - WORLD_COLS + 1 )
&& !GetVerticalWall( iMapIndex - WORLD_COLS ) )
ChangeVerticalWall( iMapIndex, EXTERIOR_EXTENDED );
else if( GetHorizontalWall( iMapIndex - WORLD_COLS ) && !GetHorizontalWall( iMapIndex - WORLD_COLS - 1 )
&& !GetVerticalWall( iMapIndex - WORLD_COLS - 1 ) )
{
ChangeVerticalWall( iMapIndex, EXTERIOR_EXTENDED );
EraseHorizontalWall( iMapIndex - WORLD_COLS );
}
}
}
else
{
if( GetVerticalWall( iMapIndex - 1 ) && !GetVerticalWall( iMapIndex - WORLD_COLS - 1 )
&& !GetHorizontalWall( iMapIndex - WORLD_COLS - 1 ) )
EraseVerticalWall( iMapIndex - 1);
if( FloorAtGridNo( iMapIndex + WORLD_COLS ) )
{ //inside
BuildWallPiece( iMapIndex, EXTERIOR_BOTTOM, gubWallUIValue );
if( GetVerticalWall( iMapIndex + WORLD_COLS ) )
ChangeVerticalWall( iMapIndex + WORLD_COLS, INTERIOR_EXTENDED );
if( GetVerticalWall( iMapIndex + WORLD_COLS - 1 ) && !GetVerticalWall( iMapIndex - 1 ) )
ChangeVerticalWall( iMapIndex + WORLD_COLS - 1, INTERIOR_EXTENDED );
else if( GetVerticalWall( iMapIndex - 1 ) && !GetVerticalWall( iMapIndex + WORLD_COLS - 1 )
&& FloorAtGridNo( iMapIndex ) )
ChangeVerticalWall( iMapIndex - 1, INTERIOR_BOTTOMEND );
}
else
{ //outside
BuildWallPiece( iMapIndex, INTERIOR_BOTTOM, gubWallUIValue );
if( GetVerticalWall( iMapIndex + WORLD_COLS ) )
ChangeVerticalWall( iMapIndex + WORLD_COLS, EXTERIOR_EXTENDED );
if( GetVerticalWall( iMapIndex + WORLD_COLS - 1 ) && !GetVerticalWall( iMapIndex - 1 ) )
ChangeVerticalWall( iMapIndex + WORLD_COLS - 1, EXTERIOR_EXTENDED );
else if( GetVerticalWall( iMapIndex - 1 ) && !GetVerticalWall( iMapIndex + WORLD_COLS - 1 )
&& FloorAtGridNo( iMapIndex ) )
ChangeVerticalWall( iMapIndex - 1, EXTERIOR_BOTTOMEND );
}
}
return;
}
//*F* See above documentation
usWallType = GetHorizontalWallType( iMapIndex + WORLD_COLS );
if( usWallType == gubWallUIValue )
{
if( !GetHorizontalWall( iMapIndex + WORLD_COLS - 1 ) )
EraseHorizontalWall( iMapIndex + WORLD_COLS );
if( FloorAtGridNo( iMapIndex + 1 ) )
{ //inside
BuildWallPiece( iMapIndex + WORLD_COLS, EXTERIOR_RIGHT, gubWallUIValue );
BuildWallPiece( iMapIndex, EXTERIOR_RIGHT, gubWallUIValue );
if( !GetVerticalWall( iMapIndex + WORLD_COLS * 2 ) && FloorAtGridNo( iMapIndex + WORLD_COLS * 2 + 1 ) )
ChangeVerticalWall( iMapIndex + WORLD_COLS, INTERIOR_BOTTOMEND );
else //override the damn other smoothing.
ChangeVerticalWall( iMapIndex + WORLD_COLS, INTERIOR_R );
}
else
{ //outside
BuildWallPiece( iMapIndex + WORLD_COLS, INTERIOR_RIGHT, gubWallUIValue );
BuildWallPiece( iMapIndex, INTERIOR_RIGHT, gubWallUIValue );
if( !GetVerticalWall( iMapIndex + WORLD_COLS * 2 ) && !FloorAtGridNo( iMapIndex + WORLD_COLS * 2 + 1 ) )
ChangeVerticalWall( iMapIndex + WORLD_COLS, EXTERIOR_BOTTOMEND );
else //override the damn other smoothing.
ChangeVerticalWall( iMapIndex + WORLD_COLS, EXTERIOR_R );
}
return;
}
usWallType = GetVerticalWallType( iMapIndex + 1 );
if( usWallType == gubWallUIValue )
{
if(FloorAtGridNo( iMapIndex + WORLD_COLS ) )
{ //inside
BuildWallPiece( iMapIndex + 1, EXTERIOR_BOTTOM, gubWallUIValue );
BuildWallPiece( iMapIndex, EXTERIOR_BOTTOM, gubWallUIValue );
if( !GetVerticalWall( iMapIndex - WORLD_COLS + 1 ) )
{
EraseVerticalWall( iMapIndex + 1 );
ChangeVerticalWall( iMapIndex + WORLD_COLS + 1, INTERIOR_EXTENDED );
}
if( !GetVerticalWall( iMapIndex + WORLD_COLS + 1) )
{
if( !GetHorizontalWall( iMapIndex - WORLD_COLS + 1) && !GetVerticalWall( iMapIndex - WORLD_COLS + 1 )
&& GetHorizontalWall( iMapIndex - WORLD_COLS + 2 ) )
ChangeVerticalWall( iMapIndex + 1, INTERIOR_EXTENDED );
else
ChangeVerticalWall( iMapIndex + 1, INTERIOR_BOTTOMEND );
}
}
else
{ //outside
BuildWallPiece( iMapIndex + 1, INTERIOR_BOTTOM, gubWallUIValue );
BuildWallPiece( iMapIndex, INTERIOR_BOTTOM, gubWallUIValue );
if( !GetVerticalWall( iMapIndex - WORLD_COLS + 1 ) )
{
EraseVerticalWall( iMapIndex + 1 );
ChangeVerticalWall( iMapIndex + WORLD_COLS + 1, EXTERIOR_EXTENDED );
}
if( !GetVerticalWall( iMapIndex + WORLD_COLS + 1) )
{
if( !GetHorizontalWall( iMapIndex - WORLD_COLS + 1) && !GetVerticalWall( iMapIndex - WORLD_COLS + 1 )
&& GetHorizontalWall( iMapIndex - WORLD_COLS + 2 ) )
ChangeVerticalWall( iMapIndex + 1, EXTERIOR_EXTENDED );
else
ChangeVerticalWall( iMapIndex + 1, EXTERIOR_BOTTOMEND );
}
}
return;
}
//Check for the highest weight value.
}
void PasteSmartDoor( UINT32 iMapIndex )
{
LEVELNODE *pWall = NULL;
UINT16 usTileIndex;
UINT16 usDoorType;
UINT16 usIndex;
UINT16 usWallOrientation;
if( pWall = GetVerticalWall( iMapIndex ) )
{
GetWallOrientation( pWall->usIndex, &usWallOrientation );
usIndex = CalcSmartDoorIndex( usWallOrientation );
usDoorType = CalcSmartDoorType();
AddToUndoList( iMapIndex );
GetTileIndexFromTypeSubIndex( usDoorType, usIndex, &usTileIndex );
ReplaceStructIndex( iMapIndex, pWall->usIndex, usTileIndex );
}
if( pWall = GetHorizontalWall( iMapIndex ) )
{
GetWallOrientation( pWall->usIndex, &usWallOrientation );
usIndex = CalcSmartDoorIndex( usWallOrientation );
usDoorType = CalcSmartDoorType();
AddToUndoList( iMapIndex );
GetTileIndexFromTypeSubIndex( usDoorType, usIndex, &usTileIndex );
ReplaceStructIndex( iMapIndex, pWall->usIndex, usTileIndex );
}
}
void PasteSmartWindow( UINT32 iMapIndex )
{
UINT16 usNewWallIndex;
LEVELNODE *pWall = NULL;
UINT32 uiTileType;
UINT16 usWallType;
UINT16 usIndex;
UINT16 usWallOrientation;
pWall = GetVerticalWall( iMapIndex );
if( pWall )
{
GetTileType( pWall->usIndex, &uiTileType );
usWallType = (UINT16)uiTileType;
if( uiTileType >= FIRSTDOOR && uiTileType <= LASTDOOR )
{
//We want to be able to replace doors with a window, however, the doors do not
//contain the wall type, so we have to search for the nearest wall to extract it.
usWallType = SearchForWallType( iMapIndex );
}
GetWallOrientation( pWall->usIndex, &usWallOrientation );
usIndex = CalcSmartWindowIndex( usWallOrientation );
//Calculate the new graphic for the window type selected.
AddToUndoList( iMapIndex );
GetTileIndexFromTypeSubIndex( usWallType, usIndex, &usNewWallIndex );
ReplaceStructIndex( iMapIndex, pWall->usIndex, usNewWallIndex );
}
pWall = GetHorizontalWall( iMapIndex );
if( pWall )
{
GetTileType( pWall->usIndex, &uiTileType );
usWallType = (UINT16)uiTileType;
if( uiTileType >= FIRSTDOOR && uiTileType <= LASTDOOR )
{
//We want to be able to replace doors with a window, however, the doors do not
//contain the wall type, so we have to search for the nearest wall to extract it.
usWallType = SearchForWallType( iMapIndex );
}
GetWallOrientation( pWall->usIndex, &usWallOrientation );
usIndex = CalcSmartWindowIndex( usWallOrientation );
//Calculate the new graphic for the window type selected.
AddToUndoList( iMapIndex );
GetTileIndexFromTypeSubIndex( usWallType, usIndex, &usNewWallIndex );
ReplaceStructIndex( iMapIndex, pWall->usIndex, usNewWallIndex );
}
}
void PasteSmartBrokenWall( UINT32 iMapIndex )
{
UINT16 usNewWallIndex;
LEVELNODE *pWall;
UINT32 uiTileType;
UINT16 usWallType;
UINT16 usIndex;
UINT16 usWallOrientation;
pWall = GetVerticalWall( iMapIndex );
if( pWall )
{
GetTileType( pWall->usIndex, &uiTileType );
usWallType = (UINT16)uiTileType;
if( uiTileType >= FIRSTDOOR && uiTileType <= LASTDOOR )
{
usWallType = SearchForWallType( iMapIndex );
}
GetWallOrientation( pWall->usIndex, &usWallOrientation );
usIndex = CalcSmartBrokenWallIndex( usWallOrientation );
if( usIndex == 0xffff )
{
AddToUndoList( iMapIndex );
RemoveStruct( iMapIndex, pWall->usIndex );
}
else
{
AddToUndoList( iMapIndex );
GetTileIndexFromTypeSubIndex( usWallType, usIndex, &usNewWallIndex );
ReplaceStructIndex( iMapIndex, pWall->usIndex, usNewWallIndex );
}
}
pWall = GetHorizontalWall( iMapIndex );
if( pWall )
{
GetTileType( pWall->usIndex, &uiTileType );
usWallType = (UINT16)uiTileType;
if( uiTileType >= FIRSTDOOR && uiTileType <= LASTDOOR )
{
//We want to be able to replace doors with a window, however, the doors do not
//contain the wall type, so we have to search for the nearest wall to extract it.
usWallType = SearchForWallType( iMapIndex );
}
GetWallOrientation( pWall->usIndex, &usWallOrientation );
usIndex = CalcSmartBrokenWallIndex( usWallOrientation );
if( usIndex == 0xffff )
{
AddToUndoList( iMapIndex );
RemoveStruct( iMapIndex, pWall->usIndex );
}
else
{
AddToUndoList( iMapIndex );
GetTileIndexFromTypeSubIndex( usWallType, usIndex, &usNewWallIndex );
ReplaceStructIndex( iMapIndex, pWall->usIndex, usNewWallIndex );
}
//Calculate the new graphic for the window type selected.
}
}
#endif
+48
View File
@@ -0,0 +1,48 @@
#include "BuildDefines.h"
#ifdef JA2EDITOR
#ifndef __SMARTMETHOD_H
#define __SMARTMETHOD_H
void CalcSmartWallDefault( UINT16 *pusObjIndex, UINT16 *pusUseIndex );
void CalcSmartDoorDefault( UINT16 *pusObjIndex, UINT16 *pusUseIndex );
void CalcSmartWindowDefault( UINT16 *pusObjIndex, UINT16 *pusUseIndex );
void CalcSmartBrokenWallDefault( UINT16 *pusObjIndex, UINT16 *pusUseIndex );
UINT16 CalcSmartWindowIndex( UINT16 usWallOrientation );
UINT16 CalcSmartDoorIndex( UINT16 usWallOrientation );
UINT16 CalcSmartBrokenWallIndex( UINT16 usWallOrientation );
UINT16 CalcSmartDoorType();
void IncSmartWallUIValue();
void DecSmartWallUIValue();
void IncSmartDoorUIValue();
void DecSmartDoorUIValue();
void IncSmartWindowUIValue();
void DecSmartWindowUIValue();
void IncSmartBrokenWallUIValue();
void DecSmartBrokenWallUIValue();
BOOLEAN CalcWallInfoUsingSmartMethod( UINT32 iMapIndex, UINT16 *pusWallType, UINT16 *pusIndex );
BOOLEAN CalcDoorInfoUsingSmartMethod( UINT32 iMapIndex, UINT16 *pusDoorType, UINT16 *pusIndex );
BOOLEAN CalcWindowInfoUsingSmartMethod( UINT32 iMapIndex, UINT16 *pusWallType, UINT16 *pusIndex );
BOOLEAN CalcBrokenWallInfoUsingSmartMethod( UINT32 iMapIndex, UINT16 *pusWallType, UINT16 *pusIndex );
void PasteSmartWall( UINT32 iMapIndex );
void PasteSmartDoor( UINT32 iMapIndex );
void PasteSmartWindow( UINT32 iMapIndex );
void PasteSmartBrokenWall( UINT32 iMapIndex );
extern UINT8 gubDoorUIValue;
extern UINT8 gubWindowUIValue;
extern UINT8 gubWallUIValue;
extern UINT8 gubBrokenWallUIValue;
#endif
#endif
+469
View File
@@ -0,0 +1,469 @@
#ifdef PRECOMPILEDHEADERS
#include "Editor All.h"
#else
#include "builddefines.h"
#endif
#ifdef JA2EDITOR
#ifndef PRECOMPILEDHEADERS
#include <stdlib.h>
#include "worlddef.h" //for LEVELNODE def
#include "worldman.h" //for RemoveXXXX()
#include "Isometric Utils.h" //for GridNoOnVisibleWorldTile()
#include "SmartMethod.h"
#include "Smoothing Utils.h"
#include "Editor Undo.h"
#include "EditorDefines.h"
#include "edit_sys.h"
#include "environment.h"
#endif
extern UINT16 PickAWallPiece( UINT16 usWallPieceType );
//This method isn't foolproof, but because erasing large areas of buildings could result in
//multiple wall types for each building. When processing the region, it is necessary to
//calculate the roof type by searching for the nearest roof tile.
UINT16 SearchForWallType( UINT32 iMapIndex )
{
UINT32 uiTileType;
LEVELNODE *pWall;
INT16 sOffset;
INT16 x, y, sRadius = 0;
if( gfBasement )
{
UINT16 usWallType;
usWallType = GetRandomIndexByRange( FIRSTWALL, LASTWALL );
if( usWallType == 0xffff )
usWallType = FIRSTWALL;
return usWallType;
}
while( sRadius < 32 )
{
//NOTE: start at the higher y value and go negative because it is possible to have another
// structure type one tile north, but not one tile south -- so it'll find the correct wall first.
for( y = sRadius; y >= -sRadius; y-- ) for( x = -sRadius; x <= sRadius; x++ )
{
if( abs(x) == abs(sRadius) || abs(y) == abs(sRadius) )
{
sOffset = y * WORLD_COLS + x;
if( !GridNoOnVisibleWorldTile( (INT16)(iMapIndex + sOffset) ) )
{
continue;
}
pWall = gpWorldLevelData[ iMapIndex + sOffset ].pStructHead;
while( pWall )
{
GetTileType( pWall->usIndex, &uiTileType );
if( uiTileType >= FIRSTWALL && uiTileType <= LASTWALL )
{ //found a roof, so return its type.
return (UINT16)uiTileType;
}
//if( uiTileType >= FIRSTWINDOW && uiTileType <= LASTWINDOW )
//{ //Window types can be converted to a wall type.
// return (UINT16)(FIRSTWALL + uiTileType - FIRSTWINDOW );
//}
pWall = pWall->pNext;
}
}
}
sRadius++;
}
return 0xffff;
}
//This method isn't foolproof, but because erasing large areas of buildings could result in
//multiple roof types for each building. When processing the region, it is necessary to
//calculate the roof type by searching for the nearest roof tile.
UINT16 SearchForRoofType( UINT32 iMapIndex )
{
UINT32 uiTileType;
LEVELNODE *pRoof;
INT16 x, y, sRadius = 0;
INT16 sOffset;
while( sRadius < 32 )
{
for( y = -sRadius; y <= sRadius; y++ ) for( x = -sRadius; x <= sRadius; x++ )
{
if( abs(x) == abs(sRadius) || abs(y) == abs(sRadius) )
{
sOffset = y * WORLD_COLS + x;
if( !GridNoOnVisibleWorldTile( (INT16)(iMapIndex + sOffset) ) )
{
continue;
}
pRoof = gpWorldLevelData[ iMapIndex + sOffset ].pRoofHead;
while( pRoof )
{
GetTileType( pRoof->usIndex, &uiTileType );
if( uiTileType >= FIRSTROOF && uiTileType <= LASTROOF )
{ //found a roof, so return its type.
return (UINT16)uiTileType;
}
pRoof = pRoof->pNext;
}
}
}
sRadius++;
}
return 0xffff;
}
BOOLEAN RoofAtGridNo( UINT32 iMapIndex )
{
LEVELNODE *pRoof;
UINT32 uiTileType;
pRoof = gpWorldLevelData[ iMapIndex ].pRoofHead;
// Look through all objects and Search for type
while( pRoof )
{
if ( pRoof->usIndex != NO_TILE )
{
GetTileType( pRoof->usIndex, &uiTileType );
if ( uiTileType >= FIRSTROOF && uiTileType <= SECONDSLANTROOF )
return TRUE;
pRoof = pRoof->pNext;
}
}
return FALSE;
}
BOOLEAN BuildingAtGridNo( UINT32 iMapIndex )
{
if( RoofAtGridNo( iMapIndex ) )
return TRUE;
if( FloorAtGridNo( iMapIndex ) )
return TRUE;
return FALSE;
}
BOOLEAN ValidDecalPlacement( UINT32 iMapIndex )
{
if( GetVerticalWall( iMapIndex ) || GetHorizontalWall( iMapIndex )
|| GetVerticalFence( iMapIndex ) || GetHorizontalFence( iMapIndex ) )
return TRUE;
return FALSE;
}
LEVELNODE* GetVerticalWall( UINT32 iMapIndex )
{
LEVELNODE *pStruct;
UINT32 uiTileType;
UINT16 usWallOrientation;
pStruct = gpWorldLevelData[ iMapIndex ].pStructHead;
while( pStruct )
{
if ( pStruct->usIndex != NO_TILE )
{
GetTileType( pStruct->usIndex, &uiTileType );
if ( uiTileType >= FIRSTWALL && uiTileType <= LASTWALL ||
uiTileType >= FIRSTDOOR && uiTileType <= LASTDOOR )
{
GetWallOrientation( pStruct->usIndex, &usWallOrientation );
if( usWallOrientation == INSIDE_TOP_RIGHT || usWallOrientation == OUTSIDE_TOP_RIGHT )
{
return pStruct;
}
}
}
pStruct = pStruct->pNext;
}
return NULL;
}
LEVELNODE* GetHorizontalWall( UINT32 iMapIndex )
{
LEVELNODE *pStruct;
UINT32 uiTileType;
UINT16 usWallOrientation;
pStruct = gpWorldLevelData[ iMapIndex ].pStructHead;
while( pStruct )
{
if ( pStruct->usIndex != NO_TILE )
{
GetTileType( pStruct->usIndex, &uiTileType );
if ( uiTileType >= FIRSTWALL && uiTileType <= LASTWALL ||
uiTileType >= FIRSTDOOR && uiTileType <= LASTDOOR )
{
GetWallOrientation( pStruct->usIndex, &usWallOrientation );
if( usWallOrientation == INSIDE_TOP_LEFT || usWallOrientation == OUTSIDE_TOP_LEFT )
{
return pStruct;
}
}
}
pStruct = pStruct->pNext;
}
return NULL;
}
UINT16 GetVerticalWallType( UINT32 iMapIndex )
{
LEVELNODE *pWall;
UINT32 uiTileType;
pWall = GetVerticalWall( iMapIndex );
if( pWall )
{
GetTileType( pWall->usIndex, &uiTileType );
if( uiTileType >= FIRSTDOOR && uiTileType <= LASTDOOR )
uiTileType = SearchForWallType( iMapIndex );
return (UINT16)uiTileType;
}
return 0;
}
UINT16 GetHorizontalWallType( UINT32 iMapIndex )
{
LEVELNODE *pWall;
UINT32 uiTileType;
pWall = GetHorizontalWall( iMapIndex );
if( pWall )
{
GetTileType( pWall->usIndex, &uiTileType );
if( uiTileType >= FIRSTDOOR && uiTileType <= LASTDOOR )
uiTileType = SearchForWallType( iMapIndex );
return (UINT16)uiTileType;
}
return 0;
}
LEVELNODE* GetVerticalFence( UINT32 iMapIndex )
{
LEVELNODE *pStruct;
UINT32 uiTileType;
UINT16 usWallOrientation;
pStruct = gpWorldLevelData[ iMapIndex ].pStructHead;
while( pStruct )
{
if ( pStruct->usIndex != NO_TILE )
{
GetTileType( pStruct->usIndex, &uiTileType );
if ( uiTileType == FENCESTRUCT )
{
GetWallOrientation( pStruct->usIndex, &usWallOrientation );
if( usWallOrientation == INSIDE_TOP_RIGHT || usWallOrientation == OUTSIDE_TOP_RIGHT )
{
return pStruct;
}
}
}
pStruct = pStruct->pNext;
}
return NULL;
}
LEVELNODE* GetHorizontalFence( UINT32 iMapIndex )
{
LEVELNODE *pStruct;
UINT32 uiTileType;
UINT16 usWallOrientation;
pStruct = gpWorldLevelData[ iMapIndex ].pStructHead;
while( pStruct )
{
if ( pStruct->usIndex != NO_TILE )
{
GetTileType( pStruct->usIndex, &uiTileType );
if ( uiTileType == FENCESTRUCT )
{
GetWallOrientation( pStruct->usIndex, &usWallOrientation );
if( usWallOrientation == INSIDE_TOP_LEFT || usWallOrientation == OUTSIDE_TOP_LEFT )
{
return pStruct;
}
}
}
pStruct = pStruct->pNext;
}
return NULL;
}
void EraseHorizontalWall( UINT32 iMapIndex )
{
LEVELNODE *pWall;
pWall = GetHorizontalWall( iMapIndex );
if( pWall )
{
AddToUndoList( iMapIndex );
RemoveStruct( iMapIndex, pWall->usIndex );
RemoveAllShadowsOfTypeRange( iMapIndex, FIRSTWALL, LASTWALL );
}
}
void EraseVerticalWall( UINT32 iMapIndex )
{
LEVELNODE *pWall;
pWall = GetVerticalWall( iMapIndex );
if( pWall )
{
AddToUndoList( iMapIndex );
RemoveStruct( iMapIndex, pWall->usIndex );
RemoveAllShadowsOfTypeRange( iMapIndex, FIRSTWALL, LASTWALL );
}
}
void ChangeHorizontalWall( UINT32 iMapIndex, UINT16 usNewPiece )
{
LEVELNODE *pWall;
UINT32 uiTileType;
UINT16 usTileIndex;
INT16 sIndex;
pWall = GetHorizontalWall( iMapIndex );
if( pWall )
{
GetTileType( pWall->usIndex, &uiTileType );
if( uiTileType >= FIRSTWALL && uiTileType <= LASTWALL )
{ //Okay, we have the wall, now change it's type.
sIndex = PickAWallPiece( usNewPiece );
AddToUndoList( iMapIndex );
GetTileIndexFromTypeSubIndex( uiTileType, sIndex, &usTileIndex );
ReplaceStructIndex( iMapIndex, pWall->usIndex, usTileIndex );
}
}
}
void ChangeVerticalWall( UINT32 iMapIndex, UINT16 usNewPiece )
{
LEVELNODE *pWall;
UINT32 uiTileType;
UINT16 usTileIndex;
INT16 sIndex;
pWall = GetVerticalWall( iMapIndex );
if( pWall )
{
GetTileType( pWall->usIndex, &uiTileType );
if( uiTileType >= FIRSTWALL && uiTileType <= LASTWALL )
{ //Okay, we have the wall, now change it's type.
sIndex = PickAWallPiece( usNewPiece );
AddToUndoList( iMapIndex );
GetTileIndexFromTypeSubIndex( uiTileType, sIndex, &usTileIndex );
ReplaceStructIndex( iMapIndex, pWall->usIndex, usTileIndex );
}
}
}
void RestoreWalls( UINT32 iMapIndex )
{
LEVELNODE *pWall = NULL;
UINT32 uiTileType;
UINT16 usWallType;
UINT16 usWallOrientation;
UINT8 ubSaveWallUIValue;
BOOLEAN fDone = FALSE;
pWall = GetHorizontalWall( iMapIndex );
if( pWall )
{
GetTileType( pWall->usIndex, &uiTileType );
usWallType = (UINT16)uiTileType;
if( uiTileType >= FIRSTDOOR && uiTileType <= LASTDOOR )
usWallType = SearchForWallType( iMapIndex );
GetWallOrientation( pWall->usIndex, &usWallOrientation );
AddToUndoList( iMapIndex );
RemoveStruct( iMapIndex, pWall->usIndex );
RemoveAllShadowsOfTypeRange( iMapIndex, FIRSTWALL, LASTWALL );
switch( usWallOrientation )
{
case OUTSIDE_TOP_LEFT:
BuildWallPiece( iMapIndex, INTERIOR_BOTTOM, usWallType );
break;
case INSIDE_TOP_LEFT:
BuildWallPiece( iMapIndex, EXTERIOR_BOTTOM, usWallType );
break;
}
fDone = TRUE;
}
pWall = GetVerticalWall( iMapIndex );
if( pWall )
{
GetTileType( pWall->usIndex, &uiTileType );
usWallType = (UINT16)uiTileType;
if( uiTileType >= FIRSTDOOR && uiTileType <= LASTDOOR )
usWallType = SearchForWallType( iMapIndex );
GetWallOrientation( pWall->usIndex, &usWallOrientation );
AddToUndoList( iMapIndex );
RemoveStruct( iMapIndex, pWall->usIndex );
RemoveAllShadowsOfTypeRange( iMapIndex, FIRSTWALL, LASTWALL );
switch( usWallOrientation )
{
case OUTSIDE_TOP_RIGHT:
BuildWallPiece( iMapIndex, INTERIOR_RIGHT, usWallType );
break;
case INSIDE_TOP_RIGHT:
BuildWallPiece( iMapIndex, EXTERIOR_RIGHT, usWallType );
break;
}
fDone = TRUE;
}
if( fDone )
{
return;
}
//we are in a special case here. The user is attempting to restore a wall, though nothing
//is here. We will hook into the smart wall method by tricking it into using the local wall
//type, but only if we have adjacent walls.
fDone = FALSE;
if( pWall = GetHorizontalWall( iMapIndex - 1 ) )
fDone = TRUE;
if( !fDone && (pWall = GetHorizontalWall( iMapIndex + 1 )) )
fDone = TRUE;
if( !fDone && (pWall = GetVerticalWall( iMapIndex - WORLD_COLS )) )
fDone = TRUE;
if( !fDone && (pWall = GetVerticalWall( iMapIndex + WORLD_COLS )) )
fDone = TRUE;
if( !fDone )
return;
//found a wall. Let's back up the current wall value, and restore it after pasting a smart wall.
if( pWall )
{
GetTileType( pWall->usIndex, &uiTileType );
usWallType = (UINT16)uiTileType;
if( uiTileType >= FIRSTDOOR && uiTileType <= LASTDOOR )
usWallType = SearchForWallType( iMapIndex );
if( usWallType != 0xffff )
{
ubSaveWallUIValue = gubWallUIValue; //save the wall UI value.
gubWallUIValue = (UINT8)usWallType; //trick the UI value
PasteSmartWall( iMapIndex ); //paste smart wall with fake UI value
gubWallUIValue = ubSaveWallUIValue; //restore the real UI value.
}
}
}
UINT16 GetWallClass( LEVELNODE *pWall )
{
UINT16 row, col, rowVariants;
UINT16 usWallIndex;
if( !pWall )
return 0xffff;
GetSubIndexFromTileIndex( pWall->usIndex, &usWallIndex );
for ( row = 0; row < NUM_WALL_TYPES; row++ )
{
rowVariants = gbWallTileLUT[row][0];
for( col = 1; col <= rowVariants; col++ )
{
if( usWallIndex == gbWallTileLUT[row][col] )
{
return row; //row is the wall class
}
}
}
return 0xffff;
}
UINT16 GetVerticalWallClass( UINT16 iMapIndex )
{
LEVELNODE *pWall;
if( pWall = GetVerticalWall( iMapIndex ) )
return GetWallClass( pWall );
return 0xffff;
}
UINT16 GetHorizontalWallClass( UINT16 iMapIndex )
{
LEVELNODE *pWall;
if( pWall = GetVerticalWall( iMapIndex ) )
return GetWallClass( pWall );
return 0xffff;
}
#endif
+65
View File
@@ -0,0 +1,65 @@
#include "BuildDefines.h"
#ifdef JA2EDITOR
#ifndef __SMOOTHING_UTILS_H
#define __SMOOTHING_UTILS_H
#include "worlddef.h"
//Use these values when specifically replacing a wall with new type.
enum { //Wall tile types
INTERIOR_L, //interior wall with a top left orientation
INTERIOR_R, //interior wall with a top right orientation
EXTERIOR_L, //exterior wall with a top left orientation
EXTERIOR_R, //exterior wall with a top right orientation
INTERIOR_CORNER, //special interior end piece with top left orientation.
//The rest of these walls are special wall tiles for top right orientations.
INTERIOR_BOTTOMEND, //interior wall for bottom corner
EXTERIOR_BOTTOMEND, //exterior wall for bottom corner
INTERIOR_EXTENDED, //extended interior wall for top corner
EXTERIOR_EXTENDED, //extended exterior wall for top corner
INTERIOR_EXTENDED_BOTTOMEND, //extended interior wall for both top and bottom corners.
EXTERIOR_EXTENDED_BOTTOMEND, //extended exterior wall for both top and bottom corners.
NUM_WALL_TYPES
};
//Use these values when passing a ubWallPiece to BuildWallPieces.
enum {
NO_WALLS,
INTERIOR_TOP,
INTERIOR_BOTTOM,
INTERIOR_LEFT,
INTERIOR_RIGHT,
EXTERIOR_TOP,
EXTERIOR_BOTTOM,
EXTERIOR_LEFT,
EXTERIOR_RIGHT,
};
//in newsmooth.c
extern INT8 gbWallTileLUT[NUM_WALL_TYPES][7];
extern void EraseWalls( UINT32 iMapIndex );
extern void BuildWallPiece( UINT32 iMapIndex, UINT8 ubWallPiece, UINT16 usWallType );
//in Smoothing Utils
void RestoreWalls( UINT32 iMapIndex );
UINT16 SearchForRoofType( UINT32 iMapIndex );
UINT16 SearchForWallType( UINT32 iMapIndex );
BOOLEAN RoofAtGridNo( UINT32 iMapIndex );
BOOLEAN BuildingAtGridNo( UINT32 iMapIndex );
LEVELNODE* GetHorizontalWall( UINT32 iMapIndex );
LEVELNODE* GetVerticalWall( UINT32 iMapIndex );
LEVELNODE* GetVerticalFence( UINT32 iMapIndex );
LEVELNODE* GetHorizontalFence( UINT32 iMapIndex );
UINT16 GetHorizontalWallType( UINT32 iMapIndex );
UINT16 GetVerticalWallType( UINT32 iMapIndex );
void EraseHorizontalWall( UINT32 iMapIndex );
void EraseVerticalWall( UINT32 iMapIndex );
void ChangeHorizontalWall( UINT32 iMapIndex, UINT16 usNewPiece );
void ChangeVerticalWall( UINT32 iMapIndex, UINT16 usNewPiece );
UINT16 GetWallClass( LEVELNODE *pWall );
UINT16 GetVerticalWallClass( UINT16 iMapIndex );
UINT16 GetHorizontalWallClass( UINT16 iMapIndex );
BOOLEAN ValidDecalPlacement( UINT32 iMapIndex );
#endif
#endif
+109
View File
@@ -0,0 +1,109 @@
#include "BuildDefines.h"
#ifdef JA2EDITOR
#ifndef __SUMMARY_INFO_H
#define __SUMMARY_INFO_H
#include "Types.h"
#define GLOBAL_SUMMARY_VERSION 14
#define MINIMUMVERSION 7
typedef struct TEAMSUMMARY
{
UINT8 ubTotal;
UINT8 ubDetailed;
UINT8 ubProfile;
UINT8 ubExistance;
UINT8 ubNumAnimals;
UINT8 ubBadA, ubPoorA, ubAvgA, ubGoodA, ubGreatA; //attributes
UINT8 ubBadE, ubPoorE, ubAvgE, ubGoodE, ubGreatE; //equipment
}TEAMSUMMARY; //15 bytes
typedef struct SUMMARYFILE
{
//start version 1
UINT8 ubSummaryVersion;
UINT8 ubSpecial;
UINT16 usNumItems;
UINT16 usNumLights;
MAPCREATE_STRUCT MapInfo;
TEAMSUMMARY EnemyTeam;
TEAMSUMMARY CreatureTeam;
TEAMSUMMARY RebelTeam;
TEAMSUMMARY CivTeam;
UINT8 ubNumDoors;
UINT8 ubNumDoorsLocked;
UINT8 ubNumDoorsTrapped;
UINT8 ubNumDoorsLockedAndTrapped;
//start version 2
UINT8 ubTilesetID;
UINT8 ubNumRooms;
//start version 3
UINT8 ubNumElites;
UINT8 ubNumAdmins;
UINT8 ubNumTroops;
//start version 4
UINT8 ubEliteDetailed;
UINT8 ubAdminDetailed;
UINT8 ubTroopDetailed;
//start version 5
UINT8 ubEliteProfile;
UINT8 ubAdminProfile;
UINT8 ubTroopProfile;
//start version 6
UINT8 ubEliteExistance;
UINT8 ubAdminExistance;
UINT8 ubTroopExistance;
//start version 7
FLOAT dMajorMapVersion;
//start version 8
UINT8 ubCivSchedules;
//start version 9
UINT8 ubCivCows;
UINT8 ubCivBloodcats;
// //-----
// 190
//start version 10
EXITGRID ExitGrid[4]; //5*4 // 20
UINT16 usExitGridSize[4]; //2*4 // 8
BOOLEAN fInvalidDest[4]; // 4
UINT8 ubNumExitGridDests; // 1
BOOLEAN fTooManyExitGridDests; // 1
// //-----
// // 224
//start version 11
UINT8 ubEnemiesReqWaypoints; // 1
// //-----
// 225
//start version 12
UINT16 usWarningRoomNums; // 2
// 227
//start version 13
UINT8 ubEnemiesHaveWaypoints; // 1
UINT32 uiNumItemsPosition; // 4
//-----
// 232
//start version 14
UINT32 uiEnemyPlacementPosition; // 4
//-----
// 236
UINT8 ubPadding[164]; // 164
// //-----
// 400 total bytes
}SUMMARYFILE;
extern BOOLEAN gfAutoLoadA9;
extern BOOLEAN EvaluateWorld( UINT8 * pSector, UINT8 ubLevel );
extern void WriteSectorSummaryUpdate( UINT8 *puiFilename, UINT8 ubLevel, SUMMARYFILE *pSummaryFileInfo );
extern BOOLEAN gfMustForceUpdateAllMaps;
extern BOOLEAN gfMajorUpdate;
void ApologizeOverrideAndForceUpdateEverything();
#endif
#endif
+1446
View File
File diff suppressed because it is too large Load Diff
+80
View File
@@ -0,0 +1,80 @@
#include "BuildDefines.h"
#ifdef JA2EDITOR
#ifndef __EDIT_SYS_H
#define __EDIT_SYS_H
#define SMALLBRUSH 0
#define MEDIUMBRUSH 1
#define LARGEBRUSH 2
#define NO_BANKS 0
#define DRAW_BANKS 1
#define DRAW_BANK_WATER 2
#define DRAW_ERASE 3
#define NO_CLIFFS 0
#define DRAW_CLIFFS 1
#define DRAW_CLIFF_LAND 2
extern BOOLEAN gfWarning;
extern BOOLEAN gfDoFill;
extern UINT16 CurrentPaste;
extern UINT16 gDebrisPaste;
extern UINT16 gChangeElevation;
extern UINT16 CurrentStruct;
extern UINT32 gDoBanks;
extern UINT32 gDoCliffs;
void EraseMapTile( UINT32 iMapIndex );
void QuickEraseMapTile( UINT32 iMapIndex );
void DeleteStuffFromMapTile( UINT32 iMapIndex );
void PasteDebris( UINT32 iMapIndex );
void PasteStructure( UINT32 iMapIndex );
void PasteStructure1( UINT32 iMapIndex );
void PasteStructure2( UINT32 iMapIndex );
void PasteStructureCommon( UINT32 iMapIndex );
void PasteSingleWall( UINT32 iMapIndex );
void PasteSingleDoor( UINT32 iMapIndex );
void PasteSingleWindow( UINT32 iMapIndex );
void PasteSingleRoof( UINT32 iMapIndex );
void PasteSingleBrokenWall( UINT32 iMapIndex );
void PasteSingleDecoration( UINT32 iMapIndex );
void PasteSingleDecal( UINT32 iMapIndex );
void PasteSingleFloor( UINT32 iMapIndex );
void PasteSingleToilet( UINT32 iMapIndex );
void PasteRoomNumber( UINT32 iMapIndex, UINT8 ubRoomNumber );
void PasteSingleWallCommon( UINT32 iMapIndex );
UINT16 GetRandomIndexByRange( UINT16 usRangeStart, UINT16 usRangeEnd );
UINT16 GetRandomTypeByRange( UINT16 usRangeStart, UINT16 usRangeEnd );
void PasteFloor( UINT32 iMapIndex, UINT16 usFloorIndex , BOOLEAN fReplace);
void PasteBanks( UINT32 iMapIndex, UINT16 usStructIndex, BOOLEAN fReplace );
void PasteRoads( UINT32 iMapIndex );
void PasteCliffs( UINT32 iMapIndex, UINT16 usStructIndex , BOOLEAN fReplace);
void PasteTexture( UINT32 iMapIndex );
void PasteTextureCommon( UINT32 iMapIndex );
void PasteHigherTexture( UINT32 iMapIndex, UINT32 fNewType );
void RaiseWorldLand();
void EliminateObjectLayerRedundancy();
#endif
#endif
File diff suppressed because it is too large Load Diff
+83
View File
@@ -0,0 +1,83 @@
#include "BuildDefines.h"
#ifdef JA2EDITOR
#ifndef EDITSCREEN_H
#define EDITSCREEN_H
#include "Button System.h"
#define EDITOR_LIGHT_MAX (SHADE_MIN + SHADE_MAX)
#define EDITOR_LIGHT_FAKE (EDITOR_LIGHT_MAX - SHADE_MAX - 2)
extern BOOLEAN gfFakeLights;
extern GUI_BUTTON *gpPersistantButton;
extern UINT16 GenericButtonFillColors[40];
void DisplayWayPoints(void);
BOOLEAN CheckForSlantRoofs( void );
BOOLEAN CheckForFences( void );
void ShowLightPositionHandles( void );
void RemoveLightPositionHandles( void );
extern BOOLEAN DoWindowSelection( void );
extern void RemoveTempMouseCursorObject(void);
extern BOOLEAN DrawTempMouseCursorObject(void);
extern void ShowCurrentDrawingMode( void );
extern void ShowCurrentSlotImage( HVOBJECT hVObj, INT32 iWindow );
extern void ShowCurrentSlotSurface( UINT32 hSurface, INT32 iWindow );
void CreateNewMap();
void DisplayTilesetPage(void);
void FindTilesetComments(void);
void GetMasterList(void);
void HandleJA2ToolbarSelection( void );
void HandleKeyboardShortcuts( );
UINT32 PerformSelectedAction( void );
UINT32 WaitForSelectionWindowResponse( void );
UINT32 WaitForMessageBoxResponse( UINT32 uiCurrentScreen );
UINT32 WaitForHelpScreenResponse( void );
BOOLEAN PlaceLight( INT16 sRadius, INT16 iMapX, INT16 iMapY, INT16 sType );
BOOLEAN RemoveLight( INT16 iMapX, INT16 iMapY );
extern BOOLEAN gfMercResetUponEditorEntry;
void ShowEditorToolbar( INT32 iNewTaskMode );
void HideEditorToolbar( INT32 iOldTaskMode );
void ProcessSelectionArea();
void MapOptimize(void);
extern UINT16 GenericButtonFillColors[40];
//These go together. The taskbar has a specific color scheme.
extern UINT16 gusEditorTaskbarColor;
extern UINT16 gusEditorTaskbarHiColor;
extern UINT16 gusEditorTaskbarLoColor;
extern INT32 iOldTaskMode;
extern INT32 iCurrentTaskbar;
extern INT32 iTaskMode;
void ProcessAreaSelection( BOOLEAN fWithLeftButton );
void ShowEntryPoints();
void HideEntryPoints();
extern BOOLEAN gfConfirmExitFirst;
extern BOOLEAN gfConfirmExitPending;
extern BOOLEAN gfIntendOnEnteringEditor;
#endif
#endif
+167
View File
@@ -0,0 +1,167 @@
#ifdef PRECOMPILEDHEADERS
#include "Editor All.h"
#else
#include "builddefines.h"
#endif
#ifdef JA2EDITOR
#ifndef PRECOMPILEDHEADERS
#include "vobject.h"
#include "video.h"
#include "font.h"
#include "Font Control.h"
#include "messagebox.h"
#include "input.h"
#include "english.h"
#endif
//internal variables.
INT32 iMsgBoxNum;
INT32 iMsgBoxOkImg, iMsgBoxCancelImg;
INT32 iMsgBoxBgrnd,iMsgBoxOk,iMsgBoxCancel;
SGPRect MsgBoxRect;
BOOLEAN gfMessageBoxResult = FALSE;
UINT8 gubMessageBoxStatus = MESSAGEBOX_NONE;
void MsgBoxOkClkCallback( GUI_BUTTON *butn, INT32 reason );
void MsgBoxCnclClkCallback( GUI_BUTTON *butn, INT32 reason );
void CreateMessageBox( UINT16 *wzString )
{
INT16 sPixLen;
INT16 sStartX, sStartY;
sPixLen = StringPixLength ( wzString, (UINT16)gpLargeFontType1 ) + 10;
if ( sPixLen > 600 )
sPixLen = 600;
sStartX = (640 - sPixLen) / 2;
sStartY = (480 - 96) / 2;
gfMessageBoxResult = FALSE;
// Fake button for background w/ text
iMsgBoxBgrnd = CreateTextButton( wzString, (UINT16)gpLargeFontType1,
FONT_LTKHAKI, FONT_DKKHAKI, BUTTON_USE_DEFAULT, sStartX, sStartY,
sPixLen, 96, BUTTON_NO_TOGGLE, MSYS_PRIORITY_HIGHEST - 2,
BUTTON_NO_CALLBACK, BUTTON_NO_CALLBACK);
DisableButton( iMsgBoxBgrnd );
SpecifyDisabledButtonStyle( iMsgBoxBgrnd, DISABLED_STYLE_NONE );
iMsgBoxOkImg = LoadButtonImage("EDITOR//ok.sti",0,1,2,3,4);
iMsgBoxCancelImg = LoadButtonImage("EDITOR//cancel.sti",0,1,2,3,4);
iMsgBoxOk = QuickCreateButton(iMsgBoxOkImg, (INT16)(sStartX + (sPixLen/2) - 35), (INT16)(sStartY + 58),
BUTTON_NO_TOGGLE, MSYS_PRIORITY_HIGHEST - 1,
BUTTON_NO_CALLBACK, (GUI_CALLBACK)MsgBoxOkClkCallback);
iMsgBoxCancel = QuickCreateButton(iMsgBoxCancelImg, (INT16)(sStartX + (sPixLen/2) + 5), (INT16)(sStartY + 58),
BUTTON_NO_TOGGLE, MSYS_PRIORITY_HIGHEST - 1,
BUTTON_NO_CALLBACK, (GUI_CALLBACK)MsgBoxCnclClkCallback);
MsgBoxRect.iLeft = sStartX;
MsgBoxRect.iTop = sStartY;
MsgBoxRect.iRight = sStartX + sPixLen;
MsgBoxRect.iBottom = sStartY + 96;
RestrictMouseCursor( &MsgBoxRect );
gubMessageBoxStatus = MESSAGEBOX_WAIT;
}
BOOLEAN MessageBoxHandled()
{
InputAtom DummyEvent;
while( DequeueEvent( &DummyEvent ) )
{
if ( DummyEvent.usEvent == KEY_DOWN )
{
switch( DummyEvent.usParam )
{
case ENTER:
case 'y':
case 'Y':
gubMessageBoxStatus = MESSAGEBOX_DONE;
gfMessageBoxResult = TRUE;
break;
case ESC:
case 'n':
case 'N':
gubMessageBoxStatus = MESSAGEBOX_DONE;
gfMessageBoxResult = FALSE;
break;
}
}
}
if( gubMessageBoxStatus == MESSAGEBOX_DONE )
{
while( DequeueEvent( &DummyEvent ) )
continue;
}
MarkButtonsDirty();
RenderButtons( );
// InvalidateScreen( );
// ExecuteBaseDirtyRectQueue();
EndFrameBufferRender( );
return gubMessageBoxStatus == MESSAGEBOX_DONE;
}
void RemoveMessageBox( )
{
FreeMouseCursor( );
RemoveButton( iMsgBoxCancel );
RemoveButton( iMsgBoxOk );
RemoveButton( iMsgBoxBgrnd );
UnloadButtonImage( iMsgBoxOkImg );
UnloadButtonImage( iMsgBoxCancelImg );
gubMessageBoxStatus = MESSAGEBOX_NONE;
}
//----------------------------------------------------------------------------------------------
// Quick Message Box button callback functions.
//----------------------------------------------------------------------------------------------
void MsgBoxOkClkCallback( GUI_BUTTON *butn, INT32 reason )
{
if ( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN)
{
butn->uiFlags |= BUTTON_CLICKED_ON;
}
else if ( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
{
gubMessageBoxStatus = MESSAGEBOX_DONE;
gfMessageBoxResult = TRUE;
}
}
void MsgBoxCnclClkCallback( GUI_BUTTON *butn, INT32 reason )
{
if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN )
{
butn->uiFlags |= BUTTON_CLICKED_ON;
}
else if ( reason & MSYS_CALLBACK_REASON_LBUTTON_UP )
{
gubMessageBoxStatus = MESSAGEBOX_DONE;
gfMessageBoxResult = FALSE;
}
}
//----------------------------------------------------------------------------------------------
// End of the quick message box callback functions
//----------------------------------------------------------------------------------------------
#endif
+51
View File
@@ -0,0 +1,51 @@
#include "BuildDefines.h"
#ifdef JA2EDITOR
#ifndef __MESSAGEBOX_H
#define __MESSAGEBOX_H
enum
{
MESSAGEBOX_NONE,
MESSAGEBOX_DONE,
MESSAGEBOX_WAIT
};
extern UINT8 gubMessageBoxStatus;
extern BOOLEAN gfMessageBoxResult;
void CreateMessageBox( UINT16 *wzString );
BOOLEAN MessageBoxHandled();
void RemoveMessageBox();
//NOTES:
//Rewrote the damn thing. It is better now because you have less management issues.
//In your screen's main loop, instead of using the previous method, you would use the following syntax:
//
// if( gubMessageBoxState )
// {
// if( MessageBoxHandled() )
// return ProcessMyOwnMessageBoxResultHandler();
// return MYCURRENT_SCREEN;
// }
//
// UINT32 ProcessMyOwnMessageBoxResultHandlerFunction()
// {
// RemoveMessageBox(); //MUST BE HERE
// if( gfMessageBoxResult ) //user selected yes
// {
// ...
// return DESIRED_SCREEN;
// }
// else //user selected no
// ...
// }
#endif
#endif
+1190
View File
File diff suppressed because it is too large Load Diff
+28
View File
@@ -0,0 +1,28 @@
#include "BuildDefines.h"
#ifdef JA2EDITOR
#ifndef __NEWSMOOTH_H
#define __NEWSMOOTH_H
void AddBuildingSectionToWorld( SGPRect *pSelectRegion );
void RemoveBuildingSectionFromWorld( SGPRect *pSelectRegion );
void AddCaveSectionToWorld( SGPRect *pSelectRegion );
void RemoveCaveSectionFromWorld( SGPRect *pSelectRegion );
void EraseBuilding( UINT32 iMapIndex );
void RebuildRoof( UINT32 iMapIndex, UINT16 usRoofType );
void RebuildRoofUsingFloorInfo( INT32 iMapIndex, UINT16 usRoofType );
void AddCave( INT32 iMapIndex, UINT16 usIndex );
void AnalyseCaveMapForStructureInfo();
#endif
#endif
+497
View File
@@ -0,0 +1,497 @@
//FUNCTIONALITY:
//This popup menu functions IDENTICALLY to Windows95's methodology. You can use the arrow keys, or the
//mouse in two methods. The first method is where you release the mouse button before
//moving the cursor inside the popup menu, which makes it persistant (it won't go away until you click again),
//or non-persistant, where you release the button inside the menu after your initial click (non-persistant).
//IMPORTANT NOTE:
//Linda Currie, the main user of the editor dislikes the non-persistant functionality, however, it is still
//supported. Just remove the commented line of code (search for UNCOMMENT), and it's fixed -- it is
//currently disabled.
#ifdef PRECOMPILEDHEADERS
#include "Editor All.h"
#else
#include "builddefines.h"
#endif
#ifdef JA2EDITOR
#ifndef PRECOMPILEDHEADERS
#include "tiledef.h"
#include "sysutil.h"
#include "font.h"
#include "Font Control.h"
#include "line.h"
#include "worlddat.h"
#include "selectwin.h"
#include "popupmenu.h"
#include "EditorDefines.h"
#include "render dirty.h"
#include "debug.h"
#include "mousesystem.h"
#include "cursors.h"
#include "overhead types.h"
#include "EditorMercs.h"
#include "Scheduling.h"
#include "english.h"
#include "Item Statistics.h"
#endif
CurrentPopupMenuInformation gPopup;
MOUSE_REGION popupRegion;
UINT16 gusEntryHeight;
BOOLEAN fWaitingForLButtonRelease = FALSE;
extern UINT16 gszScheduleActions[ NUM_SCHEDULE_ACTIONS ][20];
//Finds the string for any popup menu in JA2 -- the strings are stored
//in different ways in each instance.
INT16* GetPopupMenuString( UINT8 ubIndex )
{
switch( gPopup.ubPopupMenuID )
{
case CHANGETSET_POPUP: //tile sets
return gTilesets[ ubIndex ].zName;
case OWNERSHIPGROUP_POPUP: //civilian groups
case CHANGECIVGROUP_POPUP: //civilian groups
return (INT16 *)gszCivGroupNames[ ubIndex ];
case SCHEDULEACTION_POPUP: //setting scheduling actions
return (INT16 *)gszScheduleActions[ ubIndex ];
case ACTIONITEM_POPUP:
return (INT16 *)gszActionItemDesc[ ubIndex ];
default:
return 0;
}
}
/*
InitPopUpMenu
---------------
Creates the popup menu, then takes control of the i/o
effectively turning the popup into a modal system (forcing the
user to make a selection or cancel before doing anything else.
There are two modes of operation as soon as the user presses the mouse
on a popup menu activation button.
1) The user releases the mouse before moving the cursor onto
the popup region. The popup menu will end as soon as the
user presses the mouse button. If the cursor is out of the
popup region, then it returns 0.
2) The user holds the mouse while moving the cursor onto the
popup region. The popup menu will end as soon as the user
releases the mouse button. If the cursor is out of the popup
region, then it returns 0.
Returns 0 if nothing in menu was selected, else
returns the menu entry number starting from 1.
*/
void InitPopupMenu( INT32 iButtonID, UINT8 ubPopupMenuID, UINT8 ubDirection )
{
UINT16 usX, usY;
UINT16 usMenuHeight;
UINT16 usMenuWidth = 0;
UINT16 usCurrStrWidth;
UINT8 ubColumn, ubEntry;
UINT8 ubCounter;
GUI_BUTTON *button;
//calculate the location of the menu based on the button position.
//This also calculates the menu's direction based on position.
gPopup.usFont = (UINT16)SMALLFONT1;
gusEntryHeight = GetFontHeight( gPopup.usFont );
button = ButtonList[ iButtonID ];
MSYS_DisableRegion( &gBottomPanalRegion );
switch( ubDirection )
{
case DIR_UPRIGHT:
usX = button->Area.RegionTopLeftX;
usY = button->Area.RegionTopLeftY;
break;
case DIR_UPLEFT:
usX = button->Area.RegionBottomRightX;
usY = button->Area.RegionTopLeftY;
break;
case DIR_DOWNRIGHT:
usX = button->Area.RegionTopLeftX;
usY = button->Area.RegionBottomRightY;
break;
case DIR_DOWNLEFT:
usX = button->Area.RegionBottomRightX;
usY = button->Area.RegionBottomRightY;
break;
}
//Decipher the popupMenuID
switch( ubPopupMenuID )
{
case CHANGETSET_POPUP: //change tileset
gPopup.ubNumEntries = NUM_TILESETS;
break;
case OWNERSHIPGROUP_POPUP:
case CHANGECIVGROUP_POPUP:
gPopup.ubNumEntries = NUM_CIV_GROUPS;
break;
case SCHEDULEACTION_POPUP:
gPopup.ubNumEntries = NUM_SCHEDULE_ACTIONS;
break;
case ACTIONITEM_POPUP:
gPopup.ubNumEntries = NUM_ACTIONITEMS;
break;
default:
return;
}
gPopup.usFont = (UINT16)SMALLFONT1;
gusEntryHeight = GetFontHeight( gPopup.usFont );
button = ButtonList[ iButtonID ];
MSYS_DisableRegion( &gBottomPanalRegion );
gPopup.ubPopupMenuID = ubPopupMenuID;
gPopup.ubSelectedIndex = 0;
gPopup.ubActiveType = POPUP_ACTIVETYPE_NOT_YET_DETERMINED;
gPopup.fActive = TRUE;
fWaitingForLButtonRelease = FALSE;
gPopup.fUseKeyboardInfoUntilMouseMoves = FALSE;
//Initialize the last mouse position to be out of bounds.
gPopup.usLastMouseX = 1000;
gPopup.usLastMouseY = 1000;
//clear the column widths.
for( ubColumn = 0; ubColumn < MAX_COLUMNS; ubColumn++ )
gPopup.ubColumnWidth[ ubColumn ] = 0;
//1) Calc total entry height of the popup region.
gPopup.ubColumns = 1;
gPopup.ubMaxEntriesPerColumn = gPopup.ubNumEntries;
usMenuHeight = gPopup.ubNumEntries * gusEntryHeight + 3;
while( usMenuHeight >= usY && ( ubDirection == DIR_UPLEFT || ubDirection == DIR_UPRIGHT ) ||
480-usMenuHeight >= usY && ( ubDirection == DIR_DOWNLEFT || ubDirection == DIR_DOWNRIGHT ) )
{ //menu has too many entries. Increase the number of columns until the height is
//less than the max height.
gPopup.ubMaxEntriesPerColumn = (gPopup.ubNumEntries+gPopup.ubColumns)/(gPopup.ubColumns+1);
usMenuHeight = gPopup.ubMaxEntriesPerColumn * gusEntryHeight + 3;
gPopup.ubColumns++;
}
//now we have the number of columns as well as the max number of entries per column, and
//the total menu height.
//We now calculate the total width of the menu as well as the max width of each column.
ubCounter = 0;
usMenuWidth = 0;
for( ubColumn = 0; ubColumn < gPopup.ubColumns; ubColumn++ )
{
for( ubEntry = 0; ubEntry < gPopup.ubMaxEntriesPerColumn; ubEntry++ )
{
if( ubCounter >= gPopup.ubNumEntries )
break; //done (don't want to process undefined entries...)
usCurrStrWidth = 16 + StringPixLength( GetPopupMenuString( ubCounter ) , gPopup.usFont );
if( usCurrStrWidth > gPopup.ubColumnWidth[ ubColumn ] )
{
gPopup.ubColumnWidth[ ubColumn ] = (UINT8)usCurrStrWidth;
}
ubCounter++;
}
usMenuWidth += gPopup.ubColumnWidth[ ubColumn ];
}
//Calculate popup menu boundaries based on direction from argument point.
switch( ubDirection )
{
case DIR_UPRIGHT:
gPopup.usLeft = usX;
gPopup.usTop = usY - usMenuHeight - 1;
gPopup.usRight = usX + usMenuWidth;
gPopup.usBottom = usY - 1;
break;
case DIR_UPLEFT:
gPopup.usLeft = usX - usMenuWidth;
gPopup.usTop = usY - usMenuHeight - 1;
gPopup.usRight = usX;
gPopup.usBottom = usY - 1;
break;
case DIR_DOWNRIGHT:
gPopup.usLeft = usX;
gPopup.usTop = usY + 1;
gPopup.usRight = usX + usMenuWidth;
gPopup.usBottom = usY + usMenuHeight + 1;
break;
case DIR_DOWNLEFT:
gPopup.usLeft = usX - usMenuWidth;
gPopup.usTop = usY + 1;
gPopup.usRight = usX;
gPopup.usBottom = usY + usMenuHeight + 1;
break;
}
MSYS_DefineRegion( &popupRegion, 0, 0, 640, 480, MSYS_PRIORITY_HIGHEST,
CURSOR_NORMAL, MSYS_NO_CALLBACK, MSYS_NO_CALLBACK );
RenderPopupMenu();
}
void RenderPopupMenu()
{
UINT16 usX, usY;
UINT8 ubColumn, ubEntry, ubCounter;
UINT8 *pDestBuf;
UINT32 uiDestPitchBYTES;
UINT16 usLineColor;
UINT16 usStringWidth;
UINT16 usStart;
//Draw the menu
ColorFillVideoSurfaceArea(FRAME_BUFFER,
gPopup.usLeft, gPopup.usTop, gPopup.usRight, gPopup.usBottom,
Get16BPPColor(FROMRGB(128, 128, 128) ) );
pDestBuf = LockVideoSurface( FRAME_BUFFER, &uiDestPitchBYTES );
SetClippingRegionAndImageWidth( uiDestPitchBYTES, 0, 0, 640, 480 );
usLineColor = Get16BPPColor( FROMRGB( 64, 64, 64 ) );
RectangleDraw( TRUE, gPopup.usLeft, gPopup.usTop, gPopup.usRight, gPopup.usBottom,
usLineColor, pDestBuf );
if( gPopup.ubColumns > 1 )
{ //draw a vertical line between each column
usStart = gPopup.usLeft + gPopup.ubColumnWidth[ 0 ];
for( ubColumn = 1; ubColumn < gPopup.ubColumns; ubColumn++ )
{
LineDraw( TRUE, usStart, gPopup.usTop, usStart, gPopup.usBottom, usLineColor, pDestBuf );
}
usStart += (UINT16)gPopup.ubColumnWidth[ ubColumn ];
}
UnLockVideoSurface( FRAME_BUFFER );
//Set up the text attributes.
SetFont( gPopup.usFont);
SetFontBackground( FONT_MCOLOR_BLACK );
SetFontForeground( FONT_MCOLOR_WHITE );
usX = gPopup.usLeft + 1;
ubCounter = 0;
usStart = gPopup.usLeft;
for( ubColumn = 0; ubColumn < gPopup.ubColumns; ubColumn++ )
{
for( ubEntry = 0; ubEntry < gPopup.ubMaxEntriesPerColumn; ubEntry++ )
{
if( ubCounter >= gPopup.ubNumEntries )
return; //done
//Calc current string's width in pixels. Adding 14 pixels which is the width of
//two padded gPopup.usFont spaces not stored in the string.
usStringWidth = 14 + StringPixLength( GetPopupMenuString( ubCounter ), gPopup.usFont );
//Horizontally center the string inside the popup menu
usX = usStart + ( gPopup.ubColumnWidth[ ubColumn ] - usStringWidth ) / 2;
usY = gPopup.usTop + 1 + ubEntry * gusEntryHeight;
if( ubCounter == gPopup.ubSelectedIndex - 1 )
{
//This is the highlighted menu entry.
SetFontForeground( FONT_MCOLOR_LTBLUE );
mprintf( usX, usY, L" %s ", GetPopupMenuString( ubCounter ) );
SetFontForeground( FONT_MCOLOR_WHITE );
}
else
{
mprintf( usX, usY, L" %s ", GetPopupMenuString( ubCounter ) );
}
ubCounter++;
}
usStart += gPopup.ubColumnWidth[ ubColumn ];
}
}
//This private function of PopupMenuHandle determines which menu entry
//is highlighted based on the mouse cursor position. Returns 0 if the
//mouse is out of the menu region.
UINT8 GetPopupIndexFromMousePosition()
{
UINT8 ubNumEntriesDown;
UINT16 usRelX;
UINT8 ubCount;
if( gusMouseXPos >= gPopup.usLeft
&& gusMouseXPos <= gPopup.usRight
&& gusMouseYPos > gPopup.usTop //one pixel gap on top ignored
&& gusMouseYPos < gPopup.usBottom - 2 ) //two pixel gap on bottom ignored
{
//subtract the top y coord of the popup region from the mouse's yPos as well
//as an extra pixel at the top of the region which is ignored in menu selection,
//divide this number by the height of a menu entry, then add one. This will
//return the menu index from 1 (at the top) to n (at the bottom).
ubNumEntriesDown = (gusMouseYPos - gPopup.usTop - 1) / gusEntryHeight + 1;
usRelX = gusMouseXPos - gPopup.usLeft;
ubCount=0;
while( usRelX > gPopup.ubColumnWidth[ ubCount ] )
{
usRelX -= gPopup.ubColumnWidth[ ubCount ];
ubCount++;
ubNumEntriesDown += gPopup.ubMaxEntriesPerColumn;
}
if( ubNumEntriesDown >= gPopup.ubNumEntries )
ubNumEntriesDown = gPopup.ubNumEntries;
return ubNumEntriesDown;
}
return 0; //mouse not in valid region.
}
void PopupMenuHandle()
{
InputAtom InputEvent;
if( gPopup.ubActiveType == POPUP_ACTIVETYPE_NOT_YET_DETERMINED )
{
//Attempt to determine if the menu will be persistant or not.
//Determination is made when the mouse's left button is released or if
//the mouse cursor enters the menu region.
if( gusMouseXPos >= gPopup.usLeft
&& gusMouseXPos <= gPopup.usRight
&& gusMouseYPos > gPopup.usTop //one pixel gap on top ignored
&& gusMouseYPos < gPopup.usBottom - 1 ) //two pixel gap on bottom ignored
{
//mouse cursor has just entered the menu region -- nonpersistant.
//KRIS: !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//Disabled this because Linda doesn't like it... (I like it though, and it works)
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//UNCOMMENT IF NONPERSISTANT IS ALLOWED
//gPopup.ubActiveType = POPUP_ACTIVETYPE_NONPERSISTANT;
return;
}
else if( !gfLeftButtonState )
{ //left button has been released before entering region -- persistant
gPopup.ubActiveType = POPUP_ACTIVETYPE_PERSISTANT;
return;
}
}
if( !gPopup.fUseKeyboardInfoUntilMouseMoves )
{
//check menu entry based on mouse position
gPopup.ubSelectedIndex = GetPopupIndexFromMousePosition();
}
else if( gusMouseXPos != gPopup.usLastMouseX || gusMouseYPos != gPopup.usLastMouseY )
{
//The keyboard determined the last entry, but the mouse has moved,
//so use the mouse to determine the new entry.
gPopup.fUseKeyboardInfoUntilMouseMoves = FALSE;
gPopup.ubSelectedIndex = GetPopupIndexFromMousePosition();
}
//Check terminating conditions for persistant states.
if( gfLeftButtonState && gPopup.ubActiveType == POPUP_ACTIVETYPE_PERSISTANT )
fWaitingForLButtonRelease = TRUE;
if( gfLeftButtonState && gPopup.ubActiveType == POPUP_ACTIVETYPE_PERSISTANT
|| !gfLeftButtonState && gPopup.ubActiveType == POPUP_ACTIVETYPE_NONPERSISTANT )
{
//Selection conditions via mouse have been met whether the mouse is in the
//menu region or not.
gPopup.ubSelectedIndex = GetPopupIndexFromMousePosition();
if( gPopup.ubSelectedIndex )
{
ProcessPopupMenuSelection();
}
gPopup.fActive = FALSE;
MSYS_RemoveRegion( &popupRegion );
gfRenderWorld = TRUE;
gfRenderTaskbar = TRUE;
return;
}
//Use keyboard input as well.
while( DequeueEvent( &InputEvent ) )
{
switch(InputEvent.usEvent)
{
case KEY_DOWN:
switch( InputEvent.usParam )
{
case DNARROW:
gPopup.fUseKeyboardInfoUntilMouseMoves = TRUE;
gPopup.usLastMouseX = gusMouseXPos;
gPopup.usLastMouseY = gusMouseYPos;
gPopup.ubSelectedIndex++;
if( gPopup.ubSelectedIndex > gPopup.ubNumEntries )
{
gPopup.ubSelectedIndex = 1;
}
break;
case UPARROW:
gPopup.fUseKeyboardInfoUntilMouseMoves = TRUE;
gPopup.usLastMouseX = gusMouseXPos;
gPopup.usLastMouseY = gusMouseYPos;
if( gPopup.ubSelectedIndex < 2 )
{
gPopup.ubSelectedIndex = gPopup.ubNumEntries;
}
else
{
gPopup.ubSelectedIndex--;
}
break;
case ESC:
gPopup.fActive = FALSE;
MSYS_RemoveRegion( &popupRegion );
gfRenderWorld = TRUE;
gfRenderTaskbar = TRUE;
break;
case ENTER:
ProcessPopupMenuSelection();
gPopup.fActive = FALSE;
MSYS_RemoveRegion( &popupRegion );
gfRenderWorld = TRUE;
gfRenderTaskbar = TRUE;
break;
}
break;
}
}
}
void ProcessPopupMenuSelection()
{
switch( gPopup.ubPopupMenuID )
{
case CHANGETSET_POPUP:
//change the tileset here.
ReloadTileset( (UINT8)(gPopup.ubSelectedIndex - 1 ) );
InitJA2SelectionWindow( );
break;
case CHANGECIVGROUP_POPUP:
ChangeCivGroup( (UINT8)(gPopup.ubSelectedIndex - 1) );
break;
case SCHEDULEACTION_POPUP:
UpdateScheduleAction( (UINT8)(gPopup.ubSelectedIndex - 1) );
break;
case ACTIONITEM_POPUP:
UpdateActionItem( (UINT8)(gPopup.ubSelectedIndex - 1) );
break;
case OWNERSHIPGROUP_POPUP:
SetOwnershipGroup( (UINT8)(gPopup.ubSelectedIndex - 1) );
break;
}
}
BOOLEAN ProcessPopupMenuIfActive( )
{
if( !gPopup.fActive && !fWaitingForLButtonRelease )
return FALSE;
if( fWaitingForLButtonRelease )
{
if( !gfLeftButtonState )
{
fWaitingForLButtonRelease = FALSE;
return FALSE;
}
return TRUE;
}
PopupMenuHandle();
RenderPopupMenu();
InvalidateRegion( gPopup.usLeft, gPopup.usTop, gPopup.usRight, gPopup.usBottom );
ExecuteBaseDirtyRectQueue();
EndFrameBufferRender( );
return TRUE;
}
#endif
+106
View File
@@ -0,0 +1,106 @@
#include "BuildDefines.h"
#ifdef JA2EDITOR
//popupmenu.h
//Author: Kris Morness
//Created: Sept 4, 1997
#ifndef __POPUPMENU_H
#define __POPUPMENU_H
/*
POPUP MENU
DESIGN CONSIDERATIONS
There is currently no support for nested popup menus. Let Kris know if
you need this.
USER INSTRUCTIONS
The goal of this popup menu system is to create a quick and intuitive
interface system which is functionally similar to Win95 and MacOS.
As soon as you click on a button which activates the popup menu, the user
will choose a selection in one of three ways:
1) KEYBOARD - at anytime, the user can use the keyboard regardless of mouse
mode. The up/down arrow keys will cycle through the choices and enter will
accept the choice. ESC will cancel the menu without making a choice.
2) When the mousedown event activates the menu, the user releases the mouse before
entering the popup menu region. The menu mode will change and become persistant.
Clicking on the hilighted item will close the popup and activate the choice.
Clicking elsewhere, the popup will be closed without making a selection. This
is functionally equivalent to Win95.
3) When the mousedown event activates the menu, the user holds the mouse down and
moves the cursor over the popup region. At this moment the menu becomes
non-persistant and a choice is made by releasing the mouse. If the mouse is
released on a highlighted choice, that choice is selected, otherwise the popup
is cancelled. This is functionally equivalent to MacOS. The small diffence is
that under Win95's standard convention, the release of the mouse outside of the
region doesn't kill the menu, but in MacOS, it does.
*/
enum popupMenuIDs
{
CHANGETSET_POPUP,
CHANGECIVGROUP_POPUP,
SCHEDULEACTION_POPUP,
ACTIONITEM_POPUP,
OWNERSHIPGROUP_POPUP,
};
//The direction of the popup menu relative to the button
//pressed to activate it or mouse position. In editor mode,
//this will attempt to go up and to the right of the button.
#define UPMASK 0x00
#define DNMASK 0x10
#define RTMASK 0x00
#define LTMASK 0x01
#define DIR_UPRIGHT (UPMASK + RTMASK)
#define DIR_UPLEFT (UPMASK + LTMASK)
#define DIR_DOWNRIGHT (DNMASK + RTMASK)
#define DIR_DOWNLEFT (DNMASK + LTMASK)
#define POPUP_ACTIVETYPE_NOT_YET_DETERMINED 0
#define POPUP_ACTIVETYPE_PERSISTANT 1
#define POPUP_ACTIVETYPE_NONPERSISTANT 2
#define MAX_COLUMNS 8
//This structure contains all the required information for rendering
//the popup menu while in
typedef struct currentPopupMenuInformation{
UINT8 ubPopupMenuID;
UINT8 ubSelectedIndex; //current popup menu index hilited.
UINT8 ubNumEntries;
UINT8 ubColumns;
UINT8 ubMaxEntriesPerColumn;
UINT8 ubColumnWidth[ MAX_COLUMNS ];
UINT8 ubActiveType;
UINT16 usFont;
BOOLEAN fActive;
BOOLEAN fUseKeyboardInfoUntilMouseMoves;
UINT16 usLeft, usTop, usRight, usBottom; //popup region coords.
UINT16 usLastMouseX, usLastMouseY;
}CurrentPopupMenuInformation;
//A global var that keeps the popup menu information.
extern CurrentPopupMenuInformation gPopup;
extern UINT16 *popupMenuStrings[5];
//These are the two main functions that outside users would call.
void InitPopupMenu( INT32 iButtonID, UINT8 ubPopupMenuID, UINT8 ubDirection );
BOOLEAN ProcessPopupMenuIfActive();
//Internal functions that handled by ProcessPopupMenuIfActive
void RenderPopupMenu();
void PopupMenuHandle();
void ProcessPopupMenuSelection();
#endif
#endif
+1671
View File
File diff suppressed because it is too large Load Diff
+186
View File
@@ -0,0 +1,186 @@
#include "BuildDefines.h"
#ifdef JA2EDITOR
#ifndef _SELECTION_WIN_H_
#define _SELECTION_WIN_H_
#include "Types.h"
#include "vobject.h"
#include "mousesystem.h"
#include "Button System.h"
#define CANCEL_ICON 0
#define UP_ICON 1
#define DOWN_ICON 2
#define OK_ICON 3
extern INT32 iButtonIcons[4];
extern INT32 iSelectWin,iCancelWin,iScrollUp,iScrollDown;
extern BOOLEAN fAllDone;
extern void CreateJA2SelectionWindow( INT16 sWhat );
extern void InitJA2SelectionWindow( void );
extern void ShutdownJA2SelectionWindow( void );
extern void RemoveJA2SelectionWindow( void );
extern void RenderSelectionWindow( void );
extern void DrawSelections( void );
extern void SelWinClkCallback( GUI_BUTTON *button, INT32 reason );
extern void CnclClkCallback( GUI_BUTTON *button, INT32 reason );
extern void UpClkCallback( GUI_BUTTON *button, INT32 reason );
extern void DwnClkCallback( GUI_BUTTON *button, INT32 reason );
extern void OkClkCallback( GUI_BUTTON *button, INT32 reason );
extern void ScrollSelWinUp(void);
extern void ScrollSelWinDown(void);
// defines for DisplaySpec.ubType
#define DISPLAY_TEXT 1
#define DISPLAY_GRAPHIC 2
#define ONE_COLUMN 0x0001
#define ONE_ROW 0x0002
#define CLEAR_BACKGROUND 0x0004
#define DISPLAY_ALL_OBJECTS 0xffff
#define MAX_SELECTIONS 120
enum
{
SELWIN_SINGLEWALL,
SELWIN_SINGLEDOOR,
SELWIN_SINGLEWINDOW,
SELWIN_SINGLEROOF,
SELWIN_SINGLENEWROOF,
SELWIN_SINGLEBROKENWALL,
SELWIN_SINGLEDECOR,
SELWIN_SINGLEDECAL,
SELWIN_SINGLEFLOOR,
SELWIN_SINGLETOILET,
SELWIN_ROOM,
SELWIN_BANKS,
SELWIN_ROADS,
SELWIN_DEBRIS,
SELWIN_OSTRUCTS,
SELWIN_OSTRUCTS1,
SELWIN_OSTRUCTS2
};
typedef struct
{
UINT8 ubType;
union
{
struct
{
HVOBJECT hVObject;
UINT16 usStart;
UINT16 usEnd;
UINT32 uiObjIndx;
};
struct
{
UINT16 * pString;
};
};
}
DisplaySpec;
typedef struct _DisplayList
{
HVOBJECT hObj;
UINT16 uiIndex;
INT16 iX;
INT16 iY;
INT16 iWidth;
INT16 iHeight;
UINT32 uiObjIndx;
BOOLEAN fChosen;
struct _DisplayList *pNext;
} DisplayList;
typedef struct _Selections
{
UINT32 uiObject;
UINT16 usIndex;
INT16 sCount;
} Selections;
INT32 FindInSelectionList( DisplayList *pNode );
BOOLEAN IsInSelectionList( DisplayList *pNode );
INT32 GetRandomSelection( void );
BOOLEAN RemoveFromSelectionList( DisplayList *pNode );
void AddToSelectionList( DisplayList *pNode );
void RestoreSelectionList( void );
void SaveSelectionList( void );
BOOLEAN ClearSelectionList( void );
void DisplaySelectionWindowGraphicalInformation();
extern INT32 iCurBank;
extern Selections *pSelList;
extern INT32 *pNumSelList;
extern Selections SelOStructs[ MAX_SELECTIONS ];
extern Selections SelOStructs1[ MAX_SELECTIONS ];
extern Selections SelOStructs2[ MAX_SELECTIONS ];
extern Selections SelBanks[ MAX_SELECTIONS ];
extern Selections SelRoads[ MAX_SELECTIONS ];
extern Selections SelDebris[ MAX_SELECTIONS ];
extern Selections SelSingleWall[ MAX_SELECTIONS ];
extern Selections SelSingleDoor[ MAX_SELECTIONS ];
extern Selections SelSingleWindow[ MAX_SELECTIONS ];
extern Selections SelSingleRoof[ MAX_SELECTIONS ];
extern Selections SelSingleNewRoof[ MAX_SELECTIONS ];
extern Selections SelSingleBrokenWall[ MAX_SELECTIONS ];
extern Selections SelSingleDecor[ MAX_SELECTIONS ];
extern Selections SelSingleDecal[ MAX_SELECTIONS ];
extern Selections SelSingleFloor[ MAX_SELECTIONS ];
extern Selections SelSingleToilet[ MAX_SELECTIONS ];
extern Selections SelRoom[ MAX_SELECTIONS ];
extern INT32 iNumOStructsSelected;
extern INT32 iNumOStructs1Selected;
extern INT32 iNumOStructs2Selected;
extern INT32 iNumBanksSelected;
extern INT32 iNumRoadsSelected;
extern INT32 iNumDebrisSelected;
extern INT32 iNumWallsSelected;
extern INT32 iNumDoorsSelected;
extern INT32 iNumWindowsSelected;
extern INT32 iNumDecorSelected;
extern INT32 iNumDecalsSelected;
extern INT32 iNumBrokenWallsSelected;
extern INT32 iNumFloorsSelected;
extern INT32 iNumToiletsSelected;
extern INT32 iNumRoofsSelected;
extern INT32 iNumNewRoofsSelected;
extern INT32 iNumRoomsSelected;
extern INT32 iDrawMode;
extern DisplayList *TrashList( DisplayList *pNode );
extern BOOLEAN BuildDisplayWindow( DisplaySpec *pDisplaySpecs, UINT16 usNumSpecs, DisplayList **pDisplayList,
SGPPoint * pUpperLeft, SGPPoint * pBottomRight,
SGPPoint * pSpacing, UINT16 fFlags );
extern BOOLEAN DisplayWindowFunc( DisplayList *pNode, INT16 iTopCutOff, INT16 iBottomCutOff, SGPPoint *pUpperLeft, UINT16 fFlags);
#endif
#endif
+733
View File
@@ -0,0 +1,733 @@
#ifdef PRECOMPILEDHEADERS
#include "Editor All.h"
#else
#include "builddefines.h"
#endif
#ifdef JA2EDITOR
#ifndef PRECOMPILEDHEADERS
#include "stdlib.h"
#include "FileMan.h"
#include "time.h"
#include "debug.h"
#include "tiledef.h"
#include "worlddef.h"
#include "worldman.h"
#include "smooth.h"
#include "editscreen.h"
#include "selectwin.h"
#include "isometric utils.h"
#include "structure wrap.h"
#include "Exit Grids.h"
#include "Editor Undo.h"
#endif
INT16 gbSmoothStruct[] =
{
3, 2, 12, 27, 12, 0,
5, 2, 15, 30, 39, 0,
7, 2, 17, 32, 41, 0,
11, 2, 14, 29, 14, 0,
8, 2, 13, 28, 38, 0,
15, 1, 19, 0, 43, 0,
26, 1, 20, 0, 44, 0,
12, 2, 18, 33, 42, 0,
23, 1, 21, 0, 45, 0,
18, 2, 16, 31, 40, 0,
21, 1, 22, 0, 46, 0,
14, 2, 11, 26, 11, 0,
19, 1, 23, 0, 47, 0,
16, 2, 24, 34, 48, 0,
10, 2, 25, 35, 49, 0,
-1
};
// This is a list of smoothed out water/shoreline textures
// Coding is as such:
// 1st - the corresponding bitvalue for the surrounding water tiles
// 2nd - the number of variations to randomize terrain
// 3rd - the first variation
// 4th - the second variation
INT16 gbSmoothWaterStruct[] =
// FIRST ENTRY MAJIC NUMBER CALCULATED
// 2nd ENTRY # OF VARIATIONS
// 3rd, 4rth ENTRY TILE NUMBERS ( entry 1, entry 2 )
{
1020, 1, 11, 0,
1000, 1, 12, 0,
510, 2, 13, 43,
190, 1, 14, 0,
894, 1, 15, 0,
622, 1, 16, 0,
1014, 2, 17, 41,
944, 1, 18, 24,
872, 1, 19, 0,
992, 1, 20, 0,
62, 1, 21, 0,
190, 2, 22, 14,
620, 1, 23, 0,
944, 1, 24, 18,
878, 2, 25, 32,
434, 1, 28, 0,
110, 1, 29,0,
1010, 1, 30,0,
876, 2, 31, 32,
878, 2, 32, 31,
1004, 2, 32, 31,
1006, 2, 33, 34,
1008, 2, 34, 33,
1016, 2, 33, 34,
126, 2, 35, 36,
254, 2, 35, 26,
638, 2, 36, 26,
438, 2, 38, 27,
446, 2, 37, 38,
950, 2, 37, 27,
864, 1, 39, 0,
1040, 1, 40, 0,
1014, 2, 41, 17,
432, 1, 42, 0,
510, 1, 43, 13,
54, 1, 44, 0,
108, 1, 45, 0,
-1
};
BOOLEAN HigherLevel( UINT32 gridno, UINT8 NewLevel );
BOOLEAN ContainsWater( UINT32 gridno );
void SmoothTerrain(int gridno, int origType, UINT16 *piNewTile, BOOLEAN fForceSmooth )
{
int temp=0,type=0;
int FullTile = FALSE;
UINT16 usOldIndex;
UINT16 usTempIndex;
UINT32 cnt;
BOOLEAN fFound;
UINT32 uiTempIndex;
UINT16 usTileIndex;
UINT16 land=0;
UINT32 uiTopType;
BOOLEAN fSameTile;
INT16 *pSmoothStruct;
// Check to see if the orginal texture was water, is so, smooth square/hex with
// SmoothWaterTerrain rather than the proceeding method
if( origType==REGWATERTEXTURE)
{
SmoothWaterTerrain( gridno, origType, piNewTile, TRUE);
return;
}
pSmoothStruct = gbSmoothStruct;
// Get land index value for given level and adjust according to type
if ( TypeExistsInLandLayer( gridno, origType, &usTileIndex ) )
{
GetTypeSubIndexFromTileIndex( origType, usTileIndex, &usOldIndex );
}
else
{
*piNewTile = NO_TILE;
return;
}
// Check if we're dealing with a 'full' tile ( first ten )
// If so, do not smooth
// Onlt do if we are not forcing the smooth
if ( !fForceSmooth )
{
if ( usOldIndex >= 1 && usOldIndex <= 10 )
{
*piNewTile = NO_TILE;
return;
}
}
// is land height one tile above not the same type?
if ( (gridno- WORLD_COLS ) >= 0 )
{
if ( !TypeExistsInLandLayer( gridno - WORLD_COLS, origType, &usTempIndex ) )
{
// no it's not
temp+=3;
}
}
// is land height one tile to the right not the same type?
// (make sure there IS a tile to the right, i.e. check for border)
if ((gridno+1)% WORLD_COLS !=0)
{
if ( !TypeExistsInLandLayer( gridno+1, origType, &usTempIndex ) )
{
// no it's not
temp+=5;
}
}
// is land height one tile down not the same type?
if ( (gridno + WORLD_COLS ) < ( WORLD_COLS * WORLD_ROWS ) )
{
if ( !TypeExistsInLandLayer( gridno + WORLD_COLS, origType, &usTempIndex ) )
{
// no it's not
temp+=7;
}
}
// is land height one tile to left not the same type?
if (gridno % WORLD_COLS!=0)
{
if ( !TypeExistsInLandLayer( gridno-1, origType, &usTempIndex ) )
{
// no it's not
temp+=11;
}
}
// Now, at this point the height (of "temp") will tell us
// which texture piece to use
// Loop through smooth struct
cnt = 0;
fFound = FALSE;
GetLandHeadType( gridno, &uiTopType );
while( pSmoothStruct[ cnt ] != -1 )
{
if ( pSmoothStruct[ cnt ] == temp )
{
fSameTile = FALSE;
// If water is it's top type
do
{
// CHeck if it's the same tile
if ( pSmoothStruct[ cnt + 2 ] == usOldIndex )
{
fSameTile = TRUE;
}
if ( pSmoothStruct[ cnt + 3 ] )
{
if ( pSmoothStruct[ cnt + 3 ] == usOldIndex )
{
fSameTile = TRUE;
}
}
if ( fSameTile )
{
*piNewTile = NO_TILE;
return;
}
uiTempIndex = rand() % pSmoothStruct[ cnt + 1 ];
land = pSmoothStruct[ cnt + 2 + uiTempIndex ];
fFound = TRUE;
} while( FALSE );
break;
}
cnt += 6;
};
if ( !fFound )
{
// Check for existance of same tile
if ( usOldIndex >= 1 && usOldIndex <= 10 )
{
*piNewTile = NO_TILE;
return;
}
// this is a "full" tile, so randomize between the
// five available tiles
land = (rand( ) % 10 ) + 1;
FullTile = TRUE;
}
GetTileIndexFromTypeSubIndex( origType, land, &usTileIndex );
*piNewTile = usTileIndex;
}
void SmoothExitGridRadius( INT16 sMapIndex, UINT8 ubRadius )
{
LEVELNODE* pShadow;
INT16 x, y;
INT16 centerX, centerY;
ConvertGridNoToXY( sMapIndex, &centerX, &centerY );
for( y = centerY - ubRadius; y <= centerY + ubRadius; y++ )
{
for( x = centerX - ubRadius; x <= centerX + ubRadius; x++ )
{
sMapIndex = y * WORLD_COLS + x;
if( GridNoOnVisibleWorldTile( sMapIndex ) )
{
if( GetExitGridLevelNode( sMapIndex, &pShadow ) )
{
UINT16 usIndex;
SmoothExitGrid( sMapIndex, &usIndex, TRUE );
if( usIndex != NO_TILE && usIndex != pShadow->usIndex )
{
AddToUndoList( sMapIndex );
pShadow->usIndex = usIndex;
}
}
}
}
}
}
void SmoothExitGrid(int gridno, UINT16 *piNewTile, BOOLEAN fForceSmooth )
{
int temp=0,type=0;
int FullTile = FALSE;
UINT16 usOldIndex;
UINT16 usTempIndex;
UINT32 cnt;
BOOLEAN fFound;
UINT32 uiTempIndex;
UINT16 usTileIndex;
UINT16 usExitGridIndex=0;
BOOLEAN fSameTile;
INT16 *pSmoothStruct;
pSmoothStruct = gbSmoothStruct;
// Get Object index value for given level and adjust according to type
if ( TypeExistsInShadowLayer( gridno, EXITTEXTURE, &usTileIndex ) )
{
GetTypeSubIndexFromTileIndex( EXITTEXTURE, usTileIndex, &usOldIndex );
}
else
{
*piNewTile = NO_TILE;
return;
}
// Check if we're dealing with a 'full' tile ( first ten )
// If so, do not smooth
// Onlt do if we are not forcing the smooth
if ( !fForceSmooth )
{
if ( usOldIndex >= 1 && usOldIndex <= 10 )
{
*piNewTile = NO_TILE;
return;
}
}
// is Object height one tile above not the same type?
if ( (gridno- WORLD_COLS ) >= 0 )
{
if ( !TypeExistsInShadowLayer( gridno - WORLD_COLS, EXITTEXTURE, &usTempIndex ) )
{
// no it's not
temp+=3;
}
}
// is Object height one tile to the right not the same type?
// (make sure there IS a tile to the right, i.e. check for border)
if ((gridno+1)% WORLD_COLS !=0)
{
if ( !TypeExistsInShadowLayer( gridno+1, EXITTEXTURE, &usTempIndex ) )
{
// no it's not
temp+=5;
}
}
// is Object height one tile down not the same type?
if ( (gridno + WORLD_COLS ) < ( WORLD_COLS * WORLD_ROWS ) )
{
if ( !TypeExistsInShadowLayer( gridno + WORLD_COLS, EXITTEXTURE, &usTempIndex ) )
{
// no it's not
temp+=7;
}
}
// is Object height one tile to left not the same type?
if (gridno % WORLD_COLS!=0)
{
if ( !TypeExistsInShadowLayer( gridno-1, EXITTEXTURE, &usTempIndex ) )
{
// no it's not
temp+=11;
}
}
// Now, at this point the height (of "temp") will tell us
// which texture piece to use
// Loop through smooth struct
cnt = 0;
fFound = FALSE;
while( pSmoothStruct[ cnt ] != -1 )
{
if ( pSmoothStruct[ cnt ] == temp )
{
fSameTile = FALSE;
// If water is it's top type
do
{
// CHeck if it's the same tile
if ( pSmoothStruct[ cnt + 2 ] == usOldIndex )
{
fSameTile = TRUE;
}
if ( pSmoothStruct[ cnt + 3 ] )
{
if ( pSmoothStruct[ cnt + 3 ] == usOldIndex )
{
fSameTile = TRUE;
}
}
if ( fSameTile )
{
*piNewTile = NO_TILE;
return;
}
uiTempIndex = rand() % pSmoothStruct[ cnt + 1 ];
usExitGridIndex = pSmoothStruct[ cnt + 2 + uiTempIndex ];
fFound = TRUE;
} while( FALSE );
break;
}
cnt += 6;
};
if ( !fFound )
{
// Check for existance of same tile
if ( usOldIndex >= 1 && usOldIndex <= 10 )
{
*piNewTile = NO_TILE;
return;
}
// this is a "full" tile, so randomize between the
// five available tiles
usExitGridIndex = (rand( ) % 10 ) + 1;
FullTile = TRUE;
}
GetTileIndexFromTypeSubIndex( EXITTEXTURE, usExitGridIndex, &usTileIndex );
*piNewTile = usTileIndex;
}
void SmoothTerrainWorld( UINT32 uiCheckType )
{
int cnt;
UINT16 usIndex;
UINT16 NewTile;
// Smooth out entire world surrounding tiles
for ( cnt = 0; cnt < WORLD_MAX; cnt++ )
{
if ( TypeExistsInLandLayer( cnt, uiCheckType, &usIndex ) )
{
SmoothTerrain( cnt, uiCheckType, &NewTile, TRUE );
if ( NewTile != NO_TILE )
{
// Change tile
SetLandIndex( cnt, NewTile, uiCheckType, FALSE );
}
}
}
}
void SmoothAllTerrainWorld( void )
{
int cnt;
UINT16 usIndex;
UINT16 NewTile;
UINT32 uiCheckType;
// Smooth out entire world surrounding tiles
for ( cnt = 0; cnt < WORLD_MAX; cnt++ )
{
for ( uiCheckType = FIRSTTEXTURE; uiCheckType <= SEVENTHTEXTURE; uiCheckType++ )
{
if ( TypeExistsInLandLayer( cnt, uiCheckType, &usIndex ) )
{
SmoothTerrain( cnt, uiCheckType, &NewTile, TRUE );
if ( NewTile != NO_TILE )
{
// Change tile
SetLandIndex( cnt, NewTile, uiCheckType, FALSE );
}
}
}
}
}
void SmoothTerrainRadius( UINT32 iMapIndex, UINT32 uiCheckType, UINT8 ubRadius, BOOLEAN fForceSmooth )
{
INT16 sTop, sBottom;
INT16 sLeft, sRight;
INT16 cnt1, cnt2;
INT32 iNewIndex;
UINT16 NewTile;
UINT16 usIndex;
INT32 leftmost;
// Don't bother to smooth floors, they don't need them
if ( uiCheckType >= FIRSTFLOOR && uiCheckType <= LASTFLOOR )
return;
// Determine start end end indicies and num rows
sTop = ubRadius;
sBottom = -ubRadius;
sLeft = - ubRadius;
sRight = ubRadius;
for( cnt1 = sBottom; cnt1 <= sTop; cnt1++ )
{
leftmost = ( ( iMapIndex + ( WORLD_COLS * cnt1 ) )/ WORLD_COLS ) * WORLD_COLS;
for( cnt2 = sLeft; cnt2 <= sRight; cnt2++ )
{
iNewIndex = iMapIndex + ( WORLD_COLS * cnt1 ) + cnt2;
if ( iNewIndex >=0 && iNewIndex < WORLD_MAX &&
iNewIndex >= leftmost && iNewIndex < ( leftmost + WORLD_COLS ) )
{
if ( TypeExistsInLandLayer( iNewIndex, uiCheckType, &usIndex ) )
{
SmoothTerrain( iNewIndex, uiCheckType, &NewTile, fForceSmooth );
if ( NewTile != NO_TILE )
{
// Change tile
AddToUndoList( iNewIndex );
SetLandIndex( iNewIndex, NewTile, uiCheckType, FALSE );
}
}
}
}
}
}
void SmoothAllTerrainTypeRadius( UINT32 iMapIndex, UINT8 ubRadius, BOOLEAN fForceSmooth )
{
INT16 sTop, sBottom;
INT16 sLeft, sRight;
INT16 cnt1, cnt2, cnt3;
INT32 iNewIndex;
UINT16 NewTile;
UINT16 usIndex;
INT32 leftmost;
// Determine start end end indicies and num rows
sTop = ubRadius;
sBottom = -ubRadius;
sLeft = - ubRadius;
sRight = ubRadius;
for( cnt3 = FIRSTTEXTURE; cnt3 <= SEVENTHTEXTURE; cnt3++ )
{
for( cnt1 = sBottom; cnt1 <= sTop; cnt1++ )
{
leftmost = ( ( iMapIndex + ( WORLD_COLS * cnt1 ) )/ WORLD_COLS ) * WORLD_COLS;
for( cnt2 = sLeft; cnt2 <= sRight; cnt2++ )
{
iNewIndex = iMapIndex + ( WORLD_COLS * cnt1 ) + cnt2;
if ( iNewIndex >=0 && iNewIndex < WORLD_MAX &&
iNewIndex >= leftmost && iNewIndex < ( leftmost + WORLD_COLS ) )
{
if ( TypeExistsInLandLayer( iNewIndex, cnt3, &usIndex ) )
{
SmoothTerrain( iNewIndex, cnt3, &NewTile, fForceSmooth );
if ( NewTile != NO_TILE )
{
// Change tile
SetLandIndex( iNewIndex, NewTile, cnt3, FALSE );
}
}
}
}
}
}
}
void SmoothWaterTerrain( int gridno, int origType, UINT16 *piNewTile, BOOLEAN fForceSmooth )
{
// This procedure will calculate the approriate smooth texture for a water texture
// based on the surrounding water textures. This is done via masking bits within
// a temp variable, then searching for the right texture and inserting it
int temp=0,type=0;
int FullTile = FALSE;
UINT16 usOldIndex;
UINT16 usTempIndex;
UINT32 cnt;
BOOLEAN fFound;
UINT32 uiTempIndex;
UINT16 usTileIndex;
UINT16 land=0;
UINT32 uiTopType;
BOOLEAN fSameTile;
INT16 *pSmoothStruct;
pSmoothStruct = gbSmoothWaterStruct;
// Get land index value for given level and adjust according to type
if ( TypeExistsInLandLayer( gridno, origType, &usTileIndex ) )
{
GetTypeSubIndexFromTileIndex( origType, usTileIndex, &usOldIndex );
}
else
{
*piNewTile = NO_TILE;
return;
}
// Check if we're dealing with a 'full' tile ( first ten )
// If so, do not smooth
// Onlt do if we are not forcing the smooth
if ( !fForceSmooth )
{
if ( usOldIndex >= 1 && usOldIndex <= 10 )
{
*piNewTile = NO_TILE;
return;
}
}
// Mask approriate bits in temp for the lookup in the SmoothWaterStruct list
if ( (gridno- WORLD_COLS ) >= 0 )
{
if ( TypeRangeExistsInLandLayer( gridno - WORLD_COLS, origType, origType, &usTempIndex ) )
{
// no it's not
temp|=4;
}
}
// is land height one tile to the right not the same type?
// (make sure there IS a tile to the right, i.e. check for border)
if ((gridno+1)% WORLD_COLS !=0)
{
if ( TypeRangeExistsInLandLayer( gridno + 1, origType, origType, &usTempIndex ) )
{
// no it's not
temp|=64;
}
}
// is land height one tile down not the same type?
if ( (gridno + WORLD_COLS ) < ( WORLD_COLS * WORLD_ROWS ) )
{
if ( TypeRangeExistsInLandLayer( gridno + WORLD_COLS, origType, origType, &usTempIndex ) )
{
// no it's not
temp|=256;
}
}
// is land height one tile to left not the same type?
if (gridno % WORLD_COLS!=0)
{
if ( TypeRangeExistsInLandLayer( gridno - 1, origType, origType, &usTempIndex ) )
{
// no it's not
temp|=16;
}
}
if ((gridno+1)% WORLD_COLS !=0)
{
if ( (gridno- WORLD_COLS ) >= 0 )
{
if ( TypeRangeExistsInLandLayer( gridno - WORLD_COLS + 1, origType, origType, &usTempIndex ) )
{
// no it's not
temp|=8;
}
}
}
if (gridno % WORLD_COLS!=0)
{
if ( (gridno- WORLD_COLS ) >= 0 )
{
if ( TypeRangeExistsInLandLayer( gridno - WORLD_COLS - 1, origType, origType, &usTempIndex ) )
{
// no it's not
temp|=2;
}
}
}
if ((gridno+1)% WORLD_COLS !=0)
{
if ( (gridno + WORLD_COLS ) < ( WORLD_COLS * WORLD_ROWS ) )
{
if ( TypeRangeExistsInLandLayer( gridno + WORLD_COLS + 1, origType, origType, &usTempIndex ) )
{
// no it's not
temp|=512;
}
}
}
if (gridno % WORLD_COLS!=0)
{
if ( (gridno + WORLD_COLS ) < ( WORLD_COLS * WORLD_ROWS ) )
{
if ( TypeRangeExistsInLandLayer( gridno + WORLD_COLS - 1, origType, origType, &usTempIndex ) )
{
// no it's not
temp|=128;
}
}
}
if ( TypeRangeExistsInLandLayer( gridno, origType, origType, &usTempIndex ) )
{
// no it's not
temp|=32;
}
// Loop through smooth struct
cnt = 0;
fFound = FALSE;
GetLandHeadType( gridno, &uiTopType );
// Speed up of this while loop using double/quick search will result
// in an incorrect solution due to multiple instances of bitvalues in the list of
// smoothed water textures
while( pSmoothStruct[ cnt ] != -1 )
{
if ( pSmoothStruct[ cnt ] == temp )
{
fSameTile = FALSE;
do
{
// CHeck if it's the same tile
if ( pSmoothStruct[ cnt + 2 ] == usOldIndex )
{
fSameTile = TRUE;
}
if ( pSmoothStruct[ cnt + 3 ] )
{
if ( pSmoothStruct[ cnt + 3 ] == usOldIndex )
{
fSameTile = TRUE;
}
}
if ( fSameTile )
{
*piNewTile = NO_TILE;
return;
}
uiTempIndex = rand() % pSmoothStruct[ cnt + 1 ];
land = pSmoothStruct[ cnt + 2 + uiTempIndex ];
fFound = TRUE;
} while( FALSE );
break;
}
cnt += 4;
};
if ( !fFound )
{
// Check for existance of same tile
if ( usOldIndex >= 1 && usOldIndex <= 10 )
{
*piNewTile = NO_TILE;
return;
}
land = (rand( ) % 10 ) + 1;
FullTile = TRUE;
}
GetTileIndexFromTypeSubIndex( origType, land, &usTileIndex );
*piNewTile = usTileIndex;
}
#endif
+34
View File
@@ -0,0 +1,34 @@
#include "BuildDefines.h"
#ifdef JA2EDITOR
#ifndef __SMOOTH_H
#define __SMOOTH_H
#define ONELEVELTYPEONEROOF 1
#define ONELEVELTYPETWOROOF 2
// Area (pointer to SGP rect) +
// Location to check-+--| | |---- Check left and right edges -----| |---- Check top and bottom edges -----|
#define IsLocationInArea( x, y, r ) ( ((x) >= r->iLeft) && ((x) <= r->iRight) && ((y) >= r->iTop) && ((y) <= r->iBottom) )
void SmoothAllTerrainWorld( void );
void SmoothTerrain(int gridno, int origType, UINT16 *piNewTile, BOOLEAN fForceSmooth );
void SmoothTerrainRadius( UINT32 iMapIndex, UINT32 uiCheckType, UINT8 ubRadius, BOOLEAN fForceSmooth );
void SmoothTerrainWorld( UINT32 uiCheckType );
void SmoothWaterTerrain( int gridno, int origType, UINT16 *piNewTile, BOOLEAN fForceSmooth );
void SmoothAllTerrainTypeRadius( UINT32 iMapIndex, UINT8 ubRadius, BOOLEAN fForceSmooth );
void SmoothExitGrid(int gridno, UINT16 *piNewTile, BOOLEAN fForceSmooth );
void SmoothExitGridRadius( INT16 sMapIndex, UINT8 ubRadius );
#endif
#endif