inventory hud (unfinished), acceleration during FLIGHT and WALK, old HUD (DrawCursorInfo) commented out
|
@ -19,9 +19,6 @@
|
|||
<text>Tötet den höchstrangigen Clonk des dritten Spielers. (Die Zählung beginnt mit 0)</text>
|
||||
</example>
|
||||
</examples>
|
||||
<related>
|
||||
<funclink>GetCaptain</funclink>
|
||||
</related>
|
||||
</func>
|
||||
<author>jwk</author><date>April 2002</date>
|
||||
</funcs>
|
||||
|
|
|
@ -1,23 +1,30 @@
|
|||
#strict 2
|
||||
|
||||
/*
|
||||
Per-Player Controller
|
||||
Per-Player Controller (HUD)
|
||||
Author: Newton
|
||||
|
||||
Creates and removes the crew selectors as well as reorders them and
|
||||
manages when a crew changes it's controller
|
||||
manages when a crew changes it's controller. Responsible for taking
|
||||
care of the action (inventory) bar.
|
||||
*/
|
||||
|
||||
|
||||
// TODO -
|
||||
// following callbacks missing:
|
||||
// OnClonkUnRecruitment - clonk gets de-recruited from a crew
|
||||
// ...? - entire player is eliminated
|
||||
|
||||
local actionbar;
|
||||
|
||||
protected func Construction()
|
||||
{
|
||||
actionbar = CreateArray();
|
||||
|
||||
// find all clonks of this crew which do not have a selector yet (and can have one)
|
||||
for(var i=GetCrewCount(GetOwner())-1; i >= 0; --i)
|
||||
{
|
||||
var crew = GetCrew(GetOwner(),i);
|
||||
if(!(crew->HUDSelectable())) continue;
|
||||
if(!(crew->HUDAdapter())) continue;
|
||||
|
||||
var sel = crew->GetSelector();
|
||||
if(!sel)
|
||||
|
@ -33,7 +40,7 @@ protected func OnClonkRecruitment(object clonk, int plr)
|
|||
// not my business
|
||||
if(plr != GetOwner()) return;
|
||||
|
||||
if(!(clonk->HUDSelectable())) return;
|
||||
if(!(clonk->HUDAdapter())) return;
|
||||
|
||||
// if the clonk already has a hud, it means that he belonged to another
|
||||
// crew. So we need another handling here in this case.
|
||||
|
@ -61,7 +68,7 @@ protected func OnClonkDeath(object clonk, int killer)
|
|||
{
|
||||
if(clonk->GetController() != GetOwner()) return;
|
||||
|
||||
if(!(clonk->HUDSelectable())) return;
|
||||
if(!(clonk->HUDAdapter())) return;
|
||||
|
||||
// notify the hud
|
||||
clonk->GetSelector()->CrewGone();
|
||||
|
@ -70,6 +77,81 @@ protected func OnClonkDeath(object clonk, int killer)
|
|||
ReorderCrewSelectors();
|
||||
}
|
||||
|
||||
// call from HUDAdapter (Clonk)
|
||||
public func OnCrewSelection(object obj, bool deselect)
|
||||
{
|
||||
|
||||
// selected
|
||||
if(!deselect)
|
||||
{
|
||||
// if several clonks were selected:
|
||||
// only the cursor is of interest
|
||||
var cursor = GetCursor(GetOwner());
|
||||
//Log("cursor: %s",cursor->GetName());
|
||||
//if(obj != cursor) return;
|
||||
// TODO: what if two clonks are selected? Which clonk gets the actionbar?
|
||||
|
||||
// fill actionbar
|
||||
|
||||
// inventory
|
||||
var i;
|
||||
for(i = 0; i < obj->MaxContentsCount(); ++i)
|
||||
{
|
||||
ActionButton(obj,i);
|
||||
actionbar[i]->SetObject(obj->GetItem(i),ACTIONTYPE_INVENTORY,i);
|
||||
actionbar[i]->UpdateSelectionStatus();
|
||||
}
|
||||
// make rest invisible
|
||||
for(; i < GetLength(actionbar); ++i)
|
||||
{
|
||||
// we don't have to remove them all the time, no?
|
||||
if(actionbar[i])
|
||||
actionbar[i]["Visibility"] = VIS_None;
|
||||
}
|
||||
|
||||
// and start effect to monitor vehicles and structures...
|
||||
// TODO
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
|
||||
// call from HUDAdapter (Clonk)
|
||||
public func OnSelectionChanged(int old, int new)
|
||||
{
|
||||
// update both old and new
|
||||
actionbar[old]->UpdateSelectionStatus();
|
||||
actionbar[new]->UpdateSelectionStatus();
|
||||
}
|
||||
|
||||
private func ActionButton(object forClonk, int i)
|
||||
{
|
||||
var size = ACBT->GetDefWidth();
|
||||
var spacing = 12 + size;
|
||||
|
||||
// don't forget the spacings between inventory - vehicle,structure
|
||||
var extra = 0;
|
||||
if(forClonk->MaxContentsCount() <= i) extra = 80;
|
||||
|
||||
var bt = actionbar[i];
|
||||
// no object yet... create it
|
||||
if(!bt)
|
||||
{
|
||||
bt = CreateObject(ACBT,0,0,GetOwner());
|
||||
}
|
||||
|
||||
bt->SetPosition(64 + i * spacing + extra, -16 - size/2);
|
||||
|
||||
if(i+1 == 10) bt->SetHotkey(0);
|
||||
else if(i+1 < 10) bt->SetHotkey(i+1);
|
||||
|
||||
bt->SetCrew(forClonk);
|
||||
|
||||
actionbar[i] = bt;
|
||||
}
|
||||
|
||||
private func CreateSelectorFor(object clonk)
|
||||
{
|
||||
var selector = CreateObject(CSLR,10,10,-1);
|
||||
|
@ -85,16 +167,16 @@ public func ReorderCrewSelectors()
|
|||
var j = 0;
|
||||
for(var i=GetCrewCount(GetOwner())-1; i >= 0; --i)
|
||||
{
|
||||
var spacing = 12;
|
||||
var crew = GetCrew(GetOwner(),i);
|
||||
var sel = crew->GetSelector();
|
||||
if(sel)
|
||||
{
|
||||
sel->SetPosition(32 + j * (CSLR->GetDefWidth() + spacing) + CSLR->GetDefWidth()/2, 16+CSLR->GetDefHeight()/2);
|
||||
if(j+1 == 10) sel->SetHotkey(0);
|
||||
else sel->SetHotkey(j+1);
|
||||
else if(j+1 < 10) sel->SetHotkey(j+1);
|
||||
}
|
||||
|
||||
var spacing = 12;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,11 +2,13 @@
|
|||
|
||||
/*
|
||||
Progress-Bar element
|
||||
Author: Newton
|
||||
|
||||
This object can show an unlimited amount of progress bars in different
|
||||
locations, sizes and colors. Using this basic funcionality, one could create
|
||||
floating health bars attached to clonks or include the bars as layers into
|
||||
(HUD) objects.
|
||||
This object is used by the crew selector.
|
||||
*/
|
||||
|
||||
local offsx, offsy, layer, width, height;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
/*
|
||||
Crew selector HUD
|
||||
Author: Newton
|
||||
|
||||
For each crew member, one of these HUD elements exist in the top bar.
|
||||
It shows the rank, health, breath and magic bars as well as the title
|
||||
|
@ -98,8 +99,6 @@ public func SetCrew(object c)
|
|||
UpdateSelectionStatus();
|
||||
|
||||
this["Visibility"] = VIS_Owner;
|
||||
|
||||
//ScheduleCall(0,"SetCrew",1,0,c);
|
||||
}
|
||||
|
||||
public func SetHotkey(int num)
|
||||
|
@ -128,6 +127,8 @@ public func UpdateController()
|
|||
if(!crew) return;
|
||||
// visibility
|
||||
SetOwner(crew->GetController());
|
||||
// name
|
||||
SetName(crew->GetName());
|
||||
}
|
||||
|
||||
public func UpdateSelectionStatus()
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
[DefCore]
|
||||
id=ACBT
|
||||
Version=4,9,5
|
||||
Category=C4D_StaticBack | C4D_IgnoreFoW | C4D_Foreground | C4D_Parallax | C4D_MouseSelect
|
||||
Width=64
|
||||
Height=64
|
||||
Offset=-32,-32
|
After Width: | Height: | Size: 152 B |
After Width: | Height: | Size: 5.3 KiB |
After Width: | Height: | Size: 5.3 KiB |
After Width: | Height: | Size: 4.4 KiB |
After Width: | Height: | Size: 4.5 KiB |
|
@ -0,0 +1,2 @@
|
|||
DE:Auswählen
|
||||
US:Select
|
|
@ -0,0 +1,198 @@
|
|||
#strict 2
|
||||
|
||||
/*
|
||||
Object selector HUD
|
||||
Author: Newton
|
||||
|
||||
For each inventory item (and each vehicle, house etc on the same pos)
|
||||
one of this objects exists in the bottom bar. If clicked, the associated
|
||||
object is selected (inventory item is selected, vehicle is grabbed
|
||||
or ungrabbed, house is entered or exited...).
|
||||
|
||||
HUD elements are passive, they don't update their status by themselves
|
||||
but rely on the clonk to update their status.
|
||||
|
||||
This object works only for crew members that included the standard clonk
|
||||
controls (see Libraries.c4d/ClonkControl.c4d)
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
usage of layers:
|
||||
-----------------
|
||||
layer 0 - unused
|
||||
layer 1 - title
|
||||
layer 2 - select-marker
|
||||
|
||||
layer 12 - hotkey
|
||||
|
||||
*/
|
||||
|
||||
// needs to be notified when:
|
||||
|
||||
// inventory changes:
|
||||
// clonk collects something, clonk drops/throws/looses(removeobject) something,
|
||||
// clonk changes order of something
|
||||
|
||||
// vehicles etc:
|
||||
// moves by vehicles or structures...
|
||||
|
||||
// general:
|
||||
// something gets selected/unselected
|
||||
|
||||
local isSelected, crew, hotkey, myobject, inventory_pos, actiontype;
|
||||
|
||||
static const ACTIONTYPE_INVENTORY = 0;
|
||||
static const ACTIONTYPE_VEHICLE = 1;
|
||||
static const ACTIONTYPE_STRUCTURE = 2;
|
||||
|
||||
protected func Construction()
|
||||
{
|
||||
_inherited();
|
||||
|
||||
isSelected = false;
|
||||
hotkey = false;
|
||||
myobject = nil;
|
||||
|
||||
// parallaxity
|
||||
this["Parallaxity"] = [0,0];
|
||||
|
||||
// visibility
|
||||
this["Visibility"] = VIS_None;
|
||||
}
|
||||
|
||||
public func MouseSelection(int plr)
|
||||
{
|
||||
if(!crew) return false;
|
||||
// invisible...
|
||||
if(this["Visibility"] != VIS_Owner) return false;
|
||||
|
||||
// object is in inventory
|
||||
if(actiontype == ACTIONTYPE_INVENTORY)
|
||||
{
|
||||
crew->SelectItem(inventory_pos);
|
||||
return true;
|
||||
}
|
||||
|
||||
// no object
|
||||
if(!myobject) return false;
|
||||
|
||||
// object is a pushable vehicle
|
||||
if(actiontype == ACTIONTYPE_VEHICLE)
|
||||
{
|
||||
var proc = crew->GetProcedure();
|
||||
|
||||
// crew is currently pushing my vehicle -> let go
|
||||
if(proc == "PUSH" && crew->GetActionTarget() == myobject)
|
||||
{
|
||||
PlayerObjectCommand(plr, false, "Ungrab");
|
||||
return true;
|
||||
}
|
||||
// grab
|
||||
else if(proc == "WALK")
|
||||
{
|
||||
PlayerObjectCommand(plr, false, "Grab", myobject);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// object is a building
|
||||
if(actiontype == ACTIONTYPE_STRUCTURE)
|
||||
{
|
||||
// inside? -> exit
|
||||
if(crew->Contained() == myobject)
|
||||
{
|
||||
PlayerObjectCommand(plr, false, "Exit");
|
||||
return true;
|
||||
}
|
||||
// outside? -> enter
|
||||
else if(crew->CanEnter())
|
||||
{
|
||||
PlayerObjectCommand(plr, false, "Enter", myobject);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// TODO: more script choices... Selection-Callbacks for all objects
|
||||
}
|
||||
|
||||
// TODO: update von select nach deselect...
|
||||
|
||||
public func SetObject(object obj, int type, int inv_pos)
|
||||
{
|
||||
actiontype = type;
|
||||
myobject = obj;
|
||||
inventory_pos = inv_pos;
|
||||
|
||||
if(!myobject)
|
||||
{
|
||||
SetGraphics(nil,nil,1);
|
||||
SetName(Format("$LabelSlot$ %d",inventory_pos));
|
||||
}
|
||||
else
|
||||
{
|
||||
SetGraphics(nil,myobject->GetID(),1,GFXOV_MODE_IngamePicture);
|
||||
if(actiontype == nil)
|
||||
{
|
||||
if(myobject->Contained() == crew) actiontype = ACTIONTYPE_INVENTORY;
|
||||
else if(myobject->GetDefGrab()) actiontype = ACTIONTYPE_VEHICLE;
|
||||
else if(myobject->GetDefCoreVal("Entrance","DefCore",2) != nil) actiontype = ACTIONTYPE_STRUCTURE;
|
||||
}
|
||||
|
||||
SetName(myobject->GetName());
|
||||
}
|
||||
}
|
||||
|
||||
public func SetCrew(object c)
|
||||
{
|
||||
crew = c;
|
||||
SetOwner(c->GetOwner());
|
||||
|
||||
this["Visibility"] = VIS_Owner;
|
||||
}
|
||||
|
||||
public func SetHotkey(int num)
|
||||
{
|
||||
if(num < 0 || num > 9)
|
||||
{
|
||||
SetGraphics(nil,nil,12);
|
||||
hotkey = false;
|
||||
return;
|
||||
}
|
||||
|
||||
hotkey = true;
|
||||
var name = Format("%d",num);
|
||||
SetGraphics(name,NUMB,12,GFXOV_MODE_IngamePicture);
|
||||
SetObjDrawTransform(300,0,16000,0,300,-30000, 12);
|
||||
SetClrModulation(RGB(160,0,0),12);
|
||||
}
|
||||
|
||||
public func UpdateSelectionStatus()
|
||||
{
|
||||
// determine...
|
||||
isSelected = false;
|
||||
|
||||
if(actiontype == ACTIONTYPE_VEHICLE)
|
||||
if(crew->GetProcedure() == "PUSH" && crew->GetActionTarget() == myobject)
|
||||
isSelected = true;
|
||||
|
||||
if(actiontype == ACTIONTYPE_STRUCTURE)
|
||||
if(crew->Contained() == myobject)
|
||||
isSelected = true;
|
||||
|
||||
if(actiontype == ACTIONTYPE_INVENTORY)
|
||||
if(crew->GetSelected() == inventory_pos)
|
||||
isSelected = true;
|
||||
|
||||
if(!hotkey) return;
|
||||
|
||||
if(isSelected)
|
||||
{
|
||||
SetClrModulation(RGB(220,0,0),12);
|
||||
SetObjDrawTransform(500,0,16000,0,500,-30000, 12);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetClrModulation(RGB(160,0,0),12);
|
||||
SetObjDrawTransform(300,0,16000,0,300,-30000, 12);
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
LabelSlot=Slot
|
|
@ -0,0 +1 @@
|
|||
LabelSlot=Slot
|
Before Width: | Height: | Size: 124 B After Width: | Height: | Size: 124 B |
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
HUD Adapter
|
||||
Author: Newton
|
||||
|
||||
Clonk-side scripts for the HUD. This object basically redirects the
|
||||
engine callbacks for the clonk to the HUD. All crew members that
|
||||
are to be shown in the HUD have to include this object and return
|
||||
_inherited(); if they overload one of the callbacks used here.
|
||||
|
||||
Requires the ClonkControl.c4d to be included in the clonk too.
|
||||
*/
|
||||
|
||||
local HUDselector, HUDcontroller;
|
||||
|
||||
public func SetSelector(object sel) { HUDselector = sel; }
|
||||
public func GetSelector() { return HUDselector; }
|
||||
|
||||
public func HUDAdapter()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Engine callbacks */
|
||||
|
||||
// bootstrap the hud
|
||||
protected func Recruitment(int iPlr)
|
||||
{
|
||||
HUDcontroller = FindObject(Find_ID(HUDC),Find_Owner(iPlr));
|
||||
if(!HUDcontroller)
|
||||
HUDcontroller = CreateObject(HUDC,10,10,iPlr);
|
||||
return _inherited(...);
|
||||
}
|
||||
|
||||
// calls to the crew selector hud
|
||||
protected func OnPromotion() { if(HUDselector) HUDselector->UpdateRank(); return _inherited(...); }
|
||||
protected func OnEnergyChange() { if(HUDselector) HUDselector->UpdateHealthBar(); return _inherited(...); }
|
||||
protected func OnBreathChange() { if(HUDselector) HUDselector->UpdateBreathBar(); return _inherited(...); }
|
||||
protected func OnMagicEnergyChange() { if(HUDselector) HUDselector->UpdateMagicBar(); return _inherited(...); }
|
||||
|
||||
protected func OnPhysicalChange(string physical, int change, int mode)
|
||||
{
|
||||
|
||||
if(HUDselector)
|
||||
{
|
||||
|
||||
// all physicals are resetted
|
||||
if(!physical)
|
||||
{
|
||||
HUDselector->UpdateHealthBar();
|
||||
HUDselector->UpdateBreathBar();
|
||||
HUDselector->UpdateMagicBar();
|
||||
}
|
||||
else if(physical == "Energy") HUDselector->UpdateHealthBar();
|
||||
else if(physical == "Breath") HUDselector->UpdateBreathBar();
|
||||
else if(physical == "Magic") HUDselector->UpdateMagicBar();
|
||||
}
|
||||
return _inherited(...);
|
||||
}
|
||||
|
||||
// calls to both crew selector and controller
|
||||
|
||||
protected func CrewSelection(bool unselect)
|
||||
{
|
||||
if(HUDselector) HUDselector->UpdateSelectionStatus();
|
||||
if(HUDcontroller) HUDcontroller->OnCrewSelection(this,unselect);
|
||||
return _inherited(...);
|
||||
}
|
||||
|
||||
// call from ClonkControl.c4d (self)
|
||||
public func OnSelectionChanged(int old, int new)
|
||||
{
|
||||
// update selection status in hud
|
||||
if(HUDcontroller) HUDcontroller->OnSelectionChanged(old, new);
|
||||
return _inherited(...);
|
||||
}
|
||||
|
||||
// calls to controller
|
||||
|
||||
protected func Collection2(object obj)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected func Ejection(object obj)
|
||||
{
|
||||
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
|
||||
local selector;
|
||||
|
||||
public func SetSelector(object sel)
|
||||
{
|
||||
selector = sel;
|
||||
}
|
||||
|
||||
public func GetSelector()
|
||||
{
|
||||
return selector;
|
||||
}
|
||||
|
||||
public func HUDSelectable()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// bootstrap the hud
|
||||
protected func Recruitment(int iPlr)
|
||||
{
|
||||
if(!FindObject(Find_ID(HUDC),Find_Owner(iPlr)))
|
||||
CreateObject(HUDC,10,10,iPlr);
|
||||
|
||||
}
|
||||
|
||||
// calls to the crew selector hud
|
||||
protected func OnPromotion() { if(selector) selector->UpdateRank(); }
|
||||
protected func OnEnergyChange() { if(selector) selector->UpdateHealthBar(); }
|
||||
protected func OnBreathChange() { if(selector) selector->UpdateBreathBar(); }
|
||||
protected func OnMagicEnergyChange() { if(selector) selector->UpdateMagicBar(); }
|
||||
protected func CrewSelection(bool unselect) { if(selector) selector->UpdateSelectionStatus(); }
|
||||
protected func OnPhysicalChange(string physical, int change, int mode)
|
||||
{
|
||||
|
||||
if(!selector) return;
|
||||
|
||||
// all physicals are resetted
|
||||
if(!physical)
|
||||
{
|
||||
selector->UpdateHealthBar();
|
||||
selector->UpdateBreathBar();
|
||||
selector->UpdateMagicBar();
|
||||
}
|
||||
else if(physical == "Energy") selector->UpdateHealthBar();
|
||||
else if(physical == "Breath") selector->UpdateBreathBar();
|
||||
else if(physical == "Magic") selector->UpdateMagicBar();
|
||||
}
|
|
@ -1,47 +1,172 @@
|
|||
/*-- Standard controls --*/
|
||||
/*
|
||||
Standard clonk controls
|
||||
Author: Newton
|
||||
|
||||
This object provides handling of the clonk controls including item
|
||||
management and standard throwing behaviour. It should be included
|
||||
into any clonk definition.
|
||||
The controls in System.c4g/PlayerControl.c only provide basic movement
|
||||
handling, namely the movement left, right, up and down. The rest is
|
||||
handled here:
|
||||
Grabbing, ungrabbing, shifting and pushing vehicles into buildings;
|
||||
entering and exiting buildings; throwing, dropping; inventory shifting,
|
||||
hotkey controls and it's callbacks and forwards to script.
|
||||
|
||||
Objects that inherit this object need to return _inherited() in the
|
||||
following callbacks (if defined):
|
||||
Construction, Collection2, Ejection, RejectCollect
|
||||
|
||||
The following callbacks are made to other objects:
|
||||
*Stop
|
||||
*Left, *Right, *Up, *Down
|
||||
*Use, *UseStop, *UseHolding
|
||||
wheras * is 'Contained' if the clonk is contained and otherwise (riding,
|
||||
pushing, to self) it is 'Control'. The item in the inventory only gets
|
||||
the Use*-calls. If the callback is handled, you should return true.
|
||||
|
||||
The inventory management:
|
||||
The objects in the inventory are saved (parallel to Contents()) in the
|
||||
array 'inventory' while the variable 'selected' is the index of the
|
||||
currently selected item. The currently selected item is thus retrieved by
|
||||
'inventory[selected]' or better by using the public function
|
||||
GetSelectedItem();
|
||||
Other functions are MaxContentsCount() (defines the maximum number of
|
||||
contents) and SelectItem(object or index) (selects inventory by index
|
||||
or directly)
|
||||
*/
|
||||
|
||||
// currently selected
|
||||
local selected;
|
||||
|
||||
local inventory;
|
||||
local throwAngle;
|
||||
|
||||
/* ++++++++ Item controls ++++++++++ */
|
||||
|
||||
/* Item limit */
|
||||
|
||||
public func MaxContentsCount() { return 3; }
|
||||
|
||||
/* Item select access*/
|
||||
|
||||
public func Select(int selection)
|
||||
public func SelectItem(selection)
|
||||
{
|
||||
var item = Contents(selected);
|
||||
var item, old;
|
||||
|
||||
// selection is given as integer
|
||||
/*if(GetType(selection) == C4V_Int)
|
||||
{
|
||||
*/
|
||||
// selection didnt change
|
||||
if(selected == selection) return;
|
||||
|
||||
old = selected;
|
||||
item = inventory[selected];
|
||||
selected = selection;
|
||||
/*
|
||||
}
|
||||
|
||||
// ...as object
|
||||
else if(GetType(selection) == C4V_C4Object)
|
||||
{
|
||||
// selection didnt change
|
||||
if(inventory[selected] == selection) return false;
|
||||
|
||||
item = selection;
|
||||
if(item == nil) return;
|
||||
|
||||
// find object
|
||||
var found = false;
|
||||
for(var i=0; i<MaxContentsCount(); ++i)
|
||||
if(inventory[i] == selection)
|
||||
{ selected = i; found = true; break; }
|
||||
if(!found) return;
|
||||
}
|
||||
*/
|
||||
|
||||
// de-select previous (if any)
|
||||
if(item) item->~Deselection(this);
|
||||
|
||||
// select new (if any)
|
||||
selected = selection;
|
||||
var item = Contents(selected);
|
||||
item = inventory[selected];
|
||||
|
||||
// DEBUG
|
||||
var bla = "nothing";
|
||||
if(item) bla = item->~GetName();
|
||||
Message("selected %s (position %d)", this, bla, selected);
|
||||
|
||||
if (!item) return;
|
||||
if (item->~Selection(this)) return;
|
||||
|
||||
Sound("Grab");
|
||||
if(item)
|
||||
if(!item->~Selection(this))
|
||||
Sound("Grab");
|
||||
|
||||
// callback to clonk (self):
|
||||
// OnSelectionChanged(oldslotnumber, newslotnumber)
|
||||
this->~OnSelectionChanged(old, selected);
|
||||
}
|
||||
|
||||
public func GetSelection()
|
||||
public func GetSelected()
|
||||
{
|
||||
return selected;
|
||||
}
|
||||
|
||||
protected func Initialize()
|
||||
public func GetSelectedItem()
|
||||
{
|
||||
return inventory[selected];
|
||||
}
|
||||
|
||||
public func GetItem(int i)
|
||||
{
|
||||
return inventory[i];
|
||||
}
|
||||
|
||||
protected func Construction(object by)
|
||||
{
|
||||
selected = 0;
|
||||
inventory = CreateArray();
|
||||
return _inherited(by);
|
||||
}
|
||||
|
||||
protected func Collection2(object obj)
|
||||
{
|
||||
// into selected area if empty
|
||||
if(!inventory[selected])
|
||||
{
|
||||
inventory[selected] = obj;
|
||||
}
|
||||
// otherwise, next if empty
|
||||
else
|
||||
{
|
||||
for(var i = 1; i < MaxContentsCount(); ++i)
|
||||
{
|
||||
var sel = (selected+i) % MaxContentsCount();
|
||||
if(!inventory[sel])
|
||||
{
|
||||
inventory[sel] = obj;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return _inherited(...);
|
||||
}
|
||||
|
||||
protected func Ejection(object obj)
|
||||
{
|
||||
// find obj in array and delete
|
||||
for(var i = 0; i < MaxContentsCount(); ++i)
|
||||
{
|
||||
if(inventory[i] == obj)
|
||||
{ inventory[i] = nil; break; }
|
||||
}
|
||||
|
||||
_inherited(...);
|
||||
}
|
||||
|
||||
protected func RejectCollect(id objid, object obj)
|
||||
{
|
||||
// check max contents
|
||||
if(ContentsCount() >= MaxContentsCount()) return true;
|
||||
return _inherited(...);
|
||||
}
|
||||
|
||||
|
||||
/* Main control function */
|
||||
public func ObjectControl(int plr, int ctrl, int x, int y, int strength, bool repeat, bool release)
|
||||
{
|
||||
|
@ -70,7 +195,7 @@ public func ObjectControl(int plr, int ctrl, int x, int y, int strength, bool re
|
|||
// building, vehicle, contents control
|
||||
var house = Contained();
|
||||
var vehicle = GetActionTarget();
|
||||
var contents = Contents(selected);
|
||||
var contents = GetSelectedItem();
|
||||
|
||||
if (house)
|
||||
{
|
||||
|
@ -93,11 +218,11 @@ public func ObjectControl(int plr, int ctrl, int x, int y, int strength, bool re
|
|||
if (Control2Script(ctrl, x, y, strength, repeat, release, "Control", contents))
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
if(!vehicle && !house)
|
||||
{
|
||||
if(ctrl == CON_Jump) if(this->~ControlJump(this)) return true;
|
||||
}
|
||||
if(ctrl == CON_Jump) if(this->~ControlJump(this)) return true;
|
||||
}*/
|
||||
|
||||
// everything down from here:
|
||||
// standard controls that are called if not overloaded via script
|
||||
|
@ -117,21 +242,16 @@ public func ObjectControl(int plr, int ctrl, int x, int y, int strength, bool re
|
|||
// Inventory control
|
||||
if (ctrl == CON_NextItem)
|
||||
{
|
||||
var sel = selected;
|
||||
sel++;
|
||||
if (sel >= MaxContentsCount()) sel = 0;
|
||||
|
||||
Select(sel);
|
||||
SelectItem((selected+1) % MaxContentsCount());
|
||||
|
||||
return true;
|
||||
}
|
||||
if (ctrl == CON_PreviousItem)
|
||||
{
|
||||
var sel = selected;
|
||||
sel--;
|
||||
var sel = selected-1;
|
||||
if (sel <= 0) sel = MaxContentsCount()-1;
|
||||
|
||||
Select(sel);
|
||||
SelectItem(sel);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -206,6 +326,15 @@ private func Control2Script(int ctrl, int x, int y, int strength, bool repeat, b
|
|||
return false;
|
||||
}
|
||||
|
||||
// returns true if the clonk is able to enter a building (actionwise)
|
||||
public func CanEnter()
|
||||
{
|
||||
var proc = GetProcedure();
|
||||
if (proc != "WALK" && proc != "SWIM" && proc != "SCALE" &&
|
||||
proc != "HANGLE" && proc != "FLOAT" && proc != "FLIGHT") return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Handles enter and exit
|
||||
private func ObjectControlEntrance(int plr, int ctrl)
|
||||
{
|
||||
|
@ -215,8 +344,7 @@ private func ObjectControlEntrance(int plr, int ctrl)
|
|||
if (ctrl == CON_Enter)
|
||||
{
|
||||
// enter only if... one can
|
||||
if (proc != "WALK" && proc != "SWIM" && proc != "SCALE" &&
|
||||
proc != "HANGLE" && proc != "FLOAT" && proc != "FLIGHT") return false;
|
||||
if (!CanEnter()) return false;
|
||||
|
||||
// a building with an entrance at right position is there?
|
||||
var obj = GetEntranceObject();
|
||||
|
@ -337,7 +465,7 @@ private func ShiftVehicle(int plr, bool back)
|
|||
private func Throwing()
|
||||
{
|
||||
// throw selected inventory
|
||||
var obj = Contents(selected);
|
||||
var obj = inventory[selected];
|
||||
if(!obj) return;
|
||||
|
||||
// parameters...
|
||||
|
@ -373,7 +501,7 @@ public func ControlThrow(object me, int x, int y)
|
|||
// standard throw after all
|
||||
if(!x && !y) return false;
|
||||
|
||||
if(!Contents(selected)) return false;
|
||||
if(!inventory[selected]) return false;
|
||||
|
||||
throwAngle = Angle(0,0,x,y);
|
||||
|
||||
|
|
|
@ -232,9 +232,9 @@ global func ObjectControlUpdateComdir(int plr)
|
|||
ComDir2XY(new_comdir, new_cx, new_cy);
|
||||
var is_handled;
|
||||
var proc = GetProcedure();
|
||||
if (proc == "WALK" || proc == "HANGLE" || proc == "PUSH" || proc == "PULL")
|
||||
if (proc == "WALK" || proc == "HANGLE" || proc == "PUSH" || proc == "PULL" || proc == "FLIGHT")
|
||||
// Only horizontal movement changed actual direction
|
||||
// Also, enfore clear Left/Right commands without leftover Up/Down
|
||||
// Also, enforce clear Left/Right commands without leftover Up/Down
|
||||
// CON_Down is never handled this way, thus forcing a CON_Stop
|
||||
is_handled = (old_cx != new_cx) && !new_cy;
|
||||
else if (proc == "SCALE")
|
||||
|
|
|
@ -31,7 +31,7 @@ const int CornerRange=AttachRange+2;
|
|||
|
||||
extern const FIXED FloatAccel;
|
||||
extern const FIXED HitSpeed1,HitSpeed2,HitSpeed3,HitSpeed4;
|
||||
extern const FIXED WalkAccel,SwimAccel;
|
||||
extern const FIXED WalkAccel,WalkBreak,ScaleAccel,SwimAccel;
|
||||
extern const FIXED FloatFriction;
|
||||
extern const FIXED RotateAccel;
|
||||
|
||||
|
|
|
@ -39,7 +39,10 @@ const FIXED FixFullCircle=itofix(360),FixHalfCircle=FixFullCircle/2;
|
|||
const FIXED FloatFriction=FIXED100(2);
|
||||
const FIXED RotateAccel=FIXED100(20);
|
||||
const FIXED FloatAccel=FIXED100(10);
|
||||
const FIXED WalkAccel=FIXED100(50),SwimAccel=FIXED100(20);
|
||||
const FIXED WalkAccel=FIXED100(10);
|
||||
const FIXED WalkBreak=FIXED100(20);
|
||||
const FIXED ScaleAccel=FIXED100(20);
|
||||
const FIXED SwimAccel=FIXED100(10);
|
||||
const FIXED HitSpeed1=FIXED100(150); // Hit Event
|
||||
const FIXED HitSpeed2=itofix(2); // Cross Check Hit
|
||||
const FIXED HitSpeed3=itofix(6); // Scale disable, kneel
|
||||
|
|
|
@ -3825,18 +3825,25 @@ void C4Object::ExecAction()
|
|||
|
||||
// Handle Default Action Procedure: evaluates Procedure and Action.ComDir
|
||||
// Update xdir,ydir,Action.Dir,attachment,iPhaseAdvance
|
||||
int32_t dir = Action.Dir;
|
||||
FIXED accel = WalkAccel;
|
||||
|
||||
switch (pAction->GetPropertyInt(P_Procedure))
|
||||
{
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
case DFA_WALK:
|
||||
lLimit=ValByPhysical(280, pPhysical->Walk);
|
||||
|
||||
switch (Action.ComDir)
|
||||
{
|
||||
case COMD_Left: case COMD_UpLeft: case COMD_DownLeft:
|
||||
xdir-=WalkAccel; if (xdir<-lLimit) xdir=-lLimit;
|
||||
// breaaak!!!
|
||||
if (dir == DIR_Right) accel = WalkBreak;
|
||||
xdir-=accel; if (xdir<-lLimit) xdir=-lLimit;
|
||||
break;
|
||||
case COMD_Right: case COMD_UpRight: case COMD_DownRight:
|
||||
xdir+=WalkAccel; if (xdir>+lLimit) xdir=+lLimit;
|
||||
if (dir == DIR_Left) accel = WalkBreak;
|
||||
xdir+=accel; if (xdir>+lLimit) xdir=+lLimit;
|
||||
break;
|
||||
case COMD_Stop: case COMD_Up: case COMD_Down:
|
||||
if (xdir<0) xdir+=WalkAccel;
|
||||
|
@ -3845,8 +3852,17 @@ void C4Object::ExecAction()
|
|||
break;
|
||||
}
|
||||
iPhaseAdvance=0;
|
||||
if (xdir<0) { iPhaseAdvance=-fixtoi(xdir*10); SetDir(DIR_Left); }
|
||||
if (xdir>0) { iPhaseAdvance=+fixtoi(xdir*10); SetDir(DIR_Right); }
|
||||
if (xdir<0)
|
||||
{
|
||||
if(dir != DIR_Left) { SetDir(DIR_Left); xdir = -1; }
|
||||
iPhaseAdvance=-fixtoi(xdir*10);
|
||||
}
|
||||
if (xdir>0)
|
||||
{
|
||||
if(dir != DIR_Right) { SetDir(DIR_Right); xdir = 1; }
|
||||
iPhaseAdvance=+fixtoi(xdir*10);
|
||||
}
|
||||
|
||||
Action.t_attach|=CNAT_Bottom;
|
||||
Mobile=1;
|
||||
// object is rotateable? adjust to ground, if in horizontal movement or not attached to the center vertex
|
||||
|
@ -3878,13 +3894,13 @@ void C4Object::ExecAction()
|
|||
switch (ComDir)
|
||||
{
|
||||
case COMD_Up: case COMD_UpRight: case COMD_UpLeft:
|
||||
ydir-=WalkAccel; if (ydir<-lLimit) ydir=-lLimit; break;
|
||||
ydir-=ScaleAccel; if (ydir<-lLimit) ydir=-lLimit; break;
|
||||
case COMD_Down: case COMD_DownRight: case COMD_DownLeft:
|
||||
ydir+=WalkAccel; if (ydir>+lLimit) ydir=+lLimit; break;
|
||||
ydir+=ScaleAccel; if (ydir>+lLimit) ydir=+lLimit; break;
|
||||
case COMD_Left: case COMD_Right: case COMD_Stop:
|
||||
if (ydir<0) ydir+=WalkAccel;
|
||||
if (ydir>0) ydir-=WalkAccel;
|
||||
if ((ydir>-WalkAccel) && (ydir<+WalkAccel)) ydir=0;
|
||||
if (ydir<0) ydir+=ScaleAccel;
|
||||
if (ydir>0) ydir-=ScaleAccel;
|
||||
if ((ydir>-ScaleAccel) && (ydir<+ScaleAccel)) ydir=0;
|
||||
break;
|
||||
}
|
||||
iPhaseAdvance=0;
|
||||
|
@ -3909,20 +3925,20 @@ void C4Object::ExecAction()
|
|||
switch (Action.ComDir)
|
||||
{
|
||||
case COMD_Left: case COMD_UpLeft: case COMD_DownLeft:
|
||||
xdir-=WalkAccel; if (xdir<-lLimit) xdir=-lLimit;
|
||||
xdir-=ScaleAccel; if (xdir<-lLimit) xdir=-lLimit;
|
||||
break;
|
||||
case COMD_Right: case COMD_UpRight: case COMD_DownRight:
|
||||
xdir+=WalkAccel; if (xdir>+lLimit) xdir=+lLimit;
|
||||
xdir+=ScaleAccel; if (xdir>+lLimit) xdir=+lLimit;
|
||||
break;
|
||||
case COMD_Up:
|
||||
xdir += (Action.Dir == DIR_Left) ? -WalkAccel : WalkAccel;
|
||||
xdir += (Action.Dir == DIR_Left) ? -ScaleAccel : ScaleAccel;
|
||||
if (xdir<-lLimit) xdir=-lLimit;
|
||||
if (xdir>+lLimit) xdir=+lLimit;
|
||||
break;
|
||||
case COMD_Stop: case COMD_Down:
|
||||
if (xdir<0) xdir+=WalkAccel;
|
||||
if (xdir>0) xdir-=WalkAccel;
|
||||
if ((xdir>-WalkAccel) && (xdir<+WalkAccel)) xdir=0;
|
||||
if (xdir<0) xdir+=ScaleAccel;
|
||||
if (xdir>0) xdir-=ScaleAccel;
|
||||
if ((xdir>-ScaleAccel) && (xdir<+ScaleAccel)) xdir=0;
|
||||
break;
|
||||
}
|
||||
iPhaseAdvance=0;
|
||||
|
@ -3941,6 +3957,18 @@ void C4Object::ExecAction()
|
|||
StopActionDelayCommand(this);
|
||||
SetCommand(C4CMD_Exit);
|
||||
}
|
||||
|
||||
lLimit = itofix(2);
|
||||
switch (Action.ComDir)
|
||||
{
|
||||
case COMD_Left: case COMD_UpLeft: case COMD_DownLeft:
|
||||
xdir-=FloatAccel; if (xdir<-lLimit) xdir=-lLimit;
|
||||
break;
|
||||
case COMD_Right: case COMD_UpRight: case COMD_DownRight:
|
||||
xdir+=FloatAccel; if (xdir>+lLimit) xdir=+lLimit;
|
||||
break;
|
||||
}
|
||||
|
||||
// Gravity/mobile
|
||||
DoGravity(this);
|
||||
Mobile=1;
|
||||
|
|
|
@ -874,9 +874,10 @@ void C4Viewport::DrawOverlay(C4TargetFacet &cgo, const ZoomData &GameZoom)
|
|||
DrawPlayerFogOfWar(cgo);
|
||||
C4ST_STOP(FoWStat)
|
||||
// Player info
|
||||
C4ST_STARTNEW(CInfoStat, "C4Viewport::DrawOverlay: Cursor Info")
|
||||
DrawCursorInfo(cgo);
|
||||
C4ST_STOP(CInfoStat)
|
||||
// TODO: remove all the functions for drawing portraits, ranks, bla bla etc.
|
||||
//C4ST_STARTNEW(CInfoStat, "C4Viewport::DrawOverlay: Cursor Info")
|
||||
//DrawCursorInfo(cgo);
|
||||
//C4ST_STOP(CInfoStat)
|
||||
C4ST_STARTNEW(PInfoStat, "C4Viewport::DrawOverlay: Player Info")
|
||||
DrawPlayerInfo(cgo);
|
||||
C4ST_STOP(PInfoStat)
|
||||
|
|