Rework of Carry Heavy Objects: Pick up with Shift.

No more interaction necessary!
shapetextures
Clonkonaut 2015-09-10 01:17:44 +02:00
parent 24e18bf7e2
commit b4905b2bcf
10 changed files with 248 additions and 370 deletions

View File

@ -303,9 +303,8 @@ public func Definition(proplist def)
SetProperty("PictureTransformation", Trans_Mul(Trans_Translate(0, 1000, 0), Trans_Rotate(-40, 1, 0, 0), Trans_Rotate(20, 0, 0, 1)), def); SetProperty("PictureTransformation", Trans_Mul(Trans_Translate(0, 1000, 0), Trans_Rotate(-40, 1, 0, 0), Trans_Rotate(20, 0, 0, 1)), def);
} }
local Collectible = false; local Collectible = true;
local Touchable = 2;
local Name = "$Name$"; local Name = "$Name$";
local Description = "$Description$"; local Description = "$Description$";
local Rebuy = true; local Rebuy = true;
local ContactIncinerate = 2; local ContactIncinerate = 2;

View File

@ -225,6 +225,7 @@ func Launch(int angle, object clonk)
SetR(angle); SetR(angle);
SetVelocity(angle,60); SetVelocity(angle,60);
this.Collectible = false;
} }
func DoFireworks() func DoFireworks()
@ -273,8 +274,7 @@ func Definition(def) {
DefaultPicTransform(); DefaultPicTransform();
} }
local Collectible = false; local Collectible = true;
local Touchable = 2;
local Name = "$Name$"; local Name = "$Name$";
local Description = "$Description$"; local Description = "$Description$";
local UsageHelp = "$UsageHelp$"; local UsageHelp = "$UsageHelp$";

View File

@ -74,6 +74,5 @@ func Hit()
local Name = "$Name$"; local Name = "$Name$";
local Description = "$Description$"; local Description = "$Description$";
local Collectible = false; local Collectible = true;
local ContainBlast = true; local ContainBlast = true;
local Touchable = 2;

View File

@ -142,8 +142,7 @@ func AlchemyProcessTime() { return 100; }
/*-- Properties --*/ /*-- Properties --*/
local Collectible = false; local Collectible = true;
local Touchable = 2;
local Name = "$Name$"; local Name = "$Name$";
local Description = "$Description$"; local Description = "$Description$";
local Rebuy = true; local Rebuy = true;

View File

@ -1,278 +1,20 @@
/*-- /*--
Carry-Heavy Library Carry-Heavy Library
Author: Ringwaul Author: Ringwaul, Clonkonaut
Special circumstances for when the clonk is carrying heavy objects To be included by all objects that are heavy and need carrying by two hands.
--*/ --*/
local liftheavy_carrier; /* Status */
public func IsCarryHeavy() { return true; } public func IsCarryHeavy() { return true; }
public func IsInvInteract() { return true; } public func GetDropDescription() { return Format("$TxtPutDown$", GetName()); }
/* Visibility */
public func GetCarryMode(clonk) { return CARRY_BothHands; } public func GetCarryMode(clonk) { return CARRY_BothHands; }
public func GetCarryBone() { return "main"; }
public func GetCarrySpecial(clonk) public func GetCarrySpecial(clonk)
{ {
var action = clonk->~GetAction(); var action = clonk->~GetAction();
if(action == "Scale" || action == "Hangle" || action == "Push") if(action == "Scale" || action == "Hangle" || action == "Push")
return "skeleton_body"; return "skeleton_body";
}
public func GetDropDescription() { return Format("$TxtPutDown$", GetName()); }
public func Grabbed(object clonk, bool grab)
{
if(grab)
{
// clonk already carries something. Don't pick up
if(clonk->~IsCarryingHeavy())
{
CustomMessage("$TxtHandsFull$", clonk, clonk->GetController(), 0, 0, 0xff0000);
//Let go of object
clonk->SetAction("Walk");
//Clear animation
clonk->SetCommand("None");
return false;
}
// do pickup stuff enter stuff whatever
liftheavy_carrier = clonk;
Enter(liftheavy_carrier);
DoLift();
}
}
private func DoLift(bool forceEnter)
{
if(!liftheavy_carrier)
return;
if(!IsCarryingHeavy(liftheavy_carrier))
AddEffect("IntLiftHeavy", liftheavy_carrier, 1, 1, this, nil, forceEnter);
}
// ------------------
// Lifting the object
// ------------------
static const lift_heavy_time = 60;
func FxIntLiftHeavyStart(object clonk, proplist effect, bool tmp, bool forceEnter)
{
if(tmp) return;
if(!clonk) return -1;
if(Contained() != clonk) return -1;
// if the clonk is inside, we can skip the animation
if(clonk->Contained())
{
AddEffect("IntCarryHeavy", clonk, 1, 1, this);
return -1;
}
//Stop the clonk from moving, and tell the clonk's control library
//it now has a hand action
clonk->SetTurnForced(clonk->GetDir());
clonk->SetHandAction(1);
clonk->SetAction("Stand");
//Attach the mesh of the object. It is not displayed normally because the
//hands are told they have an action in the next few lines
effect.mesh = clonk->AttachMesh(this->GetID(), "pos_tool1", "main", this->~GetCarryTransform(clonk));
//Play the animation of the clonk picking up the object
effect.anim = clonk->PlayAnimation("CarryArmsPickup", 10, Anim_Linear(0,0,clonk->GetAnimationLength("CarryArmsPickup"), lift_heavy_time, ANIM_Remove), Anim_Const(1000));
effect.doExit = !forceEnter; // default: true
}
func FxIntLiftHeavyTimer(object clonk, proplist effect, int timer)
{
//If the clonk moves, he'll stop lifting and drop the object
if(timer < lift_heavy_time)
{
//from 0 to 40, the clonk will drop the object if he moves
if(timer < lift_heavy_time - 20)
{
if(clonk->GetAction() != "Stand" || clonk->IsJumping() || Abs(clonk->GetXDir()) > 0)
{
return -1;
}
}
//There is a small over-shot at the end the player may mistake for finished lifting
//So stop the clonk from moving during 40-60
else
{
if(clonk->GetAction() != "Stand")
{
//If the clonk moved when he was disabled from doing so (or jumped), cancel lifting
return -1;
}
}
}
//When the clonk has finished lifting, remove movement-restrictions and add carry effect
if(timer >= lift_heavy_time)
{
AddEffect("IntCarryHeavy", clonk, 1, 1, this);
// don't exit the object
effect.doExit = false;
return -1;
}
// we got moved out during lifting
if(Contained() != clonk)
return -1;
}
func FxIntLiftHeavyStop(object clonk, proplist effect, int reason, bool tmp)
{
if(tmp) return;
// drop the object
if(effect.doExit && Contained()==clonk) // only if still in the clonk
Exit();
clonk->DetachMesh(effect.mesh);
clonk->StopAnimation(effect.anim);
UndoLift(clonk);
}
// -------------------
// Carrying the object
// -------------------
func FxIntCarryHeavyTimer(object clonk, proplist effect, int timer)
{
//Delete this effect if not contained in the clonk anymore
if(Contained() != clonk) return -1;
}
// ------------------
// Dropping the object
// ------------------
func FxIntDropHeavyStart(object clonk, proplist effect, bool tmp)
{
if(tmp) return;
if(!clonk) return -1;
if(Contained() != clonk) return -1;
if(clonk->GetEffect("IntCarryHeavy"))
clonk->RemoveEffect("IntCarryHeavy");
// if the clonk is inside, we don't play the animation
if(clonk->Contained())
return -1;
clonk->SetTurnForced(clonk->GetDir());
clonk->SetHandAction(1);
clonk->SetAction("Stand");
//Stop the clonk if he is moving
if(clonk->GetXDir() != 0) clonk->SetXDir();
//Attach the mesh of the object. It is not displayed normally because the
//hands are told they have an action in the next few lines
effect.mesh = clonk->AttachMesh(this->GetID(), "pos_tool1", "main", this->~GetCarryTransform(clonk));
//Play the animation of the clonk setting down the object
effect.anim = clonk->PlayAnimation("CarryArmsPickup", 10, Anim_Linear(clonk->GetAnimationLength("CarryArmsPickup"),clonk->GetAnimationLength("CarryArmsPickup"),0, lift_heavy_time, ANIM_Remove), Anim_Const(1000));
//liftheavy_anim = clonk->PlayAnimation("CarryArmsSetdown", 10, Anim_Linear(0,0,clonk->GetAnimationLength("CarryArmsSetdown"), lift_heavy_time, ANIM_Remove), Anim_Const(1000));
}
func FxIntDropHeavyTimer(object clonk, proplist effect, int timer)
{
//Clonk was interrupted?
if(clonk->GetAction() != "Stand")
{
return -1;
}
// animation finished?
if(timer >= lift_heavy_time)
return -1;
// we got moved out during lifting
if(Contained() != clonk)
return -1;
}
func FxIntDropHeavyStop(object clonk, proplist effect, int reason, bool tmp)
{
if(tmp) return;
clonk->DetachMesh(effect.mesh);
clonk->StopAnimation(effect.anim);
if(clonk->GetAction() != "Stand")
Exit();
else
{
var dir = 1;
if(clonk->GetDir() == DIR_Left)
dir = -1;
// Set down at barrel position
Exit(6*dir, 9);
}
UndoLift(clonk);
}
func Drop()
{
if(liftheavy_carrier == nil)
return;
if(!IsCarryingHeavy(liftheavy_carrier))
return;
AddEffect("IntDropHeavy", liftheavy_carrier, 1, 1, this);
}
func UndoLift(object clonk)
{
//allow the clonk to turn again
clonk->SetTurnForced(-1);
clonk->SetHandAction(0);
if(clonk->GetAction() == "Stand") clonk->SetAction("Walk");
}
func IsCarryingHeavy(object clonk)
{
//Is the clonk in the process of lifting or carrying a heavy object?
if(GetEffect("IntLiftHeavy", clonk)) return 1;
if(GetEffect("IntCarryHeavy", clonk)) return 2;
if(GetEffect("IntDropHeavy", clonk)) return 3;
return false;
}
func Entrance(object obj)
{
// tell the carrier to carryheavy if it got moved into it by script
if(!liftheavy_carrier)
if(obj->~GetCarryHeavy() == this)
{
liftheavy_carrier = obj;
if(obj->GetAction() == "Walk" && !obj->Contained())
DoLift(true);
else
AddEffect("IntCarryHeavy",obj, 1, 1, this);
}
return _inherited(obj, ...);
}
func Departure(object obj)
{
if(!liftheavy_carrier)
return;
liftheavy_carrier = nil;
return _inherited(obj, ...);
}
// Cannot pickup other carryheavy objects (is that really what you intended, Ringwaul?)
func RejectCollect(id collectid, object collect)
{
if(collect->~IsCarryHeavy()) return true;
return _inherited(collectid, collect, ...);
} }

View File

@ -1,2 +1 @@
TxtHandsFull=Hände sind voll!
TxtPutDown=%s abstellen TxtPutDown=%s abstellen

View File

@ -1,2 +1 @@
TxtHandsFull=Hands are full!
TxtPutDown=Put %s down TxtPutDown=Put %s down

View File

@ -1,11 +1,49 @@
/** /**
CarryHeavyControl CarryHeavyControl
Handles the control of carry-heavy-objects as inventory objects. Handles the control of carry-heavy-objects as inventory objects.
Depends on Clonk Control and Inventory
*/ */
local carryheavy; // object beeing carried with carryheavy local lib_carryheavy_obj; // object beeing carried with carryheavy
public func GetCarryHeavy() { return lib_carryheavy_obj; }
public func IsCarryingHeavy() { return lib_carryheavy_obj != nil; }
/* Overloads for Inventory */
// Check if we can carry a carry heavy object
protected func RejectCollect(id objid, object obj)
{
// Carry heavy only gets picked up if none held already
if(this.inventory.force_collection && obj->~IsCarryHeavy())
{
// collection of that object magically disabled?
if(GetEffect("NoCollection", obj)) return true;
if(IsCarryingHeavy())
{
CustomMessage("$TxtHandsFull$", this, this->GetController(), 0, 0, 0xff0000);
return true;
}
return false;
}
return _inherited(objid,obj,...);
}
// Start visual effect when picking up carry heavy objects
public func Collection2(object obj)
{
if(obj->~IsCarryHeavy()) // we can assume that we don't have a carryheavy object yet. If we do, Scripters are to blame.
{
CarryHeavy(obj);
DoLiftCarryHeavy(obj);
return true;
}
return _inherited(obj,...);
}
// overload for carry-heavy
public func GetHandItem(int i) public func GetHandItem(int i)
{ {
// carrying a carry heavy item always returns said item. (he holds it in both hands, after all!) // carrying a carry heavy item always returns said item. (he holds it in both hands, after all!)
@ -14,7 +52,6 @@ public func GetHandItem(int i)
return _inherited(i, ...); return _inherited(i, ...);
} }
// overload for carry-heavy
public func SetHandItemPos(int hand, int inv) public func SetHandItemPos(int hand, int inv)
{ {
// can't use anything except carryheavy if carrying heavy object. // can't use anything except carryheavy if carrying heavy object.
@ -23,20 +60,8 @@ public func SetHandItemPos(int hand, int inv)
return _inherited(hand, inv, ...); return _inherited(hand, inv, ...);
} }
func Collection2(object obj) // Delete internal variables
{ public func Ejection(object obj)
// carryheavy object gets special treatment
if(obj->~IsCarryHeavy()) // we can assume that we don't have a carryheavy object yet. If we do, Scripters are to blame.
{
if(obj != GetCarryHeavy())
CarryHeavy(obj);
return true;
}
return _inherited(obj,...);
}
func Ejection(object obj)
{ {
// carry heavy special treatment // carry heavy special treatment
if(obj == GetCarryHeavy()) if(obj == GetCarryHeavy())
@ -44,10 +69,11 @@ func Ejection(object obj)
StopCarryHeavy(); StopCarryHeavy();
return true; return true;
} }
_inherited(obj,...); return _inherited(obj,...);
} }
func ContentsDestruction(object obj) // Delete internal variables
public func ContentsDestruction(object obj)
{ {
// check if it was carryheavy // check if it was carryheavy
if(obj == GetCarryHeavy()) if(obj == GetCarryHeavy())
@ -55,96 +81,24 @@ func ContentsDestruction(object obj)
StopCarryHeavy(); StopCarryHeavy();
} }
_inherited(obj, ...); return _inherited(obj, ...);
} }
protected func RejectCollect(id objid, object obj) /* Overloads for Clonk Control */
{
// collection of that object magically disabled?
if(GetEffect("NoCollection", obj)) return true;
// Carry heavy only gets picked up if none held already
if(obj->~IsCarryHeavy())
{
if(IsCarryingHeavy())
return true;
else
{
return false;
}
}
//No collection if the clonk is carrying a 'carry-heavy' object
// todo: does this still make sense with carry heavy not beeing in inventory and new inventory in general?
if(IsCarryingHeavy() && !this.inventory.force_collection) return true; // this.inventory.force_collection declared in Inventory.ocd
return _inherited(objid,obj,...);
}
// overload function from ClonkControl
public func GetExtraInteractions() public func GetExtraInteractions()
{ {
var functions = _inherited(...); var functions = _inherited(...);
// dropping carry heavy // dropping carry heavy
if(IsCarryingHeavy() && GetAction() == "Walk") if(IsCarryingHeavy() && GetAction() == "Walk")
{ {
var ch = GetCarryHeavy(); var ch = GetCarryHeavy();
PushBack(functions, {Fn = "Drop", Description=ch->GetDropDescription(), Object=ch, IconName="", IconID=Icon_LetGo, Priority=1}); PushBack(functions, {Fn = "DropCarryHeavy", Description=ch->GetDropDescription(), Object=this, IconName="", IconID=Icon_LetGo, Priority=1});
} }
return functions; return functions;
} }
/* Carry heavy stuff */
/** Tells the clonk that he is carrying the given carry heavy object */
public func CarryHeavy(object target)
{
if(!target)
return;
// actually.. is it a carry heavy object?
if(!target->~IsCarryHeavy())
return;
// only if not carrying a heavy objcet already
if(IsCarryingHeavy())
return;
carryheavy = target;
if(target->Contained() != this)
target->Enter(this);
// Update attach stuff
this->~OnSlotFull();
return true;
}
/** Drops the carried heavy object, if any */
public func DropCarryHeavy()
{
// only if actually possible
if(!IsCarryingHeavy())
return;
GetCarryHeavy()->Drop();
StopCarryHeavy();
return true;
}
// Internal function to clear carryheavy-status
private func StopCarryHeavy()
{
if(!IsCarryingHeavy())
return;
carryheavy = nil;
this->~OnSlotEmpty();
}
public func GetCarryHeavy() { return carryheavy; }
public func IsCarryingHeavy() { return carryheavy != nil; }
public func ObjectControl(int plr, int ctrl, int x, int y, int strength, bool repeat, bool release) public func ObjectControl(int plr, int ctrl, int x, int y, int strength, bool repeat, bool release)
{ {
if (!this) if (!this)
@ -160,4 +114,189 @@ public func ObjectControl(int plr, int ctrl, int x, int y, int strength, bool re
return true; return true;
} }
} }
}
/* Carry heavy stuff */
/** Tells the clonk that he is carrying the given carry heavy object */
public func CarryHeavy(object target)
{
if(!target)
return;
// actually.. is it a carry heavy object?
if(!target->~IsCarryHeavy())
return;
// only if not carrying a heavy objcet already
if(IsCarryingHeavy())
return;
lib_carryheavy_obj = target;
if(target->Contained() != this)
target->Enter(this);
// Update attach stuff
this->~OnSlotFull();
return true;
}
/** Drops the carried heavy object, if any */
public func DropCarryHeavy()
{
// only if actually possible
if(!IsCarryingHeavy())
return;
DoDropCarryHeavy(GetCarryHeavy());
StopCarryHeavy();
return true;
}
// Internal function to clear carryheavy-status
private func StopCarryHeavy()
{
if(!IsCarryingHeavy())
return;
lib_carryheavy_obj = nil;
this->~OnSlotEmpty();
}
/* Lifting / dropping effect */
local lib_carryheavy_lifttime = 45;
private func DoLiftCarryHeavy(object obj)
{
if (!obj || !obj->~IsCarryHeavy())
return;
if (obj->Contained() != this)
return;
// If inside something or not walking, skip the animation
if (Contained() || GetAction() != "Walk")
return;
AddEffect("IntLiftHeavy", this, 1, 1, this, nil, obj);
}
private func DoDropCarryHeavy(object obj)
{
if (!obj || !obj->~IsCarryHeavy())
return;
if (obj->Contained() != this)
return;
// If inside something or not walking, skip the animation
if (Contained() || GetAction() != "Walk")
return;
AddEffect("IntDropHeavy", this, 1, 1, this, nil, obj);
}
private func FxIntLiftHeavyStart(object me, proplist effect, bool tmp, object to_lift)
{
//Stop the clonk from moving, and tell the clonk's control library
//it now has a hand action
me->SetTurnForced(GetDir());
me->SetHandAction(1);
SetAction("Stand");
//Stop the clonk if he is moving
if(GetXDir() != 0) SetXDir();
//Attach the mesh of the object. It is not displayed normally because the
//hands are told they have an action in the next few lines
effect.mesh = AttachMesh(to_lift, "pos_tool1", to_lift->GetCarryBone(), to_lift->~GetCarryTransform(this));
//Play the animation of the clonk picking up the object
effect.anim = PlayAnimation("CarryArmsPickup", 10, Anim_Linear(0,0, GetAnimationLength("CarryArmsPickup"), lib_carryheavy_lifttime, ANIM_Remove), Anim_Const(1000));
effect.obj = to_lift;
}
private func FxIntLiftHeavyTimer(object me, proplist effect, int time)
{
//If the clonk moves, he'll stop lifting and drop the object
if(time < lib_carryheavy_lifttime)
{
// first 2/3 of time, clonk will drop the object
if(time < lib_carryheavy_lifttime * 2 / 3)
{
if(GetAction() != "Stand" || me->IsJumping() || Abs(GetXDir()) > 0)
{
effect.fail = true;
return FX_Execute_Kill;
}
}
else
{
if(GetAction() != "Stand")
return FX_Execute_Kill;
}
}
//When the clonk has finished lifting, remove movement-restrictions
if(time >= lib_carryheavy_lifttime)
return FX_Execute_Kill;
// Object got moved out during lifting
if(!effect.obj || effect.obj->Contained() != this)
return FX_Execute_Kill;
}
private func FxIntLiftHeavyStop(object me, proplist effect)
{
// If failed, drop the object
if(effect.fail && effect.obj && effect.obj->Contained() == this)
effect.obj->Exit(0,9);
DetachMesh(effect.mesh);
StopAnimation(effect.anim);
me->SetTurnForced(-1);
me->SetHandAction(0);
if(GetAction() == "Stand") SetAction("Walk");
}
private func FxIntDropHeavyStart(object me, proplist effect, bool tmp, object to_lift)
{
if(GetEffect("IntCarryHeavy"))
RemoveEffect("IntCarryHeavy", this, nil, true);
//Stop the clonk from moving, and tell the clonk's control library
//it now has a hand action
me->SetTurnForced(GetDir());
me->SetHandAction(1);
SetAction("Stand");
//Stop the clonk if he is moving
if(GetXDir() != 0) SetXDir();
//Attach the mesh of the object. It is not displayed normally because the
//hands are told they have an action in the next few lines
effect.mesh = AttachMesh(to_lift, "pos_tool1", to_lift->GetCarryBone(), to_lift->~GetCarryTransform(this));
//Play the animation of the clonk setting down the object
effect.anim = PlayAnimation("CarryArmsPickup", 10, Anim_Linear(GetAnimationLength("CarryArmsPickup"), GetAnimationLength("CarryArmsPickup"), 0, lib_carryheavy_lifttime, ANIM_Remove), Anim_Const(1000));
effect.obj = to_lift;
}
private func FxIntDropHeavyTimer(object me, proplist effect, int time)
{
if (time >= lib_carryheavy_lifttime)
return FX_Execute_Kill;
if (GetAction() != "Stand")
return FX_Execute_Kill;
if (!effect.obj)
return FX_Execute_Kill;
if (effect.obj->Contained() != this)
return FX_Execute_Kill;
}
private func FxIntDropHeavyStop(object me, proplist effect)
{
// Drop the object
if(effect.obj && effect.obj->Contained() == this)
effect.obj->Exit(0,9);
DetachMesh(effect.mesh);
StopAnimation(effect.anim);
me->SetTurnForced(-1);
me->SetHandAction(0);
if(GetAction() == "Stand") SetAction("Walk");
} }

View File

@ -0,0 +1 @@
TxtHandsFull=Hände sind voll!

View File

@ -0,0 +1 @@
TxtHandsFull=Hands are full!