2012-01-02 02:14:57 +00:00
/**
Constructor
Library for objects which are able to construct structures .
@ author Maikel
*/
public func IsConstructor ( ) { return true ; }
public func ControlUseStart ( object clonk , int x , int y )
{
// Is the clonk able to construct?
if ( clonk - > GetProcedure ( ) ! = " WALK " )
{
clonk - > CancelUse ( ) ;
return true ;
}
// Is the clonk at an construction site?
var structure = FindObject ( Find_Category ( C4D_Structure ) , Find_Or ( Find_Distance ( 20 ) , Find_AtPoint ( ) ) , Find_Layer ( GetObjectLayer ( ) ) ) ;
if ( structure )
{
2012-03-29 20:08:54 +00:00
/* if (structure->GetCon() < 100)
2012-01-02 02:14:57 +00:00
{
Construct ( clonk , structure ) ;
return true ;
2012-03-29 20:08:54 +00:00
} */
2012-01-02 02:14:57 +00:00
if ( structure - > GetDamage ( ) > 0 )
{
Repair ( clonk , structure ) ;
return true ;
}
}
// Otherwise create a menu with possible structures to build.
clonk - > CreateConstructionMenu ( this ) ;
clonk - > CancelUse ( ) ;
return true ;
}
public func HoldingEnabled ( ) { return true ; }
public func ControlUseHolding ( object clonk , int x , int y )
{
// Is the clonk still able to construct?
if ( clonk - > GetProcedure ( ) ! = " WALK " )
{
clonk - > CancelUse ( ) ;
return true ;
}
// Is the clonk still at an construction site?
var structure = FindObject ( Find_Category ( C4D_Structure ) , Find_Or ( Find_Distance ( 20 ) , Find_AtPoint ( ) ) , Find_Layer ( GetObjectLayer ( ) ) ) ;
if ( structure )
{
2012-03-29 20:08:54 +00:00
/*
2012-01-02 02:14:57 +00:00
if ( structure - > GetCon ( ) < 100 )
{
Construct ( clonk , structure ) ;
return true ;
2012-03-29 20:08:54 +00:00
} */
2012-01-02 02:14:57 +00:00
if ( structure - > GetDamage ( ) > 0 )
{
Repair ( clonk , structure ) ;
return true ;
}
}
clonk - > CancelUse ( ) ;
return true ;
}
private func Construct ( object clonk , object structure )
{
// Look for missing components.
var structure_id = structure - > GetID ( ) ;
var con = structure - > GetCon ( ) ;
var comp , index = 0 ;
2012-01-08 14:22:26 +00:00
var can_construct = true ;
2012-01-02 02:14:57 +00:00
while ( comp = structure - > GetComponent ( nil , index ) )
{
var max_amount = GetComponent ( comp , nil , nil , structure_id ) ;
2012-01-08 14:22:26 +00:00
// Try to transfer components from constructing clonk to the structure.
for ( var i = 0 ; i < max_amount - structure - > GetComponent ( comp ) ; i + + )
2012-01-02 02:14:57 +00:00
{
var content = FindObject ( Find_Container ( clonk ) , Find_ID ( comp ) ) ;
2012-01-08 14:22:26 +00:00
if ( content )
2012-01-02 02:14:57 +00:00
{
2012-01-08 14:22:26 +00:00
clonk - > Message ( " Used {{%i}} " , comp ) ;
content - > RemoveObject ( ) ;
structure - > SetComponent ( comp , structure - > GetComponent ( comp ) + 1 ) ;
2012-01-02 02:14:57 +00:00
}
2012-01-08 14:22:26 +00:00
}
// Check if there now is enough material for current con, if so the construction can continue.
if ( 100 * structure - > GetComponent ( comp ) / max_amount < con )
can_construct = false ;
index + + ;
}
// Continue construction if possible.
if ( can_construct )
{
structure - > DoCon ( 1 ) ;
clonk - > Message ( " Constructing %d% " , structure - > GetCon ( ) ) ;
}
// Otherwise show missing construction materials.
else
{
ShowConstructionMaterial ( clonk , structure ) ;
clonk - > CancelUse ( ) ;
}
return ;
}
private func ShowConstructionMaterial ( object clonk , object structure )
{
var mat_msg = " Construction needs " ;
var structure_id = structure - > GetID ( ) ;
var comp , index = 0 ;
while ( comp = structure - > GetComponent ( nil , index ) )
{
var current_amount = structure - > GetComponent ( comp ) ;
var max_amount = GetComponent ( comp , nil , nil , structure_id ) ;
mat_msg = Format ( " %s %dx{{%i}} " , mat_msg , Max ( 0 , max_amount - current_amount ) , comp ) ;
2012-01-02 02:14:57 +00:00
index + + ;
}
2012-01-08 14:22:26 +00:00
clonk - > Message ( mat_msg ) ;
2012-01-02 02:14:57 +00:00
return ;
}
private func Repair ( object clonk , object structure )
{
}
/** Gives a list of ids of the players knowledge.
*/
public func GetConstructionPlans ( int plr )
{
var construction_plans = [ ] ;
var construct_id , index = 0 ;
while ( construct_id = GetPlrKnowledge ( plr , 0 , index + + , C4D_Structure ) )
construction_plans [ index - 1 ] = construct_id ;
return construction_plans ;
}
2012-03-27 18:10:44 +00:00
/* Construction preview */
func ShowConstructionPreview ( object clonk , id structure_id )
{
AddEffect ( " ControlConstructionPreview " , clonk , 1 , 0 , this , nil , structure_id , clonk ) ;
SetPlayerControlEnabled ( clonk - > GetOwner ( ) , CON_Aim , true ) ;
return true ;
}
func FxControlConstructionPreviewStart ( object clonk , effect , int temp , id structure_id , object clonk )
{
if ( temp ) return ;
effect . structure = structure_id ;
2012-05-08 18:27:24 +00:00
effect . flipable = ! structure_id - > ~ NoConstructionFlip ( ) ;
2012-03-27 18:10:44 +00:00
effect . preview = CreateObject ( ConstructionPreviewer , AbsX ( clonk - > GetX ( ) ) , AbsY ( clonk - > GetY ( ) ) , clonk - > GetOwner ( ) ) ;
effect . preview - > Set ( structure_id , clonk ) ;
}
// Called by Control2Effect
func FxControlConstructionPreviewControl ( object clonk , effect , int ctrl , int x , int y , int strength , bool repeat , bool release )
{
if ( ctrl ! = CON_Aim )
{
2012-03-28 17:39:00 +00:00
// CON_Use is accept
2012-03-27 18:10:44 +00:00
if ( ctrl = = CON_Use )
2012-04-21 23:00:41 +00:00
CreateConstructionSite ( clonk , effect . structure , AbsX ( effect . preview - > GetX ( ) ) , AbsY ( effect . preview - > GetY ( ) + effect . preview . dimension_y / 2 ) , effect . preview . direction , effect . preview . stick_to ) ;
2012-03-28 17:39:00 +00:00
// movement is allowed
2012-05-08 18:27:24 +00:00
else if ( IsMovementControl ( ctrl ) )
2012-03-28 17:39:00 +00:00
return false ;
2012-04-16 15:31:38 +00:00
// Flipping
2012-05-08 18:27:24 +00:00
// this is actually realized twice. Once as an Extra-Interaction in the clonk, and here. We don't want the Clonk to get any non-movement controls though, so we handle it here too.
// (yes, this means that actionbar-hotkeys wont work for it. However clicking the button will.)
else if ( IsInteractionControl ( ) )
2012-04-16 15:31:38 +00:00
{
if ( release )
effect . preview - > Flip ( ) ;
return true ;
}
2012-03-28 17:39:00 +00:00
// everything else declines
2012-03-27 18:10:44 +00:00
RemoveEffect ( " ControlConstructionPreview " , clonk , effect ) ;
return true ;
}
2012-03-28 17:39:00 +00:00
2012-03-27 18:10:44 +00:00
effect . preview - > Reposition ( x , y ) ;
return true ;
}
2012-04-14 21:16:17 +00:00
func FxControlConstructionPreviewStop ( object clonk , effect , int reason , bool temp )
2012-03-27 18:10:44 +00:00
{
if ( temp ) return ;
effect . preview - > RemoveObject ( ) ;
2012-04-14 21:16:17 +00:00
SetPlayerControlEnabled ( clonk - > GetOwner ( ) , CON_Aim , false ) ;
2012-03-27 18:10:44 +00:00
}
/* Construction */
2012-04-21 23:00:41 +00:00
func CreateConstructionSite ( object clonk , id structure_id , int x , int y , int dir , object stick_to )
2012-01-02 02:14:57 +00:00
{
// Only when the clonk is standing and outdoors
if ( clonk - > GetAction ( ) ! = " Walk " )
return false ;
2012-04-21 23:00:41 +00:00
if ( clonk - > Contained ( ) )
2012-01-02 02:14:57 +00:00
return false ;
// Check if the building can be build here
2012-03-27 18:10:44 +00:00
if ( structure_id - > ~ RejectConstruction ( x , y , clonk ) )
2012-01-02 02:14:57 +00:00
return false ;
2012-04-02 21:49:39 +00:00
if ( ! CheckConstructionSite ( structure_id , x , y ) )
{
2012-04-14 22:29:38 +00:00
CustomMessage ( " Can't build here! " , this , clonk - > GetOwner ( ) , nil , nil , RGB ( 255 , 0 , 0 ) ) ; // todo: stringtable
2012-04-02 21:49:39 +00:00
return false ;
}
2012-04-14 22:29:38 +00:00
// intersection-check with all other construction sites... bah
for ( var other_site in FindObjects ( Find_ID ( ConstructionSite ) ) )
{
if ( ! ( other_site - > GetLeftEdge ( ) > GetX ( ) + x + structure_id - > GetDefWidth ( ) / 2 | |
other_site - > GetRightEdge ( ) < GetX ( ) + x - structure_id - > GetDefWidth ( ) / 2 | |
other_site - > GetTopEdge ( ) > GetY ( ) + y + structure_id - > GetDefHeight ( ) / 2 | |
other_site - > GetBottomEdge ( ) < GetY ( ) + y - structure_id - > GetDefHeight ( ) / 2 ) )
{
CustomMessage ( Format ( " Construction blocked by %s " , other_site - > GetName ( ) ) , this , clonk - > GetOwner ( ) , nil , nil , RGB ( 255 , 0 , 0 ) ) ; // todo: stringtable
return false ;
}
}
2012-04-02 21:49:39 +00:00
// Set owner for CreateConstruction
SetOwner ( clonk - > GetOwner ( ) ) ;
2012-04-16 15:31:38 +00:00
// Save direction so the structure can ask for it
this . constructionDirection = dir ;
2012-04-02 21:49:39 +00:00
// Create construction site
var site ;
site = CreateObject ( ConstructionSite , x , y , Contained ( ) - > GetOwner ( ) ) ;
2012-04-21 23:00:41 +00:00
site - > Set ( structure_id , dir , stick_to ) ;
2012-04-02 21:49:39 +00:00
//if(!(site = CreateConstruction(structure_id, x, y, Contained()->GetOwner(), 1, 1, 1)))
//return false;
2012-03-29 20:08:54 +00:00
// check for material
var comp , index = 0 ;
2012-04-02 21:49:39 +00:00
var mat ;
var w = structure_id - > GetDefWidth ( ) + 10 ;
var h = structure_id - > GetDefHeight ( ) + 10 ;
2012-03-29 20:08:54 +00:00
while ( comp = GetComponent ( nil , index , nil , structure_id ) )
{
// find material
2012-04-02 21:49:39 +00:00
var count_needed = GetComponent ( comp , nil , nil , structure_id ) ;
index + + ;
2012-03-29 20:08:54 +00:00
2012-04-02 21:49:39 +00:00
mat = CreateArray ( ) ;
2012-03-29 20:08:54 +00:00
// 1. look for stuff in the clonk
2012-04-02 21:49:39 +00:00
mat [ 0 ] = FindObjects ( Find_ID ( comp ) , Find_Container ( clonk ) ) ;
2012-03-29 20:08:54 +00:00
// 2. look for stuff lying around
2012-04-02 21:49:39 +00:00
mat [ 1 ] = clonk - > FindObjects ( Find_ID ( comp ) , Find_NoContainer ( ) , Find_InRect ( - w / 2 , - h / 2 , w , h ) ) ;
2012-03-29 20:08:54 +00:00
// 3. look for stuff in nearby lorries/containers
2012-04-14 21:16:17 +00:00
var i = 2 ;
for ( var cont in clonk - > FindObjects ( Find_Or ( Find_Func ( " IsLorry " ) , Find_Func ( " IsContainer " ) ) , Find_InRect ( - w / 2 , - h / 2 , w , h ) ) )
mat [ i ] = FindObjects ( Find_ID ( comp ) , Find_Container ( cont ) ) ;
2012-04-02 21:49:39 +00:00
// move it
for ( var mat2 in mat )
{
for ( var o in mat2 )
2012-03-29 20:08:54 +00:00
{
2012-04-02 21:49:39 +00:00
if ( count_needed < = 0 )
break ;
o - > Exit ( ) ;
o - > Enter ( site ) ;
count_needed - - ;
2012-03-29 20:08:54 +00:00
}
}
}
2012-04-02 21:49:39 +00:00
2012-03-29 20:08:54 +00:00
2012-01-02 02:14:57 +00:00
// Message
2012-04-02 21:49:39 +00:00
clonk - > Message ( " $TxtConstructions$ " , structure_id - > GetName ( ) ) ;
2012-01-02 02:14:57 +00:00
return true ;
}
2012-04-16 15:31:38 +00:00
// Returns the desired direction for a construction
func GetConstructionDirection ( )
{
return this . constructionDirection ;
2012-04-14 22:29:38 +00:00
}