2010-03-30 13:33:21 +00:00
/*--
2010-03-30 17:16:26 +00:00
Commits . c
2010-07-21 09:54:09 +00:00
Authors : flgr , Joern , Tyron , Newton , Ringwaul , Sven2 , Maikel
2010-03-30 13:33:21 +00:00
Useful user committed functions , this should really be organized into more sensible categories .
- - */
2009-12-29 13:44:16 +00:00
// Returns the offset to x.
2010-09-13 15:27:48 +00:00
global func AbsX ( int x )
2010-03-30 13:33:21 +00:00
{
2010-09-13 15:27:48 +00:00
return x - GetX ( ) ;
2010-03-30 13:33:21 +00:00
}
2009-12-29 13:44:16 +00:00
// Returns the offset to y.
2010-09-13 15:27:48 +00:00
global func AbsY ( int y )
2010-03-30 13:33:21 +00:00
{
2010-09-13 15:27:48 +00:00
return y - GetY ( ) ;
2010-03-30 13:33:21 +00:00
}
2009-12-29 13:44:16 +00:00
// Supports negative values, and can deliver random values between two bounds.
2010-09-13 15:27:48 +00:00
global func RandomX ( int start , int end )
2010-03-30 13:33:21 +00:00
{
var swap ;
// Values swapped: reswap them.
2010-09-13 15:27:48 +00:00
if ( start > end )
{
2010-03-30 13:33:21 +00:00
swap = start ;
start = end ;
2010-09-13 15:27:48 +00:00
end = swap ;
2010-03-30 13:33:21 +00:00
}
// Return random factor.
return Random ( end - start + 1 ) + start ;
2009-12-29 13:44:16 +00:00
}
2010-03-30 13:33:21 +00:00
// Tangens.
global func Tan ( int angle , int radius , int prec )
{
2010-03-30 16:48:38 +00:00
return radius * Sin ( angle , radius * 100 , prec ) / Cos ( angle , radius * 100 , prec ) ;
2009-12-29 13:44:16 +00:00
}
2010-03-30 13:33:21 +00:00
global func Normalize ( int angle , int start , int precision )
{
2010-09-13 15:27:48 +00:00
if ( ! precision )
2010-03-30 13:33:21 +00:00
precision = 1 ;
var end = precision * 360 + start ;
2010-03-30 16:48:38 +00:00
2010-03-30 13:33:21 +00:00
while ( angle < start )
angle + = precision * 360 ;
2010-09-13 15:27:48 +00:00
while ( angle > = end )
2010-03-30 13:33:21 +00:00
angle - = precision * 360 ;
return angle ;
2009-12-29 13:44:16 +00:00
}
2010-03-30 13:33:21 +00:00
// Does not set the speed of an object. But you can set two components of the velocity vector with this function.
global func SetSpeed ( int x_dir , int y_dir , int prec )
{
SetXDir ( x_dir , prec ) ;
SetYDir ( y_dir , prec ) ;
return ;
2009-12-29 13:44:16 +00:00
}
2010-03-30 13:33:21 +00:00
// Sets an objects's speed and its direction, doesn't it?
2011-10-01 05:28:01 +00:00
// Can set either speed or angle of velocity, or both
2010-10-29 21:13:19 +00:00
global func SetVelocity ( int angle , int speed , int precAng , int precSpd )
2010-03-30 13:33:21 +00:00
{
2011-10-01 05:28:01 +00:00
if ( ! speed )
speed = Distance ( 0 , 0 , GetXDir ( precSpd ) , GetYDir ( precSpd ) ) ;
if ( ! angle )
angle = Angle ( 0 , 0 , GetXDir ( precSpd ) , GetYDir ( precSpd ) , precAng ) ;
2010-10-29 21:13:19 +00:00
if ( ! precAng ) precAng = 1 ;
var x_dir = Sin ( angle , speed , precAng ) ;
var y_dir = - Cos ( angle , speed , precAng ) ;
2010-03-30 13:33:21 +00:00
2010-10-29 21:13:19 +00:00
SetXDir ( x_dir , precSpd ) ;
SetYDir ( y_dir , precSpd ) ;
2010-03-30 13:33:21 +00:00
return ;
2009-12-29 13:44:16 +00:00
}
2010-09-13 15:27:48 +00:00
// Sets the completion of this to new_con.
2010-03-30 13:33:21 +00:00
global func SetCon ( int new_con )
{
return DoCon ( new_con - GetCon ( ) ) ;
}
2009-12-29 13:44:16 +00:00
2010-03-30 13:33:21 +00:00
// Adds value to the account of iPlayer.
global func DoWealth ( int plr , int value )
2009-12-29 13:44:16 +00:00
{
2010-03-30 13:33:21 +00:00
return SetWealth ( plr , value + GetWealth ( plr ) ) ;
2009-12-29 13:44:16 +00:00
}
2010-03-30 13:33:21 +00:00
// Sets both the X and Y-coordinate of one vertex.
global func SetVertexXY ( int index , int x , int y )
{
// Set vertices.
SetVertex ( index , VTX_X , x ) ;
SetVertex ( index , VTX_Y , y ) ;
return ;
}
2009-12-29 13:44:16 +00:00
2010-09-13 15:27:48 +00:00
// Returns the number of stuck vertices. (of this)
2010-03-30 13:33:21 +00:00
global func VerticesStuck ( )
{
var vertices = 0 ;
// Loop through vertices.
for ( var i = - 1 ; i < GetVertexNum ( ) ; i + + )
// Solid?
if ( GBackSolid ( GetVertex ( i , VTX_X ) , GetVertex ( i , VTX_Y ) ) )
// Count vertices.
vertices + + ;
return vertices ;
}
2009-12-29 13:44:16 +00:00
2011-10-05 03:47:07 +00:00
// Returns whether the object has a vertex with the given CNAT value
global func HasCNAT ( int cnat )
{
for ( var i = - 1 ; i < GetVertexNum ( ) ; i + + )
if ( GetVertex ( i , VTX_CNAT ) = = cnat )
return true ;
return false ;
}
2010-09-13 15:27:48 +00:00
// Creates amount objects of type id inside the indicated rectangle(optional) in the indicated material.
2009-12-29 13:44:16 +00:00
// Returns the number of iterations needed, or -1 when the placement failed.
2010-03-30 13:33:21 +00:00
global func PlaceObjects ( id id , int amount , string mat_str , int x , int y , int wdt , int hgt , bool onsf , bool nostuck )
{
var i , j ;
var rndx , rndy , obj ;
2012-02-20 11:58:58 +00:00
var mat ;
var objhgt = id - > GetDefCoreVal ( " Height " , " DefCore " ) ;
2010-03-30 16:48:38 +00:00
2010-03-30 13:33:21 +00:00
mat = Material ( mat_str ) ;
// Some failsavety.
if ( mat = = - 1 )
2010-03-30 16:48:38 +00:00
if ( mat_str ! = " GBackSolid " & & mat_str ! = " GBackSemiSolid " & & mat_str ! = " GBackLiquid " & & mat_str ! = " GBackSky " )
2010-03-30 13:33:21 +00:00
return - 1 ;
2010-03-30 16:48:38 +00:00
2010-03-30 13:33:21 +00:00
// Optional parameters wdt and hgt.
2010-09-13 15:27:48 +00:00
if ( ! wdt )
2010-03-30 13:33:21 +00:00
wdt = LandscapeWidth ( ) - x - GetX ( ) ;
2010-09-13 15:27:48 +00:00
if ( ! hgt )
2010-03-30 13:33:21 +00:00
hgt = LandscapeHeight ( ) - y - GetY ( ) ;
// Cycle-saving method.
2010-09-13 15:27:48 +00:00
if ( mat ! = - 1 )
while ( i < amount )
2010-03-30 13:33:21 +00:00
{
// If there's isn't any or not enough of the given material, break before it gets an endless loop.
2010-09-13 15:27:48 +00:00
if ( j + + > 20000 )
2010-03-30 13:33:21 +00:00
return - 1 ;
// Destinated rectangle.
rndx = x + Random ( wdt ) ;
rndy = y + Random ( hgt ) ;
// Positioning.
if ( GetMaterial ( rndx , rndy ) = = mat )
{
// On-surface option.
2010-09-13 15:27:48 +00:00
if ( onsf )
while ( GBackSemiSolid ( rndx , rndy ) & & rndy > = y )
2010-03-30 13:33:21 +00:00
rndy - - ;
2010-09-13 15:27:48 +00:00
if ( rndy < y )
2010-03-30 13:33:21 +00:00
continue ;
// Create and verify stuckness.
obj = CreateObject ( id , rndx , rndy + objhgt / 2 , NO_OWNER ) ;
obj - > SetR ( Random ( 360 ) ) ;
2010-09-13 15:27:48 +00:00
if ( obj - > Stuck ( ) | | nostuck )
2010-03-30 13:33:21 +00:00
i + + ;
2010-09-13 15:27:48 +00:00
else
2010-03-30 13:33:21 +00:00
obj - > RemoveObject ( ) ;
}
}
2010-09-13 15:27:48 +00:00
if ( mat = = - 1 )
2010-03-30 13:33:21 +00:00
while ( i < amount )
{
// If there's isn't any or not enough of the given material, break before it gets an endless loop.
if ( j + + > 20000 )
return - 1 ;
// Destinated rectangle.
rndx = x + Random ( wdt ) ;
rndy = y + Random ( hgt ) ;
// Positioning.
if ( eval ( Format ( " %s(%d,%d) " , mat_str , rndx , rndy ) ) )
{
// On-surface Option.
2010-09-13 15:27:48 +00:00
if ( onsf )
while ( GBackSemiSolid ( rndx , rndy ) & & rndy > = y )
2010-03-30 13:33:21 +00:00
rndy - - ;
if ( rndy < y )
continue ;
// Create and verify stuckness.
obj = CreateObject ( id , rndx , rndy + objhgt / 2 , NO_OWNER ) ;
obj - > SetR ( Random ( 360 ) ) ;
if ( obj - > Stuck ( ) | | nostuck )
i + + ;
else
obj - > RemoveObject ( ) ;
}
}
2009-12-29 13:44:16 +00:00
2010-03-30 13:33:21 +00:00
return j ;
2009-12-29 13:44:16 +00:00
}
2010-03-30 13:33:21 +00:00
global func CastObjects ( id def , int am , int lev , int x , int y , int angs , int angw )
{
2010-09-13 15:27:48 +00:00
if ( ! angw )
2010-03-30 13:33:21 +00:00
angw = 360 ;
for ( var i = 0 ; i < am ; i + + )
{
var obj = CreateObject ( def , x , y , NO_OWNER ) ;
var ang = angs - 90 + RandomX ( - angw / 2 , angw / 2 ) ;
var xdir = Cos ( ang , lev ) + RandomX ( - 3 , 3 ) ;
obj - > SetR ( Random ( 360 ) ) ;
obj - > SetXDir ( xdir ) ;
obj - > SetYDir ( Sin ( ang , lev ) + RandomX ( - 3 , 3 ) ) ;
2010-07-02 23:42:43 +00:00
if ( xdir ! = 0 ) obj - > SetRDir ( ( 10 + Random ( 21 ) ) * ( xdir / Abs ( xdir ) ) ) ;
else
obj - > SetRDir ( - 10 + Random ( 21 ) ) ;
2010-03-30 13:33:21 +00:00
}
return ;
2009-12-29 13:44:16 +00:00
}
2010-03-30 13:33:21 +00:00
global func CastPXS ( string mat , int am , int lev , int x , int y , int angs , int angw )
{
2010-09-13 15:27:48 +00:00
if ( ! angw )
2010-03-30 13:33:21 +00:00
angw = 360 ;
for ( var i = 0 ; i < am ; i + + )
{
var ang = angs - 90 + RandomX ( - angw / 2 , angw / 2 ) ;
InsertMaterial ( Material ( mat ) , x , y , Cos ( ang , lev ) + RandomX ( - 3 , 3 ) , Sin ( ang , lev ) + RandomX ( - 3 , 3 ) ) ;
}
return ;
2009-12-29 13:44:16 +00:00
}
2010-03-30 13:33:21 +00:00
global func MaterialDepthCheck ( int x , int y , string mat , int depth )
2009-12-29 13:44:16 +00:00
{
2010-03-30 13:33:21 +00:00
var travelled ;
var xval = x ;
var yval = y ;
2009-12-29 13:44:16 +00:00
2010-03-30 13:33:21 +00:00
//If depth is equal to zero, the function will always measure the depth of the material.
//If depth is not equal to zero, the function will return true if the material is as deep or deeper than depth (in pixels).
if ( depth = = nil )
depth = LandscapeHeight ( ) ;
2009-12-29 13:44:16 +00:00
2010-09-13 15:27:48 +00:00
while ( travelled ! = depth )
2009-12-29 13:44:16 +00:00
{
2010-09-13 15:27:48 +00:00
if ( GetMaterial ( xval , yval ) = = Material ( mat ) )
2010-03-30 13:33:21 +00:00
{
travelled + + ;
2010-09-13 15:27:48 +00:00
yval + + ;
2010-03-30 13:33:21 +00:00
}
if ( GetMaterial ( xval , yval ) ! = Material ( mat ) )
return travelled ; // Returns depth of material.
2009-12-29 13:44:16 +00:00
}
2010-03-30 13:33:21 +00:00
if ( travelled = = depth )
return true ;
return false ;
2009-12-29 13:44:16 +00:00
}
2010-04-05 14:22:30 +00:00
global func LaunchProjectile ( int angle , int dist , int speed , int x , int y , bool rel_x )
2009-12-29 13:44:16 +00:00
{
2010-03-30 13:33:21 +00:00
// dist: Distance object travels on angle. Offset from calling object.
// x: X offset from container's center
// y: Y offset from container's center
// rel_x: if true, makes the X offset relative to container direction. (x=+30 will become x=-30 when Clonk turns left. This way offset always stays in front of a Clonk.)
2009-12-29 13:44:16 +00:00
2010-03-30 13:33:21 +00:00
var x_offset = Sin ( angle , dist ) ;
var y_offset = - Cos ( angle , dist ) ;
2009-12-29 13:44:16 +00:00
2010-09-13 15:27:48 +00:00
if ( Contained ( ) ! = nil & & rel_x = = true )
if ( Contained ( ) - > GetDir ( ) = = 0 )
2010-03-30 13:33:21 +00:00
x = - x ;
2010-01-20 00:25:02 +00:00
2010-03-30 13:33:21 +00:00
if ( Contained ( ) ! = nil )
2010-01-20 00:25:02 +00:00
{
2010-03-30 13:33:21 +00:00
Exit ( x_offset + x , y_offset + y , angle ) ;
SetVelocity ( angle , speed ) ;
return true ;
2010-01-20 00:25:02 +00:00
}
2010-09-13 15:27:48 +00:00
if ( Contained ( ) = = nil )
2010-01-20 00:25:02 +00:00
{
2010-03-30 13:33:21 +00:00
SetPosition ( GetX ( ) + x_offset + x , GetY ( ) + y_offset + y ) ;
SetR ( angle ) ;
SetVelocity ( angle , speed ) ;
return true ;
2010-01-20 00:25:02 +00:00
}
2010-03-30 13:33:21 +00:00
return false ;
2010-01-20 00:25:02 +00:00
}
2010-02-18 23:49:27 +00:00
global func ComDirLike ( int comdir1 , int comdir2 )
{
2010-09-13 15:27:48 +00:00
if ( comdir1 = = comdir2 )
2010-03-30 13:33:21 +00:00
return true ;
if ( comdir1 = = COMD_Stop | | comdir2 = = COMD_Stop )
return false ;
2011-07-06 16:13:39 +00:00
if ( comdir1 = = COMD_None | | comdir2 = = COMD_None )
return false ;
2010-03-30 13:33:21 +00:00
if ( comdir1 % 8 + 1 = = comdir2 )
return true ;
2010-09-13 15:27:48 +00:00
if ( comdir1 = = comdir2 % 8 + 1 )
2010-03-30 13:33:21 +00:00
return true ;
return false ;
2010-02-26 06:18:06 +00:00
}
2010-03-30 13:33:21 +00:00
global func SetObjAlpha ( int by_alpha )
2010-02-26 06:18:06 +00:00
{
2010-03-30 13:33:21 +00:00
var clr_mod = GetClrModulation ( ) ;
2010-09-13 15:27:48 +00:00
if ( ! clr_mod )
clr_mod = by_alpha < < 24 ;
else
2010-03-30 13:33:21 +00:00
clr_mod = clr_mod & 16777215 | by_alpha < < 24 ;
return SetClrModulation ( clr_mod ) ;
}
2010-07-21 09:54:09 +00:00
2010-08-01 15:23:36 +00:00
global func FindPosInMat ( string sMat , int iXStart , int iYStart , int iWidth , int iHeight , int iSize )
2010-07-21 09:54:09 +00:00
{
var iX , iY ;
2010-08-01 15:23:36 +00:00
var iMaterial = Material ( sMat ) ;
2010-07-21 09:54:09 +00:00
for ( var i = 0 ; i < 500 ; i + + )
{
2010-08-01 15:23:36 +00:00
iX = AbsX ( iXStart + Random ( iWidth ) ) ;
iY = AbsY ( iYStart + Random ( iHeight ) ) ;
if ( GetMaterial ( iX , iY ) = = iMaterial & &
GetMaterial ( iX + iSize , iY + iSize ) = = iMaterial & &
GetMaterial ( iX + iSize , iY - iSize ) = = iMaterial & &
GetMaterial ( iX - iSize , iY - iSize ) = = iMaterial & &
GetMaterial ( iX - iSize , iY + iSize ) = = iMaterial
2010-07-21 09:54:09 +00:00
) {
2010-08-01 15:23:36 +00:00
return [ iX , iY ] ; // Location found.
2010-07-21 09:54:09 +00:00
}
}
2010-08-01 15:23:36 +00:00
return 0 ; // No location found.
2011-07-06 16:13:39 +00:00
}
2012-02-26 00:34:56 +00:00
global func MovePosition ( int x , int y , int prec )
{
SetPosition ( GetX ( prec ) + x , GetY ( prec ) + y , nil , prec ) ;
}
2012-03-18 12:16:25 +00:00
// Makes the calling object invincible.
global func MakeInvincible ( )
{
if ( ! this )
return ;
return AddEffect ( " IntInvincible " , this , 300 ) ;
}
global func FxIntInvincibleDamage ( )
{
// Object receives zero damage.
return 0 ;
}
// Makes the calling object non flammable.
global func MakeNonFlammable ( )
{
if ( ! this )
return ;
return AddEffect ( " IntNonFlammable " , this , 300 ) ;
}
global func FxIntNonFlammableEffect ( string new_name )
{
// Block fire effects.
if ( WildcardMatch ( new_name , " *Fire* " ) )
return - 1 ;
// All other effects are okay.
return 0 ;
}