Ask a simple question, get a simple answer

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
AndakRainor
Posts: 674
Joined: Thu Nov 20, 2014 5:18 pm

Re: Ask a simple question, get a simple answer

Post by AndakRainor »

You need a script entity in your dungeon and set its source to your external lua file. Then choose a specific id for that script entity, so you can use that id anywhere you want.
User avatar
zimberzimber
Posts: 432
Joined: Fri Feb 08, 2013 8:06 pm

Re: Ask a simple question, get a simple answer

Post by zimberzimber »

And so I face another spell related issue. :cry:
When I have to change more than one thing related to the tileDamager I have to make any other modification after the first one not part of the 'spawn' line. I tried doing it separately, but it shows me an error saying 'tried to index local 'a' (a nil value)'

Now, I've followed some custom spell examples I've seen, and they used a 'local a = spawn(...)', and later changed the spawned object with 'a.tiledamager:setAttackPower(...)'

The function is defined in an external script and is linked into the game through a scrip entity on the first level, where I do the testing.
Here's the part of the function that causes the error:

Code: Select all

	local a = spawn(s, party.level, x, y, direction, party.elevation).tiledamager:setCastByChampion(champ:getOrdinal())
	a.tiledamager:setAttackPower(power)
Removing 'a.tiledamager:setAttackPower(power)' will stop it from crashing, but its needed for the spell to work properly.
My asset pack [v1.10]
Features a bit of everything! :D
User avatar
AndakRainor
Posts: 674
Joined: Thu Nov 20, 2014 5:18 pm

Re: Ask a simple question, get a simple answer

Post by AndakRainor »

Try that instead!

Code: Select all

  local a = spawn(s, party.level, x, y, direction, party.elevation)
  a.tiledamager:setCastByChampion(champ:getOrdinal())
  a.tiledamager:setAttackPower(power)
User avatar
akroma222
Posts: 1029
Joined: Thu Oct 04, 2012 10:08 am

Re: Ask a simple question, get a simple answer

Post by akroma222 »

Quick 2 questions:
1. What does projectile:pushForward() do??
2. What does champion:getDualClass() do??

Thanks all :D
User avatar
zimberzimber
Posts: 432
Joined: Fri Feb 08, 2013 8:06 pm

Re: Ask a simple question, get a simple answer

Post by zimberzimber »

AndakRainor wrote:Try that instead!

Code: Select all

  local a = spawn(s, party.level, x, y, direction, party.elevation)
  a.tiledamager:setCastByChampion(champ:getOrdinal())
  a.tiledamager:setAttackPower(power)
Huh.. This works... But why didn't the previous one work?
My asset pack [v1.10]
Features a bit of everything! :D
User avatar
Zo Kath Ra
Posts: 937
Joined: Sat Apr 21, 2012 9:57 am
Location: Germany

Re: Ask a simple question, get a simple answer

Post by Zo Kath Ra »

zimberzimber wrote:
AndakRainor wrote:Try that instead!

Code: Select all

  local a = spawn(s, party.level, x, y, direction, party.elevation)
  a.tiledamager:setCastByChampion(champ:getOrdinal())
  a.tiledamager:setAttackPower(power)
Huh.. This works... But why didn't the previous one work?
The spawn() function returns a game object.
The setCastByChampion() function always returns nil.

So this will set the variable "a" to the newly spawned game object:
local a = spawn(s, party.level, x, y, direction, party.elevation)

But this will set the variable "a" to nil:
local a = spawn(s, party.level, x, y, direction, party.elevation).tiledamager:setCastByChampion(champ:getOrdinal())

Maybe this shows it more clearly:
local a = spawn("wall_fire", party.level, party.x, party.y, party.facing, party.elevation)
local b = a.tiledamager:setAttackPower(0)
hudPrint("a = " .. tostring(a))
hudPrint("b = " .. tostring(b))
User avatar
zimberzimber
Posts: 432
Joined: Fri Feb 08, 2013 8:06 pm

Re: Ask a simple question, get a simple answer

Post by zimberzimber »

Zo Kath Ra wrote: The spawn() function returns a game object.
The setCastByChampion() function always returns nil.
Ah, I see. Thanks for clarifying!

And thanks to everyone who helped with the positioning, obstacle detection, and spell damage/source!

So here's my complete script for summoning tile damagers:

Code: Select all

function tileDamagerSpell(champ, direction, skill, s, power)
	local dx,dy = getForward(party.facing)
	local o = party.map:checkObstacle(party, party.facing)
	local x, y
	
	if party.map:isWall(party.x + dx, party.y + dy) then
		x = party.x
		y = party.y
	else
		x = party.x + dx
		y = party.y + dy
	end
	
	if party.map:getElevation(x, y) == party.elevation then
		if  not o or o == "dynamic_obstacle" then
			local a = spawn(s, party.level, x, y, direction, party.elevation)
			a.tiledamager:setCastByChampion(champ:getOrdinal())
			a.tiledamager:setAttackPower(power)
		else
			local a = spawn(s, party.level, party.x, party.y, direction, party.elevation)
			a.tiledamager:setCastByChampion(champ:getOrdinal())
			a.tiledamager:setAttackPower(power)
		end
		return
	else
		if  not o or o == "dynamic_obstacle" then
			for e in party.map:entitiesAt(x, y) do
				if e.platform and e.platform:isEnabled() and e.elevation == party.elevation then
					if  not o or o == "dynamic_obstacle" then
						local a = spawn(s, party.level, x, y, direction, party.elevation)
						a.tiledamager:setCastByChampion(champ:getOrdinal())
						a.tiledamager:setAttackPower(power)
					else
						local a = spawn(s, party.level, party.x, party.y, direction, party.elevation)
						a.tiledamager:setCastByChampion(champ:getOrdinal())
						a.tiledamager:setAttackPower(power)
					end
					return
				end
			end
		elseif (party.map:getElevation(party.x, party.y) == party.elevation) then
			local a = spawn(s, party.level, party.x, party.y, direction, party.elevation)
			a.tiledamager:setCastByChampion(champ:getOrdinal())
			a.tiledamager:setAttackPower(power)
			return
		end
	end
	playSound("spell_fizzle")
end
My asset pack [v1.10]
Features a bit of everything! :D
User avatar
AndakRainor
Posts: 674
Joined: Thu Nov 20, 2014 5:18 pm

Re: Ask a simple question, get a simple answer

Post by AndakRainor »

Do you have problems with ItemComponent.onUnequipItem(self, champion, slot)?

I get an attempt to index field 'map' (a nil value) each time, just by clicking the item in the inventory to grab it. I don't use anything from the calling item in the hooked function.

Edit: the problem happens only with Component:addConnector(event, target, action), not if I define the onUnequipItem function directly in the object definition.
User avatar
Isaac
Posts: 3185
Joined: Fri Mar 02, 2012 10:02 pm

Re: Ask a simple question, get a simple answer

Post by Isaac »

Confirmed. I get that with the following:

Code: Select all

function addItem(item)
	local d = party:spawn(item)
	print("map level: "..d.map:getLevel())
	d.item:addConnector("onEquipItem", self.go.id, "payload")
	d.item:addConnector("onUnEquipItem", self.go.id, "payload")
end
addItem("dagger")	

function payload(...)
	print(...)
end
minmay
Posts: 2780
Joined: Mon Sep 23, 2013 2:24 am

Re: Ask a simple question, get a simple answer

Post by minmay »

If an object not on a map has any connectors, and it triggers them, it will crash, because triggering a connector uses the triggering object's map. The raw hooks in the component definition will still work; they don't use the map. This means that you can imitate connector functionality without needing a map. There is already a Grimrock 2 library that can do this: viewtopic.php?f=22&t=8345
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.
Post Reply