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
zimberzimber
Posts: 432
Joined: Fri Feb 08, 2013 8:06 pm

Re: Ask a simple question, get a simple answer

Post by zimberzimber »

OK so as the lazy fuck I am, I really don't feel like redefening every monster attack component, so I went with modifying base_monster with a new 'Null' component, that calls a function through onInit, that iterates through every component the monster has, and do stuff from there.
Now I got two problems:
1) There doesn't seem to be a getPierce/setPierce
2) Monsters that are not placed on the map don't seem to call that function (thing like the spawn function)

Any help with those?
My asset pack [v1.10]
Features a bit of everything! :D
minmay
Posts: 2780
Joined: Mon Sep 23, 2013 2:24 am

Re: Ask a simple question, get a simple answer

Post by minmay »

zimberzimber wrote:OK so as the lazy fuck I am, I really don't feel like redefening every monster attack component, so I went with modifying base_monster with a new 'Null' component, that calls a function through onInit, that iterates through every component the monster has, and do stuff from there.
Now I got two problems:
1) There doesn't seem to be a getPierce/setPierce
2) Monsters that are not placed on the map don't seem to call that function (thing like the spawn function)

Any help with those?
Just have code like this in your init.lua before you import any monsters:

Code: Select all

local orig_defineObject = defineObject
defineObject = function(def)
	if def.components then
		for i,c in ipairs(def.components) do
			if c.class == "MonsterAttack" or c.class == "CrowernAttack" then
				c.pierce = math.huge
			end
		end
	end
	orig_defineObject(def)
end
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
zimberzimber
Posts: 432
Joined: Fri Feb 08, 2013 8:06 pm

Re: Ask a simple question, get a simple answer

Post by zimberzimber »

What I'm trying to do though is to set their pierce to 1000 + actual pierce so that pierce could be used in my damage filter, so I have to get their pierce later anyways
My asset pack [v1.10]
Features a bit of everything! :D
minmay
Posts: 2780
Joined: Mon Sep 23, 2013 2:24 am

Re: Ask a simple question, get a simple answer

Post by minmay »

Then you could do something gross like this:

Code: Select all

Config.pierceData = {}
local orig_defineObject = defineObject
defineObject = function(def)
	if def.components then
		for i,c in ipairs(def.components) do
			if c.class == "MonsterAttack" or c.class == "CrowernAttack" then
				if not Config.pierceData[def.name] then Config.pierceData[def.name] = {} end
				Config.pierceData[def.name][c.name or string.lower(c.class)] = c.pierce
				c.pierce = c.pierce+1000
			end
		end
	end
	orig_defineObject(def)
end
and when you want to use attack:getPierce(), which doesn't exist, use Config.pierceData[attack.go.name][attack:getName()] instead
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
zimberzimber
Posts: 432
Joined: Fri Feb 08, 2013 8:06 pm

Re: Ask a simple question, get a simple answer

Post by zimberzimber »

oh brother...
Will give it a try
My asset pack [v1.10]
Features a bit of everything! :D
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 »

minmay wrote:That was the save editor, which includes a button to remove nonstandard traits from the party to prevent this crash. But that's a tool for users to use, you can't integrate it in your mod obviously. There's no practical way to get rid of all the nonstandard traits from within your mod itself, because you don't know what the names of those traits are.
I see I see - Thankyou for explaining/confirming ;)
Isaac wrote:Here is an experimental charge attack for the party; implemented as a magical "Horn of Berserker Charge'.

*It's not necessarily balanced for play, but it does have some usage checks (and experimental limitations). As-is it may well allow the breaking puzzles that can be broken by a faster than expected party —provided they don't need to change direction during the charge.
Hahah Isaac that is Fantastic man - Ive been knocking snails down pits for the last 10 mins :D :D
Thats pretty much how I had envisioned it coded up - didnt think to use a Condition though (nice idea!)

And yeah - only 1 Berserk Horn to avoid abuse
Perhaps Ill add a check for monsters in front of the party so that folks dont break puzzles with it too easily (limiting it to when a monster is 1 or 2 squares in front)
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 »

Hah, so apparently I'll have to redefine every monster that uses melee attacks after all /̵͇̿​̿/’̿’̿ ̿ ̿̿ :lol: (Gotta index the monster when it melee hits a champion in a global table for future interactions)
So question - Would redefining the whole definition instead of defining an object with the same name and using the previous (original) definition as a base class have a significant difference?
My asset pack [v1.10]
Features a bit of everything! :D
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 »

zimberzimber wrote:Hah, so apparently I'll have to redefine every monster that uses melee attacks after all /̵͇̿​̿/’̿’̿ ̿ ̿̿ :lol: (Gotta index the monster when it melee hits a champion in a global table for future interactions)
Im (fairly) sure you can still do that Zimber
So you would be recording the monster name or id in a global table (like Config) from one of these hooks?:
SpoilerShow
MonsterAttackComponent.onAttack(self)
MonsterAttackComponent.onAttackHit(self, champion)
MonsterAttackComponent.onDealDamage(self, champion, damage)
I think minmays Example should demonstrate its doable:
EDIT viewtopic.php?f=22&t=9863&p=108716#p108716

Sorry if Im not spot on with these shadow functions, ive been keeping examples but haven't started making my own just yet.
I will be needing to do so as I plan to use this method to set up and bunch of checks at various times through most monsters' monsterAttacks
Im thinking this is a good way to simplify and cut down on all the extra code...
(my checks will be to determine probability of champs counter striking various monster attacks)

zimberzimber wrote:So question - Would redefining the whole definition instead of defining an object with the same name and using the previous (original) definition as a base class have a significant difference?
Did you decide to use the CloneObject script ??
(viewtopic.php?f=22&t=7951&p=110184&hili ... ct#p110184)
Ive been using to make templates for each item type
(although Ive found that if your base definition has a traits Table - those traits will not be merged with a new definitions trait Table - have to include all the traits in your new def's table)
Last edited by akroma222 on Thu Apr 13, 2017 4:31 am, edited 1 time in total.
minmay
Posts: 2780
Joined: Mon Sep 23, 2013 2:24 am

Re: Ask a simple question, get a simple answer

Post by minmay »

akroma222 wrote:I think this Example (this is minmays work) should demonstrate its doable:
SpoilerShow

Code: Select all

local awardXp = function(self)
       
	local rval = Config.monsterOnDieMap[self.go.name] and Config.monsterOnDieMap[self.go.name](self) or true
    if rval then
		local xp = Config.monsterExpMap[self.go.name]
        if xp then
			xp = math.floor(xp * 1.1^(self:getLevel() - 1))
            for i=1,4 do
				if party.party:getChampion(i):getEnabled() and not party.party:getChampion(i):hasTrait("farmer") then
					party.party:getChampion(i):gainExp(xp)
                end
            end
            self:showDamageText(string.format("+%d xp",xp),"0xffff88")
		end
		-- oh, while we're at it, fix the phantom flames bug
		if self.go.burning then 
			self.go:removeComponent("burning") 
		end
    end
    return rval
end
--------------------------------------this method makes MonsterComponent:getExp() useless.
local orig_defineObject = defineObject
Config.monsterExpMap = {}
Config.monsterOnDieMap = {}
--------------------------------------
	defineObject = function(def)
       
		if def.components then 
			for _,c in ipairs(def.components) do
				if c.class == "Monster" then
					Config.monsterExpMap[def.name] = c.exp
					Config.monsterOnDieMap[def.name] = c.onDie
					c.onDie = awardXp
					c.exp = false 				-- removes the +xp text
				end
			end 
		end
		orig_defineObject(def)
    end
Logging on despite the sudden lack of HTTPS, just to say that this terrible indentation is not my work. Here is the original.
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: Ask a simple question, get a simple answer

Post by akroma222 »

minmay wrote:
akroma222 wrote:I think this Example (this is minmays work) should demonstrate its doable:
SpoilerShow

Code: Select all

local awardXp = function(self)
       
	local rval = Config.monsterOnDieMap[self.go.name] and Config.monsterOnDieMap[self.go.name](self) or true
    if rval then
		local xp = Config.monsterExpMap[self.go.name]
        if xp then
			xp = math.floor(xp * 1.1^(self:getLevel() - 1))
            for i=1,4 do
				if party.party:getChampion(i):getEnabled() and not party.party:getChampion(i):hasTrait("farmer") then
					party.party:getChampion(i):gainExp(xp)
                end
            end
            self:showDamageText(string.format("+%d xp",xp),"0xffff88")
		end
		-- oh, while we're at it, fix the phantom flames bug
		if self.go.burning then 
			self.go:removeComponent("burning") 
		end
    end
    return rval
end
--------------------------------------this method makes MonsterComponent:getExp() useless.
local orig_defineObject = defineObject
Config.monsterExpMap = {}
Config.monsterOnDieMap = {}
--------------------------------------
	defineObject = function(def)
       
		if def.components then 
			for _,c in ipairs(def.components) do
				if c.class == "Monster" then
					Config.monsterExpMap[def.name] = c.exp
					Config.monsterOnDieMap[def.name] = c.onDie
					c.onDie = awardXp
					c.exp = false 				-- removes the +xp text
				end
			end 
		end
		orig_defineObject(def)
    end
Logging on despite the sudden lack of HTTPS, just to say that this terrible indentation is not my work. Here is the original.
Your code, I had forgot Id messed up the indents since - sorry
Should have just linked to the page - Fixed now
Post Reply