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
- - */
2015-10-11 12:08:14 +00:00
/* Predefined animation slots */
// Any kind of movement, either legs only (like Walk or Stand) or whole body (like Swim).
// In cases of whole body animation, make sure to let other effect know that the clonk
// can do arms animation (e.g. check ReadyToAction in the Clonk's script).
static const CLONK_ANIM_SLOT_Movement = 5 ;
// Arms or upper body animations (like Aiming or Throwing)
static const CLONK_ANIM_SLOT_Arms = 10 ;
// Eye animations (like Blinking or Closing)
static const CLONK_ANIM_SLOT_Eyes = 3 ;
// Hand animations (like closing the hand)
static const CLONK_ANIM_SLOT_Hands = 6 ;
// Make sure to never use a higher slot than this, so Death will always overwrite all other animations.
static const CLONK_ANIM_SLOT_Death = 20 ;
2011-10-08 17:04:57 +00:00
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 ) ;
2017-11-23 19:38:11 +00:00
SetMeshTransformation ( Trans_Rotate ( effect . curr_rot , 0 , 1 , 0 ) , CLONK_MESH_TRANSFORM_SLOT_Turn ) ;
2011-10-08 17:04:57 +00:00
}
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 ;
2016-10-25 01:01:41 +00:00
for ( var test in ActualReplace )
2011-10-08 17:04:57 +00:00
{
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 )
{
2012-04-07 21:32:57 +00:00
lAnim . closedEyes + = iCounter ;
if ( lAnim . closedEyes > = 1 )
2016-01-29 04:47:53 +00:00
PlayAnimation ( " CloseEyes " , CLONK_ANIM_SLOT_Eyes , Anim_Linear ( 0 , 0 , GetAnimationLength ( " CloseEyes " ) / 2 , 3 , ANIM_Hold ) ) ;
2011-10-08 17:04:57 +00:00
else
2016-01-29 04:47:53 +00:00
PlayAnimation ( " CloseEyes " , CLONK_ANIM_SLOT_Eyes , Anim_Linear ( GetAnimationLength ( " CloseEyes " ) / 2 , GetAnimationLength ( " CloseEyes " ) / 2 , GetAnimationLength ( " CloseEyes " ) , 3 , ANIM_Remove ) ) ;
2011-10-08 17:04:57 +00:00
}
/*--
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
{
2016-05-13 15:13:34 +00:00
AddEffect ( " IntWalkBack " , this , 1 , 0 , this , nil , lAnim . backwardsSpeed ) ;
2012-04-07 21:32:57 +00:00
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 )
2015-12-13 21:14:55 +00:00
Sound ( " Clonk::Movement::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 ) ;
2015-12-13 21:14:55 +00:00
Sound ( " Clonk::Movement::StepSoft? " ) ;
2011-10-08 17:04:57 +00:00
}
}
2017-11-26 13:28:04 +00:00
// Returns an animation position (Anim_* function) for new_anim depending on the position of the current animation
// for smoother transitions. Does not work with replaced animations.
func GetWalkAnimationPosition ( string new_anim , int current_pos , string current_anim )
2011-10-08 17:04:57 +00:00
{
var dir = - 1 ;
if ( GetDirection ( ) = = COMD_Right ) dir = + 1 ;
if ( PropAnimations ! = nil )
2017-11-26 13:28:04 +00:00
if ( GetProperty ( Format ( " %s_Position " , new_anim ) , PropAnimations ) )
2011-10-08 17:04:57 +00:00
{
2017-11-26 13:28:04 +00:00
var length = GetAnimationLength ( new_anim ) , replacement ;
if ( replacement = GetProperty ( new_anim , PropAnimations ) )
2012-10-14 17:39:40 +00:00
{
// 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 ) ;
}
2017-11-26 13:28:04 +00:00
return Anim_X ( 0 , 0 , length , GetProperty ( Format ( " %s_Position " , new_anim ) , PropAnimations ) * dir ) ;
2011-10-08 17:04:57 +00:00
}
2017-11-26 13:28:04 +00:00
// Inside a container the position is always 0.
if ( new_anim = = Clonk_WalkInside )
2011-10-08 17:04:57 +00:00
return Anim_Const ( 0 ) ;
2017-11-26 13:28:04 +00:00
// Transitions into stand are always arbitrary. A nice transition is possible but is probably
// too much of a hassle for such a small effect and has nothing to do with the position of the
// Stand animation.
if ( new_anim = = Clonk_WalkStand )
return Anim_Linear ( 0 , 0 , GetAnimationLength ( new_anim ) , 35 , ANIM_Loop ) ;
// Transition into the Walk animation
else if ( new_anim = = Clonk_WalkWalk )
{
// Transition from Inside or Stand:
// Start on a position where one foot is on the ground (the foreground one) and in the center
if ( current_anim = = Clonk_WalkInside | | current_anim = = Clonk_WalkStand )
{
var pos = 720 ;
if ( dir = = - 1 )
pos = 1896 ;
return Anim_X ( pos , 0 , GetAnimationLength ( new_anim ) , 20 * dir ) ;
}
// Transition from run: position + 1200
if ( current_anim = = Clonk_WalkRun )
{
var pos = current_pos + 1200 ;
if ( pos > 2400 )
pos - = 2400 ;
return Anim_X ( pos , 0 , GetAnimationLength ( new_anim ) , 20 * dir ) ;
}
if ( current_anim = = Clonk_WalkWalk ) // why is this called?
return Anim_X ( current_pos , 0 , GetAnimationLength ( new_anim ) , 20 * dir ) ;
}
else if ( new_anim = = Clonk_WalkRun )
{
// Transition from Inside or Stand:
// Start on a position where one foot is on the ground (the foreground one) and in the center
if ( current_anim = = Clonk_WalkInside | | current_anim = = Clonk_WalkStand )
{
var pos = 1824 ;
if ( dir = = - 1 )
pos = 600 ;
return Anim_X ( pos , 0 , GetAnimationLength ( new_anim ) , 50 * dir ) ;
}
// Transition from walk: position + 1200
if ( current_anim = = Clonk_WalkWalk )
{
var pos = current_pos + 1200 ;
if ( pos > 2400 )
pos - = 2400 ;
return Anim_X ( pos , 0 , GetAnimationLength ( new_anim ) , 50 * dir ) ;
}
if ( current_anim = = Clonk_WalkRun ) // why is this called?
return Anim_X ( current_pos , 0 , GetAnimationLength ( new_anim ) , 50 * dir ) ;
}
2011-10-08 17:04:57 +00:00
}
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 ;
2015-10-11 12:08:14 +00:00
effect . animation_id = PlayAnimation ( anim , CLONK_ANIM_SLOT_Movement , GetWalkAnimationPosition ( anim ) , Anim_Linear ( 0 , 0 , 1000 , 5 , ANIM_Remove ) ) ;
2011-10-08 17:04:57 +00:00
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 ;
2017-11-26 13:28:04 +00:00
effect . animation_id = PlayAnimation ( anim , CLONK_ANIM_SLOT_Movement , GetWalkAnimationPosition ( anim , GetAnimationPosition ( effect . animation_id ) , effect . animation_name ) , Anim_Linear ( 0 , 0 , 1000 , 5 , ANIM_Remove ) ) ;
2011-10-08 17:04:57 +00:00
}
// The clonk has to stand, not making a pause animation yet and not doing other actions with the hands (e.g. loading the bow)
2015-12-20 17:45:48 +00:00
else if ( anim = = Clonk_WalkStand & & ! GetHandAction ( ) & & GetMenu ( ) = = nil )
2011-10-08 17:04:57 +00:00
{
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 ) ) ;
2015-10-11 12:08:14 +00:00
PlayAnimation ( Clonk_IdleActions [ rand ] [ 0 ] , CLONK_ANIM_SLOT_Movement , Anim_Linear ( 0 , 0 , GetAnimationLength ( Clonk_IdleActions [ rand ] [ 0 ] ) , Clonk_IdleActions [ rand ] [ 1 ] , ANIM_Remove ) , Anim_Linear ( 0 , 0 , 1000 , 5 , ANIM_Remove ) ) ;
2011-10-08 17:04:57 +00:00
effect . idle_animation_time = Clonk_IdleActions [ rand ] [ 1 ] - 5 ;
2015-12-20 17:45:48 +00:00
if ( ! Random ( 10 ) )
2015-12-16 22:00:17 +00:00
this - > PlaySoundIdle ( ) ;
2011-10-08 17:04:57 +00:00
}
}
}
else
{
effect . idle_time = 0 ;
if ( effect . idle_animation_time )
{
effect . animation_name = nil ;
effect . idle_animation_time = 0 ;
}
if ( anim = = Clonk_WalkRun )
{
2015-10-13 13:11:11 +00:00
// There are roughly two animation positions in Run when a foot touches the ground:
// 550 and 1700
// This here is trying to trigger a footstep as close as possible to these two moments.
var pos = GetAnimationPosition ( effect . animation_id ) ;
if ( pos < 550 & & effect . footstep_time )
effect . footstep_time = 0 ;
if ( Inside ( pos , 550 , 1699 ) & & effect . footstep_time ! = 1 )
2011-10-08 17:04:57 +00:00
{
Footstep ( ) ;
2015-10-13 13:11:11 +00:00
effect . footstep_time = 1 ;
}
if ( pos > = 1700 & & effect . footstep_time ! = 2 )
{
Footstep ( ) ;
effect . footstep_time = 2 ;
2011-10-08 17:04:57 +00:00
}
}
else if ( effect . footstep_time ) effect . footstep_time = 0 ;
}
}
func FxIntWalkReset ( pTarget , effect )
{
effect . animation_name = nil ;
}
func StartStand ( )
{
2015-10-11 12:08:14 +00:00
PlayAnimation ( Clonk_WalkStand , CLONK_ANIM_SLOT_Movement , GetWalkAnimationPosition ( Clonk_WalkStand ) , Anim_Linear ( 0 , 0 , 1000 , 5 , ANIM_Remove ) ) ;
2011-10-08 17:04:57 +00:00
// 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 .
- - */
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
2016-01-02 02:58:45 +00:00
// Check the head vertex
if ( GBackSolid ( - 1 + 2 * GetDir ( ) , - 7 ) ) return false ;
// Check the shoulder vertices
if ( GBackSolid ( - 3 + 6 * GetDir ( ) , - 3 ) ) return false ;
// Check the hip vertices
if ( GBackSolid ( - 5 + 10 * GetDir ( ) , 2 ) ) return false ;
2011-10-08 17:04:57 +00:00
return true ;
}
Added a slight helper for corner scaling when just pressing up (#1770, #1630).
The problem occurred as soon as the clonk's leg vertices passed the edge. It seems the engine does not really align the bottom vertex to the material. However, the bottom vertex does have CNAT_Bottom & _Left & _Right, in theory it should be properly attached. Maybe this is a little bit broken engine-wise or maybe assigning both left and right to a vertex isn't supported?
Because the lower vertex (foot vertex) isn't attached, the clonk falls down onto its leg vertex and gets stuck in an endless loop of Scale, Jump, Walk, Scale, ...
When pressing left/right, this is no problem as the clonk will be pushed towards the edge when walking and soon touch it with its foot vertex (I assume at this point regular engine behaviour kicks in).
I added a little helper in the scale effect that sets COMD_UpLeft / UpRight whenever this situation is detected and only Up is pressed. 2 frames (1 is not enough) after the effect ended, the ComDir will reset to COMD_Up. It is then possible to climb an edge and stand still on top of it.
Maybe not a perfect solution (a perfect solution would probably be to fix attachment in the engine but I couldn't pinpoint the exact problem) but it works for now.
2016-08-09 23:19:11 +00:00
func CheckScaleTopHelper ( )
{
// Check if the clonk has passed the material with its leg vertices
// and if COMD_Up is used to climb in which case corner scale would fail
if ( GBackSolid ( - 3 + 6 * GetDir ( ) , 6 ) ) return false ;
if ( GetComDir ( ) ! = COMD_Up ) return false ;
return true ;
}
2011-10-08 17:04:57 +00:00
func FxIntScaleStart ( target , effect , tmp )
{
if ( tmp ) return ;
2015-10-11 12:08:14 +00:00
effect . animation_id = PlayAnimation ( " Scale " , CLONK_ANIM_SLOT_Movement , Anim_Y ( 0 , GetAnimationLength ( " Scale " ) , 0 , 15 ) , Anim_Linear ( 0 , 0 , 1000 , 5 , ANIM_Remove ) ) ;
2011-10-08 17:04:57 +00:00
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 ;
2016-01-02 02:58:45 +00:00
dist = BoundBy ( dist , 0 , GetAnimationLength ( " ScaleTop " ) ) ;
2011-10-08 17:04:57 +00:00
if ( number . animation_mode ! = 1 )
{
2015-10-11 12:08:14 +00:00
number . animation_id = PlayAnimation ( " ScaleTop " , CLONK_ANIM_SLOT_Movement , 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 ) ;
2017-02-21 02:22:10 +00:00
SetScaleRotation ( 0 , 0 , 0 , 0 , 0 , true ) ;
Added a slight helper for corner scaling when just pressing up (#1770, #1630).
The problem occurred as soon as the clonk's leg vertices passed the edge. It seems the engine does not really align the bottom vertex to the material. However, the bottom vertex does have CNAT_Bottom & _Left & _Right, in theory it should be properly attached. Maybe this is a little bit broken engine-wise or maybe assigning both left and right to a vertex isn't supported?
Because the lower vertex (foot vertex) isn't attached, the clonk falls down onto its leg vertex and gets stuck in an endless loop of Scale, Jump, Walk, Scale, ...
When pressing left/right, this is no problem as the clonk will be pushed towards the edge when walking and soon touch it with its foot vertex (I assume at this point regular engine behaviour kicks in).
I added a little helper in the scale effect that sets COMD_UpLeft / UpRight whenever this situation is detected and only Up is pressed. 2 frames (1 is not enough) after the effect ended, the ComDir will reset to COMD_Up. It is then possible to climb an edge and stand still on top of it.
Maybe not a perfect solution (a perfect solution would probably be to fix attachment in the engine but I couldn't pinpoint the exact problem) but it works for now.
2016-08-09 23:19:11 +00:00
// Check if corner scale help is needed
if ( CheckScaleTopHelper ( ) )
{
if ( GetDir ( ) = = DIR_Left )
SetComDir ( COMD_UpLeft ) ;
else
SetComDir ( COMD_UpRight ) ;
number . corner_scale_helper = true ;
}
else if ( number . corner_scale_helper )
number . corner_scale_helper = false ;
}
else if ( number . corner_scale_helper )
{
// This will delay everything for 1 frame just for cleanup, hopefully it's not too bad
number . corner_scale_helper = false ;
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 ) ;
2015-10-11 12:08:14 +00:00
number . animation_id = PlayAnimation ( " ScaleHands " , CLONK_ANIM_SLOT_Movement , Anim_Y ( pos , GetAnimationLength ( " ScaleHands " ) , 0 , 15 ) , Anim_Linear ( 0 , 0 , 1000 , 5 , ANIM_Remove ) ) ;
number . animation_id2 = PlayAnimation ( " ScaleHands2 " , CLONK_ANIM_SLOT_Movement , Anim_Y ( pos , GetAnimationLength ( " ScaleHands2 " ) , 0 , 15 ) , Anim_Const ( 1000 ) , number . animation_id ) ;
2011-10-08 17:04:57 +00:00
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 ) ;
2015-10-11 12:08:14 +00:00
number . animation_id = PlayAnimation ( " Scale " , CLONK_ANIM_SLOT_Movement , Anim_Y ( 0 , GetAnimationLength ( " Scale " ) , 0 , 15 ) , Anim_Linear ( 0 , 0 , 1000 , 5 , ANIM_Remove ) ) ;
2011-10-08 17:04:57 +00:00
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 ;
2017-11-23 19:38:11 +00:00
SetMeshTransformation ( Trans_Mul ( Trans_Translate ( eff . oldX - turnx , eff . oldY - turny ) , Trans_Rotate ( eff . oldR , 0 , 0 , 1 ) , Trans_Translate ( turnx , turny ) ) , CLONK_MESH_TRANSFORM_SLOT_Rotation_Scaling ) ;
2011-10-08 17:04:57 +00:00
}
2017-02-21 02:22:10 +00:00
func SetScaleRotation ( int r , int xoff , int yoff , int rotZ , int turny , bool instant ) {
2011-10-08 17:04:57 +00:00
if ( r < - 180 ) r + = 360 ;
if ( r > 180 ) r - = 360 ;
// set matrix values
var turnx = - 1000 ;
2017-02-21 02:22:10 +00:00
turny + = 10000 ; // rotation relative to clonk center
2011-10-08 17:04:57 +00:00
if ( instant )
{
RemoveEffect ( " IntScaleRot " , this ) ;
2017-11-23 19:38:11 +00:00
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 ) ) , CLONK_MESH_TRANSFORM_SLOT_Rotation_Scaling ) ;
2011-10-08 17:04:57 +00:00
}
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
2015-10-11 12:08:14 +00:00
/* if(number.animation_mode == 1) PlayAnimation(Clonk_WalkStand, CLONK_ANIM_SLOT_Movement, GetWalkAnimationPosition(Clonk_WalkStand), Anim_Const(1000));
2011-10-08 17:04:57 +00:00
// Finally stop if the user has scheduled a stop
2011-10-09 08:58:58 +00:00
if ( number . ScheduleStop ) SetComDir ( COMD_Stop ) ; */
Added a slight helper for corner scaling when just pressing up (#1770, #1630).
The problem occurred as soon as the clonk's leg vertices passed the edge. It seems the engine does not really align the bottom vertex to the material. However, the bottom vertex does have CNAT_Bottom & _Left & _Right, in theory it should be properly attached. Maybe this is a little bit broken engine-wise or maybe assigning both left and right to a vertex isn't supported?
Because the lower vertex (foot vertex) isn't attached, the clonk falls down onto its leg vertex and gets stuck in an endless loop of Scale, Jump, Walk, Scale, ...
When pressing left/right, this is no problem as the clonk will be pushed towards the edge when walking and soon touch it with its foot vertex (I assume at this point regular engine behaviour kicks in).
I added a little helper in the scale effect that sets COMD_UpLeft / UpRight whenever this situation is detected and only Up is pressed. 2 frames (1 is not enough) after the effect ended, the ComDir will reset to COMD_Up. It is then possible to climb an edge and stand still on top of it.
Maybe not a perfect solution (a perfect solution would probably be to fix attachment in the engine but I couldn't pinpoint the exact problem) but it works for now.
2016-08-09 23:19:11 +00:00
// Reset the transform
2011-10-08 17:04:57 +00:00
SetScaleRotation ( 0 ) ;
Added a slight helper for corner scaling when just pressing up (#1770, #1630).
The problem occurred as soon as the clonk's leg vertices passed the edge. It seems the engine does not really align the bottom vertex to the material. However, the bottom vertex does have CNAT_Bottom & _Left & _Right, in theory it should be properly attached. Maybe this is a little bit broken engine-wise or maybe assigning both left and right to a vertex isn't supported?
Because the lower vertex (foot vertex) isn't attached, the clonk falls down onto its leg vertex and gets stuck in an endless loop of Scale, Jump, Walk, Scale, ...
When pressing left/right, this is no problem as the clonk will be pushed towards the edge when walking and soon touch it with its foot vertex (I assume at this point regular engine behaviour kicks in).
I added a little helper in the scale effect that sets COMD_UpLeft / UpRight whenever this situation is detected and only Up is pressed. 2 frames (1 is not enough) after the effect ended, the ComDir will reset to COMD_Up. It is then possible to climb an edge and stand still on top of it.
Maybe not a perfect solution (a perfect solution would probably be to fix attachment in the engine but I couldn't pinpoint the exact problem) but it works for now.
2016-08-09 23:19:11 +00:00
// Remove the corner scale helper com dir
if ( number . corner_scale_helper )
if ( GetComDir ( ) = = COMD_UpLeft | | GetComDir ( ) = = COMD_UpRight )
Schedule ( this , " SetComDir(COMD_Up) " , 2 ) ;
2011-10-08 17:04:57 +00:00
}
/*--
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 )
2015-10-11 12:08:14 +00:00
PlayAnimation ( Format ( " Jump.%s " , side ) , CLONK_ANIM_SLOT_Movement , Anim_Linear ( 0 , 0 , GetAnimationLength ( " Jump.L " ) , 8 * 5 , ANIM_Hold ) , Anim_Linear ( 0 , 0 , 1000 , 5 , ANIM_Remove ) ) ;
2011-10-08 17:04:57 +00:00
//Walk kick jump
if ( GetEffect ( " WallKick " , this ) )
{
SetAction ( " WallJump " ) ;
var side = " L " ;
if ( GetDir ( ) = = DIR_Left ) side = " R " ;
2015-10-11 12:08:14 +00:00
PlayAnimation ( Format ( " JumpWall.%s " , side ) , CLONK_ANIM_SLOT_Movement , Anim_Linear ( 0 , 0 , GetAnimationLength ( " JumpWall.L " ) , 8 * 5 , ANIM_Hold ) , Anim_Linear ( 0 , 0 , 1000 , 5 , ANIM_Remove ) ) ;
2011-10-08 17:04:57 +00:00
}
//Upwards jump
else if ( GetXDir ( ) = = 0 )
{
2015-10-11 12:08:14 +00:00
PlayAnimation ( Format ( " JumpUp.%s " , side ) , CLONK_ANIM_SLOT_Movement , Anim_Linear ( 0 , 0 , GetAnimationLength ( " JumpUp.L " ) , 8 * 5 , ANIM_Hold ) , Anim_Linear ( 0 , 0 , 1000 , 5 , ANIM_Remove ) ) ;
2011-10-08 17:04:57 +00:00
}
// 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 ( ) )
{
2018-01-19 11:34:12 +00:00
var flight = SimFlight ( 0 , GetBottom ( ) , nil , nil , C4M_Liquid ) ;
if ( GBackLiquid ( flight [ 0 ] - GetX ( ) , flight [ 1 ] - GetY ( ) ) & & GBackLiquid ( flight [ 0 ] - GetX ( ) , flight [ 1 ] + GetBottom ( ) - GetY ( ) ) )
2012-04-29 16:12:04 +00:00
{
2015-10-11 12:08:14 +00:00
PlayAnimation ( " JumpDive " , CLONK_ANIM_SLOT_Movement , Anim_Linear ( 0 , 0 , GetAnimationLength ( " JumpDive " ) , 60 , ANIM_Hold ) , Anim_Linear ( 0 , 0 , 1000 , 5 , ANIM_Remove ) ) ;
2017-11-27 20:57:17 +00:00
if ( ! GetEffect ( " IntDiveJump " , this ) )
AddEffect ( " IntDiveJump " , this , 1 , 1 , this ) ;
2012-04-29 16:12:04 +00:00
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 )
{
2016-06-18 17:47:39 +00:00
if ( GetAction ( ) ! = " Jump " )
return - 1 ;
2011-10-08 17:04:57 +00:00
//falling off ledges without jumping results in fall animation
if ( timer = = 2 & & GetYDir ( ) > 1 )
{
2015-10-11 12:08:14 +00:00
PlayAnimation ( " FallShort " , CLONK_ANIM_SLOT_Movement , Anim_Linear ( 0 , 0 , GetAnimationLength ( " FallShort " ) , 8 * 3 , ANIM_Hold ) , Anim_Linear ( 0 , 0 , 1000 , 5 , ANIM_Remove ) ) ;
2011-10-08 17:04:57 +00:00
}
if ( timer = = 2 & & GetYDir ( ) < 1 )
{
2015-12-13 21:14:55 +00:00
Sound ( " Clonk::Movement::Rustle? " ) ;
2011-10-08 17:04:57 +00:00
}
if ( GetYDir ( ) > 55 & & GetAction ( ) = = " Jump " )
{
2015-10-11 12:08:14 +00:00
PlayAnimation ( " FallLong " , CLONK_ANIM_SLOT_Movement , Anim_Linear ( 0 , 0 , GetAnimationLength ( " FallLong " ) , 8 * 3 , ANIM_Hold ) , Anim_Linear ( 0 , 0 , 1000 , 5 , ANIM_Remove ) ) ;
2011-10-08 17:04:57 +00:00
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
- - */
/* Replaces the named action by an instance with a different speed */
func PushActionSpeed ( string action , int n )
{
if ( ActMap = = this . Prototype . ActMap )
ActMap = { Prototype = this . Prototype . ActMap } ;
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 ( ! 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
2015-10-11 12:08:14 +00:00
effect . animation_id = PlayAnimation ( " HangleStand " , CLONK_ANIM_SLOT_Movement , Anim_Linear ( 0 , 0 , 2000 , 100 , ANIM_Loop ) , Anim_Linear ( 0 , 0 , 1000 , 5 , ANIM_Remove ) ) ;
2011-10-08 17:04:57 +00:00
}
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")
2017-11-21 19:56:35 +00:00
// The speed factor used to be between 0 and 50 (radius 50 in the cos function),
// now it is between 25 and 50 for a motion that feels more fluid
var iSpeed = 50 - Cos ( GetAnimationPosition ( effect . animation_id ) / 10 * 360 * 2 / 1000 , 25 ) ;
2011-10-08 17:04:57 +00:00
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 " ) ) ) ;
2017-11-21 19:49:41 +00:00
// Stop movement
if ( GetComDir ( ) = = COMD_Stop )
2011-10-08 17:04:57 +00:00
{
2017-11-21 19:49:41 +00:00
if ( ! effect . request_stop )
{
// Delay the stop animation a little, for nicer looking motion of the clonk
// This is still the same variable name as in the previous implementation,
// although the functionality was changed a little - this should impact
// other parts of the script that maybe rely on this variable name
// as little as possible.
// This also prevents a strange pose of the clonk if you hangle by
// tapping the left/right buttons repeatedly.
effect . request_stop = 10 ; // play the current animation for 10 more timer calls
}
2011-10-08 17:04:57 +00:00
else
2017-11-21 19:49:41 +00:00
{
// Start the hanging animation once the delay is over
effect . request_stop - = 1 ;
if ( effect . request_stop = = 0 )
{
// Remember 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 " , CLONK_ANIM_SLOT_Movement , Anim_Linear ( begin , begin , end , 100 , ANIM_Loop ) , Anim_Linear ( 0 , 0 , 1000 , 5 , ANIM_Remove ) ) ;
effect . is_moving = 0 ;
}
}
2011-10-08 17:04:57 +00:00
}
2017-11-21 19:49:41 +00:00
else
2011-10-08 17:04:57 +00:00
{
2017-11-21 19:49:41 +00:00
effect . request_stop = 0 ; // Reset the delay
2011-10-08 17:04:57 +00:00
}
}
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 ) ;
2015-10-11 12:08:14 +00:00
effect . animation_id = PlayAnimation ( " Hangle " , CLONK_ANIM_SLOT_Movement , Anim_Const ( begin ) , Anim_Linear ( 0 , 0 , 1000 , 5 , ANIM_Remove ) ) ;
2011-10-08 17:04:57 +00:00
}
}
}
/*--
Swim
Different animation for swiming and diving . Adjusting the rotation while diving .
- - */
func StartSwim ( )
{
2015-03-26 18:51:09 +00:00
if ( ! InLiquid ( ) )
return ;
if ( ! GetEffect ( " IntSwim " , this ) )
2011-10-08 17:04:57 +00:00
AddEffect ( " IntSwim " , this , 1 , 1 , this ) ;
2015-03-26 18:51:09 +00:00
SetSwimmingVertices ( true ) ;
return ;
2011-10-08 17:04:57 +00:00
}
func StopSwim ( )
{
2015-03-26 18:51:09 +00:00
if ( GetAction ( ) ! = " Swim " )
RemoveEffect ( " IntSwim " , this ) ;
SetSwimmingVertices ( false ) ;
return ;
2013-10-06 12:55:48 +00:00
}
func SetSwimmingVertices ( bool is_swimming )
{
2015-07-14 17:14:17 +00:00
// Remove old delayed vertex effects.
while ( GetEffect ( " IntDelayedVertex " , this ) )
RemoveEffect ( " IntDelayedVertex " , this ) ;
2015-03-26 18:51:09 +00:00
var vtx_list = [ [ 0 , 2 , 0 , 300 ] , [ 0 , - 7 , 4 , 300 ] , [ 0 , 9 , 11 , 300 ] , [ - 2 , - 3 , 1 , 300 ] , [ 2 , - 3 , 2 , 300 ] , [ - 4 , 2 , 1 , 300 ] , [ 4 , 2 , 2 , 300 ] , [ - 2 , 6 , 1 , 300 ] , [ 2 , 6 , 2 , 300 ] ] ;
2013-10-06 12:55:48 +00:00
if ( is_swimming )
2015-03-26 18:51:09 +00:00
vtx_list = [ [ 0 , 2 , 0 , 50 ] , [ 0 , - 2 , 4 , 50 ] , [ 0 , 7 , 11 , 50 ] , [ - 4 , - 1 , 1 , 50 ] , [ 4 , - 1 , 2 , 50 ] , [ - 4 , 2 , 1 , 50 ] , [ 4 , 2 , 2 , 50 ] , [ - 4 , 4 , 1 , 50 ] , [ 4 , 4 , 2 , 50 ] ] ;
2013-10-06 12:55:48 +00:00
for ( var i = 0 ; i < GetVertexNum ( ) ; i + + )
{
2015-03-26 18:51:09 +00:00
var x = GetVertex ( i , VTX_X ) ;
var y = GetVertex ( i , VTX_Y ) ;
var cnat = GetVertex ( i , VTX_CNAT ) ;
var friction = GetVertex ( i , VTX_Friction ) ;
2013-10-06 12:55:48 +00:00
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 ) ;
2015-03-26 18:51:09 +00:00
SetVertex ( i , VTX_Friction , vtx_list [ i ] [ 3 ] , 2 ) ;
// Don't do the update if that would stuck the clonk.
if ( Stuck ( ) )
{
SetVertex ( i , VTX_X , x , 2 ) ;
SetVertex ( i , VTX_Y , y , 2 ) ;
SetVertex ( i , VTX_CNAT , cnat , 2 ) ;
SetVertex ( i , VTX_Friction , friction , 2 ) ;
// But add an effect which does this delayed.
var effect = AddEffect ( " IntDelayedVertex " , this , 100 , 1 , this ) ;
effect . vertex = i ;
2015-07-14 17:14:17 +00:00
effect . to_vertex = vtx_list [ i ] ;
2015-03-26 18:51:09 +00:00
}
2013-10-06 12:55:48 +00:00
}
return ;
2011-10-08 17:04:57 +00:00
}
2015-03-26 18:51:09 +00:00
protected func FxIntDelayedVertexTimer ( object target , proplist effect , int time )
{
2015-07-14 17:14:17 +00:00
if ( Stuck ( ) )
return FX_OK ;
SetVertex ( effect . vertex , VTX_X , effect . to_vertex [ 0 ] , 2 ) ;
SetVertex ( effect . vertex , VTX_Y , effect . to_vertex [ 1 ] , 2 ) ;
SetVertex ( effect . vertex , VTX_CNAT , effect . to_vertex [ 2 ] , 2 ) ;
SetVertex ( effect . vertex , VTX_Friction , effect . to_vertex [ 3 ] , 2 ) ;
return FX_Execute_Kill ;
2015-03-26 18:51:09 +00:00
}
2011-10-08 17:04:57 +00:00
func FxIntSwimStart ( pTarget , effect , fTmp )
{
if ( fTmp ) return ;
2017-11-27 20:57:17 +00:00
var enter_diving = GetEffect ( " IntDiveJump " , this ) ;
2011-10-08 17:04:57 +00:00
effect . animation_name = " SwimStand " ;
2017-11-27 20:57:17 +00:00
if ( ! enter_diving )
{
effect . animation = PlayAnimation ( " SwimStand " , CLONK_ANIM_SLOT_Movement , Anim_Linear ( 0 , 0 , GetAnimationLength ( " SwimStand " ) , 20 , ANIM_Loop ) , Anim_Linear ( 0 , 0 , 1000 , 5 , ANIM_Remove ) ) ;
}
2011-10-08 17:04:57 +00:00
// Set proper turn type
SetTurnType ( 0 ) ;
// Update carried items
UpdateAttach ( ) ;
}
func FxIntSwimTimer ( pTarget , effect , iTime )
{
var iSpeed = Distance ( 0 , 0 , GetXDir ( ) , GetYDir ( ) ) ;
2017-11-23 20:16:12 +00:00
SetMeshTransformation ( nil , CLONK_MESH_TRANSFORM_SLOT_Translation_Dive ) ;
2017-11-27 20:57:17 +00:00
var is_at_surface = ! GBackSemiSolid ( 0 , - 5 ) ;
var enter_diving = GetEffect ( " IntDiveJump " , this ) ;
2011-10-08 17:04:57 +00:00
// TODO: Smaller transition time between dive<->swim, keep 15 for swimstand<->swim/swimstand<->dive
2017-11-27 20:57:17 +00:00
if ( is_at_surface & & ! enter_diving )
2011-10-08 17:04:57 +00:00
{
2017-11-27 20:57:17 +00:00
// Play stand animation when not moving
if ( Abs ( GetXDir ( ) ) < 1 )
2011-10-08 17:04:57 +00:00
{
2017-11-27 20:57:17 +00:00
if ( GetContact ( - 1 ) & CNAT_Bottom )
{
SetAction ( " Walk " ) ;
return - 1 ;
}
if ( effect . animation_name ! = " SwimStand " )
{
effect . animation_name = " SwimStand " ;
effect . animation = PlayAnimation ( " SwimStand " , CLONK_ANIM_SLOT_Movement , Anim_Linear ( 0 , 0 , GetAnimationLength ( " SwimStand " ) , 20 , ANIM_Loop ) , Anim_Linear ( 0 , 0 , 1000 , 15 , ANIM_Remove ) ) ;
}
2011-10-08 17:04:57 +00:00
}
2017-11-27 20:57:17 +00:00
// Swimming
else
2011-10-08 17:04:57 +00:00
{
2017-11-27 20:57:17 +00:00
if ( GBackLiquid ( ) ) // re-check water background before effects to prevent waves in wrong color
2011-10-08 17:04:57 +00:00
{
2017-11-27 20:57:17 +00:00
var percent = GetAnimationPosition ( GetRootAnimation ( 5 ) ) * 200 / GetAnimationLength ( " Swim " ) ;
percent = ( percent % 100 ) ;
if ( percent < 40 )
2013-11-04 12:06:13 +00:00
{
2017-11-27 20:57:17 +00:00
if ( iTime % 5 = = 0 )
2016-01-15 02:51:30 +00:00
{
2017-11-27 20:57:17 +00:00
var phases = PV_Linear ( 0 , 7 ) ;
if ( GetDir ( ) = = 1 ) phases = PV_Linear ( 8 , 15 ) ;
var color = GetAverageTextureColor ( GetTexture ( 0 , 0 ) ) ;
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 ,
} ;
CreateParticle ( " Wave " , 0 , - 4 , ( RandomX ( - 5 , 5 ) - ( - 1 + 2 * GetDir ( ) ) * 4 ) / 4 , 0 , 16 , particles ) ;
}
Sound ( " Liquids::Swim? " ) ;
2016-01-15 02:51:30 +00:00
}
2011-10-08 17:04:57 +00:00
}
2017-11-27 20:57:17 +00:00
// Animation speed by X
if ( effect . animation_name ! = " Swim " )
{
effect . animation_name = " Swim " ;
// TODO: Determine starting position from previous animation
PlayAnimation ( " Swim " , CLONK_ANIM_SLOT_Movement , Anim_AbsX ( 0 , 0 , GetAnimationLength ( " Swim " ) , 25 ) , Anim_Linear ( 0 , 0 , 1000 , 15 , ANIM_Remove ) ) ;
}
2011-10-08 17:04:57 +00:00
}
}
// Diving
else
{
if ( effect . animation_name ! = " SwimDive " )
{
effect . animation_name = " SwimDive " ;
// TODO: Determine starting position from previous animation
2015-10-11 12:08:14 +00:00
effect . animation2 = PlayAnimation ( " SwimDiveUp " , CLONK_ANIM_SLOT_Movement , Anim_Linear ( 0 , 0 , GetAnimationLength ( " SwimDiveUp " ) , 40 , ANIM_Loop ) , Anim_Linear ( 0 , 0 , 1000 , 15 , ANIM_Remove ) ) ;
effect . animation3 = PlayAnimation ( " SwimDiveDown " , CLONK_ANIM_SLOT_Movement , Anim_Linear ( 0 , 0 , GetAnimationLength ( " SwimDiveDown " ) , 40 , ANIM_Loop ) , Anim_Const ( 500 ) , effect . animation2 ) ;
2011-10-08 17:04:57 +00:00
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 ;
2017-11-23 20:16:12 +00:00
effect . yoff = 0 ;
2011-10-08 17:04:57 +00:00
}
if ( iSpeed )
{
var iRot = Angle ( - Abs ( GetXDir ( ) ) , GetYDir ( ) ) ;
effect . rot + = BoundBy ( iRot - effect . rot , - 4 , 4 ) ;
}
2017-11-27 20:57:17 +00:00
if ( enter_diving )
{
effect . rot = Max ( 0 , 180 - enter_diving . rot ) ;
}
2011-10-08 17:04:57 +00:00
// 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 ) ) ;
2017-11-23 20:16:12 +00:00
// Adjust graphics position so that it matches the vertices (offset 0 to -5000, with -5000 at 90 degrees or less, while diving down)
var y_adjust = - Sin ( BoundBy ( effect . rot , 90 , 180 ) , 5000 ) ;
effect . yoff + = BoundBy ( y_adjust - effect . yoff , - 100 , 100 ) ;
SetMeshTransformation ( Trans_Translate ( 0 , effect . yoff , 0 ) , CLONK_MESH_TRANSFORM_SLOT_Translation_Dive ) ;
2011-10-08 17:04:57 +00:00
}
}
2017-11-23 20:16:12 +00:00
func FxIntSwimStop ( object target , proplist effect , int reason , temp )
{
if ( temp ) return ;
SetMeshTransformation ( nil , CLONK_MESH_TRANSFORM_SLOT_Translation_Dive ) ;
}
2011-10-08 17:04:57 +00:00
func GetSwimRotation ( )
{
var effect = GetEffect ( " IntSwim " , this ) ;
if ( ! effect ) return 0 ;
return effect . rot * ( - 1 + 2 * ( GetDirection ( ) = = COMD_Right ) ) ;
}
2017-11-27 20:57:17 +00:00
func FxIntDiveJumpTimer ( pTarget , effect , iTime )
{
if ( GetAction ( ) = = " Jump " ) // Calculate the diving entry angle
{
effect . rot = BoundBy ( 150 * GetActTime ( ) / 32 , 0 , 150 ) ;
return FX_OK ;
}
else if ( GetAction ( ) = = " Swim " ) // Diving already?
{
var idle = 0 = = GetComDir ( ) ;
if ( idle & & GetSpeed ( ) < 10 ) // Swim upwards again without player interaction
{
SetComDir ( COMD_Up ) ;
}
if ( idle | | GetActTime ( ) < 2 ) // Leave at least two frames, so that the dive animation can get the correct angle
{
return FX_OK ;
}
}
return FX_Execute_Kill ;
}
2011-10-08 17:04:57 +00:00
/*--
Roll and kneel
2015-08-07 14:12:41 +00:00
When the clonk hits the ground a kneel animation or are roll are performed .
2011-10-08 17:04:57 +00:00
- - */
func Hit ( int iXSpeed , int iYSpeed )
{
2017-06-09 19:43:35 +00:00
HandleRollOnHit ( iXSpeed , iYSpeed ) ;
2015-08-07 14:12:41 +00:00
return _inherited ( iXSpeed , iYSpeed , . . . ) ;
}
func DoKneel ( bool create_dust )
{
var iKneelDownSpeed = 18 ;
SetXDir ( 0 ) ;
SetAction ( " Kneel " ) ;
2015-12-13 21:14:55 +00:00
Sound ( " Clonk::Movement::RustleLand " ) ;
2015-10-11 12:08:14 +00:00
PlayAnimation ( " KneelDown " , CLONK_ANIM_SLOT_Movement , Anim_Linear ( 0 , 0 , GetAnimationLength ( " KneelDown " ) , iKneelDownSpeed , ANIM_Remove ) , Anim_Linear ( 0 , 0 , 1000 , 5 , ANIM_Remove ) ) ;
2015-08-07 14:12:41 +00:00
ScheduleCall ( this , " EndKneel " , iKneelDownSpeed , 1 ) ;
if ( create_dust )
2011-10-08 17:04:57 +00:00
{
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
}
2015-08-07 14:12:41 +00:00
2011-10-08 17:04:57 +00:00
return 1 ;
}
func EndKneel ( )
{
if ( GetAction ( ) ! = " Roll " ) SetAction ( " Walk " ) ;
}
2015-08-07 14:12:41 +00:00
2017-06-09 19:43:35 +00:00
// Handle rolling when hitting the landscape
func HandleRollOnHit ( int iXSpeed , int iYSpeed )
{
if ( this - > IsWalking ( ) & & iYSpeed > 450 )
{
// roll :D
var x_movement = ComDir2XY ( GetComDir ( ) ) [ 0 ] ;
var looking_right = GetDir ( ) = = DIR_Right ;
if ( ( x_movement > 0 & & looking_right ) | | ( x_movement < 0 & & ! looking_right ) )
{
2017-07-28 20:08:19 +00:00
DoRoll ( true ) ;
2017-06-09 19:43:35 +00:00
}
else // Force kneel-down when hitting the ground at high velocity.
2017-07-28 20:08:19 +00:00
{
2017-06-09 19:43:35 +00:00
DoKneel ( true ) ;
2017-07-28 20:08:19 +00:00
}
2017-06-09 19:43:35 +00:00
}
}
2015-08-07 14:12:41 +00:00
// Start a roll into the current direction.
2017-07-28 20:08:19 +00:00
// The parameter should distinguish between
// rolling from a fall, and rolling while
// running, so that you can implement
// custom effects for both version, if desired
func DoRoll ( bool is_falling )
2015-08-07 14:12:41 +00:00
{
SetAction ( " Roll " ) ;
}
// Called when the roll action is started.
func OnStartRoll ( )
2011-10-08 17:04:57 +00:00
{
2011-10-25 22:01:27 +00:00
SetTurnForced ( GetDir ( ) ) ;
2015-12-13 21:14:55 +00:00
Sound ( " Clonk::Movement::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 ;
2015-10-11 12:08:14 +00:00
PlayAnimation ( " KneelRoll " , CLONK_ANIM_SLOT_Movement , 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 ) ;
}
2015-08-07 14:12:41 +00:00
// Called when the roll action is interrupted.
func OnAbortRoll ( )
{
var e = GetEffect ( " Rolling " , this ) ;
if ( e )
RemoveEffect ( nil , this , e ) ;
}
2016-01-02 01:45:43 +00:00
func FxRollingTimer ( object target , effect effect , int timer )
2011-10-08 17:04:57 +00:00
{
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
{
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
}
2015-08-07 14:12:41 +00:00
func FxRollingStop ( object target , proplist effect , int reason , temp )
{
if ( temp & & ! this ) return ;
if ( GetAction ( ) = = " Roll " )
SetAction ( " Walk " ) ;
SetTurnForced ( - 1 ) ;
lAnim . rollDir = nil ;
}
2011-10-08 17:04:57 +00:00
/*--
Digging
The effect just is responsible for the sound and the termination of digging .
- - */
2016-02-07 09:17:47 +00:00
public func StartDigging ( )
2011-10-08 17:04:57 +00:00
{
2016-02-07 09:17:47 +00:00
if ( ! GetEffect ( " IntDig " , this ) )
2011-10-08 17:04:57 +00:00
AddEffect ( " IntDig " , this , 1 , 1 , this ) ;
}
2016-02-07 09:17:47 +00:00
public func StopDigging ( )
2011-10-08 17:04:57 +00:00
{
2016-02-07 09:17:47 +00:00
if ( GetAction ( ) ! = " Dig " )
RemoveEffect ( " IntDig " , this ) ;
2011-10-08 17:04:57 +00:00
}
2016-02-07 09:17:47 +00:00
public func GetDiggingAnimation ( )
2011-10-08 17:04:57 +00:00
{
2016-02-07 09:17:47 +00:00
var dig_effect = GetEffect ( " IntDig " , this ) ;
if ( dig_effect )
return dig_effect . animation ;
return ;
}
public func FxIntDigStart ( object target , effect fx , int temp )
{
if ( temp )
return FX_OK ;
fx . animation = PlayAnimation ( " Dig " , CLONK_ANIM_SLOT_Movement , 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
2015-12-13 21:14:55 +00:00
Sound ( " Clonk::Action::Dig::Dig? " ) ;
2011-10-08 17:04:57 +00:00
// Set proper turn type
SetTurnType ( 0 ) ;
2016-02-07 09:17:47 +00:00
return FX_OK ;
2011-10-08 17:04:57 +00:00
}
2016-02-07 09:17:47 +00:00
public func FxIntDigTimer ( object target , effect fx , int time )
2011-10-08 17:04:57 +00:00
{
2016-02-07 09:17:47 +00:00
if ( time % 36 = = 0 )
2011-10-08 17:04:57 +00:00
{
2015-12-13 21:14:55 +00:00
Sound ( " Clonk::Action::Dig::Dig? " ) ;
2011-10-08 17:04:57 +00:00
}
2016-02-07 09:17:47 +00:00
if ( time = = 18 | | time > = 36 )
2011-10-08 17:04:57 +00:00
{
2016-02-07 09:17:47 +00:00
var no_dig = true ;
for ( var shovel in FindObjects ( Find_ID ( Shovel ) , Find_Container ( this ) ) )
if ( shovel - > IsDigging ( ) )
no_dig = false ;
if ( no_dig )
2011-10-08 17:04:57 +00:00
{
SetAction ( " Walk " ) ;
SetComDir ( COMD_Stop ) ;
2016-02-07 09:17:47 +00:00
return FX_Execute_Kill ;
2011-10-08 17:04:57 +00:00
}
}
2016-02-07 09:17:47 +00:00
return FX_OK ;
2011-10-08 17:04:57 +00:00
}
/*--
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
2013-11-03 14:32:30 +00:00
if ( ( GetProcedure ( ) = = " WALK " | | GetAction ( ) = = " Jump " | | GetAction ( ) = = " WallJump " | | GetAction ( ) = = " Dive " )
2011-10-08 17:04:57 +00:00
& & this - > ~ HasHandAction ( ) )
{
if ( throwAngle < 180 ) SetDir ( DIR_Right ) ;
else SetDir ( DIR_Left ) ;
//SetAction("Throw");
this - > ~ SetHandAction ( 1 ) ; // Set hands ocupied
2016-05-13 15:13:34 +00:00
AddEffect ( " IntThrow " , this , 1 , 1 , this , nil , target , throwAngle ) ;
2011-10-08 17:04:57 +00:00
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 ;
2016-01-29 04:47:53 +00:00
PlayAnimation ( " ThrowArms " , CLONK_ANIM_SLOT_Arms , Anim_Linear ( 0 , 0 , GetAnimationLength ( " ThrowArms " ) , iThrowTime ) ) ;
2011-10-08 17:04:57 +00:00
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 ( )
{
2015-10-11 12:08:14 +00:00
PlayAnimation ( " Dead " , CLONK_ANIM_SLOT_Death , Anim_Linear ( 0 , 0 , GetAnimationLength ( " Dead " ) , 20 , ANIM_Hold ) , Anim_Linear ( 0 , 0 , 1000 , 5 , ANIM_Remove ) ) ;
2011-10-08 17:04:57 +00:00
// 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 ) ;
2015-10-11 12:08:14 +00:00
PlayAnimation ( " Tumble " , CLONK_ANIM_SLOT_Movement , Anim_Linear ( 0 , 0 , GetAnimationLength ( " Tumble " ) , 20 , ANIM_Loop ) , Anim_Linear ( 0 , 0 , 1000 , 5 , ANIM_Remove ) ) ;
2011-10-08 17:04:57 +00:00
// 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
2015-10-11 12:08:14 +00:00
PlayAnimation ( " Push " , CLONK_ANIM_SLOT_Movement , Anim_AbsX ( 0 , 0 , GetAnimationLength ( " Push " ) , 20 ) , Anim_Linear ( 0 , 0 , 1000 , 5 , ANIM_Remove ) ) ;
2011-10-08 17:04:57 +00:00
// 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
2015-10-11 12:08:14 +00:00
PlayAnimation ( " OnRope " , CLONK_ANIM_SLOT_Movement , Anim_Linear ( 0 , 0 , GetAnimationLength ( " OnRope " ) , 20 , ANIM_Loop ) , Anim_Linear ( 0 , 0 , 1000 , 5 , ANIM_Remove ) ) ;
2011-10-08 17:04:57 +00:00
// 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
2015-10-11 12:08:14 +00:00
PlayAnimation ( " Eat " , CLONK_ANIM_SLOT_Arms , Anim_Linear ( 0 , 0 , GetAnimationLength ( " Eat " ) , 45 , ANIM_Remove ) , Anim_Linear ( 0 , 0 , 1000 , 5 , ANIM_Remove ) ) ;
2011-10-08 21:28:49 +00:00
// Update carried items
UpdateAttach ( ) ;
2012-06-08 14:17:42 +00:00
}