diff --git a/binaries/data/mods/public/gui/session_new/input.js b/binaries/data/mods/public/gui/session_new/input.js
index 393d9c26c9..34123f2225 100644
--- a/binaries/data/mods/public/gui/session_new/input.js
+++ b/binaries/data/mods/public/gui/session_new/input.js
@@ -65,7 +65,7 @@ function findGatherType(gatherer, supply)
/**
* Determine the context-sensitive action that should be performed when the mouse is at (x,y)
*/
-function determineAction(x, y)
+function determineAction(x, y, fromMinimap)
{
var selection = g_Selection.toList();
@@ -89,7 +89,9 @@ function determineAction(x, y)
return entState && entState.rallyPoint;
});
- var targets = Engine.PickEntitiesAtPoint(x, y);
+ var targets = [];
+ if (!fromMinimap)
+ targets = Engine.PickEntitiesAtPoint(x, y);
// If there's a target unit
if (targets.length)
@@ -119,13 +121,13 @@ function determineAction(x, y)
// If the target is a resource and we have the right kind of resource gatherers selected, then gather
// If the target is a foundation and we have builders selected, then build (or repair)
// If the target is an enemy, then attack
- if (targetState.resourceSupply && (playerOwned || gaiaOwned))
- {
+ if (targetState.resourceSupply && (playerOwned || gaiaOwned))
+ {
var resource = findGatherType(entState.resourceGatherRates, targetState.resourceSupply);
if (resource)
return {"type": "gather", "cursor": "action-gather-"+resource, "target": targets[0]};
}
- else if (targetState.foundation && entState.buildEntities && playerOwned)
+ else if (targetState.foundation && entState.buildEntities && playerOwned)
{
return {"type": "build", "cursor": "action-build", "target": targets[0]};
}
@@ -528,7 +530,7 @@ function handleInputAfterGui(ev)
return true;
default:
- throw new Error("Invalid action.type "+action.type);
+ error("Invalid action.type "+action.type);
}
}
break;
@@ -608,6 +610,45 @@ function handleInputAfterGui(ev)
return false;
}
+function handleMinimapEvent(target)
+{
+ // Partly duplicated from handleInputAfterGui(), but with the input being
+ // world coordinates instead of screen coordinates.
+
+ if (inputState == INPUT_NORMAL)
+ {
+ var fromMinimap = true;
+ var action = determineAction(undefined, undefined, fromMinimap);
+ if (!action)
+ return false;
+
+ var selection = g_Selection.toList();
+
+ var queued = (specialKeyStates[SDLK_RSHIFT] || specialKeyStates[SDLK_LSHIFT]);
+
+ switch (action.type)
+ {
+ case "move":
+ Engine.PostNetworkCommand({"type": "walk", "entities": selection, "x": target.x, "z": target.z, "queued": queued});
+ return true;
+
+ case "set-rallypoint":
+ Engine.PostNetworkCommand({"type": "set-rallypoint", "entities": selection, "x": target.x, "z": target.z});
+ // Display rally point at the new coordinates, to avoid display lag
+ Engine.GuiInterfaceCall("DisplayRallyPoint", {
+ "entities": selection,
+ "x": target.x,
+ "z": target.z
+ });
+ return true;
+
+ default:
+ error("Invalid action.type "+action.type);
+ }
+ }
+ return false;
+}
+
// Called by GUI when user clicks construction button
function startBuildingPlacement(buildEntType)
{
diff --git a/binaries/data/mods/public/gui/session_new/session.xml b/binaries/data/mods/public/gui/session_new/session.xml
index c76b0c6751..2c723b9c2d 100644
--- a/binaries/data/mods/public/gui/session_new/session.xml
+++ b/binaries/data/mods/public/gui/session_new/session.xml
@@ -310,7 +310,9 @@
+ >
+ handleMinimapEvent(arguments[0]);
+
diff --git a/source/gui/IGUIObject.cpp b/source/gui/IGUIObject.cpp
index 248c683285..8ba2809f24 100644
--- a/source/gui/IGUIObject.cpp
+++ b/source/gui/IGUIObject.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 2009 Wildfire Games.
+/* Copyright (C) 2010 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@@ -26,6 +26,7 @@ IGUIObject
#include "gui/scripting/JSInterface_IGUIObject.h"
#include "gui/scripting/JSInterface_GUITypes.h"
+#include "scriptinterface/ScriptVal.h"
#include "ps/CLogger.h"
#define LOG_CATEGORY L"gui"
@@ -509,6 +510,8 @@ void IGUIObject::ScriptEvent(const CStr& Action)
JSObject* jsGuiObject = JS_ConstructObjectWithArguments(g_ScriptingHost.getContext(), &JSI_IGUIObject::JSI_class, m_pGUI->m_ScriptObject, NULL, 1, &guiObject);
debug_assert(jsGuiObject); // TODO: Handle errors
+ // TODO: why don't we use GetJSObject here?
+
// Prevent it from being garbage-collected before it's passed into the function
JS_AddRoot(g_ScriptingHost.getContext(), &jsGuiObject);
@@ -537,6 +540,24 @@ void IGUIObject::ScriptEvent(const CStr& Action)
JS_RemoveRoot(g_ScriptingHost.getContext(), &jsGuiObject);
}
+void IGUIObject::ScriptEvent(const CStr& Action, const CScriptValRooted& Argument)
+{
+ std::map::iterator it = m_ScriptHandlers.find(Action);
+ if (it == m_ScriptHandlers.end())
+ return;
+
+ JSObject* object = GetJSObject();
+
+ jsval arg = Argument.get();
+
+ jsval result;
+ JSBool ok = JS_CallFunctionValue(g_ScriptingHost.getContext(), object, OBJECT_TO_JSVAL(*it->second), 1, &arg, &result);
+ if (!ok)
+ {
+ JS_ReportError(g_ScriptingHost.getContext(), "Errors executing script action \"%s\"", Action.c_str());
+ }
+}
+
JSObject* IGUIObject::GetJSObject()
{
// Cache the object when somebody first asks for it, because otherwise
diff --git a/source/gui/IGUIObject.h b/source/gui/IGUIObject.h
index a656145234..1ffdf2249a 100644
--- a/source/gui/IGUIObject.h
+++ b/source/gui/IGUIObject.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2009 Wildfire Games.
+/* Copyright (C) 2010 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@@ -59,6 +59,7 @@ The base class of an object
struct SGUISetting;
struct SGUIStyle;
class CGUI;
+class CScriptValRooted;
//--------------------------------------------------------
// Macros
@@ -437,11 +438,21 @@ protected:
/**
* Execute the script for a particular action.
* Does nothing if no script has been registered for that action.
+ * The mouse coordinates will be passed as the first argument.
*
* @param Action Name of action
*/
void ScriptEvent(const CStr& Action);
+ /**
+ * Execute the script for a particular action.
+ * Does nothing if no script has been registered for that action.
+ *
+ * @param Action Name of action
+ * @param Argument Argument to pass to action
+ */
+ void ScriptEvent(const CStr& Action, const CScriptValRooted& Argument);
+
void SetScriptHandler(const CStr& Action, JSObject* Function);
//@}
diff --git a/source/gui/MiniMap.cpp b/source/gui/MiniMap.cpp
index a866a67bec..266a4d8080 100644
--- a/source/gui/MiniMap.cpp
+++ b/source/gui/MiniMap.cpp
@@ -36,6 +36,7 @@
#include "ps/World.h"
#include "renderer/Renderer.h"
#include "renderer/WaterManager.h"
+#include "scriptinterface/ScriptInterface.h"
#include "simulation2/Simulation2.h"
#include "simulation2/components/ICmpMinimap.h"
@@ -135,19 +136,18 @@ void CMiniMap::SetCameraPos()
void CMiniMap::FireWorldClickEvent(int button, int clicks)
{
- // TODO: we ought to pass this through to the GUI system
-
- //debug_printf(L"FireWorldClickEvent: button %d, clicks %d\n", button, clicks);
-
-/*
+ // Determine X and Z according to proportion of mouse position and minimap
CPos MousePos = GetMousePos();
- CVector2D Destination;
- //X and Z according to proportion of mouse position and minimap
- Destination.x = CELL_SIZE * m_MapSize *
- ( (MousePos.x - m_CachedActualSize.left) / m_CachedActualSize.GetWidth() );
- Destination.y = CELL_SIZE * m_MapSize * ( (m_CachedActualSize.bottom - MousePos.y) /
- m_CachedActualSize.GetHeight() );
-*/
+ float x = CELL_SIZE * m_MapSize *
+ ((MousePos.x - m_CachedActualSize.left) / m_CachedActualSize.GetWidth());
+ float z = CELL_SIZE * m_MapSize *
+ ((m_CachedActualSize.bottom - MousePos.y) / m_CachedActualSize.GetHeight());
+
+ CScriptValRooted coords;
+ g_ScriptingHost.GetScriptInterface().Eval("({})", coords);
+ g_ScriptingHost.GetScriptInterface().SetProperty(coords.get(), "x", x, false);
+ g_ScriptingHost.GetScriptInterface().SetProperty(coords.get(), "z", z, false);
+ ScriptEvent("worldclick", coords);
UNUSED2(button);
UNUSED2(clicks);