Main Menu & GUI questions

Ask for help about creating mods and scripts for Grimrock 2 or share your tips, scripts, tools and assets with other modders here. Warning: forum contains spoilers!
User avatar
akroma222
Posts: 1029
Joined: Thu Oct 04, 2012 10:08 am

Main Menu & GUI questions

Post by akroma222 »

Hey All,
A few questions regarding what can and can't be done at Party Creation...

First & Foremost - can we somehow access / create a drawGui function while creating champions ??

.... what Ive messed around with so far ....
When I choose to start a New Game (vanilla campaign), I can access the Party object w the console
>>> print(party.party) returns a table
Ive tried messing with a few things:

1. party.party:move(dir) & party.party:turn(dir)
>>> but nothing happens (prints nil to the console)

2. party.party:rest() & wakeup()
>>> will actually fade out the screen to black
(and I assume allows time to pass as if you are resting too, because I woke up and it was night time :roll: )
SpoilerShow
Image
2. party.party:getChampion(ord)
>>> if there is a champion created then a table is returned and I can use getName() ....
>>> ordinal slots not yet containing a champion will return a table too but return false with getEnabled()

But! None of this can be done if choosing to play a custom dungeon (party.party returns nil)
I defined a party object in a test dungeon which printed INITIALIZE in its onInit hook...
>> spawn("party") did indeed spawn the party object (with print) ......
but then must have been destroyed as trying to access the party object afterwards returned nil :cry: :oops:

Other things:
It seems the main menu is Level: 0, called "Unnamed" and party.map:isVisited() returns true
The main menu level also contains the objects defined in the asset pack's mainmenu.lua
(menu_fog / island / ocean / sky / camera / heightmap) - But! .....
standard_assets.lua shows that mainmenu.lua is not imported with the rest of the asset packs lua files ? :? ?

I decided to disable / move those menu objects around and take some pics to feel like I had done something useful w my time
SpoilerShow
Image
SpoilerShow
Image
SpoilerShow
Image
Not very useful at all really

Basically, I would like to know what is and isnt possible to mess with while the main menu party creation is going on
specifically, can I use any draw functions / access the / any party object at this stage
I tried searching for answers here obviously but came up w nothing
Any help or guidance regarding any of the above would be rather splendid

Akroma :)
minmay
Posts: 2768
Joined: Mon Sep 23, 2013 2:24 am

Re: Main Menu & GUI questions

Post by minmay »

The custom dungeon isn't loaded until the player clicks either "Play" or "Create Characters". When character creation starts, your init.lua will be run but your dungeon.lua won't, so you won't have a dungeon. During the character creation screen, your MaterialEx.onUpdate hooks and your hooks for traits/skills (onRecomputeStats) etc. will run. There are a lot of things you can do from within these hooks, but obtaining a GraphicsContext is not one of them, sorry. Rearranging the background is certainly possible with this method though.
You won't be able to get to the party either; it exists, but it's not on a map yet so you can't get it with findEntity(). But you couldn't do anything useful with it on the character creation screen anyway; you already have access to the champions.
Grimrock 1 dungeon
Grimrock 2 resources
I no longer answer scripting questions in private messages. Please ask in a forum topic or this Discord server.
User avatar
akroma222
Posts: 1029
Joined: Thu Oct 04, 2012 10:08 am

Re: Main Menu & GUI questions

Post by akroma222 »

your init.lua will be run but your dungeon.lua won't
Right! So, no dungeon nor its contents .... only what is contained within or imported by init.lua
MaterialEx.onUpdate hooks and your hooks for traits/skills (onRecomputeStats) etc. will run.
Ah yes, Material onUpdate , Skills & Traits hooks .... that is good news!
Thanks for the swift reply minmay, I have some ideas to test out now :D
(will report back w progress) 8-) :geek:
User avatar
akroma222
Posts: 1029
Joined: Thu Oct 04, 2012 10:08 am

Re: Main Menu & GUI questions

Post by akroma222 »

Hey All,
questions regarding champion attack panel GUI...

1. How do we mimic / recreate the Attack Panels' behavior when click dragging one champion's panel into another (in order to swap party positions)

2. Is it possible to rotate a GuiItem or Image around a center point (like making a machine cog turn) with any of the GraphicsComponent options (drawImage, drawImage2, translate etc)

Any help appreciated... the GUI stuff stumps me everytime :oops: :roll:
Akroma
User avatar
Isaac
Posts: 3172
Joined: Fri Mar 02, 2012 10:02 pm

Re: Main Menu & GUI questions

Post by Isaac »

akroma222 wrote:Hey All,
questions regarding champion attack panel GUI...

1. How do we mimic / recreate the Attack Panels' behavior when click dragging one champion's panel into another (in order to swap party positions)

2. Is it possible to rotate a GuiItem or Image around a center point (like making a machine cog turn) with any of the GraphicsComponent options (drawImage, drawImage2, translate etc)

Any help appreciated... the GUI stuff stumps me everytime :oops: :roll:
Akroma
1. AFAIK, you don't need to... at least, in my tiger_form mod, the X & Y context locations seem to get updated as the player drags the panel. I didn't do any of that myself; but the graphics stay relative. On second thought... it would make a lot of sense if the engine just simply moves a snapshot of the panel instead. My guess is that that is what it does, rather than update the context positions. You cannot interact with the panel while it moves.

2. The way to do it is to manually animate it with the region coordinates. Make your cog as a sprite sheet, and update the texture position every frame.

**Funfact... You can animate GUI Icons the same way (using a sprite sheet), but instead of region coordinates, you just update the Icon from the custom (sprite-sheet) icon atlas.

Image
(This could be used to make flickering torches, on the mouse, and when equipped.)
User avatar
akroma222
Posts: 1029
Joined: Thu Oct 04, 2012 10:08 am

Re: Main Menu & GUI questions

Post by akroma222 »

Isaac wrote:1. AFAIK, you don't need to... at least, in my tiger_form mod, the X & Y context locations seem to get updated as the player drags the panel. I didn't do any of that myself; but the graphics stay relative. On second thought... it would make a lot of sense if the engine just simply moves a snapshot of the panel instead. My guess is that that is what it does, rather than update the context positions. You cannot interact with the panel while it moves.
Teehee! Thanks heaps Isaac... I spent quite a bit of time and a bunch of useless code trying to get that to work through onDrawGui hook :lol: :roll: :oops:
Yup - onDrawAttackPanel passes you the X, Y coords of the attack panel (even as you drag it around) and modified things are all tied into the panel when performing
the champion party position swap
I got some tidying up to do through (atm - dragging the attack panels will stop drawing the champions portrait and their race specified hand icon...)
SpoilerShow
Image
swapping ord 1 & 4....
SpoilerShow
Image
Isaac wrote:2. The way to do it is to manually animate it with the region coordinates. Make your cog as a sprite sheet, and update the texture position every frame.
**Funfact... You can animate GUI Icons the same way (using a sprite sheet), but instead of region coordinates, you just update the Icon from the custom (sprite-sheet) icon atlas.
Definitely a Fun Fact! However.... I may require further explanation.
I veered off track a little ..... initial trials as a spell object - I will experiment further and report back!
User avatar
akroma222
Posts: 1029
Joined: Thu Oct 04, 2012 10:08 am

Re: Main Menu & GUI questions

Post by akroma222 »

Hey All!
I have some questions regarding TOOL TIPS :o
Recently Ive been modifying the champs Attack Panels and Character Sheet / Menus - and needed to hide / replace / change the vanilla game's Tooltips for Stats etc
I believe I may have succeeded - sort of.... but would like confirmation that Ive either done it correctly or made a terrible mess

0. Created a gui object using grimtk - but it doesnt use any images or backgrounds.
Its just a bunch of sort of invisible GPushButtons (you can see the rectangular hover tint in the pic below near 'Hunger')
(this is not important here atm, im using the press/release to do other things - but the buttons do line up with the Tooltip related stats)

1. add Connectors from onDrawInventory, onDrawStats, onDrawSkills, & onDrawTraits ==> 3 functions ... which are activated....

One (f) that calls context.drawImage2 (I made a texture for the new CharSheet)
Another (f) to set a global Variable 'charSheetOpen' = true
And the last (f) activates/shows the grimtk button object mentioned above

2. In onDrawGUI hook - I check if 'charSheetOpen' == true. If so.... I run checks on the mouse Position....example:
SpoilerShow

Code: Select all

local health1, health2 = context.button("Health", 1527, 100, 150, 21)	
					if health1 or health2 then	
						tooltipScript.script.drawTooltip(self, context, 427, 976, 150, 21, 12, "Health")
					end
3. So if the mouse is within the specified area (context.button(ID,x,y,width,height)) then ....
a drawTooltip function is called, code here has been borrowed (from AndakRainor) and altered:
SpoilerShow

Code: Select all

tooltipRefTable = {
	{"Health", "njnnsldnlskdvnlksvnzlkvnzlkvn",  "njnnsldnlskdvnlksvnzlkvnzlkvn",  "njnnsldnlskdvnlksvnzlkvnzlkvn",  "njnnsldnlskdvnlksvnzlkvnzlkvn"},
}
---------------------------------------------------	getScale(context)
function getScale(context)
	local r = context.width / context.height
	return (r < 1.3 and 0.8 or r < 1.4 and 0.9 or 1) * context.height/1080
end
			
			
------------------------------------------------------drawChampionGUI(pcomp, context, champion)	
function drawTooltip(self, context, X, Y, W, H, B, txtRef)	
	----------------------------------------------------------	
	local w, h, f = context.width, context.height, getScale(context)
	local mX, mY = context.inverseTransformPoint(context.mouseX, context.mouseY)
	local xw = w - f * X		--1920,
	local yw = h - f * Y		-- 998		
	local ww = f * W			-- 
	local hw = f * H		
	local tText = {}
	------------------------
	for k, v in pairs(tooltipRefTable) do
		if type(v) == "table" and txtRef == v[1] then
			tText = table.copy(v)
			if tText ~= {} then
				break
			end
		end
	end
	-------------------------------------------------------------------------------CHECK SCREEN EDGES
	if ( xw < mX ) and ( mX < xw + ww ) and ( yw + 2 < mY ) and ( mY < yw + 2 + hw ) then
		
		------------------------------------
		context.font(fontSize[1 + math.floor(#fontSize * f * 0.5)] or fontSize[#fontSize])
		------------------------------------
		local TH = context.getLineHeight()
		local tipW, tipH, border = 0, #tText * TH, B or 12
		------------------------------------
		for _, l in ipairs(tText) do
			local lineW = context.getTextWidth(l)
			if lineW > tipW then 
				tipW = lineW 
			end
		end
		------------------------------------
		tipW, tipH	 = 		tipW + 2 * border, 	tipH + 2 * border
		------------------------------------
		local x = math.min(w - tipW - 2 * border, 		mX - tipW / 2)
		local y = mY < h / 2 and math.min(mY + 37, 1080 - tipH) 	or 		math.max(mY - 37 - tipH, 0)
		
		--------------------------------------------------transparent shaded RECTANGLE
		context.color(0, 0, 0, 192)
		context.drawRect(x - 1, y - 1, tipW + 2, tipH + 2)
		--------------------------------------------------white BORDER	
		context.color(255, 255, 255, 255)
		----------------------------------------lines
		context.drawGuiItem2("DialogFrameSideBottom", 	x, 			y+tipH-2, 	0, 0, 		90, 5, 		tipW, 5)
		context.drawGuiItem2("DialogFrameSideLeft", 	x-3, 		y, 			0, 0, 		5, 90, 		5, tipH)
		context.drawGuiItem2("DialogFrameSideRight", 	x+tipW-2, 	y, 			0, 0, 		5, 90, 		5, tipH)
		context.drawGuiItem2("DialogFrameSideTop", 		x, 			y-3, 		0, 0, 		90, 5, 		tipW, 5)
		--------------------------------------corners
		context.drawGuiItem("DialogFrameCornerBottomLeft", 	x-3, 		y+tipH-2)
		context.drawGuiItem("DialogFrameCornerBottomRight", x+tipW-2, 	y+tipH-2)
		context.drawGuiItem("DialogFrameCornerTopLeft", 	x-3, 		y-3)
		context.drawGuiItem("DialogFrameCornerTopRight", 	x+tipW-2, 	y-3)
		
		---------------------------------------tooltip COORDS
		context.color(255, 255, 255, 255)
		x, y = x + border, y + border
		--------------------------------------------------tooltip TITLE
		context.font(fontSize[1 + math.floor(#fontSize * f)] or fontSize[#fontSize])
		context.drawText(tText[1], x, y + TH)
		--------------------------------------------------tooltip TEXT
		context.font(fontSize[1 + math.floor(#fontSize * f * 0.5)] or fontSize[#fontSize])
		for i = 2, #tText do 
			context.drawText(tText[i], x, y + i * TH) 
		end
	end
end
Now, when I run the mouse over the Statistic areas in the char sheet - my tooltips work!!!
(mouse is hovering over the 'Hunger' stat - you can see the grimtk buttons tint around it)
SpoilerShow
Image
However, there are 6 diff Statistic areas I need to check - and when the mouse runs over the border between those areas (ie, from one area into another)
.....the original vanilla tooltip flashes on screen for a split second. I suspect this has something to do with the way 'context.button(ID,x,y,w,h)' works ....
I believe it returns only 2 values (jKos wiki):
Returns two values indicating if the mouse cursor is inside, outside, entering, or exiting a specific area on the screen.

...and I have printed these to the console every frame - 2nd value is usually always true.
The first returns nil or false but I cant work out exactly how or why or what it is telling me.... :? :roll:

Can anyone steer me in the right direction regarding the returned values of 'context.button(ID,x,y,w,h)'
... and / or how to stop the original tooltips from flickering through my custom tooltips??

Akroma
Last edited by akroma222 on Thu Dec 07, 2017 5:04 pm, edited 2 times in total.
User avatar
akroma222
Posts: 1029
Joined: Thu Oct 04, 2012 10:08 am

Re: Main Menu & GUI questions

Post by akroma222 »

And Eh!? while Im showing recent works....
Attack Panels (each race has their own bare hand icons now):
SpoilerShow
Image
complete with race sound FX and inventory backgrounds:
SpoilerShow
Image
Its taking a while, but a Release should be soonish :lol:
User avatar
Isaac
Posts: 3172
Joined: Fri Mar 02, 2012 10:02 pm

Re: Main Menu & GUI questions

Post by Isaac »

@akroma222

Do these graphics overwrite the default graphics (after they render), or do these replace the default graphics? I had a tough time with the hands/paws for my tiger-form potion, and am still looking for the best way to implement them.
SpoilerShow
Image
*I've not used GrimTK yet; so far, I've only built composited frames from scratch.
(I suppose I should download it and read through it line by line. ;) )
User avatar
akroma222
Posts: 1029
Joined: Thu Oct 04, 2012 10:08 am

Re: Main Menu & GUI questions

Post by akroma222 »

Isaac, your Tiger Form attack swipe looks awesome hey! :twisted:
Did you return false at the end of the onDrawAttackPanel hook to remove the vanilla game's human hand icons?
From what I saw on your video, it seems to be in working order :geek:

OK, from what I can tell (and I'm likely incorrect), the drawing hooks overwrite after the default are rendered (literally draw over the top of them)
So, overwrite, not replace (I think :? )

And worth noting! - if you use grimtk - I think it draws after the party's drawing hooks have.
At first I was using grimtk to create the character sheet changes...
(GWindow with the background texture)
SpoilerShow

Code: Select all

{
		name = "charSheetTop",
		type = "GWindow",
		gravity = GTK.Constants.Gravity.West,
		offset = {1348, -348},							
		size = {550, 198},
		borderColor = {0, 0, 0, 0},
		borders = {0, 0, 0, 0},
		bgColor = {0, 0, 0, 0},
		bgDrawMode = GTK.Constants.ImageDrawMode.Anchored,
		draggable = false,
		freezeAI = false,
		lockParty = false,
		disableMouseLook = false,
		bgImage = "charSheetTopPattern2",
....but that was drawing the background over any Tooltips I created through the onDrawGui hook
So I placed the background though the drawing hooks instead (fixing the overwriting tooltip issue)
SpoilerShow

Code: Select all

onDrawTraits = function(self, context, champion)
				--(self, context, champion)
				------------------------------------------------------------------
				local w, h, f = context.width, context.height, context.height/1080
				local MX, MY = context.mouseX, context.mouseY
				local mX,mY = context.inverseTransformPoint(MX, MY)
				local mLeft, mRight = context.mouseDown(0), context.mouseDown(2)
				-------------------------------------------------
				grimtkAttackPanels.script.showCharSheetTopGui()
				grimtkAttackPanels.script.setCharSheetShowing(true)
				akromaSTATISTICS.script.drawCharacterSheetTop(pcomp, context, champion)
                  -------------------------------------------------
Ive left the grimtk GWindow intact through and attached 6 invisible pushButtons to it (as 'children')
SpoilerShow

Code: Select all

{
		name = "charSheetTop",
		type = "GWindow",
		gravity = GTK.Constants.Gravity.West,
		offset = {1348, -348},							
		size = {550, 198},
		borderColor = {0, 0, 0, 0},
		borders = {0, 0, 0, 0},
		bgColor = {0, 0, 0, 0},
		bgDrawMode = GTK.Constants.ImageDrawMode.Anchored,
		draggable = false,
		freezeAI = false,
		lockParty = false,
		disableMouseLook = false,
		--bgImage = "charSheetTopPattern2",   --background removed
		children = {
			
			-------------- Tooltip HEALTH button
			{	
				type = "GPushButton",
				name = "tooltip_Health",
				position = {175, 40},
				size = {140, 20},
				--bgImage          -- no background
				bgColor = {0, 0, 0, 0},		
				borderColor = {0, 0, 0, 0},
				borders = {0, 0, 0, 0},
				tintHover = {0, 0, 0, 32},
				tintDown = {128, 128, 128, 32},
				bgDrawMode = GTK.Constants.ImageDrawMode.Anchored,
				onPressed = self.go.id .. ".script.onPressedShowTooltip",
				onPressedSound = "item_equip",
				onReleased = self.go.id .. ".script.onReleasedHideTooltip",	
				label = {
					text = "Health",
					textAlign = "left",
					textColor = {225, 225, 225, 255}, 	
					font = "tiny",
				},
			},
			-------------- Tooltip ENERGY button
			{	
				type = "GPushButton",
				name = "tooltip_Energy",
				position = {175, 60},
				size = {140, 20},
				--bgImage          -- no background
				bgColor = {0, 0, 0, 0},		
				borderColor = {0, 0, 0, 0},
				borders = {0, 0, 0, 0},
				tintHover = {0, 0, 0, 32},
				tintDown = {128, 128, 128, 32},
				bgDrawMode = GTK.Constants.ImageDrawMode.Anchored,
				onPressed = self.go.id .. ".script.onPressedShowTooltip",
				onPressedSound = "item_equip",
				onReleased = self.go.id .. ".script.onReleasedHideTooltip",	
				label = {
					text = "Energy",
					textAlign = "left",
					textColor = {225, 225, 225, 255}, 	
					font = "tiny",
				},
			},
			-------------- Tooltip STAMINA button
			{	
				type = "GPushButton",
				name = "tooltip_Stamina",
				position = {175, 80},
				size = {140, 20},
				--bgImage          -- no background
				bgColor = {0, 0, 0, 0},		
				borderColor = {0, 0, 0, 0},
				borders = {0, 0, 0, 0},
				tintHover = {0, 0, 0, 32},
				tintDown = {128, 128, 128, 32},
				bgDrawMode = GTK.Constants.ImageDrawMode.Anchored,
				onPressed = self.go.id .. ".script.onPressedShowTooltip",
				onPressedSound = "item_equip",
				onReleased = self.go.id .. ".script.onReleasedHideTooltip",	
				label = {
					text = "Stamina",
					textAlign = "left",
					textColor = {225, 225, 225, 255}, 	
					font = "tiny",
				},
			},
			
			
			
			-------------- Tooltip EXPERIENCE button
			{	
				type = "GPushButton",
				name = "tooltip_Experience",
				position = {175, 100},
				size = {140, 20},
				--bgImage          -- no background
				bgColor = {0, 0, 0, 0},		
				borderColor = {0, 0, 0, 0},
				borders = {0, 0, 0, 0},
				tintHover = {0, 0, 0, 32},
				tintDown = {128, 128, 128, 32},
				bgDrawMode = GTK.Constants.ImageDrawMode.Anchored,
				onPressed = self.go.id .. ".script.onPressedShowTooltip",
				onPressedSound = "item_equip",
				onReleased = self.go.id .. ".script.onReleasedHideTooltip",	
				label = {
					text = "Experience",
					textAlign = "left",
					textColor = {225, 225, 225, 255}, 	
					font = "tiny",
				},
			},
			-------------- Tooltip HUNGER button
			{	
				type = "GPushButton",
				name = "tooltip_Hunger",
				position = {175, 120},
				size = {140, 20},
				--bgImage          -- no background
				bgColor = {0, 0, 0, 0},		
				borderColor = {0, 0, 0, 0},
				borders = {0, 0, 0, 0},
				tintHover = {0, 0, 0, 32},
				tintDown = {128, 128, 128, 32},
				bgDrawMode = GTK.Constants.ImageDrawMode.Anchored,
				onPressed = self.go.id .. ".script.onPressedShowTooltip",
				onPressedSound = "item_equip",
				onReleased = self.go.id .. ".script.onReleasedHideTooltip",	
				label = {
					text = "Hunger",
					textAlign = "left",
					textColor = {225, 225, 225, 255}, 	
					font = "tiny",
				},
			},
			-------------- Tooltip MORALE button
			{	
				type = "GPushButton",
				name = "tooltip_Morale",
				position = {175, 140},
				size = {140, 20},
				--bgImage          -- no background
				bgColor = {0, 0, 0, 0},		
				borderColor = {0, 0, 0, 0},
				borders = {0, 0, 0, 0},
				tintHover = {0, 0, 0, 32},
				tintDown = {128, 128, 128, 32},
				bgDrawMode = GTK.Constants.ImageDrawMode.Anchored,
				onPressed = self.go.id .. ".script.onPressedShowTooltip",
				onPressedSound = "item_equip",
				onReleased = self.go.id .. ".script.onReleasedHideTooltip",	
				label = {
					text = "Morale",
					textAlign = "left",
					textColor = {225, 225, 225, 255}, 	
					font = "tiny",
				},
			},
basically its going to be a bunch of invisible buttons attached to the invisible GWindow that will manage tool tip click effects

Definitely take a look at grimtk -
Constants.lua & Inputs.lua are short simple references,
Widgets.lua lists all the diff pre made graphics objects you can call up / create
Core.lua is the guts of it and isnt all need to know material for the user
At the very least it can save you a bunch of time here and there by using the pre made graphics objects instead of doing it from scratch :P

I can post up the code for my drawing hooks (drawing character sheet & attack panels) if you like..?? but I will need to clean it up first :oops:
...and it wont be complete - Im still to implement features such as: 'shift' key stack management, cooldown fx for dual wielding, power attack visuals, etc
Post Reply