fully working ringmenu controls, with gamepad too

Tobias Zwick 2010-03-23 21:57:30 +01:00
parent f553e3f4d4
commit 949d706751
10 changed files with 138 additions and 85 deletions

View File

@ -16,8 +16,6 @@
#include Library_HUDAdapter
// standard controls
#include Library_ClonkControl
// menu adapter
#include Library_MenuControl
// manager for aiming
#include Library_AimManager

View File

@ -136,6 +136,10 @@ func Show()
shown=true;
}
public func UpdateCursor(int angle)
{
Log("%d",angle);
}
public func Hide() {
for(var i=0; i<GetLength(menu_icons); i++)if(menu_icons[i]) menu_icons[i]["Visibility"] = VIS_None;
@ -147,7 +151,9 @@ public func Hide() {
func Close()
{
for(var i=0; i<GetLength(menu_icons); i++) if(menu_icons[i]) menu_icons[i]->RemoveObject();
return RemoveObject();
if(menu_object)
menu_object->SetMenu(nil);
RemoveObject();
}

View File

@ -5,14 +5,13 @@
Virtual cursor for gamepad controls
*/
local crew, angle, dirx, diry, saveangle, xpos,ypos, analogaim, aiming;
local crew, angle, dirx, diry, xpos,ypos, analogaim, aiming;
static const CURSOR_Radius = 100;
protected func Initialize()
{
this["Visibility"] = VIS_None;
saveangle = 900;
dirx = diry = xpos = ypos = 0;
aiming = false;
}
@ -21,7 +20,7 @@ public func FxMoveTimer()
{
var speed = 0;
var dpad_rotatespeed = 35;
// dpad mode
if(diry)
{
@ -44,6 +43,7 @@ public func FxMoveTimer()
var analog_strength = BoundBy(Sqrt(xpos*xpos+ypos*ypos),0,100);
var angle_diff = Normalize(target_angle - angle, -1800, 10);
if (angle_diff == 0) angle_diff = 1;
var dir = angle_diff / Abs(angle_diff);
angle = angle + angle_diff * analog_strength / 100 / 8;
@ -59,17 +59,13 @@ private func UpdateAnalogpadPos()
ypos = Cos(angle/10,-100);
}
public func StartAim(int ctrl, object clonk, object using, bool stealth)
public func StartAim(object clonk, bool stealth)
{
// only reinitialize angle if the crosshair hasn't been there before
if(!GetEffect("Move",this))
{
if(ctrl != CON_ThrowDelayed)
angle = saveangle*(clonk->GetDir()*2-1);
// throw must be fast! normally, the clonk wants to throw
// like 80° or so. Previously thrown direction is not saved
else
angle = 800*(clonk->GetDir()*2-1);
// which should basically be only the case on the first time aiming
angle = 800*(clonk->GetDir()*2-1);
}
// set starting position for analog pad
@ -111,7 +107,6 @@ public func StopAim()
dirx = 0;
diry = 0;
EnableKeyAimControls(false);
saveangle = Abs(Normalize(angle,-1800,10));
analogaim = false;
aiming = false;
}
@ -139,7 +134,7 @@ public func Aim(int ctrl, object clonk, int strength, int repeat, int release)
{
// start (stealth) aiming
if(!GetEffect("Move",this))
StartAim(nil, clonk, nil,true);
StartAim(clonk,true);
// aiming with analog pad
if (ctrl == CON_AimAxisUp || ctrl == CON_AimAxisDown || ctrl == CON_AimAxisLeft || ctrl == CON_AimAxisRight)

View File

@ -47,6 +47,8 @@ local mlastx, mlasty;
local virtual_cursor;
local noholdingcallbacks;
local menu;
/* ++++++++ Item controls ++++++++++ */
/* Item limit */
@ -223,6 +225,7 @@ global func ShiftContents()
protected func Construction()
{
menu = nil;
selected = 0;
selected2 = Min(2,MaxContentsCount()-1);
indexed_inventory = 0;
@ -416,11 +419,11 @@ public func ObjectControl(int plr, int ctrl, int x, int y, int strength, bool re
if (ctrl == CON_Hotkey8) hot = 8;
if (ctrl == CON_Hotkey9) hot = 9;
var menu = this->~GetMenu();
var mnu = this->~GetMenu();
if (hot > 0)
{
if (menu) menu->~SelectHotkey(hot-1);
if (mnu) mnu->~SelectHotkey(hot-1);
return this->~ControlHotkey(hot-1);
}
@ -530,7 +533,7 @@ public func ObjectControl(int plr, int ctrl, int x, int y, int strength, bool re
}
else
{
VirtualCursor()->StartAim(ctrl,this,contents);
VirtualCursor()->StartAim(this);
}
}
// drop
@ -564,7 +567,7 @@ public func ObjectControl(int plr, int ctrl, int x, int y, int strength, bool re
}
else
{
VirtualCursor()->StartAim(ctrl,this,contents2);
VirtualCursor()->StartAim(this);
}
}
// drop
@ -660,7 +663,7 @@ private func StartUseDelayedControl(int ctrl, control, object obj)
var estr = "";
if (alt && !(obj->Contained())) estr = "Alt";
VirtualCursor()->StartAim(ctrl,this,obj);
VirtualCursor()->StartAim(this);
// call UseStart
var handled = obj->Call(Format("~%sUseStart%s",control,estr),this,mlastx,mlasty);
@ -714,7 +717,7 @@ private func HoldingUseControl(int ctrl, control, int x, int y, object obj)
//Message("%d,%d",this,mex,mey);
// automatic adjustment of the position
// automatic adjustment of the direction
// --------------------
// if this is desired for ALL objects is the question, we will find out.
// For now, this is done for items and vehicles, not for buildings and
@ -776,16 +779,27 @@ private func StopUseDelayedControl(control, object obj)
private func Control2Menu(int ctrl, int x, int y, int strength, bool repeat, bool release)
{
var angle = Angle(0,0,x,y);
if (repeat) return true;
// select
if (ctrl == CON_Use || ctrl == CON_UseDelayed)
this->GetMenu()->Select(angle, false);
if (ctrl == CON_UseAlt || ctrl == CON_UseAltDelayed)
this->GetMenu()->Select(angle, false);
var angle;
if (PlayerHasVirtualCursor(GetOwner()))
angle = Angle(0,0,mlastx,mlasty);
else
angle = Angle(0,0,x,y);
if (repeat)
{
if (ctrl == CON_Use || ctrl == CON_UseDelayed
|| ctrl == CON_UseAlt || ctrl == CON_UseAltDelayed)
this->GetMenu()->~UpdateCursor(angle);
}
if (release)
{
// select
if (ctrl == CON_Use || ctrl == CON_UseDelayed)
this->GetMenu()->Select(angle, false);
if (ctrl == CON_UseAlt || ctrl == CON_UseAltDelayed)
this->GetMenu()->Select(angle, false);
}
return true;
}
@ -1042,7 +1056,14 @@ public func UpdateVirtualCursorPos()
public func TriggerHoldingControl()
{
if (using && !noholdingcallbacks)
// using has been commented because it must be possible to use the virtual
// cursor aim also without a used object - for menus
// However, I think the check for 'using' here is just an unecessary safeguard
// since there is always a using-object if the clonk is aiming for a throw
// or a use. If the clonk uses it, there will be callbacks that cancel the
// callbacks to the virtual cursor
// - Newton
if (/*using && */!noholdingcallbacks)
{
var ctrl;
if (alt) ctrl = CON_UseAltDelayed;
@ -1053,6 +1074,64 @@ public func TriggerHoldingControl()
}
func HasMenuControl()
{
return true;
}
func SetMenu(object m)
{
// multiple menus are currently not supported (yet)
if (menu && m)
{
menu->Close();
}
// new one
menu = m;
if (menu)
{
// we need to be notified when the ringmenu is gone
if (PlayerHasVirtualCursor(GetOwner()))
VirtualCursor()->StartAim(this);
else
SetPlayerControlEnabled(GetOwner(), CON_Aim, true);
}
// close menu
if (!menu)
{
if (PlayerHasVirtualCursor(GetOwner()))
VirtualCursor()->StopAim();
else
SetPlayerControlEnabled(GetOwner(), CON_Aim, false);
}
}
func GetMenu()
{
return menu;
}
func ReinitializeControls()
{
if((PlayerHasVirtualCursor(GetOwner())))
{
// if is aiming or in menu and no virtual cursor is there? Create one
if (!virtual_cursor)
if (menu || using)
{
VirtualCursor()->StartAim(this);
}
}
else
{
// remove any virtual cursor
if (virtual_cursor)
virtual_cursor->RemoveObject();
}
}
// Throwing
private func DoThrow(object obj, int angle)
{

View File

@ -1,5 +0,0 @@
[DefCore]
id=Library_MenuControl
Version=4,10,0,0
Category=C4D_StaticBack
Picture=0,0,64,64

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

View File

@ -1,36 +0,0 @@
/*
Menu control
Author: Newton
*/
local menu;
func Construction()
{
menu = nil;
return _inherited(...);
}
func HasMenuControl()
{
return true;
}
func SetMenu(object m)
{
// destroy old one:
// multiple menus are currently not supported (yet)
if (menu)
{
menu->Close();
}
// new one
menu = m;
}
func GetMenu()
{
return menu;
}

View File

@ -1,6 +1,7 @@
static const CON_Gamepad_Deadzone = 60;
static CON_VC_Players;
// Functions to handle player controls (i.e., input keys)
@ -51,6 +52,29 @@ global func PlayerControl(int plr, int ctrl, id spec_id, int x, int y, int stren
return false;
}
global func InitializePlayerControl(int plr, string controlset_name, bool keyboard, bool mouse, bool gamepad)
{
// VC = VirtualCursor
if(!CON_VC_Players)
CON_VC_Players = CreateArray();
CON_VC_Players[plr] = !mouse;
// for all clonks...
for(var clonk in FindObjects(Find_OCF(OCF_CrewMember)))
{
clonk->~ReinitializeControls();
}
}
global func PlayerHasVirtualCursor(int plr)
{
if(!CON_VC_Players)
return -1;
return CON_VC_Players[plr];
}
// Control2Player
// Player-wide controls
global func Control2Player(int plr, int ctrl, int x, int y, int strength, bool repeat, bool release)

View File

@ -1,18 +1,8 @@
/*
*/
/*
Spellchooser via Mouse
Author: MimmoO
*/
local menuitem;
local choses;
func ContainedUse(object clonk, int x, int y)
func ChooseMenu(object clonk)
{
if(!menuitem)
{

View File

@ -30,7 +30,9 @@ protected func PlrHasRespawned(int iPlr, object cp)
{
var clonk = GetCrew(iPlr);
clonk->Contents()->RemoveObject();
clonk->Enter(CreateObject(RelaunchRoom,LandscapeWidth()/2,240,clonk->GetOwner()));
var relaunch = CreateObject(RelaunchRoom,LandscapeWidth()/2,240,clonk->GetOwner());
clonk->Enter(relaunch);
relaunch->ChooseMenu(clonk);
//clonk->CreateContents(SpellChooser,2);
return;
}