forked from Mirrors/openclonk
collect objects solely via CTRL now
The player can also choose which object to collect by holding CTRL and navigating left/right.Controls
parent
d1ceafea16
commit
e9a69c4252
|
@ -23,54 +23,20 @@ func Construction()
|
|||
return _inherited(...);
|
||||
}
|
||||
|
||||
// Called by other libraries and objects when the Clonk has forcefully dropped (not thrown) an object. Collection will be disabled for some time.
|
||||
// Called by other libraries and objects when the Clonk has forcefully dropped (not thrown) an object.
|
||||
func OnDropped(object obj)
|
||||
{
|
||||
// An object has just left this one. Make sure we don't immediately collect it again.
|
||||
// Note that this can also happen for objects which were not originally contained in this one but in a subcontainer (f.e. items in HasExtraSlot objects).
|
||||
AddEffect("NoCollectDelay", this, 1, 36 * 1, this, nil, obj, GetX(), GetY());
|
||||
return _inherited(obj, ...);
|
||||
}
|
||||
|
||||
func FxNoCollectDelayStart(object target, proplist effect, temp, object item, int x, int y)
|
||||
{
|
||||
if (temp) return;
|
||||
effect.x = x;
|
||||
effect.y = y;
|
||||
effect.item = item;
|
||||
}
|
||||
|
||||
func FxNoCollectDelayTimer(object target, proplist effect, int time)
|
||||
{
|
||||
if (!effect.item) return -1;
|
||||
if (ObjectDistance(this, effect.item) > 20) return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Checks if we just dropped the object and thus can not collect it again.
|
||||
func HadJustDroppedObject(object obj)
|
||||
{
|
||||
var current_x = GetX(), current_y = GetY();
|
||||
var i = 0, e = nil;
|
||||
while (e = GetEffect("NoCollectDelay", this, i++))
|
||||
{
|
||||
if (e.item == obj) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
func RejectCollect(id objid, object obj)
|
||||
{
|
||||
var rejected = _inherited(objid,obj,...);
|
||||
var rejected = _inherited(objid, obj, ...);
|
||||
if(rejected) return rejected;
|
||||
|
||||
// check if the hand slot is full.
|
||||
// If the overloaded Collect() is called, this check will be skipped.
|
||||
// Also handle collection of contained objects (chests, other Clonks) more relaxed.
|
||||
if (!this.inventory.force_collection && !obj->Contained())
|
||||
if (this->GetHandItem(0) || HadJustDroppedObject(obj))
|
||||
return true;
|
||||
|
||||
// Allow collection only if called via clonk->Collect, to prevent picking up stuff on the ground.
|
||||
// Make an exception for containers, though.
|
||||
if (!this.inventory.force_collection && !obj->Contained()) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -91,6 +57,46 @@ public func ObjectControl(int plr, int ctrl, int x, int y, int strength, bool re
|
|||
return true;
|
||||
}
|
||||
|
||||
// Begin picking up objects.
|
||||
if (ctrl == CON_PickUp && !release)
|
||||
{
|
||||
BeginPickingUp();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Switching pickup object or finish pickup?
|
||||
if (this.inventory.is_picking_up)
|
||||
{
|
||||
// Stop picking up.
|
||||
if (ctrl == CON_PickUpNext_Stop)
|
||||
{
|
||||
this.inventory.pickup_item = nil;
|
||||
EndPickingUp();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Finish picking up (aka "collect").
|
||||
if (ctrl == CON_PickUp && release)
|
||||
{
|
||||
EndPickingUp();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Switch left/right through objects.
|
||||
var dir = nil;
|
||||
if (ctrl == CON_PickUpNext_Left) dir = -1;
|
||||
else if (ctrl == CON_PickUpNext_Right) dir = 1;
|
||||
|
||||
if (dir != nil)
|
||||
{
|
||||
var item = FindNextPickupObject(this.inventory.pickup_item, dir);
|
||||
if (item)
|
||||
SetNextPickupItem(item);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// shift inventory
|
||||
var inventory_shift = 0;
|
||||
if (ctrl == CON_InventoryShiftForward) inventory_shift = 1;
|
||||
|
@ -149,6 +155,151 @@ public func ObjectControl(int plr, int ctrl, int x, int y, int strength, bool re
|
|||
return inherited(plr, ctrl, x, y, strength, repeat, release, ...);
|
||||
}
|
||||
|
||||
private func FxIntHighlightItemStart(object target, effect fx, temp, object item)
|
||||
{
|
||||
if (temp) return;
|
||||
fx.item = item;
|
||||
|
||||
fx.dummy = CreateObject(Dummy, item->GetX() - GetX(), item->GetY() - GetY(), GetOwner());
|
||||
fx.dummy.ActMap =
|
||||
{
|
||||
Attach =
|
||||
{
|
||||
Name = "Attach",
|
||||
Procedure = DFA_ATTACH,
|
||||
FaceBase = 1
|
||||
}
|
||||
};
|
||||
fx.dummy.Visibility = VIS_Owner;
|
||||
fx.dummy.Plane = item.Plane + 1;
|
||||
fx.dummy->Message("@%s", item->GetName());
|
||||
|
||||
// Center dummy!
|
||||
fx.dummy->SetVertexXY(0, item->GetVertex(0, VTX_X), item->GetVertex(0, VTX_Y));
|
||||
fx.dummy->SetAction("Attach", item);
|
||||
|
||||
fx.width = item->GetDefWidth();
|
||||
fx.height = item->GetDefHeight();
|
||||
|
||||
var particle =
|
||||
{
|
||||
Prototype = Particles_Flash(),
|
||||
Size = Max(fx.width, fx.height),
|
||||
Attach = ATTACH_Front
|
||||
};
|
||||
fx.dummy->CreateParticle("SphereSpark", 0, 0, 0, 0, 20, particle, 1);
|
||||
|
||||
// And smaller sparks during the effect.
|
||||
fx.particles =
|
||||
{
|
||||
Prototype = particle,
|
||||
Size = PV_Linear(2, 0),
|
||||
Rotation = PV_Random(360),
|
||||
Stretch = PV_Linear(0, 4000),
|
||||
};
|
||||
|
||||
fx.width /= 2;
|
||||
fx.height /= 2;
|
||||
}
|
||||
|
||||
private func FxIntHighlightItemTimer(object target, effect fx, int time)
|
||||
{
|
||||
if (!fx.dummy) return -1;
|
||||
if (!fx.item) return -1;
|
||||
if (ObjectDistance(this, fx.item) > 20) return -1;
|
||||
if (Contained(fx.item)) return -1;
|
||||
|
||||
fx.dummy->CreateParticle("StarSpark", PV_Random(-fx.width, fx.width), PV_Random(-fx.height, fx.height), 0, 0, 10, fx.particles, 2);
|
||||
}
|
||||
|
||||
private func FxIntHighlightItemStop(object target, effect fx, int reason, temp)
|
||||
{
|
||||
if (temp) return;
|
||||
if (fx.dummy) fx.dummy->RemoveObject();
|
||||
if (!this) return;
|
||||
if (fx.item == this.inventory.pickup_item)
|
||||
this.inventory.pickup_item = nil;
|
||||
}
|
||||
|
||||
private func SetNextPickupItem(object to)
|
||||
{
|
||||
// Clear all old markers.
|
||||
var e = nil;
|
||||
while (e = GetEffect("IntHighlightItem", this))
|
||||
RemoveEffect(nil, this, e);
|
||||
// And set & mark new one.
|
||||
this.inventory.pickup_item = to;
|
||||
if (to)
|
||||
AddEffect("IntHighlightItem", this, 1, 2, this, nil, to);
|
||||
}
|
||||
|
||||
private func FindNextPickupObject(object start_from, int x_dir)
|
||||
{
|
||||
if (!start_from) start_from = this;
|
||||
var sort = Sort_Func("Library_ClonkInventoryControl_Sort_Priority", start_from->GetX());
|
||||
var objects = FindObjects(Find_Distance(20), Find_Category(C4D_Object), Find_NoContainer(), Find_Func("GetProperty", "Collectible"), sort);
|
||||
var len = GetLength(objects);
|
||||
// Find object next to the current one.
|
||||
var index = GetIndexOf(objects, start_from);
|
||||
if (index != nil)
|
||||
{
|
||||
index = index + x_dir;
|
||||
if (index < 0) index += len;
|
||||
index = index % len;
|
||||
}
|
||||
else index = 0;
|
||||
|
||||
if (index >= len) return nil;
|
||||
var next = objects[index];
|
||||
if (next == start_from) return nil;
|
||||
return next;
|
||||
}
|
||||
|
||||
private func BeginPickingUp()
|
||||
{
|
||||
this.inventory.is_picking_up = true;
|
||||
|
||||
var dir = -1;
|
||||
if (GetDir() == DIR_Right) dir = 1;
|
||||
var obj = FindNextPickupObject(this, dir);
|
||||
if (obj)
|
||||
SetNextPickupItem(obj);
|
||||
}
|
||||
|
||||
private func EndPickingUp()
|
||||
{
|
||||
this.inventory.is_picking_up = false;
|
||||
|
||||
if (this.inventory.pickup_item)
|
||||
{
|
||||
// Remember stuff for a possible message - the item might have removed itself later.
|
||||
var item = this.inventory.pickup_item;
|
||||
var x = item->GetX();
|
||||
var y = item->GetY();
|
||||
var name = item->GetName();
|
||||
// Try to collect the item.
|
||||
Collect(item);
|
||||
|
||||
// If anything happened, assume collection.
|
||||
if (!item || item->Contained())
|
||||
{
|
||||
var message = CreateObject(FloatingMessage, AbsX(x), AbsY(y), GetOwner());
|
||||
message.Visibility = VIS_Owner;
|
||||
message->SetMessage(name);
|
||||
message->SetYDir(-10);
|
||||
message->FadeOut(1, 20);
|
||||
}
|
||||
}
|
||||
|
||||
var e = nil;
|
||||
while (e = GetEffect("IntHighlightItem", this))
|
||||
{
|
||||
RemoveEffect(nil, this, e);
|
||||
}
|
||||
|
||||
this.inventory.pickup_item = nil;
|
||||
}
|
||||
|
||||
// used in Inventory.ocd
|
||||
public func SetHandItemPos(int hand, int inv)
|
||||
{
|
||||
|
|
|
@ -445,7 +445,7 @@ protected func RejectCollect(id objid, object obj)
|
|||
if(GetEffect("NoCollection", obj)) return true;
|
||||
|
||||
// Only handle extra-slot objects if the object was not dropped on purpose.
|
||||
if (this.inventory.force_collection || !this->HadJustDroppedObject(obj))
|
||||
if (this.inventory.force_collection)
|
||||
{
|
||||
// try to stuff obj into an object with an extra slot
|
||||
for(var i=0; Contents(i); ++i)
|
||||
|
|
|
@ -519,3 +519,15 @@ global func MouseDragDrop(int plr, object source, object target)
|
|||
Log("%s%d, %s, %i, %d, %d, %d, %v, %v", rs, plr, GetPlayerControlName(ctrl), spec_id, x,y,strength, repeat, release);
|
||||
return r;
|
||||
}*/
|
||||
|
||||
/*
|
||||
This is used by Library_ClonkInventoryControl and needs to be a global function (in a non-appendto).
|
||||
This function returns the priority of an object when selecting an object to pick up.
|
||||
*/
|
||||
global func Library_ClonkInventoryControl_Sort_Priority(int x_position)
|
||||
{
|
||||
// Objects are sorted by position, preferring the direction of the key press.
|
||||
var priority_x = GetX() - x_position;
|
||||
if (priority_x < 0) priority_x += 1000;
|
||||
return priority_x;
|
||||
}
|
|
@ -162,7 +162,26 @@
|
|||
GUIName=$CON_Drop$
|
||||
GUIDesc=$CON_Drop_Desc$
|
||||
Hold=1
|
||||
|
||||
|
||||
# Picking up objects on the ground.
|
||||
[ControlDef]
|
||||
Identifier=PickUp
|
||||
GUIName=$CON_PickUp$
|
||||
GUIDesc=$CON_PickUp_Desc$
|
||||
Hold=1
|
||||
|
||||
[ControlDef]
|
||||
Identifier=PickUpNext_Left
|
||||
GUIName=None
|
||||
|
||||
[ControlDef]
|
||||
Identifier=PickUpNext_Right
|
||||
GUIName=None
|
||||
|
||||
[ControlDef]
|
||||
Identifier=PickUpNext_Stop
|
||||
GUIName=None
|
||||
|
||||
# Hotkeys (Inventory)
|
||||
|
||||
[ControlDef]
|
||||
|
@ -566,13 +585,34 @@
|
|||
[Assignment]
|
||||
Key=E
|
||||
Control=Contents
|
||||
Group=1
|
||||
GUIGroup=1
|
||||
|
||||
[Assignment]
|
||||
Key=Q
|
||||
Control=QuickSwitch
|
||||
GUIGroup=50
|
||||
|
||||
[Assignment]
|
||||
Key=Ctrl+LeftControl
|
||||
Control=PickUp
|
||||
GUIGroup=50
|
||||
|
||||
[Assignment]
|
||||
Key=Ctrl+CON_Left
|
||||
Control=PickUpNext_Left
|
||||
|
||||
[Assignment]
|
||||
Key=Ctrl+CON_Right
|
||||
Control=PickUpNext_Right
|
||||
|
||||
[Assignment]
|
||||
Key=Ctrl+CON_Up
|
||||
Control=PickUpNext_Stop
|
||||
|
||||
[Assignment]
|
||||
Key=Ctrl+CON_Down
|
||||
Control=PickUpNext_Stop
|
||||
|
||||
[Assignment]
|
||||
Key=Mouse1Wheel1Up
|
||||
GUIGroup=50
|
||||
|
|
|
@ -30,6 +30,9 @@ CON_Throw_Desc=Werfen des Gegenstandes in der Hand in die anvisierte Richtung.
|
|||
CON_UseAlt=Use
|
||||
CON_UseAlt_Desc=Use the item in the hand alternatively.
|
||||
|
||||
CON_PickUp=Aufheben
|
||||
CON_PickUp_Desc=Hebt ein Objekt in der Nähe auf.
|
||||
|
||||
CON_Hotkey1=Hotkey 1
|
||||
CON_Hotkey2=Hotkey 2
|
||||
CON_Hotkey3=Hotkey 3
|
||||
|
|
|
@ -31,6 +31,9 @@ CON_Throw_Desc=Throw the item in the hand into the aimed direction.
|
|||
CON_UseAlt=Use
|
||||
CON_UseAlt_Desc=Use the item in the hand alternatively.
|
||||
|
||||
CON_PickUp=Pick Up
|
||||
CON_PickUp_Desc=Pick up an object near you.
|
||||
|
||||
CON_Hotkey1=Hotkey 1
|
||||
CON_Hotkey2=Hotkey 2
|
||||
CON_Hotkey3=Hotkey 3
|
||||
|
|
Loading…
Reference in New Issue