forked from Mirrors/openclonk
Moving controls to script...
parent
22d689d560
commit
f6fadb300d
|
@ -80,7 +80,7 @@
|
|||
</row>
|
||||
<row>
|
||||
<col>Script (Standardwert)</col>
|
||||
<col>Ausfuehrung des Scriptbefehls <em>PlayerControl</em> bzw. <em>PlayerControlReleased</em>. Siehe <emlink href="playercontrols.xml#Script">Script-Callbacks</emlink>.</col>
|
||||
<col>Ausfuehrung des Scriptbefehls <em>PlayerControl</em> bzw. <em>PlayerControlRelease</em>. Siehe <emlink href="playercontrols.xml#Script">Script-Callbacks</emlink>.</col>
|
||||
</row>
|
||||
<row>
|
||||
<col>Menu</col>
|
||||
|
@ -113,7 +113,7 @@
|
|||
<row>
|
||||
<col>Name</col>
|
||||
<col>Zeichenfolge</col>
|
||||
<col>Interner Name zur Identifikation gleicher Steuerungsbelegungen. Die Namen der Standardbelegungen sind <em>Keyboard1</em>, <em>Keyboard1Classic</em>, <em>Keyboard2</em>, <em>Keyboard2Classic</em>, <em>Gamepad</em></col>
|
||||
<col>Interner Name zur Identifikation gleicher Steuerungsbelegungen. Die Namen der Standardbelegungen sind <em>Keyboard1</em>, <em>Keyboard1Classic</em>, <em>Keyboard2</em>, <em>Keyboard2Classic</em>, <em>Gamepad</em>. Ueber Platzhalter (*) koennen Tasten direkt in mehreren Belegungen definiert werden**.</col>
|
||||
</row></table>
|
||||
|
||||
<text><table>
|
||||
|
@ -128,6 +128,11 @@
|
|||
<col>Zeichenfolge</col>
|
||||
<col>Taste(n) dieser Belegung oder Referenz auf eine andere Belegung. Siehe <emlink href="playercontrols.xml#Keys">Tastenbelegungen</emlink>.</col>
|
||||
</row>
|
||||
<row>
|
||||
<col>ComboIsSequence</col>
|
||||
<col>Boolean</col>
|
||||
<col>Wenn wahr, werden mehrfache Tasten als Sequenz interpretiert. Das heisst, sie muessen nacheinander statt gleichzeitig gedrueckt werden. Siehe <emlink href="playercontrols.xml#Keys">Tastenbelegungen</emlink>.</col>
|
||||
</row>
|
||||
<row>
|
||||
<col>Control</col>
|
||||
<col>Zeichenfolge</col>
|
||||
|
@ -193,8 +198,7 @@
|
|||
[Assignment]
|
||||
Key=W
|
||||
Control=Jump
|
||||
Priority=50
|
||||
</code>
|
||||
Priority=50</code>
|
||||
<text>Dies definiert eine Sprungtaste und die zugehoerige Standardbelegung auf der Tastatur fuer den ersten Spieler. Dazu folgendes Script zur Behandlung:</text>
|
||||
<code>global func PlayerControl(int player, int control, C4ID control_extra, int x, int y, int strength, bool repeated)
|
||||
{
|
||||
|
@ -212,8 +216,7 @@
|
|||
}
|
||||
// Unbekanntes Kommando
|
||||
return false;
|
||||
}
|
||||
</code>
|
||||
}</code>
|
||||
|
||||
<h id="ExtraData">ExtraData</h>
|
||||
<text>Da nicht jede Objektdefinition die globale PlayerControl-Funktion ueberladen kann, gibt es das ExtraData-Feld zum Verteilen von Kommandos. Zum Beispiel fuer folgende Definition:</text>
|
||||
|
@ -232,8 +235,7 @@
|
|||
if (control_extra) return control_extra->PlayerControl(player, control, x, y, strength, repeat);
|
||||
// Unbekanntes Kommando
|
||||
return false;
|
||||
}
|
||||
</code>
|
||||
}</code>
|
||||
<text>Und im Script der Schaufel:</text>
|
||||
<code>func PlayerControl(int player, int control, int x, int y, int strength, bool repeated)
|
||||
{
|
||||
|
@ -250,15 +252,81 @@
|
|||
}
|
||||
// Unbekanntes Kommando
|
||||
return false;
|
||||
}
|
||||
</code>
|
||||
}</code>
|
||||
|
||||
<h id="Hold">Gehaltene Tasten</h>
|
||||
<text>Wird fuer ein Kommando das <em>Hold</em>-Flag gesetzt, so speichert die Engine den gegenwaertigen Tastenzustand fuer diese Taste. Solche Tasten haben einige Besonderheiten:</text>
|
||||
<text><ul>
|
||||
<li>Sie generieren beim Loslassen <funclink>PlayerControlRelease</funclink>-Aufrufe im Script.</li>
|
||||
<li>Belegungen koennen mit den <em>Hold</em>/<em>Release</em>-Flags dauerhafte Tastendruecke emulieren.</li>
|
||||
<li><emlink href="playercontrols.xml#Repeat">Tastenwiederholungen</emlink> werden erzeugt.</li>
|
||||
<li>Der Haltezustand der Taste kann mit <funclink>GetPlayerControlState</funclink> im Script abgefragt werden.</li>
|
||||
</ul></text>
|
||||
<text>Bestes Beispiel hierfuer ist ein Richtungskommando:</text>
|
||||
<code> [ControlDef]
|
||||
Identifier=Left
|
||||
GUIName=Left
|
||||
GUIDesc=Walk left
|
||||
Hold=1</code>
|
||||
<text>Im Script wird die Richtung dann auf den Clonk uebertragen:</text>
|
||||
<code>global func PlayerControl(int player, int control, C4ID control_extra, int x, int y, int strength, bool repeated)
|
||||
{
|
||||
if (control == CON_Left) return UpdateControlDir(player);
|
||||
// ...
|
||||
}
|
||||
|
||||
global func PlayerControlRelease(int player, int control, C4ID control_extra, int x, int y)
|
||||
{
|
||||
if (control == CON_Left) return UpdateControlDir(player);
|
||||
// ...
|
||||
}
|
||||
|
||||
global func UpdateControlDir(int player)
|
||||
{
|
||||
// Clonk ausgewaehlt?
|
||||
var player_clonk = GetCursor(player);
|
||||
if (player_clonk)
|
||||
{
|
||||
// Clonkrichtung aktualisieren
|
||||
var new_comdir = COMD_Stop;
|
||||
if (GetPlayerControlState(player, CON_Left)) new_comdir = COMD_Left;
|
||||
player_clonk->SetComDir(new_comdir);
|
||||
// Kommando behandelt
|
||||
return true;
|
||||
}
|
||||
// Kommando behandelt
|
||||
return false;
|
||||
}</code>
|
||||
<text>Um klassisches Steuerungsverhalten zu erreichen, kann eine Tastenbelegung den <em>Hold</em>-Zustand emulieren:</text>
|
||||
<code> [Assignment]
|
||||
Key=A
|
||||
Control=Left
|
||||
TriggerMode=Hold
|
||||
|
||||
[Assignment]
|
||||
Key=S
|
||||
Control=Left
|
||||
TriggerMode=Release | AlwaysUnhandled</code>
|
||||
|
||||
<h id="Globals">Globale Definitionen</h>
|
||||
<text>...</text>
|
||||
<h id="Repeat">Tastenwiederholungen</h>
|
||||
<h id="Deactivate">Deaktivierte Kommandos</h>
|
||||
<text>Hat ein Kommando ein <em>RepeatDelay</em> definiert, so werden wiederholte Kommandos beim Halten der Taste erzeugt. Zum Beispiel fuer ein Wurkommando:</text>
|
||||
<code> [ControlDef]
|
||||
Identifier=Throw
|
||||
GUIName=Throw
|
||||
GUIDesc=Get rid of your selected inventory
|
||||
Hold=1
|
||||
RepeatDelay=5
|
||||
InitialRepeatDelay=35</code>
|
||||
<text>Im Beispiel koennte man die Wurftaste nach einmal Druecken auch halten. Das Wurfkommando wuerde dann nach 35 Frames (ca. eine Sekunde) halten alle 5 Frames automatisch wiederholt.</text>
|
||||
<text>Wiederholungen werden nur erzeugt, wenn das Kommando ebenfalls das <em>Hold</em>-Flag gesetzt hat.</text>
|
||||
<h id="Deactivate">Deaktivierte Kommandos**</h>
|
||||
<text>...</text>
|
||||
<h id="Keys">Tastenbelegungen</h>
|
||||
<text>...</text>
|
||||
<h id="Priority">Prioritaeten</h>
|
||||
<text>...</text>
|
||||
</part>
|
||||
<text><em>** - noch nicht implementiert</em></text>
|
||||
<author>Sven2</author><date>Juni 2009</date>
|
||||
|
|
|
@ -99,6 +99,8 @@ class C4PlayerControlDefs
|
|||
void CompileFunc(StdCompiler *pComp);
|
||||
void MergeFrom(const C4PlayerControlDefs &Src); // copy all defs from source file; overwrite defs of same name if found
|
||||
|
||||
void FinalInit(); // after all defs have been loaded: register script constants
|
||||
|
||||
const C4PlayerControlDef *GetControlByIndex(int32_t idx) const;
|
||||
int32_t GetControlIndexByIdentifier(const char *szIdentifier) const; // return CON_None for not found
|
||||
int32_t GetCount() const { return Defs.size(); }
|
||||
|
@ -167,7 +169,7 @@ class C4PlayerControlAssignment
|
|||
bool IsComboMatched(const C4PlayerControlRecentKeyList &DownKeys, const C4PlayerControlRecentKeyList &RecentKeys) const; // check if combo is currently fulfilled (assuming TriggerKey is already matched)
|
||||
|
||||
bool operator ==(const C4PlayerControlAssignment &cmp) const; // doesn't compare resolved TriggerKey/iControl
|
||||
bool operator <(const C4PlayerControlAssignment &cmp) const { return iPriority < cmp.iPriority; }
|
||||
bool operator <(const C4PlayerControlAssignment &cmp) const { return iPriority > cmp.iPriority; } // assignments are processed in DESCENDING priority!
|
||||
const char *GetControlName() const { return sControlName.getData(); }
|
||||
int32_t GetControl() const { return iControl; }
|
||||
bool IsRefsResolved() const { return fRefsResolved; }
|
||||
|
@ -256,7 +258,7 @@ class C4PlayerControl
|
|||
|
||||
// async values
|
||||
C4PlayerControlAssignmentSet *pControlSet; // the control set used by this player - may be NULL if the player cannot be controlled!
|
||||
typedef std::list<C4CustomKey *> KeyBindingList;
|
||||
typedef std::list<C4KeyBinding *> KeyBindingList;
|
||||
KeyBindingList KeyBindings; // keys registered into Game.KeyboardInput
|
||||
C4PlayerControlRecentKeyList RecentKeys; // keys pressed recently; for combinations
|
||||
C4PlayerControlRecentKeyList DownKeys; // keys currently held down
|
||||
|
|
|
@ -150,8 +150,8 @@ void InitFunctionMap(C4AulScriptEngine *pEngine); // add functions to engine
|
|||
#define PSF_OnHostilityChange "~OnHostilityChange" // int iPlr1, int iPlr2, bool fNewHostility, bool fOldHostility
|
||||
#define PSF_OnTeamSwitch "~OnTeamSwitch" // int iPlr1, int idNewTeam, int idOldTeam
|
||||
#define PSF_OnOwnerRemoved "~OnOwnerRemoved"
|
||||
#define PSF_PlayerControl "~PlayerControl" // int iControl, C4ID idControlExtraData, int x, int y, int iStrength, bool fRepeated
|
||||
#define PSF_PlayerControlRelease "~PlayerControlRelease" // int iControl, C4ID idControlExtraData, int x, int y
|
||||
#define PSF_PlayerControl "PlayerControl" // int iPlr, int iControl, C4ID idControlExtraData, int x, int y, int iStrength, bool fRepeated
|
||||
#define PSF_PlayerControlRelease "PlayerControlRelease" // int iPlr, int iControl, C4ID idControlExtraData, int x, int y
|
||||
|
||||
// Fx%s is automatically prefixed
|
||||
#define PSFS_FxAdd "Add" // C4Object *pTarget, int iEffectNumber, C4String *szNewEffect, int iNewTimer, C4Value vNewEffectVar1, C4Value vNewEffectVar2, C4Value vNewEffectVar3, C4Value vNewEffectVar4
|
||||
|
|
|
@ -2273,6 +2273,9 @@ BOOL C4Game::InitGame(C4Group &hGroup, bool fLoadSection, bool fLoadSky)
|
|||
{ LogFatal(LoadResStr("IDS_PRC_FAIL")); return FALSE; }
|
||||
SetInitProgress(56);
|
||||
|
||||
// Final init for loaded player commands. Before linking scripts, so CON_* constants are registered
|
||||
PlayerControlDefs.FinalInit();
|
||||
|
||||
// Link scripts
|
||||
if (!LinkScriptEngine()) return FALSE;
|
||||
SetInitProgress(57);
|
||||
|
|
|
@ -122,6 +122,20 @@ int32_t C4PlayerControlDefs::GetControlIndexByIdentifier(const char *szIdentifie
|
|||
return CON_None;
|
||||
}
|
||||
|
||||
void C4PlayerControlDefs::FinalInit()
|
||||
{
|
||||
// Assume all defs have been loaded
|
||||
// Register scritp constants
|
||||
for (DefVecImpl::const_iterator i = Defs.begin(); i != Defs.end(); ++i)
|
||||
{
|
||||
const char *szIdtf = (*i).GetIdentifier();
|
||||
if (szIdtf && *szIdtf && !SEqual(szIdtf, "None"))
|
||||
{
|
||||
Game.ScriptEngine.RegisterGlobalConstant(FormatString("CON_%s", szIdtf).getData(), C4VInt(i-Defs.begin()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* C4PlayerControlAssignment */
|
||||
|
||||
|
@ -150,6 +164,7 @@ void C4PlayerControlAssignment::CompileFunc(StdCompiler *pComp)
|
|||
{
|
||||
if (!pComp->Name("Assignment")) { pComp->NameEnd(); pComp->excNotFound("Assignment"); }
|
||||
pComp->Value(mkNamingAdapt(mkSTLContainerAdapt(KeyCombo), "Key", KeyComboVec()));
|
||||
pComp->Value(mkNamingAdapt(fComboIsSequence, "ComboIsSequence", false));
|
||||
pComp->Value(mkNamingAdapt(mkParAdapt(sControlName, StdCompiler::RCT_Idtf), "Control", "None"));
|
||||
pComp->Value(mkNamingAdapt(iPriority, "Priority", 0));
|
||||
const StdBitfieldEntry<int32_t> TriggerModeNames[] = {
|
||||
|
@ -749,7 +764,7 @@ bool C4PlayerControl::ExecuteControlScript(int32_t iControl, C4ID idControlExtra
|
|||
// control down
|
||||
C4AulFunc *pFunc = Game.ScriptEngine.GetFirstFunc(PSF_PlayerControl);
|
||||
if (!pFunc) return false;
|
||||
C4AulParSet Pars(C4VInt(iControl), C4VID(idControlExtraData), C4VInt(rKeyExtraData.x), C4VInt(rKeyExtraData.y), C4VInt(rKeyExtraData.iStrength), C4VBool(fRepeated));
|
||||
C4AulParSet Pars(C4VInt(iPlr), C4VInt(iControl), C4VID(idControlExtraData), C4VInt(rKeyExtraData.x), C4VInt(rKeyExtraData.y), C4VInt(rKeyExtraData.iStrength), C4VBool(fRepeated));
|
||||
return !!pFunc->Exec(NULL, &Pars);
|
||||
}
|
||||
else
|
||||
|
@ -757,7 +772,7 @@ bool C4PlayerControl::ExecuteControlScript(int32_t iControl, C4ID idControlExtra
|
|||
// control up
|
||||
C4AulFunc *pFunc = Game.ScriptEngine.GetFirstFunc(PSF_PlayerControlRelease);
|
||||
if (!pFunc) return false;
|
||||
C4AulParSet Pars(C4VInt(iControl), C4VID(idControlExtraData), C4VInt(rKeyExtraData.x), C4VInt(rKeyExtraData.y));
|
||||
C4AulParSet Pars(C4VInt(iPlr), C4VInt(iControl), C4VID(idControlExtraData), C4VInt(rKeyExtraData.x), C4VInt(rKeyExtraData.y));
|
||||
return !!pFunc->Exec(NULL, &Pars);
|
||||
}
|
||||
}
|
||||
|
@ -835,7 +850,7 @@ void C4PlayerControl::RegisterKeyset(int32_t iPlr, C4PlayerControlAssignmentSet
|
|||
|
||||
void C4PlayerControl::AddKeyBinding(const C4KeyCodeEx &key, bool fHoldKey, int32_t idx)
|
||||
{
|
||||
KeyBindings.push_back(new C4CustomKey(
|
||||
KeyBindings.push_back(new C4KeyBinding(
|
||||
key, FormatString("PlrKey%02d", idx).getData(), KEYSCOPE_Control,
|
||||
new C4KeyCBPassKey<C4PlayerControl>(*this, &C4PlayerControl::ProcessKeyDown, fHoldKey ? &C4PlayerControl::ProcessKeyUp : NULL),
|
||||
C4CustomKey::PRIO_PlrControl));
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
#strict 2
|
||||
|
||||
global func PlayerControl(int plr, int ctrl, id spec_id, int x, int y, int strength, bool repeat)
|
||||
{
|
||||
Log("%d, %d, %i, %d, %d, %d, %v", plr, ctrl, spec_id, x,y,strength, repeat);
|
||||
return true;
|
||||
}
|
||||
|
||||
global func PlayerControlRelease(int plr, int ctrl, id spec_id, int x, int y)
|
||||
{
|
||||
Log("re %d, %d, %i, %d, %d", plr, ctrl, spec_id, x,y);
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
[ControlDefs]
|
||||
|
||||
[ControlDef]
|
||||
Identifier=Left
|
||||
GUIName=Left
|
||||
GUIDesc=Walk left
|
||||
Hold=1
|
||||
RepeatDelay=5
|
||||
InitialRepeatDelay=35
|
||||
|
||||
[ControlDef]
|
||||
Identifier=Throw
|
||||
GUIName=Throw
|
||||
GUIDesc=Get rid of your selected inventory
|
||||
Hold=1
|
||||
RepeatDelay=5
|
||||
InitialRepeatDelay=35
|
||||
|
||||
|
||||
[ControlDef]
|
||||
Identifier=Dig
|
||||
GUIName=Dig
|
||||
GUIDesc=Delve through the earth
|
||||
|
||||
[ControlDef]
|
||||
Identifier=Test
|
||||
GUIName=Test
|
||||
GUIDesc=Test key
|
||||
|
||||
|
||||
[ControlSets]
|
||||
|
||||
[ControlSet]
|
||||
Name=Keyboard2Classic
|
||||
|
||||
[Assignment]
|
||||
Key=Q
|
||||
Control=Throw
|
||||
Priority=50
|
||||
|
||||
[Assignment]
|
||||
Key=E
|
||||
Control=Dig
|
||||
Priority=50
|
||||
|
||||
[Assignment]
|
||||
Key=A
|
||||
Control=Left
|
||||
TriggerMode=Hold
|
||||
|
||||
[Assignment]
|
||||
Key=S
|
||||
Control=Left
|
||||
TriggerMode=Release | AlwaysUnhandled
|
||||
|
||||
[Assignment]
|
||||
Key=Throw,Throw,Dig
|
||||
ComboIsSequence=1
|
||||
Control=Test
|
||||
Priority=60
|
Loading…
Reference in New Issue