1. itools_chess
2. Include file for functions to implement a human chess game with NPC
characters as well as help in other chess related traps etc.
3. Notes:
These functions assume they are called from an area containing two
waypoints, with the tags CHS_WP_WHITE and CHS_WP_BLACK, that define the
chessboard. In this version the chessboard must have ranks that run
east/west with white's king's rook in the south-east corner.Any board
size can be defined. I tested with the chessboard terrain rotated to put
white at the bottom right.
The commands will place blue and red shafts of light on given chess
squares. These indicate the squares the "pieces" will be moved to and
from respectivly. The chs_MakeIndicatedMove() command will find to
closest reature object to the blue shaft of light nad move to the
location of the red shaft light. If the target location is occupied by a
piece it is captured (destroyed). I tested this using male and female
commoners. I changed their appearances to simulate the monsters I wanted
to use.
These commands do not try to enforce any chess rules in this version.
Many of then may have a general purpose use in a chess related module.
See the include file comments for a list of the functions.
4. itools_chess verstion 1.4
NWScript:
location
chs_GetBoardLocation( int nRank, int nFile, int bFacingBlack )
{
vector vSquare = Vector(0.0,0.0,0.0 );
float fFacing = 0.0;
location lSquare = Location( OBJECT_INVALID , vSquare, fFacing );
if( nRank < 1 || nRank > 8 || nFile < 1 || nFile > 8 )
{
return lSquare;
}
object oWhiteWaypoint= GetWaypointByTag("CHS_WP_WHITE");
if( !GetIsObjectValid(oWhiteWaypoint) )
{
return lSquare;
}
vector vWhite = GetPosition( oWhiteWaypoint );
object oBlackWaypoint = GetWaypointByTag( "CHS_WP_BLACK" );
if( !GetIsObjectValid(oBlackWaypoint) )
{
return lSquare;
}
vector vBlack = GetPosition( oBlackWaypoint );
float fRank = IntToFloat(nRank)-0.5;
float fFile = IntToFloat(nFile)-0.5;
vSquare.x = vBlack.x + ( vWhite.x - vBlack.x )*(fFile/8.0);
vSquare.y = vWhite.y + ( vBlack.y - vWhite.y )*(fRank/8.0);
vSquare.z = vBlack.z;
if( bFacingBlack )
{
lSquare = Location( GetArea( oWhiteWaypoint) , vSquare, GetFacing(oWhiteWaypoint) );
}
else
{
lSquare = Location( GetArea( oWhiteWaypoint) , vSquare, GetFacing(oBlackWaypoint) );
}
return lSquare;
}
int
chs_LocationToRank( location lTest )
{
int nRank = 0;
float fDistance = 1.0;
float fBoardHight = 1.0;
object oWhiteWaypoint= GetWaypointByTag("CHS_WP_WHITE");
if( !GetIsObjectValid(oWhiteWaypoint) )
{
return 0;
}
vector vWhite = GetPosition( oWhiteWaypoint );
object oBlackWaypoint = GetWaypointByTag( "CHS_WP_BLACK" );
if( !GetIsObjectValid(oBlackWaypoint) )
{
return 0;
}
vector vBlack = GetPosition( oBlackWaypoint );
vector vTest = GetPositionFromLocation( lTest );
if( vTest.x > vBlack.x && vTest.x < vWhite.x && vTest.y < vBlack.y && vTest.y > vWhite.y )
{
fDistance = vTest.y - vWhite.y;
fBoardHight = vBlack.y - vWhite.y;
nRank = FloatToInt((8.0* fDistance/fBoardHight) + 0.999);
return nRank;
}
return 0;
}
int
chs_LocationToFile( location lTest )
{
int nFile = 0;
float fDistance = 1.0;
float fBoardWidth = 1.0;
object oWhiteWaypoint= GetWaypointByTag("CHS_WP_WHITE");
if( !GetIsObjectValid(oWhiteWaypoint) )
{
return 0;
}
vector vWhite = GetPosition( oWhiteWaypoint );
object oBlackWaypoint = GetWaypointByTag( "CHS_WP_BLACK" );
if( !GetIsObjectValid(oBlackWaypoint) )
{
return 0;
}
vector vBlack = GetPosition( oBlackWaypoint );
vector vTest = GetPositionFromLocation( lTest );
if( vTest.x > vBlack.x && vTest.x < vWhite.x && vTest.y < vBlack.y && vTest.y > vWhite.y )
{
fDistance = vTest.x - vBlack.x;
fBoardWidth = vWhite.x- vBlack.x;
nFile = FloatToInt((8.0* fDistance/fBoardWidth) + 0.999);
return nFile;
}
return 0;
}
int
chs_SetIndicatorPositon( int nRank, int nFile, int bFromMarker = TRUE )
{
object oFromShaft = GetNearestObjectByTag("Shaft of Light - Blue");
if( GetIsObjectValid(oFromShaft) )
{
DestroyObject( oFromShaft );
}
location lNewFromShaft = chs_GetBoardLocation( nRank, nFile, FALSE );
if( GetIsObjectValid( GetAreaFromLocation( lNewFromShaft ) ) )
{
object oNewFromShaft = CreateObject(OBJECT_TYPE_PLACEABLE, "plc_solblue", lNewFromShaft, TRUE);
return TRUE;
}
return FALSE;
}
int chs_SetIndicatorRank( int nRank, int bFromMarker )
{
string sMarkerTag = "Shaft of Light - Blue";
string sMarkerTemplate = "plc_solblue";
int nFile = 1;
if( !bFromMarker )
{
sMarkerTag = "Shaft of Light - Red";
sMarkerTemplate = "plc_solred";
}
object oObject = GetNearestObjectByTag(sMarkerTag );
if( GetIsObjectValid(oObject) )
{
location lOldLocation = GetLocation( oObject );
nFile =chs_LocationToFile( lOldLocation );
if( nFile <1 || nFile > 8 )
{
nFile = 1;
}
DestroyObject( oObject );
}
location lNewShaft = chs_GetBoardLocation( nRank, nFile, FALSE );
if( GetIsObjectValid( GetAreaFromLocation( lNewShaft ) ) )
{
object oNewObject = CreateObject(OBJECT_TYPE_PLACEABLE, sMarkerTemplate, lNewShaft, TRUE);
return TRUE;
}
return FALSE;
}
int
chs_SetIndicatorFile( int nFile, int bFromMarker = TRUE )
{
string sMarkerTag = "Shaft of Light - Blue";
string sMarkerTemplate = "plc_solblue";
int nRank = 1;
if( !bFromMarker )
{
sMarkerTag = "Shaft of Light - Red";
sMarkerTemplate = "plc_solred";
}
object oObject = GetNearestObjectByTag(sMarkerTag);
location lOldLocation;
if( GetIsObjectValid(oObject) )
{
lOldLocation = GetLocation( oObject );
nRank =chs_LocationToRank( lOldLocation );
if( nRank <1 || nRank > 8 )
{
nRank = 1;
}
DestroyObject( oObject );
}
location lNewShaft = chs_GetBoardLocation( nRank, nFile, FALSE );
if( GetIsObjectValid( GetAreaFromLocation( lNewShaft ) ) )
{
object oNewObject = CreateObject(OBJECT_TYPE_PLACEABLE, sMarkerTemplate, lNewShaft, TRUE);
return TRUE;
}
return FALSE;
}
object
chs_getPieceAtLocation( location lTest )
{
WriteTimestampedLogEntry("Start GetPieceAtLocation:");
object oPiece = GetNearestObjectToLocation( OBJECT_TYPE_CREATURE, lTest);
if( !GetIsObjectValid(oPiece ) )
{
PrintString("First Piece was invalid");
return oPiece;
}
PrintString( "Found piece at location: " + GetTag(oPiece ));
location lPiece = GetLocation( oPiece );
if( chs_LocationToRank(lPiece ) != chs_LocationToRank( lTest ) )
{
PrintString( "bad Rank. Piece Rank:");
PrintInteger( chs_LocationToRank(lPiece ) );
PrintString( "Location Rank:");
PrintInteger( chs_LocationToRank(lTest ) );
return OBJECT_INVALID;
}
if( chs_LocationToFile(lPiece ) != chs_LocationToFile( lTest ) )
{
PrintString( "bad File. Piece File:");
PrintInteger( chs_LocationToFile(lPiece ) );
PrintString( "Location File:");
PrintInteger( chs_LocationToFile(lTest ) );
return OBJECT_INVALID;
}
return oPiece;
}
int
chs_MakeIndicatedMove()
{
WriteTimestampedLogEntry("Start MakeIndicatedMove:");
string sFromMarkerTag = "Shaft of Light - Blue";
string sFromMarkerTemplate = "plc_solblue";
string sToMarkerTag = "Shaft of Light - Red";
string sToMarkerTemplate = "plc_solred";
object oFromMarker = GetNearestObjectByTag(sFromMarkerTag);
object oToMarker = GetNearestObjectByTag(sToMarkerTag);
if(!GetIsObjectValid(oFromMarker))
{
PrintString("Could not find from marker");
return 0;
}
if(!GetIsObjectValid(oToMarker))
{
PrintString("Could not find to marker");
return 0;
}
location lFromLocation = GetLocation( oFromMarker );
object oPieceToMove = chs_getPieceAtLocation( lFromLocation );
if( !GetIsObjectValid( oPieceToMove ) )
{
PrintString("Could not find the Piece to move");
return 0;
}
PrintString("Found a piece to move: "+ GetTag( oPieceToMove));
location lToLocation = GetLocation( oToMarker );
object oPieceToCapture = chs_getPieceAtLocation( lToLocation );
PrintString("Found a piece to capture");
AssignCommand( oPieceToMove , ActionForceMoveToLocation(lToLocation, FALSE, 10.0 ));
if( GetIsObjectValid( oPieceToCapture ))
{
PrintString("Found a piece to capture: "+ GetTag( oPieceToCapture));
DestroyObject( oPieceToCapture );
return 2;
}
return 1;
}
Examples:
I used a conversation with a "ChessMaster" NPC as the UI to move chess
pieces.
A script attached to the action taken for the players response of "The
piece shall be moved from the C file" might look like this:
NWScript: #include "itools_chess"
void main()
{
chs_SetIndicatorFile( 3,TRUE);
}
After the to and from indicators are in valid locations the player
response
"Move the piece now"
might be implement like this:
NWScript: #include "itools_chess"
void main()
{
int iReturn = chs_MakeIndicatedMove();
if( iReturn == 0 )
{
PlaySound("as_pl_screamm1");
}
if( iReturn == 1 )
{
PlaySound("as_pl_laughingm1");
}
if( iReturn == 2 )
{
PlaySound("as_pl_prisinmob1");
}
}
One know problem is that pieces can be pushed off thier spaces by other
pieces. This could be fixed by storing the current location in each
piece and sending them back to that location when necessary.
Good Luck and Have fun making chess mods!
|