2011-03-04 12:49:41 +00:00
/*
* OpenClonk , http : //www.openclonk.org
*
* Copyright ( c ) 1998 - 2000 Matthes Bender
2013-01-09 23:23:06 +00:00
* Copyright ( c ) 2004 , 2006 - 2007 , 2010 , 2012 Sven Eberhardt
* Copyright ( c ) 2005 - 2012 G ü nther Brammer
2011-03-04 12:49:41 +00:00
* Copyright ( c ) 2005 - 2006 Peter Wortmann
* Copyright ( c ) 2009 Nicolas Hake
* Copyright ( c ) 2010 Benjamin Herr
* Copyright ( c ) 2010 Armin Burgmeier
* Copyright ( c ) 2001 - 2009 , RedWolf Design GmbH , http : //www.clonk.de
*
* Portions might be copyrighted by other authors who have contributed
* to OpenClonk .
*
* Permission to use , copy , modify , and / or distribute this software for any
* purpose with or without fee is hereby granted , provided that the above
* copyright notice and this permission notice appear in all copies .
* See isc_license . txt for full license and disclaimer .
*
* " Clonk " is a registered trademark of Matthes Bender .
* See clonk_trademark_license . txt for full license .
*/
/* Functions mapped by C4Script */
# include <C4Include.h>
# include <C4AulDefFunc.h>
# include <C4AulExec.h>
# include <C4Random.h>
# include <C4Version.h>
//========================== Some Support Functions =======================================
2012-05-19 16:34:17 +00:00
StdStrBuf FnStringFormat ( C4PropList * _this , C4String * szFormatPar , C4Value * Pars , int ParCount )
2011-03-04 12:49:41 +00:00
{
int cPar = 0 ;
StdStrBuf StringBuf ( " " , false ) ;
2012-05-19 16:34:17 +00:00
const char * cpFormat = FnStringPar ( szFormatPar ) ;
2011-03-04 12:49:41 +00:00
const char * cpType ;
2012-05-19 16:34:17 +00:00
char szField [ 20 ] ;
2011-03-04 12:49:41 +00:00
while ( * cpFormat )
{
// Copy normal stuff
while ( * cpFormat & & ( * cpFormat ! = ' % ' ) )
StringBuf . AppendChar ( * cpFormat + + ) ;
// Field
if ( * cpFormat = = ' % ' )
{
// Scan field type
for ( cpType = cpFormat + 1 ; * cpType & & ( * cpType = = ' . ' | | Inside ( * cpType , ' 0 ' , ' 9 ' ) ) ; cpType + + ) { }
// Copy field
2012-05-19 16:34:17 +00:00
SCopy ( cpFormat , szField , Min < unsigned int > ( sizeof szField - 1 , cpType - cpFormat + 1 ) ) ;
2011-03-04 12:49:41 +00:00
// Insert field by type
switch ( * cpType )
{
// number
2011-03-09 23:26:31 +00:00
case ' d ' : case ' x ' : case ' X ' :
2011-03-04 12:49:41 +00:00
{
2012-05-19 16:34:17 +00:00
if ( cPar > = ParCount ) throw new C4AulExecError ( " format placeholder without parameter " ) ;
StringBuf . AppendFormat ( szField , Pars [ cPar + + ] . getInt ( ) ) ;
2011-03-04 12:49:41 +00:00
cpFormat + = SLen ( szField ) ;
break ;
}
2011-03-09 23:26:31 +00:00
// character
case ' c ' :
{
2012-05-19 16:34:17 +00:00
if ( cPar > = ParCount ) throw new C4AulExecError ( " format placeholder without parameter " ) ;
StringBuf . AppendCharacter ( Pars [ cPar + + ] . getInt ( ) ) ;
2011-03-09 23:26:31 +00:00
cpFormat + = SLen ( szField ) ;
break ;
}
2011-03-04 12:49:41 +00:00
// C4ID
case ' i ' :
{
2012-05-19 16:34:17 +00:00
if ( cPar > = ParCount ) throw new C4AulExecError ( " format placeholder without parameter " ) ;
C4ID id = Pars [ cPar + + ] . getC4ID ( ) ;
2011-03-04 12:49:41 +00:00
StringBuf . Append ( id . ToString ( ) ) ;
cpFormat + = SLen ( szField ) ;
break ;
}
// C4Value
case ' v ' :
{
2012-05-19 16:34:17 +00:00
if ( cPar > = ParCount ) throw new C4AulExecError ( " format placeholder without parameter " ) ;
StringBuf . Append ( static_cast < const StdStrBuf & > ( Pars [ cPar + + ] . GetDataString ( 10 ) ) ) ;
2011-03-04 12:49:41 +00:00
cpFormat + = SLen ( szField ) ;
break ;
}
// String
case ' s ' :
{
// get string
2012-05-19 16:34:17 +00:00
if ( cPar > = ParCount ) throw new C4AulExecError ( " format placeholder without parameter " ) ;
2011-03-04 12:49:41 +00:00
const char * szStr = " (null) " ;
2012-05-19 16:34:17 +00:00
if ( Pars [ cPar ] . GetData ( ) )
2011-03-04 12:49:41 +00:00
{
2012-05-19 16:34:17 +00:00
C4String * pStr = Pars [ cPar ] . getStr ( ) ;
2012-05-15 01:11:23 +00:00
if ( ! pStr ) throw new C4AulExecError ( " string format placeholder without string " ) ;
2011-03-04 12:49:41 +00:00
szStr = pStr - > GetCStr ( ) ;
}
2012-05-19 16:34:17 +00:00
+ + cPar ;
2011-03-04 12:49:41 +00:00
StringBuf . AppendFormat ( szField , szStr ) ;
cpFormat + = SLen ( szField ) ;
break ;
}
case ' % ' :
StringBuf . AppendChar ( ' % ' ) ;
cpFormat + = SLen ( szField ) ;
break ;
// Undefined / Empty
default :
StringBuf . AppendChar ( ' % ' ) ;
cpFormat + + ;
break ;
}
}
}
return StringBuf ;
}
bool C4ValueToMatrix ( C4Value & value , StdMeshMatrix * matrix )
{
//if(value.GetType() != C4V_Array) return false;
const C4ValueArray * array = value . getArray ( ) ;
if ( ! array ) return false ;
return C4ValueToMatrix ( * array , matrix ) ;
}
bool C4ValueToMatrix ( const C4ValueArray & array , StdMeshMatrix * matrix )
{
if ( array . GetSize ( ) ! = 12 ) return false ;
StdMeshMatrix & trans = * matrix ;
trans ( 0 , 0 ) = array [ 0 ] . getInt ( ) / 1000.0f ;
trans ( 0 , 1 ) = array [ 1 ] . getInt ( ) / 1000.0f ;
trans ( 0 , 2 ) = array [ 2 ] . getInt ( ) / 1000.0f ;
trans ( 0 , 3 ) = array [ 3 ] . getInt ( ) / 1000.0f ;
trans ( 1 , 0 ) = array [ 4 ] . getInt ( ) / 1000.0f ;
trans ( 1 , 1 ) = array [ 5 ] . getInt ( ) / 1000.0f ;
trans ( 1 , 2 ) = array [ 6 ] . getInt ( ) / 1000.0f ;
trans ( 1 , 3 ) = array [ 7 ] . getInt ( ) / 1000.0f ;
trans ( 2 , 0 ) = array [ 8 ] . getInt ( ) / 1000.0f ;
trans ( 2 , 1 ) = array [ 9 ] . getInt ( ) / 1000.0f ;
trans ( 2 , 2 ) = array [ 10 ] . getInt ( ) / 1000.0f ;
trans ( 2 , 3 ) = array [ 11 ] . getInt ( ) / 1000.0f ;
return true ;
}
2012-05-20 00:39:57 +00:00
C4AulDefFunc : : C4AulDefFunc ( C4AulScript * pOwner , C4ScriptFnDef * pDef ) :
C4AulFunc ( pOwner , pDef - > Identifier ) , Def ( pDef )
{
Owner - > GetPropList ( ) - > SetPropertyByS ( Name , C4VFunction ( this ) ) ;
}
C4AulDefFunc : : ~ C4AulDefFunc ( )
{
}
C4Value C4AulDefFunc : : Exec ( C4PropList * p , C4Value pPars [ ] , bool fPassErrors )
{
assert ( Def - > FunctionC4V ) ;
return Def - > FunctionC4V ( p , pPars ) ;
}
2011-03-04 12:49:41 +00:00
//=============================== C4Script Functions ====================================
2012-05-15 01:03:47 +00:00
static C4PropList * FnCreatePropList ( C4PropList * _this , C4PropList * prototype )
2011-03-04 12:49:41 +00:00
{
return C4PropList : : New ( prototype ) ;
}
2012-05-18 17:44:53 +00:00
static C4Value FnGetProperty ( C4PropList * _this , C4String * key , C4PropList * pObj )
2011-03-04 12:49:41 +00:00
{
2012-05-18 17:44:53 +00:00
if ( ! pObj ) pObj = _this ;
2011-03-04 12:49:41 +00:00
if ( ! pObj ) return C4VNull ;
if ( ! key ) return C4VNull ;
C4Value r ;
pObj - > GetPropertyByS ( key , & r ) ;
return r ;
}
2012-05-18 17:44:53 +00:00
static bool FnSetProperty ( C4PropList * _this , C4String * key , const C4Value & to , C4PropList * pObj )
2011-03-04 12:49:41 +00:00
{
2012-05-18 17:44:53 +00:00
if ( ! pObj ) pObj = _this ;
if ( ! pObj ) return false ;
if ( ! key ) return false ;
2011-03-04 12:49:41 +00:00
if ( pObj - > IsFrozen ( ) )
2012-05-15 01:11:23 +00:00
throw new C4AulExecError ( " proplist write: proplist is readonly " ) ;
2012-05-18 17:44:53 +00:00
pObj - > SetPropertyByS ( key , to ) ;
return true ;
2011-03-04 12:49:41 +00:00
}
2012-05-18 17:44:53 +00:00
static bool FnResetProperty ( C4PropList * _this , C4String * key , C4PropList * pObj )
2011-03-04 12:49:41 +00:00
{
2012-05-18 17:44:53 +00:00
if ( ! pObj ) pObj = _this ;
if ( ! pObj ) return false ;
if ( ! key ) return false ;
if ( ! pObj - > HasProperty ( key ) ) return false ;
2011-03-04 12:49:41 +00:00
if ( pObj - > IsFrozen ( ) )
2012-05-15 01:11:23 +00:00
throw new C4AulExecError ( " proplist write: proplist is readonly " ) ;
2011-03-04 12:49:41 +00:00
pObj - > ResetProperty ( key ) ;
2012-05-18 17:44:53 +00:00
return true ;
2011-03-04 12:49:41 +00:00
}
2012-05-25 23:32:43 +00:00
static C4ValueArray * FnGetProperties ( C4PropList * _this , C4PropList * p )
{
if ( ! p ) p = _this ;
if ( ! p ) throw new NeedNonGlobalContext ( " GetProperties " ) ;
C4ValueArray * r = p - > GetProperties ( ) ;
r - > SortStrings ( ) ;
return r ;
}
2012-08-19 15:34:53 +00:00
static C4Value FnCall ( C4PropList * _this , C4Value * Pars )
{
2013-01-31 21:38:16 +00:00
if ( ! _this ) _this = : : ScriptEngine . GetPropList ( ) ;
2012-08-19 15:34:53 +00:00
C4AulParSet ParSet ( & Pars [ 1 ] , 9 ) ;
C4AulFunc * fn = Pars [ 0 ] . getFunction ( ) ;
2012-12-29 23:59:50 +00:00
C4String * name ;
2012-08-19 15:34:53 +00:00
if ( ! fn )
2012-12-29 23:59:50 +00:00
{
name = Pars [ 0 ] . getStr ( ) ;
2013-01-31 21:38:16 +00:00
if ( name ) fn = _this - > GetFunc ( name ) ;
2012-12-29 23:59:50 +00:00
}
2012-08-19 15:34:53 +00:00
if ( ! fn )
{
2012-12-29 23:59:50 +00:00
const char * s = FnStringPar ( name ) ;
2012-08-19 15:34:53 +00:00
if ( s [ 0 ] = = ' ~ ' )
{
fn = _this - > GetFunc ( & s [ 1 ] ) ;
if ( ! fn )
return C4Value ( ) ;
}
}
if ( ! fn )
throw new C4AulExecError ( FormatString ( " Call: no function %s " , Pars [ 0 ] . GetDataString ( ) . getData ( ) ) . getData ( ) ) ;
return fn - > Exec ( _this , & ParSet , true ) ;
}
2012-05-19 16:34:17 +00:00
static C4Value FnLog ( C4PropList * _this , C4Value * Pars )
2011-03-04 12:49:41 +00:00
{
2012-05-19 16:34:17 +00:00
Log ( FnStringFormat ( _this , Pars [ 0 ] . getStr ( ) , & Pars [ 1 ] , 9 ) . getData ( ) ) ;
2011-03-04 12:49:41 +00:00
return C4VBool ( true ) ;
}
2012-05-19 16:34:17 +00:00
static C4Value FnDebugLog ( C4PropList * _this , C4Value * Pars )
2011-03-04 12:49:41 +00:00
{
2012-05-19 16:34:17 +00:00
DebugLog ( FnStringFormat ( _this , Pars [ 0 ] . getStr ( ) , & Pars [ 1 ] , 9 ) . getData ( ) ) ;
2011-03-04 12:49:41 +00:00
return C4VBool ( true ) ;
}
2012-05-19 16:34:17 +00:00
static C4Value FnFormat ( C4PropList * _this , C4Value * Pars )
2011-03-04 12:49:41 +00:00
{
2012-05-19 16:34:17 +00:00
return C4VString ( FnStringFormat ( _this , Pars [ 0 ] . getStr ( ) , & Pars [ 1 ] , 9 ) ) ;
2011-03-04 12:49:41 +00:00
}
2012-05-15 01:03:47 +00:00
static C4ID FnC4Id ( C4PropList * _this , C4String * szID )
2011-03-04 12:49:41 +00:00
{
return ( C4ID ( FnStringPar ( szID ) ) ) ;
}
2012-05-15 01:03:47 +00:00
static long FnAbs ( C4PropList * _this , long iVal )
2011-03-04 12:49:41 +00:00
{
return Abs ( iVal ) ;
}
2012-05-15 01:03:47 +00:00
static long FnSin ( C4PropList * _this , long iAngle , long iRadius , long iPrec )
2011-03-04 12:49:41 +00:00
{
if ( ! iPrec ) iPrec = 1 ;
// Precalculate the modulo operation so the C4Fixed argument to Sin does not overflow
iAngle % = 360 * iPrec ;
// Let itofix and fixtoi handle the division and multiplication because that can handle higher ranges
return fixtoi ( Sin ( itofix ( iAngle , iPrec ) ) , iRadius ) ;
}
2012-05-15 01:03:47 +00:00
static long FnCos ( C4PropList * _this , long iAngle , long iRadius , long iPrec )
2011-03-04 12:49:41 +00:00
{
if ( ! iPrec ) iPrec = 1 ;
iAngle % = 360 * iPrec ;
return fixtoi ( Cos ( itofix ( iAngle , iPrec ) ) , iRadius ) ;
}
2012-05-15 01:03:47 +00:00
static long FnSqrt ( C4PropList * _this , long iValue )
2011-03-04 12:49:41 +00:00
{
if ( iValue < 0 ) return 0 ;
long iSqrt = long ( sqrt ( double ( iValue ) ) ) ;
if ( iSqrt * iSqrt < iValue ) iSqrt + + ;
if ( iSqrt * iSqrt > iValue ) iSqrt - - ;
return iSqrt ;
}
2012-05-15 01:03:47 +00:00
static long FnAngle ( C4PropList * _this , long iX1 , long iY1 , long iX2 , long iY2 , long iPrec )
2011-03-04 12:49:41 +00:00
{
long iAngle ;
// Standard prec
if ( ! iPrec ) iPrec = 1 ;
long dx = iX2 - iX1 , dy = iY2 - iY1 ;
if ( ! dx )
{
if ( dy > 0 ) return 180 * iPrec ;
else return 0 ;
}
if ( ! dy )
{
if ( dx > 0 ) return 90 * iPrec ;
else return 270 * iPrec ;
}
iAngle = static_cast < long > ( 180.0 * iPrec * atan2 ( static_cast < double > ( Abs ( dy ) ) , static_cast < double > ( Abs ( dx ) ) ) / M_PI ) ;
if ( iX2 > iX1 )
{
if ( iY2 < iY1 ) iAngle = ( 90 * iPrec ) - iAngle ;
else iAngle = ( 90 * iPrec ) + iAngle ;
}
else
{
if ( iY2 < iY1 ) iAngle = ( 270 * iPrec ) + iAngle ;
else iAngle = ( 270 * iPrec ) - iAngle ;
}
return iAngle ;
}
2012-05-15 01:03:47 +00:00
static long FnArcSin ( C4PropList * _this , long iVal , long iRadius )
2011-03-04 12:49:41 +00:00
{
// safety
if ( ! iRadius ) return 0 ;
if ( iVal > iRadius ) return 0 ;
// calc arcsin
double f1 = iVal ;
f1 = asin ( f1 / iRadius ) * 180.0 / M_PI ;
// return rounded angle
return ( long ) floor ( f1 + 0.5 ) ;
}
2012-05-15 01:03:47 +00:00
static long FnArcCos ( C4PropList * _this , long iVal , long iRadius )
2011-03-04 12:49:41 +00:00
{
// safety
if ( ! iRadius ) return 0 ;
if ( iVal > iRadius ) return 0 ;
// calc arccos
double f1 = iVal ;
f1 = acos ( f1 / iRadius ) * 180.0 / M_PI ;
// return rounded angle
return ( long ) floor ( f1 + 0.5 ) ;
}
2012-05-15 01:03:47 +00:00
static long FnMin ( C4PropList * _this , long iVal1 , long iVal2 )
2011-03-04 12:49:41 +00:00
{
return Min ( iVal1 , iVal2 ) ;
}
2012-05-15 01:03:47 +00:00
static long FnMax ( C4PropList * _this , long iVal1 , long iVal2 )
2011-03-04 12:49:41 +00:00
{
return Max ( iVal1 , iVal2 ) ;
}
2012-05-15 01:03:47 +00:00
static long FnDistance ( C4PropList * _this , long iX1 , long iY1 , long iX2 , long iY2 )
2011-03-04 12:49:41 +00:00
{
return Distance ( iX1 , iY1 , iX2 , iY2 ) ;
}
2012-05-15 01:03:47 +00:00
static long FnBoundBy ( C4PropList * _this , long iVal , long iRange1 , long iRange2 )
2011-03-04 12:49:41 +00:00
{
return BoundBy ( iVal , iRange1 , iRange2 ) ;
}
2012-05-15 01:03:47 +00:00
static bool FnInside ( C4PropList * _this , long iVal , long iRange1 , long iRange2 )
2011-03-04 12:49:41 +00:00
{
return Inside ( iVal , iRange1 , iRange2 ) ;
}
2012-05-15 01:03:47 +00:00
static long FnRandom ( C4PropList * _this , long iRange )
2011-03-04 12:49:41 +00:00
{
return Random ( iRange ) ;
}
2012-05-15 01:03:47 +00:00
static long FnAsyncRandom ( C4PropList * _this , long iRange )
2011-03-04 12:49:41 +00:00
{
return SafeRandom ( iRange ) ;
}
2012-05-15 01:03:47 +00:00
static int FnGetType ( C4PropList * _this , const C4Value & Value )
2011-03-04 12:49:41 +00:00
{
2011-09-26 18:22:31 +00:00
// dynamic types
2012-04-13 16:38:30 +00:00
if ( Value . CheckConversion ( C4V_Object ) ) return C4V_Object ;
2011-09-24 16:37:28 +00:00
if ( Value . CheckConversion ( C4V_Def ) ) return C4V_Def ;
if ( Value . CheckConversion ( C4V_Effect ) ) return C4V_Effect ;
2011-09-26 18:22:31 +00:00
// static types
return Value . GetType ( ) ;
2011-03-04 12:49:41 +00:00
}
2012-05-15 01:03:47 +00:00
static C4ValueArray * FnCreateArray ( C4PropList * _this , int iSize )
2011-03-04 12:49:41 +00:00
{
return new C4ValueArray ( iSize ) ;
}
2012-05-18 17:44:53 +00:00
static int FnGetLength ( C4PropList * _this , const C4Value & Par )
2011-03-04 12:49:41 +00:00
{
// support GetLength() etc.
2012-05-18 17:44:53 +00:00
C4ValueArray * pArray = Par . getArray ( ) ;
2011-03-04 12:49:41 +00:00
if ( pArray )
2012-05-18 17:44:53 +00:00
return pArray - > GetSize ( ) ;
C4String * pStr = Par . getStr ( ) ;
2011-03-04 12:49:41 +00:00
if ( pStr )
2012-05-18 17:44:53 +00:00
return GetCharacterCount ( pStr - > GetData ( ) . getData ( ) ) ;
2012-05-15 01:11:23 +00:00
throw new C4AulExecError ( " GetLength: parameter 0 cannot be converted to string or array " ) ;
2011-03-04 12:49:41 +00:00
}
2012-05-18 17:44:53 +00:00
static int FnGetIndexOf ( C4PropList * _this , C4ValueArray * pArray , const C4Value & Needle )
2011-03-04 12:49:41 +00:00
{
// find first occurance of first parameter in array
2012-02-25 20:57:39 +00:00
// support GetIndexOf(0, x)
2012-05-18 17:44:53 +00:00
if ( ! pArray ) return - 1 ;
2011-03-04 12:49:41 +00:00
int32_t iSize = pArray - > GetSize ( ) ;
2012-05-18 17:44:53 +00:00
for ( int32_t i = 0 ; i < iSize ; + + i )
if ( Needle = = pArray - > GetItem ( i ) )
2011-03-04 12:49:41 +00:00
// element found
2012-05-18 17:44:53 +00:00
return i ;
2011-03-04 12:49:41 +00:00
// element not found
2012-05-18 17:44:53 +00:00
return - 1 ;
2011-03-04 12:49:41 +00:00
}
2012-05-15 01:03:47 +00:00
static C4Void FnSetLength ( C4PropList * _this , C4ValueArray * pArray , int iNewSize )
2011-03-04 12:49:41 +00:00
{
// safety
if ( iNewSize < 0 | | iNewSize > C4ValueArray : : MaxSize )
2012-05-15 01:11:23 +00:00
throw new C4AulExecError ( FormatString ( " SetLength: invalid array size (%d) " , iNewSize).getData()) ;
2011-03-04 12:49:41 +00:00
// set new size
pArray - > SetSize ( iNewSize ) ;
return C4Void ( ) ;
}
2012-05-15 01:03:47 +00:00
static Nillable < long > FnGetChar ( C4PropList * _this , C4String * pString , long iIndex )
2011-03-04 12:49:41 +00:00
{
const char * szText = FnStringPar ( pString ) ;
2011-07-30 23:32:02 +00:00
if ( ! szText ) return C4Void ( ) ;
2011-03-09 23:26:31 +00:00
// C4Strings are UTF-8 encoded, so decode to get the indicated character
uint32_t c = GetNextCharacter ( & szText ) ;
for ( int i = 0 ; i < iIndex ; + + i )
{
c = GetNextCharacter ( & szText ) ;
2011-07-30 23:32:02 +00:00
if ( ! c ) return C4Void ( ) ;
2011-03-09 23:26:31 +00:00
}
return c ;
2011-03-04 12:49:41 +00:00
}
2012-05-18 17:44:53 +00:00
static C4Value Fneval ( C4PropList * _this , C4String * strScript )
2011-03-04 12:49:41 +00:00
{
// execute script in the same object
2012-05-15 01:03:47 +00:00
if ( Object ( _this ) )
2012-05-18 17:44:53 +00:00
return Object ( _this ) - > Def - > Script . DirectExec ( Object ( _this ) , FnStringPar ( strScript ) , " eval " , true ) ;
2012-05-15 01:03:47 +00:00
else if ( _this & & _this - > GetDef ( ) )
2012-05-18 17:44:53 +00:00
return _this - > GetDef ( ) - > Script . DirectExec ( 0 , FnStringPar ( strScript ) , " eval " , true ) ;
2011-03-04 12:49:41 +00:00
else
2012-05-18 17:44:53 +00:00
return : : GameScript . DirectExec ( 0 , FnStringPar ( strScript ) , " eval " , true ) ;
2011-03-04 12:49:41 +00:00
}
2012-05-15 01:03:47 +00:00
static bool FnLocateFunc ( C4PropList * _this , C4String * funcname , C4PropList * p )
2011-03-04 12:49:41 +00:00
{
// safety
if ( ! funcname | | ! funcname - > GetCStr ( ) )
{
Log ( " No func name " ) ;
return false ;
}
2012-05-15 01:03:47 +00:00
if ( ! p ) p = _this ;
2011-03-04 12:49:41 +00:00
// get function by name
2011-10-15 00:27:02 +00:00
C4AulFunc * pFunc = p - > GetFunc ( funcname ) ;
2011-03-04 12:49:41 +00:00
if ( ! pFunc )
{
LogF ( " Func %s not found " , funcname - > GetCStr ( ) ) ;
}
else
{
const char * szPrefix = " " ;
while ( pFunc )
{
C4AulScriptFunc * pSFunc = pFunc - > SFunc ( ) ;
if ( ! pSFunc )
{
2011-10-13 22:40:55 +00:00
LogF ( " %s%s (engine) " , szPrefix , pFunc - > GetName ( ) ) ;
2011-03-04 12:49:41 +00:00
}
else if ( ! pSFunc - > pOrgScript )
{
2011-10-13 22:40:55 +00:00
LogF ( " %s%s (no owner) " , szPrefix , pSFunc - > GetName ( ) ) ;
2011-03-04 12:49:41 +00:00
}
else
{
int32_t iLine = SGetLine ( pSFunc - > pOrgScript - > GetScript ( ) , pSFunc - > Script ) ;
2011-10-13 22:40:55 +00:00
LogF ( " %s%s (%s:%d) " , szPrefix , pFunc - > GetName ( ) , pSFunc - > pOrgScript - > ScriptName . getData ( ) , ( int ) iLine ) ;
2011-03-04 12:49:41 +00:00
}
// next func in overload chain
pFunc = pSFunc ? pSFunc - > OwnerOverloaded : NULL ;
szPrefix = " overloads " ;
}
}
return true ;
}
2012-05-15 01:03:47 +00:00
static long FnModulateColor ( C4PropList * _this , long iClr1 , long iClr2 )
2011-03-04 12:49:41 +00:00
{
DWORD dwClr1 = iClr1 ;
DWORD dwClr2 = iClr2 ;
// default color
if ( ! dwClr1 ) dwClr1 = 0xffffff ;
// get alpha
long iA1 = dwClr1 > > 24 , iA2 = dwClr2 > > 24 ;
// modulate color values; mod alpha upwards
DWORD r = ( ( ( dwClr1 & 0xff ) * ( dwClr2 & 0xff ) ) > > 8 ) | // blue
( ( ( dwClr1 > > 8 & 0xff ) * ( dwClr2 > > 8 & 0xff ) ) & 0xff00 ) | // green
( ( ( dwClr1 > > 16 & 0xff ) * ( dwClr2 > > 8 & 0xff00 ) ) & 0xff0000 ) | // red
( Min < long > ( iA1 + iA2 - ( ( iA1 * iA2 ) > > 8 ) , 255 ) < < 24 ) ; // alpha
return r ;
}
2012-05-15 01:03:47 +00:00
static long FnWildcardMatch ( C4PropList * _this , C4String * psString , C4String * psWildcard )
2011-03-04 12:49:41 +00:00
{
return SWildcardMatchEx ( FnStringPar ( psString ) , FnStringPar ( psWildcard ) ) ;
}
2012-05-15 01:03:47 +00:00
static bool FnFatalError ( C4PropList * _this , C4String * pErrorMsg )
2011-03-04 12:49:41 +00:00
{
2012-05-15 01:11:23 +00:00
throw new C4AulExecError ( FormatString ( " script: %s " , pErrorMsg ? pErrorMsg - > GetCStr ( ) : " (no error) " ) . getData ( ) ) ;
2011-03-04 12:49:41 +00:00
}
2012-05-15 01:03:47 +00:00
static bool FnStartCallTrace ( C4PropList * _this )
2011-03-04 12:49:41 +00:00
{
extern void C4AulStartTrace ( ) ;
C4AulStartTrace ( ) ;
return true ;
}
2012-05-15 01:03:47 +00:00
static bool FnStartScriptProfiler ( C4PropList * _this , C4ID idScript )
2011-03-04 12:49:41 +00:00
{
// get script to profile
C4AulScript * pScript ;
if ( idScript )
{
C4Def * pDef = C4Id2Def ( idScript ) ;
if ( ! pDef ) return false ;
pScript = & pDef - > Script ;
}
else
pScript = & : : ScriptEngine ;
// profile it
C4AulProfiler : : StartProfiling ( pScript ) ;
return true ;
}
2012-05-15 01:03:47 +00:00
static bool FnStopScriptProfiler ( C4PropList * _this )
2011-03-04 12:49:41 +00:00
{
C4AulProfiler : : StopProfiling ( ) ;
return true ;
}
2012-05-15 01:03:47 +00:00
static Nillable < C4String * > FnGetConstantNameByValue ( C4PropList * _this , int value , Nillable < C4String * > name_prefix , int idx )
2011-03-04 12:49:41 +00:00
{
C4String * name_prefix_s = name_prefix ;
// find a constant that has the specified value and prefix
for ( int32_t i = 0 ; i < : : ScriptEngine . GlobalConsts . GetAnzItems ( ) ; + + i )
{
if ( : : ScriptEngine . GlobalConsts [ i ] . getInt ( ) = = value )
{
const char * const_name = : : ScriptEngine . GlobalConstNames . GetItemUnsafe ( i ) ;
if ( ! name_prefix_s | | SEqual2 ( const_name , name_prefix_s - > GetCStr ( ) ) )
if ( ! idx - - )
// indexed constant found. return name minus prefix
return String ( const_name + ( name_prefix_s ? name_prefix_s - > GetData ( ) . getLength ( ) : 0 ) ) ;
}
}
// nothing found (at index)
return C4Void ( ) ;
}
2012-12-17 15:41:39 +00:00
static bool FnSortArray ( C4PropList * _this , C4ValueArray * pArray , bool descending )
{
if ( ! pArray ) throw new C4AulExecError ( " SortArray: no array given " ) ;
// sort array by its members
pArray - > Sort ( descending ) ;
return true ;
}
static bool FnSortArrayByProperty ( C4PropList * _this , C4ValueArray * pArray , C4String * prop_name , bool descending )
{
if ( ! pArray ) throw new C4AulExecError ( " SortArrayByProperty: no array given " ) ;
if ( ! prop_name ) throw new C4AulExecError ( " SortArrayByProperty: no property name given " ) ;
// sort array by property
if ( ! pArray - > SortByProperty ( prop_name , descending ) ) throw new C4AulExecError ( " SortArrayByProperty: not all array elements are proplists " ) ;
return true ;
}
static bool FnSortArrayByArrayElement ( C4PropList * _this , C4ValueArray * pArray , int32_t element_index , bool descending )
{
if ( ! pArray ) throw new C4AulExecError ( " SortArrayByArrayElement: no array given " ) ;
if ( element_index < 0 ) throw new C4AulExecError ( " SortArrayByArrayElement: element index must be >=0 " ) ;
// sort array by array element
if ( ! pArray - > SortByArrayElement ( element_index , descending ) ) throw new C4AulExecError ( " SortArrayByArrayElement: not all array elements are arrays of sufficient length " ) ;
return true ;
}
2011-03-04 12:49:41 +00:00
//=========================== C4Script Function Map ===================================
C4ScriptConstDef C4ScriptConstMap [ ] =
{
2011-09-26 18:22:31 +00:00
{ " C4V_Nil " , C4V_Int , C4V_Nil } ,
{ " C4V_Int " , C4V_Int , C4V_Int } ,
{ " C4V_Bool " , C4V_Int , C4V_Bool } ,
{ " C4V_C4Object " , C4V_Int , C4V_Object } ,
2011-09-24 16:37:28 +00:00
{ " C4V_Effect " , C4V_Int , C4V_Effect } ,
{ " C4V_Def " , C4V_Int , C4V_Def } ,
2011-09-26 18:22:31 +00:00
{ " C4V_String " , C4V_Int , C4V_String } ,
{ " C4V_Array " , C4V_Int , C4V_Array } ,
2011-09-24 23:20:18 +00:00
{ " C4V_Function " , C4V_Int , C4V_Function } ,
2011-09-26 18:22:31 +00:00
{ " C4V_PropList " , C4V_Int , C4V_PropList } ,
2011-03-04 12:49:41 +00:00
2011-09-26 18:22:31 +00:00
{ " C4X_Ver1 " , C4V_Int , C4XVER1 } ,
{ " C4X_Ver2 " , C4V_Int , C4XVER2 } ,
{ " C4X_Ver3 " , C4V_Int , C4XVER3 } ,
2011-03-04 12:49:41 +00:00
2011-05-09 12:37:28 +00:00
{ NULL , C4V_Nil , 0 }
2011-03-04 12:49:41 +00:00
} ;
C4ScriptFnDef C4ScriptFnMap [ ] =
{
2012-08-19 15:34:53 +00:00
{ " Call " , 1 , C4V_Any , { C4V_Any , C4V_Any , C4V_Any , C4V_Any , C4V_Any , C4V_Any , C4V_Any , C4V_Any , C4V_Any , C4V_Any } , FnCall } ,
2012-05-20 00:39:57 +00:00
{ " Log " , 1 , C4V_Bool , { C4V_String , C4V_Any , C4V_Any , C4V_Any , C4V_Any , C4V_Any , C4V_Any , C4V_Any , C4V_Any , C4V_Any } , FnLog } ,
{ " DebugLog " , 1 , C4V_Bool , { C4V_String , C4V_Any , C4V_Any , C4V_Any , C4V_Any , C4V_Any , C4V_Any , C4V_Any , C4V_Any , C4V_Any } , FnDebugLog } ,
{ " Format " , 1 , C4V_String , { C4V_String , C4V_Any , C4V_Any , C4V_Any , C4V_Any , C4V_Any , C4V_Any , C4V_Any , C4V_Any , C4V_Any } , FnFormat } ,
2011-03-04 12:49:41 +00:00
2012-05-20 00:39:57 +00:00
{ NULL , 0 , C4V_Nil , { C4V_Nil , C4V_Nil , C4V_Nil , C4V_Nil , C4V_Nil , C4V_Nil , C4V_Nil , C4V_Nil , C4V_Nil , C4V_Nil } , 0 }
2011-03-04 12:49:41 +00:00
} ;
void InitCoreFunctionMap ( C4AulScriptEngine * pEngine )
{
// add all def constants (all Int)
for ( C4ScriptConstDef * pCDef = & C4ScriptConstMap [ 0 ] ; pCDef - > Identifier ; pCDef + + )
{
assert ( pCDef - > ValType = = C4V_Int ) ; // only int supported currently
pEngine - > RegisterGlobalConstant ( pCDef - > Identifier , C4VInt ( pCDef - > Data ) ) ;
}
// add all def script funcs
for ( C4ScriptFnDef * pDef = & C4ScriptFnMap [ 0 ] ; pDef - > Identifier ; pDef + + )
2012-05-20 00:39:57 +00:00
new C4AulDefFunc ( pEngine , pDef ) ;
2012-05-18 17:41:38 +00:00
# define F(f) AddFunc(pEngine, #f, Fn##f)
F ( Abs ) ;
F ( Min ) ;
F ( Max ) ;
F ( Sin ) ;
F ( Cos ) ;
F ( Sqrt ) ;
F ( ArcSin ) ;
F ( ArcCos ) ;
F ( BoundBy ) ;
F ( Inside ) ;
F ( Random ) ;
F ( AsyncRandom ) ;
F ( CreateArray ) ;
F ( CreatePropList ) ;
F ( GetProperties ) ;
2012-05-18 17:44:53 +00:00
F ( GetProperty ) ;
F ( SetProperty ) ;
F ( ResetProperty ) ;
2012-05-18 17:41:38 +00:00
F ( C4Id ) ;
F ( Distance ) ;
F ( Angle ) ;
F ( GetChar ) ;
F ( GetType ) ;
F ( ModulateColor ) ;
F ( WildcardMatch ) ;
2012-05-18 17:44:53 +00:00
F ( GetLength ) ;
2012-05-18 17:41:38 +00:00
F ( SetLength ) ;
2012-05-18 17:44:53 +00:00
F ( GetIndexOf ) ;
2012-05-18 17:41:38 +00:00
F ( FatalError ) ;
F ( StartCallTrace ) ;
F ( StartScriptProfiler ) ;
F ( StopScriptProfiler ) ;
2012-12-17 15:41:39 +00:00
F ( SortArray ) ;
F ( SortArrayByProperty ) ;
F ( SortArrayByArrayElement ) ;
2012-05-18 17:41:38 +00:00
F ( LocateFunc ) ;
2012-05-18 17:44:53 +00:00
F ( eval ) ;
2012-05-18 17:41:38 +00:00
F ( GetConstantNameByValue ) ;
2011-03-04 12:49:41 +00:00
2012-04-28 19:32:29 +00:00
AddFunc ( pEngine , " Translate " , C4AulExec : : FnTranslate ) ;
2012-05-18 17:41:38 +00:00
# undef F
2011-03-04 12:49:41 +00:00
}