Page 2 of 2

Re: Boss fight help

Posted: Mon Jul 06, 2015 4:01 am
by minmay
Azel wrote:Even the Grimrock scripting reference has contradictions that only diminish after "reading between the lines" (eg, "CrystalComponent:setCooldown(number) leads us to a successful, my_crystal.crystal:setCooldown(60)" ... whereas "MonsterAttackComponent:getAttackPower() leads to a failure if you try, my_monster.monsterattack:getAttackPower()"). Granted, once you find out what went wrong you realize it was your fault for not understanding the Scripting Reference better, but at the end of the day it still feels quite sloppy, imo.
Man, I'm no fan of Lua either, but I think it's reasonable to expect programmers to know that a class name and a table key aren't the same thing. It's not the Grimrock scripting reference's job to teach compsci 101, or introduce you to Lua, it's just there to list what's available in Grimrock specifically.

Re: Boss fight help

Posted: Mon Jul 06, 2015 4:54 am
by Azel
minmay wrote:Man, I'm no fan of Lua either, but I think it's reasonable to expect programmers to know that a class name and a table key aren't the same thing. It's not the Grimrock scripting reference's job to teach compsci 101, or introduce you to Lua, it's just there to list what's available in Grimrock specifically.
I think it's the other way around: the scripting reference and asset pack could use some CompSci 101. The idea of subclasses, for example, requires Inheritance, which is nowhere to be found in the Asset definitions (instead, multiple classes are shoved in to a single component).

Furthermore, the scripting reference lists out Components and their functions/behaviors, and it explicitly states, "By default the name of a component is the class name in lower case." There is nowhere on the Scripting Reference that indicates which of their Component syntax items refers to a Table instead of a Class.

Pointing out that in some cases the Scripting Reference is referring to a table key is fine, but assuming that someone doesn't know the difference is a logical leap. Tables in LUA are nothing more than array containers for key/value pairs; and incredibly basic compared to other languages (https://msdn.microsoft.com/en-us/librar ... 10%29.aspx).

I agree that it's not the scripting references job to teach anything, but it certainly should properly reference a Method that is called at the Class lvl vs a sub-type. Other script references work on their own just fine, such as:
https://dev.twitter.com/streaming/overv ... m_messages
https://developers.google.com/+/web/api/rest/latest/

In the example I gave about MonsterAttack, the scripting reference calls it a Component (which they describe as having its class name in lowercase), but it's not until you delve in to the asset pack that you find the proper item to implement the method call.

Anyway, I did agree that some fault lies on the reader (ie, I own which failures are my own). But, I also maintain an awareness that these failures are rarely present in scripting references that are more thorough and accurate.

Re: Boss fight help

Posted: Mon Jul 06, 2015 6:21 pm
by DrKojak
I always just have the monster in a deactivated teleporter in some far corner of the map, when the boss starts, activate the teleporter and set the custom destination.
if the monster is in a 1x1 tile, he wont turn or move, so you can keep the monsters facing too!, you can set the teleporter destination higher that the floor, so he drops down and gives you a surprise if you wish.

Re: Boss fight help

Posted: Mon Jul 06, 2015 6:23 pm
by Isaac
DrKojak wrote:I always just have the monster in a deactivated teleporter in some far corner of the map, when the boss starts, activate the teleporter and set the custom destination.
if the monster is in a 1x1 tile, he wont turn or move, so you can keep the monsters facing too!, you can set the teleporter destination higher that the floor, so he drops down and gives you a surprise if you wish.
Good for Spiders. :twisted:

Re: Boss fight help

Posted: Mon Jul 06, 2015 7:10 pm
by Azel
DrKojak wrote:I always just have the monster in a deactivated teleporter in some far corner of the map, when the boss starts, activate the teleporter and set the custom destination.
if the monster is in a 1x1 tile, he wont turn or move, so you can keep the monsters facing too!, you can set the teleporter destination higher that the floor, so he drops down and gives you a surprise if you wish.
Definitely an easier solution. I use this a lot. When I created the Usurper boss battle, I wrote the auto-spawn script because the Fire Boss needs to come back to life if the player kills him without meeting certain conditions. So in this case, script is needed to continuously spawn the Boss and dynamically add him to the Boss Battle object every time he dies. However, once the player meets the proper conditions and kills the Boss, he is allowed to stay dead, and I do use the Teleporter/Placeholder trick to bring in the final enemy for the boss battle.

Although I did not know that the monster doesn't turn if in a 1x1 square! I always configure the "spin" option on teleporters to make sure things face the direction I want :geek:

Re: Boss fight help

Posted: Wed Jul 15, 2015 2:06 pm
by akroma222
Another example for you....
Paste this into a script entity called 'bossScripts'
Activate the function bossstart() via pressure plate or something...
SpoilerShow

Code: Select all

viperBossDefeated = false

function checkForThings(thing,xMin,xMax,yMin,yMax)
	for x = xMin,xMax do
    	for y = yMin,yMax do
        	for entity in self.go.map:entitiesAt(x,y) do
            	if entity.name == thing then
                	return true
                end
            end
        end
    end
    return false
end
	
function viperBossFinish()
	local b = findEntity("vinesBossFight")
	local c = findEntity("vinesBossCounter")
	
	if viperBossDefeated == false 
	and not (checkForThings("viperRootBoss_1",1,31,1,31) 
	or checkForThings("viperRootBoss_2",1,31,1,31) 
	or checkForThings("viperRootBoss_3",1,31,1,31)) then
    	viperBossDefeated = true
		if b ~= nil then
			b:destroyDelayed()
		end
		if c ~= nil then
			c:destroyDelayed()
		end 
		hudPrint("Boss fight finished")
	end
end

	function bossstart()
		
		if viperBossDefeated == true then
			hudPrint("You have already fought the boss")
       		return false
		end
		
		--if wanting to check within an area on self.level
		if viperBossDefeated == false then
			for n = 1,3 do
				if findEntity("viperRootBoss_"..n) ~= nil then
					local vleft = viperBossCounter.counter:getValue()
					local vName = vinesBossFight.bossfight:getBossName()
					if vleft > 1 then
						hudPrint("You are currently fighting the boss... there are still "..vleft.." "..vName.."s remaining.")
					elseif vleft == 1 then
						hudPrint("You are currently fighting the boss... there is only 1 "..vName.." remaining.")
					end
   					return false
				end
			end
       	end

		local b = findEntity("vinesBossFight")
		if b == nil and viperBossDefeated == false then
			local bScript = spawn("boss_fight", self.level,self.x,self.y,self.elevation,self.facing,"vinesBossFight")
			vinesBossFight.bossfight:setBossName("Viper Roots")
			vinesBossFight.bossfight:setAutoDeactivate(true)
			vinesBossFight.bossfight:setMusic("boss_fight_viper")
			vinesBossFight.bossfight:activate()
			
			local c = spawn("counter",self.level,self.x,self.y,self.elevation,self.facing,"viperBossCounter")
			c.counter:setValue(3)
			c.counter:addConnector("onActivate", "bossScripts", "viperBossFinish")
			
			for n = 1,3 do
				local v = spawn("viper_root",self.level,self.x,self.y,self.elevation,self.facing,"viperRootBoss_"..n)
				vinesBossFight.bossfight:addMonster(v.monster)
				v.monster:setMaxHealth(700)
				v.monster:addConnector("onDie", "viperBossCounter", "decrement")
			end
		end
	end
Keeps track of:
whether the fight has happened yet? (Happening currently, already over, or start!)
the number of monsters left in the fight
lets you check for remaining monsters within xMin,xMax,yMin,yMax area

Tested, let me know if any dramas
Akroma