The core.lua does define GUI, and it is a lot of stuff. Not sure why it would be seen as nil if it has an abundance of values. What does it even mean by trying to index a nil value? I feel like this is turning out to not be a simple question, and needs more than just a simple answer, hah.
For sake of clarity, here is the entire grimtk init.lua, and yeah, it is definitely imported correctly, lol.
Code: Select all
defineObject{
name = "grimtk",
baseObject = "script_entity",
components = {
{
class = "Null",
onInit = function(self)
if ( findEntity("GTK") == nil ) then
local gtk = spawn("script_entity", 1, 1, 1, 1, 1, "GTK");
gtk.script:loadFile("mod_assets/ext/grimtk/scripts/hook.lua");
gtk:createComponent("Script", "Constants"):loadFile("mod_assets/ext/grimtk/scripts/gtk/constants.lua");
gtk:createComponent("Script", "Input"):loadFile("mod_assets/ext/grimtk/scripts/gtk/input.lua");
gtk:createComponent("Script", "Core"):loadFile("mod_assets/ext/grimtk/scripts/gtk/core.lua");
gtk:createComponent("Script", "Widgets"):loadFile("mod_assets/ext/grimtk/scripts/gtk/widgets.lua");
if ( Editor.isRunning() ) then
gtk:createComponent("Script", "Debug"):loadFile("mod_assets/ext/grimtk/scripts/gtk/debug.lua");
end
delayedCall("GTK", 0.01, "emitGtkDidLoad");
end
if ( findEntity("GTKGui") == nil ) then
local gtkgui = spawn("script_entity", 1, 1, 1, 1, 1, "GTKGui");
gtkgui:createComponent("Script", "Basic"):loadFile("mod_assets/ext/grimtk/scripts/gtkgui/basic.lua");
gtkgui:createComponent("Script", "Dialogue"):loadFile("mod_assets/ext/grimtk/scripts/gtkgui/dialogue.lua");
gtkgui:createComponent("Script", "Cinematic"):loadFile("mod_assets/ext/grimtk/scripts/gtkgui/cinematic.lua");
end
end
}
}
}
--
-- If the Log2 Framework has been included before this script, then we will use the framework instead.
-- Otherwise, the default behaviour is to override these hooks.
-- NOTE: If you are using the framework, you MUST define an onDrawGui hook SOMEWHERE (even an empty one).
--
if fw_hook == nil then
defineObject{
name = "party",
baseObject = "party",
components = {
{
class = "Party",
onDrawGui = function(party, g)
end,
onRest = function(party)
if ( findEntity("GTK") ) then
if ( GTK.Core.GUI:isPartyLocked() ) then
return false;
end
end
end,
onWakeUp = function(party)
if ( findEntity("GTK") ) then
if ( GTK.Core.GUI:isPartyLocked() ) then
return false;
end
end
end
}
}
}
end
Also, here is the segment in the core.lua that defines GUI:
Code: Select all
GUI = {
_tkContext = TKContext.create(),
_debugMessages = { },
_windows = { },
_images = { },
_updateables = { },
_shortcuts = { },
_nextAutoId = 1,
_focusWidget = nil,
_partyLocks = 0,
_keyboardLocks = 0,
_aiLocks = 0,
_lastUpdateTime = 0,
_deltaTime = 0,
_maxDeltaTime = 0.25,
_delayedCalls = { },
isEnabled = true,
dimBackground = false,
mouseState = GTK.Input.MouseState.create(),
keyboardState = GTK.Input.KeyboardState.create(),
getContext = function(self)
return self._tkContext;
end,
addWindow = function(self, window)
if ( window:name() == nil ) then
Console.warn("Cannot create Root window without a name.");
return false;
end
if ( self._windows[window:name()] ~= nil ) then
Console.warn("Root window already exists with that name.");
return false;
end
self._windows[window:name()] = window;
self:showWindow(window:name());
return true;
end,
createWindow = function(self, args)
local window = GTK.Widgets.GWindow.create(args);
if ( self:addWindow(window) == true ) then
return window;
end
return nil;
end,
destroyWindow = function(self, window)
local windowName = nil;
if ( type(window) == "table" ) then
windowName = window:name();
elseif ( type(window) == "string" ) then
windowName = window;
end
if ( windowName and self._windows[windowName] ) then
self:hideWindow(windowName);
self._windows[windowName] = nil;
end
end,
getWindow = function(self, windowName)
return self._windows[windowName];
end,
showWindow = function(self, windowName)
local window = self._windows[windowName];
if ( window ) then
window:setVisible(true);
end
end,
hideWindow = function(self, windowName)
local window = self._windows[windowName];
if ( window ) then
window:setVisible(false);
end
end,
addUpdateable = function(self, updateable)
if ( updateable.update == nil or type(updateable.update) ~= "function" or updateable.updateableId == nil ) then
Console.warn("[GTK] Attempted to register invalid updateable");
return;
end
if ( self._updateables[updateable.updateableId] ~= nil ) then
Console.warn("[GTK] An updateable with that name already exists.");
return;
end
if ( updateable.startUpdates ~= nil ) then
updateable:startUpdates();
end
self._updateables[updateable.updateableId] = updateable;
end,
removeUpdateable = function(self, updateable)
local id = nil;
if ( type(updateable) == "string" ) then
id = updateable;
elseif ( updateable.updateableId ~= nil ) then
id = updateable.updateableId;
end
if ( id and self._updateables[id] ~= nil ) then
if ( self._updateables[id].endUpdates ~= nil ) then
self._updateables[id]:endUpdates();
end
self._updateables[id] = nil;
end
end,
update = function(self, guiContext)
if ( self.isEnabled == false ) then
return
end
local playTime = GameMode.getStatistic("play_time");
self._deltaTime = playTime - self._lastUpdateTime;
self._lastUpdateTime = playTime;
if ( self._deltaTime > self._maxDeltaTime ) then
self._deltaTime = self._maxDeltaTime;
end
if ( #self._delayedCalls > 0 ) then
local toRemove = { };
for i=#self._delayedCalls,1,-1 do
local v = self._delayedCalls[i];
v["delay"] = v["delay"] - self._deltaTime;
if ( v["delay"] < 0 ) then
if ( v["func"] ) then
v["func"](v["param"]);
end
table.remove(self._delayedCalls, i);
end
end
end
for _,updateable in pairs(self._updateables) do
updateable:update(self._deltaTime);
end
self._tkContext:start(guiContext);
self.mouseState:reset(self._tkContext);
self.keyboardState:reset(self._tkContext);
local dimScreen = false;
local screenSize = self._tkContext:size();
for _,window in pairs(self._windows) do
if ( window.data.dimScreen ) then
dimScreen = true;
end
end
if ( dimScreen ) then
self._tkContext:drawRect({ position={0,0}, size=screenSize, bgColor={0, 0, 0, 160} });
end
for _,window in pairs(self._windows) do
if ( window.data.visible == true ) then
if ( (window.data.fullscreen == true) and ((window.data.size[1] == screenSize[1]) or (window.data.size[2] ~= screenSize[2])) ) then
window:setSize(screenSize[1], screenSize[2]);
end
self:visit(window);
end
end
if ( #self._debugMessages > 0 ) then
self._tkContext:drawText({ position={10, 10}, size={1200, screenSize[2]-20}, text=table.concat(self._debugMessages, "\n"), textColor={255,255,255,255}, font="tiny" });
end
self.keyboardState:commit();
self.mouseState:commit();
self._tkContext:finish();
end,
visit = function(self, widget)
if ( widget == nil or widget.data.visible == false ) then
return
end
widget:updatePositionInParent(self._tkContext);
-- Slightly annoying that we do mouse stuff here (and it's not completely separate)
-- but it's more efficient to only walk the tree of workspaces once...
self.mouseState:visitWidget(self._tkContext, widget);
self.keyboardState:visitWidget(self._tkContext, widget);
widget:update(self._tkContext, self._deltaTime);
self._tkContext:setWorkspaceOpacity(widget.data.opacity);
widget:draw(self._tkContext);
self._tkContext:pushWorkspace(widget.data.position, widget.data.size);
for _,child in ipairs(widget._children) do
self:visit(child);
end
self._tkContext:popWorkspace();
end,
addImage = function(self, args)
local image = { };
if ( (args.name == nil) or (args.path == nil) or (args.size == nil)) then
Console.warn("[addImage] requires at least a name, a path and a size.");
end
if ( args.path:sub(-4):lower() ~= ".tga" ) then
Console.warn("[addImage] '" .. args.path .. "' does not end in .tga");
end
if ( args.path:find("//") ) then
Console.warn("[addImage] '" .. args.path .. "' conains '//' which WILL FAIL when exported!");
end
if ( (args.path:sub(1, 6) ~= "assets") and (args.path:sub(1, 10) ~= "mod_assets") ) then
Console.warn("[addImage] '" .. args.path .. "' does not start with assets or mod_assets." );
end
image.name = args.name;
image.path = args.path;
image.size = args.size;
image.margin = iff(args.margin ~= nil, args.margin, {8, 8, 8, 8});
image.origin = iff(args.origin ~= nil, args.origin, {0,0});
self._images[image.name] = image;
end,
getImage = function(self, name)
return self._images[name];
end,
getImageSize = function(self, name)
local image = self._images[name];
if ( image == nil ) then return {0, 0}; end
return image.size;
end,
nextAutoWidgetId = function(self)
local id = "widget_" .. self._nextAutoId;
self._nextAutoId = self._nextAutoId + 1;
return id;
end,
setFocus = function(self, widget)
if ( self._focusWidget ~= nil ) then
self:unlockKeyboard();
self:unlockParty();
self.keyboardState:finishTextEntry();
self._focusWidget:_triggerPlug("onLoseFocus");
self._focusWidget:doLoseFocus();
self._focusWidget = nil;
end
if ( widget ~= nil ) then
self:lockKeyboard();
self:lockParty();
self.keyboardState:startTextEntry(widget);
self._focusWidget = widget;
self._focusWidget:doGainFocus();
self._focusWidget:_triggerPlug("onGainFocus");
GameMode.setGameFlag("DisableKeyboardShortcuts", true);
end
end,
focusWidget = function(self)
return self._focusWidget;
end,
delayedCall = function(self, delay, param, func)
table.insert(self._delayedCalls, {delay = delay, func = func, param = param});
end,
lockParty = function(self)
self._partyLocks = self._partyLocks + 1;
GameMode.setGameFlag("DisableMovement", true);
GameMode.setGameFlag("DisableMouseLook", true);
end,
unlockParty = function(self)
self._partyLocks = self._partyLocks - 1;
if ( self._partyLocks <= 0 ) then
GameMode.setGameFlag("DisableMovement", false);
GameMode.setGameFlag("DisableMouseLook", false);
self._partyLocks = 0;
end
end,
isPartyLocked = function(self)
return self._partyLocks > 0;
end,
lockKeyboard = function(self)
self._keyboardLocks = self._keyboardLocks + 1;
GameMode.setGameFlag("DisableKeyboardShortcuts", true);
end,
unlockKeyboard = function(self)
self._keyboardLocks = self._keyboardLocks - 1;
if ( self._keyboardLocks <= 0 ) then
self._keyboardLocks = 0;
self:delayedCall(0.1, self, function(self)
if ( self._keyboardLocks == 0 ) then
GameMode.setGameFlag("DisableKeyboardShortcuts", false);
end
end);
end
end,
isKeyboardLocked = function(self)
return self._keyboardLocks > 0;
end,
freezeAI = function(self)
self._aiLocks = self._aiLocks + 1;
GameMode.setGameFlag("DisableMonsterAI", true);
end,
unfreezeAI = function(self)
self._aiLocks = self._aiLocks - 1;
if ( self._aiLocks <= 0 ) then
GameMode.setGameFlag("DisableMonsterAI", false);
self._aiLocks = 0;
end
end,
isAIFrozen = function(self)
return self._aiLocks > 0;
end,
log = function(self, message)
if ( #self._debugMessages > 50 ) then
table.remove(self._debugMessages, 1);
end
table.insert(self._debugMessages, message);
end,
clearDebug = function(self)
self._debugMessages = { };
end,
toggleDebug = function(self)
if ( self._tkContext.debugMode == false) then
self._tkContext.debugMode = true;
if ( Editor.isRunning() ) then
GTK.Debug.showDebugWindow();
end
else
self._tkContext.debugMode = false;
if ( Editor.isRunning() ) then
GTK.Debug.destroyDebugWindow();
end
end
end,
}
I'd simply pull out GrimTK but I planned to use it for dialogue popups to give hints/story elements without having to locate and read a note in places that don't really have that option. Honestly I don't remember what all uses it already, been so long.