2011-10-08 17:04:57 +00:00
/*--
Animation effects of the clonk
Authors : Randrian
Is responsible for the management of all the animations of the clonk . It containes :
* Turn
* Animation Manager
* Eyes
* Walk
* Scale
* Jump
* Hangle
* Swim
* Roll and kneel
* Digging
* Throwing
* Dead
* Tumble
* Riding
* Pushing
* HangOnto
- - */
2012-04-07 21:32:57 +00:00
local lAnim ; // proplist containing all the specific variables. "Pseudo-Namespace"
func Construction ( )
{
lAnim =
{
turnType = nil ,
turnSpecial = nil ,
turnForced = nil ,
backwards = nil ,
backwardsSpeed = nil ,
closedEyes = nil ,
rollDir = nil ,
rollLength = nil
} ;
_inherited ( . . . ) ;
}
2011-10-08 17:04:57 +00:00
/*--
Turn
Turn behavoir of the clonk . There are two turn types . Type 0 always rotated the clonk 25 ° to the screen . Type 1 views the clonk always from the side .
The clonk turns around , when he changes dir .
- - */
2012-04-07 21:32:57 +00:00
// todo, implement, make carryheavy decreasing it
static const Clonk_TurnTime = 18 ;
2011-10-08 17:04:57 +00:00
2011-10-08 17:46:22 +00:00
func SetMeshTransformation ( ) { return _inherited ( . . . ) ; }
func UpdateAttach ( ) { return _inherited ( . . . ) ; }
func GetHandAction ( ) { return _inherited ( . . . ) ; }
func DoThrow ( ) { return _inherited ( . . . ) ; }
local ActMap ;
2011-10-08 17:04:57 +00:00
func SetTurnForced ( int dir )
{
2012-04-07 21:32:57 +00:00
lAnim . turnForced = dir + 1 ;
2011-10-08 17:04:57 +00:00
}
func FxIntTurnStart ( pTarget , effect , fTmp )
{
if ( fTmp ) return ;
effect . dir = GetDirection ( ) ;
var iTurnPos = 0 ;
if ( effect . dir = = COMD_Right ) iTurnPos = 1 ;
effect . curr_rot = 24 ;
effect . rot = 25 ;
2011-10-09 08:52:28 +00:00
effect . turn_type = - 1 ;
2011-10-08 17:04:57 +00:00
SetTurnType ( 0 ) ;
}
func FxIntTurnTimer ( pTarget , effect , iTime )
{
// Check wether the clonk wants to turn (Not when he wants to stop)
var iRot = effect . rot ;
2012-04-29 16:09:37 +00:00
if ( ( effect . dir ! = GetDirection ( ) & & ( GetAction ( ) ! = " Jump " ) | | this - > ~ IsAiming ( ) ) | | effect . turn_type ! = lAnim . turnType )
2011-10-08 17:04:57 +00:00
{
effect . dir = GetDirection ( ) ;
if ( effect . dir = = COMD_Right )
{
2012-04-07 21:32:57 +00:00
if ( lAnim . turnType = = 0 )
2011-10-08 17:04:57 +00:00
iRot = 180 - 25 ;
2012-04-07 21:32:57 +00:00
if ( lAnim . turnType = = 1 )
2011-10-08 17:04:57 +00:00
iRot = 180 ;
}
else
{
2012-04-07 21:32:57 +00:00
if ( lAnim . turnType = = 0 )
2011-10-08 17:04:57 +00:00
iRot = 25 ;
2012-04-07 21:32:57 +00:00
if ( lAnim . turnType = = 1 )
2011-10-08 17:04:57 +00:00
iRot = 0 ;
}
// Save new ComDir
effect . dir = GetDirection ( ) ;
2012-04-07 21:32:57 +00:00
effect . turn_type = lAnim . turnType ;
2011-10-08 17:04:57 +00:00
// Notify effects
// ResetAnimationEffects();
}
if ( iRot ! = effect . curr_rot )
{
effect . curr_rot + = BoundBy ( iRot - effect . curr_rot , - 18 , 18 ) ;
SetMeshTransformation ( Trans_Rotate ( effect . curr_rot , 0 , 1 , 0 ) , 0 ) ;
}
effect . rot = iRot ;
return ;
}
2011-10-09 13:26:52 +00:00
public func UpdateTurnRotation ( )
{
var iEff = GetEffect ( " IntTurn " , this ) ;
iEff . turn_type = - 1 ;
}
2011-10-08 17:04:57 +00:00
public func GetTurnPhase ( )
{
var iEff = GetEffect ( " IntTurn " , this ) ;
var iRot = iEff . curr_rot ;
2012-04-07 21:32:57 +00:00
if ( lAnim . turnType = = 0 )
2011-10-08 17:04:57 +00:00
return ( iRot - 25 ) * 100 / 130 ;
2012-04-07 21:32:57 +00:00
if ( lAnim . turnType = = 1 )
2011-10-08 17:04:57 +00:00
return iRot * 100 / 180 ;
}
func SetTurnType ( iIndex , iSpecial )
{
if ( iSpecial ! = nil & & iSpecial ! = 0 )
{
if ( iSpecial = = 1 ) // Start a turn that is forced to the clonk and overwrites the normal action's turntype
2012-04-07 21:32:57 +00:00
lAnim . turnSpecial = 1 ;
2011-10-08 17:04:57 +00:00
if ( iSpecial = = - 1 ) // Reset special turn (here the iIndex is ignored)
{
2012-04-07 21:32:57 +00:00
lAnim . turnSpecial = 0 ;
SetTurnType ( lAnim . turnType ) ;
2011-10-08 17:04:57 +00:00
return ;
}
}
else
{
// Standart turn? Save and do nothing if we are blocked
2012-04-07 21:32:57 +00:00
lAnim . turnType = iIndex ;
if ( lAnim . turnSpecial ) return ;
2011-10-08 17:04:57 +00:00
}
return ;
}
func GetDirection ( )
{
// Are we forced to a special direction?
2012-04-07 21:32:57 +00:00
if ( lAnim . turnForced )
2011-10-08 17:04:57 +00:00
{
2012-04-07 21:32:57 +00:00
if ( lAnim . turnForced = = 1 ) return COMD_Left ;
if ( lAnim . turnForced = = 2 ) return COMD_Right ;
2011-10-08 17:04:57 +00:00
}
// Get direction from ComDir
if ( GetAction ( ) ! = " Scale " )
{
if ( ComDirLike ( GetComDir ( ) , COMD_Right ) ) return COMD_Right ;
else if ( ComDirLike ( GetComDir ( ) , COMD_Left ) ) return COMD_Left ;
}
// if ComDir hasn't a direction, use GetDir
if ( GetDir ( ) = = DIR_Right ) return COMD_Right ;
else return COMD_Left ;
}
/*--
Animation Manager
Animations can be replaced . E . g . while aiming with the bow the normal walk animation gets replaced by a bow walk animation .
- - */
local PropAnimations ;
local ActualReplace ;
public func ReplaceAction ( string action , byaction )
{
if ( PropAnimations = = nil ) PropAnimations = CreatePropList ( ) ;
if ( byaction = = nil | | byaction = = 0 )
{
SetProperty ( action , nil , PropAnimations ) ;
ResetAnimationEffects ( ) ;
return true ;
}
/* if(GetAnimationLength(byaction) == nil)
{
Log ( " ERROR: No animation %s in Definition %s " , byaction , GetID ( ) - > GetName ( ) ) ;
return false ;
} */
if ( GetType ( byaction ) = = C4V_Array )
{
var old = GetProperty ( action , PropAnimations ) ;
SetProperty ( action , byaction , PropAnimations ) ;
if ( GetType ( old ) = = C4V_Array )
{
if ( ActualReplace = = nil ) return true ;
if ( old [ 0 ] = = byaction [ 0 ] & & old [ 1 ] = = byaction [ 1 ] )
{
var i = 0 ;
for ( test in ActualReplace )
{
if ( test & & test [ 0 ] = = action )
break ;
i + + ;
}
if ( i < GetLength ( ActualReplace ) )
SetAnimationWeight ( ActualReplace [ i ] [ 1 ] , Anim_Const ( byaction [ 2 ] ) ) ;
return true ;
}
}
}
2012-10-14 17:39:40 +00:00
else SetProperty ( action , byaction , PropAnimations ) ;
2011-10-08 17:04:57 +00:00
// if(ActualReplace != nil)
// SetAnimationWeight(ActualReplace, Anim_Const(byaction[2]));
ResetAnimationEffects ( ) ;
return true ;
}
public func ResetAnimationEffects ( )
{
if ( GetEffect ( " IntWalk " , this ) )
EffectCall ( this , GetEffect ( " IntWalk " , this ) , " Reset " ) ;
if ( GetAction ( ) = = " Jump " )
StartJump ( ) ;
}
public func PlayAnimation ( string animation , int index , array position , array weight , int sibling )
{
if ( ! ActualReplace ) ActualReplace = [ ] ;
ActualReplace [ index ] = nil ;
if ( PropAnimations ! = nil )
if ( GetProperty ( animation , PropAnimations ) ! = nil )
{
var replacement = GetProperty ( animation , PropAnimations ) ;
if ( GetType ( replacement ) = = C4V_Array )
{
var animation1 = inherited ( replacement [ 0 ] , index , position , weight ) ;
var animation2 = inherited ( replacement [ 1 ] , index , position , Anim_Const ( 500 ) , animation1 ) ;
var animationKnot = animation2 + 1 ;
ActualReplace [ index ] = [ animation , animationKnot ] ;
SetAnimationWeight ( animationKnot , Anim_Const ( replacement [ 2 ] ) ) ;
return animation1 ;
}
else
animation = GetProperty ( animation , PropAnimations ) ;
}
return inherited ( animation , index , position , weight , sibling , . . . ) ;
}
public func GetAnimationLength ( string animation )
{
var replacement ;
if ( PropAnimations ! = nil )
if ( replacement = GetProperty ( animation , PropAnimations ) )
{
if ( GetType ( replacement ) = = C4V_Array )
animation = replacement [ 0 ] ;
else
animation = replacement ;
}
return inherited ( animation , . . . ) ;
}
/*--
Eyes
The clonk automatically closed his eyes every now and then . With CloseEyes ( number ) the eyes can be opened and shut . If the counter is > 0 the eyes are shut if not they are open . This is also used e . g . by the tumbling animation . While tumbling the clonk ' s eyes are shut .
- - */
func FxIntEyesTimer ( target , effect , time )
{
if ( ! Random ( 4 ) )
AddEffect ( " IntEyesClosed " , this , 10 , 6 , this ) ;
}
func FxIntEyesClosedStart ( target , effect , tmp )
{
CloseEyes ( 1 ) ;
}
func FxIntEyesClosedStop ( target , effect , reason , tmp )
{
CloseEyes ( - 1 ) ;
}
func CloseEyes ( iCounter )
{
StopAnimation ( GetRootAnimation ( 3 ) ) ;
2012-04-07 21:32:57 +00:00
lAnim . closedEyes + = iCounter ;
if ( lAnim . closedEyes > = 1 )
2011-10-08 17:04:57 +00:00
PlayAnimation ( " CloseEyes " , 3 , Anim_Linear ( 0 , 0 , GetAnimationLength ( " CloseEyes " ) / 2 , 3 , ANIM_Hold ) , Anim_Const ( 1000 ) ) ;
else
PlayAnimation ( " CloseEyes " , 3 , Anim_Linear ( GetAnimationLength ( " CloseEyes " ) / 2 , GetAnimationLength ( " CloseEyes " ) / 2 , GetAnimationLength ( " CloseEyes " ) , 3 , ANIM_Remove ) , Anim_Const ( 1000 ) ) ;
}
/*--
Walk
The Clonk adjusts his animation acording to his velocity : Stand , Walk and Run . It he is in a building he uses " Inside " insead of " Stand " . For walking while aiming in the different direction a speed for walking bachwards can be set .
While standing and doing nothing the clonk starts an idle animation every now and then .
- - */
/* Walking backwards */
func SetBackwardsSpeed ( int value )
{
2012-04-07 21:32:57 +00:00
lAnim . backwardsSpeed = value ;
2011-10-08 17:04:57 +00:00
UpdateBackwardsSpeed ( ) ;
}
func UpdateBackwardsSpeed ( )
{
2012-04-07 21:32:57 +00:00
if ( GetComDir ( ) ! = GetDirection ( ) & & lAnim . backwards ! = 1 & & lAnim . backwardsSpeed ! = nil )
2011-10-08 17:04:57 +00:00
{
2012-04-07 21:32:57 +00:00
AddEffect ( " IntWalkBack " , this , 1 , 0 , this , 0 , lAnim . backwardsSpeed ) ;
lAnim . backwards = 1 ;
2011-10-08 17:04:57 +00:00
}
2012-04-07 21:32:57 +00:00
if ( ( GetComDir ( ) = = GetDirection ( ) & & lAnim . backwards = = 1 ) | | lAnim . backwardsSpeed = = nil )
2011-10-08 17:04:57 +00:00
{
RemoveEffect ( " IntWalkBack " , this ) ;
2012-04-07 21:32:57 +00:00
lAnim . backwards = nil ;
2011-10-08 17:04:57 +00:00
}
}
func FxIntWalkBackStart ( pTarget , effect , fTmp , iValue )
{
if ( iValue = = nil ) iValue = 84 ;
pTarget - > PushActionSpeed ( " Walk " , iValue ) ;
}
func FxIntWalkBackStop ( pTarget , effect )
{
pTarget - > PopActionSpeed ( " Walk " ) ;
}
/* Walk */
static const Clonk_WalkInside = " Inside " ;
static const Clonk_WalkStand = " Stand " ;
static const Clonk_WalkWalk = " Walk " ;
static const Clonk_WalkRun = " Run " ;
static Clonk_IdleActions ;
func StartWalk ( )
{
if ( Clonk_IdleActions = = nil )
Clonk_IdleActions = [ [ " IdleLookAround " , 60 ] , [ " IdleHandwatch " , 100 ] , [ " IdleScratch " , 70 ] , [ " IdleStrech " , 100 ] , [ " IdleShoe " , 120 ] , [ " IdleShoeSole " , 200 ] , [ " IdleHandstrech " , 100 ] ] ;
if ( ! GetEffect ( " IntWalk " , this ) )
AddEffect ( " IntWalk " , this , 1 , 1 , this ) ;
}
func StopWalk ( )
{
if ( GetAction ( ) ! = " Walk " ) RemoveEffect ( " IntWalk " , this ) ;
}
func GetCurrentWalkAnimation ( )
{
if ( Contained ( ) )
{
if ( Contained ( ) - > GetCategory ( ) & C4D_Structure )
{
return Clonk_WalkInside ;
}
return ;
}
else SetProperty ( " PictureTransformation " , Trans_Mul ( Trans_Translate ( 0 , 1000 , 5000 ) , Trans_Rotate ( 70 , 0 , 1 , 0 ) ) , this ) ;
var velocity = Distance ( 0 , 0 , GetXDir ( ) , GetYDir ( ) ) ;
if ( velocity < 1 ) return Clonk_WalkStand ;
if ( velocity < 10 ) return Clonk_WalkWalk ;
return Clonk_WalkRun ;
}
func Footstep ( )
{
if ( GetMaterialVal ( " DigFree " , " Material " , GetMaterial ( 0 , 10 ) ) = = 0 )
2011-10-12 21:09:22 +00:00
Sound ( " StepHard? " ) ;
2011-10-08 17:04:57 +00:00
else
{
2012-12-17 00:14:32 +00:00
var dir = Sign ( GetXDir ( ) ) ;
2011-10-08 17:04:57 +00:00
var clr = GetAverageTextureColor ( GetTexture ( 0 , 10 ) ) ;
2013-10-20 16:15:14 +00:00
var particles =
{
Prototype = Particles_Dust ( ) ,
R = ( clr > > 16 ) & 0xff ,
G = ( clr > > 8 ) & 0xff ,
B = clr & 0xff ,
} ;
2013-12-17 20:40:40 +00:00
CreateParticle ( " Dust " , PV_Random ( dir * - 2 , dir * - 1 ) , 8 , PV_Random ( dir * 2 , dir * 1 ) , PV_Random ( - 2 , - 3 ) , PV_Random ( 36 , 2 * 36 ) , particles , 5 ) ;
2011-10-12 21:09:22 +00:00
Sound ( " StepSoft? " ) ;
2011-10-08 17:04:57 +00:00
}
}
func GetWalkAnimationPosition ( string anim , int pos )
{
var dir = - 1 ;
if ( GetDirection ( ) = = COMD_Right ) dir = + 1 ;
if ( PropAnimations ! = nil )
if ( GetProperty ( Format ( " %s_Position " , anim ) , PropAnimations ) )
{
2012-10-14 17:39:40 +00:00
var length = GetAnimationLength ( anim ) , replacement ;
if ( replacement = GetProperty ( anim , PropAnimations ) )
{
// at this point /replacement/ may contain an array of two animations that signal a merge
// in that case, just take the first one..
if ( GetType ( replacement ) = = C4V_Array )
replacement = replacement [ 0 ] ;
length = GetAnimationLength ( replacement ) ;
}
2011-10-08 17:04:57 +00:00
return Anim_X ( pos , 0 , length , GetProperty ( Format ( " %s_Position " , anim ) , PropAnimations ) * dir ) ;
}
// TODO: Choose proper starting positions, depending on the current
// animation and its position: For Stand->Walk or Stand->Run, start
// with a frame where one of the clonk's feets is on the ground and
// the other one is in the air. For Walk->Run and Run->Walk, fade to
// a state where its feets are at a similar position (just taking
// over previous animation's position might work, using
// GetAnimationPosition()). Walk->Stand is arbitrary I guess.
// First parameter of Anim_Linear/Anim_AbsX is initial position.
// Movement synchronization might also be tweaked somewhat as well.
if ( anim = = Clonk_WalkInside )
return Anim_Const ( 0 ) ;
if ( anim = = Clonk_WalkStand )
return Anim_Linear ( pos , 0 , GetAnimationLength ( anim ) , 35 , ANIM_Loop ) ;
else if ( anim = = Clonk_WalkWalk )
return Anim_X ( pos , 0 , GetAnimationLength ( anim ) , 20 * dir ) ;
else if ( anim = = Clonk_WalkRun )
return Anim_X ( pos , 0 , GetAnimationLength ( anim ) , 50 * dir ) ;
}
func FxIntWalkStart ( pTarget , effect , fTmp )
{
if ( fTmp ) return ;
// Always start in Stand for now... should maybe fade properly from previous animation instead
var anim = " Stand " ; //GetCurrentWalkAnimation();
effect . animation_name = anim ;
effect . animation_id = PlayAnimation ( anim , 5 , GetWalkAnimationPosition ( anim ) , Anim_Linear ( 0 , 0 , 1000 , 5 , ANIM_Remove ) ) ;
effect . idle_animation_time = 0 ;
effect . idle_time = 0 ; // Idle counter
effect . idle_offset = Random ( 300 ) ; // Random offset for idle time
// Update carried items
UpdateAttach ( ) ;
// Set proper turn
SetTurnType ( 0 ) ;
}
func FxIntWalkTimer ( pTarget , effect )
{
// Test Waterlevel
2012-04-09 01:50:31 +00:00
if ( InLiquid ( ) & & GBackLiquid ( 0 , - 5 ) & & ! Contained ( ) )
2011-10-08 17:04:57 +00:00
{
SetAction ( " Swim " ) ;
if ( GetComDir ( ) = = COMD_Left )
SetComDir ( COMD_UpLeft ) ;
else if ( GetComDir ( ) = = COMD_Right )
SetComDir ( COMD_UpRight ) ;
else if ( GetComDir ( ) ! = COMD_Down & & GetComDir ( ) ! = COMD_DownLeft & & GetComDir ( ) ! = COMD_DownRight )
SetComDir ( COMD_Up ) ;
return ;
}
2012-04-07 21:32:57 +00:00
if ( lAnim . backwardsSpeed ! = nil )
2011-10-08 17:04:57 +00:00
UpdateBackwardsSpeed ( ) ;
if ( effect . idle_animation_time )
{
effect . idle_animation_time - - ;
if ( effect . idle_animation_time = = 0 )
effect . animation_name = nil ;
}
var anim = GetCurrentWalkAnimation ( ) ;
2011-10-09 08:58:58 +00:00
if ( anim ! = effect . animation_name )
2011-10-08 17:04:57 +00:00
{
effect . animation_name = anim ;
effect . idle_time = 0 ;
effect . animation_id = PlayAnimation ( anim , 5 , GetWalkAnimationPosition ( anim , 0 ) , Anim_Linear ( 0 , 0 , 1000 , 5 , ANIM_Remove ) ) ;
}
// The clonk has to stand, not making a pause animation yet and not doing other actions with the hands (e.g. loading the bow)
else if ( anim = = Clonk_WalkStand & & ! GetHandAction ( ) )
{
if ( effect . footstop_time ) effect . footstep_time = 0 ;
if ( ! effect . idle_animation_time )
{
effect . idle_time + + ;
if ( effect . idle_time > 300 + effect . idle_offset )
{
effect . idle_time = 0 ;
effect . idle_offset = Random ( 300 ) ;
var rand = Random ( GetLength ( Clonk_IdleActions ) ) ;
PlayAnimation ( Clonk_IdleActions [ rand ] [ 0 ] , 5 , Anim_Linear ( 0 , 0 , GetAnimationLength ( Clonk_IdleActions [ rand ] [ 0 ] ) , Clonk_IdleActions [ rand ] [ 1 ] , ANIM_Remove ) , Anim_Linear ( 0 , 0 , 1000 , 5 , ANIM_Remove ) ) ;
effect . idle_animation_time = Clonk_IdleActions [ rand ] [ 1 ] - 5 ;
}
}
}
else
{
effect . idle_time = 0 ;
if ( effect . idle_animation_time )
{
effect . animation_name = nil ;
effect . idle_animation_time = 0 ;
}
if ( anim = = Clonk_WalkRun )
{
effect . footstep_time + + ;
if ( effect . footstep_time = = 12 )
{
Footstep ( ) ;
effect . footstep_time = 0 ;
}
}
else if ( effect . footstep_time ) effect . footstep_time = 0 ;
}
}
func FxIntWalkReset ( pTarget , effect )
{
effect . animation_name = nil ;
}
func StartStand ( )
{
PlayAnimation ( Clonk_WalkStand , 5 , GetWalkAnimationPosition ( Clonk_WalkStand ) , Anim_Linear ( 0 , 0 , 1000 , 5 , ANIM_Remove ) ) ;
// Update carried items
UpdateAttach ( ) ;
// Set proper turn type
SetTurnType ( 0 ) ;
}
/*--
Scale
During scaling the clonk adjusts his rotation to the ground . . When he is a the top , he uses a extra animation . When the wall doesn ' t have a platform for the feet he just scales using his arms .
- - */
2011-12-30 15:53:10 +00:00
/* Renders the clonk unable to scale */
func DisableScale ( )
{
if ( ! this . ActMap . Scale ) return ;
this . Scale = this . ActMap . Scale ;
this . ActMap . Scale = nil ;
}
/* Reenabled hangling */
func EnableScale ( )
{
if ( ! this . Scale ) return ;
this . ActMap . Scale = this . Scale ;
this . Scale = nil ;
}
2011-10-08 17:04:57 +00:00
func StartScale ( )
{
if ( ! GetEffect ( " IntScale " , this ) )
AddEffect ( " IntScale " , this , 1 , 1 , this ) ;
// Set proper turn type
SetTurnType ( 1 ) ;
// Update carried items
UpdateAttach ( ) ;
}
func StopScale ( )
{
if ( GetAction ( ) ! = " Scale " ) RemoveEffect ( " IntScale " , this ) ;
}
func CheckScaleTop ( )
{
// Test whether the clonk has reached a top corner
2012-06-08 14:17:42 +00:00
// That is, the leg vertices are the only ones attached to the wall
if ( GBackSolid ( - 3 + 6 * GetDir ( ) , - 3 ) | | GBackSolid ( - 5 + 10 * GetDir ( ) , 2 ) ) return false ;
2011-10-08 17:04:57 +00:00
return true ;
}
func FxIntScaleStart ( target , effect , tmp )
{
if ( tmp ) return ;
effect . animation_id = PlayAnimation ( " Scale " , 5 , Anim_Y ( 0 , GetAnimationLength ( " Scale " ) , 0 , 15 ) , Anim_Linear ( 0 , 0 , 1000 , 5 , ANIM_Remove ) ) ;
effect . animation_mode = 0 ;
}
func FxIntScaleTimer ( target , number , time )
{
if ( GetAction ( ) ! = " Scale " ) return ;
// When the clonk reaches the top play an extra animation
if ( CheckScaleTop ( ) )
{
// If the animation is not already set
var dist = 0 ;
2012-06-08 14:17:42 +00:00
while ( ! ( GBackSolid ( - 3 + 6 * GetDir ( ) , dist - 3 ) | | GBackSolid ( - 5 + 10 * GetDir ( ) , dist + 2 ) ) & & dist < 8 ) dist + + ;
2011-10-08 17:04:57 +00:00
dist * = 100 ;
2012-06-08 14:17:42 +00:00
// add the fractional part of the position (dist counts in the opposite direction of y)
dist - = GetY ( 100 ) - GetY ( ) * 100 ;
2011-10-08 17:04:57 +00:00
if ( number . animation_mode ! = 1 )
{
2012-06-08 14:17:42 +00:00
number . animation_id = PlayAnimation ( " ScaleTop " , 5 , Anim_Const ( GetAnimationLength ( " ScaleTop " ) * dist / 800 ) , Anim_Linear ( 0 , 0 , 1000 , 5 , ANIM_Remove ) ) ;
2011-10-08 17:04:57 +00:00
number . animation_mode = 1 ;
}
this . dist = dist ;
2012-06-08 14:17:42 +00:00
SetAnimationPosition ( number . animation_id , Anim_Const ( GetAnimationLength ( " ScaleTop " ) * dist / 800 ) ) ;
2011-10-08 17:04:57 +00:00
// The animation's graphics has to be shifet a bit to adjust to the clonk movement
var pos = GetAnimationPosition ( number . animation_id ) ;
2012-06-08 14:17:42 +00:00
SetScaleRotation ( 0 , 0 , 0 , 0 , 0 , 1 ) ;
2011-10-08 17:04:57 +00:00
}
else if ( ! GBackSolid ( - 10 + 20 * GetDir ( ) , 8 ) )
{
if ( number . animation_mode ! = 2 )
{
var pos = GetAnimationPosition ( number . animation_id ) ;
number . animation_id = PlayAnimation ( " ScaleHands " , 5 , Anim_Y ( pos , GetAnimationLength ( " ScaleHands " ) , 0 , 15 ) , Anim_Linear ( 0 , 0 , 1000 , 5 , ANIM_Remove ) ) ;
number . animation_id2 = PlayAnimation ( " ScaleHands2 " , 5 , Anim_Y ( pos , GetAnimationLength ( " ScaleHands2 " ) , 0 , 15 ) , Anim_Const ( 1000 ) , number . animation_id ) ;
number . animation_id2 + + ;
number . animation_mode = 2 ;
}
SetAnimationWeight ( number . animation_id2 , Anim_Const ( Cos ( time * 2 , 500 ) + 500 ) ) ;
SetScaleRotation ( 0 ) ;
}
// If not play the normal scale animation
else if ( number . animation_mode ! = 0 )
{
2011-10-09 08:58:58 +00:00
if ( number . ScheduleStop )
2011-10-08 17:04:57 +00:00
{
SetComDir ( COMD_Stop ) ;
2011-10-09 08:58:58 +00:00
number . ScheduleStop = 0 ;
2011-10-08 17:04:57 +00:00
}
var pos = 0 ;
if ( number . animation_mode = = 2 ) pos = GetAnimationPosition ( number . animation_id ) ;
number . animation_id = PlayAnimation ( " Scale " , 5 , Anim_Y ( 0 , GetAnimationLength ( " Scale " ) , 0 , 15 ) , Anim_Linear ( 0 , 0 , 1000 , 5 , ANIM_Remove ) ) ;
number . animation_mode = 0 ;
SetScaleRotation ( 0 ) ;
}
if ( number . animation_mode = = 0 )
{
var x , x2 ;
var y = - 7 , y2 = 8 ;
var dir = - 1 + 2 * GetDir ( ) ;
for ( x = 0 ; x < 10 ; x + + )
if ( GBackSolid ( x * dir , y ) ) break ;
for ( x2 = 0 ; x2 < 10 ; x2 + + )
if ( GBackSolid ( x2 * dir , y2 ) ) break ;
var angle = Angle ( x2 , y2 , x , y ) * dir ;
var mid = ( x + x2 ) * 1000 / 2 - 5000 - this . Off ;
this . TestAngle = angle ;
this . TestMid = mid ;
SetScaleRotation ( angle , mid * dir ) ;
}
}
func FxIntScaleRotTimer ( target , eff , time )
{
eff . oldR + = BoundBy ( eff . r - eff . oldR , - 3 , 3 ) ;
eff . oldX + = BoundBy ( eff . xoff - eff . oldX , - 500 , 500 ) ;
eff . oldY + = BoundBy ( eff . yoff - eff . oldY , - 500 , 500 ) ;
var turnx = - 1000 ;
var turny = 10000 ;
SetMeshTransformation ( Trans_Mul ( Trans_Translate ( eff . oldX - turnx , eff . oldY - turny ) , Trans_Rotate ( eff . oldR , 0 , 0 , 1 ) , Trans_Translate ( turnx , turny ) ) , 1 ) ;
}
func SetScaleRotation ( int r , int xoff , int yoff , int rotZ , int turny , int instant ) {
if ( r < - 180 ) r + = 360 ;
if ( r > 180 ) r - = 360 ;
// set matrix values
var turnx = - 1000 ;
var turny = 10000 ;
if ( instant )
{
RemoveEffect ( " IntScaleRot " , this ) ;
SetMeshTransformation ( Trans_Mul ( Trans_Translate ( xoff - turnx , yoff - turny ) , Trans_Rotate ( r , 0 , 0 , 1 ) , Trans_Translate ( turnx , turny ) , Trans_Rotate ( rotZ , 0 , 1 , 0 ) ) , 1 ) ;
}
else
{
var eff = GetEffect ( " IntScaleRot " , this ) ;
if ( ! eff )
eff = AddEffect ( " IntScaleRot " , this , 1 , 1 , this ) ;
eff . r = r ;
eff . xoff = xoff ;
eff . yoff = yoff ;
}
}
func FxIntScaleStop ( target , number , reason , tmp )
{
if ( tmp ) return ;
// Set the animation to stand without blending! That's cause the animation of Scale moves the clonkmesh wich would result in a stange blend moving the clonk around while blending
/* if(number.animation_mode == 1) PlayAnimation(Clonk_WalkStand, 5, GetWalkAnimationPosition(Clonk_WalkStand), Anim_Const(1000));
// Finally stop if the user has scheduled a stop
2011-10-09 08:58:58 +00:00
if ( number . ScheduleStop ) SetComDir ( COMD_Stop ) ; */
2011-10-08 17:04:57 +00:00
// and reset the transform
SetScaleRotation ( 0 ) ;
// SetObjDrawTransform(1000, 0, 0, 0, 1000, 0);
}
/*--
Jump
Different jump animations for different situations .
- - */
func StartJump ( )
{
//which leg to kick off with?
var side = " R " ;
if ( Random ( 2 ) ) side = " L " ;
//Normal forward jump
if ( Abs ( GetXDir ( ) ) > = 1 )
PlayAnimation ( Format ( " Jump.%s " , side ) , 5 , Anim_Linear ( 0 , 0 , GetAnimationLength ( " Jump.L " ) , 8 * 5 , ANIM_Hold ) , Anim_Linear ( 0 , 0 , 1000 , 5 , ANIM_Remove ) ) ;
//Walk kick jump
if ( GetEffect ( " WallKick " , this ) )
{
SetAction ( " WallJump " ) ;
var side = " L " ;
if ( GetDir ( ) = = DIR_Left ) side = " R " ;
PlayAnimation ( Format ( " JumpWall.%s " , side ) , 5 , Anim_Linear ( 0 , 0 , GetAnimationLength ( " JumpWall.L " ) , 8 * 5 , ANIM_Hold ) , Anim_Linear ( 0 , 0 , 1000 , 5 , ANIM_Remove ) ) ;
}
//Upwards jump
else if ( GetXDir ( ) = = 0 )
{
PlayAnimation ( Format ( " JumpUp.%s " , side ) , 5 , Anim_Linear ( 0 , 0 , GetAnimationLength ( " JumpUp.L " ) , 8 * 5 , ANIM_Hold ) , Anim_Linear ( 0 , 0 , 1000 , 5 , ANIM_Remove ) ) ;
}
// Update carried items
UpdateAttach ( ) ;
// Set proper turn type
SetTurnType ( 0 ) ;
2012-04-29 16:12:04 +00:00
//Dive jump (only if not aiming)
if ( ! this - > ~ IsAiming ( ) )
{
var flight = SimFlight ( AbsX ( GetX ( ) ) , AbsY ( GetY ( ) ) , GetXDir ( ) * 2 , GetYDir ( ) * 2 , 25 ) ; //I have no clue why the dirs must be doubled... but it seems to fix it
if ( GBackLiquid ( flight [ 0 ] - GetX ( ) , flight [ 1 ] - GetY ( ) ) & & GBackLiquid ( flight [ 0 ] - GetX ( ) , flight [ 1 ] + GetDefHeight ( ) / 2 - GetY ( ) ) )
{
PlayAnimation ( " JumpDive " , 5 , Anim_Linear ( 0 , 0 , GetAnimationLength ( " JumpDive " ) , 60 , ANIM_Hold ) , Anim_Linear ( 0 , 0 , 1000 , 5 , ANIM_Remove ) ) ;
return 1 ;
}
}
2011-10-08 17:04:57 +00:00
2012-04-29 16:12:04 +00:00
if ( ! GetEffect ( " Fall " , this ) )
AddEffect ( " Fall " , this , 1 , 1 , this ) ;
RemoveEffect ( " WallKick " , this ) ;
2011-10-08 17:04:57 +00:00
}
func FxFallEffect ( string new_name , object target )
{
// reject more than one fall effects.
if ( new_name = = " Fall " ) return - 1 ;
}
func FxFallTimer ( object target , effect , int timer )
{
//falling off ledges without jumping results in fall animation
if ( timer = = 2 & & GetYDir ( ) > 1 )
{
PlayAnimation ( " FallShort " , 5 , Anim_Linear ( 0 , 0 , GetAnimationLength ( " FallShort " ) , 8 * 3 , ANIM_Hold ) , Anim_Linear ( 0 , 0 , 1000 , 5 , ANIM_Remove ) ) ;
}
if ( timer = = 2 & & GetYDir ( ) < 1 )
{
2011-10-12 21:09:22 +00:00
Sound ( " Rustle? " ) ;
2011-10-08 17:04:57 +00:00
}
if ( GetYDir ( ) > 55 & & GetAction ( ) = = " Jump " )
{
PlayAnimation ( " FallLong " , 5 , Anim_Linear ( 0 , 0 , GetAnimationLength ( " FallLong " ) , 8 * 3 , ANIM_Hold ) , Anim_Linear ( 0 , 0 , 1000 , 5 , ANIM_Remove ) ) ;
return - 1 ;
}
if ( GetAction ( ) ! = " Jump " )
return - 1 ;
}
/*--
Hangle
2012-04-07 21:32:57 +00:00
Adjust the speed sinusoidal . Plays two different stand animations according to the position the clonk stops .
2011-10-08 17:04:57 +00:00
- - */
2011-12-30 15:53:10 +00:00
/* Renders the clonk unable to hangle */
func DisableHangle ( )
{
if ( ! this . ActMap . Hangle ) return ;
this . Hangle = this . ActMap . Hangle ;
this . ActMap . Hangle = nil ;
}
/* Reenabled hangling */
func EnableHangle ( )
{
if ( ! this . Hangle ) return ;
this . ActMap . Hangle = this . Hangle ;
this . Hangle = nil ;
}
2011-10-08 17:04:57 +00:00
/* Replaces the named action by an instance with a different speed */
func PushActionSpeed ( string action , int n )
{
ActMap [ action ] = { Prototype = ActMap [ action ] , Speed = n } ;
if ( this . Action = = ActMap [ action ] . Prototype )
this . Action = ActMap [ action ] ;
}
/* Resets the named action to the previous one */
func PopActionSpeed ( string action , int n ) {
// FIXME: This only works if PushActionSpeed and PopActionSpeed are the only functions manipulating the ActMap
if ( this . Action = = ActMap [ action ] )
this . Action = ActMap [ action ] . Prototype ;
ActMap [ action ] = ActMap [ action ] . Prototype ;
}
func StartHangle ( )
{
/* if(Clonk_HangleStates == nil)
Clonk_HangleStates = [ " HangleStand " , " Hangle " ] ; */
if ( ! GetEffect ( " IntHangle " , this ) )
AddEffect ( " IntHangle " , this , 1 , 1 , this ) ;
// Set proper turn type
SetTurnType ( 1 ) ;
// Update carried items
UpdateAttach ( ) ;
}
func StopHangle ( )
{
if ( GetAction ( ) ! = " Hangle " ) RemoveEffect ( " IntHangle " , this ) ;
}
func FxIntHangleStart ( pTarget , effect , fTmp )
{
effect . hangle_speed = ActMap . Hangle . Speed ;
PushActionSpeed ( " Hangle " , effect . hangle_speed ) ;
if ( fTmp ) return ;
// is_moving: whether the clonk is currently moving or not (<=> current animation is Hangle or HangleStand)
// request_stop: Player requested the clonk to stop
// facing_front: Whether the HangleStand animation is shown front-facing or back-facing
effect . animation_id = PlayAnimation ( " HangleStand " , 5 , Anim_Linear ( 0 , 0 , 2000 , 100 , ANIM_Loop ) , Anim_Linear ( 0 , 0 , 1000 , 5 , ANIM_Remove ) ) ;
}
func FxIntHangleStop ( pTarget , effect , iReasonm , fTmp )
{
PopActionSpeed ( " Hangle " ) ;
if ( fTmp ) return ;
2012-07-13 20:55:44 +00:00
// Delayed stop request
if ( effect . request_stop ) SetComDir ( COMD_Stop ) ;
2011-10-08 17:04:57 +00:00
}
func FxIntHangleTimer ( pTarget , effect , iTime )
{
// (TODO: Instead of effect.is_moving we should be able
// to query the current animation... maybe via a to-be-implemented
// GetAnimationName() engine function.
// If we are currently moving
if ( effect . is_moving )
{
// Use a cosine-shaped movement speed (the clonk only moves when he makes a "stroke")
var iSpeed = 50 - Cos ( GetAnimationPosition ( effect . animation_id ) / 10 * 360 * 2 / 1000 , 50 ) ;
ActMap . Hangle . Speed = effect . hangle_speed * iSpeed / 50 ;
// Exec movement animation (TODO: Use Anim_Linear?)
var position = GetAnimationPosition ( effect . animation_id ) ;
position + = ( effect . hangle_speed * 5 / 48 * 1000 / ( 14 * 2 ) ) ;
SetAnimationPosition ( effect . animation_id , Anim_Const ( position % GetAnimationLength ( " Hangle " ) ) ) ;
// Continue movement, if the clonk still has momentum
if ( GetComDir ( ) = = COMD_Stop & & iSpeed > 10 )
{
// Make it stop after the current movement
effect . request_stop = 1 ;
if ( GetDir ( ) )
SetComDir ( COMD_Right ) ;
else
SetComDir ( COMD_Left ) ;
}
// Stop movement if the clonk has lost his momentum
else if ( iSpeed < = 10 & & ( GetComDir ( ) = = COMD_Stop | | effect . request_stop ) )
{
effect . request_stop = 0 ;
SetComDir ( COMD_Stop ) ;
// and remeber the pose (front or back)
if ( GetAnimationPosition ( effect . animation_id ) > 2500 & & GetAnimationPosition ( effect . animation_id ) < 7500 )
effect . facing_front = 1 ;
else
effect . facing_front = 0 ;
// Change to HangleStand animation
var begin = 4000 * effect . facing_front ;
var end = 2000 + begin ;
effect . animation_id = PlayAnimation ( " HangleStand " , 5 , Anim_Linear ( begin , begin , end , 100 , ANIM_Loop ) , Anim_Linear ( 0 , 0 , 1000 , 5 , ANIM_Remove ) ) ;
effect . is_moving = 0 ;
}
}
else
{
// We are currently not moving
if ( GetComDir ( ) ! = COMD_Stop )
{
// Switch to move
effect . is_moving = 1 ;
// start with frame 100 or from the back hanging pose frame 600
var begin = 10 * ( 100 + 500 * effect . facing_front ) ;
effect . animation_id = PlayAnimation ( " Hangle " , 5 , Anim_Const ( begin ) , Anim_Linear ( 0 , 0 , 1000 , 5 , ANIM_Remove ) ) ;
}
}
}
/*--
Swim
Different animation for swiming and diving . Adjusting the rotation while diving .
- - */
func StartSwim ( )
{
/* if(Clonk_SwimStates == nil)
Clonk_SwimStates = [ " SwimStand " , " Swim " , " SwimDive " , " SwimTurn " , " SwimDiveTurn " , " SwimDiveUp " , " SwimDiveDown " ] ; */
2012-04-09 01:50:31 +00:00
if ( ! InLiquid ( ) ) return ;
2011-10-08 17:04:57 +00:00
if ( ! GetEffect ( " IntSwim " , this ) )
AddEffect ( " IntSwim " , this , 1 , 1 , this ) ;
2013-10-06 12:55:48 +00:00
return SetSwimmingVertices ( true ) ;
2011-10-08 17:04:57 +00:00
}
func StopSwim ( )
{
if ( GetAction ( ) ! = " Swim " ) RemoveEffect ( " IntSwim " , this ) ;
2013-10-06 12:55:48 +00:00
return SetSwimmingVertices ( false ) ;
}
func SetSwimmingVertices ( bool is_swimming )
{
var vtx_list = [ [ 0 , 2 , 0 ] , [ 0 , - 7 , 4 ] , [ 0 , 9 , 11 ] , [ - 2 , - 3 , 1 ] , [ 2 , - 3 , 2 ] , [ - 4 , 2 , 1 ] , [ 4 , 2 , 2 ] , [ - 2 , 6 , 1 ] , [ 2 , 6 , 2 ] ] ;
if ( is_swimming )
vtx_list = [ [ 0 , 3 , 0 ] , [ 0 , - 2 , 4 ] , [ 0 , 7 , 11 ] , [ - 4 , 0 , 1 ] , [ 4 , 0 , 2 ] , [ - 5 , 3 , 1 ] , [ 5 , 3 , 2 ] , [ - 4 , 4 , 1 ] , [ 4 , 4 , 2 ] ] ;
for ( var i = 0 ; i < GetVertexNum ( ) ; i + + )
{
SetVertex ( i , VTX_X , vtx_list [ i ] [ 0 ] , 2 ) ;
SetVertex ( i , VTX_Y , vtx_list [ i ] [ 1 ] , 2 ) ;
SetVertex ( i , VTX_CNAT , vtx_list [ i ] [ 2 ] , 2 ) ;
}
return ;
2011-10-08 17:04:57 +00:00
}
func FxIntSwimStart ( pTarget , effect , fTmp )
{
if ( fTmp ) return ;
effect . animation_name = " SwimStand " ;
effect . animation = PlayAnimation ( " SwimStand " , 5 , Anim_Linear ( 0 , 0 , GetAnimationLength ( " SwimStand " ) , 20 , ANIM_Loop ) , Anim_Linear ( 0 , 0 , 1000 , 5 , ANIM_Remove ) ) ;
// Set proper turn type
SetTurnType ( 0 ) ;
// Update carried items
UpdateAttach ( ) ;
}
func FxIntSwimTimer ( pTarget , effect , iTime )
{
var iSpeed = Distance ( 0 , 0 , GetXDir ( ) , GetYDir ( ) ) ;
// TODO: Smaller transition time between dive<->swim, keep 15 for swimstand<->swim/swimstand<->dive
// Play stand animation when not moving
if ( Abs ( GetXDir ( ) ) < 1 & & ! GBackSemiSolid ( 0 , - 5 ) )
{
if ( GetContact ( - 1 ) & CNAT_Bottom )
{
SetAction ( " Walk " ) ;
return - 1 ;
}
if ( effect . animation_name ! = " SwimStand " )
{
effect . animation_name = " SwimStand " ;
effect . animation = PlayAnimation ( " SwimStand " , 5 , Anim_Linear ( 0 , 0 , GetAnimationLength ( " SwimStand " ) , 20 , ANIM_Loop ) , Anim_Linear ( 0 , 0 , 1000 , 15 , ANIM_Remove ) ) ;
}
}
// Swimming
else if ( ! GBackSemiSolid ( 0 , - 5 ) )
{
var percent = GetAnimationPosition ( GetRootAnimation ( 5 ) ) * 200 / GetAnimationLength ( " Swim " ) ;
percent = ( percent % 100 ) ;
if ( percent < 40 )
{
if ( iTime % 5 = = 0 )
{
2013-11-04 12:06:13 +00:00
var phases = PV_Linear ( 0 , 7 ) ;
if ( GetDir ( ) = = 1 ) phases = PV_Linear ( 8 , 15 ) ;
2011-10-08 17:04:57 +00:00
var color = GetAverageTextureColor ( GetTexture ( 0 , 0 ) ) ;
2013-11-04 12:06:13 +00:00
var particles =
{
Size = 16 ,
Phase = phases ,
CollisionVertex = 750 ,
OnCollision = PC_Die ( ) ,
R = ( color > > 16 ) & 0xff ,
G = ( color > > 8 ) & 0xff ,
B = ( color > > 0 ) & 0xff ,
Attach = ATTACH_Front ,
} ;
2013-12-17 20:40:40 +00:00
CreateParticle ( " Wave " , 0 , - 4 , ( RandomX ( - 5 , 5 ) - ( - 1 + 2 * GetDir ( ) ) * 4 ) / 4 , 0 , 16 , particles ) ;
2011-10-08 17:04:57 +00:00
}
2011-10-12 21:09:22 +00:00
Sound ( " Splash? " ) ;
2011-10-08 17:04:57 +00:00
}
// Animation speed by X
if ( effect . animation_name ! = " Swim " )
{
effect . animation_name = " Swim " ;
// TODO: Determine starting position from previous animation
PlayAnimation ( " Swim " , 5 , Anim_AbsX ( 0 , 0 , GetAnimationLength ( " Swim " ) , 25 ) , Anim_Linear ( 0 , 0 , 1000 , 15 , ANIM_Remove ) ) ;
}
}
// Diving
else
{
if ( effect . animation_name ! = " SwimDive " )
{
effect . animation_name = " SwimDive " ;
// TODO: Determine starting position from previous animation
effect . animation2 = PlayAnimation ( " SwimDiveUp " , 5 , Anim_Linear ( 0 , 0 , GetAnimationLength ( " SwimDiveUp " ) , 40 , ANIM_Loop ) , Anim_Linear ( 0 , 0 , 1000 , 15 , ANIM_Remove ) ) ;
effect . animation3 = PlayAnimation ( " SwimDiveDown " , 5 , Anim_Linear ( 0 , 0 , GetAnimationLength ( " SwimDiveDown " ) , 40 , ANIM_Loop ) , Anim_Const ( 500 ) , effect . animation2 ) ;
effect . animation = effect . animation3 + 1 ;
// TODO: This should depend on which animation we come from
// Guess for SwimStand we should fade from 0, otherwise from 90.
effect . rot = 90 ;
}
if ( iSpeed )
{
var iRot = Angle ( - Abs ( GetXDir ( ) ) , GetYDir ( ) ) ;
effect . rot + = BoundBy ( iRot - effect . rot , - 4 , 4 ) ;
}
// TODO: Shouldn't weight go by sin^2 or cos^2 instead of linear in angle?
var weight = 1000 * effect . rot / 180 ;
SetAnimationWeight ( effect . animation , Anim_Const ( 1000 - weight ) ) ;
}
}
func GetSwimRotation ( )
{
var effect = GetEffect ( " IntSwim " , this ) ;
if ( ! effect ) return 0 ;
return effect . rot * ( - 1 + 2 * ( GetDirection ( ) = = COMD_Right ) ) ;
}
/*--
Roll and kneel
When the clonk hits the ground a kneel animation of are roll are performed .
- - */
func Hit ( int iXSpeed , int iYSpeed )
{
if ( iYSpeed < 450 ) return ;
if ( GetAction ( ) ! = " Walk " ) return ;
//Roll :D
if ( GetComDir ( ) = = COMD_Right & & GetDir ( ) = = 1 | | GetComDir ( ) = = COMD_Left & & GetDir ( ) = = 0 )
{
if ( Abs ( iXSpeed ) > 130 & & iYSpeed < = 80 * 10 )
SetAction ( " Roll " ) ;
else
2011-10-08 20:44:24 +00:00
{
2011-10-08 17:04:57 +00:00
DoKneel ( ) ;
2011-10-08 20:44:24 +00:00
if ( GetMaterialVal ( " DigFree " , " Material " , GetMaterial ( 0 , 10 ) ) )
{
var clr = GetAverageTextureColor ( GetTexture ( 0 , 10 ) ) ;
2013-10-20 16:15:14 +00:00
var particles =
{
Prototype = Particles_Dust ( ) ,
R = ( clr > > 16 ) & 0xff ,
G = ( clr > > 8 ) & 0xff ,
B = clr & 0xff ,
} ;
2013-12-17 20:40:40 +00:00
CreateParticle ( " Dust " , PV_Random ( - 4 , 4 ) , 8 , PV_Random ( - 3 , 3 ) , PV_Random ( - 2 , - 4 ) , PV_Random ( 36 , 2 * 36 ) , particles , 12 ) ;
2011-10-08 20:44:24 +00:00
}
}
2011-10-08 17:04:57 +00:00
}
else
{
DoKneel ( ) ;
2011-10-08 20:44:24 +00:00
if ( GetMaterialVal ( " DigFree " , " Material " , GetMaterial ( 0 , 10 ) ) )
{
var clr = GetAverageTextureColor ( GetTexture ( 0 , 10 ) ) ;
2013-10-20 16:15:14 +00:00
var particles =
{
Prototype = Particles_Dust ( ) ,
R = ( clr > > 16 ) & 0xff ,
G = ( clr > > 8 ) & 0xff ,
B = clr & 0xff ,
} ;
2013-12-17 20:40:40 +00:00
CreateParticle ( " Dust " , PV_Random ( - 4 , 4 ) , 8 , PV_Random ( - 3 , 3 ) , PV_Random ( - 2 , - 4 ) , PV_Random ( 36 , 2 * 36 ) , particles , 12 ) ;
2011-10-08 20:44:24 +00:00
}
2011-10-08 17:04:57 +00:00
}
}
func DoKneel ( )
{
var iKneelDownSpeed = 18 ;
SetXDir ( 0 ) ;
SetAction ( " Kneel " ) ;
2011-10-12 21:09:22 +00:00
Sound ( " RustleLand " ) ;
2011-10-08 17:04:57 +00:00
PlayAnimation ( " KneelDown " , 5 , Anim_Linear ( 0 , 0 , GetAnimationLength ( " KneelDown " ) , iKneelDownSpeed , ANIM_Remove ) , Anim_Linear ( 0 , 0 , 1000 , 5 , ANIM_Remove ) ) ;
ScheduleCall ( this , " EndKneel " , iKneelDownSpeed , 1 ) ;
return 1 ;
}
func EndKneel ( )
{
if ( GetAction ( ) ! = " Roll " ) SetAction ( " Walk " ) ;
}
//rollp
func StartRoll ( )
{
2011-10-25 22:01:27 +00:00
SetTurnForced ( GetDir ( ) ) ;
2011-10-12 21:09:22 +00:00
Sound ( " Roll " ) ;
2012-04-07 21:32:57 +00:00
if ( GetDir ( ) = = 1 ) lAnim . rollDir = 1 ;
2011-10-08 17:04:57 +00:00
else
2012-04-07 21:32:57 +00:00
lAnim . rollDir = - 1 ;
2011-10-08 17:04:57 +00:00
2012-04-07 21:32:57 +00:00
lAnim . rollLength = 22 ;
PlayAnimation ( " KneelRoll " , 5 , Anim_Linear ( 0 , 0 , 1500 , lAnim . rollLength , ANIM_Remove ) , Anim_Linear ( 0 , 0 , 1000 , 5 , ANIM_Remove ) ) ;
2011-10-08 17:04:57 +00:00
AddEffect ( " Rolling " , this , 1 , 1 , this ) ;
}
func FxRollingTimer ( object target , int num , int timer )
{
2012-04-07 21:32:57 +00:00
if ( GetContact ( - 1 ) ) SetXDir ( 23 * lAnim . rollDir ) ;
2011-10-08 17:04:57 +00:00
//Hacky fun
var i = 3 ;
2012-04-07 21:32:57 +00:00
while ( GBackSolid ( lAnim . rollDir , 9 ) & & i ! = 0 )
2011-10-08 17:04:57 +00:00
{
SetPosition ( GetX ( ) , GetY ( ) - 1 ) ;
i - - ;
}
2012-04-07 21:32:57 +00:00
if ( timer > lAnim . rollLength )
2011-10-08 17:04:57 +00:00
{
SetAction ( " Walk " ) ;
2011-10-25 22:01:27 +00:00
SetTurnForced ( - 1 ) ;
2012-04-07 21:32:57 +00:00
lAnim . rollDir = nil ;
2011-10-08 17:04:57 +00:00
return - 1 ;
}
2011-10-08 20:44:24 +00:00
if ( GetMaterialVal ( " DigFree " , " Material " , GetMaterial ( 0 , 10 ) ) )
{
var clr = GetAverageTextureColor ( GetTexture ( 0 , 10 ) ) ;
var dir = GetDir ( ) * 2 - 1 ;
2013-10-20 16:15:14 +00:00
var particles =
{
Prototype = Particles_Dust ( ) ,
R = ( clr > > 16 ) & 0xff ,
G = ( clr > > 8 ) & 0xff ,
B = clr & 0xff ,
} ;
2013-12-17 20:40:40 +00:00
CreateParticle ( " Dust " , PV_Random ( dir * - 2 , dir * - 1 ) , 8 , PV_Random ( dir * 2 , dir * 1 ) , PV_Random ( - 2 , - 5 ) , PV_Random ( 36 , 2 * 36 ) , particles , 6 ) ;
2011-10-08 20:44:24 +00:00
}
2011-10-08 17:04:57 +00:00
}
/*--
Digging
The effect just is responsible for the sound and the termination of digging .
- - */
func StartDigging ( )
{
if ( ! GetEffect ( " IntDig " , this ) )
AddEffect ( " IntDig " , this , 1 , 1 , this ) ;
}
func StopDigging ( )
{
if ( GetAction ( ) ! = " Dig " ) RemoveEffect ( " IntDig " , this ) ;
}
func FxIntDigStart ( pTarget , effect , fTmp )
{
if ( fTmp ) return ;
2011-10-09 08:58:58 +00:00
PlayAnimation ( " Dig " , 5 , Anim_Linear ( 0 , 0 , GetAnimationLength ( " Dig " ) , 36 , ANIM_Loop ) , Anim_Linear ( 0 , 0 , 1000 , 5 , ANIM_Remove ) ) ;
2011-10-08 17:04:57 +00:00
// Update carried items
UpdateAttach ( ) ;
// Sound
2011-10-12 21:09:22 +00:00
Sound ( " Dig? " ) ;
2011-10-08 17:04:57 +00:00
// Set proper turn type
SetTurnType ( 0 ) ;
}
func FxIntDigTimer ( pTarget , effect , iTime )
{
if ( iTime % 36 = = 0 )
{
2011-10-12 21:09:22 +00:00
Sound ( " Dig? " ) ;
2011-10-08 17:04:57 +00:00
}
if ( ( iTime - 18 ) % 36 = = 0 | | iTime > 35 )
{
var noDig = 1 ;
for ( var pShovel in FindObjects ( Find_ID ( Shovel ) , Find_Container ( this ) ) )
if ( pShovel - > IsDigging ( ) ) noDig = 0 ;
if ( noDig )
{
SetAction ( " Walk " ) ;
SetComDir ( COMD_Stop ) ;
return - 1 ;
}
}
}
/*--
Throwing
Throw animation
- - */
// custom throw
public func ControlThrow ( object target , int x , int y )
{
// standard throw after all
if ( ! x & & ! y ) return false ;
if ( ! target ) return false ;
var throwAngle = Angle ( 0 , 0 , x , y ) ;
// walking (later with animation: flight, scale, hangle?) and hands free
if ( ( GetProcedure ( ) = = " WALK " | | GetAction ( ) = = " Jump " | | GetAction ( ) = = " Dive " )
& & this - > ~ HasHandAction ( ) )
{
if ( throwAngle < 180 ) SetDir ( DIR_Right ) ;
else SetDir ( DIR_Left ) ;
//SetAction("Throw");
this - > ~ SetHandAction ( 1 ) ; // Set hands ocupied
AddEffect ( " IntThrow " , this , 1 , 1 , this , 0 , target , throwAngle ) ;
return true ;
}
// attached
if ( GetProcedure ( ) = = " ATTACH " )
{
//SetAction("RideThrow");
return DoThrow ( target , throwAngle ) ;
}
return false ;
}
func FxIntThrowStart ( target , effect , tmp , targetobj , throwAngle )
{
var iThrowTime = 16 ;
if ( tmp ) return ;
PlayAnimation ( " ThrowArms " , 10 , Anim_Linear ( 0 , 0 , GetAnimationLength ( " ThrowArms " ) , iThrowTime ) , Anim_Const ( 1000 ) ) ;
effect . targetobj = targetobj ;
effect . angle = throwAngle ;
}
func FxIntThrowTimer ( target , effect , time )
{
// cancel throw if object does not exist anymore
if ( ! effect . targetobj )
return - 1 ;
var iThrowTime = 16 ;
if ( time = = iThrowTime * 8 / 15 )
DoThrow ( effect . targetobj , effect . angle ) ;
if ( time > = iThrowTime )
return - 1 ;
}
func FxIntThrowStop ( target , effect , reason , tmp )
{
if ( tmp ) return ;
StopAnimation ( GetRootAnimation ( 10 ) ) ;
this - > ~ SetHandAction ( 0 ) ;
}
/*--
Dead
Animation on clonk death
- - */
func StartDead ( )
{
PlayAnimation ( " Dead " , 5 , Anim_Linear ( 0 , 0 , GetAnimationLength ( " Dead " ) , 20 , ANIM_Hold ) , Anim_Linear ( 0 , 0 , 1000 , 5 , ANIM_Remove ) ) ;
// Update carried items
UpdateAttach ( ) ;
// Set proper turn type
SetTurnType ( 1 ) ;
}
/*--
Tumble
Tumble animation with shut eyes .
- - */
func StartTumble ( )
{
if ( GetEffect ( " IntTumble " , this ) ) return ;
// Close eyes
CloseEyes ( 1 ) ;
PlayAnimation ( " Tumble " , 5 , Anim_Linear ( 0 , 0 , GetAnimationLength ( " Tumble " ) , 20 , ANIM_Loop ) , Anim_Linear ( 0 , 0 , 1000 , 5 , ANIM_Remove ) ) ;
// Update carried items
UpdateAttach ( ) ;
// Set proper turn type
SetTurnType ( 0 ) ;
AddEffect ( " IntTumble " , this , 1 , 0 ) ;
}
func StopTumble ( )
{
if ( GetAction ( ) ! = " Tumble " )
{
RemoveEffect ( " IntTumble " , this ) ;
CloseEyes ( - 1 ) ;
}
}
/*--
Riding
Riding effect . Makes clonk invisible if the mount attaches the clonk as a mesh ( e . g . the boompack )
- - */
public func StartRiding ( )
{
if ( ! GetEffect ( " IntRiding " , this ) )
AddEffect ( " IntRiding " , this , 1 , 0 , this ) ;
}
public func AttachTargetLost ( )
{
if ( GetEffect ( " IntRiding " , this ) )
RemoveEffect ( " IntRiding " , this ) ;
}
public func StopRiding ( )
{
if ( GetEffect ( " IntRiding " , this ) )
RemoveEffect ( " IntRiding " , this ) ;
}
func FxIntRidingStart ( pTarget , effect , fTmp )
{
if ( fTmp ) return ;
var pMount = GetActionTarget ( ) ;
if ( ! pMount ) return - 1 ;
if ( pMount - > ~ OnMount ( this ) ) // Notifiy the mount, that the clonk is mounted (it should take care, that the clonk get's attached!
{
// if mount has returned true we should be attached
// So make the clonk object invisible
effect . vis = GetProperty ( " Visibility " ) ;
SetProperty ( " Visibility " , VIS_None ) ;
}
else effect . vis = - 1 ;
effect . mount = pMount ;
}
func FxIntRidingStop ( pTarget , effect , fTmp )
{
if ( fTmp ) return ;
if ( effect . vis ! = - 1 )
SetProperty ( " Visibility " , effect . vis ) ;
var pMount = effect . mount ;
if ( pMount )
pMount - > ~ OnUnmount ( this ) ;
}
/*--
Pushing
Just plays the push animation .
- - */
func StartPushing ( )
{
// if(GetEffect("IntTumble", this)) return;
// Close eyes
PlayAnimation ( " Push " , 5 , Anim_AbsX ( 0 , 0 , GetAnimationLength ( " Push " ) , 20 ) , Anim_Linear ( 0 , 0 , 1000 , 5 , ANIM_Remove ) ) ;
// Update carried items
UpdateAttach ( ) ;
// Set proper turn type
SetTurnType ( 1 ) ;
// AddEffect("IntTumble", this, 1, 0);
}
protected func StopPushing ( )
{
return _inherited ( . . . ) ;
}
/*--
HangOnto
Plays the animation and notifies the target if aborted . Used then the clonk hangs on the grappler ' s rope
- - */
func StartHangOnto ( )
{
// if(GetEffect("IntTumble", this)) return;
// Close eyes
PlayAnimation ( " OnRope " , 5 , Anim_Linear ( 0 , 0 , GetAnimationLength ( " OnRope " ) , 20 , ANIM_Loop ) , Anim_Linear ( 0 , 0 , 1000 , 5 , ANIM_Remove ) ) ;
// Update carried items
UpdateAttach ( ) ;
// Set proper turn type
SetTurnType ( 1 ) ;
// AddEffect("IntTumble", this, 1, 0);
}
protected func AbortHangOnto ( )
{
if ( GetActionTarget ( 0 ) )
GetActionTarget ( 0 ) - > ~ HangOntoLost ( this ) ;
return ;
2011-10-08 21:28:49 +00:00
}
/*--
Eat
Plays the animation
- - */
func StartEat ( )
{
// Nom nom
PlayAnimation ( " Eat " , 10 , Anim_Linear ( 0 , 0 , GetAnimationLength ( " Eat " ) , 45 , ANIM_Remove ) , Anim_Linear ( 0 , 0 , 1000 , 5 , ANIM_Remove ) ) ;
// Update carried items
UpdateAttach ( ) ;
2012-06-08 14:17:42 +00:00
}