2007-01-15 12:09:25 -08:00
/*
This file is part of Warzone 2100.
Copyright ( C ) 1999 - 2004 Eidos Interactive
2013-01-16 12:34:57 -08:00
Copyright ( C ) 2005 - 2013 Warzone 2100 Project
2007-01-15 12:09:25 -08:00
Warzone 2100 is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
Warzone 2100 is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with Warzone 2100 ; if not , write to the Free Software
Foundation , Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 USA
*/
2007-06-28 10:47:08 -07:00
/*
* ScriptFuncs . c
*
* All the C functions callable from the script code
*
*/
2011-04-01 11:31:15 -07:00
# include "lib/framework/wzapp.h"
2006-09-23 10:24:55 -07:00
# include "lib/framework/strres.h"
2009-02-11 06:13:30 -08:00
# include "lib/framework/stdio_ext.h"
2006-05-27 09:37:17 -07:00
# include "lib/widget/widget.h"
2007-06-28 10:47:08 -07:00
2010-05-15 18:36:21 -07:00
# include <time.h>
# include <string.h>
2007-06-28 10:47:08 -07:00
# include "effects.h"
2006-05-27 09:37:17 -07:00
# include "lib/script/script.h"
2007-06-28 10:47:08 -07:00
# include "scripttabs.h"
2006-05-27 09:37:17 -07:00
# include "lib/gamelib/gtime.h"
2007-06-28 10:47:08 -07:00
# include "objects.h"
# include "hci.h"
2009-08-11 13:36:44 -07:00
# include "loadsave.h"
2007-06-28 10:47:08 -07:00
# include "message.h"
2009-08-11 13:36:44 -07:00
# include "challenge.h"
2007-06-28 10:47:08 -07:00
# include "intelmap.h"
# include "map.h"
# include "structure.h"
# include "display3d.h"
# include "research.h"
2006-05-27 09:37:17 -07:00
# include "lib/sound/audio.h"
2007-03-27 11:59:03 -07:00
# include "lib/sound/audio_id.h"
2007-06-28 10:47:08 -07:00
# include "power.h"
# include "console.h"
# include "scriptfuncs.h"
# include "geometry.h"
# include "visibility.h"
# include "gateway.h"
# include "drive.h"
# include "display.h"
# include "component.h"
# include "scriptextern.h"
# include "seqdisp.h"
# include "configuration.h"
# include "fpath.h"
# include "warzoneconfig.h"
# include "lighting.h"
# include "atmos.h"
2006-05-27 09:37:17 -07:00
# include "lib/sound/cdaudio.h"
# include "lib/netplay/netplay.h"
2007-06-28 10:47:08 -07:00
# include "multiplay.h"
# include "multigifts.h"
# include "multilimit.h"
2011-01-09 07:35:49 -08:00
# include "multiint.h"
2007-06-28 10:47:08 -07:00
# include "advvis.h"
2010-01-22 04:06:02 -08:00
# include "mapgrid.h"
2010-12-31 13:37:14 -08:00
# include "lib/ivis_opengl/piestate.h"
2007-06-28 10:47:08 -07:00
# include "wrappers.h"
# include "order.h"
# include "orderdef.h"
# include "mission.h"
# include "loop.h"
# include "frontend.h"
# include "group.h"
# include "transporter.h"
# include "radar.h"
# include "levels.h"
# include "mission.h"
# include "projectile.h"
# include "cluster.h"
2006-08-21 08:33:49 -07:00
# include "multigifts.h" //because of giftRadar()
2006-10-08 01:06:46 -07:00
# include "display3d.h" //for showRangeAtPos()
2006-11-01 05:56:23 -08:00
# include "multimenu.h"
2006-12-16 06:59:50 -08:00
# include "lib/script/chat_processing.h"
2007-05-29 08:47:56 -07:00
# include "keymap.h"
2008-04-30 08:44:04 -07:00
# include "visibility.h"
2008-05-10 06:20:23 -07:00
# include "design.h"
2010-02-06 09:14:43 -08:00
# include "random.h"
2011-12-17 15:23:51 -08:00
# include "template.h"
2012-11-27 10:05:23 -08:00
# include "qtscript.h" // this is fun...
2007-06-28 10:47:08 -07:00
2006-11-19 12:50:02 -08:00
static INTERP_VAL scrFunctionResult ; //function return value to be pushed to stack
2007-06-28 10:47:08 -07:00
// If this is defined then check max number of units not reached before adding more.
# define SCRIPT_CHECK_MAX_UNITS
2012-12-16 12:03:00 -08:00
static SDWORD bitMask [ ] = { 0x01 , 0x02 , 0x04 , 0x08 , 0x10 , 0x20 , 0x40 , 0x80 } ;
2006-12-16 06:59:50 -08:00
static char strParam1 [ MAXSTRLEN ] , strParam2 [ MAXSTRLEN ] ; //these should be used as string parameters for stackPopParams()
2006-10-24 06:05:40 -07:00
2011-03-12 17:32:15 -08:00
static bool structHasModule ( STRUCTURE * psStruct ) ;
2007-06-28 10:47:08 -07:00
2012-12-16 12:03:00 -08:00
static DROID_TEMPLATE * scrCheckTemplateExists ( SDWORD player , DROID_TEMPLATE * psTempl ) ;
2008-05-10 06:20:23 -07:00
2010-01-12 12:24:04 -08:00
/// Hold the previously assigned player
2011-12-06 11:43:39 -08:00
Vector2i positions [ MAX_PLAYERS ] ;
2011-01-22 05:00:13 -08:00
std : : vector < Vector2i > derricks ;
2010-01-24 04:48:13 -08:00
2012-01-07 06:52:31 -08:00
bool scriptOperatorEquals ( INTERP_VAL const & v1 , INTERP_VAL const & v2 )
{
ASSERT_OR_RETURN ( false , scriptTypeIsPointer ( v1 . type ) & & scriptTypeIsPointer ( v2 . type ) , " Bad types. " ) ;
2013-10-04 10:16:49 -07:00
if ( v1 . type = = ( INTERP_TYPE ) ST_RESEARCH & & v2 . type = = ( INTERP_TYPE ) ST_RESEARCH )
2012-01-07 06:52:31 -08:00
{
return ( ( RESEARCH * ) v1 . v . oval ) - > ref = = ( ( RESEARCH * ) v2 . v . oval ) - > ref ;
}
return v1 . v . oval = = v2 . v . oval ;
}
2010-01-24 04:48:13 -08:00
void scriptSetStartPos ( int position , int x , int y )
{
positions [ position ] . x = x ;
positions [ position ] . y = y ;
2010-02-07 06:28:55 -08:00
debug ( LOG_SCRIPT , " Setting start position %d to (%d, %d) " , position , x , y ) ;
2010-01-24 04:48:13 -08:00
}
2010-01-12 12:24:04 -08:00
2011-01-22 05:00:13 -08:00
void scriptSetDerrickPos ( int x , int y )
{
Vector2i pos ( x , y ) ;
derricks . push_back ( pos ) ;
}
2011-03-12 17:32:15 -08:00
bool scriptInit ( )
2010-01-12 12:24:04 -08:00
{
2010-10-18 14:00:09 -07:00
int i ;
for ( i = 0 ; i < MAX_PLAYERS ; i + + )
{
scriptSetStartPos ( i , 0 , 0 ) ;
}
2011-01-22 05:00:13 -08:00
derricks . clear ( ) ;
derricks . reserve ( 8 * MAX_PLAYERS ) ;
2010-01-12 12:24:04 -08:00
return true ;
}
2011-03-12 17:32:15 -08:00
bool scrScavengersActive ( )
2010-01-12 14:32:06 -08:00
{
2011-01-03 05:48:41 -08:00
scrFunctionResult . v . ival = scavengerPlayer ( ) ;
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
2010-01-12 14:32:06 -08:00
{
return false ;
}
return true ;
}
2011-03-12 17:32:15 -08:00
bool scrGetDifficulty ( )
2010-01-12 12:24:04 -08:00
{
2011-01-09 13:24:09 -08:00
int player ;
if ( ! stackPopParams ( 1 , VAL_INT , & player ) )
{
return false ;
}
ASSERT_OR_RETURN ( false , player < MAX_PLAYERS , " Bad player index " ) ;
scrFunctionResult . v . ival = NetPlay . players [ player ] . difficulty ;
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
{
ASSERT ( false , " Failed to initialize player " ) ;
return false ;
}
return true ;
}
2010-01-12 12:24:04 -08:00
2011-03-12 17:32:15 -08:00
bool scrGetPlayer ( )
2010-01-12 12:24:04 -08:00
{
2011-01-09 07:35:49 -08:00
if ( ! stackPopParams ( 1 , VAL_STRING , & strParam1 ) )
{
debug ( LOG_ERROR , " stack failed " ) ;
return false ;
}
int i = scrFunctionResult . v . ival = getNextAIAssignment ( strParam1 ) ;
debug ( LOG_SCRIPT , " Initialized player %d, starts at position (%d, %d), max %d players " , i , positions [ i ] . x , positions [ i ] . y , game . maxPlayers ) ;
2010-01-12 12:24:04 -08:00
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
{
2010-02-07 06:28:55 -08:00
ASSERT ( false , " Failed to initialize player " ) ;
2010-01-12 12:24:04 -08:00
return false ;
}
return true ;
}
2011-03-12 17:32:15 -08:00
bool scrGetDerrick ( )
2011-01-22 05:00:13 -08:00
{
int x , y , i ;
if ( ! stackPopParams ( 1 , VAL_INT , & i ) )
{
debug ( LOG_ERROR , " stack failed " ) ;
return false ;
}
scrFunctionResult . v . oval = NULL ;
if ( i < ( int ) derricks . size ( ) )
{
x = derricks [ i ] . x ;
y = derricks [ i ] . y ;
MAPTILE * psTile = worldTile ( x , y ) ;
2011-06-05 13:57:31 -07:00
ASSERT ( psTile , " No derrick or oil at position! " ) ;
2011-01-22 05:00:13 -08:00
if ( psTile )
{
scrFunctionResult . v . oval = psTile - > psObject ;
}
}
2011-06-05 13:57:31 -07:00
if ( ! stackPushResult ( ( INTERP_TYPE ) ST_BASEOBJECT , & scrFunctionResult ) )
2011-01-22 05:00:13 -08:00
{
ASSERT ( false , " Failed to push result " ) ;
return false ;
}
return true ;
}
2010-10-17 08:04:11 -07:00
Vector2i getPlayerStartPosition ( int player )
{
return positions [ player ] ;
}
2011-03-12 17:32:15 -08:00
bool scrSetSunPosition ( void )
2010-12-26 13:12:53 -08:00
{
2011-01-07 06:29:45 -08:00
float x , y , z ;
2010-12-26 13:12:53 -08:00
if ( ! stackPopParams ( 3 , VAL_FLOAT , & x , VAL_FLOAT , & y , VAL_FLOAT , & z ) )
{
return false ;
}
setTheSun ( Vector3f ( x , y , z ) ) ;
return true ;
}
2011-03-12 17:32:15 -08:00
bool scrSetSunIntensity ( void )
2010-12-26 13:12:53 -08:00
{
float ambient [ 4 ] , diffuse [ 4 ] , specular [ 4 ] ;
// Scary list of parameters... ambient, diffuse and specular RGB components
// One day we should add support for vectors to our scripting language to cut
// down on such noise.
if ( ! stackPopParams ( 9 , VAL_FLOAT , & ambient [ 0 ] , VAL_FLOAT , & ambient [ 1 ] , VAL_FLOAT , & ambient [ 2 ] ,
2012-12-16 12:03:00 -08:00
VAL_FLOAT , & diffuse [ 0 ] , VAL_FLOAT , & diffuse [ 1 ] , VAL_FLOAT , & diffuse [ 2 ] ,
VAL_FLOAT , & specular [ 0 ] , VAL_FLOAT , & specular [ 1 ] , VAL_FLOAT , & specular [ 2 ] ) )
2010-12-26 13:12:53 -08:00
{
return false ;
}
ambient [ 3 ] = 1.0 ;
diffuse [ 3 ] = 1.0 ;
specular [ 3 ] = 1.0 ;
pie_Lighting0 ( LIGHT_AMBIENT , ambient ) ;
pie_Lighting0 ( LIGHT_DIFFUSE , diffuse ) ;
pie_Lighting0 ( LIGHT_SPECULAR , specular ) ;
2013-02-18 08:19:48 -08:00
pie_SetupLighting ( ) ;
2010-12-26 13:12:53 -08:00
return true ;
}
2011-03-12 17:32:15 -08:00
bool scrSafeDest ( void )
2010-11-05 13:16:05 -07:00
{
SDWORD x , y , player ;
if ( ! stackPopParams ( 3 , VAL_INT , & player , VAL_INT , & x , VAL_INT , & y ) )
{
return false ;
}
2011-01-07 15:53:50 -08:00
ASSERT_OR_RETURN ( false , player < game . maxPlayers , " Out of bounds player index " ) ;
2010-11-21 14:21:23 -08:00
ASSERT_OR_RETURN ( false , worldOnMap ( x , y ) , " Out of bounds coordinates(%d, %d) " , x , y ) ;
scrFunctionResult . v . bval = ! ( auxTile ( map_coord ( x ) , map_coord ( y ) , player ) & AUXBITS_DANGER ) ;
2010-11-05 13:16:05 -07:00
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
{
return false ;
}
return true ;
}
2011-03-12 17:32:15 -08:00
bool scrThreatAt ( void )
2010-11-05 13:16:05 -07:00
{
SDWORD x , y , player ;
if ( ! stackPopParams ( 3 , VAL_INT , & player , VAL_INT , & x , VAL_INT , & y ) )
{
return false ;
}
2011-01-07 15:53:50 -08:00
ASSERT_OR_RETURN ( false , player < game . maxPlayers , " Out of bounds player index " ) ;
2010-11-21 14:21:23 -08:00
ASSERT_OR_RETURN ( false , worldOnMap ( x , y ) , " Out of bounds coordinates(%d, %d) " , x , y ) ;
scrFunctionResult . v . bval = auxTile ( map_coord ( x ) , map_coord ( y ) , player ) & AUXBITS_THREAT ;
2010-11-05 13:16:05 -07:00
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
{
return false ;
}
return true ;
}
2011-03-12 17:32:15 -08:00
bool scrGetPlayerStartPosition ( void )
2010-01-24 04:48:13 -08:00
{
SDWORD * x , * y , player ;
2012-12-16 12:03:00 -08:00
if ( ! stackPopParams ( 3 , VAL_INT , & player , VAL_REF | VAL_INT , & x , VAL_REF | VAL_INT , & y ) )
2010-01-24 04:48:13 -08:00
{
return false ;
}
2011-01-07 15:53:50 -08:00
if ( player < game . maxPlayers )
2010-01-24 04:48:13 -08:00
{
* x = positions [ player ] . x ;
* y = positions [ player ] . y ;
scrFunctionResult . v . bval = true ;
}
else
{
* x = 0 ;
* y = 0 ;
scrFunctionResult . v . bval = false ;
}
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
{
return false ;
}
return true ;
}
2007-06-28 10:47:08 -07:00
/******************************************************************************************/
/* Check for objects in areas */
2010-01-12 12:24:04 -08:00
2007-06-28 10:47:08 -07:00
// check for a base object being in range of a point
2011-03-12 17:32:15 -08:00
bool objectInRange ( BASE_OBJECT * psList , SDWORD x , SDWORD y , SDWORD range )
2007-06-28 10:47:08 -07:00
{
2006-05-27 09:37:17 -07:00
BASE_OBJECT * psCurr ;
2007-06-28 10:47:08 -07:00
SDWORD xdiff , ydiff , rangeSq ;
// See if there is a droid in range
rangeSq = range * range ;
2012-12-16 12:03:00 -08:00
for ( psCurr = psList ; psCurr ; psCurr = psCurr - > psNext )
2007-06-28 10:47:08 -07:00
{
// skip partially build structures
2012-12-16 12:03:00 -08:00
if ( ( psCurr - > type = = OBJ_STRUCTURE ) & &
( ( ( STRUCTURE * ) psCurr ) - > status ! = SS_BUILT ) )
2007-06-28 10:47:08 -07:00
{
continue ;
}
// skip flying vtols
2012-12-16 12:03:00 -08:00
if ( ( psCurr - > type = = OBJ_DROID ) & &
isVtolDroid ( ( DROID * ) psCurr ) & &
( ( DROID * ) psCurr ) - > sMove . Status ! = MOVEINACTIVE )
2007-06-28 10:47:08 -07:00
{
continue ;
}
2007-12-15 07:39:29 -08:00
xdiff = ( SDWORD ) psCurr - > pos . x - x ;
ydiff = ( SDWORD ) psCurr - > pos . y - y ;
2012-12-16 12:03:00 -08:00
if ( xdiff * xdiff + ydiff * ydiff < rangeSq )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
}
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// Check for any player object being within a certain range of a position
2011-03-12 17:32:15 -08:00
bool scrObjectInRange ( void )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD range , player , x , y ;
2011-03-12 17:32:15 -08:00
bool found ;
2007-06-28 10:47:08 -07:00
if ( ! stackPopParams ( 4 , VAL_INT , & player , VAL_INT , & x , VAL_INT , & y , VAL_INT , & range ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2007-06-28 10:47:08 -07:00
2012-12-16 12:03:00 -08:00
found = objectInRange ( ( BASE_OBJECT * ) apsDroidLists [ player ] , x , y , range ) | |
objectInRange ( ( BASE_OBJECT * ) apsStructLists [ player ] , x , y , range ) ;
2007-06-28 10:47:08 -07:00
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . bval = found ;
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// Check for a droid being within a certain range of a position
2011-03-12 17:32:15 -08:00
bool scrDroidInRange ( void )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD range , player , x , y ;
2011-03-12 17:32:15 -08:00
bool found ;
2007-06-28 10:47:08 -07:00
if ( ! stackPopParams ( 4 , VAL_INT , & player , VAL_INT , & x , VAL_INT , & y , VAL_INT , & range ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2007-06-28 10:47:08 -07:00
2012-12-16 12:03:00 -08:00
found = objectInRange ( ( BASE_OBJECT * ) apsDroidLists [ player ] , x , y , range ) ;
2007-06-28 10:47:08 -07:00
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . bval = found ;
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// Check for a struct being within a certain range of a position
2011-03-12 17:32:15 -08:00
bool scrStructInRange ( void )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD range , player , x , y ;
2011-03-12 17:32:15 -08:00
bool found ;
2007-06-28 10:47:08 -07:00
if ( ! stackPopParams ( 4 , VAL_INT , & player , VAL_INT , & x , VAL_INT , & y , VAL_INT , & range ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2007-06-28 10:47:08 -07:00
2012-12-16 12:03:00 -08:00
found = objectInRange ( ( BASE_OBJECT * ) apsStructLists [ player ] , x , y , range ) ;
2007-06-28 10:47:08 -07:00
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . bval = found ;
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
2011-03-12 17:32:15 -08:00
bool scrPlayerPower ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD player ;
if ( ! stackPopParams ( 1 , VAL_INT , & player ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2008-02-15 13:48:51 -08:00
scrFunctionResult . v . ival = getPower ( player ) ;
2006-11-19 12:50:02 -08:00
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// check for a base object being in an area
2011-03-12 17:32:15 -08:00
static bool objectInArea ( BASE_OBJECT * psList , SDWORD x1 , SDWORD y1 , SDWORD x2 , SDWORD y2 )
2007-06-28 10:47:08 -07:00
{
BASE_OBJECT * psCurr ;
2012-12-16 12:03:00 -08:00
SDWORD ox , oy ;
2007-06-28 10:47:08 -07:00
// See if there is a droid in Area
2012-12-16 12:03:00 -08:00
for ( psCurr = psList ; psCurr ; psCurr = psCurr - > psNext )
2007-06-28 10:47:08 -07:00
{
// skip partially build structures
2012-12-16 12:03:00 -08:00
if ( ( psCurr - > type = = OBJ_STRUCTURE ) & &
( ( ( STRUCTURE * ) psCurr ) - > status ! = SS_BUILT ) )
2007-06-28 10:47:08 -07:00
{
continue ;
}
2007-12-15 07:39:29 -08:00
ox = ( SDWORD ) psCurr - > pos . x ;
oy = ( SDWORD ) psCurr - > pos . y ;
2007-06-28 10:47:08 -07:00
if ( ox > = x1 & & ox < = x2 & &
2012-12-16 12:03:00 -08:00
oy > = y1 & & oy < = y2 )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
}
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// Check for any player object being within a certain area
2011-03-12 17:32:15 -08:00
bool scrObjectInArea ( void )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD player , x1 , y1 , x2 , y2 ;
2011-03-12 17:32:15 -08:00
bool found ;
2007-06-28 10:47:08 -07:00
if ( ! stackPopParams ( 5 , VAL_INT , & player , VAL_INT , & x1 , VAL_INT , & y1 , VAL_INT , & x2 , VAL_INT , & y2 ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2007-06-28 10:47:08 -07:00
2012-12-16 12:03:00 -08:00
found = objectInArea ( ( BASE_OBJECT * ) apsDroidLists [ player ] , x1 , y1 , x2 , y2 ) | |
objectInArea ( ( BASE_OBJECT * ) apsStructLists [ player ] , x1 , y1 , x2 , y2 ) ;
2007-06-28 10:47:08 -07:00
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . bval = found ;
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// Check for a droid being within a certain area
2011-03-12 17:32:15 -08:00
bool scrDroidInArea ( void )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD player , x1 , y1 , x2 , y2 ;
2011-03-12 17:32:15 -08:00
bool found ;
2007-06-28 10:47:08 -07:00
if ( ! stackPopParams ( 5 , VAL_INT , & player , VAL_INT , & x1 , VAL_INT , & y1 , VAL_INT , & x2 , VAL_INT , & y2 ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2007-06-28 10:47:08 -07:00
2012-12-16 12:03:00 -08:00
found = objectInArea ( ( BASE_OBJECT * ) apsDroidLists [ player ] , x1 , y1 , x2 , y2 ) ;
2007-06-28 10:47:08 -07:00
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . bval = found ;
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// Check for a struct being within a certain Area of a position
2011-03-12 17:32:15 -08:00
bool scrStructInArea ( void )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD player , x1 , y1 , x2 , y2 ;
2011-03-12 17:32:15 -08:00
bool found ;
2007-06-28 10:47:08 -07:00
if ( ! stackPopParams ( 5 , VAL_INT , & player , VAL_INT , & x1 , VAL_INT , & y1 , VAL_INT , & x2 , VAL_INT , & y2 ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2007-06-28 10:47:08 -07:00
2012-12-16 12:03:00 -08:00
found = objectInArea ( ( BASE_OBJECT * ) apsStructLists [ player ] , x1 , y1 , x2 , y2 ) ;
2007-06-28 10:47:08 -07:00
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . bval = found ;
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
2011-03-12 17:32:15 -08:00
bool scrSeenStructInArea ( void )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
int32_t walls = false ; // was BOOL (int) ** see warning about conversion
2011-03-19 15:40:25 -07:00
bool found = false ;
2012-12-16 12:03:00 -08:00
SDWORD player , enemy , x1 , y1 , x2 , y2 ;
2007-06-28 10:47:08 -07:00
STRUCTURE * psCurr ;
2012-12-16 12:03:00 -08:00
SDWORD ox , oy ;
2007-06-28 10:47:08 -07:00
// player, enemyplayer, walls, x1,r1,x2,y2
2012-12-16 12:03:00 -08:00
if ( ! stackPopParams ( 7 , VAL_INT , & player , VAL_INT , & enemy , VAL_BOOL , & walls , VAL_INT , & x1 , VAL_INT , & y1 , VAL_INT , & x2 , VAL_INT , & y2 ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2007-06-28 10:47:08 -07:00
2012-12-16 12:03:00 -08:00
for ( psCurr = apsStructLists [ enemy ] ; psCurr ; psCurr = psCurr - > psNext )
2007-06-28 10:47:08 -07:00
{
// skip partially build structures
2012-12-16 12:03:00 -08:00
if ( ( psCurr - > type = = OBJ_STRUCTURE ) & & ( ( ( STRUCTURE * ) psCurr ) - > status ! = SS_BUILT ) )
2007-06-28 10:47:08 -07:00
{
continue ;
}
// possible skip walls
2012-12-16 12:03:00 -08:00
if ( walls & & ( psCurr - > pStructureType - > type ! = REF_WALL | | psCurr - > pStructureType - > type ! = REF_WALLCORNER ) )
2007-06-28 10:47:08 -07:00
{
continue ;
}
2007-12-15 07:39:29 -08:00
ox = ( SDWORD ) psCurr - > pos . x ;
oy = ( SDWORD ) psCurr - > pos . y ;
2007-06-28 10:47:08 -07:00
if ( ox > = x1 & & ox < = x2 & & oy > = y1 & & oy < = y2 )
{
// structure is in area.
2012-12-16 12:03:00 -08:00
if ( psCurr - > visible [ player ] )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
found = true ;
2007-06-28 10:47:08 -07:00
}
}
}
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . bval = found ;
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// Check for a players structures but no walls being within a certain area
2011-03-12 17:32:15 -08:00
bool scrStructButNoWallsInArea ( void )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD player , x1 , y1 , x2 , y2 ;
SDWORD ox , oy ;
2007-06-28 10:47:08 -07:00
STRUCTURE * psStruct ;
2008-03-24 09:51:17 -07:00
SDWORD found = false ;
2007-06-28 10:47:08 -07:00
if ( ! stackPopParams ( 5 , VAL_INT , & player , VAL_INT , & x1 , VAL_INT , & y1 , VAL_INT , & x2 , VAL_INT , & y2 ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2007-06-28 10:47:08 -07:00
2012-12-16 12:03:00 -08:00
for ( psStruct = apsStructLists [ player ] ; psStruct ; psStruct = psStruct - > psNext )
2007-06-28 10:47:08 -07:00
{
if ( ( psStruct - > pStructureType - > type ! = REF_WALL ) & &
2012-12-16 12:03:00 -08:00
( psStruct - > pStructureType - > type ! = REF_WALLCORNER ) & &
( psStruct - > status = = SS_BUILT ) )
2007-06-28 10:47:08 -07:00
{
2007-12-15 07:39:29 -08:00
ox = ( SDWORD ) psStruct - > pos . x ;
oy = ( SDWORD ) psStruct - > pos . y ;
2007-06-28 10:47:08 -07:00
if ( ( ox > = x1 ) & & ( ox < = x2 ) & &
2012-12-16 12:03:00 -08:00
( oy > = y1 ) & & ( oy < = y2 ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
found = true ;
2007-06-28 10:47:08 -07:00
break ;
}
}
}
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . bval = found ;
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// check for the number of base objects in an area
static SDWORD numObjectsInArea ( BASE_OBJECT * psList , SDWORD x1 , SDWORD y1 , SDWORD x2 , SDWORD y2 )
{
BASE_OBJECT * psCurr ;
2012-12-16 12:03:00 -08:00
SDWORD ox , oy ;
2007-06-28 10:47:08 -07:00
SDWORD count ;
// See if there is a droid in Area
count = 0 ;
2012-12-16 12:03:00 -08:00
for ( psCurr = psList ; psCurr ; psCurr = psCurr - > psNext )
2007-06-28 10:47:08 -07:00
{
// skip partially build structures
2012-12-16 12:03:00 -08:00
if ( ( psCurr - > type = = OBJ_STRUCTURE ) & &
( ( ( STRUCTURE * ) psCurr ) - > status ! = SS_BUILT ) )
2007-06-28 10:47:08 -07:00
{
continue ;
}
2007-12-15 07:39:29 -08:00
ox = ( SDWORD ) psCurr - > pos . x ;
oy = ( SDWORD ) psCurr - > pos . y ;
2007-06-28 10:47:08 -07:00
if ( ox > = x1 & & ox < = x2 & &
2012-12-16 12:03:00 -08:00
oy > = y1 & & oy < = y2 )
2007-06-28 10:47:08 -07:00
{
count + = 1 ;
}
}
return count ;
}
// -----------------------------------------------------------------------------------------
// Count the number of player objects within a certain area
2011-03-12 17:32:15 -08:00
bool scrNumObjectsInArea ( void )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD player , x1 , y1 , x2 , y2 ;
2007-06-28 10:47:08 -07:00
SDWORD count ;
if ( ! stackPopParams ( 5 , VAL_INT , & player , VAL_INT , & x1 , VAL_INT , & y1 , VAL_INT , & x2 , VAL_INT , & y2 ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2007-06-28 10:47:08 -07:00
2012-12-16 12:03:00 -08:00
count = numObjectsInArea ( ( BASE_OBJECT * ) apsDroidLists [ player ] , x1 , y1 , x2 , y2 ) +
numObjectsInArea ( ( BASE_OBJECT * ) apsStructLists [ player ] , x1 , y1 , x2 , y2 ) ;
2007-06-28 10:47:08 -07:00
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . ival = count ;
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// Count the number of player droids within a certain area
2011-03-12 17:32:15 -08:00
bool scrNumDroidsInArea ( void )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD player , x1 , y1 , x2 , y2 ;
2007-06-28 10:47:08 -07:00
SDWORD count ;
if ( ! stackPopParams ( 5 , VAL_INT , & player , VAL_INT , & x1 , VAL_INT , & y1 , VAL_INT , & x2 , VAL_INT , & y2 ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2007-06-28 10:47:08 -07:00
2012-12-16 12:03:00 -08:00
count = numObjectsInArea ( ( BASE_OBJECT * ) apsDroidLists [ player ] , x1 , y1 , x2 , y2 ) ;
2007-06-28 10:47:08 -07:00
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . ival = count ;
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// Count the number of player structures within a certain area
2011-03-12 17:32:15 -08:00
bool scrNumStructsInArea ( void )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD player , x1 , y1 , x2 , y2 ;
2007-06-28 10:47:08 -07:00
SDWORD count ;
if ( ! stackPopParams ( 5 , VAL_INT , & player , VAL_INT , & x1 , VAL_INT , & y1 , VAL_INT , & x2 , VAL_INT , & y2 ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2007-06-28 10:47:08 -07:00
2012-12-16 12:03:00 -08:00
count = numObjectsInArea ( ( BASE_OBJECT * ) apsStructLists [ player ] , x1 , y1 , x2 , y2 ) ;
2007-06-28 10:47:08 -07:00
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . ival = count ;
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// Count the number of player structures but not walls within a certain area
2011-03-12 17:32:15 -08:00
bool scrNumStructsButNotWallsInArea ( void )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD player , x1 , y1 , x2 , y2 ;
SDWORD count , ox , oy ;
2007-06-28 10:47:08 -07:00
STRUCTURE * psStruct ;
if ( ! stackPopParams ( 5 , VAL_INT , & player , VAL_INT , & x1 , VAL_INT , & y1 , VAL_INT , & x2 , VAL_INT , & y2 ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2007-06-28 10:47:08 -07:00
count = 0 ;
2012-12-16 12:03:00 -08:00
for ( psStruct = apsStructLists [ player ] ; psStruct ; psStruct = psStruct - > psNext )
2007-06-28 10:47:08 -07:00
{
if ( ( psStruct - > pStructureType - > type ! = REF_WALL ) & &
2012-12-16 12:03:00 -08:00
( psStruct - > pStructureType - > type ! = REF_WALLCORNER ) & &
( psStruct - > status = = SS_BUILT ) )
2007-06-28 10:47:08 -07:00
{
2007-12-15 07:39:29 -08:00
ox = ( SDWORD ) psStruct - > pos . x ;
oy = ( SDWORD ) psStruct - > pos . y ;
2007-06-28 10:47:08 -07:00
if ( ( ox > = x1 ) & & ( ox < = x2 ) & &
2012-12-16 12:03:00 -08:00
( oy > = y1 ) & & ( oy < = y2 ) )
2007-06-28 10:47:08 -07:00
{
count + = 1 ;
}
}
}
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . ival = count ;
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// Count the number of structures in an area of a certain type
2011-03-12 17:32:15 -08:00
bool scrNumStructsByTypeInArea ( void )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD player , type , x1 , y1 , x2 , y2 ;
SDWORD count , ox , oy ;
2007-06-28 10:47:08 -07:00
STRUCTURE * psStruct ;
if ( ! stackPopParams ( 6 , VAL_INT , & player , VAL_INT , & type ,
2012-12-16 12:03:00 -08:00
VAL_INT , & x1 , VAL_INT , & y1 , VAL_INT , & x2 , VAL_INT , & y2 ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2007-06-28 10:47:08 -07:00
count = 0 ;
2012-12-16 12:03:00 -08:00
for ( psStruct = apsStructLists [ player ] ; psStruct ; psStruct = psStruct - > psNext )
2007-06-28 10:47:08 -07:00
{
if ( ( psStruct - > pStructureType - > type = = ( UDWORD ) type ) & &
2012-12-16 12:03:00 -08:00
( psStruct - > status = = SS_BUILT ) )
2007-06-28 10:47:08 -07:00
{
2007-12-15 07:39:29 -08:00
ox = ( SDWORD ) psStruct - > pos . x ;
oy = ( SDWORD ) psStruct - > pos . y ;
2007-06-28 10:47:08 -07:00
if ( ( ox > = x1 ) & & ( ox < = x2 ) & &
2012-12-16 12:03:00 -08:00
( oy > = y1 ) & & ( oy < = y2 ) )
2007-06-28 10:47:08 -07:00
{
count + = 1 ;
}
}
}
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . ival = count ;
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// Check for a droid having seen a certain object
2011-03-12 17:32:15 -08:00
bool scrDroidHasSeen ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD player ;
BASE_OBJECT * psObj ;
2011-03-12 17:32:15 -08:00
bool seen ;
2007-06-28 10:47:08 -07:00
if ( ! stackPopParams ( 2 , ST_BASEOBJECT , & psObj , VAL_INT , & player ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , psObj ! = NULL , " NULL object " ) ;
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2007-06-28 10:47:08 -07:00
// See if any droid has seen this object
2008-03-24 09:51:17 -07:00
seen = false ;
2007-06-28 10:47:08 -07:00
if ( psObj - > visible [ player ] )
{
2008-03-24 09:51:17 -07:00
seen = true ;
2007-06-28 10:47:08 -07:00
}
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . bval = seen ;
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// Enable a component to be researched
2011-03-12 17:32:15 -08:00
bool scrEnableComponent ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD player ;
INTERP_VAL sVal ;
if ( ! stackPopParams ( 1 , VAL_INT , & player ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
if ( ! stackPop ( & sVal ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2007-06-28 10:47:08 -07:00
// enable the appropriate component
2010-12-21 15:58:59 -08:00
switch ( ( unsigned ) sVal . type ) // Unsigned cast to suppress compiler warnings due to enum abuse.
2007-06-28 10:47:08 -07:00
{
case ST_BODY :
apCompLists [ player ] [ COMP_BODY ] [ sVal . v . ival ] = FOUND ;
break ;
case ST_PROPULSION :
apCompLists [ player ] [ COMP_PROPULSION ] [ sVal . v . ival ] = FOUND ;
break ;
case ST_ECM :
apCompLists [ player ] [ COMP_ECM ] [ sVal . v . ival ] = FOUND ;
break ;
case ST_SENSOR :
apCompLists [ player ] [ COMP_SENSOR ] [ sVal . v . ival ] = FOUND ;
break ;
case ST_CONSTRUCT :
apCompLists [ player ] [ COMP_CONSTRUCT ] [ sVal . v . ival ] = FOUND ;
break ;
case ST_WEAPON :
apCompLists [ player ] [ COMP_WEAPON ] [ sVal . v . ival ] = FOUND ;
break ;
case ST_REPAIR :
apCompLists [ player ] [ COMP_REPAIRUNIT ] [ sVal . v . ival ] = FOUND ;
break ;
case ST_BRAIN :
apCompLists [ player ] [ COMP_BRAIN ] [ sVal . v . ival ] = FOUND ;
break ;
default :
2012-12-16 12:03:00 -08:00
ASSERT ( false , " Unknown type " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// Make a component available
2011-03-12 17:32:15 -08:00
bool scrMakeComponentAvailable ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD player ;
INTERP_VAL sVal ;
if ( ! stackPopParams ( 1 , VAL_INT , & player ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
if ( ! stackPop ( & sVal ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2007-06-28 10:47:08 -07:00
// make the appropriate component available
2010-12-21 15:58:59 -08:00
switch ( ( unsigned ) sVal . type ) // Unsigned cast to suppress compiler warnings due to enum abuse.
2007-06-28 10:47:08 -07:00
{
case ST_BODY :
apCompLists [ player ] [ COMP_BODY ] [ sVal . v . ival ] = AVAILABLE ;
break ;
case ST_PROPULSION :
apCompLists [ player ] [ COMP_PROPULSION ] [ sVal . v . ival ] = AVAILABLE ;
break ;
case ST_ECM :
apCompLists [ player ] [ COMP_ECM ] [ sVal . v . ival ] = AVAILABLE ;
break ;
case ST_SENSOR :
apCompLists [ player ] [ COMP_SENSOR ] [ sVal . v . ival ] = AVAILABLE ;
break ;
case ST_CONSTRUCT :
apCompLists [ player ] [ COMP_CONSTRUCT ] [ sVal . v . ival ] = AVAILABLE ;
break ;
case ST_WEAPON :
apCompLists [ player ] [ COMP_WEAPON ] [ sVal . v . ival ] = AVAILABLE ;
break ;
case ST_REPAIR :
apCompLists [ player ] [ COMP_REPAIRUNIT ] [ sVal . v . ival ] = AVAILABLE ;
break ;
case ST_BRAIN :
apCompLists [ player ] [ COMP_BRAIN ] [ sVal . v . ival ] = AVAILABLE ;
break ;
default :
2012-12-16 12:03:00 -08:00
ASSERT ( false , " Unknown type " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// Add a droid
2011-03-12 17:32:15 -08:00
bool scrAddDroidToMissionList ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD player ;
DROID_TEMPLATE * psTemplate ;
DROID * psDroid ;
if ( ! stackPopParams ( 2 , ST_TEMPLATE , & psTemplate , VAL_INT , & player ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
ASSERT ( psTemplate ! = NULL , " Invalid template pointer " ) ;
2007-06-28 10:47:08 -07:00
# ifdef SCRIPT_CHECK_MAX_UNITS
// Don't build a new droid if player limit reached, unless it's a transporter.
2012-12-16 12:03:00 -08:00
if ( IsPlayerDroidLimitReached ( player ) & & ( psTemplate - > droidType ! = DROID_TRANSPORTER & & psTemplate - > droidType ! = DROID_SUPERTRANSPORTER ) )
2012-02-25 19:35:21 -08:00
{
2012-12-16 12:45:58 -08:00
debug ( LOG_SCRIPT , " Max units reached for player %d adding %s to mission list (type %d) " ,
2013-05-12 14:50:57 -07:00
player , getName ( psTemplate ) , psTemplate - > droidType ) ;
2007-06-28 10:47:08 -07:00
psDroid = NULL ;
2012-12-16 12:03:00 -08:00
}
else
2007-06-28 10:47:08 -07:00
# endif
{
2012-12-16 12:03:00 -08:00
psDroid = buildMissionDroid ( psTemplate , 128 , 128 , player ) ;
2007-06-28 10:47:08 -07:00
}
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . oval = psDroid ;
if ( ! stackPushResult ( ( INTERP_TYPE ) ST_DROID , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// Add a droid
2011-03-12 17:32:15 -08:00
bool scrAddDroid ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD x , y , player ;
DROID_TEMPLATE * psTemplate ;
DROID * psDroid ;
if ( ! stackPopParams ( 4 , ST_TEMPLATE , & psTemplate , VAL_INT , & x , VAL_INT , & y , VAL_INT , & player ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
ASSERT ( psTemplate ! = NULL , " Invalid template pointer " ) ;
2007-06-28 10:47:08 -07:00
# ifdef SCRIPT_CHECK_MAX_UNITS
// Don't build a new droid if player limit reached, unless it's a transporter.
2012-12-16 12:03:00 -08:00
if ( IsPlayerDroidLimitReached ( player ) & & ( psTemplate - > droidType ! = DROID_TRANSPORTER & & psTemplate - > droidType ! = DROID_SUPERTRANSPORTER ) )
2012-02-25 19:35:21 -08:00
{
2012-12-16 12:03:00 -08:00
debug ( LOG_NEVER , " scrAddUnit : Max units reached ,player %d \n " , player ) ;
2007-06-28 10:47:08 -07:00
psDroid = NULL ;
2012-12-16 12:03:00 -08:00
}
else
2007-06-28 10:47:08 -07:00
# endif
{
2010-02-22 04:29:28 -08:00
psDroid = buildDroid ( psTemplate , x , y , player , false , NULL ) ;
2007-06-28 10:47:08 -07:00
if ( psDroid )
{
addDroid ( psDroid , apsDroidLists ) ;
2012-12-16 12:03:00 -08:00
debug ( LOG_LIFE , " created droid for AI player %d %u " , player , psDroid - > id ) ;
2008-07-07 03:15:00 -07:00
if ( isVtolDroid ( psDroid ) )
2007-06-28 10:47:08 -07:00
{
// vtols start in the air
moveMakeVtolHover ( psDroid ) ;
}
}
2009-02-22 09:59:57 -08:00
else
{
2012-12-16 12:03:00 -08:00
debug ( LOG_LIFE , " send droid create message to game queue for AI player %d " , player ) ;
2009-02-22 09:59:57 -08:00
}
2007-06-28 10:47:08 -07:00
}
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . oval = psDroid ;
if ( ! stackPushResult ( ( INTERP_TYPE ) ST_DROID , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// Add droid to transporter
2011-03-12 17:32:15 -08:00
bool scrAddDroidToTransporter ( void )
2007-06-28 10:47:08 -07:00
{
DROID * psTransporter , * psDroid ;
if ( ! stackPopParams ( 2 , ST_DROID , & psTransporter , ST_DROID , & psDroid ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2006-05-27 09:37:17 -07:00
2008-02-09 03:17:34 -08:00
if ( psTransporter = = NULL | | psDroid = = NULL )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " Null unit passed " ) ;
2008-03-24 09:51:17 -07:00
return true ; // allow to continue
2008-02-09 03:17:34 -08:00
}
ASSERT ( psTransporter ! = NULL , " scrAddUnitToTransporter: invalid transporter pointer " ) ;
ASSERT ( psDroid ! = NULL , " scrAddUnitToTransporter: invalid unit pointer " ) ;
2012-02-27 18:17:47 -08:00
ASSERT ( ( psTransporter - > droidType = = DROID_TRANSPORTER | | psTransporter - > droidType = = DROID_SUPERTRANSPORTER ) , " scrAddUnitToTransporter: invalid transporter type " ) ;
2007-06-28 10:47:08 -07:00
/* check for space */
if ( checkTransporterSpace ( psTransporter , psDroid ) )
{
if ( droidRemove ( psDroid , mission . apsDroidLists ) )
2008-02-09 03:17:34 -08:00
{
2011-01-20 14:16:57 -08:00
psTransporter - > psGroup - > add ( psDroid ) ;
2008-02-09 03:17:34 -08:00
}
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
//check for a building to have been destroyed
2011-03-12 17:32:15 -08:00
bool scrBuildingDestroyed ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD player ;
UDWORD structureID ;
2011-03-12 17:32:15 -08:00
bool destroyed ;
2007-06-28 10:47:08 -07:00
STRUCTURE * psCurr ;
if ( ! stackPopParams ( 2 , ST_STRUCTUREID , & structureID , VAL_INT , & player ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2007-06-28 10:47:08 -07:00
2008-03-24 09:51:17 -07:00
destroyed = true ;
2007-06-28 10:47:08 -07:00
//look thru the players list to see if the structure still exists
for ( psCurr = apsStructLists [ player ] ; psCurr ! = NULL ; psCurr = psCurr - > psNext )
{
if ( psCurr - > id = = structureID )
{
2008-03-24 09:51:17 -07:00
destroyed = false ;
2007-06-28 10:47:08 -07:00
}
}
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . bval = destroyed ;
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// Enable a structure to be built
2011-03-12 17:32:15 -08:00
bool scrEnableStructure ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD player , index ;
if ( ! stackPopParams ( 2 , ST_STRUCTURESTAT , & index , VAL_INT , & player ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2007-02-10 08:39:39 -08:00
if ( index < ( SDWORD ) 0 | | index > ( SDWORD ) numStructureStats )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " Invalid structure stat " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
// enable the appropriate structure
apStructTypeLists [ player ] [ index ] = AVAILABLE ;
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// Check if a structure can be built.
// currently PC skirmish only.
2011-03-12 17:32:15 -08:00
bool scrIsStructureAvailable ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD player , index ;
2011-03-12 17:32:15 -08:00
bool bResult ;
2007-06-28 10:47:08 -07:00
if ( ! stackPopParams ( 2 , ST_STRUCTURESTAT , & index , VAL_INT , & player ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2010-01-25 02:43:56 -08:00
if ( apStructTypeLists [ player ] [ index ] = = AVAILABLE
& & asStructLimits [ player ] [ index ] . currentQuantity < asStructLimits [ player ] [ index ] . limit )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
bResult = true ;
2007-06-28 10:47:08 -07:00
}
else
{
2008-03-24 09:51:17 -07:00
bResult = false ;
2007-06-28 10:47:08 -07:00
}
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . bval = bResult ;
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
//make the droid with the matching id the currently selected droid
2011-03-12 17:32:15 -08:00
bool scrSelectDroidByID ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD player , droidID ;
2011-03-12 17:32:15 -08:00
bool selected ;
2007-06-28 10:47:08 -07:00
if ( ! stackPopParams ( 2 , ST_DROIDID , & droidID , VAL_INT , & player ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2007-06-28 10:47:08 -07:00
2008-03-24 09:51:17 -07:00
selected = false ;
2007-06-28 10:47:08 -07:00
if ( selectDroidByID ( droidID , player ) )
{
2008-03-24 09:51:17 -07:00
selected = true ;
2007-06-28 10:47:08 -07:00
}
2006-11-16 06:30:29 -08:00
//store the result cos might need to check the droid exists before doing anything else
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . bval = selected ;
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// Pop up a message box with a number value in it
2011-03-12 17:32:15 -08:00
bool scrNumMB ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD val ;
if ( ! stackPopParams ( 1 , VAL_INT , & val ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-12-28 13:47:48 -08:00
debug ( LOG_NEVER , " called by script with value: %d " , val ) ;
2007-06-28 10:47:08 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// Do an approximation to a square root
2011-03-12 17:32:15 -08:00
bool scrApproxRoot ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD val1 , val2 ;
if ( ! stackPopParams ( 2 , VAL_INT , & val1 , VAL_INT , & val2 ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
if ( val1 < val2 )
{
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . ival = val2 + ( val1 > > 1 ) ;
2007-06-28 10:47:08 -07:00
}
else
{
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . ival = val1 + ( val2 > > 1 ) ;
2007-06-28 10:47:08 -07:00
}
2006-11-19 12:50:02 -08:00
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// Add a reticule button to the interface
2011-03-12 17:32:15 -08:00
bool scrAddReticuleButton ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD val ;
if ( ! stackPopParams ( 1 , VAL_INT , & val ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
//set the appropriate flag to 'draw' the button
switch ( val )
{
case IDRET_OPTIONS :
// bit of a hack here to keep compatibility with old scripts
widgReveal ( psWScreen , IDRET_COMMAND ) ;
break ;
case IDRET_COMMAND :
widgReveal ( psWScreen , IDRET_COMMAND ) ;
break ;
case IDRET_BUILD :
widgReveal ( psWScreen , IDRET_BUILD ) ;
break ;
case IDRET_MANUFACTURE :
widgReveal ( psWScreen , IDRET_MANUFACTURE ) ;
break ;
case IDRET_RESEARCH :
widgReveal ( psWScreen , IDRET_RESEARCH ) ;
break ;
case IDRET_INTEL_MAP :
widgReveal ( psWScreen , IDRET_INTEL_MAP ) ;
break ;
case IDRET_DESIGN :
widgReveal ( psWScreen , IDRET_DESIGN ) ;
break ;
case IDRET_CANCEL :
widgReveal ( psWScreen , IDRET_CANCEL ) ;
break ;
default :
2012-12-16 12:03:00 -08:00
ASSERT ( false , " Invalid reticule Button ID " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
//Remove a reticule button from the interface
2011-03-12 17:32:15 -08:00
bool scrRemoveReticuleButton ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD val ;
2011-03-19 18:52:25 -07:00
int32_t bReset ; // was BOOL (int) ** see warning about conversion
2007-06-28 10:47:08 -07:00
2012-12-16 12:03:00 -08:00
if ( ! stackPopParams ( 2 , VAL_INT , & val , VAL_BOOL , & bReset ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
if ( bInTutorial )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
if ( bReset ) // not always desirable
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
intResetScreen ( true ) ;
2007-06-28 10:47:08 -07:00
}
}
switch ( val )
{
case IDRET_OPTIONS :
// bit of a hack here to keep compatibility with old scripts
widgHide ( psWScreen , IDRET_COMMAND ) ;
break ;
case IDRET_COMMAND :
widgHide ( psWScreen , IDRET_COMMAND ) ;
break ;
case IDRET_BUILD :
widgHide ( psWScreen , IDRET_BUILD ) ;
break ;
case IDRET_MANUFACTURE :
widgHide ( psWScreen , IDRET_MANUFACTURE ) ;
break ;
case IDRET_RESEARCH :
widgHide ( psWScreen , IDRET_RESEARCH ) ;
break ;
case IDRET_INTEL_MAP :
widgHide ( psWScreen , IDRET_INTEL_MAP ) ;
break ;
case IDRET_DESIGN :
widgHide ( psWScreen , IDRET_DESIGN ) ;
break ;
case IDRET_CANCEL :
widgHide ( psWScreen , IDRET_CANCEL ) ;
break ;
default :
2012-12-16 12:03:00 -08:00
ASSERT ( false , " Invalid reticule Button ID " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// add a message to the Intelligence Display
2011-03-12 17:32:15 -08:00
bool scrAddMessage ( void )
2007-06-28 10:47:08 -07:00
{
MESSAGE * psMessage ;
2007-01-07 15:50:30 -08:00
MESSAGE_TYPE msgType ;
SDWORD player ;
2011-03-19 18:52:25 -07:00
int32_t playImmediate ; // was BOOL (int) ** see warning about conversion
2007-06-28 10:47:08 -07:00
VIEWDATA * psViewData ;
UDWORD height ;
if ( ! stackPopParams ( 4 , ST_INTMESSAGE , & psViewData , VAL_INT , & msgType ,
2012-12-16 12:03:00 -08:00
VAL_INT , & player , VAL_BOOL , & playImmediate ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2006-09-19 09:07:06 -07:00
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2007-06-28 10:47:08 -07:00
//create the message
2008-03-24 09:51:17 -07:00
psMessage = addMessage ( msgType , false , player ) ;
2007-06-28 10:47:08 -07:00
if ( psMessage )
{
//set the data
psMessage - > pViewData = ( MSG_VIEWDATA * ) psViewData ;
2008-04-19 14:41:18 -07:00
debug ( LOG_MSG , " Adding %s pViewData=%p " , psViewData - > pName , psMessage - > pViewData ) ;
2007-06-28 10:47:08 -07:00
if ( msgType = = MSG_PROXIMITY )
{
//check the z value is at least the height of the terrain
2006-05-27 09:37:17 -07:00
height = map_Height ( ( ( VIEW_PROXIMITY * ) psViewData - > pData ) - > x ,
2012-12-16 12:03:00 -08:00
( ( VIEW_PROXIMITY * ) psViewData - > pData ) - > y ) ;
2007-06-28 10:47:08 -07:00
if ( ( ( VIEW_PROXIMITY * ) psViewData - > pData ) - > z < height )
{
( ( VIEW_PROXIMITY * ) psViewData - > pData ) - > z = height ;
}
}
2012-01-21 08:01:08 -08:00
if ( playImmediate )
2007-06-28 10:47:08 -07:00
{
displayImmediateMessage ( psMessage ) ;
2012-03-29 15:56:23 -07:00
// FIXME: We should add some kind of check to see if the FMVs are available or not, and enable this based on that.
// If we want to inform user of a message, we shouldn't stop the flash right?
//stopReticuleButtonFlash(IDRET_INTEL_MAP);
2007-06-28 10:47:08 -07:00
}
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// remove a message from the Intelligence Display
2011-03-12 17:32:15 -08:00
bool scrRemoveMessage ( void )
2007-06-28 10:47:08 -07:00
{
MESSAGE * psMessage ;
2007-01-07 15:50:30 -08:00
MESSAGE_TYPE msgType ;
SDWORD player ;
2007-06-28 10:47:08 -07:00
VIEWDATA * psViewData ;
2008-04-19 14:41:18 -07:00
if ( ! stackPopParams ( 3 , ST_INTMESSAGE , & psViewData , VAL_INT , & msgType , VAL_INT , & player ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2007-06-28 10:47:08 -07:00
//find the message
psMessage = findMessage ( ( MSG_VIEWDATA * ) psViewData , msgType , player ) ;
if ( psMessage )
{
//delete it
2008-04-19 14:41:18 -07:00
debug ( LOG_MSG , " Removing %s " , psViewData - > pName ) ;
2007-06-28 10:47:08 -07:00
removeMessage ( psMessage , player ) ;
}
else
{
2010-01-07 18:42:51 -08:00
debug ( LOG_ERROR , " cannot find message - %s " , psViewData - > pName ) ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
/*builds a droid in the specified factory*/
2011-03-12 17:32:15 -08:00
bool scrBuildDroid ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD player , productionRun ;
STRUCTURE * psFactory ;
DROID_TEMPLATE * psTemplate ;
2010-01-10 13:26:05 -08:00
if ( ! stackPopParams ( 4 , ST_TEMPLATE , & psTemplate , ST_STRUCTURE , & psFactory , VAL_INT , & player , VAL_INT , & productionRun ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2010-01-10 13:26:05 -08:00
ASSERT_OR_RETURN ( false , psFactory ! = NULL , " NULL factory object " ) ;
2010-01-10 14:41:35 -08:00
ASSERT_OR_RETURN ( false , psTemplate ! = NULL , " NULL template object sent to %s " , objInfo ( ( BASE_OBJECT * ) psFactory ) ) ;
2010-01-10 13:26:05 -08:00
ASSERT_OR_RETURN ( false , player < MAX_PLAYERS , " Invalid player number " ) ;
ASSERT_OR_RETURN ( false , productionRun < = UBYTE_MAX , " Production run too high " ) ;
ASSERT_OR_RETURN ( false , ( psFactory - > pStructureType - > type = = REF_FACTORY | |
2012-12-16 12:03:00 -08:00
psFactory - > pStructureType - > type = = REF_CYBORG_FACTORY | |
psFactory - > pStructureType - > type = = REF_VTOL_FACTORY ) ,
" Structure is not a factory " ) ;
2012-02-07 13:05:36 -08:00
ASSERT_OR_RETURN ( false , validTemplateForFactory ( psTemplate , psFactory , true ) , " Invalid template - %s for factory - %s " ,
2013-05-12 14:50:57 -07:00
getName ( psTemplate ) , getID ( psFactory - > pStructureType ) ) ;
2010-02-23 09:43:18 -08:00
if ( productionRun ! = 1 )
{
2012-11-23 10:33:22 -08:00
debug ( LOG_WARNING , " A wzscript is trying to build a different number (%d) than 1 droid. " , productionRun ) ;
}
if ( researchedTemplate ( psTemplate , psFactory - > player , true , true ) )
{
structSetManufacture ( psFactory , psTemplate , ModeQueue ) ;
}
else
{
2013-05-12 14:50:57 -07:00
debug ( LOG_WARNING , " A wzscript tried to build a template (%s) that has not been researched yet " , getName ( psTemplate ) ) ;
2010-02-23 09:43:18 -08:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// for a specified structure, set the assembly point droids go to when built
2011-03-12 17:32:15 -08:00
bool scrSetAssemblyPoint ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD x , y ;
STRUCTURE * psBuilding ;
if ( ! stackPopParams ( 3 , ST_STRUCTURE , & psBuilding , VAL_INT , & x , VAL_INT , & y ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
if ( psBuilding = = NULL )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " NULL structure " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2007-02-10 08:39:39 -08:00
if ( psBuilding - > pStructureType - > type ! = REF_FACTORY & &
2012-12-16 12:03:00 -08:00
psBuilding - > pStructureType - > type ! = REF_CYBORG_FACTORY & &
psBuilding - > pStructureType - > type ! = REF_VTOL_FACTORY )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " Structure is not a factory " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
setAssemblyPoint ( ( ( FACTORY * ) psBuilding - > pFunctionality ) - > psAssemblyPoint , x , y ,
psBuilding - > player , true ) ;
2007-06-28 10:47:08 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// test for structure is idle or not
2011-03-12 17:32:15 -08:00
bool scrStructureIdle ( void )
2007-06-28 10:47:08 -07:00
{
STRUCTURE * psBuilding ;
2011-03-12 17:32:15 -08:00
bool idle ;
2007-06-28 10:47:08 -07:00
if ( ! stackPopParams ( 1 , ST_STRUCTURE , & psBuilding ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
if ( psBuilding = = NULL )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " NULL structure " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2010-01-15 06:05:17 -08:00
idle = structureIdle ( psBuilding ) ;
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . bval = idle ;
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2006-05-27 09:37:17 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// sends a players droids to a location to attack
2011-03-12 17:32:15 -08:00
bool scrAttackLocation ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD player , x , y ;
if ( ! stackPopParams ( 3 , VAL_INT , & x , VAL_INT , & y , VAL_INT , & player ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2007-06-28 10:47:08 -07:00
2007-11-20 14:58:25 -08:00
debug ( LOG_ERROR , " UNUSED FUNCTION attackLocation called - do not use! " ) ;
2007-06-28 10:47:08 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
//Destroy a feature
2011-03-12 17:32:15 -08:00
bool scrDestroyFeature ( void )
2007-06-28 10:47:08 -07:00
{
FEATURE * psFeature ;
if ( ! stackPopParams ( 1 , ST_FEATURE , & psFeature ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
if ( psFeature = = NULL )
{
2012-12-16 12:03:00 -08:00
ASSERT ( psFeature ! = NULL , " Invalid feature pointer " ) ;
2007-06-28 10:47:08 -07:00
}
removeFeature ( psFeature ) ;
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// static vars to enum features.
static FEATURE_STATS * psFeatureStatToFind [ MAX_PLAYERS ] ;
static SDWORD playerToEnum [ MAX_PLAYERS ] ;
2012-12-16 12:03:00 -08:00
static SDWORD getFeatureCount [ MAX_PLAYERS ] = { 0 } ;
2007-01-02 12:12:14 -08:00
static FEATURE * psCurrEnumFeature [ MAX_PLAYERS ] ;
2007-06-28 10:47:08 -07:00
// -----------------------------------------------------------------------------------------
2010-01-14 07:51:35 -08:00
// Init enum visible features. May use player==-1 to ignore visibility check.
2011-03-12 17:32:15 -08:00
bool scrInitGetFeature ( void )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD player , iFeat , bucket ;
2006-05-27 09:37:17 -07:00
2010-01-14 07:51:35 -08:00
if ( ! stackPopParams ( 3 , ST_FEATURESTAT , & iFeat , VAL_INT , & player , VAL_INT , & bucket ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2010-01-14 07:51:35 -08:00
ASSERT_OR_RETURN ( false , bucket > = 0 & & bucket < MAX_PLAYERS , " Bucket out of bounds: %d " , bucket ) ;
ASSERT_OR_RETURN ( false , ( player > = 0 | | player = = - 1 ) & & player < MAX_PLAYERS , " Player out of bounds: %d " , player ) ;
2007-01-04 10:15:17 -08:00
2007-06-28 10:47:08 -07:00
psFeatureStatToFind [ bucket ] = ( FEATURE_STATS * ) ( asFeatureStats + iFeat ) ; // find this stat
playerToEnum [ bucket ] = player ; // that this player can see
2007-01-02 12:12:14 -08:00
psCurrEnumFeature [ bucket ] = apsFeatureLists [ 0 ] ;
2007-06-28 10:47:08 -07:00
getFeatureCount [ bucket ] = 0 ; // start at the beginning of list.
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// get next visible feature of required type
2006-05-27 09:37:17 -07:00
// notes: can't rely on just using the feature list, since it may change
2007-06-28 10:47:08 -07:00
// between calls, Use an index into list instead.
// Doesn't return Features sharing a tile with a structure.
// Skirmish Only, dunno if kev uses this?
2011-03-12 17:32:15 -08:00
bool scrGetFeature ( void )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD bucket , count ;
2007-06-28 10:47:08 -07:00
FEATURE * psFeat ;
2012-12-16 12:03:00 -08:00
if ( ! stackPopParams ( 1 , VAL_INT , & bucket ) )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " Failed to pop player number from stack " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT ( bucket > = 0 & & bucket < MAX_PLAYERS , " Bucket out of bounds: %d " , bucket ) ;
2007-01-04 10:15:17 -08:00
2012-12-16 12:03:00 -08:00
count = 0 ;
2007-06-28 10:47:08 -07:00
// go to the correct start point in the feature list.
2012-12-16 12:03:00 -08:00
for ( psFeat = apsFeatureLists [ 0 ] ; psFeat & & count < getFeatureCount [ bucket ] ; count + + )
2007-06-28 10:47:08 -07:00
{
psFeat = psFeat - > psNext ;
}
2006-05-27 09:37:17 -07:00
2012-12-16 12:03:00 -08:00
if ( psFeat = = NULL ) // no more to find.
2007-06-28 10:47:08 -07:00
{
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . oval = NULL ;
if ( ! stackPushResult ( ( INTERP_TYPE ) ST_FEATURE , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " Failed to push result " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
2006-05-27 09:37:17 -07:00
// check to see if badly called
2012-12-16 12:03:00 -08:00
if ( psFeatureStatToFind [ bucket ] = = NULL )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
debug ( LOG_NEVER , " invalid feature to find. possibly due to save game \n " ) ;
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . oval = NULL ;
2012-12-16 12:03:00 -08:00
if ( ! stackPushResult ( ( INTERP_TYPE ) ST_FEATURE , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " Failed to push result " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// begin searching the feature list for the required stat.
2012-12-16 12:03:00 -08:00
while ( psFeat )
2007-06-28 10:47:08 -07:00
{
2007-09-28 12:25:21 -07:00
if ( psFeat - > psStats - > subType = = psFeatureStatToFind [ bucket ] - > subType
2012-12-16 12:03:00 -08:00
& & ( playerToEnum [ bucket ] < 0 | | psFeat - > visible [ playerToEnum [ bucket ] ] ! = 0 )
& & ! TileHasStructure ( mapTile ( map_coord ( psFeat - > pos . x ) , map_coord ( psFeat - > pos . y ) ) )
& & ! fireOnLocation ( psFeat - > pos . x , psFeat - > pos . y ) // not burning.
2007-09-28 12:25:21 -07:00
)
2007-06-28 10:47:08 -07:00
{
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . oval = psFeat ;
if ( ! stackPushResult ( ( INTERP_TYPE ) ST_FEATURE , & scrFunctionResult ) ) // push scrFunctionResult
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " Failed to push result " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
getFeatureCount [ bucket ] + + ;
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
getFeatureCount [ bucket ] + + ;
2012-12-16 12:03:00 -08:00
psFeat = psFeat - > psNext ;
2007-06-28 10:47:08 -07:00
}
2006-05-27 09:37:17 -07:00
2007-06-28 10:47:08 -07:00
// none found
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . oval = NULL ;
if ( ! stackPushResult ( ( INTERP_TYPE ) ST_FEATURE , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " Failed to push result " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
2010-01-14 07:51:35 -08:00
/* Faster implementation of scrGetFeature - assumes no features are deleted between calls */
2011-03-12 17:32:15 -08:00
bool scrGetFeatureB ( void )
2007-01-02 12:12:14 -08:00
{
SDWORD bucket ;
2012-12-16 12:03:00 -08:00
if ( ! stackPopParams ( 1 , VAL_INT , & bucket ) )
2007-01-02 12:12:14 -08:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " Failed to pop player number from stack " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-01-02 12:12:14 -08:00
}
2012-12-16 12:03:00 -08:00
ASSERT ( bucket > = 0 & & bucket < MAX_PLAYERS , " Bucket out of bounds: %d " , bucket ) ;
2007-01-04 10:15:17 -08:00
2007-01-02 12:12:14 -08:00
// check to see if badly called
2012-12-16 12:03:00 -08:00
if ( psFeatureStatToFind [ bucket ] = = NULL )
2007-01-02 12:12:14 -08:00
{
2012-12-16 12:03:00 -08:00
debug ( LOG_NEVER , " invalid feature to find. possibly due to save game \n " ) ;
2007-01-02 12:12:14 -08:00
scrFunctionResult . v . oval = NULL ;
2012-12-16 12:03:00 -08:00
if ( ! stackPushResult ( ( INTERP_TYPE ) ST_FEATURE , & scrFunctionResult ) )
2007-01-02 12:12:14 -08:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " Failed to push result " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-01-02 12:12:14 -08:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-01-02 12:12:14 -08:00
}
// begin searching the feature list for the required stat.
2012-12-16 12:03:00 -08:00
while ( psCurrEnumFeature [ bucket ] )
2007-01-02 12:12:14 -08:00
{
2010-01-14 07:51:35 -08:00
if ( psCurrEnumFeature [ bucket ] - > psStats - > subType = = psFeatureStatToFind [ bucket ] - > subType
& & ( playerToEnum [ bucket ] < 0 | | psCurrEnumFeature [ bucket ] - > visible [ playerToEnum [ bucket ] ] ! = 0 )
& & ! TileHasStructure ( mapTile ( map_coord ( psCurrEnumFeature [ bucket ] - > pos . x ) , map_coord ( psCurrEnumFeature [ bucket ] - > pos . y ) ) )
2012-12-16 12:03:00 -08:00
& & ! fireOnLocation ( psCurrEnumFeature [ bucket ] - > pos . x , psCurrEnumFeature [ bucket ] - > pos . y ) // not burning.
)
2007-01-02 12:12:14 -08:00
{
scrFunctionResult . v . oval = psCurrEnumFeature [ bucket ] ;
if ( ! stackPushResult ( ( INTERP_TYPE ) ST_FEATURE , & scrFunctionResult ) ) // push scrFunctionResult
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " Failed to push result " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-01-02 12:12:14 -08:00
}
psCurrEnumFeature [ bucket ] = psCurrEnumFeature [ bucket ] - > psNext ;
2008-03-24 09:51:17 -07:00
return true ;
2007-01-02 12:12:14 -08:00
}
psCurrEnumFeature [ bucket ] = psCurrEnumFeature [ bucket ] - > psNext ;
}
// none found
scrFunctionResult . v . oval = NULL ;
if ( ! stackPushResult ( ( INTERP_TYPE ) ST_FEATURE , & scrFunctionResult ) )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " Failed to push result " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-01-02 12:12:14 -08:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-01-02 12:12:14 -08:00
}
2007-06-28 10:47:08 -07:00
// -----------------------------------------------------------------------------------------
//Add a feature
2011-03-12 17:32:15 -08:00
bool scrAddFeature ( void )
2007-06-28 10:47:08 -07:00
{
FEATURE_STATS * psStat ;
FEATURE * psFeat = NULL ;
SDWORD iX , iY , iMapX , iMapY , iTestX , iTestY , iFeat ;
2012-12-16 12:03:00 -08:00
if ( ! stackPopParams ( 3 , ST_FEATURESTAT , & iFeat ,
VAL_INT , & iX , VAL_INT , & iY ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
psStat = ( FEATURE_STATS * ) ( asFeatureStats + iFeat ) ;
2011-10-30 15:33:42 -07:00
ASSERT ( psStat ! = NULL , " Invalid feature pointer " ) ;
2007-06-28 10:47:08 -07:00
2012-12-16 12:03:00 -08:00
if ( psStat ! = NULL )
2007-06-28 10:47:08 -07:00
{
2007-09-28 12:25:21 -07:00
iMapX = map_coord ( iX ) ;
iMapY = map_coord ( iY ) ;
2007-06-28 10:47:08 -07:00
/* check for wrecked feature already on-tile and remove */
2012-12-16 12:03:00 -08:00
for ( psFeat = apsFeatureLists [ 0 ] ; psFeat ; psFeat = psFeat - > psNext )
2007-06-28 10:47:08 -07:00
{
2007-12-15 07:39:29 -08:00
iTestX = map_coord ( psFeat - > pos . x ) ;
iTestY = map_coord ( psFeat - > pos . y ) ;
2007-06-28 10:47:08 -07:00
2011-10-30 15:33:42 -07:00
ASSERT ( iTestX ! = iMapX | | iTestY ! = iMapY , " Building feature on tile already occupied " ) ;
2007-06-28 10:47:08 -07:00
}
2006-05-27 09:37:17 -07:00
2012-12-16 12:03:00 -08:00
psFeat = buildFeature ( psStat , iX , iY , false ) ;
2007-06-28 10:47:08 -07:00
}
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . oval = psFeat ;
if ( ! stackPushResult ( ( INTERP_TYPE ) ST_FEATURE , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
//Add a structure
2011-03-12 17:32:15 -08:00
bool scrAddStructure ( void )
2007-06-28 10:47:08 -07:00
{
STRUCTURE_STATS * psStat ;
STRUCTURE * psStruct = NULL ;
SDWORD iX , iY , iMapX , iMapY ; //, iWidth, iBreadth;
SDWORD iStruct , iPlayer ; //, iW, iB;
2012-12-16 12:03:00 -08:00
if ( ! stackPopParams ( 4 , ST_STRUCTURESTAT , & iStruct , VAL_INT , & iPlayer ,
VAL_INT , & iX , VAL_INT , & iY ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
psStat = ( STRUCTURE_STATS * ) ( asStructureStats + iStruct ) ;
2012-12-16 12:03:00 -08:00
ASSERT ( psStat ! = NULL , " Invalid feature pointer " ) ;
2007-06-28 10:47:08 -07:00
2012-12-16 12:03:00 -08:00
if ( psStat ! = NULL )
2007-06-28 10:47:08 -07:00
{
/* offset coords so building centre at (iX, iY) */
2012-12-16 12:03:00 -08:00
/* no longer necessary - buildStruct no longer uses top left
iX - = psStat - > baseWidth * TILE_UNITS / 2 ;
iY - = psStat - > baseBreadth * TILE_UNITS / 2 ; */
2007-06-28 10:47:08 -07:00
2007-09-28 12:25:21 -07:00
iMapX = map_coord ( iX ) ;
iMapY = map_coord ( iY ) ;
2007-06-28 10:47:08 -07:00
/* check for structure already on-tile */
2012-12-16 12:03:00 -08:00
if ( TileHasStructure ( mapTile ( iMapX , iMapY ) ) )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " Tile already occupied by structure " ) ;
2007-06-28 10:47:08 -07:00
}
2006-05-27 09:37:17 -07:00
2012-12-16 12:03:00 -08:00
psStruct = buildStructure ( psStat , iX , iY , iPlayer , false ) ;
if ( psStruct ! = NULL )
2007-06-28 10:47:08 -07:00
{
psStruct - > status = SS_BUILT ;
buildingComplete ( psStruct ) ;
2012-12-16 12:03:00 -08:00
/*
Apart from this being wrong ( iWidth = 0 when psStat - > baseWidth = 1
and you end up in an infinite loop ) we don ' t need to do this here
since the map is flattened as part of buildStructure
2007-06-28 10:47:08 -07:00
iWidth = psStat - > baseWidth / 2 ;
iBreadth = psStat - > baseBreadth / 2 ;
// flatten tiles across building base
for ( iW = iMapX ; iW < = iMapX + ( SDWORD ) psStat - > baseWidth ; iW + = iWidth )
{
for ( iB = iMapY ; iB < = iMapY + ( SDWORD ) psStat - > baseBreadth ; iB + = iBreadth )
{
2007-12-15 07:39:29 -08:00
setTileHeight ( iW , iB , psStruct - > pos . z ) ;
2007-06-28 10:47:08 -07:00
}
} */
}
}
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . oval = psStruct ;
if ( ! stackPushResult ( ( INTERP_TYPE ) ST_STRUCTURE , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
//Destroy a structure
2011-03-12 17:32:15 -08:00
bool scrDestroyStructure ( void )
2007-06-28 10:47:08 -07:00
{
STRUCTURE * psStruct ;
if ( ! stackPopParams ( 1 , ST_STRUCTURE , & psStruct ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
if ( psStruct = = NULL )
{
2012-12-16 12:03:00 -08:00
ASSERT ( psStruct ! = NULL , " Invalid structure pointer " ) ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
removeStruct ( psStruct , true ) ;
2007-06-28 10:47:08 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
//NEXT 2 FUNCS ONLY USED IN MULTIPLAYER AS FAR AS I KNOW (25 AUG98) alexl.
// static vars to enum structs;
static STRUCTURE_STATS * psStructStatToFind ;
static UDWORD playerToEnumStruct ;
static UDWORD enumStructCount ;
2011-03-12 17:32:15 -08:00
static bool structfindany ;
2006-08-26 08:50:47 -07:00
static SDWORD playerVisibleStruct ; //player whose structures must be visible
2007-06-28 10:47:08 -07:00
2007-01-04 13:47:12 -08:00
//for the bucket version
static STRUCTURE_STATS * psStructStatToFindB [ MAX_PLAYERS ] ;
static UDWORD playerToEnumStructB [ MAX_PLAYERS ] ;
static UDWORD enumStructCountB [ MAX_PLAYERS ] ;
2011-03-19 18:52:25 -07:00
static int32_t structfindanyB [ MAX_PLAYERS ] ; // was BOOL (int) ** see warning about conversion
2007-01-04 13:47:12 -08:00
static SDWORD playerVisibleStructB [ MAX_PLAYERS ] ; //player whose structures must be visible
2007-06-28 10:47:08 -07:00
// init enum visible structures.
2011-03-12 17:32:15 -08:00
bool scrInitEnumStruct ( void )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD lookingPlayer , iStat , targetPlayer ;
2011-03-19 18:52:25 -07:00
int32_t any ; // was BOOL (int) ** see warning about conversion
2006-05-27 09:37:17 -07:00
2012-12-16 12:03:00 -08:00
if ( ! stackPopParams ( 4 , VAL_BOOL , & any , ST_STRUCTURESTAT , & iStat , VAL_INT , & targetPlayer , VAL_INT , & lookingPlayer ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2007-01-04 13:47:12 -08:00
ASSERT ( targetPlayer > = 0 & & targetPlayer < MAX_PLAYERS ,
2012-12-16 12:03:00 -08:00
" targetPlayer out of bounds: %d " , targetPlayer ) ;
2007-01-04 13:47:12 -08:00
ASSERT ( lookingPlayer > = 0 & & lookingPlayer < MAX_PLAYERS ,
2012-12-16 12:03:00 -08:00
" lookingPlayer out of bounds: %d " , lookingPlayer ) ;
2007-01-04 13:47:12 -08:00
structfindany = any ;
2007-06-28 10:47:08 -07:00
psStructStatToFind = ( STRUCTURE_STATS * ) ( asStructureStats + iStat ) ;
2006-12-02 15:27:00 -08:00
playerToEnumStruct = ( UDWORD ) targetPlayer ;
2007-01-04 13:47:12 -08:00
playerVisibleStruct = lookingPlayer ; //remember who must be able to see the structure
2007-06-28 10:47:08 -07:00
enumStructCount = 0 ;
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
2011-03-12 17:32:15 -08:00
bool scrEnumStruct ( void )
2007-06-28 10:47:08 -07:00
{
UDWORD count ;
STRUCTURE * psStruct ;
// go to the correct start point in the structure list.
count = 0 ;
2012-12-16 12:03:00 -08:00
for ( psStruct = apsStructLists [ playerToEnumStruct ] ; psStruct & & count < enumStructCount ; count + + )
2007-06-28 10:47:08 -07:00
{
psStruct = psStruct - > psNext ;
}
2006-05-27 09:37:17 -07:00
2012-12-16 12:03:00 -08:00
if ( psStruct = = NULL ) // no more to find.
2007-06-28 10:47:08 -07:00
{
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . oval = NULL ;
if ( ! stackPushResult ( ( INTERP_TYPE ) ST_STRUCTURE , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
while ( psStruct ) // find a visible structure of required type.
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
if ( ( structfindany | | ( psStruct - > pStructureType - > ref = = psStructStatToFind - > ref ) )
& &
( ( playerVisibleStruct < 0 ) | | ( psStruct - > visible [ playerVisibleStruct ] ) ) //fix: added playerVisibleStruct for visibility test
)
2007-06-28 10:47:08 -07:00
{
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . oval = psStruct ;
if ( ! stackPushResult ( ( INTERP_TYPE ) ST_STRUCTURE , & scrFunctionResult ) ) // push scrFunctionResult
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
enumStructCount + + ;
2006-12-02 15:27:00 -08:00
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
enumStructCount + + ;
psStruct = psStruct - > psNext ;
}
// push NULL, none found;
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . oval = NULL ;
if ( ! stackPushResult ( ( INTERP_TYPE ) ST_STRUCTURE , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
2007-01-04 13:47:12 -08:00
// init enum visible structures - takes bucket as additional parameter
2011-03-12 17:32:15 -08:00
bool scrInitEnumStructB ( void )
2007-01-04 13:47:12 -08:00
{
2012-12-16 12:03:00 -08:00
SDWORD lookingPlayer , iStat , targetPlayer , bucket ;
2011-03-19 18:52:25 -07:00
int32_t any ; // was BOOL (int) ** see warning about conversion
2007-01-04 13:47:12 -08:00
2012-12-16 12:03:00 -08:00
if ( ! stackPopParams ( 5 , VAL_BOOL , & any , ST_STRUCTURESTAT , & iStat ,
VAL_INT , & targetPlayer , VAL_INT , & lookingPlayer , VAL_INT , & bucket ) )
2007-01-04 13:47:12 -08:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-01-04 13:47:12 -08:00
}
ASSERT ( targetPlayer > = 0 & & targetPlayer < MAX_PLAYERS ,
2012-12-16 12:03:00 -08:00
" targetPlayer out of bounds: %d " , targetPlayer ) ;
2007-01-04 13:47:12 -08:00
ASSERT ( lookingPlayer > = 0 & & lookingPlayer < MAX_PLAYERS ,
2012-12-16 12:03:00 -08:00
" lookingPlayer out of bounds: %d " , lookingPlayer ) ;
2007-01-04 13:47:12 -08:00
ASSERT ( bucket > = 0 & & bucket < MAX_PLAYERS ,
2012-12-16 12:03:00 -08:00
" bucket out of bounds: %d " , bucket ) ;
2007-01-04 13:47:12 -08:00
/* Any structure type regardless of the passed type? */
structfindanyB [ bucket ] = any ;
psStructStatToFindB [ bucket ] = ( STRUCTURE_STATS * ) ( asStructureStats + iStat ) ;
playerToEnumStructB [ bucket ] = ( UDWORD ) targetPlayer ;
playerVisibleStructB [ bucket ] = lookingPlayer ; //remember who must be able to see the structure
enumStructCountB [ bucket ] = 0 ;
2008-03-24 09:51:17 -07:00
return true ;
2007-01-04 13:47:12 -08:00
}
// Similar to scrEnumStruct, but uses bucket
2011-03-12 17:32:15 -08:00
bool scrEnumStructB ( void )
2007-01-04 13:47:12 -08:00
{
SDWORD bucket ;
UDWORD count ;
STRUCTURE * psStruct ;
2012-12-16 12:03:00 -08:00
if ( ! stackPopParams ( 1 , VAL_INT , & bucket ) )
2007-01-04 13:47:12 -08:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-01-04 13:47:12 -08:00
}
2012-12-16 12:03:00 -08:00
ASSERT ( bucket > = 0 & & bucket < MAX_PLAYERS , " Bucket out of bounds: %d " , bucket ) ;
2007-06-28 10:47:08 -07:00
2007-01-04 13:47:12 -08:00
// go to the correct start point in the structure list.
count = 0 ;
2012-12-16 12:03:00 -08:00
for ( psStruct = apsStructLists [ playerToEnumStructB [ bucket ] ] ; psStruct & & count < enumStructCountB [ bucket ] ; count + + )
2007-01-04 13:47:12 -08:00
{
psStruct = psStruct - > psNext ;
}
2012-12-16 12:03:00 -08:00
if ( psStruct = = NULL ) // no more to find.
2007-01-04 13:47:12 -08:00
{
scrFunctionResult . v . oval = NULL ;
if ( ! stackPushResult ( ( INTERP_TYPE ) ST_STRUCTURE , & scrFunctionResult ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-01-04 13:47:12 -08:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-01-04 13:47:12 -08:00
}
2012-12-16 12:03:00 -08:00
while ( psStruct ) // find a visible structure of required type.
2007-01-04 13:47:12 -08:00
{
2012-12-16 12:03:00 -08:00
if ( ( structfindanyB [ bucket ] | | ( psStruct - > pStructureType - > ref = = psStructStatToFindB [ bucket ] - > ref ) )
& &
( ( playerVisibleStructB [ bucket ] < 0 ) | | ( psStruct - > visible [ playerVisibleStructB [ bucket ] ] ) ) //perform visibility test
)
2007-01-04 13:47:12 -08:00
{
scrFunctionResult . v . oval = psStruct ;
if ( ! stackPushResult ( ( INTERP_TYPE ) ST_STRUCTURE , & scrFunctionResult ) ) // push scrFunctionResult
{
2008-03-24 09:51:17 -07:00
return false ;
2007-01-04 13:47:12 -08:00
}
enumStructCountB [ bucket ] + + ;
2008-03-24 09:51:17 -07:00
return true ;
2007-01-04 13:47:12 -08:00
}
enumStructCountB [ bucket ] + + ;
psStruct = psStruct - > psNext ;
}
// push NULL, none found;
scrFunctionResult . v . oval = NULL ;
if ( ! stackPushResult ( ( INTERP_TYPE ) ST_STRUCTURE , & scrFunctionResult ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-01-04 13:47:12 -08:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-01-04 13:47:12 -08:00
}
2007-06-28 10:47:08 -07:00
// -----------------------------------------------------------------------------------------
/*looks to see if a structure (specified by type) exists and is being built*/
2011-03-12 17:32:15 -08:00
bool scrStructureBeingBuilt ( void )
2007-06-28 10:47:08 -07:00
{
UDWORD structInc ;
STRUCTURE_STATS * psStats ;
SDWORD player ;
2011-03-12 17:32:15 -08:00
bool beingBuilt ;
2007-06-28 10:47:08 -07:00
if ( ! stackPopParams ( 2 , ST_STRUCTURESTAT , & structInc , VAL_INT , & player ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
ASSERT_OR_RETURN ( false , structInc < numStructureStats , " Invalid range referenced for numStructureStats, %d > %d " , structInc , numStructureStats ) ;
2007-06-28 10:47:08 -07:00
psStats = ( STRUCTURE_STATS * ) ( asStructureStats + structInc ) ;
2008-03-24 09:51:17 -07:00
beingBuilt = false ;
2007-06-28 10:47:08 -07:00
if ( checkStructureStatus ( psStats , player , SS_BEING_BUILT ) )
{
2008-03-24 09:51:17 -07:00
beingBuilt = true ;
2007-06-28 10:47:08 -07:00
}
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . bval = beingBuilt ;
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2006-05-27 09:37:17 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// multiplayer skirmish only for now.
2008-03-24 09:51:17 -07:00
// returns true if a specific struct is complete. I know it's like the previous func,
2011-03-12 17:32:15 -08:00
bool scrStructureComplete ( void )
2007-06-28 10:47:08 -07:00
{
STRUCTURE * psStruct ;
2011-03-12 17:32:15 -08:00
bool bResult ;
2006-08-26 08:50:47 -07:00
2007-06-28 10:47:08 -07:00
if ( ! stackPopParams ( 1 , ST_STRUCTURE , & psStruct ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
if ( psStruct - > status = = SS_BUILT )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
bResult = true ;
2007-06-28 10:47:08 -07:00
}
else
{
2008-03-24 09:51:17 -07:00
bResult = false ;
2007-06-28 10:47:08 -07:00
}
2006-11-16 06:30:29 -08:00
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . bval = bResult ;
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2006-05-27 09:37:17 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
/*looks to see if a structure (specified by type) exists and built*/
2011-03-12 17:32:15 -08:00
bool scrStructureBuilt ( void )
2007-06-28 10:47:08 -07:00
{
UDWORD structInc ;
STRUCTURE_STATS * psStats ;
SDWORD player ;
2011-03-12 17:32:15 -08:00
bool built ;
2007-06-28 10:47:08 -07:00
if ( ! stackPopParams ( 2 , ST_STRUCTURESTAT , & structInc , VAL_INT , & player ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
ASSERT_OR_RETURN ( false , structInc < numStructureStats , " Invalid range referenced for numStructureStats, %d > %d " , structInc , numStructureStats ) ;
2007-06-28 10:47:08 -07:00
psStats = ( STRUCTURE_STATS * ) ( asStructureStats + structInc ) ;
2008-03-24 09:51:17 -07:00
built = false ;
2007-06-28 10:47:08 -07:00
if ( checkStructureStatus ( psStats , player , SS_BUILT ) )
{
2008-03-24 09:51:17 -07:00
built = true ;
2007-06-28 10:47:08 -07:00
}
2006-11-16 06:30:29 -08:00
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . bval = built ;
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
/*centre the view on an object - can be droid/structure or feature */
2011-03-12 17:32:15 -08:00
bool scrCentreView ( void )
2007-06-28 10:47:08 -07:00
{
BASE_OBJECT * psObj ;
if ( ! stackPopParams ( 1 , ST_BASEOBJECT , & psObj ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
if ( psObj = = NULL )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " NULL object " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
//centre the view on the objects x/y
2008-03-24 09:51:17 -07:00
setViewPos ( map_coord ( psObj - > pos . x ) , map_coord ( psObj - > pos . y ) , false ) ;
2007-06-28 10:47:08 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
/*centre the view on a position */
2011-03-12 17:32:15 -08:00
bool scrCentreViewPos ( void )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD x , y ;
2007-06-28 10:47:08 -07:00
if ( ! stackPopParams ( 2 , VAL_INT , & x , VAL_INT , & y ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
if ( ( x < 0 ) | | ( x > = ( SDWORD ) mapWidth * TILE_UNITS ) | |
( y < 0 ) | | ( y > = ( SDWORD ) mapHeight * TILE_UNITS ) )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " coords off map " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
//centre the view on the objects x/y
2008-03-24 09:51:17 -07:00
setViewPos ( map_coord ( x ) , map_coord ( y ) , false ) ;
2007-06-28 10:47:08 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
2010-02-08 12:02:06 -08:00
static STRUCTURE * unbuiltIter = NULL ;
static int unbuiltPlayer = - 1 ;
2011-03-12 17:32:15 -08:00
bool scrEnumUnbuilt ( void )
2010-02-08 12:02:06 -08:00
{
if ( ! stackPopParams ( 1 , VAL_INT , & unbuiltPlayer ) )
{
return false ;
}
ASSERT_OR_RETURN ( false , unbuiltPlayer < MAX_PLAYERS & & unbuiltPlayer > = 0 , " Player number %d out of bounds " , unbuiltPlayer ) ;
unbuiltIter = apsStructLists [ unbuiltPlayer ] ;
return true ;
}
2011-03-12 17:32:15 -08:00
bool scrIterateUnbuilt ( void )
2010-02-08 12:02:06 -08:00
{
2012-12-16 12:03:00 -08:00
for ( ; unbuiltIter & & unbuiltIter - > status ! = SS_BEING_BUILT ; unbuiltIter = unbuiltIter - > psNext )
{
;
}
2010-02-08 12:02:06 -08:00
scrFunctionResult . v . oval = unbuiltIter ;
if ( unbuiltIter )
{
unbuiltIter = unbuiltIter - > psNext ; // proceed to next, so we do not report same twice (or infinitely loop)
}
if ( ! stackPushResult ( ( INTERP_TYPE ) ST_STRUCTURE , & scrFunctionResult ) )
{
return false ;
}
return true ;
}
2007-06-28 10:47:08 -07:00
// -----------------------------------------------------------------------------------------
// Get a pointer to a structure based on a stat - returns NULL if cannot find one
2011-03-12 17:32:15 -08:00
bool scrGetStructure ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD player , index ;
STRUCTURE * psStruct ;
UDWORD structType ;
2011-03-12 17:32:15 -08:00
bool found ;
2007-06-28 10:47:08 -07:00
if ( ! stackPopParams ( 2 , ST_STRUCTURESTAT , & index , VAL_INT , & player ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2007-06-28 10:47:08 -07:00
structType = asStructureStats [ index ] . ref ;
//search the players' list of built structures to see if one exists
2008-03-24 09:51:17 -07:00
found = false ;
2006-05-27 09:37:17 -07:00
for ( psStruct = apsStructLists [ player ] ; psStruct ! = NULL ; psStruct =
2012-12-16 12:03:00 -08:00
psStruct - > psNext )
2007-06-28 10:47:08 -07:00
{
if ( psStruct - > pStructureType - > ref = = structType )
{
2008-03-24 09:51:17 -07:00
found = true ;
2007-06-28 10:47:08 -07:00
break ;
}
}
//make sure pass NULL back if not got one
if ( ! found )
{
psStruct = NULL ;
}
2006-05-27 09:37:17 -07:00
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . oval = psStruct ;
if ( ! stackPushResult ( ( INTERP_TYPE ) ST_STRUCTURE , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// Get a pointer to a template based on a component stat - returns NULL if cannot find one
2011-03-12 17:32:15 -08:00
bool scrGetTemplate ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD player ;
DROID_TEMPLATE * psTemplate ;
2011-03-12 17:32:15 -08:00
bool found ;
2007-06-28 10:47:08 -07:00
INTERP_VAL sVal ;
UDWORD i ;
if ( ! stackPopParams ( 1 , VAL_INT , & player ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2007-06-28 10:47:08 -07:00
if ( ! stackPop ( & sVal ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
//search the players' list of templates to see if one exists
2008-03-24 09:51:17 -07:00
found = false ;
2006-05-27 09:37:17 -07:00
for ( psTemplate = apsDroidTemplates [ player ] ; psTemplate ! = NULL ; psTemplate =
2012-12-16 12:03:00 -08:00
psTemplate - > psNext )
2007-06-28 10:47:08 -07:00
{
2010-12-21 15:58:59 -08:00
switch ( ( unsigned ) sVal . type ) // Unsigned cast to suppress compiler warnings due to enum abuse.
2007-06-28 10:47:08 -07:00
{
case ST_BODY :
if ( psTemplate - > asParts [ COMP_BODY ] = = sVal . v . ival )
{
2008-03-24 09:51:17 -07:00
found = true ;
2007-06-28 10:47:08 -07:00
}
break ;
case ST_PROPULSION :
if ( psTemplate - > asParts [ COMP_PROPULSION ] = = sVal . v . ival )
{
2008-03-24 09:51:17 -07:00
found = true ;
2007-06-28 10:47:08 -07:00
}
break ;
case ST_ECM :
if ( psTemplate - > asParts [ COMP_ECM ] = = sVal . v . ival )
{
2008-03-24 09:51:17 -07:00
found = true ;
2007-06-28 10:47:08 -07:00
}
break ;
case ST_SENSOR :
if ( psTemplate - > asParts [ COMP_SENSOR ] = = sVal . v . ival )
{
2008-03-24 09:51:17 -07:00
found = true ;
2007-06-28 10:47:08 -07:00
}
break ;
case ST_CONSTRUCT :
if ( psTemplate - > asParts [ COMP_CONSTRUCT ] = = sVal . v . ival )
{
2008-03-24 09:51:17 -07:00
found = true ;
2007-06-28 10:47:08 -07:00
}
break ;
case ST_REPAIR :
if ( psTemplate - > asParts [ COMP_REPAIRUNIT ] = = sVal . v . ival )
{
2008-03-24 09:51:17 -07:00
found = true ;
2007-06-28 10:47:08 -07:00
}
break ;
case ST_WEAPON :
2012-12-16 12:03:00 -08:00
for ( i = 0 ; i < DROID_MAXWEAPS ; i + + )
2007-06-28 10:47:08 -07:00
{
if ( psTemplate - > asWeaps [ i ] = = ( UDWORD ) sVal . v . ival )
{
2008-03-24 09:51:17 -07:00
found = true ;
2007-06-28 10:47:08 -07:00
break ;
}
}
break ;
default :
2012-12-16 12:03:00 -08:00
ASSERT ( false , " Unknown type " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
if ( found )
{
break ;
}
}
//make sure pass NULL back if not got one
if ( ! found )
{
psTemplate = NULL ;
}
2006-05-27 09:37:17 -07:00
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . oval = psTemplate ;
if ( ! stackPushResult ( ( INTERP_TYPE ) ST_TEMPLATE , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// Get a pointer to a droid based on a component stat - returns NULL if cannot find one
2011-03-12 17:32:15 -08:00
bool scrGetDroid ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD player ;
DROID * psDroid ;
2011-03-12 17:32:15 -08:00
bool found ;
2007-06-28 10:47:08 -07:00
INTERP_VAL sVal ;
UDWORD i ;
if ( ! stackPopParams ( 1 , VAL_INT , & player ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2007-06-28 10:47:08 -07:00
if ( ! stackPop ( & sVal ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
//search the players' list of droid to see if one exists
2008-03-24 09:51:17 -07:00
found = false ;
2006-05-27 09:37:17 -07:00
for ( psDroid = apsDroidLists [ player ] ; psDroid ! = NULL ; psDroid =
2012-12-16 12:03:00 -08:00
psDroid - > psNext )
2007-06-28 10:47:08 -07:00
{
2010-12-21 15:58:59 -08:00
switch ( ( unsigned ) sVal . type ) // Unsigned cast to suppress compiler warnings due to enum abuse.
2007-06-28 10:47:08 -07:00
{
case ST_BODY :
2013-05-09 04:24:19 -07:00
if ( psDroid - > asBits [ COMP_BODY ] = = ( UDWORD ) sVal . v . ival )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
found = true ;
2007-06-28 10:47:08 -07:00
}
break ;
case ST_PROPULSION :
2013-05-09 04:24:19 -07:00
if ( psDroid - > asBits [ COMP_PROPULSION ] = = ( UDWORD ) sVal . v . ival )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
found = true ;
2007-06-28 10:47:08 -07:00
}
break ;
case ST_ECM :
2013-05-09 04:24:19 -07:00
if ( psDroid - > asBits [ COMP_ECM ] = = ( UDWORD ) sVal . v . ival )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
found = true ;
2007-06-28 10:47:08 -07:00
}
break ;
case ST_SENSOR :
2013-05-09 04:24:19 -07:00
if ( psDroid - > asBits [ COMP_SENSOR ] = = ( UDWORD ) sVal . v . ival )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
found = true ;
2007-06-28 10:47:08 -07:00
}
break ;
case ST_CONSTRUCT :
2013-05-09 04:24:19 -07:00
if ( psDroid - > asBits [ COMP_CONSTRUCT ] = = ( UDWORD ) sVal . v . ival )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
found = true ;
2007-06-28 10:47:08 -07:00
}
break ;
case ST_REPAIR :
2013-05-09 04:24:19 -07:00
if ( psDroid - > asBits [ COMP_REPAIRUNIT ] = = ( UDWORD ) sVal . v . ival )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
found = true ;
2007-06-28 10:47:08 -07:00
}
break ;
case ST_WEAPON :
2012-12-16 12:03:00 -08:00
for ( i = 0 ; i < DROID_MAXWEAPS ; i + + )
2007-06-28 10:47:08 -07:00
{
if ( psDroid - > asWeaps [ i ] . nStat = = ( UDWORD ) sVal . v . ival )
{
2008-03-24 09:51:17 -07:00
found = true ;
2007-06-28 10:47:08 -07:00
break ;
}
}
break ;
default :
2012-12-16 12:03:00 -08:00
ASSERT ( false , " Unknown type " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
if ( found )
{
break ;
}
}
//make sure pass NULL back if not got one
if ( ! found )
{
psDroid = NULL ;
}
2006-05-27 09:37:17 -07:00
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . oval = psDroid ;
if ( ! stackPushResult ( ( INTERP_TYPE ) ST_DROID , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// Sets all the scroll params for the map
2011-03-12 17:32:15 -08:00
bool scrSetScrollParams ( void )
2007-06-28 10:47:08 -07:00
{
2008-02-09 08:10:10 -08:00
SDWORD minX , minY , maxX , maxY , prevMinX , prevMinY , prevMaxX , prevMaxY ;
2007-06-28 10:47:08 -07:00
if ( ! stackPopParams ( 4 , VAL_INT , & minX , VAL_INT , & minY , VAL_INT , & maxX , VAL_INT , & maxY ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2007-10-29 15:23:40 -07:00
// check that the values entered are valid
ASSERT ( minX > = 0 , " Minimum scroll x value %d is less than zero - " , minX ) ;
ASSERT ( minY > = 0 , " Minimum scroll y value %d is less than zero - " , minY ) ;
ASSERT ( maxX < = mapWidth , " Maximum scroll x value %d is greater than mapWidth %d " , maxX , ( int ) mapWidth ) ;
ASSERT ( maxY < = mapHeight , " Maximum scroll y value %d is greater than mapHeight %d " , maxY , ( int ) mapHeight ) ;
2007-06-28 10:47:08 -07:00
2008-02-09 08:10:10 -08:00
prevMinX = scrollMinX ;
prevMinY = scrollMinY ;
prevMaxX = scrollMaxX ;
prevMaxY = scrollMaxY ;
2007-06-28 10:47:08 -07:00
scrollMinX = minX ;
scrollMaxX = maxX ;
scrollMinY = minY ;
scrollMaxY = maxY ;
2008-02-09 08:10:10 -08:00
// When the scroll limits change midgame - need to redo the lighting
initLighting ( prevMinX < scrollMinX ? prevMinX : scrollMinX ,
2012-12-16 12:03:00 -08:00
prevMinY < scrollMinY ? prevMinY : scrollMinY ,
prevMaxX < scrollMaxX ? prevMaxX : scrollMaxX ,
prevMaxY < scrollMaxY ? prevMaxY : scrollMaxY ) ;
2009-05-15 20:33:49 -07:00
// need to reset radar to take into account of new size
resizeRadar ( ) ;
2007-06-28 10:47:08 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// Sets the scroll minX separately for the map
2011-03-12 17:32:15 -08:00
bool scrSetScrollMinX ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD minX , prevMinX ;
if ( ! stackPopParams ( 1 , VAL_INT , & minX ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
//check the value entered are valid
if ( minX < 0 )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " Minimum scroll x value %d is less than zero - " , minX ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2009-05-15 20:33:49 -07:00
prevMinX = scrollMinX ;
scrollMinX = minX ;
2007-06-28 10:47:08 -07:00
2009-05-15 20:33:49 -07:00
//when the scroll limits change midgame - need to redo the lighting
initLighting ( prevMinX < scrollMinX ? prevMinX : scrollMinX ,
2012-12-16 12:03:00 -08:00
scrollMinY , scrollMaxX , scrollMaxY ) ;
2007-06-28 10:47:08 -07:00
2009-05-15 20:33:49 -07:00
// need to reset radar to take into account of new size
resizeRadar ( ) ;
2007-06-28 10:47:08 -07:00
2009-05-15 20:33:49 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// Sets the scroll minY separately for the map
2011-03-12 17:32:15 -08:00
bool scrSetScrollMinY ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD minY , prevMinY ;
if ( ! stackPopParams ( 1 , VAL_INT , & minY ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
//check the value entered are valid
if ( minY < 0 )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " Minimum scroll y value %d is less than zero - " , minY ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2009-05-15 20:33:49 -07:00
prevMinY = scrollMinY ;
2007-06-28 10:47:08 -07:00
scrollMinY = minY ;
2009-05-15 20:33:49 -07:00
//when the scroll limits change midgame - need to redo the lighting
initLighting ( scrollMinX ,
2012-12-16 12:03:00 -08:00
prevMinY < scrollMinY ? prevMinY : scrollMinY ,
scrollMaxX , scrollMaxY ) ;
2009-05-15 20:33:49 -07:00
// need to reset radar to take into account of new size
resizeRadar ( ) ;
2007-06-28 10:47:08 -07:00
2009-05-15 20:33:49 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// Sets the scroll maxX separately for the map
2011-03-12 17:32:15 -08:00
bool scrSetScrollMaxX ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD maxX , prevMaxX ;
if ( ! stackPopParams ( 1 , VAL_INT , & maxX ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
//check the value entered are valid
if ( maxX > ( SDWORD ) mapWidth )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " Maximum scroll x value %d is greater than mapWidth - " , maxX ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2009-05-15 20:33:49 -07:00
prevMaxX = scrollMaxX ;
2007-06-28 10:47:08 -07:00
scrollMaxX = maxX ;
2009-05-15 20:33:49 -07:00
//when the scroll limits change midgame - need to redo the lighting
initLighting ( scrollMinX , scrollMinY ,
2012-12-16 12:03:00 -08:00
prevMaxX < scrollMaxX ? prevMaxX : scrollMaxX ,
scrollMaxY ) ;
2007-06-28 10:47:08 -07:00
2009-05-15 20:33:49 -07:00
// need to reset radar to take into account of new size
resizeRadar ( ) ;
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// Sets the scroll maxY separately for the map
2011-03-12 17:32:15 -08:00
bool scrSetScrollMaxY ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD maxY , prevMaxY ;
if ( ! stackPopParams ( 1 , VAL_INT , & maxY ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
//check the value entered are valid
if ( maxY > ( SDWORD ) mapHeight )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " Maximum scroll y value %d is greater than mapWidth - " , maxY ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2009-05-15 20:33:49 -07:00
prevMaxY = scrollMaxY ;
2007-06-28 10:47:08 -07:00
scrollMaxY = maxY ;
2009-05-15 20:33:49 -07:00
//when the scroll limits change midgame - need to redo the lighting
initLighting ( scrollMinX , scrollMinY , scrollMaxX ,
2012-12-16 12:03:00 -08:00
prevMaxY < scrollMaxY ? prevMaxY : scrollMaxY ) ;
2009-05-15 20:33:49 -07:00
// need to reset radar to take into account of new size
resizeRadar ( ) ;
2007-06-28 10:47:08 -07:00
2009-05-15 20:33:49 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// Sets which sensor will be used as the default for a player
2011-03-12 17:32:15 -08:00
bool scrSetDefaultSensor ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD player ;
UDWORD sensorInc ;
if ( ! stackPopParams ( 2 , ST_SENSOR , & sensorInc , VAL_INT , & player ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2007-06-28 10:47:08 -07:00
//check is a valid sensor Inc
if ( sensorInc > numSensorStats )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " Sensor Inc is too high - %d " , sensorInc ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
//check that this sensor is a default sensor
if ( asSensorStats [ sensorInc ] . location ! = LOC_DEFAULT )
{
2013-05-13 14:11:34 -07:00
ASSERT ( false , " This sensor is not a default one - %s " , getName ( & asSensorStats [ sensorInc ] ) ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
//assign since OK!
aDefaultSensor [ player ] = sensorInc ;
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// Sets which ECM will be used as the default for a player
2011-03-12 17:32:15 -08:00
bool scrSetDefaultECM ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD player ;
UDWORD ecmInc ;
if ( ! stackPopParams ( 2 , ST_ECM , & ecmInc , VAL_INT , & player ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2007-06-28 10:47:08 -07:00
//check is a valid ecmInc
if ( ecmInc > numECMStats )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " ECM Inc is too high - %d " , ecmInc ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
//check that this ecm is a default ecm
if ( asECMStats [ ecmInc ] . location ! = LOC_DEFAULT )
{
2013-05-13 14:11:34 -07:00
ASSERT ( false , " This ecm is not a default one - %s " , getName ( & asECMStats [ ecmInc ] ) ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
//assign since OK!
aDefaultECM [ player ] = ecmInc ;
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// Sets which RepairUnit will be used as the default for a player
2011-03-12 17:32:15 -08:00
bool scrSetDefaultRepair ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD player ;
UDWORD repairInc ;
if ( ! stackPopParams ( 2 , ST_REPAIR , & repairInc , VAL_INT , & player ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2007-06-28 10:47:08 -07:00
//check is a valid repairInc
if ( repairInc > numRepairStats )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " Repair Inc is too high - %d " , repairInc ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
//check that this repair is a default repair
if ( asRepairStats [ repairInc ] . location ! = LOC_DEFAULT )
{
2013-05-13 14:11:34 -07:00
ASSERT ( false , " This repair is not a default one - %s " , getName ( & asRepairStats [ repairInc ] ) ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
//assign since OK!
aDefaultRepair [ player ] = repairInc ;
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// Sets the structure limits for a player
2011-03-12 17:32:15 -08:00
bool scrSetStructureLimits ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD player , limit ;
UDWORD structInc ;
STRUCTURE_LIMITS * psStructLimits ;
if ( ! stackPopParams ( 3 , ST_STRUCTURESTAT , & structInc , VAL_INT , & limit , VAL_INT , & player ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2007-06-28 10:47:08 -07:00
if ( structInc > numStructureStats )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " Structure stat is too high - %d " , structInc ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
if ( limit < 0 )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " limit is less than zero - %d " , limit ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
if ( limit > LOTS_OF )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " limit is too high - %d - must be less than %d " ,
limit , LOTS_OF ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
psStructLimits = asStructLimits [ player ] ;
2011-02-12 13:23:57 -08:00
psStructLimits [ structInc ] . limit = limit ;
2007-06-28 10:47:08 -07:00
2011-02-12 13:23:57 -08:00
psStructLimits [ structInc ] . globalLimit = limit ;
2007-06-28 10:47:08 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// multiplayer limit handler.
2011-03-12 17:32:15 -08:00
bool scrApplyLimitSet ( void )
2007-06-28 10:47:08 -07:00
{
applyLimitSet ( ) ;
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
2006-05-27 09:37:17 -07:00
// plays a sound for the specified player - only plays the sound if the
2007-06-28 10:47:08 -07:00
// specified player = selectedPlayer
2011-03-12 17:32:15 -08:00
bool scrPlaySound ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD player , soundID ;
if ( ! stackPopParams ( 2 , ST_SOUND , & soundID , VAL_INT , & player ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2007-06-28 10:47:08 -07:00
if ( player = = ( SDWORD ) selectedPlayer )
{
audio_QueueTrack ( soundID ) ;
2012-12-16 12:03:00 -08:00
if ( bInTutorial )
2007-06-28 10:47:08 -07:00
{
audio_QueueTrack ( ID_SOUND_OF_SILENCE ) ;
}
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
2006-05-27 09:37:17 -07:00
// plays a sound for the specified player - only plays the sound if the
2007-06-28 10:47:08 -07:00
// specified player = selectedPlayer - saves position
2011-03-12 17:32:15 -08:00
bool scrPlaySoundPos ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD player , soundID , iX , iY , iZ ;
if ( ! stackPopParams ( 5 , ST_SOUND , & soundID , VAL_INT , & player ,
2012-12-16 12:03:00 -08:00
VAL_INT , & iX , VAL_INT , & iY , VAL_INT , & iZ ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2007-06-28 10:47:08 -07:00
if ( player = = ( SDWORD ) selectedPlayer )
{
audio_QueueTrackPos ( soundID , iX , iY , iZ ) ;
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
/* add a text message to the top of the screen for the selected player*/
2011-03-12 17:32:15 -08:00
bool scrShowConsoleText ( void )
2007-06-28 10:47:08 -07:00
{
2006-11-03 13:35:50 -08:00
char * pText ;
2007-06-28 10:47:08 -07:00
SDWORD player ;
if ( ! stackPopParams ( 2 , ST_TEXTSTRING , & pText , VAL_INT , & player ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2006-05-27 09:37:17 -07:00
2007-06-28 10:47:08 -07:00
if ( player = = ( SDWORD ) selectedPlayer )
{
2008-03-24 09:51:17 -07:00
permitNewConsoleMessages ( true ) ;
2008-03-30 10:59:13 -07:00
addConsoleMessage ( pText , CENTRE_JUSTIFY , SYSTEM_MESSAGE ) ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
/* add a text message to the top of the screen for the selected player*/
2011-03-12 17:32:15 -08:00
bool scrAddConsoleText ( void )
2007-06-28 10:47:08 -07:00
{
2006-11-03 13:35:50 -08:00
char * pText ;
2007-06-28 10:47:08 -07:00
SDWORD player ;
if ( ! stackPopParams ( 2 , ST_TEXTSTRING , & pText , VAL_INT , & player ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2006-05-27 09:37:17 -07:00
2007-06-28 10:47:08 -07:00
if ( player = = ( SDWORD ) selectedPlayer )
{
2008-03-24 09:51:17 -07:00
permitNewConsoleMessages ( true ) ;
2012-12-16 12:03:00 -08:00
setConsolePermanence ( true , true ) ;
2008-03-30 10:59:13 -07:00
addConsoleMessage ( pText , CENTRE_JUSTIFY , SYSTEM_MESSAGE ) ;
2008-03-24 09:51:17 -07:00
permitNewConsoleMessages ( false ) ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
/* add a text message to the top of the screen for the selected player - without clearing whats there*/
2011-03-12 17:32:15 -08:00
bool scrTagConsoleText ( void )
2007-06-28 10:47:08 -07:00
{
2006-11-03 13:35:50 -08:00
char * pText ;
2007-06-28 10:47:08 -07:00
SDWORD player ;
if ( ! stackPopParams ( 2 , ST_TEXTSTRING , & pText , VAL_INT , & player ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2006-05-27 09:37:17 -07:00
2007-06-28 10:47:08 -07:00
if ( player = = ( SDWORD ) selectedPlayer )
{
2008-03-24 09:51:17 -07:00
permitNewConsoleMessages ( true ) ;
2012-12-16 12:03:00 -08:00
setConsolePermanence ( true , false ) ;
2008-03-30 10:59:13 -07:00
addConsoleMessage ( pText , CENTRE_JUSTIFY , SYSTEM_MESSAGE ) ;
2008-03-24 09:51:17 -07:00
permitNewConsoleMessages ( false ) ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
2011-03-12 17:32:15 -08:00
bool scrClearConsole ( void )
2007-06-28 10:47:08 -07:00
{
flushConsoleMessages ( ) ;
2008-03-24 09:51:17 -07:00
return ( true ) ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
//demo functions for turning the power on
2011-03-12 17:32:15 -08:00
bool scrTurnPowerOff ( void )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
//powerCalculated = false;
powerCalc ( false ) ;
2007-06-28 10:47:08 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
//demo functions for turning the power off
2011-03-12 17:32:15 -08:00
bool scrTurnPowerOn ( void )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
//powerCalculated = true;
powerCalc ( true ) ;
2007-06-28 10:47:08 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
//flags when the tutorial is over so that console messages can be turned on again
2011-03-12 17:32:15 -08:00
bool scrTutorialEnd ( void )
2007-06-28 10:47:08 -07:00
{
initConsoleMessages ( ) ;
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
//function to play a full-screen video in the middle of the game for the selected player
2011-03-12 17:32:15 -08:00
bool scrPlayVideo ( void )
2007-06-28 10:47:08 -07:00
{
2006-11-03 13:35:50 -08:00
char * pVideo , * pText ;
2007-06-28 10:47:08 -07:00
if ( ! stackPopParams ( 2 , ST_TEXTSTRING , & pVideo , ST_TEXTSTRING , & pText ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
seq_ClearSeqList ( ) ;
seq_AddSeqToList ( pVideo , NULL , pText , false ) ; // Arpzzzzzzzzzzzzzzzlksht!
seq_StartNextFullScreenVideo ( ) ;
2007-06-28 10:47:08 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
//checks to see if there are any droids for the specified player
2011-03-12 17:32:15 -08:00
bool scrAnyDroidsLeft ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD player ;
2011-03-12 17:32:15 -08:00
bool droidsLeft ;
2007-06-28 10:47:08 -07:00
if ( ! stackPopParams ( 1 , VAL_INT , & player ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2007-06-28 10:47:08 -07:00
//check the players list for any droid
2008-03-24 09:51:17 -07:00
droidsLeft = true ;
2007-06-28 10:47:08 -07:00
if ( apsDroidLists [ player ] = = NULL )
{
2008-03-24 09:51:17 -07:00
droidsLeft = false ;
2007-06-28 10:47:08 -07:00
}
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . bval = droidsLeft ;
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
//function to call when the game is over, plays a message then does game over stuff.
//
2011-03-12 17:32:15 -08:00
bool scrGameOverMessage ( void )
2007-06-28 10:47:08 -07:00
{
2011-03-19 18:52:25 -07:00
int32_t gameWon ; // was BOOL (int) ** see warning about conversion
2007-06-28 10:47:08 -07:00
MESSAGE * psMessage ;
2007-01-07 15:50:30 -08:00
MESSAGE_TYPE msgType ;
SDWORD player ;
2007-06-28 10:47:08 -07:00
VIEWDATA * psViewData ;
if ( ! stackPopParams ( 4 , ST_INTMESSAGE , & psViewData , VAL_INT , & msgType ,
2012-12-16 12:03:00 -08:00
VAL_INT , & player , VAL_BOOL , & gameWon ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2007-06-28 10:47:08 -07:00
2012-12-16 12:03:00 -08:00
if ( gameWon )
2008-04-03 09:50:05 -07:00
{
2012-12-16 12:03:00 -08:00
addConsoleMessage ( _ ( " YOU ARE VICTORIOUS! " ) , DEFAULT_JUSTIFY , SYSTEM_MESSAGE ) ;
2008-04-03 09:50:05 -07:00
}
else
{
2012-12-16 12:03:00 -08:00
addConsoleMessage ( _ ( " YOU WERE DEFEATED! " ) , DEFAULT_JUSTIFY , SYSTEM_MESSAGE ) ;
2008-04-03 09:50:05 -07:00
}
2007-07-16 03:08:00 -07:00
2007-06-28 10:47:08 -07:00
//create the message
2008-03-24 09:51:17 -07:00
psMessage = addMessage ( msgType , false , player ) ;
2007-06-28 10:47:08 -07:00
2012-12-16 12:03:00 -08:00
ASSERT ( msgType ! = MSG_PROXIMITY , " Bad message type (MSG_PROXIMITY) " ) ;
2007-06-28 10:47:08 -07:00
if ( psMessage )
{
//set the data
psMessage - > pViewData = ( MSG_VIEWDATA * ) psViewData ;
displayImmediateMessage ( psMessage ) ;
stopReticuleButtonFlash ( IDRET_INTEL_MAP ) ;
2008-10-08 11:24:19 -07:00
//we need to set this here so the VIDEO_QUIT callback is not called
setScriptWinLoseVideo ( ( UBYTE ) ( gameWon ? PLAY_WIN : PLAY_LOSE ) ) ;
2007-06-28 10:47:08 -07:00
}
2008-04-19 14:41:18 -07:00
debug ( LOG_MSG , " Game over message " ) ;
2007-06-28 10:47:08 -07:00
2012-12-16 12:03:00 -08:00
// this should be called when the video Quit is processed
// not always is tough, so better be sure
2008-04-03 09:50:05 -07:00
displayGameOver ( gameWon ) ;
2007-06-28 10:47:08 -07:00
2009-08-11 13:36:44 -07:00
if ( challengeActive )
{
2011-04-25 06:16:49 -07:00
updateChallenge ( gameWon ) ;
2009-08-11 13:36:44 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
//function to call when the game is over
2011-03-12 17:32:15 -08:00
bool scrGameOver ( void )
2007-06-28 10:47:08 -07:00
{
2011-03-19 18:52:25 -07:00
int32_t gameOver ; // was BOOL (int) ** see warning about conversion
2007-06-28 10:47:08 -07:00
if ( ! stackPopParams ( 1 , VAL_BOOL , & gameOver ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
/*this function will only be called with gameOver = true when at the end of
the game so we ' ll just hard - code what happens ! */
2007-06-28 10:47:08 -07:00
2012-12-16 12:03:00 -08:00
//don't want this in multiplayer...
if ( ! bMultiPlayer )
2007-06-28 10:47:08 -07:00
2012-12-16 12:03:00 -08:00
{
if ( gameOver = = true & & ! bInTutorial )
{
//we need to set this here so the VIDEO_QUIT callback is not called
setScriptWinLoseVideo ( PLAY_WIN ) ;
2007-06-28 10:47:08 -07:00
2012-12-16 12:03:00 -08:00
seq_ClearSeqList ( ) ;
2007-06-28 10:47:08 -07:00
2012-12-16 12:03:00 -08:00
seq_AddSeqToList ( " outro.ogg " , NULL , " outro.txa " , false ) ;
seq_StartNextFullScreenVideo ( ) ;
2007-06-28 10:47:08 -07:00
2012-12-16 12:03:00 -08:00
}
}
2007-06-28 10:47:08 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
2011-03-12 17:32:15 -08:00
bool scrAnyFactoriesLeft ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD player ;
2011-03-12 17:32:15 -08:00
bool bResult ;
2007-06-28 10:47:08 -07:00
STRUCTURE * psCurr ;
if ( ! stackPopParams ( 1 , VAL_INT , & player ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2007-06-28 10:47:08 -07:00
//check the players list for any structures
2008-03-24 09:51:17 -07:00
bResult = false ;
2012-12-16 12:03:00 -08:00
if ( apsStructLists [ player ] )
2007-06-28 10:47:08 -07:00
{
for ( psCurr = apsStructLists [ player ] ; psCurr ! = NULL ; psCurr = psCurr - > psNext )
{
2012-12-16 12:03:00 -08:00
if ( StructIsFactory ( psCurr ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
bResult = true ;
2007-06-28 10:47:08 -07:00
break ;
}
}
}
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . bval = bResult ;
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
//checks to see if there are any structures (except walls) for the specified player
2011-03-12 17:32:15 -08:00
bool scrAnyStructButWallsLeft ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD player ;
2011-03-12 17:32:15 -08:00
bool structuresLeft ;
2007-06-28 10:47:08 -07:00
STRUCTURE * psCurr ;
if ( ! stackPopParams ( 1 , VAL_INT , & player ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2007-06-28 10:47:08 -07:00
//check the players list for any structures
2011-12-11 09:12:21 -08:00
structuresLeft = false ;
for ( psCurr = apsStructLists [ player ] ; psCurr ! = NULL ; psCurr = psCurr - > psNext )
2007-06-28 10:47:08 -07:00
{
2011-12-11 09:12:21 -08:00
if ( psCurr - > pStructureType - > type ! = REF_WALL & & psCurr - > pStructureType - >
2012-12-16 12:03:00 -08:00
type ! = REF_WALLCORNER )
2011-12-11 09:12:21 -08:00
{
structuresLeft = true ;
break ;
2007-06-28 10:47:08 -07:00
}
}
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . bval = structuresLeft ;
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
//defines the background audio to play
2011-03-12 17:32:15 -08:00
bool scrPlayBackgroundAudio ( void )
2007-06-28 10:47:08 -07:00
{
2006-11-03 13:35:50 -08:00
char * pText ;
2007-06-28 10:47:08 -07:00
SDWORD iVol ;
if ( ! stackPopParams ( 2 , ST_TEXTSTRING , & pText , VAL_INT , & iVol ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-01-03 11:38:06 -08:00
audio_PlayStream ( pText , ( float ) iVol / 100.f , NULL , NULL ) ;
2007-06-28 10:47:08 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2006-05-27 09:37:17 -07:00
2007-06-28 10:47:08 -07:00
}
2011-03-12 17:32:15 -08:00
bool scrPlayIngameCDAudio ( void )
2007-06-28 10:47:08 -07:00
{
2008-06-21 08:40:56 -07:00
debug ( LOG_SOUND , " Script wanted music to start " ) ;
cdAudio_PlayTrack ( SONG_INGAME ) ;
2007-06-28 10:47:08 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
2011-03-12 17:32:15 -08:00
bool scrStopCDAudio ( void )
2007-06-28 10:47:08 -07:00
{
2008-06-21 08:40:56 -07:00
debug ( LOG_SOUND , " Script wanted music to stop " ) ;
cdAudio_Stop ( ) ;
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
2011-03-12 17:32:15 -08:00
bool scrPauseCDAudio ( void )
2007-06-28 10:47:08 -07:00
{
2008-06-21 08:40:56 -07:00
cdAudio_Pause ( ) ;
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
2011-03-12 17:32:15 -08:00
bool scrResumeCDAudio ( void )
2007-06-28 10:47:08 -07:00
{
2008-06-21 08:40:56 -07:00
cdAudio_Resume ( ) ;
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// set the retreat point for a player
2011-03-12 17:32:15 -08:00
bool scrSetRetreatPoint ( void )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD player , x , y ;
2007-06-28 10:47:08 -07:00
if ( ! stackPopParams ( 3 , VAL_INT , & player , VAL_INT , & x , VAL_INT , & y ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
if ( x < 0 | | x > = ( SDWORD ) mapWidth * TILE_UNITS | |
y < 0 | | y > = ( SDWORD ) mapHeight * TILE_UNITS )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " coords off map " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
asRunData [ player ] . sPos . x = x ;
asRunData [ player ] . sPos . y = y ;
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// set the retreat force level
2011-03-12 17:32:15 -08:00
bool scrSetRetreatForce ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD player , level , numDroids ;
DROID * psCurr ;
if ( ! stackPopParams ( 2 , VAL_INT , & player , VAL_INT , & level ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2007-06-28 10:47:08 -07:00
if ( level > 100 | | level < 0 )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " level out of range " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
// count up the current number of droids
numDroids = 0 ;
2012-12-16 12:03:00 -08:00
for ( psCurr = apsDroidLists [ player ] ; psCurr ; psCurr = psCurr - > psNext )
2007-06-28 10:47:08 -07:00
{
numDroids + = 1 ;
}
asRunData [ player ] . forceLevel = ( UBYTE ) ( level * numDroids / 100 ) ;
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// set the retreat leadership
2011-03-12 17:32:15 -08:00
bool scrSetRetreatLeadership ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD player , level ;
if ( ! stackPopParams ( 2 , VAL_INT , & player , VAL_INT , & level ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2007-06-28 10:47:08 -07:00
if ( level > 100 | | level < 0 )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " level out of range " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
asRunData [ player ] . leadership = ( UBYTE ) level ;
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// set the retreat point for a group
2011-03-12 17:32:15 -08:00
bool scrSetGroupRetreatPoint ( void )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD x , y ;
2007-06-28 10:47:08 -07:00
DROID_GROUP * psGroup ;
if ( ! stackPopParams ( 3 , ST_GROUP , & psGroup , VAL_INT , & x , VAL_INT , & y ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
if ( x < 0 | | x > = ( SDWORD ) mapWidth * TILE_UNITS | |
y < 0 | | y > = ( SDWORD ) mapHeight * TILE_UNITS )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " coords off map " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
psGroup - > sRunData . sPos . x = x ;
psGroup - > sRunData . sPos . y = y ;
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
2011-03-12 17:32:15 -08:00
bool scrSetGroupRetreatForce ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD level , numDroids ;
DROID_GROUP * psGroup ;
DROID * psCurr ;
if ( ! stackPopParams ( 2 , ST_GROUP , & psGroup , VAL_INT , & level ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
if ( level > 100 | | level < 0 )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " level out of range " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
// count up the current number of droids
numDroids = 0 ;
2012-12-16 12:03:00 -08:00
for ( psCurr = psGroup - > psList ; psCurr ; psCurr = psCurr - > psGrpNext )
2007-06-28 10:47:08 -07:00
{
numDroids + = 1 ;
}
psGroup - > sRunData . forceLevel = ( UBYTE ) ( level * numDroids / 100 ) ;
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// set the retreat health level
2011-03-12 17:32:15 -08:00
bool scrSetRetreatHealth ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD player , health ;
if ( ! stackPopParams ( 2 , VAL_INT , & player , VAL_INT , & health ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2007-06-28 10:47:08 -07:00
if ( health > 100 | | health < 0 )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " health out of range " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
asRunData [ player ] . healthLevel = ( UBYTE ) health ;
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
2011-03-12 17:32:15 -08:00
bool scrSetGroupRetreatHealth ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD health ;
DROID_GROUP * psGroup ;
if ( ! stackPopParams ( 2 , ST_GROUP , & psGroup , VAL_INT , & health ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
if ( health > 100 | | health < 0 )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " health out of range " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
psGroup - > sRunData . healthLevel = ( UBYTE ) health ;
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// set the retreat leadership
2011-03-12 17:32:15 -08:00
bool scrSetGroupRetreatLeadership ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD level ;
DROID_GROUP * psGroup ;
if ( ! stackPopParams ( 2 , ST_GROUP , & psGroup , VAL_INT , & level ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
if ( level > 100 | | level < 0 )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " level out of range " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
psGroup - > sRunData . leadership = ( UBYTE ) level ;
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
//start a Mission - the missionType is ignored now - gets it from the level data ***********
2011-03-12 17:32:15 -08:00
bool scrStartMission ( void )
2007-06-28 10:47:08 -07:00
{
2006-11-03 13:35:50 -08:00
char * pGame ;
2007-06-28 10:47:08 -07:00
SDWORD missionType ;
LEVEL_DATASET * psNewLevel ;
if ( ! stackPopParams ( 2 , VAL_INT , & missionType , ST_LEVEL , & pGame ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
//if (missionType > MISSION_NONE)
if ( missionType > LDS_NONE )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " Invalid Mission Type " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-05-25 06:46:49 -07:00
sstrcpy ( aLevelName , pGame ) ;
2007-06-28 10:47:08 -07:00
// find the level dataset
2008-04-27 08:27:39 -07:00
psNewLevel = levFindDataSet ( pGame ) ;
if ( psNewLevel = = NULL )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
debug ( LOG_FATAL , " scrStartMission: couldn't find level data " ) ;
2006-08-22 07:28:49 -07:00
abort ( ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
//set the mission rolling...
//nextMissionType = missionType;
nextMissionType = psNewLevel - > type ;
loopMissionState = LMS_CLEAROBJECTS ;
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
//set Snow (enable disable snow)
2011-03-12 17:32:15 -08:00
bool scrSetSnow ( void )
2007-06-28 10:47:08 -07:00
{
2011-03-19 18:52:25 -07:00
int32_t bState ; // was BOOL (int) ** see warning about conversion
2007-06-28 10:47:08 -07:00
if ( ! stackPopParams ( 1 , VAL_BOOL , & bState ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
if ( bState )
2007-06-28 10:47:08 -07:00
{
atmosSetWeatherType ( WT_SNOWING ) ;
}
else
{
atmosSetWeatherType ( WT_NONE ) ;
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
//set Rain (enable disable Rain)
2011-03-12 17:32:15 -08:00
bool scrSetRain ( void )
2007-06-28 10:47:08 -07:00
{
2011-03-19 18:52:25 -07:00
int32_t bState ; // was BOOL (int) ** see warning about conversion
2007-06-28 10:47:08 -07:00
if ( ! stackPopParams ( 1 , VAL_BOOL , & bState ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
if ( bState )
2007-06-28 10:47:08 -07:00
{
atmosSetWeatherType ( WT_RAINING ) ;
}
else
{
atmosSetWeatherType ( WT_NONE ) ;
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
//set Background Fog (replace fade out with fog)
2011-03-12 17:32:15 -08:00
bool scrSetBackgroundFog ( void )
2007-06-28 10:47:08 -07:00
{
2011-03-19 18:52:25 -07:00
int32_t bState ; // was BOOL (int) ** see warning about conversion
2007-06-28 10:47:08 -07:00
if ( ! stackPopParams ( 1 , VAL_BOOL , & bState ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2011-10-20 18:04:50 -07:00
// no-op
2007-06-28 10:47:08 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
//set Depth Fog (gradual fog from mid range to edge of world)
2011-03-12 17:32:15 -08:00
bool scrSetDepthFog ( void )
2007-06-28 10:47:08 -07:00
{
2011-03-19 18:52:25 -07:00
int32_t bState ; // was BOOL (int) ** see warning about conversion
2007-06-28 10:47:08 -07:00
if ( ! stackPopParams ( 1 , VAL_BOOL , & bState ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2011-10-20 18:04:50 -07:00
// no-op
2007-06-28 10:47:08 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
//set Mission Fog colour, may be modified by weather effects
2011-03-12 17:32:15 -08:00
bool scrSetFogColour ( void )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD red , green , blue ;
2007-11-25 15:06:24 -08:00
PIELIGHT scrFogColour ;
2007-06-28 10:47:08 -07:00
if ( ! stackPopParams ( 3 , VAL_INT , & red , VAL_INT , & green , VAL_INT , & blue ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2011-10-20 18:04:50 -07:00
scrFogColour . byte . r = red ;
scrFogColour . byte . g = green ;
scrFogColour . byte . b = blue ;
scrFogColour . byte . a = 255 ;
pie_SetFogColour ( scrFogColour ) ;
2007-06-28 10:47:08 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// test function to test variable references
2011-03-12 17:32:15 -08:00
bool scrRefTest ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD Num = 0 ;
2012-12-16 12:03:00 -08:00
if ( ! stackPopParams ( 1 , VAL_INT , Num ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
debug ( LOG_NEVER , " scrRefTest: num: %d \n " , Num ) ;
2007-06-28 10:47:08 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// is player a human or computer player? (multiplayer only)
2011-03-12 17:32:15 -08:00
bool scrIsHumanPlayer ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD player ;
if ( ! stackPopParams ( 1 , VAL_INT , & player ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . bval = isHumanPlayer ( player ) ;
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// Set an alliance between two players
2011-03-12 17:32:15 -08:00
bool scrCreateAlliance ( void )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD player1 , player2 ;
2007-06-28 10:47:08 -07:00
if ( ! stackPopParams ( 2 , VAL_INT , & player1 , VAL_INT , & player2 ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
if ( player1 < 0 | | player1 > = MAX_PLAYERS | |
2012-12-16 12:03:00 -08:00
player2 < 0 | | player2 > = MAX_PLAYERS )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " player out of range p1=%d p2=%d " , player1 , player2 ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
if ( bMultiPlayer )
2007-06-28 10:47:08 -07:00
{
2013-04-29 12:20:34 -07:00
if ( alliancesFixed ( game . alliance )
2012-12-16 12:03:00 -08:00
| | player1 > = game . maxPlayers | | player2 > = game . maxPlayers )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
}
2012-12-16 12:03:00 -08:00
formAlliance ( ( UBYTE ) player1 , ( UBYTE ) player2 , true , false , true ) ;
2007-06-28 10:47:08 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// offer an alliance
2011-03-12 17:32:15 -08:00
bool scrOfferAlliance ( void )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD player1 , player2 ;
2007-06-28 10:47:08 -07:00
if ( ! stackPopParams ( 2 , VAL_INT , & player1 , VAL_INT , & player2 ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2013-04-29 12:20:34 -07:00
if ( alliancesFixed ( game . alliance ) | |
2012-12-16 12:03:00 -08:00
player1 < 0 | | player1 > = MAX_PLAYERS | |
player2 < 0 | | player2 > = MAX_PLAYERS )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " player out of range p1=%d p2=%d " , player1 , player2 ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
requestAlliance ( ( UBYTE ) player1 , ( UBYTE ) player2 , true , true ) ;
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// Break an alliance between two players
2011-03-12 17:32:15 -08:00
bool scrBreakAlliance ( void )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD player1 , player2 ;
2007-06-28 10:47:08 -07:00
if ( ! stackPopParams ( 2 , VAL_INT , & player1 , VAL_INT , & player2 ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2011-01-12 10:43:53 -08:00
if ( player1 < 0 | | player1 > = MAX_PLAYERS | | player2 < 0 | | player2 > = MAX_PLAYERS )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " player out of range p1=%d p2=%d " , player1 , player2 ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
if ( bMultiPlayer )
2007-06-28 10:47:08 -07:00
{
2013-04-29 12:20:34 -07:00
if ( alliancesFixed ( game . alliance )
2012-12-16 12:03:00 -08:00
| | player1 > = game . maxPlayers | | player2 > = game . maxPlayers )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
breakAlliance ( player1 , player2 , true , true ) ;
2007-06-28 10:47:08 -07:00
}
else
{
2012-12-16 12:03:00 -08:00
breakAlliance ( player1 , player2 , false , true ) ;
2007-06-28 10:47:08 -07:00
}
2011-01-12 10:43:53 -08:00
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// Multiplayer relevant scriptfuncs
// returns true if 2 or more players are in alliance.
2011-03-12 17:32:15 -08:00
bool scrAllianceExists ( void )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
UDWORD i , j ;
for ( i = 0 ; i < MAX_PLAYERS ; i + + )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
for ( j = 0 ; j < MAX_PLAYERS ; j + + )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
if ( alliances [ i ] [ j ] = = ALLIANCE_FORMED )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
scrFunctionResult . v . bval = true ;
2006-11-19 12:50:02 -08:00
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
}
}
2008-03-24 09:51:17 -07:00
scrFunctionResult . v . bval = false ;
2006-11-19 12:50:02 -08:00
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
2011-03-12 17:32:15 -08:00
bool scrAllianceExistsBetween ( void )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
UDWORD i , j ;
2007-06-28 10:47:08 -07:00
2012-12-16 12:03:00 -08:00
if ( ! stackPopParams ( 2 , VAL_INT , & i , VAL_INT , & j ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2011-06-05 13:57:31 -07:00
if ( i < MAX_PLAYERS & & j < MAX_PLAYERS & & alliances [ i ] [ j ] = = ALLIANCE_FORMED )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
scrFunctionResult . v . bval = true ;
2006-11-19 12:50:02 -08:00
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
scrFunctionResult . v . bval = false ;
2006-11-19 12:50:02 -08:00
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
2011-03-12 17:32:15 -08:00
bool scrPlayerInAlliance ( void )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD player , j ;
2007-06-28 10:47:08 -07:00
if ( ! stackPopParams ( 1 , VAL_INT , & player ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2007-06-28 10:47:08 -07:00
2012-12-16 12:03:00 -08:00
for ( j = 0 ; j < MAX_PLAYERS ; j + + )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
if ( alliances [ player ] [ j ] = = ALLIANCE_FORMED )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
scrFunctionResult . v . bval = true ;
2006-11-19 12:50:02 -08:00
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
}
2008-03-24 09:51:17 -07:00
scrFunctionResult . v . bval = false ;
2006-11-19 12:50:02 -08:00
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// returns true if a single alliance is dominant.
2011-03-12 17:32:15 -08:00
bool scrDominatingAlliance ( void )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
UDWORD i , j ;
2007-06-28 10:47:08 -07:00
2012-12-16 12:03:00 -08:00
for ( i = 0 ; i < MAX_PLAYERS ; i + + )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
for ( j = 0 ; j < MAX_PLAYERS ; j + + )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
if ( isHumanPlayer ( j )
& & isHumanPlayer ( i )
& & i ! = j
& & alliances [ i ] [ j ] ! = ALLIANCE_FORMED )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
scrFunctionResult . v . bval = false ;
2006-11-19 12:50:02 -08:00
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
}
}
2008-03-24 09:51:17 -07:00
scrFunctionResult . v . bval = true ;
2006-11-19 12:50:02 -08:00
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
2011-03-12 17:32:15 -08:00
bool scrMyResponsibility ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD player ;
if ( ! stackPopParams ( 1 , VAL_INT , & player ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
if ( myResponsibility ( player ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
scrFunctionResult . v . bval = true ;
2006-11-19 12:50:02 -08:00
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
}
else
{
2008-03-24 09:51:17 -07:00
scrFunctionResult . v . bval = false ;
2006-11-19 12:50:02 -08:00
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
}
2008-03-24 09:51:17 -07:00
return true ;
2006-05-27 09:37:17 -07:00
}
2007-06-28 10:47:08 -07:00
// -----------------------------------------------------------------------------------------
2010-01-22 04:06:02 -08:00
/**
* Checks to see if a structure of the type specified exists within the specified range of an XY location .
* Use player - 1 to find structures owned by any player . In this case , ignore if they are completed .
*/
2011-03-12 17:32:15 -08:00
bool scrStructureBuiltInRange ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD player , index , x , y , range ;
2010-01-22 04:06:02 -08:00
STRUCTURE * psStruct = NULL ;
2007-06-28 10:47:08 -07:00
STRUCTURE_STATS * psTarget ;
2010-01-22 04:06:02 -08:00
if ( ! stackPopParams ( 5 , ST_STRUCTURESTAT , & index , VAL_INT , & x , VAL_INT , & y , VAL_INT , & range , VAL_INT , & player ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2010-01-22 04:06:02 -08:00
ASSERT_OR_RETURN ( false , player < MAX_PLAYERS , " Player index out of bounds " ) ;
ASSERT_OR_RETURN ( false , x > = 0 & & map_coord ( x ) < mapWidth , " Invalid X coord " ) ;
ASSERT_OR_RETURN ( false , y > = 0 & & map_coord ( y ) < mapHeight , " Invalid Y coord " ) ;
ASSERT_OR_RETURN ( false , index > = 0 & & index < numStructureStats , " Invalid structure stat " ) ;
ASSERT_OR_RETURN ( false , range > = 0 , " Negative range " ) ;
2007-06-28 10:47:08 -07:00
2010-01-22 04:06:02 -08:00
// Now look through the players list of structures to see if this type exists within range
2007-06-28 10:47:08 -07:00
psTarget = & asStructureStats [ index ] ;
2010-01-22 04:06:02 -08:00
2013-02-09 03:33:00 -08:00
static GridList gridList ; // static to avoid allocations.
gridList = gridStartIterate ( x , y , range ) ;
for ( GridIterator gi = gridList . begin ( ) ; gi ! = gridList . end ( ) ; + + gi )
2007-06-28 10:47:08 -07:00
{
2013-02-09 03:33:00 -08:00
BASE_OBJECT * psCurr = * gi ;
2010-01-22 04:06:02 -08:00
if ( psCurr - > type = = OBJ_STRUCTURE )
2006-05-27 09:37:17 -07:00
{
2010-01-22 04:06:02 -08:00
psStruct = ( STRUCTURE * ) psCurr ;
if ( ( psStruct - > status = = SS_BUILT | | player = = - 1 )
& & ( player = = - 1 | | psStruct - > player = = player )
2013-05-12 14:50:57 -07:00
& & psStruct - > pStructureType - > id . compare ( psTarget - > id ) = = 0 )
2007-06-28 10:47:08 -07:00
{
2010-01-22 04:06:02 -08:00
break ;
2007-06-28 10:47:08 -07:00
}
}
2010-01-22 04:06:02 -08:00
psStruct = NULL ;
2007-06-28 10:47:08 -07:00
}
2006-05-27 09:37:17 -07:00
2010-01-22 04:06:02 -08:00
scrFunctionResult . v . oval = psStruct ;
2006-11-19 12:50:02 -08:00
if ( ! stackPushResult ( ( INTERP_TYPE ) ST_STRUCTURE , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// generate a random number
2011-03-12 17:32:15 -08:00
bool scrRandom ( void )
2007-06-28 10:47:08 -07:00
{
2006-11-16 06:30:29 -08:00
SDWORD range , iResult ;
2007-06-28 10:47:08 -07:00
if ( ! stackPopParams ( 1 , VAL_INT , & range ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
if ( range = = 0 )
{
2006-11-16 06:30:29 -08:00
iResult = 0 ;
2007-06-28 10:47:08 -07:00
}
else
{
2012-12-16 12:03:00 -08:00
iResult = rand ( ) % abs ( range ) ;
2007-06-28 10:47:08 -07:00
}
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . ival = iResult ;
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// randomise the random number seed
2011-03-12 17:32:15 -08:00
bool scrRandomiseSeed ( void )
2007-06-28 10:47:08 -07:00
{
2010-02-06 09:14:43 -08:00
// Why? What's the point? What on earth were they thinking, exactly? If the numbers don't have enough randominess, just set the random seed again and again until the numbers are double-plus super-duper full of randonomium?
debug ( LOG_ERROR , " A script is trying to set the random seed with srand(). That just doesn't make sense. " ) ;
//srand((UDWORD)clock());
2007-06-28 10:47:08 -07:00
2010-02-06 09:14:43 -08:00
// Resisting the urge to return a random number here. Afraid of triggering some sort of fallback mechanism in the scripts for when setting the random seed somehow fails.
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
//explicitly enables a research topic
2011-03-12 17:32:15 -08:00
bool scrEnableResearch ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD player ;
RESEARCH * psResearch ;
if ( ! stackPopParams ( 2 , ST_RESEARCH , & psResearch , VAL_INT , & player ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2013-03-11 15:30:18 -07:00
ASSERT_OR_RETURN ( false , psResearch , " Research topic specified not found " ) ;
2007-06-28 10:47:08 -07:00
if ( ! enableResearch ( psResearch , player ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
//acts as if the research topic was completed - used to jump into the tree
2011-03-12 17:32:15 -08:00
bool scrCompleteResearch ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD player ;
RESEARCH * psResearch ;
UDWORD researchIndex ;
if ( ! stackPopParams ( 2 , ST_RESEARCH , & psResearch , VAL_INT , & player ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2007-06-28 10:47:08 -07:00
2012-01-14 14:12:54 -08:00
if ( psResearch = = NULL )
2006-05-27 09:37:17 -07:00
{
2012-12-16 12:03:00 -08:00
// hack to make T2 and T3 work even though the research lists
2012-01-14 14:12:54 -08:00
// are polluted with tons of non-existent techs :(
return true ;
2007-06-28 10:47:08 -07:00
}
2011-12-02 05:26:37 -08:00
researchIndex = psResearch - > index ;
if ( researchIndex > asResearch . size ( ) )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " Invalid research index " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
if ( bMultiMessages & & ( gameTime > 2 ) )
2010-01-07 15:08:08 -08:00
{
2010-03-12 04:46:28 -08:00
SendResearch ( player , researchIndex , false ) ;
// Wait for our message before doing anything.
}
else
{
researchResult ( researchIndex , player , false , NULL , false ) ;
2010-01-07 15:08:08 -08:00
}
2007-06-28 10:47:08 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// This routine used to start just a reticule button flashing
// .. now it starts any button flashing (awaiting implmentation from widget library)
2011-03-12 17:32:15 -08:00
bool scrFlashOn ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD button ;
if ( ! stackPopParams ( 1 , VAL_INT , & button ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
// For the time being ... we will perform the old code for the reticule ...
if ( button > = IDRET_OPTIONS & & button < = IDRET_CANCEL )
{
flashReticuleButton ( ( UDWORD ) button ) ;
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
if ( widgGetFromID ( psWScreen , button ) ! = NULL )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
widgSetButtonFlash ( psWScreen , button ) ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// stop a generic button flashing
2011-03-12 17:32:15 -08:00
bool scrFlashOff ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD button ;
if ( ! stackPopParams ( 1 , VAL_INT , & button ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
if ( button > = IDRET_OPTIONS & & button < = IDRET_CANCEL )
{
stopReticuleButtonFlash ( ( UDWORD ) button ) ;
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
if ( widgGetFromID ( psWScreen , button ) ! = NULL )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
widgClearButtonFlash ( psWScreen , button ) ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
//set the initial power level settings for a player
2011-03-12 17:32:15 -08:00
bool scrSetPowerLevel ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD player , power ;
if ( ! stackPopParams ( 2 , VAL_INT , & power , VAL_INT , & player ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2006-05-27 09:37:17 -07:00
2009-04-08 07:31:22 -07:00
setPower ( player , power ) ;
2007-06-28 10:47:08 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
//add some power for a player
2011-03-12 17:32:15 -08:00
bool scrAddPower ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD player , power ;
if ( ! stackPopParams ( 2 , VAL_INT , & power , VAL_INT , & player ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2006-05-27 09:37:17 -07:00
2010-07-05 23:43:44 -07:00
giftPower ( ANYPLAYER , player , power , true ) ;
2007-06-28 10:47:08 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
2006-05-27 09:37:17 -07:00
/*set the landing Zone position for the map - this is for player 0. Can be
2007-06-28 10:47:08 -07:00
scrapped and replaced by setNoGoAreas , left in for compatibility */
2011-03-12 17:32:15 -08:00
bool scrSetLandingZone ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD x1 , x2 , y1 , y2 ;
if ( ! stackPopParams ( 4 , VAL_INT , & x1 , VAL_INT , & y1 , VAL_INT , & x2 , VAL_INT , & y2 ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
//check the values - check against max possible since can set in one mission for the next
if ( x1 > ( SDWORD ) MAP_MAXWIDTH )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " x1 is greater than max mapWidth " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
if ( x2 > ( SDWORD ) MAP_MAXWIDTH )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " x2 is greater than max mapWidth " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
if ( y1 > ( SDWORD ) MAP_MAXHEIGHT )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " y1 is greater than max mapHeight " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
if ( y2 > ( SDWORD ) MAP_MAXHEIGHT )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " y2 is greater than max mapHeight " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
//check won't overflow!
2007-02-10 08:39:39 -08:00
if ( x1 > UBYTE_MAX | | y1 > UBYTE_MAX | | x2 > UBYTE_MAX | | y2 > UBYTE_MAX )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " one coord is greater than %d " , UBYTE_MAX ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2011-06-21 12:04:46 -07:00
setNoGoArea ( ( UBYTE ) x1 , ( UBYTE ) y1 , ( UBYTE ) x2 , ( UBYTE ) y2 , 0 ) ;
2007-06-28 10:47:08 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
2006-05-27 09:37:17 -07:00
/*set the landing Zone position for the Limbo droids and adds the Limbo droids
2007-06-28 10:47:08 -07:00
to the world at the location */
2011-03-12 17:32:15 -08:00
bool scrSetLimboLanding ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD x1 , x2 , y1 , y2 ;
if ( ! stackPopParams ( 4 , VAL_INT , & x1 , VAL_INT , & y1 , VAL_INT , & x2 , VAL_INT , & y2 ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
//check the values - check against max possible since can set in one mission for the next
if ( x1 > ( SDWORD ) MAP_MAXWIDTH )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " x1 is greater than max mapWidth " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
if ( x2 > ( SDWORD ) MAP_MAXWIDTH )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " x2 is greater than max mapWidth " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
if ( y1 > ( SDWORD ) MAP_MAXHEIGHT )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " y1 is greater than max mapHeight " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
if ( y2 > ( SDWORD ) MAP_MAXHEIGHT )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " y2 is greater than max mapHeight " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
//check won't overflow!
2007-02-10 08:39:39 -08:00
if ( x1 > UBYTE_MAX | | y1 > UBYTE_MAX | | x2 > UBYTE_MAX | | y2 > UBYTE_MAX )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " one coord is greater than %d " , UBYTE_MAX ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
setNoGoArea ( ( UBYTE ) x1 , ( UBYTE ) y1 , ( UBYTE ) x2 , ( UBYTE ) y2 , LIMBO_LANDING ) ;
2011-06-21 12:04:46 -07:00
// this calls the Droids from the Limbo list onto the map
placeLimboDroids ( ) ;
2007-06-28 10:47:08 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
//initialises all the no go areas
2011-03-12 17:32:15 -08:00
bool scrInitAllNoGoAreas ( void )
2007-06-28 10:47:08 -07:00
{
initNoGoAreas ( ) ;
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
//set a no go area for the map - landing zones for the enemy, or player 0
2011-03-12 17:32:15 -08:00
bool scrSetNoGoArea ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD x1 , x2 , y1 , y2 , area ;
2006-05-27 09:37:17 -07:00
if ( ! stackPopParams ( 5 , VAL_INT , & x1 , VAL_INT , & y1 , VAL_INT , & x2 , VAL_INT , & y2 ,
2012-12-16 12:03:00 -08:00
VAL_INT , & area ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
if ( area = = LIMBO_LANDING )
{
ASSERT ( false , " Cannot set the Limbo Landing area with this function " ) ;
return false ;
}
2007-06-28 10:47:08 -07:00
//check the values - check against max possible since can set in one mission for the next
if ( x1 > ( SDWORD ) MAP_MAXWIDTH )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " x1 is greater than max mapWidth " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
if ( x2 > ( SDWORD ) MAP_MAXWIDTH )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " x2 is greater than max mapWidth " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
if ( y1 > ( SDWORD ) MAP_MAXHEIGHT )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " y1 is greater than max mapHeight " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
if ( y2 > ( SDWORD ) MAP_MAXHEIGHT )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " y2 is greater than max mapHeight " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
//check won't overflow!
2007-02-10 08:39:39 -08:00
if ( x1 > UBYTE_MAX | | y1 > UBYTE_MAX | | x2 > UBYTE_MAX | | y2 > UBYTE_MAX )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " one coord is greater than %d " , UBYTE_MAX ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
if ( area > = MAX_NOGO_AREAS )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " max num of areas is %d " , MAX_NOGO_AREAS ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
setNoGoArea ( ( UBYTE ) x1 , ( UBYTE ) y1 , ( UBYTE ) x2 , ( UBYTE ) y2 , ( UBYTE ) area ) ;
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// set the zoom level for the radar
2011-03-12 17:32:15 -08:00
bool scrSetRadarZoom ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD level ;
if ( ! stackPopParams ( 1 , VAL_INT , & level ) )
{
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
2011-07-18 17:41:39 -07:00
2007-06-28 10:47:08 -07:00
if ( level < 0 | | level > 2 )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " zoom level out of range " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
SetRadarZoom ( ( UWORD ) level ) ;
2011-07-18 17:41:39 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
//set how long an offworld mission can last -1 = no limit
2011-03-12 17:32:15 -08:00
bool scrSetMissionTime ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD time ;
if ( ! stackPopParams ( 1 , VAL_INT , & time ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
time * = 100 ;
//check not more than one hour - the mission timers cannot cope at present! - (visually)
//if (time > 60*60*GAME_TICKS_PER_SEC)
//check not more than 99 mins - the mission timers cannot cope at present! - (visually)
2012-12-16 12:03:00 -08:00
//we're allowing up to 5 hours now!
if ( time > 5 * 60 * 60 * GAME_TICKS_PER_SEC )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " The mission timer cannot be set to more than 99! " ) ;
2007-06-28 10:47:08 -07:00
time = - 1 ;
}
//store the value
mission . time = time ;
2012-12-16 12:03:00 -08:00
// ffs ab ... but shouldn't this be on the psx ?
setMissionCountDown ( ) ;
2007-06-28 10:47:08 -07:00
//add the timer to the interface
if ( mission . time > = 0 )
{
mission . startTime = gameTime ;
addMissionTimerInterface ( ) ;
}
2012-12-16 12:03:00 -08:00
else
{
//make sure its not up if setting to -1
intRemoveMissionTimer ( ) ;
//make sure the cheat time is not set
mission . cheatTime = 0 ;
}
2007-06-28 10:47:08 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// this returns how long is left for the current mission time is 1/100th sec - same units as passed in
2011-03-12 17:32:15 -08:00
bool scrMissionTimeRemaining ( void )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD timeRemaining ;
2007-06-28 10:47:08 -07:00
timeRemaining = mission . time - ( gameTime - mission . startTime ) ;
2012-12-16 12:03:00 -08:00
if ( timeRemaining < 0 )
{
timeRemaining = 0 ;
}
else
{
timeRemaining / = 100 ;
}
2007-06-28 10:47:08 -07:00
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . ival = timeRemaining ;
2012-12-16 12:03:00 -08:00
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return ( false ) ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return ( true ) ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
//set the time delay for reinforcements for an offworld mission
2011-03-12 17:32:15 -08:00
bool scrSetReinforcementTime ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD time ;
2012-12-16 12:03:00 -08:00
DROID * psDroid ;
2007-06-28 10:47:08 -07:00
if ( ! stackPopParams ( 1 , VAL_INT , & time ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
time * = 100 ;
2007-06-28 10:47:08 -07:00
//check not more than one hour - the mission timers cannot cope at present!
2012-12-16 12:03:00 -08:00
if ( time ! = LZ_COMPROMISED_TIME & & time > 60 * 60 * GAME_TICKS_PER_SEC )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " The transport timer cannot be set to more than 1 hour! " ) ;
2007-06-28 10:47:08 -07:00
time = - 1 ;
}
//store the value
mission . ETA = time ;
//if offworld or campaign change mission, then add the timer
2012-12-16 12:03:00 -08:00
if ( missionCanReEnforce ( ) )
2007-06-28 10:47:08 -07:00
{
addTransporterTimerInterface ( ) ;
}
2012-12-16 12:03:00 -08:00
//make sure the timer is not there if the reinforcement time has been set to < 0
if ( time < 0 )
{
2007-06-28 10:47:08 -07:00
2012-12-16 12:03:00 -08:00
intRemoveTransporterTimer ( ) ;
2007-06-28 10:47:08 -07:00
2012-12-16 12:03:00 -08:00
/*only remove the launch if haven't got a transporter droid since the
scripts set the time to - 1 at the between stage if there are not going
to be reinforcements on the submap */
for ( psDroid = apsDroidLists [ selectedPlayer ] ; psDroid ! = NULL ; psDroid =
psDroid - > psNext )
{
if ( psDroid - > droidType = = DROID_TRANSPORTER | | psDroid - > droidType = = DROID_SUPERTRANSPORTER )
{
break ;
}
}
//if not found a transporter, can remove the launch button
if ( psDroid = = NULL )
{
intRemoveTransporterLaunch ( ) ;
}
}
2007-06-28 10:47:08 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// Sets all structure limits for a player to a specified value
2011-03-12 17:32:15 -08:00
bool scrSetAllStructureLimits ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD player , limit ;
STRUCTURE_LIMITS * psStructLimits ;
UDWORD i ;
if ( ! stackPopParams ( 2 , VAL_INT , & limit , VAL_INT , & player ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2007-06-28 10:47:08 -07:00
if ( limit < 0 )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " limit is less than zero - %d " , limit ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
if ( limit > LOTS_OF )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " limit is too high - %d - must be less than %d " ,
limit , LOTS_OF ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
//set all the limits to the value specified
psStructLimits = asStructLimits [ player ] ;
for ( i = 0 ; i < numStructureStats ; i + + )
{
2011-02-12 13:23:57 -08:00
psStructLimits [ i ] . limit = limit ;
2007-06-28 10:47:08 -07:00
2011-02-12 13:23:57 -08:00
psStructLimits [ i ] . globalLimit = limit ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// clear all the console messages
2011-03-12 17:32:15 -08:00
bool scrFlushConsoleMessages ( void )
2007-06-28 10:47:08 -07:00
{
flushConsoleMessages ( ) ;
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// Establishes the distance between two points - uses an approximation
2012-12-16 12:03:00 -08:00
bool scrDistanceTwoPts ( void )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD x1 , y1 , x2 , y2 ;
2007-06-28 10:47:08 -07:00
2012-12-16 12:03:00 -08:00
if ( ! stackPopParams ( 4 , VAL_INT , & x1 , VAL_INT , & y1 , VAL_INT , & x2 , VAL_INT , & y2 ) )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " Distance between two points - cannot get parameters " ) ;
2008-03-24 09:51:17 -07:00
return ( false ) ;
2007-06-28 10:47:08 -07:00
}
/* Approximate the distance */
2008-10-14 13:25:41 -07:00
scrFunctionResult . v . ival = hypotf ( x1 - x2 , y1 - y2 ) ;
2012-12-16 12:03:00 -08:00
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " Distance between two points - cannot return scrFunctionResult " ) ;
2008-03-24 09:51:17 -07:00
return ( false ) ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return ( true ) ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// Returns whether two objects can see each other
2012-12-16 12:03:00 -08:00
bool scrLOSTwoBaseObjects ( void )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
BASE_OBJECT * psSource , * psDest ;
int32_t bWallsBlock ; // was BOOL (int) ** see warning about conversion
bool retVal ;
2007-06-28 10:47:08 -07:00
2012-12-16 12:03:00 -08:00
if ( ! stackPopParams ( 3 , ST_BASEOBJECT , & psSource , ST_BASEOBJECT , & psDest , VAL_BOOL , & bWallsBlock ) )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " Cannot get parameters " ) ;
2008-03-24 09:51:17 -07:00
return ( false ) ;
2007-06-28 10:47:08 -07:00
}
2008-06-18 15:23:47 -07:00
retVal = visibleObject ( psSource , psDest , bWallsBlock ) ;
2007-06-28 10:47:08 -07:00
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . bval = retVal ;
2012-12-16 12:03:00 -08:00
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " Cannot return scrFunctionResult " ) ;
2008-03-24 09:51:17 -07:00
return ( false ) ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return ( true ) ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// Destroys all structures within a certain bounding area.
2012-12-16 12:03:00 -08:00
bool scrDestroyStructuresInArea ( void )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD x1 , y1 , x2 , y2 ;
UDWORD typeRef ;
int player ;
STRUCTURE * psStructure , * psNextS ;
FEATURE * psFeature , * psNextF ;
int32_t bVisible , bTakeFeatures ; // was BOOL (int) ** see warning about conversion
SDWORD sX , sY ;
2007-06-28 10:47:08 -07:00
2012-12-16 12:03:00 -08:00
if ( ! stackPopParams ( 8 , VAL_INT , & player , VAL_INT , & typeRef , VAL_INT , & x1 , VAL_INT , & y1 , VAL_INT , & x2 ,
VAL_INT , & y2 , VAL_BOOL , & bVisible , VAL_BOOL , & bTakeFeatures ) )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " Cannot get parameters " ) ;
2008-03-24 09:51:17 -07:00
return ( false ) ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2006-05-27 09:37:17 -07:00
2012-12-16 12:03:00 -08:00
for ( psStructure = apsStructLists [ player ] ; psStructure ; psStructure = psNextS )
2007-06-28 10:47:08 -07:00
{
/* Keep a copy */
psNextS = psStructure - > psNext ;
2007-12-15 07:39:29 -08:00
sX = psStructure - > pos . x ;
sY = psStructure - > pos . y ;
2007-06-28 10:47:08 -07:00
2012-12-16 12:03:00 -08:00
if ( psStructure - > pStructureType - > type = = typeRef )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
if ( sX > = x1 & & sX < = x2 & & sY > = y1 & & sY < = y2 )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
if ( bVisible )
2007-06-28 10:47:08 -07:00
{
2010-02-26 04:03:29 -08:00
SendDestroyStructure ( psStructure ) ;
2007-06-28 10:47:08 -07:00
}
else
{
2008-03-24 09:51:17 -07:00
removeStruct ( psStructure , true ) ;
2006-05-27 09:37:17 -07:00
}
2007-06-28 10:47:08 -07:00
}
}
}
2012-12-16 12:03:00 -08:00
if ( bTakeFeatures )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
for ( psFeature = apsFeatureLists [ 0 ] ; psFeature ; psFeature = psNextF )
2007-06-28 10:47:08 -07:00
{
/* Keep a copy */
psNextF = psFeature - > psNext ;
2007-12-15 07:39:29 -08:00
sX = psFeature - > pos . x ;
sY = psFeature - > pos . y ;
2007-06-28 10:47:08 -07:00
2012-12-16 12:03:00 -08:00
if ( psFeature - > psStats - > subType = = FEAT_BUILDING )
// (psFeature->psStats->subType != FEAT_OIL_DRUM) &&
// (psFeature->psStats->subType != FEAT_OIL_RESOURCE) )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
if ( sX > = x1 & & sX < = x2 & & sY > = y1 & & sY < = y2 )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
if ( bVisible )
2007-06-28 10:47:08 -07:00
{
2011-12-28 05:42:41 -08:00
destroyFeature ( psFeature , gameTime ) ;
2007-06-28 10:47:08 -07:00
}
else
{
removeFeature ( psFeature ) ;
2006-05-27 09:37:17 -07:00
}
2007-06-28 10:47:08 -07:00
}
}
}
}
2008-03-24 09:51:17 -07:00
return ( true ) ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// Returns a value representing the threat from droids in a given area
2012-12-16 12:03:00 -08:00
bool scrThreatInArea ( void )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD x1 , y1 , x2 , y2 ;
SDWORD ldThreat , mdThreat , hdThreat ;
UDWORD playerLooking , playerTarget ;
SDWORD totalThreat ;
DROID * psDroid ;
SDWORD dX , dY ;
int32_t bVisible ; // was BOOL (int) ** see warning about conversion
2006-05-27 09:37:17 -07:00
2012-12-16 12:03:00 -08:00
if ( ! stackPopParams ( 10 , VAL_INT , & playerLooking , VAL_INT , & playerTarget , VAL_INT , & x1 , VAL_INT , & y1 , VAL_INT , & x2 , VAL_INT , & y2 ,
VAL_INT , & ldThreat , VAL_INT , & mdThreat , VAL_INT , & hdThreat , VAL_BOOL , & bVisible ) )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " Cannot get parameters " ) ;
2008-03-24 09:51:17 -07:00
return ( false ) ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
if ( playerLooking > = MAX_PLAYERS | | playerTarget > = MAX_PLAYERS )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " Player number too high " ) ;
2008-03-24 09:51:17 -07:00
return ( false ) ;
2007-06-28 10:47:08 -07:00
}
totalThreat = 0 ;
2012-12-16 12:03:00 -08:00
for ( psDroid = apsDroidLists [ playerTarget ] ; psDroid ; psDroid = psDroid - > psNext )
2007-06-28 10:47:08 -07:00
{
2008-01-05 11:42:43 -08:00
if ( ! objHasWeapon ( ( BASE_OBJECT * ) psDroid ) )
2007-06-28 10:47:08 -07:00
{
continue ;
}
2007-12-15 07:39:29 -08:00
dX = psDroid - > pos . x ;
dY = psDroid - > pos . y ;
2007-06-28 10:47:08 -07:00
/* Do we care if the droid is visible or not */
2012-12-16 12:03:00 -08:00
if ( bVisible ? psDroid - > visible [ playerLooking ] : true )
2007-06-28 10:47:08 -07:00
{
/* Have we found a droid in this area */
2012-12-16 12:03:00 -08:00
if ( dX > = x1 & & dX < = x2 & & dY > = y1 & & dY < = y2 )
2007-06-28 10:47:08 -07:00
{
2013-05-09 04:24:19 -07:00
switch ( ( asBodyStats + psDroid - > asBits [ COMP_BODY ] ) - > size )
2006-05-27 09:37:17 -07:00
{
2007-06-28 10:47:08 -07:00
case SIZE_LIGHT :
totalThreat + = ldThreat ;
break ;
case SIZE_MEDIUM :
totalThreat + = mdThreat ;
break ;
case SIZE_HEAVY :
case SIZE_SUPER_HEAVY :
totalThreat + = hdThreat ;
break ;
default :
2012-12-16 12:03:00 -08:00
ASSERT ( false , " Weird droid size in threat assessment " ) ;
2007-06-28 10:47:08 -07:00
break ;
}
}
}
}
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . ival = totalThreat ;
2012-12-16 12:03:00 -08:00
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " Cannot push scrFunctionResult " ) ;
2008-03-24 09:51:17 -07:00
return ( false ) ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return ( true ) ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// returns the nearest gateway bottleneck to a specified point
2012-12-16 12:03:00 -08:00
bool scrGetNearestGateway ( void )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD x , y ;
2006-12-16 06:59:50 -08:00
UDWORD nearestSoFar ;
UDWORD dist ;
GATEWAY * psGateway ;
2012-12-16 12:03:00 -08:00
SDWORD retX , retY ;
SDWORD * rX , * rY ;
2011-03-12 17:32:15 -08:00
bool success ;
2007-06-28 10:47:08 -07:00
2012-12-16 12:03:00 -08:00
if ( ! stackPopParams ( 4 , VAL_INT , & x , VAL_INT , & y , VAL_REF | VAL_INT , & rX , VAL_REF | VAL_INT , & rY ) )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " Cannot get parameters " ) ;
2008-03-24 09:51:17 -07:00
return ( false ) ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
if ( x < 0 | | x > ( SDWORD ) mapWidth | | y < 0 | | y > ( SDWORD ) mapHeight )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " Invalid coordinates " ) ;
2008-03-24 09:51:17 -07:00
return ( false ) ;
2007-06-28 10:47:08 -07:00
}
nearestSoFar = UDWORD_MAX ;
2009-12-15 14:04:01 -08:00
retX = retY = - 1 ;
2008-03-24 09:51:17 -07:00
success = false ;
2009-03-26 11:32:24 -07:00
for ( psGateway = gwGetGateways ( ) ; psGateway ; psGateway = psGateway - > psNext )
2007-06-28 10:47:08 -07:00
{
/* Get gateway midpoint */
2012-12-16 12:03:00 -08:00
const int gX = ( psGateway - > x1 + psGateway - > x2 ) / 2 ;
const int gY = ( psGateway - > y1 + psGateway - > y2 ) / 2 ;
2007-06-28 10:47:08 -07:00
/* Estimate the distance to it */
2008-10-14 13:25:41 -07:00
dist = hypotf ( x - gX , y - gY ) ;
2007-06-28 10:47:08 -07:00
/* Is it best we've found? */
2012-12-16 12:03:00 -08:00
if ( dist < nearestSoFar )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
success = true ;
2007-06-28 10:47:08 -07:00
/* Yes, then keep a record of it */
nearestSoFar = dist ;
retX = gX ;
retY = gY ;
}
}
* rX = retX ;
* rY = retY ;
2006-05-27 09:37:17 -07:00
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . bval = success ;
2012-12-16 12:03:00 -08:00
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " Cannot return scrFunctionResult " ) ;
2008-03-24 09:51:17 -07:00
return ( false ) ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return ( true ) ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
2011-03-12 17:32:15 -08:00
bool scrSetWaterTile ( void )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
UDWORD tileNum ;
2007-06-28 10:47:08 -07:00
2012-12-16 12:03:00 -08:00
if ( ! stackPopParams ( 1 , VAL_INT , & tileNum ) )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " Cannot get parameter " ) ;
2008-03-24 09:51:17 -07:00
return ( false ) ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
if ( tileNum > 96 )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " Water tile number too high " ) ;
2008-03-24 09:51:17 -07:00
return ( false ) ;
2007-06-28 10:47:08 -07:00
}
setUnderwaterTile ( tileNum ) ;
2008-03-24 09:51:17 -07:00
return ( true ) ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
2011-03-12 17:32:15 -08:00
bool scrSetRubbleTile ( void )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
UDWORD tileNum ;
2007-06-28 10:47:08 -07:00
2012-12-16 12:03:00 -08:00
if ( ! stackPopParams ( 1 , VAL_INT , & tileNum ) )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " Cannot get parameter " ) ;
2008-03-24 09:51:17 -07:00
return ( false ) ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
if ( tileNum > 96 )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " Rubble tile number too high in scrSetWaterTile " ) ;
2008-03-24 09:51:17 -07:00
return ( false ) ;
2007-06-28 10:47:08 -07:00
}
setRubbleTile ( tileNum ) ;
2008-03-24 09:51:17 -07:00
return ( true ) ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
2011-03-12 17:32:15 -08:00
bool scrSetCampaignNumber ( void )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
UDWORD campaignNumber ;
2007-06-28 10:47:08 -07:00
2012-12-16 12:03:00 -08:00
if ( ! stackPopParams ( 1 , VAL_INT , & campaignNumber ) )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " Cannot get parameter for scrSetCampaignNumber " ) ;
2008-03-24 09:51:17 -07:00
return ( false ) ;
2007-06-28 10:47:08 -07:00
}
setCampaignNumber ( campaignNumber ) ;
2008-03-24 09:51:17 -07:00
return ( true ) ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// Tests whether a structure has a certain module for a player. Tests whether any structure
// has this module if structure is null
2011-03-12 17:32:15 -08:00
bool scrTestStructureModule ( void )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD player , refId ;
STRUCTURE * psStructure , * psStruct ;
bool bFound ;
2007-06-28 10:47:08 -07:00
2012-12-16 12:03:00 -08:00
if ( ! stackPopParams ( 3 , VAL_INT , & player , ST_STRUCTURE , & psStructure , VAL_INT , & refId ) )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " SCRIPT : Cannot get parameters in scrTestStructureModule " ) ;
2008-03-24 09:51:17 -07:00
return ( false ) ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
if ( player > = MAX_PLAYERS )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " SCRIPT : Player number too high in scrTestStructureModule " ) ;
2008-03-24 09:51:17 -07:00
return ( false ) ;
2007-06-28 10:47:08 -07:00
}
/* Nothing yet */
2008-03-24 09:51:17 -07:00
bFound = false ;
2007-06-28 10:47:08 -07:00
/* Check the specified case first */
2012-12-16 12:03:00 -08:00
if ( psStructure )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
if ( structHasModule ( psStructure ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
bFound = true ;
2007-06-28 10:47:08 -07:00
}
}
/* psStructure was NULL - so test the general case */
else
{
// Search them all, but exit if we get one!!
2012-12-16 12:03:00 -08:00
for ( psStruct = apsStructLists [ player ] , bFound = false ;
psStruct & & ! bFound ; psStruct = psStruct - > psNext )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
if ( structHasModule ( psStruct ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
bFound = true ;
2007-06-28 10:47:08 -07:00
}
}
}
2006-11-19 12:50:02 -08:00
/* Send back the scrFunctionResult */
scrFunctionResult . v . bval = bFound ;
2012-12-16 12:03:00 -08:00
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " SCRIPT : Cannot push scrFunctionResult for scrTestStructureModule " ) ;
2008-03-24 09:51:17 -07:00
return ( false ) ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return ( true ) ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
2012-12-16 12:03:00 -08:00
bool scrForceDamage ( void )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
DROID * psDroid ;
STRUCTURE * psStructure ;
FEATURE * psFeature ;
BASE_OBJECT * psObj ;
UDWORD damagePercent ;
float divisor ;
UDWORD newVal ;
2007-06-28 10:47:08 -07:00
/* OK - let's get the vars */
2012-12-16 12:03:00 -08:00
if ( ! stackPopParams ( 2 , ST_BASEOBJECT , & psObj , VAL_INT , & damagePercent ) )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " Cannot pop params for scrForceDamage " ) ;
2008-03-24 09:51:17 -07:00
return ( false ) ;
2007-06-28 10:47:08 -07:00
}
/* Got to be a percent, so must be less than or equal to 100 */
2012-12-16 12:03:00 -08:00
if ( damagePercent > 100 )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrForceDamage : You're supposed to be passing in a PERCENTAGE VALUE, \
instead I got given % d , which is clearly no good , now is it ! ? " , damagePercent);
2008-03-24 09:51:17 -07:00
return ( false ) ;
2007-06-28 10:47:08 -07:00
}
/* Get percentage in range [0.1] */
2012-12-16 12:03:00 -08:00
divisor = ( float ) damagePercent / 100.f ;
2007-06-28 10:47:08 -07:00
/* See what we're dealing with */
2012-12-16 12:03:00 -08:00
switch ( psObj - > type )
2007-06-28 10:47:08 -07:00
{
case OBJ_DROID :
psDroid = ( DROID * ) psObj ;
2007-12-24 05:57:19 -08:00
newVal = divisor * psDroid - > originalBody ;
2007-06-28 10:47:08 -07:00
psDroid - > body = newVal ;
break ;
case OBJ_STRUCTURE :
psStructure = ( STRUCTURE * ) psObj ;
2007-12-24 05:57:19 -08:00
newVal = divisor * structureBody ( psStructure ) ;
2007-06-28 10:47:08 -07:00
psStructure - > body = ( UWORD ) newVal ;
break ;
case OBJ_FEATURE :
psFeature = ( FEATURE * ) psObj ;
/* Some features cannot be damaged */
2012-12-16 12:03:00 -08:00
if ( psFeature - > psStats - > damageable )
2007-06-28 10:47:08 -07:00
{
2007-12-24 05:57:19 -08:00
newVal = divisor * psFeature - > psStats - > body ;
2007-06-28 10:47:08 -07:00
psFeature - > body = newVal ;
}
break ;
default :
2012-12-16 12:03:00 -08:00
ASSERT ( false , " Unsupported base object type in scrForceDamage " ) ;
2008-03-24 09:51:17 -07:00
return ( false ) ;
2007-06-28 10:47:08 -07:00
break ;
}
2008-03-24 09:51:17 -07:00
return ( true ) ;
2007-06-28 10:47:08 -07:00
}
// Kills of a droid without spawning any explosion effects.
// -----------------------------------------------------------------------------------------
2012-12-16 12:03:00 -08:00
bool scrDestroyUnitsInArea ( void )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
DROID * psDroid , * psNext ;
SDWORD x1 , y1 , x2 , y2 ;
UDWORD player ;
UDWORD count = 0 ;
2007-06-28 10:47:08 -07:00
2012-12-16 12:03:00 -08:00
if ( ! stackPopParams ( 5 , VAL_INT , & x1 , VAL_INT , & y1 , VAL_INT , & x2 , VAL_INT , & y2 , VAL_INT , & player ) )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " Cannot get params for scrDestroyUnitsInArea " ) ;
2008-03-24 09:51:17 -07:00
return ( false ) ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
if ( player > = MAX_PLAYERS )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " Invalid player number in scrKillDroidsInArea " ) ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
for ( psDroid = apsDroidLists [ player ] ; psDroid ; psDroid = psNext )
2007-06-28 10:47:08 -07:00
{
psNext = psDroid - > psNext ; // get a copy cos pointer will be lost
2012-12-16 12:03:00 -08:00
if ( ( psDroid - > pos . x > x1 ) & & ( psDroid - > pos . x < x2 ) & &
( psDroid - > pos . y > y1 ) & & ( psDroid - > pos . y < y2 ) )
2007-06-28 10:47:08 -07:00
{
/* then it's inside the area */
2010-02-26 04:03:29 -08:00
SendDestroyDroid ( psDroid ) ;
2007-06-28 10:47:08 -07:00
count + + ;
}
}
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . ival = count ;
2012-12-16 12:03:00 -08:00
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return ( false ) ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return ( true ) ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
2012-12-16 12:03:00 -08:00
bool scrRemoveDroid ( void )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
DROID * psDroid ;
2006-05-27 09:37:17 -07:00
2012-12-16 12:03:00 -08:00
if ( ! stackPopParams ( 1 , ST_DROID , & psDroid ) )
{
ASSERT ( false , " Cannot get vars for scrRemoveDroid! " ) ;
2008-03-24 09:51:17 -07:00
return ( false ) ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
if ( psDroid )
2007-06-28 10:47:08 -07:00
{
vanishDroid ( psDroid ) ;
}
2008-03-24 09:51:17 -07:00
return ( true ) ;
2007-06-28 10:47:08 -07:00
}
2012-07-28 03:49:57 -07:00
2007-06-28 10:47:08 -07:00
// -----------------------------------------------------------------------------------------
2011-03-12 17:32:15 -08:00
static bool structHasModule ( STRUCTURE * psStruct )
2007-06-28 10:47:08 -07:00
{
2012-07-28 03:49:57 -07:00
STRUCTURE_STATS * psStats ;
bool bFound = false ;
ASSERT_OR_RETURN ( false , psStruct ! = NULL , " Testing for a module from a NULL struct " ) ;
2007-06-28 10:47:08 -07:00
2006-05-27 09:37:17 -07:00
/* Fail if the structure isn't built yet */
2012-12-16 12:03:00 -08:00
if ( psStruct - > status ! = SS_BUILT )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return ( false ) ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
/* Grab a stats pointer */
psStats = psStruct - > pStructureType ;
if ( StructIsFactory ( psStruct )
| | psStats - > type = = REF_POWER_GEN | | psStats - > type = = REF_RESEARCH )
{
switch ( psStats - > type )
{
case REF_POWER_GEN :
2013-04-16 15:15:04 -07:00
if ( psStruct - > capacity )
2012-12-16 12:03:00 -08:00
{
bFound = true ;
}
break ;
case REF_FACTORY :
case REF_VTOL_FACTORY :
2013-04-16 15:15:04 -07:00
if ( psStruct - > capacity )
2012-12-16 12:03:00 -08:00
{
bFound = true ;
}
break ;
case REF_RESEARCH :
2013-04-16 15:15:04 -07:00
if ( psStruct - > capacity )
2012-12-16 12:03:00 -08:00
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
bFound = true ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
break ;
default :
//no other structures can have modules attached
break ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
}
else
{
/* Wrong type of building - cannot have a module */
bFound = false ;
}
2007-06-28 10:47:08 -07:00
return ( bFound ) ;
}
// -----------------------------------------------------------------------------------------
// give player a template belonging to another.
2011-03-12 17:32:15 -08:00
bool scrAddTemplate ( void )
2007-06-28 10:47:08 -07:00
{
DROID_TEMPLATE * psTemplate ;
UDWORD player ;
2006-05-27 09:37:17 -07:00
2007-06-28 10:47:08 -07:00
if ( ! stackPopParams ( 2 , ST_TEMPLATE , & psTemplate , VAL_INT , & player ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
if ( player > = MAX_PLAYERS )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrAddTemplate:player number is too high " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT ( psTemplate ! = NULL , " scrAddTemplate: Invalid template pointer " ) ;
2007-06-28 10:47:08 -07:00
2012-12-16 12:03:00 -08:00
if ( addTemplate ( player , psTemplate ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
scrFunctionResult . v . bval = true ;
2006-11-19 12:50:02 -08:00
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
}
else
{
2008-03-24 09:51:17 -07:00
scrFunctionResult . v . bval = false ;
2006-11-19 12:50:02 -08:00
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// additional structure check
2012-12-16 12:03:00 -08:00
bool structDoubleCheck ( BASE_STATS * psStat , UDWORD xx , UDWORD yy , SDWORD maxBlockingTiles )
2007-06-28 10:47:08 -07:00
{
2010-02-10 03:35:09 -08:00
UDWORD x , y , xTL , yTL , xBR , yBR ;
UBYTE count = 0 ;
STRUCTURE_STATS * psBuilding = ( STRUCTURE_STATS * ) psStat ;
2010-02-10 03:53:41 -08:00
GATEWAY * psGate ;
2007-06-28 10:47:08 -07:00
2012-12-16 12:03:00 -08:00
xTL = xx - 1 ;
yTL = yy - 1 ;
xBR = ( xx + psBuilding - > baseWidth ) ;
yBR = ( yy + psBuilding - > baseBreadth ) ;
2007-06-28 10:47:08 -07:00
2010-02-10 03:53:41 -08:00
// check against building in a gateway, as this can seriously block AI passages
for ( psGate = gwGetGateways ( ) ; psGate ; psGate = psGate - > psNext )
{
for ( x = xx ; x < = xBR ; x + + )
{
2012-12-16 12:03:00 -08:00
for ( y = yy ; y < = yBR ; y + + )
2010-02-10 03:53:41 -08:00
{
if ( ( x > = psGate - > x1 & & x < = psGate - > x2 ) & & ( y > = psGate - > y1 & & y < = psGate - > y2 ) )
{
return false ;
}
}
}
}
// can you get past it?
2007-06-28 10:47:08 -07:00
y = yTL ; // top
2012-12-16 12:03:00 -08:00
for ( x = xTL ; x ! = xBR + 1 ; x + + )
2007-06-28 10:47:08 -07:00
{
2008-07-10 10:59:35 -07:00
if ( fpathBlockingTile ( x , y , PROPULSION_TYPE_WHEELED ) )
2007-06-28 10:47:08 -07:00
{
count + + ;
break ;
2008-05-07 09:37:46 -07:00
}
}
2007-06-28 10:47:08 -07:00
y = yBR ; // bottom
2012-12-16 12:03:00 -08:00
for ( x = xTL ; x ! = xBR + 1 ; x + + )
2007-06-28 10:47:08 -07:00
{
2008-07-10 10:59:35 -07:00
if ( fpathBlockingTile ( x , y , PROPULSION_TYPE_WHEELED ) )
2007-06-28 10:47:08 -07:00
{
count + + ;
break ;
2008-05-07 09:37:46 -07:00
}
}
2006-05-27 09:37:17 -07:00
2007-06-28 10:47:08 -07:00
x = xTL ; // left
2012-12-16 12:03:00 -08:00
for ( y = yTL + 1 ; y ! = yBR ; y + + )
2007-06-28 10:47:08 -07:00
{
2008-07-10 10:59:35 -07:00
if ( fpathBlockingTile ( x , y , PROPULSION_TYPE_WHEELED ) )
2007-06-28 10:47:08 -07:00
{
count + + ;
break ;
2008-05-07 09:37:46 -07:00
}
}
2007-06-28 10:47:08 -07:00
x = xBR ; // right
2012-12-16 12:03:00 -08:00
for ( y = yTL + 1 ; y ! = yBR ; y + + )
2007-06-28 10:47:08 -07:00
{
2008-07-10 10:59:35 -07:00
if ( fpathBlockingTile ( x , y , PROPULSION_TYPE_WHEELED ) )
2007-06-28 10:47:08 -07:00
{
count + + ;
break ;
2008-05-07 09:37:46 -07:00
}
}
2007-06-28 10:47:08 -07:00
2007-05-05 08:38:04 -07:00
//make sure this location is not blocked from too many sides
2012-12-16 12:03:00 -08:00
if ( ( count < = maxBlockingTiles ) | | ( maxBlockingTiles = = - 1 ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2011-03-12 17:32:15 -08:00
static bool pickStructLocation ( DROID * psDroid , int index , int * pX , int * pY , int player , int maxBlockingTiles )
2007-06-28 10:47:08 -07:00
{
2011-12-03 10:13:39 -08:00
STRUCTURE_STATS * psStat = & asStructureStats [ index ] ;
2007-06-28 10:47:08 -07:00
UDWORD numIterations = 30 ;
2011-03-12 17:32:15 -08:00
bool found = false ;
2010-10-12 15:10:03 -07:00
int startX , startY , incX , incY , x , y ;
2007-06-28 10:47:08 -07:00
2010-02-10 03:35:09 -08:00
ASSERT_OR_RETURN ( false , player < MAX_PLAYERS & & player > = 0 , " Invalid player number %d " , player ) ;
2007-06-28 10:47:08 -07:00
2011-12-24 15:37:16 -08:00
Vector2i offset ( psStat - > baseWidth * ( TILE_UNITS / 2 ) , psStat - > baseBreadth * ( TILE_UNITS / 2 ) ) ; // This gets added to the chosen coordinates, at the end of the function.
2010-02-10 03:35:09 -08:00
// check for wacky coords.
if ( * pX < 0 | | * pX > world_coord ( mapWidth ) | | * pY < 0 | | * pY > world_coord ( mapHeight ) )
2007-06-28 10:47:08 -07:00
{
2011-12-03 09:47:37 -08:00
debug ( LOG_ERROR , " Bad parameters " ) ;
2010-02-10 03:35:09 -08:00
goto endstructloc ;
2007-06-28 10:47:08 -07:00
}
2010-02-10 03:35:09 -08:00
startX = map_coord ( * pX ) ; // change to tile coords.
2007-09-28 12:25:21 -07:00
startY = map_coord ( * pY ) ;
2007-05-05 08:38:04 -07:00
x = startX ;
y = startY ;
2010-03-16 11:05:37 -07:00
// save a lot of typing... checks whether a position is valid
2012-12-16 12:03:00 -08:00
# define LOC_OK(_x, _y) (tileOnMap(_x, _y) && \
( ! psDroid | | fpathCheck ( psDroid - > pos , Vector3i ( world_coord ( _x ) , world_coord ( _y ) , 0 ) , PROPULSION_TYPE_WHEELED ) ) \
& & validLocation ( psStat , world_coord ( Vector2i ( _x , _y ) ) + offset , 0 , player , false ) & & structDoubleCheck ( psStat , _x , _y , maxBlockingTiles ) )
2010-03-16 11:05:37 -07:00
2007-05-05 08:38:04 -07:00
// first try the original location
2010-03-16 11:05:37 -07:00
if ( LOC_OK ( startX , startY ) )
2007-06-28 10:47:08 -07:00
{
2010-02-10 03:35:09 -08:00
found = true ;
2007-05-05 08:38:04 -07:00
}
2007-06-28 10:47:08 -07:00
2007-05-05 08:38:04 -07:00
// try some locations nearby
2010-02-10 03:35:09 -08:00
for ( incX = 1 , incY = 1 ; incX < numIterations & & ! found ; incX + + , incY + + )
2007-05-05 08:38:04 -07:00
{
2010-02-10 03:35:09 -08:00
y = startY - incY ; // top
for ( x = startX - incX ; x < ( SDWORD ) ( startX + incX ) ; x + + )
2007-06-28 10:47:08 -07:00
{
2010-03-16 11:05:37 -07:00
if ( LOC_OK ( x , y ) )
2007-05-05 08:38:04 -07:00
{
2010-02-10 03:35:09 -08:00
found = true ;
goto endstructloc ;
}
}
x = startX + incX ; // right
for ( y = startY - incY ; y < ( SDWORD ) ( startY + incY ) ; y + + )
{
2010-03-16 11:05:37 -07:00
if ( LOC_OK ( x , y ) )
2010-02-10 03:35:09 -08:00
{
found = true ;
goto endstructloc ;
}
}
y = startY + incY ; // bottom
for ( x = startX + incX ; x > ( SDWORD ) ( startX - incX ) ; x - - )
{
2010-03-16 11:05:37 -07:00
if ( LOC_OK ( x , y ) )
2010-02-10 03:35:09 -08:00
{
found = true ;
goto endstructloc ;
}
}
x = startX - incX ; // left
for ( y = startY + incY ; y > ( SDWORD ) ( startY - incY ) ; y - - )
{
2010-03-16 11:05:37 -07:00
if ( LOC_OK ( x , y ) )
2010-02-10 03:35:09 -08:00
{
found = true ;
goto endstructloc ;
2007-05-05 08:38:04 -07:00
}
}
}
2010-02-10 03:35:09 -08:00
endstructloc :
// back to world coords.
if ( found ) // did it!
2007-05-05 08:38:04 -07:00
{
2011-12-24 15:37:16 -08:00
* pX = world_coord ( x ) + offset . x ;
* pY = world_coord ( y ) + offset . y ;
2007-05-05 08:38:04 -07:00
}
2011-12-03 09:47:37 -08:00
else
{
2013-05-12 14:50:57 -07:00
debug ( LOG_SCRIPT , " Did not find valid positioning for %s " , getID ( psStat ) ) ;
2011-12-03 09:47:37 -08:00
}
2010-02-10 03:35:09 -08:00
scrFunctionResult . v . bval = found ;
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) ) // success!
2007-05-05 08:38:04 -07:00
{
2010-02-10 03:35:09 -08:00
return false ;
2007-05-05 08:38:04 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-05-05 08:38:04 -07:00
}
2007-12-18 13:11:04 -08:00
// pick a structure location(only used in skirmish game at 27Aug) ajl.
2011-03-12 17:32:15 -08:00
bool scrPickStructLocation ( void )
2007-12-18 13:11:04 -08:00
{
2012-12-16 12:03:00 -08:00
SDWORD * pX , * pY ;
2007-12-18 13:11:04 -08:00
SDWORD index ;
UDWORD player ;
2012-12-16 12:03:00 -08:00
if ( ! stackPopParams ( 4 , ST_STRUCTURESTAT , & index , VAL_REF | VAL_INT , & pX , VAL_REF | VAL_INT , & pY , VAL_INT , & player ) )
2007-12-18 13:11:04 -08:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-12-18 13:11:04 -08:00
}
2010-03-16 11:05:37 -07:00
return pickStructLocation ( NULL , index , pX , pY , player , MAX_BLOCKING_TILES ) ;
}
// pick a structure location and check that we can build there (duh!)
2011-03-12 17:32:15 -08:00
bool scrPickStructLocationC ( void )
2010-03-16 11:05:37 -07:00
{
int * pX , * pY , index , player , maxBlockingTiles ;
DROID * psDroid ;
2012-12-16 12:03:00 -08:00
if ( ! stackPopParams ( 6 , ST_DROID , & psDroid , ST_STRUCTURESTAT , & index , VAL_REF | VAL_INT , & pX , VAL_REF | VAL_INT , & pY , VAL_INT , & player , VAL_INT , & maxBlockingTiles ) )
2010-03-16 11:05:37 -07:00
{
return false ;
}
return pickStructLocation ( psDroid , index , pX , pY , player , maxBlockingTiles ) ;
2007-12-18 13:11:04 -08:00
}
2007-05-05 08:38:04 -07:00
// pick a structure location(only used in skirmish game at 27Aug) ajl.
// Max number of blocking tiles is passed as parameter for this one
2011-03-12 17:32:15 -08:00
bool scrPickStructLocationB ( void )
2007-05-05 08:38:04 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD * pX , * pY ;
2007-05-05 08:38:04 -07:00
SDWORD index ;
UDWORD player ;
SDWORD maxBlockingTiles ;
2012-12-16 12:03:00 -08:00
if ( ! stackPopParams ( 5 , ST_STRUCTURESTAT , & index , VAL_REF | VAL_INT , & pX ,
VAL_REF | VAL_INT , & pY , VAL_INT , & player , VAL_INT , & maxBlockingTiles ) )
2007-05-05 08:38:04 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-05-05 08:38:04 -07:00
}
2010-03-16 11:05:37 -07:00
return pickStructLocation ( NULL , index , pX , pY , player , maxBlockingTiles ) ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// Sets the transporter entry and exit points for the map
2011-03-12 17:32:15 -08:00
bool scrSetTransporterExit ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD iPlayer , iExitTileX , iExitTileY ;
if ( ! stackPopParams ( 3 , VAL_INT , & iPlayer , VAL_INT , & iExitTileX , VAL_INT , & iExitTileY ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
missionSetTransporterExit ( iPlayer , iExitTileX , iExitTileY ) ;
2007-06-28 10:47:08 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
// Fly transporters in at start of map
2011-03-12 17:32:15 -08:00
bool scrFlyTransporterIn ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD iPlayer , iEntryTileX , iEntryTileY ;
2011-03-19 18:52:25 -07:00
int32_t bTrackTransporter ; // was BOOL (int) ** see warning about conversion
2007-06-28 10:47:08 -07:00
if ( ! stackPopParams ( 4 , VAL_INT , & iPlayer , VAL_INT , & iEntryTileX , VAL_INT , & iEntryTileY ,
2012-12-16 12:03:00 -08:00
VAL_BOOL , & bTrackTransporter ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
missionSetTransporterEntry ( iPlayer , iEntryTileX , iEntryTileY ) ;
missionFlyTransportersIn ( iPlayer , bTrackTransporter ) ;
2007-06-28 10:47:08 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// -----------------------------------------------------------------------------------------
/*
* * scrGetGameStatus
*
2006-05-27 09:37:17 -07:00
* PARAMETERS : The parameter passed must be one of the STATUS_ variable
2007-06-28 10:47:08 -07:00
*
2011-03-12 17:32:15 -08:00
* DESCRIPTION : Returns various bool options in the game e . g . If the reticule is open
2006-05-27 09:37:17 -07:00
* - You should use the externed variable intMode for other game mode options
2007-06-28 10:47:08 -07:00
* e . g . in the intelligence screen or desgin screen )
*
* RETURNS :
*
*/
2011-03-12 17:32:15 -08:00
bool scrGetGameStatus ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD GameChoice ;
2011-03-12 17:32:15 -08:00
bool bResult ;
2007-06-28 10:47:08 -07:00
if ( ! stackPopParams ( 1 , VAL_INT , & GameChoice ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
bResult = false ; // the default scrFunctionResult is false
2007-06-28 10:47:08 -07:00
switch ( GameChoice )
{
2012-12-16 12:03:00 -08:00
case STATUS_ReticuleIsOpen :
if ( widgGetFromID ( psWScreen , IDRET_FORM ) ! = NULL )
{
bResult = true ;
}
break ;
2007-06-28 10:47:08 -07:00
2012-12-16 12:03:00 -08:00
case STATUS_BattleMapViewEnabled :
if ( bResult = = true )
{
debug ( LOG_NEVER , " battle map active " ) ;
}
else
{
debug ( LOG_NEVER , " battle map not active " ) ;
}
break ;
2007-06-28 10:47:08 -07:00
2012-12-16 12:03:00 -08:00
case STATUS_DeliveryReposInProgress :
if ( deliveryReposValid ( ) )
{
bResult = true ;
}
break ;
2007-06-28 10:47:08 -07:00
2012-12-16 12:03:00 -08:00
default :
ASSERT ( false , " ScrGetGameStatus. Invalid STATUS_ variable " ) ;
2007-06-28 10:47:08 -07:00
break ;
}
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . bval = bResult ;
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
//get the colour number used by a player
2011-03-12 17:32:15 -08:00
bool scrGetPlayerColour ( void )
2007-06-28 10:47:08 -07:00
{
2006-11-16 06:30:29 -08:00
SDWORD player ;
2007-06-28 10:47:08 -07:00
if ( ! stackPopParams ( 1 , VAL_INT , & player ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
if ( player > = MAX_PLAYERS )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrGetPlayerColour: player number is too high " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2006-05-27 09:37:17 -07:00
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . ival = ( SDWORD ) getPlayerColour ( player ) ;
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
2006-10-08 01:06:46 -07:00
//get the colour name of the player ("green", "black" etc)
2011-03-12 17:32:15 -08:00
bool scrGetPlayerColourName ( void )
2006-10-08 01:06:46 -07:00
{
SDWORD player ;
if ( ! stackPopParams ( 1 , VAL_INT , & player ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2006-10-08 01:06:46 -07:00
}
if ( player > = MAX_PLAYERS | | player < 0 )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrGetPlayerColourName: wrong player index " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-10-08 01:06:46 -07:00
}
2008-11-13 14:42:05 -08:00
/* Casting away constness because stackPushResult doesn't modify it's
* value ( i . e . in this case it ' s not const correct ) .
*/
2012-12-16 12:03:00 -08:00
scrFunctionResult . v . sval = ( char * ) getPlayerColourName ( player ) ;
2006-11-19 12:50:02 -08:00
if ( ! stackPushResult ( VAL_STRING , & scrFunctionResult ) )
2006-10-08 01:06:46 -07:00
{
2006-10-08 07:08:53 -07:00
debug ( LOG_ERROR , " scrGetPlayerColourName(): failed to push result " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-10-08 01:06:46 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-10-08 01:06:46 -07:00
}
2007-06-28 10:47:08 -07:00
//set the colour number to use for a player
2011-03-12 17:32:15 -08:00
bool scrSetPlayerColour ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD player , colour ;
if ( ! stackPopParams ( 2 , VAL_INT , & colour , VAL_INT , & player ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
if ( player > = MAX_PLAYERS )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrSetPlayerColour:player number is too high " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2006-05-27 09:37:17 -07:00
2007-06-28 10:47:08 -07:00
if ( colour > = MAX_PLAYERS )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrSetPlayerColour:colour number is too high " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
//not the end of the world if this doesn't work so don't check the return code
( void ) setPlayerColour ( player , colour ) ;
2007-06-28 10:47:08 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
//set all droids in an area to belong to a different player - returns the number of droids changed
2011-03-12 17:32:15 -08:00
bool scrTakeOverDroidsInArea ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD fromPlayer , toPlayer , x1 , x2 , y1 , y2 , numChanged ;
2012-11-16 04:51:59 -08:00
DROID * psDroid , * psNext ;
2007-06-28 10:47:08 -07:00
2012-11-16 04:51:59 -08:00
if ( ! stackPopParams ( 6 , VAL_INT , & fromPlayer , VAL_INT , & toPlayer , VAL_INT , & x1 , VAL_INT , & y1 , VAL_INT , & x2 , VAL_INT , & y2 ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-11-16 04:51:59 -08:00
ASSERT_OR_RETURN ( false , fromPlayer < MAX_PLAYERS & & toPlayer < MAX_PLAYERS , " player number is too high " ) ;
ASSERT_OR_RETURN ( false , x1 < world_coord ( MAP_MAXWIDTH ) & & x2 < world_coord ( MAP_MAXWIDTH ) & & y1 < world_coord ( MAP_MAXHEIGHT )
2012-12-16 12:03:00 -08:00
& & y2 < world_coord ( MAP_MAXHEIGHT ) , " coordinate outside map " ) ;
2012-11-16 04:51:59 -08:00
numChanged = 0 ;
for ( psDroid = apsDroidLists [ fromPlayer ] ; psDroid ! = NULL ; psDroid = psNext )
2007-06-28 10:47:08 -07:00
{
2012-11-16 04:51:59 -08:00
psNext = psDroid - > psNext ;
// check if within area specified
if ( psDroid - > pos . x > = x1 & & psDroid - > pos . x < = x2 & & psDroid - > pos . y > = y1 & & psDroid - > pos . y < = y2
& & psDroid - > player ! = toPlayer )
{
if ( giftSingleDroid ( psDroid , toPlayer ) ) // give the droid away
{
numChanged + + ;
}
}
2007-06-28 10:47:08 -07:00
}
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . ival = numChanged ;
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-11-16 04:51:59 -08:00
return true ;
2007-06-28 10:47:08 -07:00
}
/*this takes over a single droid and passes a pointer back to the new one*/
2011-03-12 17:32:15 -08:00
bool scrTakeOverSingleDroid ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD playerToGain ;
2012-12-16 12:03:00 -08:00
DROID * psDroidToTake , * psNewDroid ;
2007-06-28 10:47:08 -07:00
2012-12-16 12:03:00 -08:00
if ( ! stackPopParams ( 2 , ST_DROID , & psDroidToTake , VAL_INT , & playerToGain ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2012-12-16 12:03:00 -08:00
}
2007-06-28 10:47:08 -07:00
if ( playerToGain > = MAX_PLAYERS )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrTakeOverSingleUnit:player number is too high " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2006-05-27 09:37:17 -07:00
2012-12-16 12:03:00 -08:00
if ( psDroidToTake = = NULL )
{
ASSERT ( false , " scrTakeOverSingleUnit: Null unit " ) ;
return false ;
}
2007-06-28 10:47:08 -07:00
2012-12-16 12:03:00 -08:00
ASSERT ( psDroidToTake ! = NULL ,
" scrTakeOverSingleUnit: Invalid unit pointer " ) ;
2007-06-28 10:47:08 -07:00
2012-12-16 12:03:00 -08:00
psNewDroid = giftSingleDroid ( psDroidToTake , playerToGain ) ;
2007-06-28 10:47:08 -07:00
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . oval = psNewDroid ;
if ( ! stackPushResult ( ( INTERP_TYPE ) ST_DROID , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2012-12-16 12:03:00 -08:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// set all droids in an area of a certain experience level or less to belong to
// a different player - returns the number of droids changed
2011-03-12 17:32:15 -08:00
bool scrTakeOverDroidsInAreaExp ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD fromPlayer , toPlayer , x1 , x2 , y1 , y2 , numChanged , level , maxUnits ;
2012-12-16 12:03:00 -08:00
DROID * psDroid , * psNext ;
2007-06-28 10:47:08 -07:00
2006-05-27 09:37:17 -07:00
if ( ! stackPopParams ( 8 , VAL_INT , & fromPlayer , VAL_INT , & toPlayer ,
2012-12-16 12:03:00 -08:00
VAL_INT , & x1 , VAL_INT , & y1 , VAL_INT , & x2 , VAL_INT , & y2 , VAL_INT , & level , VAL_INT , & maxUnits ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2007-02-10 08:39:39 -08:00
if ( fromPlayer > = MAX_PLAYERS | | toPlayer > = MAX_PLAYERS )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrTakeOverUnitsInArea:player number is too high " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2006-05-27 09:37:17 -07:00
2007-09-28 12:25:21 -07:00
if ( x1 > world_coord ( MAP_MAXWIDTH ) )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrTakeOverUnitsInArea: x1 is greater than max mapWidth " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
if ( x2 > world_coord ( MAP_MAXWIDTH ) )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrTakeOverUnitsInArea: x2 is greater than max mapWidth " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
if ( y1 > world_coord ( MAP_MAXHEIGHT ) )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrTakeOverUnitsInArea: y1 is greater than max mapHeight " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
if ( y2 > world_coord ( MAP_MAXHEIGHT ) )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrTakeOverUnitsInArea: y2 is greater than max mapHeight " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
numChanged = 0 ;
for ( psDroid = apsDroidLists [ fromPlayer ] ; psDroid ! = NULL ; psDroid = psNext )
{
psNext = psDroid - > psNext ;
//check if within area specified
if ( ( psDroid - > droidType ! = DROID_CONSTRUCT ) & &
( psDroid - > droidType ! = DROID_REPAIR ) & &
( psDroid - > droidType ! = DROID_CYBORG_CONSTRUCT ) & &
( psDroid - > droidType ! = DROID_CYBORG_REPAIR ) & &
( ( SDWORD ) psDroid - > experience / 65536 < = level ) & &
psDroid - > pos . x > = x1 & & psDroid - > pos . x < = x2 & &
psDroid - > pos . y > = y1 & & psDroid - > pos . y < = y2 )
{
//give the droid away
if ( giftSingleDroid ( psDroid , toPlayer ) )
{
numChanged + + ;
}
}
2007-06-28 10:47:08 -07:00
if ( numChanged > = maxUnits )
{
break ;
}
2012-12-16 12:03:00 -08:00
}
2007-06-28 10:47:08 -07:00
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . ival = numChanged ;
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
return true ;
2007-06-28 10:47:08 -07:00
}
/*this takes over a single structure and passes a pointer back to the new one*/
2011-03-12 17:32:15 -08:00
bool scrTakeOverSingleStructure ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD playerToGain ;
2012-12-16 12:03:00 -08:00
STRUCTURE * psStructToTake , * psNewStruct ;
UDWORD structureInc ;
2007-06-28 10:47:08 -07:00
2012-12-16 12:03:00 -08:00
if ( ! stackPopParams ( 2 , ST_STRUCTURE , & psStructToTake , VAL_INT , & playerToGain ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2012-12-16 12:03:00 -08:00
}
2007-06-28 10:47:08 -07:00
if ( playerToGain > = MAX_PLAYERS )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrTakeOverSingleStructure:player number is too high " ) ;
return false ;
}
if ( psStructToTake = = NULL )
{
ASSERT ( false , " scrTakeOverSingleStructure: Null structure " ) ;
return false ;
}
ASSERT ( psStructToTake ! = NULL ,
" scrTakeOverSingleStructure: Invalid structure pointer " ) ;
structureInc = psStructToTake - > pStructureType - > ref - REF_STRUCTURE_START ;
if ( playerToGain = = ( SDWORD ) selectedPlayer & & StructIsFactory ( psStructToTake ) & &
asStructLimits [ playerToGain ] [ structureInc ] . currentQuantity > = MAX_FACTORY )
{
debug ( LOG_NEVER , " scrTakeOverSingleStructure - factory ignored for selectedPlayer \n " ) ;
psNewStruct = NULL ;
}
else
{
psNewStruct = giftSingleStructure ( psStructToTake , ( UBYTE ) playerToGain , true ) ;
if ( psNewStruct )
{
//check the structure limits aren't compromised
if ( asStructLimits [ playerToGain ] [ structureInc ] . currentQuantity >
asStructLimits [ playerToGain ] [ structureInc ] . limit )
{
asStructLimits [ playerToGain ] [ structureInc ] . limit = asStructLimits [
playerToGain ] [ structureInc ] . currentQuantity ;
}
//for each structure taken - add graphical effect if the selectedPlayer
if ( playerToGain = = ( SDWORD ) selectedPlayer )
{
assignSensorTarget ( ( BASE_OBJECT * ) psNewStruct ) ;
}
}
}
2007-06-28 10:47:08 -07:00
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . oval = psNewStruct ;
if ( ! stackPushResult ( ( INTERP_TYPE ) ST_STRUCTURE , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2012-12-16 12:03:00 -08:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
//set all structures in an area to belong to a different player - returns the number of droids changed
//will not work on factories for the selectedPlayer
2011-03-12 17:32:15 -08:00
bool scrTakeOverStructsInArea ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD fromPlayer , toPlayer , x1 , x2 , y1 , y2 , numChanged ;
2012-12-16 12:03:00 -08:00
STRUCTURE * psStruct , * psNext , * psNewStruct ;
UDWORD structureInc ;
2007-06-28 10:47:08 -07:00
2006-05-27 09:37:17 -07:00
if ( ! stackPopParams ( 6 , VAL_INT , & fromPlayer , VAL_INT , & toPlayer ,
2012-12-16 12:03:00 -08:00
VAL_INT , & x1 , VAL_INT , & y1 , VAL_INT , & x2 , VAL_INT , & y2 ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2007-02-10 08:39:39 -08:00
if ( fromPlayer > = MAX_PLAYERS | | toPlayer > = MAX_PLAYERS )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrTakeOverStructsInArea:player number is too high " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2006-05-27 09:37:17 -07:00
2007-09-28 12:25:21 -07:00
if ( x1 > world_coord ( MAP_MAXWIDTH ) )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrTakeOverStructsInArea: x1 is greater than max mapWidth " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
if ( x2 > world_coord ( MAP_MAXWIDTH ) )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrTakeOverStructsInArea: x2 is greater than max mapWidth " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
if ( y1 > world_coord ( MAP_MAXHEIGHT ) )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrTakeOverStructsInArea: y1 is greater than max mapHeight " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
if ( y2 > world_coord ( MAP_MAXHEIGHT ) )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrTakeOverStructsInArea: y2 is greater than max mapHeight " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
numChanged = 0 ;
for ( psStruct = apsStructLists [ fromPlayer ] ; psStruct ! = NULL ; psStruct = psNext )
{
psNext = psStruct - > psNext ;
//check if within area specified
if ( psStruct - > pos . x > = x1 & & psStruct - > pos . x < = x2 & &
psStruct - > pos . y > = y1 & & psStruct - > pos . y < = y2 )
{
//changed this so allows takeOver is have less than 5 factories
//don't work on factories for the selectedPlayer
structureInc = psStruct - > pStructureType - > ref - REF_STRUCTURE_START ;
if ( toPlayer = = ( SDWORD ) selectedPlayer & & StructIsFactory ( psStruct ) & &
asStructLimits [ toPlayer ] [ structureInc ] . currentQuantity > = MAX_FACTORY )
{
debug ( LOG_NEVER , " scrTakeOverStructsInArea - factory ignored for selectedPlayer \n " ) ;
}
else
{
//give the structure away
psNewStruct = giftSingleStructure ( psStruct , ( UBYTE ) toPlayer , true ) ;
if ( psNewStruct )
{
numChanged + + ;
//check the structure limits aren't compromised
//structureInc = psNewStruct->pStructureType->ref - REF_STRUCTURE_START;
if ( asStructLimits [ toPlayer ] [ structureInc ] . currentQuantity >
asStructLimits [ toPlayer ] [ structureInc ] . limit )
{
asStructLimits [ toPlayer ] [ structureInc ] . limit = asStructLimits [
toPlayer ] [ structureInc ] . currentQuantity ;
}
//for each structure taken - add graphical effect if the selectedPlayer
if ( toPlayer = = ( SDWORD ) selectedPlayer )
{
assignSensorTarget ( ( BASE_OBJECT * ) psNewStruct ) ;
}
}
}
}
}
2007-06-28 10:47:08 -07:00
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . ival = numChanged ;
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
return true ;
2007-06-28 10:47:08 -07:00
}
//set Flag for defining what happens to the droids in a Transporter
2011-03-12 17:32:15 -08:00
bool scrSetDroidsToSafetyFlag ( void )
2007-06-28 10:47:08 -07:00
{
2011-03-19 18:52:25 -07:00
int32_t bState ; // was BOOL (int) ** see warning about conversion
2007-06-28 10:47:08 -07:00
if ( ! stackPopParams ( 1 , VAL_BOOL , & bState ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
setDroidsToSafetyFlag ( bState ) ;
2007-06-28 10:47:08 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
//set Flag for defining whether the coded countDown is called
2011-03-12 17:32:15 -08:00
bool scrSetPlayCountDown ( void )
2007-06-28 10:47:08 -07:00
{
2011-03-19 18:52:25 -07:00
int32_t bState ; // was BOOL (int) ** see warning about conversion
2007-06-28 10:47:08 -07:00
if ( ! stackPopParams ( 1 , VAL_BOOL , & bState ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
setPlayCountDown ( ( UBYTE ) bState ) ;
2007-06-28 10:47:08 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
//get the number of droids currently onthe map for a player
2011-03-12 17:32:15 -08:00
bool scrGetDroidCount ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD player ;
if ( ! stackPopParams ( 1 , VAL_INT , & player ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
if ( player > = MAX_PLAYERS )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrGetUnitCount:player number is too high " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2006-05-27 09:37:17 -07:00
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . ival = getNumDroids ( player ) ;
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// fire a weapon stat at an object
2011-03-12 17:32:15 -08:00
bool scrFireWeaponAtObj ( void )
2007-06-28 10:47:08 -07:00
{
2008-05-13 16:32:07 -07:00
Vector3i target ;
BASE_OBJECT * psTarget ;
2010-02-28 15:14:52 -08:00
WEAPON sWeapon ;
2007-06-28 10:47:08 -07:00
2010-02-28 15:14:52 -08:00
memset ( & sWeapon , 0 , sizeof ( sWeapon ) ) ;
2008-05-13 16:32:07 -07:00
if ( ! stackPopParams ( 2 , ST_WEAPON , & sWeapon . nStat , ST_BASEOBJECT , & psTarget ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
if ( psTarget = = NULL )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrFireWeaponAtObj: Null target pointer " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2010-02-28 03:53:33 -08:00
target = psTarget - > pos ;
2007-06-28 10:47:08 -07:00
// send the projectile using the selectedPlayer so that it can always be seen
2008-05-14 10:24:51 -07:00
proj_SendProjectile ( & sWeapon , NULL , selectedPlayer , target , psTarget , true , 0 ) ;
2007-06-28 10:47:08 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// fire a weapon stat at a location
2011-03-12 17:32:15 -08:00
bool scrFireWeaponAtLoc ( void )
2007-06-28 10:47:08 -07:00
{
2008-05-13 16:32:07 -07:00
Vector3i target ;
2010-02-28 15:14:52 -08:00
WEAPON sWeapon ;
2007-06-28 10:47:08 -07:00
2010-02-28 15:14:52 -08:00
memset ( & sWeapon , 0 , sizeof ( sWeapon ) ) ;
2008-05-13 16:32:07 -07:00
if ( ! stackPopParams ( 3 , ST_WEAPON , & sWeapon . nStat , VAL_INT , & target . x , VAL_INT , & target . y ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-05-13 16:32:07 -07:00
target . z = map_Height ( target . x , target . y ) ;
2007-06-28 10:47:08 -07:00
// send the projectile using the selectedPlayer so that it can always be seen
2008-05-14 10:24:51 -07:00
proj_SendProjectile ( & sWeapon , NULL , selectedPlayer , target , NULL , true , 0 ) ;
2007-06-28 10:47:08 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// set the number of kills for a droid
2011-03-12 17:32:15 -08:00
bool scrSetDroidKills ( void )
2007-06-28 10:47:08 -07:00
{
DROID * psDroid ;
SDWORD kills ;
if ( ! stackPopParams ( 2 , ST_DROID , & psDroid , VAL_INT , & kills ) )
{
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
if ( ( psDroid = = NULL ) | |
2012-12-16 12:03:00 -08:00
( psDroid - > type ! = OBJ_DROID ) )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrSetUnitKills: NULL/invalid unit pointer " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2010-11-16 05:01:18 -08:00
psDroid - > experience = kills * 100 * 65536 ;
2007-08-13 03:40:32 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2007-08-13 03:40:32 -07:00
}
// get the number of kills for a droid
2011-03-12 17:32:15 -08:00
bool scrGetDroidKills ( void )
2007-08-13 03:40:32 -07:00
{
DROID * psDroid ;
if ( ! stackPopParams ( 1 , ST_DROID , & psDroid ) )
{
2008-03-24 09:51:17 -07:00
return true ;
2007-08-13 03:40:32 -07:00
}
if ( ( psDroid = = NULL ) | |
2012-12-16 12:03:00 -08:00
( psDroid - > type ! = OBJ_DROID ) )
2007-08-13 03:40:32 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrGetDroidKills: NULL/invalid unit pointer " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-08-13 03:40:32 -07:00
}
2012-12-16 12:03:00 -08:00
scrFunctionResult . v . ival = psDroid - > experience / 65536 ;
2007-08-13 03:40:32 -07:00
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-08-13 03:40:32 -07:00
}
2007-06-28 10:47:08 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// reset the visibility for a player
2011-03-12 17:32:15 -08:00
bool scrResetPlayerVisibility ( void )
2007-06-28 10:47:08 -07:00
{
SDWORD player , i ;
BASE_OBJECT * psObj ;
if ( ! stackPopParams ( 1 , VAL_INT , & player ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2013-10-21 12:41:55 -07:00
if ( player < 0 | | player > = MAX_PLAYERS )
2007-06-28 10:47:08 -07:00
{
2013-10-21 12:41:55 -07:00
ASSERT ( false , " Invalid player %d " , player ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
for ( i = 0 ; i < MAX_PLAYERS ; i + + )
2007-06-28 10:47:08 -07:00
{
if ( i = = player )
{
continue ;
}
2012-12-16 12:03:00 -08:00
for ( psObj = ( BASE_OBJECT * ) apsDroidLists [ i ] ; psObj ; psObj = psObj - > psNext )
2007-06-28 10:47:08 -07:00
{
psObj - > visible [ player ] = 0 ;
}
2012-12-16 12:03:00 -08:00
for ( psObj = ( BASE_OBJECT * ) apsStructLists [ i ] ; psObj ; psObj = psObj - > psNext )
2007-06-28 10:47:08 -07:00
{
psObj - > visible [ player ] = 0 ;
}
}
2012-12-16 12:03:00 -08:00
for ( psObj = ( BASE_OBJECT * ) apsFeatureLists [ 0 ] ; psObj ; psObj = psObj - > psNext )
2007-06-28 10:47:08 -07:00
{
psObj - > visible [ player ] = 0 ;
}
clustResetVisibility ( player ) ;
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
// set the vtol return pos for a player
2011-03-12 17:32:15 -08:00
bool scrSetVTOLReturnPos ( void )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD player , tx , ty ;
2007-06-28 10:47:08 -07:00
if ( ! stackPopParams ( 3 , VAL_INT , & player , VAL_INT , & tx , VAL_INT , & ty ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
if ( player < 0 | | player > = MAX_PLAYERS )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrSetVTOLReturnPos: invalid player " ) ;
return false ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
asVTOLReturnPos [ player ] . x = ( tx * TILE_UNITS ) + TILE_UNITS / 2 ;
asVTOLReturnPos [ player ] . y = ( ty * TILE_UNITS ) + TILE_UNITS / 2 ;
2007-06-28 10:47:08 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
//called via the script in a Limbo Expand level to set the level to plain ol' expand
2011-03-12 17:32:15 -08:00
bool scrResetLimboMission ( void )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
//check currently on a Limbo expand mission
if ( ! missionLimboExpand ( ) )
{
ASSERT ( false , " scrResetLimboMission: current mission type invalid " ) ;
return false ;
}
2007-06-28 10:47:08 -07:00
2012-12-16 12:03:00 -08:00
//turn it into an expand mission
resetLimboMission ( ) ;
2007-06-28 10:47:08 -07:00
2012-12-16 12:03:00 -08:00
return true ;
2007-06-28 10:47:08 -07:00
}
// skirmish only.
2011-03-12 17:32:15 -08:00
bool scrIsVtol ( void )
2007-06-28 10:47:08 -07:00
{
DROID * psDroid ;
if ( ! stackPopParams ( 1 , ST_DROID , & psDroid ) )
{
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
2012-12-16 12:03:00 -08:00
if ( psDroid = = NULL )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrIsVtol: null droid passed in. " ) ;
2007-06-28 10:47:08 -07:00
}
2008-07-07 03:15:00 -07:00
scrFunctionResult . v . bval = isVtolDroid ( psDroid ) ;
2006-11-19 12:50:02 -08:00
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
2012-05-09 17:55:17 -07:00
// Fix the tutorial's template list(s).
// DO NOT MODIFY THIS WITHOUT KNOWING WHAT YOU ARE DOING. You will break the tutorial!
// In short, we want to design a ViperLtMGWheels, but it is already available to make, so we must delete it.
2011-03-12 17:32:15 -08:00
bool scrTutorialTemplates ( void )
2007-06-28 10:47:08 -07:00
{
2013-05-12 14:50:57 -07:00
#if 0
2007-06-28 10:47:08 -07:00
DROID_TEMPLATE * psCurr , * psPrev ;
// find ViperLtMGWheels
2011-01-01 11:35:07 -08:00
char const * pName = getDroidResourceName ( " ViperLtMGWheels " ) ;
2006-05-27 09:37:17 -07:00
2012-05-09 17:55:17 -07:00
for ( psCurr = apsDroidTemplates [ selectedPlayer ] , psPrev = NULL ; psCurr ! = NULL ; psCurr = psCurr - > psNext )
2007-06-28 10:47:08 -07:00
{
2013-05-12 14:50:57 -07:00
if ( psCurr - > name . compare ( pName ) = = 0 )
2007-06-28 10:47:08 -07:00
{
if ( psPrev )
{
psPrev - > psNext = psCurr - > psNext ;
}
else
{
apsDroidTemplates [ selectedPlayer ] = psCurr - > psNext ;
}
break ;
}
psPrev = psCurr ;
}
2006-05-27 09:37:17 -07:00
2012-05-09 17:55:17 -07:00
// Delete the template in *both* lists!
2012-12-16 12:03:00 -08:00
if ( psCurr )
2007-06-28 10:47:08 -07:00
{
2012-05-09 17:55:17 -07:00
for ( std : : list < DROID_TEMPLATE > : : iterator i = localTemplates . begin ( ) ; i ! = localTemplates . end ( ) ; + + i )
{
DROID_TEMPLATE * dropTemplate = & * i ;
if ( psCurr - > multiPlayerID = = dropTemplate - > multiPlayerID )
{
free ( dropTemplate - > pName ) ;
localTemplates . erase ( i ) ;
break ;
}
}
2011-01-01 11:35:07 -08:00
delete psCurr ;
2007-06-28 10:47:08 -07:00
}
else
{
2012-12-16 12:03:00 -08:00
debug ( LOG_FATAL , " tutorial template setup failed " ) ;
2006-08-22 07:28:49 -07:00
abort ( ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2013-05-12 14:50:57 -07:00
# endif
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
2006-08-20 07:48:14 -07:00
//-----------------------------------------
//New functions
//-----------------------------------------
//compare two strings (0 means they are different)
2011-03-12 17:32:15 -08:00
bool scrStrcmp ( void )
2006-08-20 07:48:14 -07:00
{
2006-11-16 06:30:29 -08:00
if ( ! stackPopParams ( 2 , VAL_STRING , & strParam1 , VAL_STRING , & strParam2 ) )
2006-08-20 07:48:14 -07:00
{
debug ( LOG_ERROR , " scrStrcmp(): stack failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-20 07:48:14 -07:00
}
2006-08-21 09:49:32 -07:00
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . bval = ! strcmp ( strParam1 , strParam2 ) ;
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2006-08-20 07:48:14 -07:00
{
debug ( LOG_ERROR , " scrStrcmp: failed to push result " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-20 07:48:14 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-08-20 07:48:14 -07:00
}
/* Output a string to console */
2011-03-12 17:32:15 -08:00
bool scrConsole ( void )
2006-08-20 07:48:14 -07:00
{
2006-11-16 06:30:29 -08:00
if ( ! stackPopParams ( 1 , VAL_STRING , & strParam1 ) )
2006-08-20 07:48:14 -07:00
{
debug ( LOG_ERROR , " scrConsole(): stack failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-20 07:48:14 -07:00
}
2012-12-16 12:03:00 -08:00
addConsoleMessage ( strParam1 , DEFAULT_JUSTIFY , SYSTEM_MESSAGE ) ;
2006-08-20 07:48:14 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2006-08-20 07:48:14 -07:00
}
2011-03-19 18:52:25 -07:00
int32_t scrDebug [ MAX_PLAYERS ] ; // was BOOL (int) ** see warning about conversion
2006-08-20 07:48:14 -07:00
//turn on debug messages
2011-03-12 17:32:15 -08:00
bool scrDbgMsgOn ( void )
2006-08-20 07:48:14 -07:00
{
2011-03-19 18:52:25 -07:00
int32_t bOn ; // was BOOL (int) ** see warning about conversion
2006-08-20 07:48:14 -07:00
SDWORD player ;
if ( ! stackPopParams ( 2 , VAL_INT , & player , VAL_BOOL , & bOn ) )
{
2012-12-16 12:03:00 -08:00
debug ( LOG_ERROR , " stack failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-20 07:48:14 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2006-08-20 07:48:14 -07:00
scrDebug [ player ] = bOn ;
2008-03-24 09:51:17 -07:00
return true ;
2006-08-20 07:48:14 -07:00
}
2011-03-12 17:32:15 -08:00
bool scrMsg ( void )
2006-08-20 07:48:14 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD playerTo , playerFrom ;
2006-11-03 13:35:50 -08:00
char tmp [ 255 ] ;
2006-08-20 07:48:14 -07:00
2006-11-16 06:30:29 -08:00
if ( ! stackPopParams ( 3 , VAL_STRING , & strParam1 , VAL_INT , & playerFrom , VAL_INT , & playerTo ) )
2006-08-20 07:48:14 -07:00
{
debug ( LOG_ERROR , " scrMsg(): stack failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-20 07:48:14 -07:00
}
2012-12-16 12:03:00 -08:00
if ( playerFrom < 0 | | playerFrom > = MAX_PLAYERS )
2006-08-20 07:48:14 -07:00
{
debug ( LOG_ERROR , " scrMsg(): playerFrom out of range " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-20 07:48:14 -07:00
}
2012-12-16 12:03:00 -08:00
if ( playerTo < 0 | | playerTo > = MAX_PLAYERS )
2006-08-20 07:48:14 -07:00
{
debug ( LOG_ERROR , " scrMsg(): playerTo out of range " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-20 07:48:14 -07:00
}
2012-11-16 06:27:53 -08:00
ssprintf ( tmp , " %d%s " , playerTo , strParam1 ) ;
sendTextMessage ( tmp , false , playerFrom ) ;
2006-08-20 07:48:14 -07:00
//show the message we sent on our local console as well (even in skirmish, if player plays as this AI)
2012-12-16 12:03:00 -08:00
if ( playerFrom = = selectedPlayer )
2006-08-20 07:48:14 -07:00
{
2012-11-16 06:27:53 -08:00
ssprintf ( tmp , " [%d-%d] : %s " , playerFrom , playerTo , strParam1 ) ; // add message
2008-03-30 10:59:13 -07:00
addConsoleMessage ( tmp , RIGHT_JUSTIFY , playerFrom ) ;
2006-08-20 07:48:14 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-08-20 07:48:14 -07:00
}
2011-03-12 17:32:15 -08:00
bool scrDbg ( void )
2006-08-20 07:48:14 -07:00
{
SDWORD player ;
2006-08-21 09:49:32 -07:00
2006-11-16 06:30:29 -08:00
if ( ! stackPopParams ( 2 , VAL_STRING , & strParam1 , VAL_INT , & player ) )
2006-08-20 07:48:14 -07:00
{
debug ( LOG_ERROR , " scrDbg(): stack failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-20 07:48:14 -07:00
}
2012-12-16 12:03:00 -08:00
if ( scrDebug [ player ] )
2006-08-20 07:48:14 -07:00
{
2006-11-03 13:35:50 -08:00
char sTmp [ 255 ] ;
2012-12-16 12:03:00 -08:00
sprintf ( sTmp , " %d) %s " , player , strParam1 ) ;
addConsoleMessage ( sTmp , DEFAULT_JUSTIFY , player ) ;
2006-08-20 07:48:14 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-08-20 07:48:14 -07:00
}
2011-03-12 17:32:15 -08:00
bool scrDebugFile ( void )
2006-08-21 15:13:13 -07:00
{
2006-11-16 06:30:29 -08:00
if ( ! stackPopParams ( 1 , VAL_STRING , & strParam1 ) )
2006-08-21 15:13:13 -07:00
{
debug ( LOG_ERROR , " scrDebugFile(): stack failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 15:13:13 -07:00
}
2008-11-04 15:09:31 -08:00
debug ( LOG_SCRIPT , " %s " , strParam1 ) ;
2006-08-21 15:13:13 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 15:13:13 -07:00
}
2007-06-28 10:47:08 -07:00
static UDWORD playerToEnumDroid ;
static UDWORD playerVisibleDroid ;
static UDWORD enumDroidCount ;
/* Prepare the droid iteration */
2011-03-12 17:32:15 -08:00
bool scrInitEnumDroids ( void )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD targetplayer , playerVisible ;
2006-05-27 09:37:17 -07:00
2012-12-16 12:03:00 -08:00
if ( ! stackPopParams ( 2 , VAL_INT , & targetplayer , VAL_INT , & playerVisible ) )
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
playerToEnumDroid = ( UDWORD ) targetplayer ;
playerVisibleDroid = ( UDWORD ) playerVisible ;
enumDroidCount = 0 ; //returned 0 droids so far
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
/* Get next droid */
2011-03-12 17:32:15 -08:00
bool scrEnumDroid ( void )
2007-06-28 10:47:08 -07:00
{
UDWORD count ;
DROID * psDroid ;
count = 0 ;
2012-12-16 12:03:00 -08:00
for ( psDroid = apsDroidLists [ playerToEnumDroid ] ; psDroid & & count < enumDroidCount ; count + + )
2007-06-28 10:47:08 -07:00
{
psDroid = psDroid - > psNext ;
}
//search the players' list of droid to see if one exists and is visible
2012-12-16 12:03:00 -08:00
while ( psDroid )
2007-06-28 10:47:08 -07:00
{
2012-12-16 12:03:00 -08:00
if ( psDroid - > visible [ playerVisibleDroid ] )
2007-06-28 10:47:08 -07:00
{
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . oval = psDroid ;
if ( ! stackPushResult ( ( INTERP_TYPE ) ST_DROID , & scrFunctionResult ) ) // push scrFunctionResult
2007-06-28 10:47:08 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
enumDroidCount + + ;
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
enumDroidCount + + ;
psDroid = psDroid - > psNext ;
}
// push NULLDROID, since didn't find any
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . oval = NULL ;
if ( ! stackPushResult ( ( INTERP_TYPE ) ST_DROID , & scrFunctionResult ) )
2007-06-28 10:47:08 -07:00
{
2006-08-20 07:48:14 -07:00
debug ( LOG_ERROR , " scrEnumDroid() - push failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-06-28 10:47:08 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-06-28 10:47:08 -07:00
}
2006-08-19 06:26:11 -07:00
2006-08-20 07:48:14 -07:00
//Return the template factory is currently building
2011-03-12 17:32:15 -08:00
bool scrFactoryGetTemplate ( void )
2006-08-20 07:48:14 -07:00
{
STRUCTURE * psStructure = NULL ;
DROID_TEMPLATE * psTemplate = NULL ;
2006-08-19 06:26:11 -07:00
2006-11-24 17:26:05 -08:00
if ( ! stackPopParams ( 1 , ST_STRUCTURE , & psStructure ) )
2006-08-20 07:48:14 -07:00
{
debug ( LOG_ERROR , " scrFactoryGetTemplate() - stackPopParams failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-20 07:48:14 -07:00
}
2006-08-19 06:26:11 -07:00
2006-08-20 07:48:14 -07:00
if ( psStructure = = NULL )
2006-08-19 06:26:11 -07:00
{
2006-08-21 08:33:49 -07:00
debug ( LOG_ERROR , " scrFactoryGetTemplate() - NULL factory object " ) ;
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrFactoryGetTemplate: NULL factory object " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-19 06:26:11 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT ( psStructure ! = NULL ,
" scrFactoryGetTemplate: Invalid structure pointer " ) ;
ASSERT ( ( psStructure - > pStructureType - > type = = REF_FACTORY | |
psStructure - > pStructureType - > type = = REF_CYBORG_FACTORY | |
psStructure - > pStructureType - > type = = REF_VTOL_FACTORY ) ,
" scrFactoryGetTemplate: structure is not a factory " ) ;
2006-08-20 07:48:14 -07:00
2012-12-16 12:03:00 -08:00
if ( ! StructIsFactory ( psStructure ) )
2006-08-19 06:26:11 -07:00
{
2006-08-20 07:48:14 -07:00
debug ( LOG_ERROR , " scrFactoryGetTemplate: structure not a factory. " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-19 06:26:11 -07:00
}
2012-12-16 12:03:00 -08:00
psTemplate = ( DROID_TEMPLATE * ) ( ( FACTORY * ) psStructure - > pFunctionality ) - > psSubject ;
2006-08-20 07:48:14 -07:00
2012-12-16 12:03:00 -08:00
ASSERT ( psTemplate ! = NULL ,
" scrFactoryGetTemplate: Invalid template pointer " ) ;
2006-08-20 07:48:14 -07:00
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . oval = psTemplate ;
if ( ! stackPushResult ( ( INTERP_TYPE ) ST_TEMPLATE , & scrFunctionResult ) )
2006-08-20 07:48:14 -07:00
{
debug ( LOG_ERROR , " scrFactoryGetTemplate: stackPushResult failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-20 07:48:14 -07:00
}
2006-08-19 06:26:11 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
2011-03-12 17:32:15 -08:00
bool scrNumTemplatesInProduction ( void )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD player , numTemplates = 0 ;
2006-08-21 08:33:49 -07:00
DROID_TEMPLATE * psTemplate ;
2012-12-16 12:03:00 -08:00
STRUCTURE * psStruct ;
2006-08-21 08:33:49 -07:00
STRUCTURE * psList ;
BASE_STATS * psBaseStats ;
if ( ! stackPopParams ( 2 , ST_TEMPLATE , & psTemplate , VAL_INT , & player ) )
{
debug ( LOG_ERROR , " scrNumTemplatesInProduction: stackPopParams failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
if ( player > = MAX_PLAYERS )
{
debug ( LOG_ERROR , " scrNumTemplatesInProduction: player number is too high " ) ;
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrNumTemplatesInProduction: player number is too high " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT ( psTemplate ! = NULL ,
" scrNumTemplatesInProduction: Invalid template pointer " ) ;
2006-08-21 08:33:49 -07:00
psBaseStats = ( BASE_STATS * ) psTemplate ; //Convert
psList = apsStructLists [ player ] ;
for ( psStruct = psList ; psStruct ! = NULL ; psStruct = psStruct - > psNext )
{
if ( StructIsFactory ( psStruct ) )
{
FACTORY * psFactory = ( FACTORY * ) psStruct - > pFunctionality ;
2006-08-21 09:49:32 -07:00
2006-08-21 08:33:49 -07:00
//if this is the template currently being worked on
if ( psBaseStats = = psFactory - > psSubject )
{
numTemplates + + ;
}
}
}
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . ival = numTemplates ;
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
2006-08-21 08:33:49 -07:00
{
debug ( LOG_ERROR , " scrNumTemplatesInProduction: stackPushResult failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
// Returns number of units based on a component a certain player has
2011-03-12 17:32:15 -08:00
bool scrNumDroidsByComponent ( void )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD player , lookingPlayer , comp ;
2006-08-21 08:33:49 -07:00
UDWORD numFound ;
INTERP_VAL sVal ;
DROID * psDroid ;
if ( ! stackPopParams ( 2 , VAL_INT , & player , VAL_INT , & lookingPlayer ) )
{
debug ( LOG_ERROR , " scrNumDroidsByComponent(): stack failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2006-08-21 08:33:49 -07:00
if ( ! stackPop ( & sVal ) )
{
debug ( LOG_ERROR , " scrNumDroidsByComponent(): failed to pop component " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
numFound = 0 ;
comp = ( SDWORD ) sVal . v . ival ; //cache access
//check droids
2012-12-16 12:03:00 -08:00
for ( psDroid = apsDroidLists [ player ] ; psDroid ; psDroid = psDroid - > psNext )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
if ( psDroid - > visible [ lookingPlayer ] ) //can see this droid?
2006-08-21 08:33:49 -07:00
{
2010-12-21 15:58:59 -08:00
switch ( ( unsigned ) sVal . type ) // Unsigned cast to suppress compiler warnings due to enum abuse.
2006-08-21 08:33:49 -07:00
{
case ST_BODY :
2013-05-09 04:24:19 -07:00
if ( psDroid - > asBits [ COMP_BODY ] = = comp )
2006-08-21 08:33:49 -07:00
{
numFound + + ;
}
break ;
case ST_PROPULSION :
2013-05-09 04:24:19 -07:00
if ( psDroid - > asBits [ COMP_PROPULSION ] = = comp )
2006-08-21 08:33:49 -07:00
{
numFound + + ;
}
break ;
case ST_ECM :
2013-05-09 04:24:19 -07:00
if ( psDroid - > asBits [ COMP_ECM ] = = comp )
2006-08-21 08:33:49 -07:00
{
numFound + + ;
}
break ;
case ST_SENSOR :
2013-05-09 04:24:19 -07:00
if ( psDroid - > asBits [ COMP_SENSOR ] = = comp )
2006-08-21 08:33:49 -07:00
{
numFound + + ;
}
break ;
case ST_CONSTRUCT :
2013-05-09 04:24:19 -07:00
if ( psDroid - > asBits [ COMP_CONSTRUCT ] = = comp )
2006-08-21 08:33:49 -07:00
{
numFound + + ;
}
break ;
case ST_REPAIR :
2013-05-09 04:24:19 -07:00
if ( psDroid - > asBits [ COMP_REPAIRUNIT ] = = comp )
2006-08-21 08:33:49 -07:00
{
numFound + + ;
}
break ;
case ST_WEAPON :
if ( psDroid - > asWeaps [ 0 ] . nStat = = comp )
{
numFound + + ;
break ;
}
break ;
2007-07-19 12:28:25 -07:00
case ST_BRAIN :
2013-05-09 04:24:19 -07:00
if ( psDroid - > asBits [ COMP_BRAIN ] = = comp )
2007-07-19 12:28:25 -07:00
{
numFound + + ;
}
break ;
2006-08-21 08:33:49 -07:00
default :
debug ( LOG_ERROR , " scrNumDroidsByComponent(): unknown component type " ) ;
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrNumDroidsByComponent: unknown component type " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
}
}
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . ival = numFound ;
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
2006-08-21 08:33:49 -07:00
{
debug ( LOG_ERROR , " scrNumDroidsByComponent(): stackPushResult failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
2011-03-12 17:32:15 -08:00
bool scrGetStructureLimit ( void )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD player , limit ;
2006-08-21 08:33:49 -07:00
UDWORD structInc ;
STRUCTURE_LIMITS * psStructLimits ;
if ( ! stackPopParams ( 2 , ST_STRUCTURESTAT , & structInc , VAL_INT , & player ) )
{
debug ( LOG_ERROR , " scrGetStructureLimit(): stackPopParams failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
if ( player > = MAX_PLAYERS )
{
debug ( LOG_ERROR , " scrGetStructureLimit(): player number is too high " ) ;
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrSetStructureLimits: player number is too high " ) ;
return false ;
}
2006-08-21 08:33:49 -07:00
if ( structInc > numStructureStats )
{
debug ( LOG_ERROR , " scrGetStructureLimit(): tructure stat is too high - %d " , structInc ) ;
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrSetStructureLimits: Structure stat is too high - %d " , structInc ) ;
return false ;
}
2006-08-21 08:33:49 -07:00
psStructLimits = asStructLimits [ player ] ;
limit = ( SDWORD ) psStructLimits [ structInc ] . limit ;
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . ival = limit ;
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
2006-08-21 08:33:49 -07:00
{
debug ( LOG_ERROR , " scrGetStructureLimit(): stackPushResult failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
2008-03-24 09:51:17 -07:00
// Returns true if limit for the passed structurestat is reached, otherwise returns false
2011-03-12 17:32:15 -08:00
bool scrStructureLimitReached ( void )
2006-08-21 08:33:49 -07:00
{
SDWORD player ;
2011-03-12 17:32:15 -08:00
bool bLimit = false ;
2006-08-21 08:33:49 -07:00
UDWORD structInc ;
STRUCTURE_LIMITS * psStructLimits ;
if ( ! stackPopParams ( 2 , ST_STRUCTURESTAT , & structInc , VAL_INT , & player ) )
{
debug ( LOG_ERROR , " scrStructureLimitReached(): stackPopParams failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
if ( player > = MAX_PLAYERS )
{
debug ( LOG_ERROR , " scrStructureLimitReached(): player number is too high " ) ;
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrSetStructureLimits: player number is too high " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
if ( structInc > numStructureStats )
{
debug ( LOG_ERROR , " scrStructureLimitReached(): Structure stat is too high - %d " , structInc ) ;
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrSetStructureLimits: Structure stat is too high - %d " , structInc ) ;
return false ;
}
2006-08-21 08:33:49 -07:00
psStructLimits = asStructLimits [ player ] ;
2012-12-16 12:03:00 -08:00
if ( psStructLimits [ structInc ] . currentQuantity > = psStructLimits [ structInc ] . limit )
{
bLimit = true ;
}
2006-08-21 08:33:49 -07:00
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . bval = bLimit ;
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2006-08-21 08:33:49 -07:00
{
debug ( LOG_ERROR , " scrStructureLimitReached(): stackPushResult failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
// How many structures of a given type a player has
2011-03-12 17:32:15 -08:00
bool scrGetNumStructures ( void )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD player , numStructures ;
2006-08-21 08:33:49 -07:00
UDWORD structInc ;
STRUCTURE_LIMITS * psStructLimits ;
if ( ! stackPopParams ( 2 , ST_STRUCTURESTAT , & structInc , VAL_INT , & player ) )
{
debug ( LOG_ERROR , " scrSetStructureLimits: failed to pop " ) ;
2012-12-16 12:03:00 -08:00
return false ;
}
2006-08-21 08:33:49 -07:00
if ( player > = MAX_PLAYERS )
{
debug ( LOG_ERROR , " scrSetStructureLimits:player number is too high " ) ;
2012-12-16 12:03:00 -08:00
return false ;
}
2006-08-21 08:33:49 -07:00
if ( structInc > numStructureStats )
{
debug ( LOG_ERROR , " scrSetStructureLimits: Structure stat is too high " ) ;
2012-12-16 12:03:00 -08:00
return false ;
}
2006-08-21 08:33:49 -07:00
psStructLimits = asStructLimits [ player ] ;
numStructures = ( SDWORD ) psStructLimits [ structInc ] . currentQuantity ;
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . ival = numStructures ;
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
2006-08-21 08:33:49 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
// Return player's unit limit
2011-03-12 17:32:15 -08:00
bool scrGetUnitLimit ( void )
2006-08-21 08:33:49 -07:00
{
2006-11-16 06:30:29 -08:00
SDWORD player ;
2006-08-21 08:33:49 -07:00
if ( ! stackPopParams ( 1 , VAL_INT , & player ) )
{
debug ( LOG_ERROR , " scrGetUnitLimit: failed to pop " ) ;
2012-12-16 12:03:00 -08:00
return false ;
}
2006-08-21 08:33:49 -07:00
if ( player > = MAX_PLAYERS )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrSetStructureLimits:player number is too high " ) ;
return false ;
}
2006-08-21 08:33:49 -07:00
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . ival = getMaxDroids ( player ) ;
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
2006-08-21 08:33:49 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
// Return minimum of 2 vals
2011-03-12 17:32:15 -08:00
bool scrMin ( void )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD val1 , val2 ;
2006-08-21 08:33:49 -07:00
if ( ! stackPopParams ( 2 , VAL_INT , & val1 , VAL_INT , & val2 ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2006-11-16 06:30:29 -08:00
}
2006-08-21 08:33:49 -07:00
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . ival = MIN ( val2 , val1 ) ;
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
2006-08-21 08:33:49 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
// Return maximum of 2 vals
2011-03-12 17:32:15 -08:00
bool scrMax ( void )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD val1 , val2 ;
2006-08-21 08:33:49 -07:00
if ( ! stackPopParams ( 2 , VAL_INT , & val1 , VAL_INT , & val2 ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . ival = MAX ( val1 , val2 ) ;
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
2006-08-21 08:33:49 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
2011-03-12 17:32:15 -08:00
bool scrFMin ( void )
2006-12-02 15:27:00 -08:00
{
2012-12-16 12:03:00 -08:00
float fval1 , fval2 ;
2006-12-02 15:27:00 -08:00
if ( ! stackPopParams ( 2 , VAL_FLOAT , & fval1 , VAL_FLOAT , & fval2 ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2006-12-02 15:27:00 -08:00
}
scrFunctionResult . v . fval = MIN ( fval2 , fval1 ) ;
if ( ! stackPushResult ( VAL_FLOAT , & scrFunctionResult ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2006-12-02 15:27:00 -08:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-12-02 15:27:00 -08:00
}
// Return maximum of 2 floats
2011-03-12 17:32:15 -08:00
bool scrFMax ( void )
2006-12-02 15:27:00 -08:00
{
2012-12-16 12:03:00 -08:00
float fval1 , fval2 ;
2006-12-02 15:27:00 -08:00
if ( ! stackPopParams ( 2 , VAL_FLOAT , & fval1 , VAL_FLOAT , & fval2 ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2006-12-02 15:27:00 -08:00
}
scrFunctionResult . v . fval = MAX ( fval1 , fval2 ) ;
if ( ! stackPushResult ( VAL_FLOAT , & scrFunctionResult ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2006-12-02 15:27:00 -08:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-12-02 15:27:00 -08:00
}
2011-03-12 17:32:15 -08:00
bool ThreatInRange ( SDWORD player , SDWORD range , SDWORD rangeX , SDWORD rangeY , bool bVTOLs )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
UDWORD i , structType ;
2006-08-21 08:33:49 -07:00
STRUCTURE * psStruct ;
DROID * psDroid ;
2008-10-14 13:25:41 -07:00
const int tx = map_coord ( rangeX ) ;
const int ty = map_coord ( rangeY ) ;
2006-08-21 08:33:49 -07:00
2012-12-16 12:03:00 -08:00
for ( i = 0 ; i < MAX_PLAYERS ; i + + )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
if ( ( alliances [ player ] [ i ] = = ALLIANCE_FORMED ) | | ( i = = player ) )
2006-08-21 08:33:49 -07:00
{
continue ;
}
//check structures
2012-12-16 12:03:00 -08:00
for ( psStruct = apsStructLists [ i ] ; psStruct ; psStruct = psStruct - > psNext )
2006-08-21 08:33:49 -07:00
{
2010-02-16 13:16:15 -08:00
if ( psStruct - > visible [ player ] | | psStruct - > born = = 2 ) // if can see it or started there
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
if ( psStruct - > status = = SS_BUILT )
2006-08-21 08:33:49 -07:00
{
2007-09-29 08:04:25 -07:00
structType = psStruct - > pStructureType - > type ;
2006-08-21 08:33:49 -07:00
2012-12-16 12:03:00 -08:00
switch ( structType ) //dangerous to get near these structures
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
case REF_DEFENSE :
case REF_CYBORG_FACTORY :
case REF_FACTORY :
case REF_VTOL_FACTORY :
case REF_REARM_PAD :
2007-09-29 08:04:25 -07:00
if ( range < 0
2012-12-16 12:03:00 -08:00
| | world_coord ( hypotf ( tx - map_coord ( psStruct - > pos . x ) , ty - map_coord ( psStruct - > pos . y ) ) ) < range ) //enemy in range
2007-09-29 08:04:25 -07:00
{
2008-03-24 09:51:17 -07:00
return true ;
2007-09-29 08:04:25 -07:00
}
2006-08-21 08:33:49 -07:00
2007-09-29 08:04:25 -07:00
break ;
}
2006-08-21 08:33:49 -07:00
}
}
}
//check droids
2012-02-25 16:21:29 -08:00
for ( psDroid = apsDroidLists [ i ] ; psDroid ; psDroid = psDroid - > psNext )
2006-08-21 08:33:49 -07:00
{
2012-02-25 16:21:29 -08:00
if ( psDroid - > visible [ player ] ) //can see this droid?
2006-08-21 08:33:49 -07:00
{
2008-01-05 11:42:43 -08:00
if ( ! objHasWeapon ( ( BASE_OBJECT * ) psDroid ) )
2006-08-21 08:33:49 -07:00
{
continue ;
}
//if VTOLs are excluded, skip them
2013-05-09 04:24:19 -07:00
if ( ! bVTOLs & & ( ( asPropulsionStats [ psDroid - > asBits [ COMP_PROPULSION ] ] . propulsionType = = PROPULSION_TYPE_LIFT ) | | ( psDroid - > droidType = = DROID_TRANSPORTER | | psDroid - > droidType = = DROID_SUPERTRANSPORTER ) ) )
2006-08-21 08:33:49 -07:00
{
continue ;
}
2007-09-28 12:25:21 -07:00
if ( range < 0
2012-12-16 12:03:00 -08:00
| | world_coord ( hypotf ( tx - map_coord ( psDroid - > pos . x ) , ty - map_coord ( psDroid - > pos . y ) ) ) < range ) //enemy in range
2006-08-21 08:33:49 -07:00
{
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
}
}
}
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
//find unrevealed tile closest to pwLooker within the range of wRange
2011-03-12 17:32:15 -08:00
bool scrFogTileInRange ( void )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD pwLookerX , pwLookerY , tBestX , tBestY , threadRange ;
SDWORD wRangeX , wRangeY , tRangeX , tRangeY , wRange , player ;
UDWORD tx , ty , i , j , wDist , wBestDist ;
2006-08-21 08:33:49 -07:00
MAPTILE * psTile ;
2011-03-12 17:32:15 -08:00
bool ok = false ;
2012-12-16 12:03:00 -08:00
SDWORD * wTileX , * wTileY ;
2006-08-21 08:33:49 -07:00
2012-12-16 12:03:00 -08:00
if ( ! stackPopParams ( 9 , VAL_REF | VAL_INT , & wTileX , VAL_REF | VAL_INT , & wTileY ,
VAL_INT , & pwLookerX , VAL_INT , & pwLookerY , VAL_INT , & wRangeX , VAL_INT , & wRangeY ,
VAL_INT , & wRange , VAL_INT , & player , VAL_INT , & threadRange ) )
2006-08-21 08:33:49 -07:00
{
debug ( LOG_ERROR , " scrFogTileInRange: failed to pop " ) ;
2012-12-16 12:03:00 -08:00
return false ;
}
2006-08-21 08:33:49 -07:00
2012-12-16 12:03:00 -08:00
//Check coords
if ( pwLookerX < 0
| | pwLookerX > world_coord ( mapWidth )
| | pwLookerY < 0
| | pwLookerY > world_coord ( mapHeight ) )
2006-08-21 08:33:49 -07:00
{
debug ( LOG_ERROR , " scrFogTileInRange: coords off map " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2007-09-28 12:25:21 -07:00
tRangeX = map_coord ( wRangeX ) ; //cache to tile coords, for faster calculations
tRangeY = map_coord ( wRangeY ) ;
2006-08-21 08:33:49 -07:00
2007-09-28 12:25:21 -07:00
tx = map_coord ( pwLookerX ) ; // change to tile coords.
ty = map_coord ( pwLookerY ) ;
2006-08-21 08:33:49 -07:00
wBestDist = 99999 ;
tBestX = - 1 ; tBestY = - 1 ;
2012-12-16 12:03:00 -08:00
for ( i = 0 ; i < mapWidth ; i + + )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
for ( j = 0 ; j < mapHeight ; j + + )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
psTile = mapTile ( i , j ) ;
if ( ! TEST_TILE_VISIBLE ( player , psTile ) ) //not vis
{
2006-08-21 08:33:49 -07:00
//within base range
2007-09-28 12:25:21 -07:00
if ( wRange < = 0
2012-12-16 12:03:00 -08:00
| | world_coord ( iHypot ( tRangeX - i , tRangeY - j ) ) < wRange ) //dist in world units between baseX/baseY and the tile
2006-08-21 08:33:49 -07:00
{
//calc dist between this tile and looker
2010-03-05 05:42:57 -08:00
wDist = world_coord ( iHypot ( tx - i , ty - j ) ) ;
2006-08-21 08:33:49 -07:00
//closer than last one?
2012-12-16 12:03:00 -08:00
if ( wDist < wBestDist )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
if ( zonedPAT ( i , j ) ) //Can reach this tile
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
if ( ( threadRange < = 0 ) | | ( ! ThreatInRange ( player , threadRange , world_coord ( i ) , world_coord ( j ) , false ) ) )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
wBestDist = wDist ;
tBestX = i ;
tBestY = j ;
ok = true ;
2006-08-21 08:33:49 -07:00
}
2006-08-21 09:49:32 -07:00
}
2006-08-21 08:33:49 -07:00
}
}
2012-12-16 12:03:00 -08:00
}
2006-08-21 08:33:49 -07:00
}
}
2012-12-16 12:03:00 -08:00
if ( ok ) //something found
2006-08-21 08:33:49 -07:00
{
2007-09-28 12:25:21 -07:00
* wTileX = world_coord ( tBestX ) ;
* wTileY = world_coord ( tBestY ) ;
2006-08-21 08:33:49 -07:00
2008-03-24 09:51:17 -07:00
scrFunctionResult . v . bval = true ;
2006-11-19 12:50:02 -08:00
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2006-08-21 08:33:49 -07:00
{
debug ( LOG_ERROR , " scrFogTileInRange: stackPushResult failed (found) " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
}
else
{
2008-03-24 09:51:17 -07:00
scrFunctionResult . v . bval = false ;
2006-11-19 12:50:02 -08:00
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2006-08-21 08:33:49 -07:00
{
debug ( LOG_ERROR , " scrFogTileInRange: stackPushResult failed (not found) " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
}
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
2011-03-12 17:32:15 -08:00
bool scrMapRevealedInRange ( void )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD wRangeX , wRangeY , tRangeX , tRangeY , wRange , tRange , player ;
2010-12-19 16:43:28 -08:00
int i , j ;
2006-08-21 08:33:49 -07:00
if ( ! stackPopParams ( 4 , VAL_INT , & wRangeX , VAL_INT , & wRangeY ,
2012-12-16 12:03:00 -08:00
VAL_INT , & wRange , VAL_INT , & player ) )
2006-08-21 08:33:49 -07:00
{
debug ( LOG_ERROR , " scrMapRevealedInRange: failed to pop " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 09:49:32 -07:00
}
2006-08-21 08:33:49 -07:00
2012-12-16 12:03:00 -08:00
//Check coords
2007-09-28 12:25:21 -07:00
if ( wRangeX < 0
2012-12-16 12:03:00 -08:00
| | wRangeX > world_coord ( mapWidth )
| | wRangeY < 0
| | wRangeY > world_coord ( mapHeight ) )
2006-08-21 08:33:49 -07:00
{
debug ( LOG_ERROR , " scrMapRevealedInRange: coords off map " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2008-03-22 10:30:57 -07:00
// convert to tile coords
tRange = map_coord ( wRange ) ;
2007-09-28 12:25:21 -07:00
tRangeX = map_coord ( wRangeX ) ; //cache to tile coords, for faster calculations
tRangeY = map_coord ( wRangeY ) ;
2006-08-21 08:33:49 -07:00
2012-12-16 12:03:00 -08:00
for ( i = 0 ; i < mapWidth ; i + + )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
for ( j = 0 ; j < mapHeight ; j + + )
2006-08-21 08:33:49 -07:00
{
2008-03-22 10:30:57 -07:00
// don't bother checking if out of range
2012-12-16 12:03:00 -08:00
if ( abs ( tRangeX - i ) < tRange & & abs ( tRangeY - j ) < tRange )
2008-03-22 10:30:57 -07:00
{
2006-08-21 08:33:49 -07:00
//within range
2010-03-05 05:42:57 -08:00
if ( world_coord ( iHypot ( tRangeX - i , tRangeY - j ) ) < wRange //dist in world units between x/y and the tile
2012-12-16 12:03:00 -08:00
& & TEST_TILE_VISIBLE ( player , mapTile ( i , j ) ) ) //not visible
2006-08-21 08:33:49 -07:00
{
2008-03-24 09:51:17 -07:00
scrFunctionResult . v . bval = true ;
2006-11-19 12:50:02 -08:00
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2006-08-21 08:33:49 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2012-12-16 12:03:00 -08:00
}
2008-03-22 10:30:57 -07:00
}
2006-08-21 08:33:49 -07:00
}
}
//nothing found
2008-03-24 09:51:17 -07:00
scrFunctionResult . v . bval = false ;
2006-11-19 12:50:02 -08:00
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2006-08-21 08:33:49 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
2008-01-05 11:42:43 -08:00
/* Returns true if a certain map tile was revealed, ie fog of war was removed */
2011-03-12 17:32:15 -08:00
bool scrMapTileVisible ( void )
2008-01-05 11:42:43 -08:00
{
2012-12-16 12:03:00 -08:00
SDWORD tileX , tileY , player ;
2008-01-05 11:42:43 -08:00
if ( ! stackPopParams ( 3 , VAL_INT , & tileX , VAL_INT , & tileY , VAL_INT , & player ) )
{
debug ( LOG_ERROR , " scrMapTileVisible: failed to pop " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2008-01-05 11:42:43 -08:00
}
2012-12-16 12:03:00 -08:00
//Check coords
2008-01-05 11:42:43 -08:00
if ( tileX < 0
2012-12-16 12:03:00 -08:00
| | tileX > world_coord ( mapWidth )
| | tileY < 0
| | tileY > world_coord ( mapHeight ) )
2008-01-05 11:42:43 -08:00
{
debug ( LOG_ERROR , " scrMapTileVisible: coords off map " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2008-01-05 11:42:43 -08:00
}
2012-12-16 12:03:00 -08:00
if ( TEST_TILE_VISIBLE ( player , mapTile ( tileX , tileY ) ) )
2008-01-05 11:42:43 -08:00
{
2008-03-24 09:51:17 -07:00
scrFunctionResult . v . bval = true ;
2008-01-05 11:42:43 -08:00
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2008-01-05 11:42:43 -08:00
}
}
else
{
//not visible
2008-03-24 09:51:17 -07:00
scrFunctionResult . v . bval = false ;
2008-01-05 11:42:43 -08:00
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2008-01-05 11:42:43 -08:00
}
}
2008-03-24 09:51:17 -07:00
return true ;
2008-01-05 11:42:43 -08:00
}
2006-08-21 08:33:49 -07:00
//return number of reserach topics that are left to be researched
//for a certain technology to become available
2011-03-12 17:32:15 -08:00
bool scrNumResearchLeft ( void )
2006-08-21 08:33:49 -07:00
{
RESEARCH * psResearch ;
2012-12-16 12:03:00 -08:00
SDWORD player , iResult ;
UWORD cur , index , tempIndex ;
2006-08-21 08:33:49 -07:00
SWORD top ;
UWORD Stack [ 400 ] ;
2012-12-16 12:03:00 -08:00
if ( ! stackPopParams ( 2 , VAL_INT , & player , ST_RESEARCH , & psResearch ) )
2006-08-21 08:33:49 -07:00
{
debug ( LOG_ERROR , " scrNumResearchLeft(): stack failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2012-12-16 12:03:00 -08:00
if ( psResearch = = NULL )
2006-08-21 09:49:32 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrNumResearchLeft(): no such research topic " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2011-12-02 05:26:37 -08:00
index = psResearch - > index ;
if ( index > = asResearch . size ( ) )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrNumResearchLeft(): invalid research index " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2012-12-16 12:03:00 -08:00
if ( beingResearchedByAlly ( index , player ) )
2006-08-21 08:33:49 -07:00
{
2006-11-16 06:30:29 -08:00
iResult = 1 ;
2006-08-21 08:33:49 -07:00
}
2012-12-16 12:03:00 -08:00
else if ( IsResearchCompleted ( & asPlayerResList [ player ] [ index ] ) )
2006-08-21 08:33:49 -07:00
{
2006-11-16 06:30:29 -08:00
iResult = 0 ;
2006-08-21 08:33:49 -07:00
}
2012-12-16 12:03:00 -08:00
else if ( IsResearchStarted ( & asPlayerResList [ player ] [ index ] ) )
2006-08-21 08:33:49 -07:00
{
2006-11-16 06:30:29 -08:00
iResult = 1 ;
2006-08-21 08:33:49 -07:00
}
2012-12-16 12:03:00 -08:00
else if ( IsResearchPossible ( & asPlayerResList [ player ] [ index ] ) | | IsResearchCancelled ( & asPlayerResList [ player ] [ index ] ) )
2006-08-21 08:33:49 -07:00
{
2006-11-16 06:30:29 -08:00
iResult = 1 ;
2006-08-21 08:33:49 -07:00
}
2012-12-16 12:03:00 -08:00
else if ( skTopicAvail ( index , player ) )
2006-08-21 08:33:49 -07:00
{
2006-11-16 06:30:29 -08:00
iResult = 1 ;
2006-08-21 08:33:49 -07:00
}
else
{
2006-11-16 06:30:29 -08:00
iResult = 1 ; //init, count the top research topic as 1
2006-08-21 08:33:49 -07:00
top = - 1 ;
cur = 0 ; //start with first index's PR
2012-12-16 12:03:00 -08:00
while ( true ) //do
2006-08-21 08:33:49 -07:00
{
2011-12-02 05:26:37 -08:00
if ( cur > = asResearch [ index ] . pPRList . size ( ) ) //this one has no PRs or end of PRs reached
2006-08-21 08:33:49 -07:00
{
top = top - 2 ;
2012-12-16 12:03:00 -08:00
if ( top < ( - 1 ) )
2006-08-21 08:33:49 -07:00
{
break ; //end of stack
}
index = Stack [ top + 2 ] ; //if index = -1, then exit
cur = Stack [ top + 1 ] ; //go to next PR of the last node
2006-08-21 09:49:32 -07:00
2006-08-21 08:33:49 -07:00
}
else //end of PRs not reached
{
2011-12-02 05:26:37 -08:00
iResult + = asResearch [ index ] . pPRList . size ( ) ; //add num of PRs this topic has
2006-08-21 08:33:49 -07:00
tempIndex = asResearch [ index ] . pPRList [ cur ] ; //get cur node's index
2006-08-21 09:49:32 -07:00
2006-08-21 08:33:49 -07:00
//decide if has to check its PRs
2012-12-16 12:03:00 -08:00
if ( ! IsResearchCompleted ( & asPlayerResList [ player ] [ tempIndex ] ) & & //don't touch if completed already
! skTopicAvail ( index , player ) & & //has no unresearched PRs left if available
! beingResearchedByAlly ( index , player ) ) //will become available soon anyway
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
if ( asResearch [ tempIndex ] . pPRList . size ( ) > 0 ) //node has any nodes itself
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
Stack [ top + 1 ] = cur ; //so can go back to it further
Stack [ top + 2 ] = index ;
2006-08-21 08:33:49 -07:00
top = top + 2 ;
index = tempIndex ; //go 1 level further
cur = - 1 ; //start with first PR of this PR next time
}
}
}
cur + + ; //try next node of the main node
2012-12-16 12:03:00 -08:00
if ( ( cur > = asResearch [ index ] . pPRList . size ( ) ) & & ( top < = ( - 1 ) ) ) //nothing left
2006-08-21 08:33:49 -07:00
{
break ;
}
}
}
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . ival = iResult ;
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
2006-08-21 08:33:49 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
//check if any of the ally is researching this topic
2011-03-12 17:32:15 -08:00
bool beingResearchedByAlly ( SDWORD resIndex , SDWORD player )
2006-08-21 08:33:49 -07:00
{
SDWORD i ;
2012-12-16 12:03:00 -08:00
for ( i = 0 ; i < MAX_PLAYERS ; i + + )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
if ( i ! = player & & aiCheckAlliances ( player , i ) )
2006-08-21 08:33:49 -07:00
{
//check each research facility to see if they are doing this topic.
2011-03-20 13:05:31 -07:00
if ( IsResearchStartedPending ( & asPlayerResList [ i ] [ resIndex ] ) )
2006-08-21 08:33:49 -07:00
{
2011-03-20 13:05:31 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
}
}
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2008-03-24 09:51:17 -07:00
// true if player has completed this research
2011-03-12 17:32:15 -08:00
bool scrResearchCompleted ( void )
2006-08-21 08:33:49 -07:00
{
RESEARCH * psResearch ;
SDWORD player ;
UWORD index ;
2012-12-16 12:03:00 -08:00
if ( ! stackPopParams ( 2 , ST_RESEARCH , & psResearch , VAL_INT , & player ) )
2006-08-21 08:33:49 -07:00
{
2007-07-27 11:18:37 -07:00
debug ( LOG_ERROR , " scrResearchCompleted: stack failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2012-12-16 12:03:00 -08:00
if ( psResearch = = NULL )
2006-08-21 09:49:32 -07:00
{
2012-12-16 12:03:00 -08:00
debug ( LOG_ERROR , " scrResearchCompleted: no such research topic " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2011-12-02 05:26:37 -08:00
index = psResearch - > index ;
if ( index > = asResearch . size ( ) )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
debug ( LOG_ERROR , " scrResearchCompleted: invalid research index " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2012-12-16 12:03:00 -08:00
if ( IsResearchCompleted ( & asPlayerResList [ player ] [ index ] ) )
2006-08-21 08:33:49 -07:00
{
2008-03-24 09:51:17 -07:00
scrFunctionResult . v . bval = true ;
2006-11-19 12:50:02 -08:00
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2006-08-21 08:33:49 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
}
else
{
2008-03-24 09:51:17 -07:00
scrFunctionResult . v . bval = false ;
2006-11-19 12:50:02 -08:00
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2006-08-21 08:33:49 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
}
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
2008-03-24 09:51:17 -07:00
// true if player has already started researching it
2011-03-12 17:32:15 -08:00
bool scrResearchStarted ( void )
2006-08-21 08:33:49 -07:00
{
RESEARCH * psResearch ;
SDWORD player ;
UWORD index ;
2012-12-16 12:03:00 -08:00
if ( ! stackPopParams ( 2 , ST_RESEARCH , & psResearch , VAL_INT , & player ) )
2006-08-21 08:33:49 -07:00
{
debug ( LOG_ERROR , " scrResearchStarted(): stack failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2012-12-16 12:03:00 -08:00
if ( psResearch = = NULL )
2006-08-21 09:49:32 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " : no such research topic " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2011-12-02 05:26:37 -08:00
index = psResearch - > index ;
if ( index > = asResearch . size ( ) )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrResearchCompleted: invalid research index " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2011-12-02 05:26:37 -08:00
if ( IsResearchStartedPending ( & asPlayerResList [ player ] [ index ] ) )
2006-08-21 08:33:49 -07:00
{
2008-03-24 09:51:17 -07:00
scrFunctionResult . v . bval = true ;
2006-11-19 12:50:02 -08:00
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2006-08-21 08:33:49 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
}
else
{
2008-03-24 09:51:17 -07:00
scrFunctionResult . v . bval = false ;
2006-11-19 12:50:02 -08:00
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2006-08-21 08:33:49 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
}
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
2008-03-24 09:51:17 -07:00
//returns true if location is dangerous
2011-03-12 17:32:15 -08:00
bool scrThreatInRange ( void )
2006-08-21 08:33:49 -07:00
{
2011-03-19 18:52:25 -07:00
SDWORD player , range , rangeX , rangeY ;
int32_t bVTOLs ; // was BOOL (int) ** see warning about conversion
2006-08-21 08:33:49 -07:00
2006-08-21 09:49:32 -07:00
if ( ! stackPopParams ( 5 , VAL_INT , & player , VAL_INT , & rangeX ,
2012-12-16 12:03:00 -08:00
VAL_INT , & rangeY , VAL_INT , & range , VAL_BOOL , & bVTOLs ) )
2006-08-21 08:33:49 -07:00
{
debug ( LOG_ERROR , " scrThreatInRange(): stack failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . bval = ThreatInRange ( player , range , rangeX , rangeY , bVTOLs ) ;
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2006-08-21 08:33:49 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
2011-03-12 17:32:15 -08:00
bool scrNumEnemyWeapObjInRange ( void )
2006-08-21 08:33:49 -07:00
{
2011-03-19 18:52:25 -07:00
SDWORD lookingPlayer , range , rangeX , rangeY , i ;
UDWORD numEnemies = 0 ;
int32_t bVTOLs , bFinished ; // was BOOL (int) ** see warning about conversion
2006-08-21 08:33:49 -07:00
2007-09-29 08:04:25 -07:00
if ( ! stackPopParams ( 6 , VAL_INT , & lookingPlayer , VAL_INT , & rangeX ,
2012-12-16 12:03:00 -08:00
VAL_INT , & rangeY , VAL_INT , & range , VAL_BOOL , & bVTOLs , VAL_BOOL , & bFinished ) )
2006-08-21 08:33:49 -07:00
{
debug ( LOG_ERROR , " scrNumEnemyWeapObjInRange(): stack failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2012-12-16 12:03:00 -08:00
for ( i = 0 ; i < MAX_PLAYERS ; i + + )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
if ( ( alliances [ lookingPlayer ] [ i ] = = ALLIANCE_FORMED ) | | ( i = = lookingPlayer ) ) //skip allies and myself
2006-08-21 08:33:49 -07:00
{
continue ;
}
2007-09-29 08:04:25 -07:00
numEnemies + = numPlayerWeapDroidsInRange ( i , lookingPlayer , range , rangeX , rangeY , bVTOLs ) ;
numEnemies + = numPlayerWeapStructsInRange ( i , lookingPlayer , range , rangeX , rangeY , bFinished ) ;
2006-08-21 08:33:49 -07:00
}
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . ival = numEnemies ;
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
2006-08-21 08:33:49 -07:00
{
debug ( LOG_ERROR , " scrNumEnemyWeapObjInRange(): failed to push result " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
2007-09-29 08:04:25 -07:00
/* Calculates the total cost of enemy weapon objects in a certain area */
2011-03-12 17:32:15 -08:00
bool scrEnemyWeapObjCostInRange ( void )
2007-09-29 08:04:25 -07:00
{
2011-03-19 18:52:25 -07:00
SDWORD lookingPlayer , range , rangeX , rangeY , i ;
UDWORD enemyCost = 0 ;
int32_t bVTOLs , bFinished ; // was BOOL (int) ** see warning about conversion
2007-09-29 08:04:25 -07:00
if ( ! stackPopParams ( 6 , VAL_INT , & lookingPlayer , VAL_INT , & rangeX ,
2012-12-16 12:03:00 -08:00
VAL_INT , & rangeY , VAL_INT , & range , VAL_BOOL , & bVTOLs , VAL_BOOL , & bFinished ) )
2007-09-29 08:04:25 -07:00
{
debug ( LOG_ERROR , " scrEnemyWeapObjCostInRange(): stack failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-09-29 08:04:25 -07:00
}
2012-12-16 12:03:00 -08:00
for ( i = 0 ; i < MAX_PLAYERS ; i + + )
2007-09-29 08:04:25 -07:00
{
2012-12-16 12:03:00 -08:00
if ( ( alliances [ lookingPlayer ] [ i ] = = ALLIANCE_FORMED ) | | ( i = = lookingPlayer ) ) //skip allies and myself
2007-09-29 08:04:25 -07:00
{
continue ;
}
enemyCost + = playerWeapDroidsCostInRange ( i , lookingPlayer , range , rangeX , rangeY , bVTOLs ) ;
enemyCost + = playerWeapStructsCostInRange ( i , lookingPlayer , range , rangeX , rangeY , bFinished ) ;
}
scrFunctionResult . v . ival = enemyCost ;
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
{
debug ( LOG_ERROR , " scrEnemyWeapObjCostInRange(): failed to push result " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-09-29 08:04:25 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-09-29 08:04:25 -07:00
}
/* Calculates the total cost of ally (+ looking player)
* weapon objects in a certain area
*/
2011-03-12 17:32:15 -08:00
bool scrFriendlyWeapObjCostInRange ( void )
2007-09-29 08:04:25 -07:00
{
2011-03-19 18:52:25 -07:00
SDWORD player , range , rangeX , rangeY , i ;
UDWORD friendlyCost = 0 ;
int32_t bVTOLs , bFinished ; // was BOOL (int) ** see warning about conversion
2007-09-29 08:04:25 -07:00
if ( ! stackPopParams ( 6 , VAL_INT , & player , VAL_INT , & rangeX ,
2012-12-16 12:03:00 -08:00
VAL_INT , & rangeY , VAL_INT , & range , VAL_BOOL , & bVTOLs , VAL_BOOL , & bFinished ) )
2007-09-29 08:04:25 -07:00
{
debug ( LOG_ERROR , " scrFriendlyWeapObjCostInRange(): stack failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-09-29 08:04:25 -07:00
}
2012-12-16 12:03:00 -08:00
for ( i = 0 ; i < MAX_PLAYERS ; i + + )
2007-09-29 08:04:25 -07:00
{
2012-12-16 12:03:00 -08:00
if ( ( alliances [ player ] [ i ] = = ALLIANCE_FORMED ) | | ( i = = player ) ) //skip enemies
2007-09-29 08:04:25 -07:00
{
friendlyCost + = numPlayerWeapDroidsInRange ( i , player , range , rangeX , rangeY , bVTOLs ) ;
2012-12-16 12:03:00 -08:00
friendlyCost + = numPlayerWeapStructsInRange ( i , player , range , rangeX , rangeY , bFinished ) ;
2007-09-29 08:04:25 -07:00
}
}
scrFunctionResult . v . ival = friendlyCost ;
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-09-29 08:04:25 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-09-29 08:04:25 -07:00
}
2007-12-18 13:11:04 -08:00
/**
* Helper function for numPlayerWeapDroidsInRange and playerWeapDroidsCostInRange .
* Will either count the number of droids or calculate the total costs .
*/
static UDWORD costOrAmountInRange ( SDWORD player , SDWORD lookingPlayer , SDWORD range ,
2012-12-16 12:03:00 -08:00
SDWORD rangeX , SDWORD rangeY , bool bVTOLs , bool justCount )
2006-08-21 08:33:49 -07:00
{
2012-02-25 16:21:29 -08:00
UDWORD droidCost = 0 ;
2006-08-21 08:33:49 -07:00
//check droids
2012-02-25 16:21:29 -08:00
for ( DROID * psDroid = apsDroidLists [ player ] ; psDroid ; psDroid = psDroid - > psNext )
2006-08-21 08:33:49 -07:00
{
2012-02-25 16:21:29 -08:00
if ( psDroid - > visible [ lookingPlayer ] ) //can see this droid?
2006-08-21 08:33:49 -07:00
{
2008-01-05 11:42:43 -08:00
if ( ! objHasWeapon ( ( BASE_OBJECT * ) psDroid ) )
2006-08-21 08:33:49 -07:00
{
continue ;
}
//if VTOLs are excluded, skip them
2013-05-09 04:24:19 -07:00
if ( ! bVTOLs & & ( ( asPropulsionStats [ psDroid - > asBits [ COMP_PROPULSION ] ] . propulsionType = = PROPULSION_TYPE_LIFT ) | | ( psDroid - > droidType = = DROID_TRANSPORTER | | psDroid - > droidType = = DROID_SUPERTRANSPORTER ) ) )
2006-08-21 08:33:49 -07:00
{
continue ;
}
2008-10-14 12:31:40 -07:00
if ( range < 0
2012-12-16 12:03:00 -08:00
| | iHypot ( rangeX - psDroid - > pos . x , rangeY - psDroid - > pos . y ) < range ) //enemy in range
2006-08-21 08:33:49 -07:00
{
2007-12-18 13:11:04 -08:00
if ( justCount )
{
droidCost + + ;
}
else
{
droidCost + = calcDroidPower ( psDroid ) ;
}
2006-08-21 08:33:49 -07:00
}
}
}
2007-12-18 13:11:04 -08:00
return droidCost ;
}
2011-03-12 17:32:15 -08:00
UDWORD numPlayerWeapDroidsInRange ( SDWORD player , SDWORD lookingPlayer , SDWORD range , SDWORD rangeX , SDWORD rangeY , bool bVTOLs )
2007-12-18 13:11:04 -08:00
{
2008-03-24 09:51:17 -07:00
return costOrAmountInRange ( player , lookingPlayer , range , rangeX , rangeY , bVTOLs , true /*only count*/ ) ;
2006-08-21 08:33:49 -07:00
}
2007-09-29 08:04:25 -07:00
UDWORD playerWeapDroidsCostInRange ( SDWORD player , SDWORD lookingPlayer , SDWORD range ,
2012-12-16 12:03:00 -08:00
SDWORD rangeX , SDWORD rangeY , bool bVTOLs )
2007-09-29 08:04:25 -07:00
{
2008-03-24 09:51:17 -07:00
return costOrAmountInRange ( player , lookingPlayer , range , rangeX , rangeY , bVTOLs , false /*total cost*/ ) ;
2007-09-29 08:04:25 -07:00
}
UDWORD numPlayerWeapStructsInRange ( SDWORD player , SDWORD lookingPlayer , SDWORD range ,
2012-12-16 12:03:00 -08:00
SDWORD rangeX , SDWORD rangeY , bool bFinished )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
const STRUCTURE * psStruct ;
2006-08-21 08:33:49 -07:00
2008-10-14 13:25:41 -07:00
const int tx = map_coord ( rangeX ) ;
const int ty = map_coord ( rangeY ) ;
2006-08-21 08:33:49 -07:00
2008-10-14 13:25:41 -07:00
unsigned int numStructs = 0 ;
2006-08-21 08:33:49 -07:00
//check structures
2008-10-14 13:25:41 -07:00
for ( psStruct = apsStructLists [ player ] ; psStruct ; psStruct = psStruct - > psNext )
2006-08-21 08:33:49 -07:00
{
2008-10-14 13:25:41 -07:00
if ( psStruct - > visible [ lookingPlayer ] //if can see it
2012-12-16 12:03:00 -08:00
& & objHasWeapon ( ( BASE_OBJECT * ) psStruct ) ) // check whether this structure is "dangerous"
2006-08-21 08:33:49 -07:00
{
2008-10-14 13:25:41 -07:00
if ( ! bFinished | | psStruct - > status = = SS_BUILT )
2006-08-21 08:33:49 -07:00
{
2008-10-14 13:25:41 -07:00
if ( range < 0
2012-12-16 12:03:00 -08:00
| | world_coord ( hypotf ( tx - map_coord ( psStruct - > pos . x ) , ty - map_coord ( psStruct - > pos . y ) ) ) < range ) //enemy in range
2006-08-21 08:33:49 -07:00
{
2008-10-14 13:25:41 -07:00
+ + numStructs ;
2006-08-21 08:33:49 -07:00
}
}
}
}
2007-09-29 08:04:25 -07:00
return numStructs ;
}
UDWORD playerWeapStructsCostInRange ( SDWORD player , SDWORD lookingPlayer , SDWORD range ,
2012-12-16 12:03:00 -08:00
SDWORD rangeX , SDWORD rangeY , bool bFinished )
2007-09-29 08:04:25 -07:00
{
2012-12-16 12:03:00 -08:00
const STRUCTURE * psStruct ;
2007-09-29 08:04:25 -07:00
2008-10-14 13:25:41 -07:00
unsigned int structsCost = 0 ;
2007-09-29 08:04:25 -07:00
//check structures
2008-10-14 13:25:41 -07:00
for ( psStruct = apsStructLists [ player ] ; psStruct ; psStruct = psStruct - > psNext )
2007-09-29 08:04:25 -07:00
{
2008-10-14 12:31:40 -07:00
if ( psStruct - > visible [ lookingPlayer ] //if can see it
2012-12-16 12:03:00 -08:00
& & objHasWeapon ( ( BASE_OBJECT * ) psStruct ) )
2007-09-29 08:04:25 -07:00
{
2008-10-14 12:31:40 -07:00
if ( ! bFinished
2012-12-16 12:03:00 -08:00
| | psStruct - > status = = SS_BUILT )
2007-09-29 08:04:25 -07:00
{
2008-10-14 12:31:40 -07:00
if ( range < 0
2012-12-16 12:03:00 -08:00
| | world_coord ( hypotf ( map_coord ( rangeX ) - map_coord ( psStruct - > pos . x ) , map_coord ( rangeY ) - map_coord ( psStruct - > pos . y ) ) ) < range ) //enemy in range
2007-09-29 08:04:25 -07:00
{
2008-10-14 12:31:40 -07:00
structsCost + = structPowerToBuild ( psStruct ) ;
2007-09-29 08:04:25 -07:00
}
}
}
}
return structsCost ;
2006-08-21 08:33:49 -07:00
}
2011-03-12 17:32:15 -08:00
bool scrNumEnemyWeapDroidsInRange ( void )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD lookingPlayer , range , rangeX , rangeY , i ;
2006-08-21 08:33:49 -07:00
UDWORD numEnemies = 0 ;
2011-03-19 18:52:25 -07:00
int32_t bVTOLs ; // was BOOL (int) ** see warning about conversion
2006-08-21 08:33:49 -07:00
2006-08-21 09:49:32 -07:00
if ( ! stackPopParams ( 5 , VAL_INT , & lookingPlayer , VAL_INT , & rangeX ,
2012-12-16 12:03:00 -08:00
VAL_INT , & rangeY , VAL_INT , & range , VAL_BOOL , & bVTOLs ) )
2006-08-21 08:33:49 -07:00
{
debug ( LOG_ERROR , " scrNumEnemyWeapDroidsInRange(): stack failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2012-12-16 12:03:00 -08:00
for ( i = 0 ; i < MAX_PLAYERS ; i + + )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
if ( ( alliances [ lookingPlayer ] [ i ] = = ALLIANCE_FORMED ) | | ( i = = lookingPlayer ) ) //skip allies and myself
2006-08-21 08:33:49 -07:00
{
continue ;
}
2007-09-29 08:04:25 -07:00
numEnemies + = numPlayerWeapDroidsInRange ( i , lookingPlayer , range , rangeX , rangeY , bVTOLs ) ;
2006-08-21 08:33:49 -07:00
}
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . ival = numEnemies ;
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
2006-08-21 08:33:49 -07:00
{
debug ( LOG_ERROR , " scrNumEnemyWeapDroidsInRange(): failed to push result " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
2011-03-12 17:32:15 -08:00
bool scrNumEnemyWeapStructsInRange ( void )
2006-08-21 08:33:49 -07:00
{
2011-03-19 18:52:25 -07:00
SDWORD lookingPlayer , range , rangeX , rangeY , i ;
UDWORD numEnemies = 0 ;
int32_t bFinished ; // was BOOL (int) ** see warning about conversion
2006-08-21 08:33:49 -07:00
2007-09-29 08:04:25 -07:00
if ( ! stackPopParams ( 5 , VAL_INT , & lookingPlayer , VAL_INT , & rangeX ,
2012-12-16 12:03:00 -08:00
VAL_INT , & rangeY , VAL_INT , & range , VAL_BOOL , & bFinished ) )
2006-08-21 08:33:49 -07:00
{
debug ( LOG_ERROR , " scrNumEnemyWeapStructsInRange(): stack failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2012-12-16 12:03:00 -08:00
for ( i = 0 ; i < MAX_PLAYERS ; i + + )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
if ( ( alliances [ lookingPlayer ] [ i ] = = ALLIANCE_FORMED ) | | ( i = = lookingPlayer ) ) //skip allies and myself
2006-08-21 08:33:49 -07:00
{
continue ;
}
2007-09-29 08:04:25 -07:00
numEnemies + = numPlayerWeapStructsInRange ( i , lookingPlayer , range , rangeX , rangeY , bFinished ) ;
2006-08-21 08:33:49 -07:00
}
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . ival = numEnemies ;
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
2006-08-21 08:33:49 -07:00
{
debug ( LOG_ERROR , " scrNumEnemyWeapStructsInRange(): failed to push result " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
2011-03-12 17:32:15 -08:00
bool scrNumFriendlyWeapObjInRange ( void )
2006-08-21 08:33:49 -07:00
{
2011-03-19 18:52:25 -07:00
SDWORD player , range , rangeX , rangeY , i ;
2006-08-21 08:33:49 -07:00
UDWORD numFriends = 0 ;
2011-03-19 18:52:25 -07:00
int32_t bVTOLs , bFinished ; // was BOOL (int) ** see warning about conversion
2006-08-21 08:33:49 -07:00
2007-09-29 08:04:25 -07:00
if ( ! stackPopParams ( 6 , VAL_INT , & player , VAL_INT , & rangeX ,
2012-12-16 12:03:00 -08:00
VAL_INT , & rangeY , VAL_INT , & range , VAL_BOOL , & bVTOLs , VAL_BOOL , & bFinished ) )
2006-08-21 08:33:49 -07:00
{
debug ( LOG_ERROR , " scrNumFriendlyWeapObjInRange(): stack failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2012-12-16 12:03:00 -08:00
for ( i = 0 ; i < MAX_PLAYERS ; i + + )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
if ( ( alliances [ player ] [ i ] = = ALLIANCE_FORMED ) | | ( i = = player ) ) //skip enemies
2006-08-21 08:33:49 -07:00
{
2007-09-29 08:04:25 -07:00
numFriends + = numPlayerWeapDroidsInRange ( i , player , range , rangeX , rangeY , bVTOLs ) ;
2012-12-16 12:03:00 -08:00
numFriends + = numPlayerWeapStructsInRange ( i , player , range , rangeX , rangeY , bFinished ) ;
2006-08-21 08:33:49 -07:00
}
}
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . ival = numFriends ;
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
2006-08-21 08:33:49 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
2011-03-12 17:32:15 -08:00
bool scrNumFriendlyWeapDroidsInRange ( void )
2006-08-21 08:33:49 -07:00
{
2011-03-19 18:52:25 -07:00
SDWORD lookingPlayer , range , rangeX , rangeY , i ;
UDWORD numEnemies = 0 ;
int32_t bVTOLs ; // was BOOL (int) ** see warning about conversion
2006-08-21 08:33:49 -07:00
2006-08-21 09:49:32 -07:00
if ( ! stackPopParams ( 5 , VAL_INT , & lookingPlayer , VAL_INT , & rangeX ,
2012-12-16 12:03:00 -08:00
VAL_INT , & rangeY , VAL_INT , & range , VAL_BOOL , & bVTOLs ) )
2006-08-21 08:33:49 -07:00
{
debug ( LOG_ERROR , " scrNumFriendlyWeapDroidsInRange(): stack failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2012-12-16 12:03:00 -08:00
for ( i = 0 ; i < MAX_PLAYERS ; i + + )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
if ( ( alliances [ lookingPlayer ] [ i ] = = ALLIANCE_FORMED ) | | ( i = = lookingPlayer ) )
2006-08-21 08:33:49 -07:00
{
2007-09-29 08:04:25 -07:00
numEnemies + = numPlayerWeapDroidsInRange ( i , lookingPlayer , range , rangeX , rangeY , bVTOLs ) ;
2006-08-21 08:33:49 -07:00
}
}
//numEnemies = numEnemyWeapObjInRange(player, range, rangeX, rangeY, bVTOLs);
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . ival = numEnemies ;
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
2006-08-21 08:33:49 -07:00
{
debug ( LOG_ERROR , " scrNumFriendlyWeapDroidsInRange(): failed to push result " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
2011-03-12 17:32:15 -08:00
bool scrNumFriendlyWeapStructsInRange ( void )
2006-08-21 08:33:49 -07:00
{
2011-03-19 18:52:25 -07:00
SDWORD lookingPlayer , range , rangeX , rangeY , i ;
2006-08-21 08:33:49 -07:00
UDWORD numEnemies = 0 ;
2011-03-19 18:52:25 -07:00
int32_t bFinished ; // was BOOL (int) ** see warning about conversion
2006-08-21 08:33:49 -07:00
2007-09-29 08:04:25 -07:00
if ( ! stackPopParams ( 5 , VAL_INT , & lookingPlayer , VAL_INT , & rangeX ,
2012-12-16 12:03:00 -08:00
VAL_INT , & rangeY , VAL_INT , & range , VAL_BOOL , & bFinished ) )
2006-08-21 08:33:49 -07:00
{
debug ( LOG_ERROR , " scrNumFriendlyWeapStructsInRange(): stack failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2012-12-16 12:03:00 -08:00
for ( i = 0 ; i < MAX_PLAYERS ; i + + )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
if ( ( alliances [ lookingPlayer ] [ i ] = = ALLIANCE_FORMED ) | | ( i = = lookingPlayer ) ) //skip enemies
2006-08-21 08:33:49 -07:00
{
2007-09-29 08:04:25 -07:00
numEnemies + = numPlayerWeapStructsInRange ( i , lookingPlayer , range , rangeX , rangeY , bFinished ) ;
2006-08-21 08:33:49 -07:00
}
}
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . ival = numEnemies ;
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
debug ( LOG_ERROR , " scrNumFriendlyWeapStructsInRange(): failed to push result " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
2011-03-12 17:32:15 -08:00
bool scrNumPlayerWeapDroidsInRange ( void )
2006-12-02 15:27:00 -08:00
{
2011-03-19 18:52:25 -07:00
SDWORD targetPlayer , lookingPlayer , range , rangeX , rangeY ;
int32_t bVTOLs ; // was BOOL (int) ** see warning about conversion
2006-12-02 15:27:00 -08:00
2007-04-01 11:22:33 -07:00
if ( ! stackPopParams ( 6 , VAL_INT , & targetPlayer , VAL_INT , & lookingPlayer ,
2012-12-16 12:03:00 -08:00
VAL_INT , & rangeX , VAL_INT , & rangeY , VAL_INT , & range , VAL_BOOL , & bVTOLs ) )
2006-12-02 15:27:00 -08:00
{
2012-12-16 12:03:00 -08:00
debug ( LOG_ERROR , " scrNumPlayerWeapDroidsInRange(): stack failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-12-02 15:27:00 -08:00
}
scrFunctionResult . v . ival = numPlayerWeapDroidsInRange ( targetPlayer , lookingPlayer , range , rangeX , rangeY , bVTOLs ) ;
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
{
debug ( LOG_ERROR , " scrNumPlayerWeapDroidsInRange(): failed to push result " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-12-02 15:27:00 -08:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-12-02 15:27:00 -08:00
}
2011-03-12 17:32:15 -08:00
bool scrNumPlayerWeapStructsInRange ( void )
2006-12-02 15:27:00 -08:00
{
2011-03-19 18:52:25 -07:00
SDWORD targetPlayer , lookingPlayer , range , rangeX , rangeY ;
int32_t bFinished ; // was BOOL (int) ** see warning about conversion
2006-12-02 15:27:00 -08:00
2007-09-29 08:04:25 -07:00
if ( ! stackPopParams ( 6 , VAL_INT , & targetPlayer , VAL_INT , & lookingPlayer ,
2012-12-16 12:03:00 -08:00
VAL_INT , & rangeX , VAL_INT , & rangeY , VAL_INT , & range , VAL_BOOL , & bFinished ) )
2006-12-02 15:27:00 -08:00
{
2012-12-16 12:03:00 -08:00
debug ( LOG_ERROR , " scrNumPlayerWeapStructsInRange(): stack failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-12-02 15:27:00 -08:00
}
2007-09-29 08:04:25 -07:00
scrFunctionResult . v . ival = numPlayerWeapStructsInRange ( targetPlayer , lookingPlayer , range , rangeX , rangeY , bFinished ) ;
2006-12-02 15:27:00 -08:00
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
{
debug ( LOG_ERROR , " scrNumPlayerWeapStructsInRange(): failed to push result " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-12-02 15:27:00 -08:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-12-02 15:27:00 -08:00
}
2011-03-12 17:32:15 -08:00
bool scrNumPlayerWeapObjInRange ( void )
2006-08-21 08:33:49 -07:00
{
2011-03-19 18:52:25 -07:00
SDWORD targetPlayer , lookingPlayer , range , rangeX , rangeY ;
2006-08-21 08:33:49 -07:00
UDWORD numEnemies = 0 ;
2011-03-19 18:52:25 -07:00
int32_t bVTOLs , bFinished ; // was BOOL (int) ** see warning about conversion
2006-08-21 08:33:49 -07:00
2007-09-29 08:04:25 -07:00
if ( ! stackPopParams ( 7 , VAL_INT , & targetPlayer , VAL_INT , & lookingPlayer ,
2012-12-16 12:03:00 -08:00
VAL_INT , & rangeX , VAL_INT , & rangeY , VAL_INT , & range ,
VAL_BOOL , & bVTOLs , VAL_BOOL , & bFinished ) )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
debug ( LOG_ERROR , " scrNumPlayerWeapObjInRange(): stack failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2007-09-29 08:04:25 -07:00
numEnemies + = numPlayerWeapDroidsInRange ( targetPlayer , lookingPlayer , range , rangeX , rangeY , bVTOLs ) ;
numEnemies + = numPlayerWeapStructsInRange ( targetPlayer , lookingPlayer , range , rangeX , rangeY , bFinished ) ;
2006-08-21 09:49:32 -07:00
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . ival = numEnemies ;
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
2006-08-21 08:33:49 -07:00
{
debug ( LOG_ERROR , " scrNumPlayerWeapObjInRange(): failed to push result " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
2011-03-12 17:32:15 -08:00
bool scrNumEnemyObjInRange ( void )
2006-08-21 08:33:49 -07:00
{
2011-03-19 18:52:25 -07:00
SDWORD lookingPlayer , range , rangeX , rangeY ;
int32_t bVTOLs , bFinished ; // was BOOL (int) ** see warning about conversion
2006-08-21 08:33:49 -07:00
2007-09-29 08:04:25 -07:00
if ( ! stackPopParams ( 6 , VAL_INT , & lookingPlayer , VAL_INT , & rangeX ,
2012-12-16 12:03:00 -08:00
VAL_INT , & rangeY , VAL_INT , & range , VAL_BOOL , & bVTOLs , VAL_BOOL , & bFinished ) )
2006-08-21 08:33:49 -07:00
{
debug ( LOG_ERROR , " scrNumEnemyObjInRange(): stack failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2007-09-29 08:04:25 -07:00
scrFunctionResult . v . ival = numEnemyObjInRange ( lookingPlayer , range , rangeX , rangeY , bVTOLs , bFinished ) ;
2006-11-19 12:50:02 -08:00
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
2006-08-21 08:33:49 -07:00
{
debug ( LOG_ERROR , " scrNumEnemyObjInRange(): failed to push result " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
2007-09-29 08:04:25 -07:00
UDWORD numEnemyObjInRange ( SDWORD player , SDWORD range , SDWORD rangeX , SDWORD rangeY ,
2012-12-16 12:03:00 -08:00
bool bVTOLs , bool bFinished )
2006-08-21 08:33:49 -07:00
{
2008-10-14 13:25:41 -07:00
unsigned int i ;
2012-12-16 12:03:00 -08:00
const STRUCTURE * psStruct ;
const DROID * psDroid ;
2006-08-21 09:49:32 -07:00
2008-10-14 13:25:41 -07:00
const int tx = map_coord ( rangeX ) ;
const int ty = map_coord ( rangeY ) ;
2006-08-21 08:33:49 -07:00
2008-10-14 13:25:41 -07:00
unsigned int numEnemies = 0 ;
2006-08-21 08:33:49 -07:00
2012-12-16 12:03:00 -08:00
for ( i = 0 ; i < MAX_PLAYERS ; i + + )
2006-08-21 08:33:49 -07:00
{
2008-10-14 13:25:41 -07:00
if ( alliances [ player ] [ i ] = = ALLIANCE_FORMED
2012-12-16 12:03:00 -08:00
| | i = = player )
2006-08-21 08:33:49 -07:00
{
continue ;
}
//check structures
2008-10-14 13:25:41 -07:00
for ( psStruct = apsStructLists [ i ] ; psStruct ; psStruct = psStruct - > psNext )
2006-08-21 08:33:49 -07:00
{
2008-10-14 13:25:41 -07:00
if ( psStruct - > visible [ player ] ) //if can see it
2006-08-21 08:33:49 -07:00
{
2008-10-14 13:25:41 -07:00
if ( ! bFinished
2012-12-16 12:03:00 -08:00
| | psStruct - > status = = SS_BUILT )
2007-09-29 08:04:25 -07:00
{
2007-09-28 12:25:21 -07:00
if ( range < 0
2012-12-16 12:03:00 -08:00
| | world_coord ( hypotf ( tx - map_coord ( psStruct - > pos . x ) , ty - map_coord ( psStruct - > pos . y ) ) ) < range ) //enemy in range
2006-08-21 08:33:49 -07:00
{
numEnemies + + ;
}
2007-09-29 08:04:25 -07:00
}
2006-08-21 08:33:49 -07:00
}
}
//check droids
2008-10-14 13:25:41 -07:00
for ( psDroid = apsDroidLists [ i ] ; psDroid ; psDroid = psDroid - > psNext )
2006-08-21 08:33:49 -07:00
{
2008-10-14 13:25:41 -07:00
if ( psDroid - > visible [ player ] ) //can see this droid?
2006-08-21 08:33:49 -07:00
{
//if VTOLs are excluded, skip them
2008-10-14 13:25:41 -07:00
if ( ! bVTOLs
2013-05-09 04:24:19 -07:00
& & ( asPropulsionStats [ psDroid - > asBits [ COMP_PROPULSION ] ] . propulsionType = = PROPULSION_TYPE_LIFT
2012-12-16 12:03:00 -08:00
| | psDroid - > droidType = = DROID_TRANSPORTER | | psDroid - > droidType = = DROID_SUPERTRANSPORTER ) )
2006-08-21 08:33:49 -07:00
{
continue ;
}
2007-09-28 12:25:21 -07:00
if ( range < 0
2012-12-16 12:03:00 -08:00
| | world_coord ( hypotf ( tx - map_coord ( psDroid - > pos . x ) , ty - map_coord ( psDroid - > pos . y ) ) ) < range ) //enemy in range
2006-08-21 08:33:49 -07:00
{
numEnemies + + ;
}
}
}
}
return numEnemies ;
}
2009-08-13 06:28:12 -07:00
/* Similar to structureBuiltInRange(), but also returns true if structure is not finished */
2011-03-12 17:32:15 -08:00
bool scrNumStructsByStatInRange ( void )
2006-08-21 08:33:49 -07:00
{
SDWORD player , lookingPlayer , index , x , y , range ;
2012-12-16 12:03:00 -08:00
SDWORD rangeSquared , NumStruct ;
2006-08-21 08:33:49 -07:00
STRUCTURE * psCurr ;
SDWORD xdiff , ydiff ;
STRUCTURE_STATS * psTarget ;
2006-08-21 09:49:32 -07:00
if ( ! stackPopParams ( 6 , ST_STRUCTURESTAT , & index , VAL_INT , & x , VAL_INT , & y ,
2012-12-16 12:03:00 -08:00
VAL_INT , & range , VAL_INT , & lookingPlayer , VAL_INT , & player ) )
2006-08-21 08:33:49 -07:00
{
debug ( LOG_ERROR , " scrNumStructsByStatInRange(): stack failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
if ( player > = MAX_PLAYERS )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrNumStructsByStatInRange:player number is too high " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2007-09-28 12:25:21 -07:00
if ( x < 0
2012-12-16 12:03:00 -08:00
| | map_coord ( x ) > ( SDWORD ) mapWidth )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrNumStructsByStatInRange : invalid X coord " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2007-09-28 12:25:21 -07:00
if ( y < 0
2012-12-16 12:03:00 -08:00
| | map_coord ( y ) > ( SDWORD ) mapHeight )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrNumStructsByStatInRange : invalid Y coord " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2007-02-10 08:39:39 -08:00
if ( index < ( SDWORD ) 0 | | index > ( SDWORD ) numStructureStats )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrNumStructsByStatInRange : Invalid structure stat " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
if ( range < ( SDWORD ) 0 )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrNumStructsByStatInRange : Rnage is less than zero " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
NumStruct = 0 ;
2006-08-21 09:49:32 -07:00
//now look through the players list of structures to see if this type
2006-08-21 08:33:49 -07:00
//exists within range
psTarget = & asStructureStats [ index ] ;
rangeSquared = range * range ;
2012-12-16 12:03:00 -08:00
for ( psCurr = apsStructLists [ player ] ; psCurr ; psCurr = psCurr - > psNext )
2006-08-21 08:33:49 -07:00
{
2007-12-15 07:39:29 -08:00
xdiff = ( SDWORD ) psCurr - > pos . x - x ;
ydiff = ( SDWORD ) psCurr - > pos . y - y ;
2012-12-16 12:03:00 -08:00
if ( xdiff * xdiff + ydiff * ydiff < = rangeSquared )
2006-08-21 09:49:32 -07:00
{
2013-05-12 14:50:57 -07:00
if ( psCurr - > pStructureType - > id . compare ( psTarget - > id ) = = 0 )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
if ( psCurr - > visible [ lookingPlayer ] ) //can we see it?
2006-08-21 08:33:49 -07:00
{
NumStruct + + ;
}
}
}
}
2006-08-21 09:49:32 -07:00
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . ival = NumStruct ;
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
2006-08-21 08:33:49 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
2011-03-12 17:32:15 -08:00
bool scrNumStructsByStatInArea ( void )
2006-08-21 08:33:49 -07:00
{
SDWORD player , lookingPlayer , index , x1 , y1 , x2 , y2 ;
SDWORD NumStruct ;
STRUCTURE * psCurr ;
STRUCTURE_STATS * psStats ;
2006-08-21 09:49:32 -07:00
if ( ! stackPopParams ( 7 , ST_STRUCTURESTAT , & index , VAL_INT , & x1 , VAL_INT , & y1 ,
2012-12-16 12:03:00 -08:00
VAL_INT , & x2 , VAL_INT , & y2 , VAL_INT , & lookingPlayer , VAL_INT , & player ) )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
debug ( LOG_ERROR , " scrNumStructsByStatInArea: failed to pop " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
if ( player > = MAX_PLAYERS )
{
2012-12-16 12:03:00 -08:00
debug ( LOG_ERROR , " scrNumStructsByStatInArea: player number too high " ) ;
ASSERT ( false , " scrStructureBuiltInRange:player number is too high " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2007-02-10 08:39:39 -08:00
if ( index < ( SDWORD ) 0 | | index > ( SDWORD ) numStructureStats )
2006-08-21 08:33:49 -07:00
{
debug ( LOG_ERROR , " scrNumStructsByStatInArea: invalid structure stat " ) ;
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrStructureBuiltInRange : Invalid structure stat " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , index < numStructureStats , " Invalid range referenced for numStructureStats, %d > %d " , index , numStructureStats ) ;
2006-08-21 08:33:49 -07:00
psStats = ( STRUCTURE_STATS * ) ( asStructureStats + index ) ;
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , psStats ! = NULL , " Invalid structure pointer " ) ;
2006-08-21 08:33:49 -07:00
NumStruct = 0 ;
2006-08-21 09:49:32 -07:00
for ( psCurr = apsStructLists [ player ] ; psCurr ! = NULL ;
2012-12-16 12:03:00 -08:00
psCurr = psCurr - > psNext )
2006-08-21 08:33:49 -07:00
{
if ( psCurr - > pStructureType = = psStats )
{
2012-12-16 12:03:00 -08:00
if ( psCurr - > visible [ lookingPlayer ] ) //can we see it?
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
if ( psCurr - > pos . x < x1 )
{
continue ; //not in bounds
}
if ( psCurr - > pos . y < y1 )
{
continue ; //not in bounds
}
if ( psCurr - > pos . x > x2 )
{
continue ; //not in bounds
}
if ( psCurr - > pos . y > y2 )
{
continue ; //not in bounds
}
2006-08-21 08:33:49 -07:00
NumStruct + + ;
}
}
}
2006-08-21 09:49:32 -07:00
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . ival = NumStruct ;
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
2006-08-21 08:33:49 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
2011-03-12 17:32:15 -08:00
bool scrNumStructsByTypeInRange ( void )
2006-08-21 08:33:49 -07:00
{
SDWORD targetPlayer , lookingPlayer , type , x , y , range ;
2012-12-16 12:03:00 -08:00
SDWORD rangeSquared , NumStruct ;
2006-08-21 08:33:49 -07:00
STRUCTURE * psCurr ;
SDWORD xdiff , ydiff ;
2006-08-21 09:49:32 -07:00
if ( ! stackPopParams ( 6 , VAL_INT , & lookingPlayer , VAL_INT , & targetPlayer ,
2012-12-16 12:03:00 -08:00
VAL_INT , & type , VAL_INT , & x , VAL_INT , & y , VAL_INT , & range ) )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
debug ( LOG_ERROR , " scrNumStructsByTypeInRange: failed to pop " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
if ( lookingPlayer > = MAX_PLAYERS | | targetPlayer > = MAX_PLAYERS )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrNumStructsByTypeInRange:player number is too high " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2007-09-28 12:25:21 -07:00
if ( x < 0
2012-12-16 12:03:00 -08:00
| | map_coord ( x ) > ( SDWORD ) mapWidth )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrNumStructsByTypeInRange : invalid X coord " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2007-09-28 12:25:21 -07:00
if ( y < 0
2012-12-16 12:03:00 -08:00
| | map_coord ( y ) > ( SDWORD ) mapHeight )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrNumStructsByTypeInRange : invalid Y coord " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
if ( range < ( SDWORD ) 0 )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrNumStructsByTypeInRange : Rnage is less than zero " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
NumStruct = 0 ;
2006-08-21 09:49:32 -07:00
//now look through the players list of structures to see if this type
2006-08-21 08:33:49 -07:00
//exists within range
rangeSquared = range * range ;
2012-12-16 12:03:00 -08:00
for ( psCurr = apsStructLists [ targetPlayer ] ; psCurr ; psCurr = psCurr - > psNext )
2006-08-21 08:33:49 -07:00
{
2007-12-15 07:39:29 -08:00
xdiff = ( SDWORD ) psCurr - > pos . x - x ;
ydiff = ( SDWORD ) psCurr - > pos . y - y ;
2012-12-16 12:03:00 -08:00
if ( xdiff * xdiff + ydiff * ydiff < = rangeSquared )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
if ( ( type < 0 ) | | ( psCurr - > pStructureType - > type = = type ) )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
if ( psCurr - > visible [ lookingPlayer ] ) //can we see it?
2006-08-21 08:33:49 -07:00
{
NumStruct + + ;
}
}
}
}
2006-08-21 09:49:32 -07:00
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . ival = NumStruct ;
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
2006-08-21 08:33:49 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
2011-03-12 17:32:15 -08:00
bool scrNumFeatByTypeInRange ( void )
2006-08-21 08:33:49 -07:00
{
SDWORD lookingPlayer , type , x , y , range ;
2012-12-16 12:03:00 -08:00
SDWORD rangeSquared , NumFeat ;
2006-08-21 08:33:49 -07:00
FEATURE * psCurr ;
SDWORD xdiff , ydiff ;
2006-08-21 09:49:32 -07:00
if ( ! stackPopParams ( 5 , VAL_INT , & lookingPlayer ,
2012-12-16 12:03:00 -08:00
VAL_INT , & type , VAL_INT , & x , VAL_INT , & y , VAL_INT , & range ) )
2006-08-21 08:33:49 -07:00
{
debug ( LOG_ERROR , " scrNumFeatByTypeInRange(): failed to pop " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
if ( lookingPlayer > = MAX_PLAYERS )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrNumFeatByTypeInRange:player number is too high " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2007-09-28 12:25:21 -07:00
if ( x < 0
2012-12-16 12:03:00 -08:00
| | map_coord ( x ) > ( SDWORD ) mapWidth )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrNumFeatByTypeInRange : invalid X coord " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2007-09-28 12:25:21 -07:00
if ( y < 0
2012-12-16 12:03:00 -08:00
| | map_coord ( y ) > ( SDWORD ) mapHeight )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrNumFeatByTypeInRange : invalid Y coord " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
if ( range < ( SDWORD ) 0 )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrNumFeatByTypeInRange : Rnage is less than zero " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
NumFeat = 0 ;
2006-08-21 09:49:32 -07:00
//now look through the players list of structures to see if this type
2006-08-21 08:33:49 -07:00
//exists within range
rangeSquared = range * range ;
2012-12-16 12:03:00 -08:00
for ( psCurr = apsFeatureLists [ 0 ] ; psCurr ; psCurr = psCurr - > psNext )
2006-08-21 08:33:49 -07:00
{
2007-12-15 07:39:29 -08:00
xdiff = ( SDWORD ) psCurr - > pos . x - x ;
ydiff = ( SDWORD ) psCurr - > pos . y - y ;
2012-12-16 12:03:00 -08:00
if ( xdiff * xdiff + ydiff * ydiff < = rangeSquared )
2006-08-21 09:49:32 -07:00
{
2012-12-16 12:03:00 -08:00
if ( ( type < 0 ) | | ( psCurr - > psStats - > subType = = type ) ) //like FEAT_OIL_RESOURCE
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
if ( psCurr - > visible [ lookingPlayer ] ) //can we see it?
2006-08-21 08:33:49 -07:00
{
NumFeat + + ;
}
}
}
}
2006-08-21 09:49:32 -07:00
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . ival = NumFeat ;
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
2006-08-21 08:33:49 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
//returns num of visible structures of a certain player in range (only visible ones)
2011-03-12 17:32:15 -08:00
bool scrNumStructsButNotWallsInRangeVis ( void )
2006-08-21 08:33:49 -07:00
{
SDWORD player , lookingPlayer , x , y , range ;
2012-12-16 12:03:00 -08:00
SDWORD rangeSquared , NumStruct ;
2006-08-21 08:33:49 -07:00
STRUCTURE * psCurr ;
SDWORD xdiff , ydiff ;
2006-08-21 09:49:32 -07:00
if ( ! stackPopParams ( 5 , VAL_INT , & x , VAL_INT , & y ,
2012-12-16 12:03:00 -08:00
VAL_INT , & range , VAL_INT , & lookingPlayer , VAL_INT , & player ) )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
debug ( LOG_ERROR , " scrNumStructsButNotWallsInRangeVis: failed to pop " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
if ( ( player > = MAX_PLAYERS ) | | ( lookingPlayer > = MAX_PLAYERS ) )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrNumStructsButNotWallsInRangeVis:player number is too high " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2007-09-28 12:25:21 -07:00
if ( x < 0
2012-12-16 12:03:00 -08:00
| | map_coord ( x ) > ( SDWORD ) mapWidth )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrNumStructsButNotWallsInRangeVis : invalid X coord " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2007-09-28 12:25:21 -07:00
if ( y < 0
2012-12-16 12:03:00 -08:00
| | map_coord ( y ) > ( SDWORD ) mapHeight )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrNumStructsButNotWallsInRangeVis : invalid Y coord " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
if ( range < ( SDWORD ) 0 )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrNumStructsButNotWallsInRangeVis : Rnage is less than zero " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
NumStruct = 0 ;
//now look through the players list of structures
rangeSquared = range * range ;
2012-12-16 12:03:00 -08:00
for ( psCurr = apsStructLists [ player ] ; psCurr ; psCurr = psCurr - > psNext )
2006-08-21 08:33:49 -07:00
{
if ( ( psCurr - > pStructureType - > type ! = REF_WALL ) & &
2012-12-16 12:03:00 -08:00
( psCurr - > pStructureType - > type ! = REF_WALLCORNER ) )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
if ( psCurr - > visible [ lookingPlayer ] ) //can we see it?
2006-08-21 08:33:49 -07:00
{
2007-12-15 07:39:29 -08:00
xdiff = ( SDWORD ) psCurr - > pos . x - x ;
ydiff = ( SDWORD ) psCurr - > pos . y - y ;
2012-12-16 12:03:00 -08:00
if ( xdiff * xdiff + ydiff * ydiff < = rangeSquared )
2006-08-21 09:49:32 -07:00
{
2006-08-21 08:33:49 -07:00
NumStruct + + ;
}
}
}
}
2006-08-21 09:49:32 -07:00
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . ival = NumStruct ;
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
2006-08-21 08:33:49 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
// Only returns structure if it is visible
2011-03-12 17:32:15 -08:00
bool scrGetStructureVis ( void )
2006-08-21 08:33:49 -07:00
{
SDWORD player , lookingPlayer , index ;
STRUCTURE * psStruct ;
UDWORD structType ;
2011-03-12 17:32:15 -08:00
bool found ;
2006-08-21 08:33:49 -07:00
if ( ! stackPopParams ( 3 , ST_STRUCTURESTAT , & index , VAL_INT , & player , VAL_INT , & lookingPlayer ) )
{
2012-12-16 12:03:00 -08:00
debug ( LOG_ERROR , " scrGetStructureVis: failed to pop " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
if ( ( player > = MAX_PLAYERS ) | | ( lookingPlayer > = MAX_PLAYERS ) )
{
2012-12-16 12:03:00 -08:00
ASSERT ( false , " scrGetStructureVis:player number is too high " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
structType = asStructureStats [ index ] . ref ;
//search the players' list of built structures to see if one exists
2008-03-24 09:51:17 -07:00
found = false ;
2006-08-21 09:49:32 -07:00
for ( psStruct = apsStructLists [ player ] ; psStruct ! = NULL ; psStruct =
2012-12-16 12:03:00 -08:00
psStruct - > psNext )
2006-08-21 08:33:49 -07:00
{
if ( psStruct - > pStructureType - > ref = = structType )
{
2012-12-16 12:03:00 -08:00
if ( psStruct - > visible [ lookingPlayer ] )
2006-08-21 08:33:49 -07:00
{
2008-03-24 09:51:17 -07:00
found = true ;
2006-08-21 08:33:49 -07:00
break ;
}
}
}
//make sure pass NULL back if not got one
if ( ! found )
{
psStruct = NULL ;
}
2006-08-21 09:49:32 -07:00
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . oval = psStruct ;
if ( ! stackPushResult ( ( INTERP_TYPE ) ST_STRUCTURE , & scrFunctionResult ) )
2006-08-21 08:33:49 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
//returns num of visible structures of a certain player in range
2011-03-12 17:32:15 -08:00
bool scrChooseValidLoc ( void )
2006-08-21 08:33:49 -07:00
{
2006-08-21 09:49:32 -07:00
SDWORD sendY , sendX , * x , * y , player , threatRange ;
2012-12-16 12:03:00 -08:00
UDWORD tx , ty ;
2006-08-21 08:33:49 -07:00
2012-12-16 12:03:00 -08:00
if ( ! stackPopParams ( 6 , VAL_REF | VAL_INT , & x , VAL_REF | VAL_INT , & y ,
VAL_INT , & sendX , VAL_INT , & sendY , VAL_INT , & player , VAL_INT , & threatRange ) )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
debug ( LOG_ERROR , " scrChooseValidLoc: failed to pop " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2006-08-21 09:49:32 -07:00
2012-12-16 12:03:00 -08:00
//Check coords
2007-09-28 12:25:21 -07:00
if ( sendX < 0
2012-12-16 12:03:00 -08:00
| | sendX > world_coord ( mapWidth )
| | sendY < 0
| | sendY > world_coord ( mapHeight ) )
2006-08-21 08:33:49 -07:00
{
debug ( LOG_ERROR , " scrChooseValidLoc: coords off map " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2007-09-28 12:25:21 -07:00
tx = map_coord ( sendX ) ;
ty = map_coord ( sendY ) ;
2006-08-21 08:33:49 -07:00
2012-12-16 12:03:00 -08:00
if ( pickATileGenThreat ( & tx , & ty , LOOK_FOR_EMPTY_TILE , threatRange , player , zonedPAT ) )
2006-08-21 08:33:49 -07:00
{
2007-09-28 12:25:21 -07:00
* x = world_coord ( tx ) ;
* y = world_coord ( ty ) ;
2008-03-24 09:51:17 -07:00
scrFunctionResult . v . bval = true ;
2006-11-19 12:50:02 -08:00
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2006-08-21 08:33:49 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
}
else
{
2008-03-24 09:51:17 -07:00
scrFunctionResult . v . bval = false ;
2006-11-19 12:50:02 -08:00
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2006-08-21 08:33:49 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
}
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
//returns closest enemy object
2011-03-12 17:32:15 -08:00
bool scrGetClosestEnemy ( void )
2006-08-21 08:33:49 -07:00
{
2011-03-19 18:52:25 -07:00
SDWORD x , y , tx , ty , player , range , i ;
2007-03-16 09:20:16 -07:00
UDWORD dist , bestDist ;
2011-03-19 18:52:25 -07:00
int32_t weaponOnly , bVTOLs ; // was BOOL (int) ** see warning about conversion
bool bFound = false ; //only military objects?
2007-03-16 09:20:16 -07:00
BASE_OBJECT * psObj = NULL ;
STRUCTURE * psStruct = NULL ;
DROID * psDroid = NULL ;
2006-08-21 08:33:49 -07:00
if ( ! stackPopParams ( 6 , VAL_INT , & x , VAL_INT , & y ,
2012-12-16 12:03:00 -08:00
VAL_INT , & range , VAL_BOOL , & weaponOnly , VAL_BOOL , & bVTOLs , VAL_INT , & player ) )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
debug ( LOG_ERROR , " scrGetClosestEnemy: stack failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2006-08-21 09:49:32 -07:00
2012-12-16 12:03:00 -08:00
//Check coords
2007-09-28 12:25:21 -07:00
if ( x < 0
2012-12-16 12:03:00 -08:00
| | x > world_coord ( mapWidth )
| | y < 0
| | y > world_coord ( mapHeight ) )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
debug ( LOG_ERROR , " scrGetClosestEnemy: coords off map " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2007-09-28 12:25:21 -07:00
tx = map_coord ( x ) ;
ty = map_coord ( y ) ;
2006-08-21 08:33:49 -07:00
bestDist = 99999 ;
2012-12-16 12:03:00 -08:00
for ( i = 0 ; i < MAX_PLAYERS ; i + + )
2006-08-21 08:33:49 -07:00
{
2012-02-25 16:21:29 -08:00
if ( ( alliances [ player ] [ i ] = = ALLIANCE_FORMED ) | | ( i = = player ) )
2006-08-21 08:33:49 -07:00
{
continue ;
}
//check droids
2012-02-25 16:21:29 -08:00
for ( psDroid = apsDroidLists [ i ] ; psDroid ; psDroid = psDroid - > psNext )
2006-08-21 08:33:49 -07:00
{
2012-02-25 16:21:29 -08:00
if ( psDroid - > visible [ player ] ) //can see this droid?
2006-08-21 08:33:49 -07:00
{
//if only weapon droids and don't have it, then skip
2008-01-05 11:42:43 -08:00
if ( weaponOnly & & ! objHasWeapon ( ( BASE_OBJECT * ) psDroid ) )
2006-08-21 08:33:49 -07:00
{
continue ;
}
//if VTOLs are excluded, skip them
2013-05-09 04:24:19 -07:00
if ( ! bVTOLs & & ( ( asPropulsionStats [ psDroid - > asBits [ COMP_PROPULSION ] ] . propulsionType = = PROPULSION_TYPE_LIFT ) | | ( psDroid - > droidType = = DROID_TRANSPORTER | | psDroid - > droidType = = DROID_SUPERTRANSPORTER ) ) )
2006-08-21 08:33:49 -07:00
{
continue ;
}
2008-10-14 13:25:41 -07:00
dist = world_coord ( hypotf ( tx - map_coord ( psDroid - > pos . x ) , ty - map_coord ( psDroid - > pos . y ) ) ) ;
2012-02-25 16:21:29 -08:00
if ( dist < bestDist )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
if ( ( range < 0 ) | | ( dist < range ) ) //enemy in range
2006-08-21 08:33:49 -07:00
{
bestDist = dist ;
2008-03-24 09:51:17 -07:00
bFound = true ;
2012-12-16 12:03:00 -08:00
psObj = ( BASE_OBJECT * ) psDroid ;
2006-08-21 08:33:49 -07:00
}
}
}
}
//check structures
2012-12-16 12:03:00 -08:00
for ( psStruct = apsStructLists [ i ] ; psStruct ; psStruct = psStruct - > psNext )
2006-08-21 08:33:49 -07:00
{
2012-02-25 16:21:29 -08:00
if ( psStruct - > visible [ player ] ) //if can see it
2006-08-21 08:33:49 -07:00
{
//only need defenses?
2012-12-16 12:03:00 -08:00
if ( weaponOnly & & ( ! objHasWeapon ( ( BASE_OBJECT * ) psStruct ) | | ( psStruct - > status ! = SS_BUILT ) ) ) //non-weapon-structures or not finished
2006-08-21 08:33:49 -07:00
{
continue ;
}
2006-08-21 09:49:32 -07:00
2008-10-14 13:25:41 -07:00
dist = world_coord ( hypotf ( tx - map_coord ( psStruct - > pos . x ) , ty - map_coord ( psStruct - > pos . y ) ) ) ;
2012-02-25 16:21:29 -08:00
if ( dist < bestDist )
2006-08-21 08:33:49 -07:00
{
2012-02-25 16:21:29 -08:00
if ( ( range < 0 ) | | ( dist < range ) ) //in range
2006-08-21 08:33:49 -07:00
{
bestDist = dist ;
2008-03-24 09:51:17 -07:00
bFound = true ;
2012-12-16 12:03:00 -08:00
psObj = ( BASE_OBJECT * ) psStruct ;
2006-08-21 08:33:49 -07:00
}
}
}
}
}
2012-02-25 16:21:29 -08:00
if ( bFound )
2006-08-21 08:33:49 -07:00
{
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . oval = psObj ;
if ( ! stackPushResult ( ( INTERP_TYPE ) ST_BASEOBJECT , & scrFunctionResult ) )
2006-08-21 08:33:49 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
}
else
{
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . oval = NULL ;
if ( ! stackPushResult ( ( INTERP_TYPE ) ST_BASEOBJECT , & scrFunctionResult ) )
2006-08-21 08:33:49 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
}
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
//How many droids can it still fit?
2011-03-12 17:32:15 -08:00
bool scrTransporterCapacity ( void )
2006-08-21 08:33:49 -07:00
{
DROID * psDroid ;
if ( ! stackPopParams ( 1 , ST_DROID , & psDroid ) )
{
debug ( LOG_ERROR , " scrTransporterCapacity(): failed to pop params " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2012-12-16 12:03:00 -08:00
if ( psDroid = = NULL )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
debug ( LOG_ERROR , " scrTransporterCapacity(): NULLOBJECT passed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2012-12-16 12:03:00 -08:00
if ( psDroid - > droidType ! = DROID_TRANSPORTER & & psDroid - > droidType ! = DROID_SUPERTRANSPORTER )
2006-08-21 08:33:49 -07:00
{
debug ( LOG_ERROR , " scrTransporterCapacity(): passed droid is not a transporter " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2006-08-21 09:49:32 -07:00
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . ival = calcRemainingCapacity ( psDroid ) ;
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
2006-08-21 08:33:49 -07:00
{
debug ( LOG_ERROR , " scrHasIndirectWeapon(): failed to push result " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
//is it?
2011-03-12 17:32:15 -08:00
bool scrTransporterFlying ( void )
2006-08-21 08:33:49 -07:00
{
DROID * psDroid ;
if ( ! stackPopParams ( 1 , ST_DROID , & psDroid ) )
{
debug ( LOG_ERROR , " scrTransporterFlying(): failed to pop params " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2012-12-16 12:03:00 -08:00
if ( psDroid = = NULL )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
debug ( LOG_ERROR , " scrTransporterFlying(): NULLOBJECT passed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2012-12-16 12:03:00 -08:00
if ( psDroid - > droidType ! = DROID_TRANSPORTER & & psDroid - > droidType ! = DROID_SUPERTRANSPORTER )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
debug ( LOG_ERROR , " scrTransporterFlying(): passed droid is not a transporter " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2006-08-21 09:49:32 -07:00
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . bval = transporterFlying ( psDroid ) ;
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
debug ( LOG_ERROR , " scrTransporterFlying(): failed to push result " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
2011-03-12 17:32:15 -08:00
bool scrUnloadTransporter ( void )
2006-08-21 08:33:49 -07:00
{
DROID * psDroid ;
2012-12-16 12:03:00 -08:00
SDWORD x , y ;
2006-08-21 08:33:49 -07:00
if ( ! stackPopParams ( 3 , ST_DROID , & psDroid , VAL_INT , & x , VAL_INT , & y ) )
{
2012-12-16 12:03:00 -08:00
debug ( LOG_ERROR , " scrUnloadTransporter(): failed to pop params " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2012-12-16 12:03:00 -08:00
if ( psDroid = = NULL )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
debug ( LOG_ERROR , " scrUnloadTransporter(): NULLOBJECT passed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2012-12-16 12:03:00 -08:00
if ( psDroid - > droidType ! = DROID_TRANSPORTER & & psDroid - > droidType ! = DROID_SUPERTRANSPORTER )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
debug ( LOG_ERROR , " scrUnloadTransporter(): passed droid is not a transporter " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2012-12-16 12:03:00 -08:00
unloadTransporter ( psDroid , x , y , false ) ;
2006-08-21 08:33:49 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
//return true if droid is a member of any group
2011-03-12 17:32:15 -08:00
bool scrHasGroup ( void )
2006-08-21 08:33:49 -07:00
{
DROID * psDroid ;
2011-03-12 17:32:15 -08:00
bool retval ;
2006-08-21 08:33:49 -07:00
if ( ! stackPopParams ( 1 , ST_DROID , & psDroid ) )
{
2012-12-16 12:03:00 -08:00
debug ( LOG_ERROR , " scrHasGroup: failed to pop " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
if ( psDroid = = NULL )
{
2012-12-16 12:03:00 -08:00
debug ( LOG_ERROR , " scrHasGroup: droid is NULLOBJECT " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
if ( psDroid - > psGroup ! = NULL )
{
2008-03-24 09:51:17 -07:00
retval = true ;
2006-08-21 08:33:49 -07:00
}
else
{
2008-03-24 09:51:17 -07:00
retval = false ;
2006-08-21 08:33:49 -07:00
}
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . bval = retval ;
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2006-08-21 08:33:49 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
2006-10-08 01:06:46 -07:00
/* Range is in world units! */
2011-03-12 17:32:15 -08:00
bool scrObjWeaponMaxRange ( void )
2006-08-21 08:33:49 -07:00
{
BASE_OBJECT * psObj ;
WEAPON_STATS * psStats ;
DROID * psDroid ;
STRUCTURE * psStruct ;
if ( ! stackPopParams ( 1 , ST_BASEOBJECT , & psObj ) )
{
debug ( LOG_ERROR , " scrObjWeaponMaxRange: stack failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
//check if valid type
2012-12-16 12:03:00 -08:00
if ( psObj - > type = = OBJ_DROID )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
psDroid = ( DROID * ) psObj ;
2006-08-21 08:33:49 -07:00
if ( psDroid - > asWeaps [ 0 ] . nStat ! = 0 )
{
2010-06-27 12:15:07 -07:00
ASSERT_OR_RETURN ( false , psDroid - > asWeaps [ 0 ] . nStat < numWeaponStats , " Invalid range referenced. " ) ;
2006-08-21 08:33:49 -07:00
psStats = asWeaponStats + psDroid - > asWeaps [ 0 ] . nStat ;
2013-05-05 04:34:59 -07:00
scrFunctionResult . v . ival = psStats - > base . maxRange ;
2006-11-19 12:50:02 -08:00
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
2006-08-21 08:33:49 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
}
2012-12-16 12:03:00 -08:00
else if ( psObj - > type = = OBJ_STRUCTURE )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
psStruct = ( STRUCTURE * ) psObj ;
2006-08-21 08:33:49 -07:00
if ( psStruct - > asWeaps [ 0 ] . nStat ! = 0 )
{
2010-06-27 12:15:07 -07:00
ASSERT_OR_RETURN ( false , psStruct - > asWeaps [ 0 ] . nStat < numWeaponStats , " Invalid range referenced. " ) ;
2006-08-21 08:33:49 -07:00
psStats = asWeaponStats + psStruct - > asWeaps [ 0 ] . nStat ;
2013-05-05 04:34:59 -07:00
scrFunctionResult . v . ival = psStats - > base . maxRange ;
2006-11-19 12:50:02 -08:00
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
2006-08-21 08:33:49 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
}
2007-01-02 12:12:14 -08:00
scrFunctionResult . v . ival = 0 ;
2006-11-19 12:50:02 -08:00
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
debug ( LOG_ERROR , " scrObjWeaponMaxRange: wrong object type " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
2011-03-12 17:32:15 -08:00
bool scrObjHasWeapon ( void )
2006-08-21 08:33:49 -07:00
{
BASE_OBJECT * psObj ;
if ( ! stackPopParams ( 1 , ST_BASEOBJECT , & psObj ) )
{
debug ( LOG_ERROR , " scrObjHasWeapon: stack failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
//check if valid type
2012-12-16 12:03:00 -08:00
if ( objHasWeapon ( psObj ) )
2006-08-21 08:33:49 -07:00
{
2008-03-24 09:51:17 -07:00
scrFunctionResult . v . bval = true ;
2008-01-05 11:42:43 -08:00
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2006-08-21 08:33:49 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
2008-01-05 11:42:43 -08:00
2008-03-24 09:51:17 -07:00
scrFunctionResult . v . bval = false ;
2006-11-19 12:50:02 -08:00
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2006-08-21 08:33:49 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
2011-03-12 17:32:15 -08:00
bool scrObjectHasIndirectWeapon ( void )
2006-08-21 08:33:49 -07:00
{
WEAPON_STATS * psWeapStats ;
2011-03-12 17:32:15 -08:00
bool bIndirect ;
2006-08-21 08:33:49 -07:00
BASE_OBJECT * psObj ;
if ( ! stackPopParams ( 1 , ST_BASEOBJECT , & psObj ) )
{
debug ( LOG_ERROR , " scrHasIndirectWeapon(): failed to pop params " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
if ( psObj = = NULL )
{
2012-12-16 12:03:00 -08:00
debug ( LOG_ERROR , " scrHasIndirectWeapon(): NULLOBJECT passed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2008-03-24 09:51:17 -07:00
bIndirect = false ;
2012-12-16 12:03:00 -08:00
if ( psObj - > type = = OBJ_DROID )
2006-08-21 08:33:49 -07:00
{
if ( ( ( DROID * ) psObj ) - > asWeaps [ 0 ] . nStat > 0 )
{
psWeapStats = asWeaponStats + ( ( DROID * ) psObj ) - > asWeaps [ 0 ] . nStat ;
bIndirect = ! proj_Direct ( psWeapStats ) ;
}
}
2012-12-16 12:03:00 -08:00
else if ( psObj - > type = = OBJ_STRUCTURE )
2006-08-21 08:33:49 -07:00
{
if ( ( ( STRUCTURE * ) psObj ) - > asWeaps [ 0 ] . nStat > 0 )
{
psWeapStats = asWeaponStats + ( ( STRUCTURE * ) psObj ) - > asWeaps [ 0 ] . nStat ;
bIndirect = ! proj_Direct ( psWeapStats ) ;
}
}
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . bval = bIndirect ;
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
debug ( LOG_ERROR , " scrHasIndirectWeapon(): failed to push result " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
//returns closest droid by type
2011-03-12 17:32:15 -08:00
bool scrGetClosestEnemyDroidByType ( void )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD x , y , tx , ty , player , range , i , type ;
UDWORD dist , bestDist ;
2011-03-12 17:32:15 -08:00
bool bFound = false ; //only military objects?
2011-03-19 18:52:25 -07:00
int32_t bVTOLs ; // was BOOL (int) ** see warning about conversion
2007-03-16 09:20:16 -07:00
DROID * psDroid = NULL , * foundDroid = NULL ;
2006-08-21 08:33:49 -07:00
if ( ! stackPopParams ( 6 , VAL_INT , & x , VAL_INT , & y ,
2012-12-16 12:03:00 -08:00
VAL_INT , & range , VAL_INT , & type , VAL_BOOL , & bVTOLs , VAL_INT , & player ) )
2006-08-21 08:33:49 -07:00
{
debug ( LOG_ERROR , " scrGetClosestEnemyDroidByType: stack failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2006-08-21 09:49:32 -07:00
2012-12-16 12:03:00 -08:00
//Check coords
2007-09-28 12:25:21 -07:00
if ( x < 0
2012-12-16 12:03:00 -08:00
| | x > world_coord ( mapWidth )
| | y < 0
| | y > world_coord ( mapHeight ) )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
debug ( LOG_ERROR , " scrGetClosestEnemyDroidByType: coords off map " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2007-09-28 12:25:21 -07:00
tx = map_coord ( x ) ;
ty = map_coord ( y ) ;
2006-08-21 08:33:49 -07:00
bestDist = 99999 ;
2012-12-16 12:03:00 -08:00
for ( i = 0 ; i < MAX_PLAYERS ; i + + )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
if ( ( alliances [ player ] [ i ] = = ALLIANCE_FORMED ) | | ( i = = player ) )
2006-08-21 08:33:49 -07:00
{
continue ;
}
//check droids
2012-12-16 12:03:00 -08:00
for ( psDroid = apsDroidLists [ i ] ; psDroid ; psDroid = psDroid - > psNext )
2006-08-21 08:33:49 -07:00
{
//if VTOLs are excluded, skip them (don't check for transporter this time)
2013-05-09 04:24:19 -07:00
if ( ! bVTOLs & & ( asPropulsionStats [ psDroid - > asBits [ COMP_PROPULSION ] ] . propulsionType = = PROPULSION_TYPE_LIFT ) )
2006-08-21 08:33:49 -07:00
{
continue ;
}
2012-12-16 12:03:00 -08:00
if ( psDroid - > visible [ player ] ) //can see this droid?
2006-08-21 08:33:49 -07:00
{
//skip?
if ( ( type ! = ( - 1 ) ) & & ( psDroid - > droidType ! = type ) )
{
continue ;
}
2008-10-14 13:25:41 -07:00
dist = world_coord ( hypotf ( tx - map_coord ( psDroid - > pos . x ) , ty - map_coord ( psDroid - > pos . y ) ) ) ;
2012-12-16 12:03:00 -08:00
if ( dist < bestDist )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
if ( dist < range ) //enemy in range
2006-08-21 08:33:49 -07:00
{
bestDist = dist ;
2008-03-24 09:51:17 -07:00
bFound = true ;
2006-08-21 08:33:49 -07:00
foundDroid = psDroid ;
}
}
}
}
}
2012-12-16 12:03:00 -08:00
if ( bFound )
2006-08-21 08:33:49 -07:00
{
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . oval = foundDroid ;
if ( ! stackPushResult ( ( INTERP_TYPE ) ST_DROID , & scrFunctionResult ) )
2006-08-21 08:33:49 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
}
else
{
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . oval = NULL ;
if ( ! stackPushResult ( ( INTERP_TYPE ) ST_DROID , & scrFunctionResult ) )
2006-08-21 08:33:49 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
}
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
//returns closest structure by type
2011-03-12 17:32:15 -08:00
bool scrGetClosestEnemyStructByType ( void )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD x , y , tx , ty , player , range , i , type , dist ;
2006-08-21 08:33:49 -07:00
UDWORD bestDist ;
2011-03-12 17:32:15 -08:00
bool bFound = false ; //only military objects?
2007-03-16 09:20:16 -07:00
STRUCTURE * psStruct = NULL , * foundStruct = NULL ;
2006-08-21 08:33:49 -07:00
if ( ! stackPopParams ( 5 , VAL_INT , & x , VAL_INT , & y ,
2012-12-16 12:03:00 -08:00
VAL_INT , & range , VAL_INT , & type , VAL_INT , & player ) )
2006-08-21 08:33:49 -07:00
{
debug ( LOG_ERROR , " scrGetClosestEnemyStructByType: stack failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2006-08-21 09:49:32 -07:00
2012-12-16 12:03:00 -08:00
//Check coords
2007-09-28 12:25:21 -07:00
if ( x < 0
2012-12-16 12:03:00 -08:00
| | x > world_coord ( mapWidth )
| | y < 0
| | y > world_coord ( mapHeight ) )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
debug ( LOG_ERROR , " scrGetClosestEnemyStructByType: coords off map " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2007-09-28 12:25:21 -07:00
tx = map_coord ( x ) ;
ty = map_coord ( y ) ;
2006-08-21 08:33:49 -07:00
bestDist = 99999 ;
2012-12-16 12:03:00 -08:00
for ( i = 0 ; i < MAX_PLAYERS ; i + + )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
if ( ( alliances [ player ] [ i ] = = ALLIANCE_FORMED ) | | ( i = = player ) )
2006-08-21 08:33:49 -07:00
{
continue ;
}
//check structures
2012-12-16 12:03:00 -08:00
for ( psStruct = apsStructLists [ i ] ; psStruct ; psStruct = psStruct - > psNext )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
if ( psStruct - > visible [ player ] ) //if can see it
2006-08-21 08:33:49 -07:00
{
//only need defenses?
2012-12-16 12:03:00 -08:00
if ( ( type ! = ( - 1 ) ) & & ( psStruct - > pStructureType - > type ! = type ) ) //non-weapon-structures
2006-08-21 08:33:49 -07:00
{
continue ;
}
2008-10-14 13:25:41 -07:00
dist = world_coord ( hypotf ( tx - map_coord ( psStruct - > pos . x ) , ty - map_coord ( psStruct - > pos . y ) ) ) ;
2012-12-16 12:03:00 -08:00
if ( dist < bestDist )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
if ( ( range < 0 ) | | ( dist < range ) ) //in range or no range check
2006-08-21 08:33:49 -07:00
{
bestDist = dist ;
2008-03-24 09:51:17 -07:00
bFound = true ;
2006-08-21 08:33:49 -07:00
foundStruct = psStruct ;
}
}
}
}
}
2012-12-16 12:03:00 -08:00
if ( bFound )
2006-08-21 08:33:49 -07:00
{
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . oval = foundStruct ;
if ( ! stackPushResult ( ( INTERP_TYPE ) ST_STRUCTURE , & scrFunctionResult ) )
2006-08-21 08:33:49 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
}
else
{
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . oval = NULL ;
if ( ! stackPushResult ( ( INTERP_TYPE ) ST_STRUCTURE , & scrFunctionResult ) )
2006-08-21 08:33:49 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
}
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
//Approx point of intersection of a circle and a line with start loc being circle's center point
2011-03-12 17:32:15 -08:00
bool scrCirclePerimPoint ( void )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD basex , basey , * grx , * gry , radius ;
2008-10-14 13:25:41 -07:00
float factor , deltaX , deltaY ;
2006-08-21 08:33:49 -07:00
2012-12-16 12:03:00 -08:00
if ( ! stackPopParams ( 5 , VAL_INT , & basex , VAL_INT , & basey , VAL_REF | VAL_INT , & grx ,
VAL_REF | VAL_INT , & gry , VAL_INT , & radius ) )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
debug ( LOG_ERROR , " scrCirclePerimPoint(): stack failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2012-12-16 12:03:00 -08:00
if ( radius = = 0 )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
debug ( LOG_ERROR , " scrCirclePerimPoint: radius == 0. " ) ;
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
2008-10-14 13:25:41 -07:00
deltaX = ( float ) ( * grx - basex ) ; //x len (signed!)
deltaY = ( float ) ( * gry - basey ) ;
2006-08-21 08:33:49 -07:00
2008-10-14 13:25:41 -07:00
factor = hypotf ( deltaX , deltaY ) / ( float ) radius ; //by what factor is distance > radius?
2006-08-21 08:33:49 -07:00
//if point was inside of the circle, don't modify passed parameter
2012-12-16 12:03:00 -08:00
if ( factor = = 0 )
2006-08-21 08:33:49 -07:00
{
2009-02-22 16:21:46 -08:00
debug_console ( " scrCirclePerimPoint: division by zero. " ) ;
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
//calc new len
2008-10-14 13:25:41 -07:00
deltaX = deltaX / factor ;
deltaY = deltaY / factor ;
2006-08-21 08:33:49 -07:00
//now add new len to the center coords
2008-10-14 13:25:41 -07:00
* grx = basex + deltaX ;
* gry = basey + deltaY ;
2006-08-21 08:33:49 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
//send my vision to AI
2011-03-12 17:32:15 -08:00
bool scrGiftRadar ( void )
2006-08-21 08:33:49 -07:00
{
SDWORD playerFrom , playerTo ;
2011-03-19 18:52:25 -07:00
int32_t playMsg ; // was BOOL (int) ** see warning about conversion
2006-08-21 08:33:49 -07:00
if ( ! stackPopParams ( 3 , VAL_INT , & playerFrom , VAL_INT , & playerTo , VAL_BOOL , & playMsg ) )
{
2012-12-16 12:03:00 -08:00
debug ( LOG_ERROR , " scrGiftRadar(): stack failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , playerFrom > = 0 & & playerFrom < MAX_PLAYERS , " Invalid player number " ) ;
ASSERT_OR_RETURN ( false , playerTo > = 0 & & playerTo < MAX_PLAYERS , " Invalid player number " ) ;
2006-08-21 08:33:49 -07:00
2012-12-16 12:03:00 -08:00
giftRadar ( playerFrom , playerTo , true ) ;
2006-08-21 08:33:49 -07:00
2012-12-16 12:03:00 -08:00
if ( playMsg )
{
2006-08-21 08:33:49 -07:00
audio_QueueTrack ( ID_SENSOR_DOWNLOAD ) ;
2012-12-16 12:03:00 -08:00
}
2006-08-21 08:33:49 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
2011-03-12 17:32:15 -08:00
bool scrNumAllies ( void )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD player , numAllies , i ;
2006-08-21 08:33:49 -07:00
if ( ! stackPopParams ( 1 , VAL_INT , & player ) )
{
debug ( LOG_ERROR , " scrNumAllies: failed to pop " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2006-08-21 08:33:49 -07:00
numAllies = 0 ;
2012-12-16 12:03:00 -08:00
for ( i = 0 ; i < MAX_PLAYERS ; i + + )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
if ( i ! = player )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
if ( alliances [ i ] [ player ] = = ALLIANCE_FORMED )
2006-08-21 08:33:49 -07:00
{
numAllies + + ;
}
}
}
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . ival = numAllies ;
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
2006-08-21 08:33:49 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2006-08-21 09:49:32 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
//num aa defenses in range
2011-03-12 17:32:15 -08:00
bool scrNumAAinRange ( void )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD targetPlayer , lookingPlayer , range , rangeX , rangeY ;
SDWORD tx , ty ;
2006-08-21 08:33:49 -07:00
UDWORD numFound = 0 ;
STRUCTURE * psStruct ;
2007-03-30 08:12:15 -07:00
if ( ! stackPopParams ( 5 , VAL_INT , & targetPlayer , VAL_INT , & lookingPlayer ,
2012-12-16 12:03:00 -08:00
VAL_INT , & rangeX , VAL_INT , & rangeY , VAL_INT , & range ) )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
debug ( LOG_ERROR , " scrNumAAinRange(): stack failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2007-09-28 12:25:21 -07:00
tx = map_coord ( rangeX ) ;
ty = map_coord ( rangeY ) ;
2006-08-21 08:33:49 -07:00
numFound = 0 ;
//check structures
2012-12-16 12:03:00 -08:00
for ( psStruct = apsStructLists [ targetPlayer ] ; psStruct ; psStruct = psStruct - > psNext )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
if ( psStruct - > visible [ lookingPlayer ] ) //if can see it
2006-08-21 08:33:49 -07:00
{
2010-10-17 14:30:58 -07:00
if ( objHasWeapon ( ( BASE_OBJECT * ) psStruct ) & & ( asWeaponStats [ psStruct - > asWeaps [ 0 ] . nStat ] . surfaceToAir & SHOOT_IN_AIR ) )
2006-08-21 08:33:49 -07:00
{
2007-09-28 12:25:21 -07:00
if ( range < 0
2012-12-16 12:03:00 -08:00
| | world_coord ( hypotf ( tx - map_coord ( psStruct - > pos . x ) , ty - map_coord ( psStruct - > pos . y ) ) ) < range ) //enemy in range
2006-08-21 08:33:49 -07:00
{
numFound + + ;
}
}
}
}
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . ival = numFound ;
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
debug ( LOG_ERROR , " scrNumAAinRange(): failed to push result " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
//select droid
2011-03-12 17:32:15 -08:00
bool scrSelectDroid ( void )
2006-08-21 08:33:49 -07:00
{
2011-03-19 18:52:25 -07:00
int32_t bSelect ; // was BOOL (int) ** see warning about conversion
2006-08-21 08:33:49 -07:00
DROID * psDroid ;
if ( ! stackPopParams ( 2 , ST_DROID , & psDroid , VAL_BOOL , & bSelect ) )
{
debug ( LOG_ERROR , " scrSelectDroid(): stack failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2012-12-16 12:03:00 -08:00
if ( psDroid = = NULL )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
debug ( LOG_ERROR , " droid is NULLOBJECT " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
psDroid - > selected = bSelect ;
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
//select droid group
2011-03-12 17:32:15 -08:00
bool scrSelectGroup ( void )
2006-08-21 08:33:49 -07:00
{
2011-03-19 18:52:25 -07:00
int32_t bSelect ; // was BOOL (int) ** see warning about conversion
2006-08-21 08:33:49 -07:00
DROID_GROUP * psGroup ;
DROID * psCurr ;
if ( ! stackPopParams ( 2 , ST_GROUP , & psGroup , VAL_BOOL , & bSelect ) )
{
debug ( LOG_ERROR , " scrSelectGroup(): stack failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2012-12-16 12:03:00 -08:00
for ( psCurr = psGroup - > psList ; psCurr ; psCurr = psCurr - > psGrpNext )
2006-08-21 08:33:49 -07:00
{
psCurr - > selected = bSelect ;
}
2006-08-21 09:49:32 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
2011-03-12 17:32:15 -08:00
bool scrModulo ( void )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD num1 , num2 ;
2006-08-21 08:33:49 -07:00
if ( ! stackPopParams ( 2 , VAL_INT , & num1 , VAL_INT , & num2 ) )
{
2012-12-16 12:03:00 -08:00
debug ( LOG_ERROR , " scrModulo(): stack failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2012-12-16 12:03:00 -08:00
scrFunctionResult . v . ival = ( num1 % num2 ) ;
2006-11-19 12:50:02 -08:00
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
debug ( LOG_ERROR , " scrModulo(): failed to push result " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 08:33:49 -07:00
}
2011-03-12 17:32:15 -08:00
bool scrPlayerLoaded ( void )
2006-08-21 08:33:49 -07:00
{
2006-12-02 15:27:00 -08:00
SDWORD player ;
2012-12-16 12:03:00 -08:00
bool bPlayerHasFactories = false ;
2006-12-02 15:27:00 -08:00
STRUCTURE * psCurr ;
2006-08-21 08:33:49 -07:00
if ( ! stackPopParams ( 1 , VAL_INT , & player ) )
{
debug ( LOG_ERROR , " scrPlayerLoaded(): stack failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2006-08-21 08:33:49 -07:00
2006-12-02 15:27:00 -08:00
/* see if there are any player factories left */
2012-12-16 12:03:00 -08:00
if ( apsStructLists [ player ] )
2006-12-02 15:27:00 -08:00
{
for ( psCurr = apsStructLists [ player ] ; psCurr ! = NULL ; psCurr = psCurr - > psNext )
{
2012-12-16 12:03:00 -08:00
if ( StructIsFactory ( psCurr ) )
2006-12-02 15:27:00 -08:00
{
2008-03-24 09:51:17 -07:00
bPlayerHasFactories = true ;
2006-12-02 15:27:00 -08:00
break ;
}
}
}
/* player is active if he has at least a unit or some factory */
scrFunctionResult . v . bval = ( apsDroidLists [ player ] ! = NULL | | bPlayerHasFactories ) ;
2006-11-19 12:50:02 -08:00
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2006-08-21 08:33:49 -07:00
{
2012-12-16 12:03:00 -08:00
debug ( LOG_ERROR , " scrPlayerLoaded(): failed to push result " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-08-21 08:33:49 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-08-21 09:49:32 -07:00
}
2006-08-22 15:46:15 -07:00
2006-09-19 09:07:06 -07:00
/* Add a beacon (blip) */
2012-11-26 14:04:41 -08:00
bool addBeaconBlip ( SDWORD locX , SDWORD locY , SDWORD forPlayer , SDWORD sender , const char * textMsg )
2006-09-19 09:07:06 -07:00
{
MESSAGE * psMessage ;
VIEWDATA * pTempData ;
if ( forPlayer > = MAX_PLAYERS )
{
2008-04-24 13:02:02 -07:00
debug ( LOG_ERROR , " addBeaconBlip: player number is too high " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-09-19 09:07:06 -07:00
}
//find the message if was already added previously
2008-04-24 13:02:02 -07:00
psMessage = findBeaconMsg ( forPlayer , sender ) ;
2006-09-19 09:07:06 -07:00
if ( psMessage )
{
//remove it
removeMessage ( psMessage , forPlayer ) ;
}
//create new message
2008-04-24 13:02:02 -07:00
psMessage = addBeaconMessage ( MSG_PROXIMITY , false , forPlayer ) ;
2006-09-19 09:07:06 -07:00
if ( psMessage )
{
2008-04-24 13:02:02 -07:00
pTempData = CreateBeaconViewData ( sender , locX , locY ) ;
2008-02-11 13:01:47 -08:00
ASSERT ( pTempData ! = NULL , " Empty help data for radar beacon " ) ;
2006-09-19 09:07:06 -07:00
psMessage - > pViewData = ( MSG_VIEWDATA * ) pTempData ;
2008-04-19 14:41:18 -07:00
debug ( LOG_MSG , " blip added, pViewData=%p " , psMessage - > pViewData ) ;
2006-09-19 09:07:06 -07:00
}
else
{
2012-11-26 14:04:41 -08:00
debug ( LOG_WARNING , " call failed " ) ;
2006-09-19 09:07:06 -07:00
}
//Received a blip message from a player callback
//store and call later
//-------------------------------------------------
//call beacon callback only if not adding for ourselves
2012-12-16 12:03:00 -08:00
if ( forPlayer ! = sender )
2006-09-19 09:07:06 -07:00
{
2012-11-27 10:05:23 -08:00
triggerEventBeacon ( sender , forPlayer , textMsg , locX , locY ) ;
2012-12-16 12:03:00 -08:00
if ( ! msgStackPush ( CALL_BEACON , sender , forPlayer , textMsg , locX , locY , NULL ) )
2006-09-19 09:07:06 -07:00
{
2012-11-26 14:04:41 -08:00
debug ( LOG_ERROR , " msgStackPush - stack failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-09-19 09:07:06 -07:00
}
2008-03-31 11:25:58 -07:00
2012-12-16 12:03:00 -08:00
if ( selectedPlayer = = forPlayer )
2008-03-31 15:52:47 -07:00
{
// show console message
2012-12-16 12:03:00 -08:00
CONPRINTF ( ConsoleString , ( ConsoleString , _ ( " Beacon received from %s! " ) ,
getPlayerName ( sender ) ) ) ;
2008-03-31 11:59:02 -07:00
2008-03-31 15:52:47 -07:00
// play audio
2012-12-16 12:03:00 -08:00
audio_QueueTrackPos ( ID_SOUND_BEACON , locX , locY , 0 ) ;
2008-03-31 15:52:47 -07:00
}
2006-09-19 09:07:06 -07:00
}
2006-09-23 07:56:18 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2006-09-19 09:07:06 -07:00
}
2012-11-26 14:04:41 -08:00
bool sendBeaconToPlayer ( SDWORD locX , SDWORD locY , SDWORD forPlayer , SDWORD sender , const char * beaconMsg )
2006-09-19 09:07:06 -07:00
{
2012-12-16 12:03:00 -08:00
if ( sender = = forPlayer | | myResponsibility ( forPlayer ) ) //if destination player is on this machine
2006-09-19 09:07:06 -07:00
{
2012-12-16 12:03:00 -08:00
debug ( LOG_WZ , " sending beacon to player %d (local player) from %d " , forPlayer , sender ) ;
2008-04-24 13:02:02 -07:00
return addBeaconBlip ( locX , locY , forPlayer , sender , beaconMsg ) ;
2006-09-19 09:07:06 -07:00
}
else
{
2012-12-16 12:03:00 -08:00
debug ( LOG_WZ , " sending beacon to player %d (remote player) from %d " , forPlayer , sender ) ;
2008-01-09 15:50:44 -08:00
return sendBeacon ( locX , locY , forPlayer , sender , beaconMsg ) ;
2006-09-19 09:07:06 -07:00
}
}
//prepare viewdata for help blip
2008-04-24 13:02:02 -07:00
VIEWDATA * CreateBeaconViewData ( SDWORD sender , UDWORD LocX , UDWORD LocY )
2006-09-19 09:07:06 -07:00
{
2008-04-24 13:02:02 -07:00
UDWORD height ;
2006-09-19 09:07:06 -07:00
VIEWDATA * psViewData ;
SDWORD audioID ;
2008-04-24 13:02:02 -07:00
char name [ MAXSTRLEN ] ;
2006-09-19 09:07:06 -07:00
//allocate message space
2012-01-07 14:02:53 -08:00
psViewData = new VIEWDATA ;
2006-09-19 09:07:06 -07:00
2008-04-24 13:02:02 -07:00
//store name
sprintf ( name , _ ( " Beacon %d " ) , sender ) ;
2012-12-16 12:03:00 -08:00
psViewData - > pName = name ;
2006-09-19 09:07:06 -07:00
2008-04-24 13:02:02 -07:00
//store text message, hardcoded for now
2012-01-07 14:02:53 -08:00
psViewData - > textMsg . push_back ( QString : : fromUtf8 ( getPlayerName ( sender ) ) ) ;
2006-09-19 09:07:06 -07:00
//store message type
2008-04-24 13:02:02 -07:00
psViewData - > type = VIEW_BEACON ;
2006-09-19 09:07:06 -07:00
//allocate memory for blip location etc
2007-04-15 03:43:05 -07:00
psViewData - > pData = ( VIEW_PROXIMITY * ) malloc ( sizeof ( VIEW_PROXIMITY ) ) ;
2006-09-19 09:07:06 -07:00
if ( psViewData - > pData = = NULL )
{
2008-03-24 09:51:17 -07:00
ASSERT ( false , " prepairHelpViewData() - Unable to allocate memory " ) ;
2013-10-04 10:16:49 -07:00
delete psViewData ;
2006-09-19 09:07:06 -07:00
return NULL ;
}
2006-09-23 07:56:18 -07:00
2006-09-19 09:07:06 -07:00
//store audio
audioID = NO_SOUND ;
( ( VIEW_PROXIMITY * ) psViewData - > pData ) - > audioID = audioID ;
//store blip location
( ( VIEW_PROXIMITY * ) psViewData - > pData ) - > x = ( UDWORD ) LocX ;
( ( VIEW_PROXIMITY * ) psViewData - > pData ) - > y = ( UDWORD ) LocY ;
2008-04-24 13:02:02 -07:00
//check the z value is at least the height of the terrain
height = map_Height ( LocX , LocY ) ;
( ( VIEW_PROXIMITY * ) psViewData - > pData ) - > z = height ;
2006-09-19 09:07:06 -07:00
//store prox message type
( ( VIEW_PROXIMITY * ) psViewData - > pData ) - > proxType = PROX_ENEMY ; //PROX_ENEMY for now
//remember who sent this msg, so we could remove this one, when same player sends a new help-blip msg
( ( VIEW_PROXIMITY * ) psViewData - > pData ) - > sender = sender ;
//remember when the message was created so can remove it after some time
( ( VIEW_PROXIMITY * ) psViewData - > pData ) - > timeAdded = gameTime ;
2008-04-19 14:41:18 -07:00
debug ( LOG_MSG , " Added message " ) ;
2006-09-19 09:07:06 -07:00
return psViewData ;
}
2008-04-24 13:02:02 -07:00
/* Looks through the players list of messages to find VIEW_BEACON (one per player!) pointer */
2012-12-16 12:03:00 -08:00
MESSAGE * findBeaconMsg ( UDWORD player , SDWORD sender )
2006-09-19 09:07:06 -07:00
{
MESSAGE * psCurr ;
for ( psCurr = apsMessages [ player ] ; psCurr ! = NULL ; psCurr = psCurr - > psNext )
{
2008-04-24 13:02:02 -07:00
//look for VIEW_BEACON, should only be 1 per player
if ( psCurr - > dataType = = MSG_DATA_BEACON )
2006-09-19 09:07:06 -07:00
{
2012-12-16 12:03:00 -08:00
if ( ( ( VIEWDATA * ) psCurr - > pViewData ) - > type = = VIEW_BEACON )
2006-09-19 09:07:06 -07:00
{
2008-04-24 13:02:02 -07:00
debug ( LOG_WZ , " findBeaconMsg: %d ALREADY HAS A MESSAGE STORED " , player ) ;
2012-12-16 12:03:00 -08:00
if ( ( ( VIEW_PROXIMITY * ) ( ( VIEWDATA * ) psCurr - > pViewData ) - > pData ) - > sender = = sender )
2006-09-19 09:07:06 -07:00
{
2008-04-24 13:02:02 -07:00
debug ( LOG_WZ , " findBeaconMsg: %d ALREADY HAS A MESSAGE STORED from %d " , player , sender ) ;
2006-09-19 09:07:06 -07:00
return psCurr ;
}
}
}
}
//not found the message so return NULL
return NULL ;
}
/* Add beacon (radar blip) */
2011-03-12 17:32:15 -08:00
bool scrDropBeacon ( void )
2006-09-19 09:07:06 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD forPlayer , sender ;
2006-11-16 06:30:29 -08:00
char ssval2 [ 255 ] ;
2012-12-16 12:03:00 -08:00
UDWORD locX , locY , locZ ;
2006-09-19 09:07:06 -07:00
2006-11-16 06:30:29 -08:00
if ( ! stackPopParams ( 6 , VAL_STRING , & strParam1 , VAL_INT , & forPlayer ,
2012-12-16 12:03:00 -08:00
VAL_INT , & sender , VAL_INT , & locX , VAL_INT , & locY , VAL_INT , & locZ ) )
2006-09-19 09:07:06 -07:00
{
2012-12-16 12:03:00 -08:00
debug ( LOG_ERROR , " scrDropBeacon failed to pop parameters " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-09-19 09:07:06 -07:00
}
2008-11-13 14:42:02 -08:00
ssprintf ( ssval2 , " %s : %s " , getPlayerName ( sender ) , strParam1 ) ; //temporary solution
2006-09-19 09:07:06 -07:00
return sendBeaconToPlayer ( locX , locY , forPlayer , sender , ssval2 ) ;
}
2007-03-30 08:12:15 -07:00
/* Remove beacon from the map */
2011-03-12 17:32:15 -08:00
bool scrRemoveBeacon ( void )
2006-09-19 09:07:06 -07:00
{
MESSAGE * psMessage ;
SDWORD player , sender ;
if ( ! stackPopParams ( 2 , VAL_INT , & player , VAL_INT , & sender ) )
{
2012-12-16 12:03:00 -08:00
debug ( LOG_ERROR , " scrRemoveBeacon: failed to pop parameters " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-09-19 09:07:06 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
ASSERT_OR_RETURN ( false , sender > = 0 & & sender < MAX_PLAYERS , " Invalid player number " ) ;
2006-09-19 09:07:06 -07:00
//find the message
2008-04-24 13:02:02 -07:00
psMessage = findBeaconMsg ( player , sender ) ;
2006-09-19 09:07:06 -07:00
if ( psMessage )
2006-08-26 08:50:47 -07:00
{
//delete it
removeMessage ( psMessage , player ) ;
2012-12-10 08:05:13 -08:00
triggerEventBeaconRemoved ( sender , player ) ;
2006-08-26 08:50:47 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-09-19 09:07:06 -07:00
}
2011-03-12 17:32:15 -08:00
bool scrClosestDamagedGroupDroid ( void )
2006-09-19 09:07:06 -07:00
{
DROID_GROUP * psGroup ;
2012-12-16 12:03:00 -08:00
DROID * psDroid , * psClosestDroid ;
SDWORD x , y , healthLeft , wBestDist , wDist , maxRepairedBy , player ;
2006-09-19 09:07:06 -07:00
if ( ! stackPopParams ( 6 , VAL_INT , & player , ST_GROUP , & psGroup , VAL_INT , & healthLeft ,
2012-12-16 12:03:00 -08:00
VAL_INT , & x , VAL_INT , & y , VAL_INT , & maxRepairedBy ) )
2006-09-19 09:07:06 -07:00
{
debug ( LOG_ERROR , " scrClosestDamagedGroupDroid: failed to pop " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-09-19 09:07:06 -07:00
}
wBestDist = 999999 ;
psClosestDroid = NULL ;
2012-12-16 12:03:00 -08:00
for ( psDroid = psGroup - > psList ; psDroid ; psDroid = psDroid - > psGrpNext )
2006-09-19 09:07:06 -07:00
{
2012-12-16 12:03:00 -08:00
if ( ( psDroid - > body * 100 / psDroid - > originalBody ) < = healthLeft ) //in%
2006-09-19 09:07:06 -07:00
{
2010-03-05 05:42:57 -08:00
wDist = map_coord ( iHypot ( psDroid - > pos . x - x , psDroid - > pos . y - y ) ) ; //in tiles
2012-12-16 12:03:00 -08:00
if ( wDist < wBestDist )
2006-09-19 09:07:06 -07:00
{
2012-12-16 12:03:00 -08:00
if ( ( maxRepairedBy < 0 ) | | ( getNumRepairedBy ( psDroid , player ) < = maxRepairedBy ) )
2006-09-19 09:07:06 -07:00
{
psClosestDroid = psDroid ;
wBestDist = wDist ;
}
}
}
}
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . oval = psClosestDroid ;
if ( ! stackPushResult ( ( INTERP_TYPE ) ST_DROID , & scrFunctionResult ) )
2006-09-19 09:07:06 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2006-09-19 09:07:06 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-09-19 09:07:06 -07:00
}
SDWORD getNumRepairedBy ( DROID * psDroidToCheck , SDWORD player )
{
DROID * psDroid ;
SDWORD numRepaired = 0 ;
2012-12-16 12:03:00 -08:00
for ( psDroid = apsDroidLists [ player ] ; psDroid ; psDroid = psDroid - > psNext )
2006-09-19 09:07:06 -07:00
{
2012-12-16 12:03:00 -08:00
if ( ( psDroid - > droidType ! = DROID_REPAIR ) & & ( psDroid - > droidType ! = DROID_CYBORG_REPAIR ) )
2006-09-19 09:07:06 -07:00
{
continue ;
}
2011-12-30 08:43:49 -08:00
if ( psDroid - > order . psObj ! = NULL & & psDroid - > order . psObj - > type = = OBJ_DROID )
2006-09-19 09:07:06 -07:00
{
2011-12-30 08:43:49 -08:00
if ( ( DROID * ) psDroid - > order . psObj = = psDroidToCheck )
2007-11-11 09:20:25 -08:00
{
2006-09-19 09:07:06 -07:00
numRepaired + + ;
2007-11-11 09:20:25 -08:00
}
2006-09-19 09:07:06 -07:00
}
}
return numRepaired ;
}
2009-02-22 16:21:46 -08:00
/* Uses debug_console() for console debug output right now */
2011-03-12 17:32:15 -08:00
bool scrMsgBox ( void )
2006-09-19 09:07:06 -07:00
{
2006-11-16 06:30:29 -08:00
if ( ! stackPopParams ( 1 , VAL_STRING , & strParam1 ) )
2006-09-19 09:07:06 -07:00
{
debug ( LOG_ERROR , " scrMsgBox(): stack failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-09-19 09:07:06 -07:00
}
2012-12-16 12:03:00 -08:00
debug_console ( " DEBUG: %s " , strParam1 ) ;
2006-09-23 07:56:18 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2006-09-19 09:07:06 -07:00
}
// Check for a struct being within a certain range of a position (must be visible)
2011-03-12 17:32:15 -08:00
bool scrStructInRangeVis ( void )
2006-09-19 09:07:06 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD range , player , lookingPlayer , x , y ;
2011-03-12 17:32:15 -08:00
bool found ;
2006-09-19 09:07:06 -07:00
if ( ! stackPopParams ( 5 , VAL_INT , & lookingPlayer , VAL_INT , & player , VAL_INT , & x , VAL_INT , & y , VAL_INT , & range ) )
{
debug ( LOG_ERROR , " scrStructInRangeVis: failed to pop " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-09-19 09:07:06 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2006-09-19 09:07:06 -07:00
2012-12-16 12:03:00 -08:00
found = objectInRangeVis ( ( BASE_OBJECT * ) apsStructLists [ player ] , x , y , range , lookingPlayer ) ;
2006-09-19 09:07:06 -07:00
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . bval = found ;
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2006-09-19 09:07:06 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2006-09-19 09:07:06 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-09-19 09:07:06 -07:00
}
2008-04-30 08:44:04 -07:00
// Check for a droid being within a certain range of a position (must be visible)
2011-03-12 17:32:15 -08:00
bool scrDroidInRangeVis ( void )
2008-04-30 08:44:04 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD range , player , lookingPlayer , x , y ;
2011-03-12 17:32:15 -08:00
bool found ;
2008-04-30 08:44:04 -07:00
if ( ! stackPopParams ( 5 , VAL_INT , & lookingPlayer , VAL_INT , & player , VAL_INT , & x , VAL_INT , & y , VAL_INT , & range ) )
{
debug ( LOG_ERROR , " scrDroidInRangeVis: failed to pop " ) ;
return false ;
}
if ( player < 0 | | player > = MAX_PLAYERS )
{
ASSERT ( false , " scrDroidInRangeVis: invalid player number " ) ;
return false ;
}
2012-12-16 12:03:00 -08:00
found = objectInRangeVis ( ( BASE_OBJECT * ) apsDroidLists [ player ] , x , y , range , lookingPlayer ) ;
2008-04-30 08:44:04 -07:00
scrFunctionResult . v . bval = found ;
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
{
return false ;
}
return true ;
}
2006-09-19 09:07:06 -07:00
// check for a base object being in range of a point
2011-03-12 17:32:15 -08:00
bool objectInRangeVis ( BASE_OBJECT * psList , SDWORD x , SDWORD y , SDWORD range , SDWORD lookingPlayer )
2006-09-19 09:07:06 -07:00
{
2006-09-23 07:56:18 -07:00
BASE_OBJECT * psCurr ;
2006-09-19 09:07:06 -07:00
SDWORD xdiff , ydiff , rangeSq ;
// See if there is a droid in range
rangeSq = range * range ;
2012-12-16 12:03:00 -08:00
for ( psCurr = psList ; psCurr ; psCurr = psCurr - > psNext )
2006-09-19 09:07:06 -07:00
{
2012-12-16 12:03:00 -08:00
if ( psCurr - > type = = OBJ_STRUCTURE )
2006-09-19 09:07:06 -07:00
{
2012-12-16 12:03:00 -08:00
if ( ! ( ( STRUCTURE * ) psCurr ) - > visible [ lookingPlayer ] )
{
2006-09-19 09:07:06 -07:00
continue ;
2012-12-16 12:03:00 -08:00
}
2006-09-19 09:07:06 -07:00
}
2012-12-16 12:03:00 -08:00
if ( psCurr - > type = = OBJ_DROID )
2006-09-19 09:07:06 -07:00
{
2012-12-16 12:03:00 -08:00
if ( ! ( ( DROID * ) psCurr ) - > visible [ lookingPlayer ] )
{
2006-09-19 09:07:06 -07:00
continue ;
2012-12-16 12:03:00 -08:00
}
2006-09-19 09:07:06 -07:00
}
// skip flying vtols
2012-12-16 12:03:00 -08:00
if ( ( psCurr - > type = = OBJ_DROID ) & &
isVtolDroid ( ( DROID * ) psCurr ) & &
( ( DROID * ) psCurr ) - > sMove . Status ! = MOVEINACTIVE )
2006-09-19 09:07:06 -07:00
{
continue ;
}
2007-12-15 07:39:29 -08:00
xdiff = ( SDWORD ) psCurr - > pos . x - x ;
ydiff = ( SDWORD ) psCurr - > pos . y - y ;
2012-12-16 12:03:00 -08:00
if ( xdiff * xdiff + ydiff * ydiff < rangeSq )
2006-09-19 09:07:06 -07:00
{
2008-03-24 09:51:17 -07:00
return true ;
2006-09-19 09:07:06 -07:00
}
}
2008-03-24 09:51:17 -07:00
return false ;
2006-09-19 09:07:06 -07:00
}
/* Go after a certain research */
2011-03-12 17:32:15 -08:00
bool scrPursueResearch ( void )
2006-09-19 09:07:06 -07:00
{
RESEARCH * psResearch ;
2010-10-18 20:02:34 -07:00
SDWORD foundIndex = 0 , player , cur , tempIndex , Stack [ 400 ] ;
2006-12-17 12:42:41 -08:00
UDWORD index ;
2006-09-19 09:07:06 -07:00
SWORD top ;
2011-03-12 17:32:15 -08:00
bool found ;
2006-09-19 09:07:06 -07:00
STRUCTURE * psBuilding ;
RESEARCH_FACILITY * psResFacilty ;
2006-09-23 07:56:18 -07:00
2012-12-16 12:03:00 -08:00
if ( ! stackPopParams ( 3 , ST_STRUCTURE , & psBuilding , VAL_INT , & player , ST_RESEARCH , & psResearch ) )
2006-09-19 09:07:06 -07:00
{
debug ( LOG_ERROR , " scrPursueResearch(): stack failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-09-19 09:07:06 -07:00
}
2010-10-18 20:02:34 -07:00
if ( psResearch = = NULL )
2006-09-23 07:56:18 -07:00
{
2008-03-24 09:51:17 -07:00
ASSERT ( false , " : no such research topic " ) ;
return false ;
2006-09-19 09:07:06 -07:00
}
2012-12-16 12:03:00 -08:00
psResFacilty = ( RESEARCH_FACILITY * ) psBuilding - > pFunctionality ;
2006-08-30 10:02:58 -07:00
2010-10-18 20:02:34 -07:00
if ( psResFacilty - > psSubject ! = NULL ) // not finished yet
2006-08-30 10:02:58 -07:00
{
2008-03-24 09:51:17 -07:00
scrFunctionResult . v . bval = false ;
2006-11-19 12:50:02 -08:00
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2006-09-19 09:07:06 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2006-09-19 09:07:06 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-09-19 09:07:06 -07:00
}
2011-12-02 05:26:37 -08:00
index = psResearch - > index ;
if ( index > = asResearch . size ( ) )
2006-09-19 09:07:06 -07:00
{
2008-03-24 09:51:17 -07:00
ASSERT ( false , " scrPursueResearch: invalid research index " ) ;
return false ;
2006-08-30 10:02:58 -07:00
}
2008-03-24 09:51:17 -07:00
found = false ;
2006-09-19 09:07:06 -07:00
2010-10-18 20:02:34 -07:00
if ( beingResearchedByAlly ( index , player ) ) //an ally is already researching it
2006-08-30 10:02:58 -07:00
{
2008-03-24 09:51:17 -07:00
found = false ;
2006-09-19 09:07:06 -07:00
}
2011-12-02 05:26:37 -08:00
else if ( IsResearchCompleted ( & asPlayerResList [ player ] [ index ] ) )
2006-09-19 09:07:06 -07:00
{
2008-03-24 09:51:17 -07:00
found = false ;
2006-09-19 09:07:06 -07:00
}
2011-12-02 05:26:37 -08:00
else if ( IsResearchStartedPending ( & asPlayerResList [ player ] [ index ] ) )
2006-09-19 09:07:06 -07:00
{
2008-03-24 09:51:17 -07:00
found = false ;
2006-09-19 09:07:06 -07:00
}
2011-12-02 05:26:37 -08:00
else if ( IsResearchPossible ( & asPlayerResList [ player ] [ index ] ) | | IsResearchCancelled ( & asPlayerResList [ player ] [ index ] ) )
2006-09-19 09:07:06 -07:00
{
foundIndex = index ;
2008-03-24 09:51:17 -07:00
found = true ;
2006-09-19 09:07:06 -07:00
}
2010-10-18 20:02:34 -07:00
else if ( skTopicAvail ( index , player ) )
2006-09-19 09:07:06 -07:00
{
foundIndex = index ;
2008-03-24 09:51:17 -07:00
found = true ;
2006-09-19 09:07:06 -07:00
}
else
{
top = - 1 ;
cur = 0 ; //start with first index's PR
2012-12-16 12:03:00 -08:00
while ( true ) //do
2006-08-30 10:02:58 -07:00
{
2011-12-02 05:26:37 -08:00
if ( cur > = asResearch [ index ] . pPRList . size ( ) ) //node has nodes?
2006-08-30 10:02:58 -07:00
{
2006-09-19 09:07:06 -07:00
top = top - 2 ;
2010-10-18 20:02:34 -07:00
if ( top < ( - 1 ) )
2006-08-30 10:02:58 -07:00
{
2006-09-19 09:07:06 -07:00
break ; //end of stack
}
index = Stack [ top + 2 ] ; //if index = -1, then exit
cur = Stack [ top + 1 ] ; //go to next PR of the last node, since this one didn't work
2006-09-23 07:56:18 -07:00
2006-09-19 09:07:06 -07:00
}
else //end of nodes not reached
{
tempIndex = asResearch [ index ] . pPRList [ cur ] ; //get cur node's index
2012-12-16 12:03:00 -08:00
if ( skTopicAvail ( tempIndex , player ) & & ( ! beingResearchedByAlly ( tempIndex , player ) ) ) //<NEW> - ally check added
2006-09-19 09:07:06 -07:00
{
2008-03-24 09:51:17 -07:00
found = true ;
2006-09-19 09:07:06 -07:00
foundIndex = tempIndex ; //done
break ;
}
2011-12-02 05:26:37 -08:00
else if ( ! IsResearchCompleted ( & asPlayerResList [ player ] [ tempIndex ] )
2012-12-16 12:03:00 -08:00
& & ! IsResearchStartedPending ( & asPlayerResList [ player ] [ tempIndex ] ) ) //not avail and not busy with it, can check this PR's PR
2006-09-19 09:07:06 -07:00
{
2011-12-02 05:26:37 -08:00
if ( ! asResearch [ tempIndex ] . pPRList . empty ( ) ) //node has any nodes itself
2006-09-19 09:07:06 -07:00
{
2012-12-16 12:03:00 -08:00
Stack [ top + 1 ] = cur ; //so can go back to it further
Stack [ top + 2 ] = index ;
2006-09-19 09:07:06 -07:00
top = top + 2 ;
index = tempIndex ; //go 1 level further
cur = - 1 ; //start with first PR of this PR next time
}
else //has no PRs, choose it (?)
{
2012-12-16 12:03:00 -08:00
if ( ! beingResearchedByAlly ( tempIndex , player ) ) //<NEW> ally check added
2006-09-19 09:07:06 -07:00
{
2008-03-24 09:51:17 -07:00
found = true ;
2006-09-19 09:07:06 -07:00
foundIndex = tempIndex ; //done
break ;
}
}
2006-08-30 10:02:58 -07:00
}
}
2006-09-19 09:07:06 -07:00
cur + + ; //try next node of the main node
2012-12-16 12:03:00 -08:00
if ( ( cur > = asResearch [ index ] . pPRList . size ( ) ) & & ( top < = ( - 1 ) ) ) //nothing left
2006-09-19 09:07:06 -07:00
{
break ;
}
2008-03-24 09:51:17 -07:00
} // while(true)
2006-09-19 09:07:06 -07:00
}
2011-12-02 05:26:37 -08:00
if ( found & & foundIndex < asResearch . size ( ) )
2006-09-19 09:07:06 -07:00
{
2010-10-18 20:02:34 -07:00
sendResearchStatus ( psBuilding , foundIndex , player , true ) ; // inform others, I'm researching this.
2010-04-20 17:59:26 -07:00
# if defined (DEBUG)
{
char sTemp [ 128 ] ;
2013-05-12 14:50:57 -07:00
sprintf ( sTemp , " player:%d starts topic: %s " , player , getName ( & asResearch [ foundIndex ] ) ) ;
2010-04-20 17:59:26 -07:00
NETlogEntry ( sTemp , SYNC_FLAG , 0 ) ;
}
# endif
2006-08-30 10:02:58 -07:00
}
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . bval = found ;
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2006-08-30 10:02:58 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2006-08-30 10:02:58 -07:00
}
2010-01-15 07:58:02 -08:00
intRefreshScreen ( ) ;
2006-08-30 10:02:58 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2006-08-30 10:02:58 -07:00
}
2011-03-12 17:32:15 -08:00
bool scrGetStructureType ( void )
2006-08-30 10:02:58 -07:00
{
2006-09-19 09:07:06 -07:00
STRUCTURE * psStruct ;
2006-08-30 10:02:58 -07:00
2006-09-19 09:07:06 -07:00
if ( ! stackPopParams ( 1 , ST_STRUCTURE , & psStruct ) )
2006-08-30 10:02:58 -07:00
{
2006-09-19 09:07:06 -07:00
debug ( LOG_ERROR , " scrGetStructureType(): stack failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-09-19 09:07:06 -07:00
}
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . ival = psStruct - > pStructureType - > type ;
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
2006-09-19 09:07:06 -07:00
{
debug ( LOG_ERROR , " scrGetStructureType(): failed to push result " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-09-19 09:07:06 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-09-19 09:07:06 -07:00
}
/* Get player name from index */
2011-03-12 17:32:15 -08:00
bool scrGetPlayerName ( void )
2006-09-19 09:07:06 -07:00
{
SDWORD player ;
if ( ! stackPopParams ( 1 , VAL_INT , & player ) )
{
debug ( LOG_ERROR , " scrGetPlayerName(): stack failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-09-19 09:07:06 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2006-09-19 09:07:06 -07:00
2008-11-13 14:42:05 -08:00
/* Casting away constness because stackPushResult doesn't modify it's
* value ( i . e . in this case it ' s not const correct ) .
*/
2012-12-16 12:03:00 -08:00
scrFunctionResult . v . sval = ( char * ) getPlayerName ( ( UDWORD ) player ) ;
2006-11-19 12:50:02 -08:00
if ( ! stackPushResult ( VAL_STRING , & scrFunctionResult ) )
2006-09-19 09:07:06 -07:00
{
2006-09-30 16:09:12 -07:00
debug ( LOG_ERROR , " scrGetPlayerName(): failed to push result " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-09-30 16:09:12 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-09-30 16:09:12 -07:00
}
/* Set player name */
2011-03-12 17:32:15 -08:00
bool scrSetPlayerName ( void )
2006-09-30 16:09:12 -07:00
{
SDWORD player ;
2006-11-16 06:30:29 -08:00
if ( ! stackPopParams ( 2 , VAL_INT , & player , VAL_STRING , & strParam1 ) )
2006-09-30 16:09:12 -07:00
{
debug ( LOG_ERROR , " scrSetPlayerName(): stack failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-09-30 16:09:12 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2006-09-30 16:09:12 -07:00
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . bval = setPlayerName ( player , strParam1 ) ;
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2006-09-30 16:09:12 -07:00
{
debug ( LOG_ERROR , " scrSetPlayerName(): failed to push result " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-09-19 09:07:06 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-09-19 09:07:06 -07:00
}
2006-11-03 13:35:50 -08:00
SDWORD getPlayerFromString ( char * playerName )
2006-09-19 09:07:06 -07:00
{
UDWORD playerIndex ;
2006-11-03 13:35:50 -08:00
char sPlayerNumber [ 255 ] ;
2006-09-19 09:07:06 -07:00
2012-12-16 12:03:00 -08:00
for ( playerIndex = 0 ; playerIndex < MAX_PLAYERS ; playerIndex + + )
2006-09-19 09:07:06 -07:00
{
/* check name */
2006-12-16 06:59:50 -08:00
//debug(LOG_SCRIPT, "checking (%s,%s)",getPlayerName(playerIndex), playerName);
2008-11-13 14:42:05 -08:00
if ( strncasecmp ( getPlayerName ( playerIndex ) , playerName , 255 ) = = 0 )
2006-08-30 10:02:58 -07:00
{
2006-12-16 06:59:50 -08:00
//debug(LOG_SCRIPT, "matched, returning %d", playerIndex);
2006-09-19 09:07:06 -07:00
return playerIndex ;
}
/* check color */
2006-12-16 06:59:50 -08:00
//debug(LOG_SCRIPT, "checking (%s,%s)",getPlayerColourName(playerIndex), playerName);
2008-11-13 14:42:05 -08:00
if ( strncasecmp ( getPlayerColourName ( playerIndex ) , playerName , 255 ) = = 0 )
2006-09-19 09:07:06 -07:00
{
2006-12-16 06:59:50 -08:00
//debug(LOG_SCRIPT, "matched, returning %d", playerIndex);
2006-09-19 09:07:06 -07:00
return playerIndex ;
}
/* check player number */
2012-12-16 12:03:00 -08:00
sprintf ( sPlayerNumber , " %d " , playerIndex ) ;
2006-12-16 06:59:50 -08:00
//debug(LOG_SCRIPT, "checking (%s,%s)",sPlayerNumber, playerName);
2012-12-16 12:03:00 -08:00
if ( strncasecmp ( sPlayerNumber , playerName , 255 ) = = 0 )
2006-09-19 09:07:06 -07:00
{
2006-12-16 06:59:50 -08:00
//debug(LOG_SCRIPT, "matched, returning %d", playerIndex);
2006-09-19 09:07:06 -07:00
return playerIndex ;
2006-08-30 10:02:58 -07:00
}
2006-09-23 07:56:18 -07:00
2006-08-30 10:02:58 -07:00
}
2006-09-19 09:07:06 -07:00
return - 1 ;
2006-08-30 10:02:58 -07:00
}
2006-10-24 06:05:40 -07:00
/* Checks if a particular bit is set in an integer */
2011-03-12 17:32:15 -08:00
bool scrGetBit ( void )
2006-10-24 06:05:40 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD val1 , val2 ;
2006-10-24 06:05:40 -07:00
if ( ! stackPopParams ( 2 , VAL_INT , & val1 , VAL_INT , & val2 ) )
{
2007-04-01 11:51:48 -07:00
debug ( LOG_ERROR , " scrGetBit(): failed to pop " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-10-24 06:05:40 -07:00
}
2007-04-01 11:51:48 -07:00
ASSERT ( val2 < MAX_PLAYERS & & val2 > = 0 , " scrGetBit(): wrong player index (%d) " , val2 ) ;
2006-10-24 06:05:40 -07:00
2007-04-01 09:22:01 -07:00
scrFunctionResult . v . bval = ( ( val1 & bitMask [ val2 ] ) ! = 0 ) ;
2006-11-19 12:50:02 -08:00
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2006-10-24 06:05:40 -07:00
{
2008-03-24 09:51:17 -07:00
return false ;
2006-10-24 06:05:40 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-10-24 06:05:40 -07:00
}
2007-04-01 09:22:01 -07:00
/* Sets a particular bit in an integer */
2011-03-12 17:32:15 -08:00
bool scrSetBit ( void )
2007-04-01 09:22:01 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD base , position ;
2011-03-19 18:52:25 -07:00
int32_t bSet ; // was BOOL (int) ** see warning about conversion
2007-04-01 09:22:01 -07:00
2007-04-01 11:22:33 -07:00
if ( ! stackPopParams ( 3 , VAL_INT , & base ,
2012-12-16 12:03:00 -08:00
VAL_INT , & position , VAL_BOOL , & bSet ) )
2007-04-01 09:22:01 -07:00
{
debug ( LOG_ERROR , " scrSetBit(): failed to pop " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-04-01 09:22:01 -07:00
}
ASSERT ( position < MAX_PLAYERS & & position > = 0 , " scrSetBit(): wrong position index (%d) " , position ) ;
2012-12-16 12:03:00 -08:00
if ( bSet )
2007-04-01 09:22:01 -07:00
{
base | = bitMask [ position ] ;
}
else
{
base & = bitMask [ position ] ;
}
scrFunctionResult . v . ival = base ;
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-04-01 09:22:01 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-04-01 09:22:01 -07:00
}
2006-11-16 06:30:29 -08:00
/* Can we create and break alliances? */
2011-03-12 17:32:15 -08:00
bool scrAlliancesLocked ( void )
2006-10-08 01:06:46 -07:00
{
2011-03-12 17:32:15 -08:00
bool bResult = true ;
2006-10-08 01:06:46 -07:00
2013-04-29 12:20:34 -07:00
if ( bMultiPlayer & & ! alliancesFixed ( game . alliance ) )
2012-12-16 12:03:00 -08:00
{
2008-03-24 09:51:17 -07:00
bResult = false ;
2012-12-16 12:03:00 -08:00
}
2006-10-08 01:06:46 -07:00
2006-11-19 12:50:02 -08:00
scrFunctionResult . v . bval = bResult ;
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
2006-10-08 01:06:46 -07:00
{
2006-11-01 05:56:23 -08:00
debug ( LOG_ERROR , " scrAlliancesLocked(): failed to push result " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-10-08 01:06:46 -07:00
}
2006-12-17 12:42:41 -08:00
2008-03-24 09:51:17 -07:00
return true ;
2006-10-08 01:06:46 -07:00
}
2011-03-12 17:32:15 -08:00
bool scrASSERT ( void )
2006-10-08 01:06:46 -07:00
{
2011-03-19 18:52:25 -07:00
int32_t bExpression ; // was BOOL (int) ** see warning about conversion
2006-10-08 01:06:46 -07:00
SDWORD player ;
2006-11-03 13:35:50 -08:00
char sTmp [ 255 ] ;
2006-10-08 01:06:46 -07:00
2006-11-16 06:30:29 -08:00
if ( ! stackPopParams ( 3 , VAL_BOOL , & bExpression , VAL_STRING , & strParam1 , VAL_INT , & player ) )
2006-10-08 01:06:46 -07:00
{
debug ( LOG_ERROR , " scrASSERT(): stack failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-10-08 01:06:46 -07:00
}
# ifdef DEBUG
/* Just pass the expression and message from script */
2012-12-16 12:03:00 -08:00
sprintf ( sTmp , " %d) %s " , player , strParam1 ) ;
2008-11-04 15:09:31 -08:00
ASSERT ( bExpression , " %s " , sTmp ) ;
2006-10-08 01:06:46 -07:00
# else
2012-12-16 12:03:00 -08:00
if ( scrDebug [ player ] )
2006-10-08 01:06:46 -07:00
{
2012-12-16 12:03:00 -08:00
if ( ! bExpression )
2006-10-08 01:06:46 -07:00
{
2012-12-16 12:03:00 -08:00
sprintf ( sTmp , " %d) %s " , player , strParam1 ) ;
addConsoleMessage ( sTmp , RIGHT_JUSTIFY , player ) ;
2006-10-08 01:06:46 -07:00
}
}
# endif
2008-03-24 09:51:17 -07:00
return true ;
2006-10-08 01:06:46 -07:00
}
/* Visualize radius at position */
2011-03-12 17:32:15 -08:00
bool scrShowRangeAtPos ( void )
2006-10-08 01:06:46 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD x , y , radius ;
2006-10-08 01:06:46 -07:00
if ( ! stackPopParams ( 3 , VAL_INT , & x , VAL_INT , & y , VAL_INT , & radius ) )
{
debug ( LOG_ERROR , " scrShowRangeAtPos(): stack failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-10-08 01:06:46 -07:00
}
//Turn on/off drawing
2012-12-16 12:03:00 -08:00
showRangeAtPos ( x , y , radius ) ;
2006-10-08 01:06:46 -07:00
2008-03-24 09:51:17 -07:00
return true ;
2006-10-08 01:06:46 -07:00
}
2006-11-01 05:56:23 -08:00
2011-03-12 17:32:15 -08:00
bool scrToPow ( void )
2006-11-01 05:56:23 -08:00
{
2012-12-16 12:03:00 -08:00
float x , y ;
2006-11-01 05:56:23 -08:00
2006-11-17 09:07:03 -08:00
if ( ! stackPopParams ( 2 , VAL_FLOAT , & x , VAL_FLOAT , & y ) )
2006-11-01 05:56:23 -08:00
{
debug ( LOG_ERROR , " scrToPow(): stack failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-11-01 05:56:23 -08:00
}
2012-12-16 12:03:00 -08:00
scrFunctionResult . v . fval = ( float ) pow ( x , y ) ;
2006-11-19 12:50:02 -08:00
if ( ! stackPushResult ( VAL_FLOAT , & scrFunctionResult ) )
2006-11-01 05:56:23 -08:00
{
debug ( LOG_ERROR , " scrToPow(): failed to push result " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-11-01 05:56:23 -08:00
}
2006-12-17 12:42:41 -08:00
2008-03-24 09:51:17 -07:00
return true ;
2006-11-01 05:56:23 -08:00
}
2007-09-29 08:04:25 -07:00
/* Exponential function */
2011-03-12 17:32:15 -08:00
bool scrExp ( void )
2007-09-29 08:04:25 -07:00
{
float fArg ;
if ( ! stackPopParams ( 1 , VAL_FLOAT , & fArg ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-09-29 08:04:25 -07:00
}
scrFunctionResult . v . fval = exp ( fArg ) ;
if ( ! stackPushResult ( VAL_FLOAT , & scrFunctionResult ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-09-29 08:04:25 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-09-29 08:04:25 -07:00
}
/* Square root */
2011-03-12 17:32:15 -08:00
bool scrSqrt ( void )
2007-09-29 08:04:25 -07:00
{
float fArg ;
if ( ! stackPopParams ( 1 , VAL_FLOAT , & fArg ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-09-29 08:04:25 -07:00
}
2008-03-07 03:59:26 -08:00
scrFunctionResult . v . fval = sqrtf ( fArg ) ;
2007-09-29 08:04:25 -07:00
if ( ! stackPushResult ( VAL_FLOAT , & scrFunctionResult ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-09-29 08:04:25 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-09-29 08:04:25 -07:00
}
2008-01-05 11:42:43 -08:00
/* Natural logarithm */
2011-03-12 17:32:15 -08:00
bool scrLog ( void )
2008-01-05 11:42:43 -08:00
{
float fArg ;
if ( ! stackPopParams ( 1 , VAL_FLOAT , & fArg ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2008-01-05 11:42:43 -08:00
}
scrFunctionResult . v . fval = log ( fArg ) ;
if ( ! stackPushResult ( VAL_FLOAT , & scrFunctionResult ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2008-01-05 11:42:43 -08:00
}
2008-03-24 09:51:17 -07:00
return true ;
2008-01-05 11:42:43 -08:00
}
2013-05-18 05:25:46 -07:00
bool scrDebugMenu ( ) // no-op
2006-11-01 05:56:23 -08:00
{
2013-05-18 05:25:46 -07:00
int32_t menuUp ;
stackPopParams ( 1 , VAL_BOOL , & menuUp ) ;
2008-03-24 09:51:17 -07:00
return true ;
2006-11-01 05:56:23 -08:00
}
2013-05-18 05:25:46 -07:00
bool scrSetDebugMenuEntry ( ) // no-op
2006-11-01 05:56:23 -08:00
{
2013-05-18 05:25:46 -07:00
int index ;
stackPopParams ( 2 , VAL_STRING , & strParam1 , VAL_INT , & index ) ;
2008-03-24 09:51:17 -07:00
return true ;
2006-11-01 05:56:23 -08:00
}
2006-12-16 06:59:50 -08:00
/* Parse chat message and return number of commands that could be extracted */
2011-03-12 17:32:15 -08:00
bool scrProcessChatMsg ( void )
2006-12-16 06:59:50 -08:00
{
if ( ! stackPopParams ( 1 , VAL_STRING , & strParam1 ) )
{
debug ( LOG_ERROR , " scrProcessChatMsg(): stack failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-12-16 06:59:50 -08:00
}
2007-01-07 12:15:07 -08:00
debug ( LOG_NEVER , " Now preparing to parse '%s' " , strParam1 ) ;
2006-12-16 06:59:50 -08:00
if ( ! chatLoad ( strParam1 , strlen ( strParam1 ) ) )
{
2008-03-24 09:51:17 -07:00
ASSERT ( false , " Couldn't process chat message: %s " , strParam1 ) ;
return false ;
2006-12-16 06:59:50 -08:00
}
scrFunctionResult . v . ival = chat_msg . numCommands ;
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
{
debug ( LOG_ERROR , " scrProcessChatMsg(): failed to push result " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-12-16 06:59:50 -08:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-12-16 06:59:50 -08:00
}
/* Returns number of command arguments for a certain
* chat command that could be extracted
*/
2011-03-12 17:32:15 -08:00
bool scrGetNumArgsInCmd ( void )
2006-12-16 06:59:50 -08:00
{
SDWORD cmdIndex ;
if ( ! stackPopParams ( 1 , VAL_INT , & cmdIndex ) )
{
debug ( LOG_ERROR , " scrGetNumArgsInCmd(): stack failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-12-16 06:59:50 -08:00
}
/* Check command bounds */
2012-12-16 12:03:00 -08:00
if ( cmdIndex < 0 | | cmdIndex > = chat_msg . numCommands )
2006-12-16 06:59:50 -08:00
{
2008-03-24 09:51:17 -07:00
ASSERT ( false , " scrGetNumArgsInCmd: command inxed out of bounds: %d (num commands: %d) " ,
2012-12-16 12:03:00 -08:00
cmdIndex , chat_msg . numCommands ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-12-16 06:59:50 -08:00
}
scrFunctionResult . v . ival = chat_msg . cmdData [ cmdIndex ] . numCmdParams ;
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
{
debug ( LOG_ERROR , " scrGetNumArgsInCmd(): failed to push result " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-12-16 06:59:50 -08:00
}
2006-12-17 12:42:41 -08:00
2008-03-24 09:51:17 -07:00
return true ;
2006-12-16 06:59:50 -08:00
}
/* Returns a string representing a certain chat command,
* based on the command index provided
*/
2011-03-12 17:32:15 -08:00
bool scrGetChatCmdDescription ( void )
2006-12-16 06:59:50 -08:00
{
SDWORD cmdIndex ;
2012-12-16 12:03:00 -08:00
char * pChatCommand = NULL ;
2006-12-16 06:59:50 -08:00
if ( ! stackPopParams ( 1 , VAL_INT , & cmdIndex ) )
{
debug ( LOG_ERROR , " scrGetCommandDescription(): stack failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-12-16 06:59:50 -08:00
}
/* Check command bounds */
2012-12-16 12:03:00 -08:00
if ( cmdIndex < 0 | | cmdIndex > = chat_msg . numCommands )
2006-12-16 06:59:50 -08:00
{
2008-03-24 09:51:17 -07:00
ASSERT ( false , " scrGetCommandDescription: command inxed out of bounds: %d (num commands: %d) " ,
2012-12-16 12:03:00 -08:00
cmdIndex , chat_msg . numCommands ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-12-16 06:59:50 -08:00
}
/* Allocate memory for the comamnd string */
2012-12-16 12:03:00 -08:00
pChatCommand = ( char * ) malloc ( MAXSTRLEN ) ;
2007-10-27 07:35:35 -07:00
if ( pChatCommand = = NULL )
{
2009-10-30 20:57:44 -07:00
debug ( LOG_FATAL , " scrGetCmdDescription: Out of memory! " ) ;
2007-10-27 07:35:35 -07:00
abort ( ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-10-27 07:35:35 -07:00
}
2006-12-16 06:59:50 -08:00
/* Copy command */
2007-10-27 07:35:35 -07:00
strlcpy ( pChatCommand , chat_msg . cmdData [ cmdIndex ] . pCmdDescription , MAXSTRLEN ) ;
2006-12-16 06:59:50 -08:00
2006-12-17 12:42:41 -08:00
/* Make scrFunctionResult point to the valid command */
2006-12-16 06:59:50 -08:00
scrFunctionResult . v . sval = pChatCommand ;
if ( ! stackPushResult ( VAL_STRING , & scrFunctionResult ) )
{
debug ( LOG_ERROR , " scrGetCommandDescription(): failed to push result " ) ;
2007-04-15 03:43:05 -07:00
free ( pChatCommand ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-12-16 06:59:50 -08:00
}
2007-04-15 03:43:05 -07:00
free ( pChatCommand ) ;
2006-12-17 12:42:41 -08:00
2008-03-24 09:51:17 -07:00
return true ;
2006-12-16 06:59:50 -08:00
}
/* Returns a certain parameter of a certain chat command
2008-03-24 09:51:17 -07:00
* Returns false if failed
2006-12-16 06:59:50 -08:00
*/
2011-03-12 17:32:15 -08:00
bool scrGetChatCmdParam ( void )
2006-12-16 06:59:50 -08:00
{
SDWORD cmdIndex , argIndex ;
2012-12-16 12:03:00 -08:00
void * pArgument = NULL ;
INTERP_TYPE argType = VAL_VOID ;
bool bSuccess = true ; //failure on type mismatch
2006-12-16 06:59:50 -08:00
if ( ! stackPopParams ( 2 , VAL_INT , & cmdIndex , VAL_INT , & argIndex ) )
{
debug ( LOG_ERROR , " scrGetChatCmdParam(): stack failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-12-16 06:59:50 -08:00
}
2012-12-16 12:03:00 -08:00
if ( cmdIndex < 0 | | cmdIndex > = chat_msg . numCommands )
2006-12-16 06:59:50 -08:00
{
2008-03-24 09:51:17 -07:00
ASSERT ( false , " scrGetChatCmdParam: command index out of bounds: %d " , cmdIndex ) ;
return false ;
2006-12-16 06:59:50 -08:00
}
2012-12-16 12:03:00 -08:00
if ( argIndex < 0 | | argIndex > = chat_msg . cmdData [ cmdIndex ] . numCmdParams )
2006-12-16 06:59:50 -08:00
{
2008-03-24 09:51:17 -07:00
ASSERT ( false , " scrGetChatCmdParam: argument index for command %d is out of bounds: %d " , cmdIndex , argIndex ) ;
return false ;
2006-12-16 06:59:50 -08:00
}
/* Find out the type of the argument we are going to pass to the script */
argType = chat_msg . cmdData [ cmdIndex ] . parameter [ argIndex ] . type ;
if ( ! stackPopParams ( 1 , VAL_REF | argType , & pArgument ) )
{
debug ( LOG_ERROR , " scrGetChatCmdParam(): stack failed or argument mismatch (expected type of argument: %d) " , argType ) ;
2008-03-24 09:51:17 -07:00
bSuccess = false ; //return type mismatch
//return false;
2006-12-16 06:59:50 -08:00
}
2012-12-16 12:03:00 -08:00
if ( pArgument = = NULL )
2006-12-16 06:59:50 -08:00
{
2008-03-24 09:51:17 -07:00
ASSERT ( false , " scrGetChatCmdParam: nullpointer check failed " ) ;
bSuccess = false ;
2006-12-16 06:59:50 -08:00
}
/* Return command argument to the script */
2012-12-16 12:03:00 -08:00
if ( bSuccess )
{
2006-12-16 06:59:50 -08:00
memcpy ( pArgument , & ( chat_msg . cmdData [ cmdIndex ] . parameter [ argIndex ] . v ) , sizeof ( chat_msg . cmdData [ cmdIndex ] . parameter [ argIndex ] . v ) ) ;
}
scrFunctionResult . v . bval = bSuccess ;
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
{
debug ( LOG_ERROR , " scrGetChatCmdParam(): failed to push result " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-12-16 06:59:50 -08:00
}
2008-03-24 09:51:17 -07:00
return true ;
2006-12-16 06:59:50 -08:00
}
/* Returns true if a certain command was addressed to a certain player */
2011-03-12 17:32:15 -08:00
bool scrChatCmdIsPlayerAddressed ( void )
2006-12-16 06:59:50 -08:00
{
2012-12-16 12:03:00 -08:00
SDWORD cmdIndex , playerInQuestion ;
2006-12-16 06:59:50 -08:00
if ( ! stackPopParams ( 2 , VAL_INT , & cmdIndex , VAL_INT , & playerInQuestion ) )
{
debug ( LOG_ERROR , " scrChatCmdIsPlayerAddressed(): stack failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-12-16 06:59:50 -08:00
}
/* Check command bounds */
2012-12-16 12:03:00 -08:00
if ( cmdIndex < 0 | | cmdIndex > = chat_msg . numCommands )
2006-12-16 06:59:50 -08:00
{
2008-03-24 09:51:17 -07:00
ASSERT ( false , " scrChatCmdIsPlayerAddressed: command inxed out of bounds: %d (num commands: %d) " ,
2012-12-16 12:03:00 -08:00
cmdIndex , chat_msg . numCommands ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-12-16 06:59:50 -08:00
}
/* Check player bounds */
2012-12-16 12:03:00 -08:00
if ( playerInQuestion < 0 | | playerInQuestion > = MAX_PLAYERS )
2006-12-16 06:59:50 -08:00
{
2008-03-24 09:51:17 -07:00
ASSERT ( false , " scrChatCmdIsPlayerAddressed: player inxed out of bounds: %d " , playerInQuestion ) ;
return false ;
2006-12-16 06:59:50 -08:00
}
scrFunctionResult . v . bval = chat_msg . cmdData [ cmdIndex ] . bPlayerAddressed [ playerInQuestion ] ;
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
{
debug ( LOG_ERROR , " scrChatCmdIsPlayerAddressed(): failed to push result " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-12-16 06:59:50 -08:00
}
2006-12-17 12:42:41 -08:00
2008-03-24 09:51:17 -07:00
return true ;
2006-12-16 06:59:50 -08:00
}
2006-12-26 08:39:07 -08:00
/* Modifies height of a tile */
2011-03-12 17:32:15 -08:00
bool scrSetTileHeight ( void )
2006-12-26 08:39:07 -08:00
{
2012-12-16 12:03:00 -08:00
UDWORD tileX , tileY , newHeight ;
2006-12-26 08:39:07 -08:00
MAPTILE * psTile ;
if ( ! stackPopParams ( 3 , VAL_INT , & tileX , VAL_INT , & tileY , VAL_INT , & newHeight ) )
{
debug ( LOG_ERROR , " scrSetTileHeight(): stack failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2006-12-26 08:39:07 -08:00
}
ASSERT ( newHeight < = 255 , " scrSetTileHeight: height out of bounds " ) ;
2012-12-16 12:03:00 -08:00
psTile = mapTile ( tileX , tileY ) ;
2006-12-26 08:39:07 -08:00
2010-11-16 11:02:22 -08:00
psTile - > height = ( UBYTE ) newHeight * ELEVATION_SCALE ;
2006-12-26 08:39:07 -08:00
2008-03-24 09:51:17 -07:00
return true ;
2006-12-26 08:39:07 -08:00
}
2007-02-10 07:23:47 -08:00
/* Returns structure which placed on provided coordinates.
* Returns NULL ( NULLOBJECT ) if there ' s no structure .
*/
2011-03-12 17:32:15 -08:00
bool scrGetTileStructure ( void )
2007-02-10 07:23:47 -08:00
{
2012-12-16 12:03:00 -08:00
SDWORD structureX , structureY ;
2007-02-10 07:23:47 -08:00
if ( ! stackPopParams ( 2 , VAL_INT , & structureX , VAL_INT , & structureY ) )
{
debug ( LOG_ERROR , " scrGetTileStructure(): stack failed " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-02-10 07:23:47 -08:00
}
scrFunctionResult . v . oval = getTileStructure ( structureX , structureY ) ;
2008-01-30 15:35:13 -08:00
if ( ! stackPushResult ( ( INTERP_TYPE ) ST_STRUCTURE , & scrFunctionResult ) )
2007-02-10 07:23:47 -08:00
{
debug ( LOG_ERROR , " scrGetTileStructure(): failed to push result " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-02-10 07:23:47 -08:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-02-10 07:23:47 -08:00
}
2007-02-14 10:29:26 -08:00
/* Outputs script call stack
*/
2011-03-12 17:32:15 -08:00
bool scrPrintCallStack ( void )
2007-02-14 10:29:26 -08:00
{
2008-10-25 10:56:43 -07:00
scrOutputCallTrace ( LOG_SCRIPT ) ;
2007-02-14 10:29:26 -08:00
2008-03-24 09:51:17 -07:00
return true ;
2007-02-14 10:29:26 -08:00
}
2007-05-29 07:21:39 -07:00
/*
* Returns true if game debug mode is on
*/
2011-03-12 17:32:15 -08:00
bool scrDebugModeEnabled ( void )
2007-05-29 07:21:39 -07:00
{
scrFunctionResult . v . bval = getDebugMappingStatus ( ) ;
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
{
debug ( LOG_ERROR , " scrDebugModeEnabled(): failed to push result " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-05-29 07:21:39 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-05-29 07:21:39 -07:00
}
2007-07-15 08:53:41 -07:00
/*
* Returns the cost of a droid
*/
2011-03-12 17:32:15 -08:00
bool scrCalcDroidPower ( void )
2007-07-15 08:53:41 -07:00
{
DROID * psDroid ;
if ( ! stackPopParams ( 1 , ST_DROID , & psDroid ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-07-15 08:53:41 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT ( psDroid ! = NULL , " can't calculate cost of a null-droid " ) ;
2007-07-15 08:53:41 -07:00
scrFunctionResult . v . ival = ( SDWORD ) calcDroidPower ( psDroid ) ;
2007-07-19 12:28:25 -07:00
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
2007-07-15 08:53:41 -07:00
{
2007-07-27 11:18:37 -07:00
debug ( LOG_ERROR , " scrCalcDroidPower(): failed to push result " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-07-27 11:18:37 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-07-27 11:18:37 -07:00
}
/*
* Returns experience level of a droid
*/
2011-03-12 17:32:15 -08:00
bool scrGetDroidLevel ( void )
2007-07-27 11:18:37 -07:00
{
DROID * psDroid ;
if ( ! stackPopParams ( 1 , ST_DROID , & psDroid ) )
{
2008-03-24 09:51:17 -07:00
return false ;
2007-07-27 11:18:37 -07:00
}
2012-12-16 12:03:00 -08:00
ASSERT ( psDroid ! = NULL , " null-pointer passed " ) ;
2007-07-27 11:18:37 -07:00
scrFunctionResult . v . ival = ( SDWORD ) getDroidLevel ( psDroid ) ;
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
{
debug ( LOG_ERROR , " scrGetDroidLevel(): failed to push result " ) ;
2008-03-24 09:51:17 -07:00
return false ;
2007-07-15 08:53:41 -07:00
}
2008-03-24 09:51:17 -07:00
return true ;
2007-07-15 08:53:41 -07:00
}
2008-04-30 08:44:04 -07:00
2008-05-10 06:20:23 -07:00
/* Assembles a template from components and returns it */
2011-03-12 17:32:15 -08:00
bool scrAssembleWeaponTemplate ( void )
2008-05-10 06:20:23 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD player , bodyIndex , weapIndex , propIndex ;
2008-05-10 06:20:23 -07:00
DROID_TEMPLATE * pNewTemplate = NULL ;
if ( ! stackPopParams ( 4 , VAL_INT , & player , ST_BODY , & bodyIndex ,
2012-12-16 12:03:00 -08:00
ST_PROPULSION , & propIndex , ST_WEAPON , & weapIndex ) )
2008-05-10 06:20:23 -07:00
{
return false ;
}
2011-01-01 11:35:07 -08:00
pNewTemplate = new DROID_TEMPLATE ;
2008-05-10 06:20:23 -07:00
if ( pNewTemplate = = NULL )
{
debug ( LOG_ERROR , " pNewTemplate: Out of memory " ) ;
return false ;
}
// set template body
pNewTemplate - > asParts [ COMP_BODY ] = bodyIndex ;
// set template propulsion
pNewTemplate - > asParts [ COMP_PROPULSION ] = propIndex ;
// set template weapon (only one)
pNewTemplate - > asWeaps [ 0 ] = weapIndex ;
pNewTemplate - > numWeaps = 1 ;
// set default components
pNewTemplate - > asParts [ COMP_SENSOR ] = 0 ;
pNewTemplate - > asParts [ COMP_ECM ] = 0 ;
pNewTemplate - > asParts [ COMP_CONSTRUCT ] = 0 ;
pNewTemplate - > asParts [ COMP_REPAIRUNIT ] = 0 ;
pNewTemplate - > asParts [ COMP_BRAIN ] = 0 ;
// set droid type
pNewTemplate - > droidType = DROID_WEAPON ;
// finalize template and set its name
2013-01-21 13:17:58 -08:00
if ( ! intValidTemplate ( pNewTemplate , GetDefaultTemplateName ( pNewTemplate ) , false , player ) )
2008-05-10 06:20:23 -07:00
{
2013-10-05 09:22:04 -07:00
delete pNewTemplate ;
2008-05-10 06:20:23 -07:00
return false ;
}
// make sure we have a valid weapon
2012-12-16 12:03:00 -08:00
if ( ! checkValidWeaponForProp ( pNewTemplate ) )
2008-05-10 06:20:23 -07:00
{
scrFunctionResult . v . oval = NULL ; // failure
}
else
{
DROID_TEMPLATE * tempTemplate = NULL ;
// check if an identical template already exists for this player
tempTemplate = scrCheckTemplateExists ( player , pNewTemplate ) ;
2012-12-16 12:03:00 -08:00
if ( tempTemplate = = NULL )
2008-05-10 06:20:23 -07:00
{
// set template id
2010-02-12 11:55:11 -08:00
pNewTemplate - > multiPlayerID = generateNewObjectId ( ) ;
2008-05-10 06:20:23 -07:00
// add template to player template list
pNewTemplate - > psNext = apsDroidTemplates [ player ] ;
apsDroidTemplates [ player ] = pNewTemplate ; //apsTemplateList?
2008-05-13 16:32:07 -07:00
2010-01-22 12:44:50 -08:00
if ( bMultiMessages )
2008-05-10 06:20:23 -07:00
{
2011-01-18 04:16:41 -08:00
sendTemplate ( player , pNewTemplate ) ;
2008-05-10 06:20:23 -07:00
}
}
else
{
// free resources
2011-01-01 11:35:07 -08:00
delete pNewTemplate ;
2008-05-10 06:20:23 -07:00
// already exists, so return it
pNewTemplate = tempTemplate ;
}
scrFunctionResult . v . oval = pNewTemplate ; // succes
}
// return template to scripts
2009-03-29 13:49:35 -07:00
if ( ! stackPushResult ( ( INTERP_TYPE ) ST_TEMPLATE , & scrFunctionResult ) )
2008-05-10 06:20:23 -07:00
{
return false ;
}
return true ;
}
/* Checks if template already exists, returns it if yes */
2012-12-16 12:03:00 -08:00
static DROID_TEMPLATE * scrCheckTemplateExists ( SDWORD player , DROID_TEMPLATE * psTempl )
2008-05-10 06:20:23 -07:00
{
2012-12-16 12:03:00 -08:00
DROID_TEMPLATE * psCurrent ;
2011-03-12 17:32:15 -08:00
bool equal ;
2008-05-10 06:20:23 -07:00
2008-11-14 10:56:40 -08:00
for ( psCurrent = apsDroidTemplates [ player ] ; psCurrent ! = NULL ; psCurrent = psCurrent - > psNext )
2008-11-14 10:47:55 -08:00
{
2008-11-14 10:56:40 -08:00
unsigned int weaponSlot ;
2008-12-25 17:46:29 -08:00
2008-12-25 06:27:19 -08:00
equal = true ;
2008-11-14 10:47:55 -08:00
2008-05-10 06:20:23 -07:00
// compare components
2013-05-13 13:20:49 -07:00
for ( int componentType = 0 ; componentType < ARRAY_SIZE ( psTempl - > asParts ) ; + + componentType )
2008-05-10 06:20:23 -07:00
{
2008-11-14 10:47:55 -08:00
if ( psTempl - > asParts [ componentType ] ! = psCurrent - > asParts [ componentType ] )
2008-05-10 06:20:23 -07:00
{
2008-12-25 06:27:19 -08:00
equal = false ;
break ;
2008-05-10 06:20:23 -07:00
}
}
// compare weapon count
2008-11-14 10:56:40 -08:00
if ( psTempl - > numWeaps ! = psCurrent - > numWeaps )
2008-05-10 06:20:23 -07:00
{
2008-12-25 06:27:19 -08:00
equal = false ;
2008-05-10 06:20:23 -07:00
}
// compare all weapons separately
2012-12-16 12:03:00 -08:00
for ( weaponSlot = 0 ; equal & & weaponSlot < psTempl - > numWeaps ; + + weaponSlot )
2008-05-10 06:20:23 -07:00
{
2008-11-14 10:56:40 -08:00
if ( psTempl - > asWeaps [ weaponSlot ] ! = psCurrent - > asWeaps [ weaponSlot ] )
2008-05-10 06:20:23 -07:00
{
2008-12-25 06:27:19 -08:00
equal = false ;
break ;
2008-05-10 06:20:23 -07:00
}
}
2008-12-25 06:27:19 -08:00
if ( equal )
{
// they are equal, so return the current template
return psCurrent ;
}
2008-11-14 10:56:40 -08:00
}
2008-05-10 06:20:23 -07:00
return NULL ;
}
2013-05-05 04:34:59 -07:00
// deprecated
2011-03-12 17:32:15 -08:00
bool scrWeaponLongHitUpgrade ( void )
2008-05-10 06:20:23 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD player , weapIndex ;
2008-05-10 06:20:23 -07:00
if ( ! stackPopParams ( 2 , VAL_INT , & player , ST_WEAPON , & weapIndex ) )
{
return false ;
}
2013-05-05 04:34:59 -07:00
scrFunctionResult . v . ival = 0 ;
2008-05-10 06:20:23 -07:00
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
{
return false ;
}
return true ;
}
2013-05-05 04:34:59 -07:00
// deprecated
2011-03-12 17:32:15 -08:00
bool scrWeaponDamageUpgrade ( void )
2008-05-10 06:20:23 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD player , weapIndex ;
2008-05-10 06:20:23 -07:00
if ( ! stackPopParams ( 2 , VAL_INT , & player , ST_WEAPON , & weapIndex ) )
{
return false ;
}
2013-05-05 04:34:59 -07:00
scrFunctionResult . v . ival = 0 ;
2008-05-10 06:20:23 -07:00
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
{
return false ;
}
return true ;
}
2013-05-05 04:34:59 -07:00
// deprecated
2011-03-12 17:32:15 -08:00
bool scrWeaponFirePauseUpgrade ( void )
2008-05-10 06:20:23 -07:00
{
2012-12-16 12:03:00 -08:00
SDWORD player , weapIndex ;
2008-05-10 06:20:23 -07:00
if ( ! stackPopParams ( 2 , VAL_INT , & player , ST_WEAPON , & weapIndex ) )
{
return false ;
}
2013-05-05 04:34:59 -07:00
scrFunctionResult . v . ival = 0 ;
2008-05-10 06:20:23 -07:00
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
{
return false ;
}
return true ;
}
2011-03-12 17:32:15 -08:00
bool scrIsComponentAvailable ( void )
2008-05-10 06:20:23 -07:00
{
SDWORD player ;
2011-03-12 17:32:15 -08:00
bool bAvailable = false ;
2008-05-10 06:20:23 -07:00
INTERP_VAL sVal ;
if ( ! stackPop ( & sVal ) )
{
return false ;
}
if ( ! stackPopParams ( 1 , VAL_INT , & player ) )
{
return false ;
}
2012-12-16 12:03:00 -08:00
ASSERT_OR_RETURN ( false , player > = 0 & & player < MAX_PLAYERS , " Invalid player number " ) ;
2008-05-10 06:20:23 -07:00
2010-12-21 15:58:59 -08:00
switch ( ( unsigned ) sVal . type ) // Unsigned cast to suppress compiler warnings due to enum abuse.
2008-05-10 06:20:23 -07:00
{
case ST_BODY :
bAvailable = ( apCompLists [ player ] [ COMP_BODY ] [ sVal . v . ival ] = = AVAILABLE ) ;
break ;
case ST_PROPULSION :
bAvailable = ( apCompLists [ player ] [ COMP_PROPULSION ] [ sVal . v . ival ] = = AVAILABLE ) ;
break ;
case ST_ECM :
bAvailable = ( apCompLists [ player ] [ COMP_ECM ] [ sVal . v . ival ] = = AVAILABLE ) ;
break ;
case ST_SENSOR :
bAvailable = ( apCompLists [ player ] [ COMP_SENSOR ] [ sVal . v . ival ] = = AVAILABLE ) ;
break ;
case ST_CONSTRUCT :
bAvailable = ( apCompLists [ player ] [ COMP_CONSTRUCT ] [ sVal . v . ival ] = = AVAILABLE ) ;
break ;
case ST_WEAPON :
bAvailable = ( apCompLists [ player ] [ COMP_WEAPON ] [ sVal . v . ival ] = = AVAILABLE ) ;
break ;
case ST_REPAIR :
bAvailable = ( apCompLists [ player ] [ COMP_REPAIRUNIT ] [ sVal . v . ival ] = = AVAILABLE ) ;
break ;
case ST_BRAIN :
bAvailable = ( apCompLists [ player ] [ COMP_BRAIN ] [ sVal . v . ival ] = = AVAILABLE ) ;
break ;
default :
2012-12-16 12:03:00 -08:00
ASSERT ( false , " unknown component type " ) ;
2008-05-10 06:20:23 -07:00
return false ;
}
scrFunctionResult . v . bval = bAvailable ;
if ( ! stackPushResult ( VAL_BOOL , & scrFunctionResult ) )
{
return false ;
}
return true ;
}
2011-03-12 17:32:15 -08:00
bool scrGetBodySize ( void )
2008-05-10 06:20:23 -07:00
{
SDWORD bodyIndex ;
2012-12-16 12:03:00 -08:00
if ( ! stackPopParams ( 1 , ST_BODY , & bodyIndex ) )
2008-05-10 06:20:23 -07:00
{
return false ;
}
scrFunctionResult . v . ival = asBodyStats [ bodyIndex ] . size ;
if ( ! stackPushResult ( VAL_INT , & scrFunctionResult ) )
{
return false ;
}
return true ;
}
2008-07-27 19:12:12 -07:00
2011-03-12 17:32:15 -08:00
bool scrGettext ( )
2008-07-27 19:12:12 -07:00
{
if ( ! stackPopParams ( 1 , VAL_STRING , & strParam1 ) )
{
return false ;
}
2012-12-16 12:03:00 -08:00
scrFunctionResult . v . sval = ( char * ) gettext ( strParam1 ) ;
2008-07-27 19:12:12 -07:00
2009-03-29 13:49:35 -07:00
return stackPushResult ( ( INTERP_TYPE ) ST_TEXTSTRING , & scrFunctionResult ) ;
2008-07-27 19:12:12 -07:00
}
2008-07-27 19:12:59 -07:00
2011-03-12 17:32:15 -08:00
bool scrGettext_noop ( )
2008-07-27 19:12:59 -07:00
{
if ( ! stackPopParams ( 1 , VAL_STRING , & strParam1 ) )
{
return false ;
}
scrFunctionResult . v . sval = gettext_noop ( strParam1 ) ;
return stackPushResult ( VAL_STRING , & scrFunctionResult ) ;
}
2011-03-12 17:32:15 -08:00
bool scrPgettext ( )
2008-07-27 19:12:59 -07:00
{
2012-12-16 12:03:00 -08:00
char * msg_ctxt_id ;
char * translation ;
2008-07-27 19:12:59 -07:00
if ( ! stackPopParams ( 2 , VAL_STRING , & strParam1 , VAL_STRING , & strParam2 ) )
{
return false ;
}
2008-11-14 06:34:32 -08:00
if ( asprintf ( & msg_ctxt_id , " %s%s%s " , strParam1 , GETTEXT_CONTEXT_GLUE , strParam2 ) = = - 1 )
2008-07-27 19:12:59 -07:00
{
2009-10-30 20:57:44 -07:00
debug ( LOG_FATAL , " Out of memory " ) ;
2008-07-27 19:12:59 -07:00
abort ( ) ;
return false ;
}
# ifdef DEFAULT_TEXT_DOMAIN
2012-12-16 12:03:00 -08:00
translation = ( char * ) dcgettext ( DEFAULT_TEXT_DOMAIN , msg_ctxt_id , LC_MESSAGES ) ;
2008-07-27 19:12:59 -07:00
# else
2012-12-16 12:03:00 -08:00
translation = ( char * ) dcgettext ( NULL , msg_ctxt_id , LC_MESSAGES ) ;
2008-07-27 19:12:59 -07:00
# endif
/* Due to the way dcgettext works a pointer comparison is enough, hence
* the reason why we free ( ) now .
*/
free ( msg_ctxt_id ) ;
if ( translation = = msg_ctxt_id )
{
scrFunctionResult . v . sval = strParam2 ;
}
else
{
scrFunctionResult . v . sval = translation ;
}
2009-03-29 13:49:35 -07:00
return stackPushResult ( ( INTERP_TYPE ) ST_TEXTSTRING , & scrFunctionResult ) ;
2008-07-27 19:12:59 -07:00
}
2011-03-12 17:32:15 -08:00
bool scrPgettext_expr ( )
2008-07-27 19:12:59 -07:00
{
if ( ! stackPopParams ( 2 , VAL_STRING , & strParam1 , VAL_STRING , & strParam2 ) )
{
return false ;
}
2012-12-16 12:03:00 -08:00
scrFunctionResult . v . sval = ( char * ) pgettext_expr ( strParam1 , strParam2 ) ;
2008-07-27 19:12:59 -07:00
2009-03-29 13:49:35 -07:00
return stackPushResult ( ( INTERP_TYPE ) ST_TEXTSTRING , & scrFunctionResult ) ;
2008-07-27 19:12:59 -07:00
}
2011-03-12 17:32:15 -08:00
bool scrPgettext_noop ( )
2008-07-27 19:12:59 -07:00
{
if ( ! stackPopParams ( 2 , VAL_STRING , & strParam1 , VAL_STRING , & strParam2 ) )
{
return false ;
}
scrFunctionResult . v . sval = gettext_noop ( strParam1 ) ;
return stackPushResult ( VAL_STRING , & scrFunctionResult ) ;
}