forked from Mirrors/openclonk
SendCursorPos controls issue CON_CursorPos (#289)
parent
f74913b687
commit
65b73b7177
|
@ -454,10 +454,18 @@ public func ObjectControl(int plr, int ctrl, int x, int y, int strength, bool re
|
|||
{
|
||||
// Cancel usage
|
||||
CancelUse();
|
||||
|
||||
// the x,y pos is wrong because the local coordinates of the clonk have been substracted
|
||||
x += GetX();
|
||||
y += GetY();
|
||||
// use x/y coordinates from last known cursor pos
|
||||
var plr_cursor_pos = GetPlayerCursorPos(plr);
|
||||
if (plr_cursor_pos)
|
||||
{
|
||||
x = plr_cursor_pos[0];
|
||||
y = plr_cursor_pos[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Cursor pos unknown? This can't really happen
|
||||
x = y = 300;
|
||||
}
|
||||
CreateRingMenu(nil,x,y,this);
|
||||
// CreateRingMenu calls SetMenu(this) in the clonk,
|
||||
// so after this call menu = the created menu
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
static const CON_Gamepad_Deadzone = 60;
|
||||
static CON_VC_Players;
|
||||
static g_player_cursor_pos; // array of [x,y] pos arrays; indexed by player. last cursor pos as sent by CON_CursorPos
|
||||
|
||||
// PlayerControlRelease
|
||||
// Called by engine whenever a control is issued
|
||||
|
@ -177,6 +178,14 @@ global func Control2Player(int plr, int ctrl, int x, int y, int strength, bool r
|
|||
}
|
||||
StopSelected(plr);
|
||||
}
|
||||
// cursor pos info - store in player values
|
||||
if (ctrl == CON_CursorPos)
|
||||
{
|
||||
if (!g_player_cursor_pos) g_player_cursor_pos = CreateArray(plr+1);
|
||||
g_player_cursor_pos[plr] = [x, y];
|
||||
|
||||
return true;
|
||||
}
|
||||
/*
|
||||
if (ctrl == CON_Test)
|
||||
{
|
||||
|
@ -187,6 +196,13 @@ global func Control2Player(int plr, int ctrl, int x, int y, int strength, bool r
|
|||
return false;
|
||||
}
|
||||
|
||||
/* return info of last sent CON_CursorPos packet for that player as [x, y] */
|
||||
global func GetPlayerCursorPos(int plr)
|
||||
{
|
||||
if (!g_player_cursor_pos) return 0;
|
||||
return g_player_cursor_pos[plr];
|
||||
}
|
||||
|
||||
global func StopSelected(int plr)
|
||||
{
|
||||
var cursor;
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
# ObjectMenuDown ObjectMenuUp ObjectMenuLeft ObjectMenuRight
|
||||
# PlayerMenu
|
||||
#
|
||||
# CursorPos
|
||||
#
|
||||
# Backpack
|
||||
#
|
||||
# with Mouse
|
||||
|
@ -193,12 +195,14 @@
|
|||
GUIName=Use
|
||||
GUIDesc=Use selected or controlled item
|
||||
Hold=1
|
||||
SendCursorPos=1
|
||||
|
||||
[ControlDef]
|
||||
Identifier=UseDelayed
|
||||
GUIName=Use
|
||||
GUIDesc=Use selected or controlled item
|
||||
Hold=1
|
||||
SendCursorPos=1
|
||||
|
||||
[ControlDef]
|
||||
Identifier=CancelUse
|
||||
|
@ -215,12 +219,14 @@
|
|||
GUIName=Use 2
|
||||
GUIDesc=Use secondary selected or controlled item
|
||||
Hold=1
|
||||
SendCursorPos=1
|
||||
|
||||
[ControlDef]
|
||||
Identifier=UseAltDelayed
|
||||
GUIName=Use 2
|
||||
GUIDesc=Use secondary selected or controlled item
|
||||
Hold=1
|
||||
SendCursorPos=1
|
||||
|
||||
[ControlDef]
|
||||
Identifier=Backpack
|
||||
|
@ -232,6 +238,7 @@
|
|||
Identifier=Grab
|
||||
GUIName=Grab
|
||||
GUIDesc=Grab vehicle
|
||||
SendCursorPos=1
|
||||
|
||||
[ControlDef]
|
||||
Identifier=Ungrab
|
||||
|
@ -257,11 +264,13 @@
|
|||
Identifier=Interact
|
||||
GUIName=Interact
|
||||
GUIDesc=Interact with object in landscape
|
||||
SendCursorPos=1
|
||||
|
||||
[ControlDef]
|
||||
Identifier=Enter
|
||||
GUIName=Enter
|
||||
GUIDesc=Go into the building
|
||||
SendCursorPos=1
|
||||
|
||||
[ControlDef]
|
||||
Identifier=Exit
|
||||
|
@ -432,6 +441,10 @@
|
|||
Identifier=ObjectMenuDown
|
||||
Action=ObjectMenuDown
|
||||
|
||||
# control sent by engine along controls with SendCursorPos=1
|
||||
[ControlDef]
|
||||
Identifier=CursorPos
|
||||
|
||||
# Extra buttons...
|
||||
|
||||
[ControlDef]
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
#include <C4Network2Stats.h>
|
||||
#include <C4MouseControl.h>
|
||||
#include <C4GamePadCon.h>
|
||||
#include <C4PlayerList.h>
|
||||
#include <C4Player.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (disable: 4355)
|
||||
|
@ -532,6 +534,10 @@ void C4GameControl::PrepareInput()
|
|||
// add per-controlframe input
|
||||
::MouseControl.DoMoveInput();
|
||||
if (Application.pGamePadControl) Application.pGamePadControl->DoAxisInput();
|
||||
// per-player input
|
||||
C4Player *plr; int32_t i=0;
|
||||
while (plr = ::Players.GetLocalByIndex(i++))
|
||||
plr->Control.PrepareInput();
|
||||
}
|
||||
|
||||
C4GameControl Control;
|
||||
|
|
|
@ -100,6 +100,7 @@ void C4PlayerControlDefs::UpdateInternalCons()
|
|||
InternalCons.CON_ObjectMenuOK = GetControlIndexByIdentifier("ObjectMenuOK");
|
||||
InternalCons.CON_ObjectMenuOKAll = GetControlIndexByIdentifier("ObjectMenuOKAll");
|
||||
InternalCons.CON_ObjectMenuCancel = GetControlIndexByIdentifier("ObjectMenuCancel");
|
||||
InternalCons.CON_CursorPos = GetControlIndexByIdentifier("CursorPos");
|
||||
}
|
||||
|
||||
void C4PlayerControlDefs::Clear()
|
||||
|
@ -762,24 +763,10 @@ bool C4PlayerControl::ProcessKeyEvent(const C4KeyCodeEx &pressed_key, const C4Ke
|
|||
if (pControlDef && pControlDef->IsValid() && !Sync.IsControlDisabled(iControlIndex) && (!fUp || pControlDef->IsHoldKey()))
|
||||
{
|
||||
// extra data from key or overwrite by current cursor pos if definition requires it
|
||||
const C4KeyEventData *pKeyExtraData = &rKeyExtraData;
|
||||
C4KeyEventData CustomKeyExtraData;
|
||||
if (pControlDef->IsSendCursorPos())
|
||||
{
|
||||
CustomKeyExtraData = rKeyExtraData;
|
||||
if (!GetCurrentPlayerCursorPos(&(CustomKeyExtraData.x), &(CustomKeyExtraData.y)))
|
||||
{
|
||||
// no cursor position is known. set it to -1/-1 so scripters get a hint
|
||||
CustomKeyExtraData.x = CustomKeyExtraData.y = -1;
|
||||
}
|
||||
if (!pControlPacket)
|
||||
pKeyExtraData = &CustomKeyExtraData;
|
||||
else
|
||||
pControlPacket->SetExtraData(CustomKeyExtraData);
|
||||
}
|
||||
if (pControlDef->IsAsync() && !pControlPacket)
|
||||
{
|
||||
if (ExecuteControl(iControlIndex, fUp, *pKeyExtraData, pAssignment->GetTriggerMode(), pressed_key.IsRepeated()))
|
||||
if (pControlDef->IsSendCursorPos()) IsCursorPosRequested = true; // async cursor pos request - doesn't really make sense to set this flag for async controls
|
||||
if (ExecuteControl(iControlIndex, fUp, rKeyExtraData, pAssignment->GetTriggerMode(), pressed_key.IsRepeated()))
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
@ -789,8 +776,10 @@ bool C4PlayerControl::ProcessKeyEvent(const C4KeyCodeEx &pressed_key, const C4Ke
|
|||
if (pressed_key.IsRepeated()) return false;
|
||||
// sync control has higher priority - no more async execution then
|
||||
// build a control packet and add control data instead. even for async controls later in chain, as they may be blocked by a sync handler
|
||||
if (!pControlPacket) pControlPacket = new C4ControlPlayerControl(iPlr, fUp, *pKeyExtraData);
|
||||
if (!pControlPacket) pControlPacket = new C4ControlPlayerControl(iPlr, fUp, rKeyExtraData);
|
||||
pControlPacket->AddControl(iControlIndex, pAssignment->GetTriggerMode());
|
||||
// sync cursor pos request; pos will be added to control before it is synced/executed
|
||||
if (pControlDef->IsSendCursorPos()) IsCursorPosRequested = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1032,7 +1021,7 @@ void C4PlayerControl::Execute()
|
|||
if (irk != RecentKeys.begin()) RecentKeys.erase(RecentKeys.begin(), irk);
|
||||
}
|
||||
|
||||
C4PlayerControl::C4PlayerControl() : ControlDefs(Game.PlayerControlDefs), iPlr(-1), pControlSet(NULL)
|
||||
C4PlayerControl::C4PlayerControl() : ControlDefs(Game.PlayerControlDefs), iPlr(-1), pControlSet(NULL), IsCursorPosRequested(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -1045,6 +1034,7 @@ void C4PlayerControl::Clear()
|
|||
RecentKeys.clear();
|
||||
DownKeys.clear();
|
||||
Sync.Clear();
|
||||
IsCursorPosRequested = false;
|
||||
}
|
||||
|
||||
void C4PlayerControl::RegisterKeyset(int32_t iPlr, C4PlayerControlAssignmentSet *pKeyset)
|
||||
|
@ -1155,4 +1145,35 @@ bool C4PlayerControl::GetCurrentPlayerCursorPos(int32_t *x_out, int32_t *y_out)
|
|||
float gui_y = (screen_y - vp->last_game_draw_cgo.Y) / C4GUI::GetZoom() + vp->last_game_draw_cgo.Y;
|
||||
*x_out = int32_t(gui_x); *y_out = int32_t(gui_y);
|
||||
return true;
|
||||
}
|
||||
|
||||
void C4PlayerControl::PrepareInput()
|
||||
{
|
||||
if (IsCursorPosRequested)
|
||||
{
|
||||
int32_t x, y;
|
||||
// add current cursor pos in GUI coordinates to input
|
||||
if (GetCurrentPlayerCursorPos(&x, &y))
|
||||
{
|
||||
// CON_CursorPos might not have been defined in definition file
|
||||
if (ControlDefs.InternalCons.CON_CursorPos != CON_None)
|
||||
{
|
||||
C4KeyEventData ev;
|
||||
ev.iStrength = 0;
|
||||
ev.x = x;
|
||||
ev.y = y;
|
||||
C4ControlPlayerControl *pControlPacket = new C4ControlPlayerControl(iPlr, false, ev);
|
||||
pControlPacket->AddControl(ControlDefs.InternalCons.CON_CursorPos, C4PlayerControlAssignment::CTM_Default);
|
||||
// make sure it's added at head, because controls that have SendCursorPos=1 set will follow, which will rely
|
||||
// on the cursor pos being known
|
||||
Game.Input.AddHead(CID_PlrControl, pControlPacket);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// no cursor is known (e.g.: Cursor Clonk dead, etc.). Don't create a control.
|
||||
// Script will probably fall back to last known cursor pos
|
||||
}
|
||||
IsCursorPosRequested = false;
|
||||
}
|
||||
}
|
|
@ -93,8 +93,8 @@ private:
|
|||
public:
|
||||
struct CInternalCons
|
||||
{
|
||||
int32_t CON_ObjectMenuSelect, CON_ObjectMenuOKAll, CON_ObjectMenuOK, CON_ObjectMenuCancel;
|
||||
CInternalCons() : CON_ObjectMenuSelect(CON_None), CON_ObjectMenuOKAll(CON_None), CON_ObjectMenuOK(CON_None), CON_ObjectMenuCancel(CON_None) {}
|
||||
int32_t CON_ObjectMenuSelect, CON_ObjectMenuOKAll, CON_ObjectMenuOK, CON_ObjectMenuCancel, CON_CursorPos;
|
||||
CInternalCons() : CON_ObjectMenuSelect(CON_None), CON_ObjectMenuOKAll(CON_None), CON_ObjectMenuOK(CON_None), CON_ObjectMenuCancel(CON_None), CON_CursorPos(CON_None) {}
|
||||
} InternalCons;
|
||||
|
||||
void UpdateInternalCons();
|
||||
|
@ -290,6 +290,7 @@ private:
|
|||
KeyBindingList KeyBindings; // keys registered into Game.KeyboardInput
|
||||
C4PlayerControlRecentKeyList RecentKeys; // keys pressed recently; for combinations
|
||||
C4PlayerControlRecentKeyList DownKeys; // keys currently held down
|
||||
bool IsCursorPosRequested; // set to true when a SendCursorPos-control had been issued
|
||||
|
||||
public:
|
||||
// sync values
|
||||
|
@ -376,6 +377,8 @@ public:
|
|||
bool SetControlDisabled(int ctrl, bool is_disabled) { return Sync.SetControlDisabled(ctrl, is_disabled); }
|
||||
bool IsControlDisabled(int ctrl) const { return Sync.IsControlDisabled(ctrl); }
|
||||
|
||||
// callback from C4GameControl when the next control packet is finalized
|
||||
void PrepareInput();
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -315,7 +315,7 @@ void C4PacketList::Add(C4PacketType eType, C4PacketBase *pPkt)
|
|||
|
||||
void C4PacketList::AddHead(C4PacketType eType, C4PacketBase *pPkt)
|
||||
{
|
||||
Add(new C4IDPacket(eType, pPkt));
|
||||
AddHead(new C4IDPacket(eType, pPkt));
|
||||
}
|
||||
|
||||
void C4PacketList::Take(C4PacketList &List)
|
||||
|
|
Loading…
Reference in New Issue