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
fisch
Posts: 8
Joined: Thu May 05, 2016 6:00 pm
Location: Austria

Re: Ask a simple question, get a simple answer

Post by fisch »

Hi,
when I do something like this:

Code: Select all

function devParty()
	local mySack = spawn("sack")
	mySack.containeritem:addItem(spawn("round_key").item)
	mySack.containeritem:addItem(spawn("iron_key").item)
	party.party:getChampion(1):insertItem(13, mySack.item)
end
then I have a Sack with two Items in it. When I stop the preview in the editor and later I click play - I have an empty Sack equipped. Why?
minmay
Posts: 2780
Joined: Mon Sep 23, 2013 2:24 am

Re: Ask a simple question, get a simple answer

Post by minmay »

When you restart the editor preview, it restarts the entire dungeon. It doesn't actually keep the items the party had equipped; it spawns new versions of those items. So if one of those items was a sack with contents, it will spawn an empty sack in that spot.
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
fisch
Posts: 8
Joined: Thu May 05, 2016 6:00 pm
Location: Austria

Re: Ask a simple question, get a simple answer

Post by fisch »

minmay wrote:... It doesn't actually keep the items the party had equipped; it spawns new versions of those items. ...
Oh .. ok .. all clear now. Thanks minmay!
User avatar
Illidan
Posts: 19
Joined: Sat Mar 12, 2016 3:23 pm
Location: Germany

Re: Ask a simple question, get a simple answer

Post by Illidan »

Hi everyone,

I need urgent help with a script. I found nothing on the forum that could solve the problem.

When a party member dies, there should be spawned a "remains_of_character" (I created one for each charcter like the "remains_of_toorum"). This shall work always and shall not be triggered by a trigger or something, just at the moment when a party member dies. I want to use the remains then to resurrect a party member on an Altar of VI.
What script can archieve this?
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 »

I don't think there is one; not that I have seen.

I have a script for that in the ORRR2 mod [for LoG1]. When the PC died of ectoplasm poisoning, they were removed from the party, and a skeletal corpse was left on the floor. Their remains could be picked up, and used to add the dead PC back into the party (as a corpse), to then be healed as usual at a crystal.

For LoG2, something similar should work. Provided that your mod does not have joinable NPCs, you should be able to just disable the PC upon death; drop their stuff with a corpse, and either make the corpse a usable item that re-enables the PC by ordinal, or have the Altar do it when the corpse is placed upon it.

IIRC... A way to drop all of their stuff is to create a custom altar/surface that positions contained items at floor level, and deletes itself when emptied of the last item. You would spawn one of these at the party's location, and [from within a loop] add an inventory item to the altar, then remove it from the champion... until all of the PC's items are in the surface container.
User avatar
Eleven Warrior
Posts: 746
Joined: Thu Apr 18, 2013 2:32 pm
Location: Australia

Re: Ask a simple question, get a simple answer

Post by Eleven Warrior »

Isaac wrote:I don't think there is one; not that I have seen.

I have a script for that in the ORRR2 mod [for LoG1]. When the PC died of ectoplasm poisoning, they were removed from the party, and a skeletal corpse was left on the floor. Their remains could be picked up, and used to add the dead PC back into the party (as a corpse), to then be healed as usual at a crystal.

For LoG2, something similar should work. Provided that your mod does not have joinable NPCs, you should be able to just disable the PC upon death; drop their stuff with a corpse, and either make the corpse a usable item that re-enables the PC by ordinal, or have the Altar do it when the corpse is placed upon it.

IIRC... A way to drop all of their stuff is to create a custom altar/surface that positions contained items at floor level, and deletes itself when emptied of the last item. You would spawn one of these at the party's location, and [from within a loop] add an inventory item to the altar, then remove it from the champion... until all of the PC's items are in the surface container.
Err so what is the code for matey lol. I t would require a lot of checks for this.
User avatar
Illidan
Posts: 19
Joined: Sat Mar 12, 2016 3:23 pm
Location: Germany

Re: Ask a simple question, get a simple answer

Post by Illidan »

@Isaac:

Hmm, I will have a look at your sourcecode of ORRR2, perhaps it can help me with my problem in my Grimrock 2 mod.

To make things clear, I am creating a Dungeon Master Clone for Grimrock 2 that should be as authentic to the original one as possible.
I created much new stuff that was missing in Germannys Dungeon Master asset. New Items and new objects, like centered doors. And all new monsters (around 20), even the Rustmonster will be there.
My mod is nearly completed! All levels are ready, all traps and riddles are beta tested, everything is like in the original. However, I have still much work to do with the creatures! Many are already rigged, the half of them is nearly completely animated. I invested ofer 300 hours of time until now. :roll:
And: I have problems with a few scripts to make the Dungeon Master feeling authentic. ;)

Like this with a spawned corpse when a character dies, to put it then on an Altar of VI to resurrect the champion. :?

I have an other Idea: Is it not possible to use an onDie hook in the party component? It does exist in the grimrock scripting reference: PartyComponent.onDie(self, champion). PartyComponent.onReceiveCondition(self, champion, condition) would be, perhaps, also a solution?
I could write a party component in the init.lua of my dungeon mod like this:

defineObject{
name = "party",
baseObject = "party",
components = {
{
class = "Party",
onDie = function(self, champion)
????????????????
????????????????

end,
},
},
}

I must say, that I am still not an expert at scripting, I get problems when it get's complicated. But, I solved most problems alone and some with help of minmay (he will be credited!).
So if you want to help me, pleeease, make helping suggestions with scripts I can use. :shock: :D
Thank you in advance!
minmay
Posts: 2780
Joined: Mon Sep 23, 2013 2:24 am

Re: Ask a simple question, get a simple answer

Post by minmay »

This is pretty easy to do, actually. Here is an implementation of it. I trust that you can add any visual effects you want on your own.

Put this in your init.lua before any defineCondition() calls:

Code: Select all

CONDITION_LIST = {"dead","cursed","diseased","paralyzed","petrified","poison",
"slow","bear_form","haste","invisibility","level_up","rage","water_breathing",
"fire_shield","frost_shield","poison_shield","protective_shield","shock_shield",
"chest_wound","feet_wound","head_wound","left_hand_wound","leg_wound","right_hand_wound"}

-- Automatically adds custom conditions to the list
local orig_defineCondition = defineCondition
defineCondition = function(desc)
	orig_defineCondition(desc)
	table.insert(CONDITION_LIST,desc.name)
end
and define these objects (the dm_wall_altarvi redefinition, of course, must come *after* all your defineCondition() calls have been made)

Code: Select all

defineObject{
	name = "dummy_monster",
	placement = "floor",
	components = {
		{
			class = "Model",
			model = "assets/models/monsters/snail.fbx", -- simplest existing valid monster model (would be easy to make a new one though)
			storeSourceData = true,
			enabled = false,
		},
		{
			class = "Animation",
			animations = {idle = "assets/animations/monsters/snail/snail_idle.fbx"},
			currentLevelOnly = true,
			enabled = false,
		},
		{
			class = "Monster",
			meshName = "snail_mesh",
			hitSound = "snail_hit",
			dieSound = "snail_die",
			hitEffect = "hit_goo",
			health = 100,
			capsuleHeight = 0,
			capsuleRadius = 0,
			collisionRadius = 0,
			exp = 0,
		},
	}
}
defineObject{
	name = "champion_remains",
	baseObject = "base_item",
	components = {
		{
			class = "Model",
			model = "assets/models/items/remains_of_toorum.fbx",
		},
		{
			class = "Item",
			uiName = "Remains",
			gfxIndex = 212,
			weight = 5.0,
		},
		{
			class = "Particle",
			particleSystem = "glitter_toorum",
		},
		{
			class = "Counter",
			name = "ordinal",
		},
	},
}
defineObject{
	name = "party",
	baseObject = "party",
	components = {
		{
			class = "Party",
			onDie = function(self, champion)
				local championCount = 0
				for i=1,4 do
					if party.party:getChampion(i):getEnabled() and party.party:getChampion(i):isAlive() then championCount = championCount+1 end
				end
				if championCount ~= 0 then -- champion that just "died" counts as dead
					champion:setEnabled(false)
					-- Spawning a dummy monster is the only way to move items from the inventory to the map
					local dummy = self.go:spawn("dummy_monster")
					for slot,itm in champion:carriedItems() do
						champion:removeItemFromSlot(slot)
						dummy.monster:addItem(itm)
					end
					dummy.monster:dropAllItems()
					dummy:destroy()
					local remains = self.go:spawn("champion_remains")
					remains.item:setUiName(string.format("Remains of %s",champion:getName()))
					remains.ordinal:setValue(champion:getOrdinal())
					playSound("champion_die")
					return false -- Important! There is no good scripting-side way to remove the "dead" condition without healing the entire party.
				else
					return true
				end
			end,
		},
	},
}
local conditions = CONDITION_LIST
defineObject{
	name = "dm_wall_altarvi",
	baseObject = "dm_wall_altarvi",
	components = {
		{
			class = "Surface",
			offset = vec(0, 0.904, 0.3),
			size = vec(1.3, 0.65),
			onInsertItem = function(self, item)
				if item.go.name == "champion_remains" then
					local champ = party.party:getChampionByOrdinal(item.go.ordinal:getValue())
					champ:setEnabled(true)
					for _,condition in ipairs(conditions) do
						champ:removeCondition(condition)
					end
					champ:regainHealth(math.huge)
					champ:regainEnergy(math.huge)
					champ:playHealingIndicator()
					champ:showAttackResult("Resurrected","HitSplash")
					playSound("heal_party")
					item.go:destroy()
				end
			end,
		},
	},
}
Do not use surfaces or sockets to add items to the map. Items cannot be removed from surfaces or sockets except by destroying the items or having the player click on them (destroying the surface/socket just taints the item and makes it impossible to pick up ever again without causing a crash).
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
Illidan
Posts: 19
Joined: Sat Mar 12, 2016 3:23 pm
Location: Germany

Re: Ask a simple question, get a simple answer

Post by Illidan »

Wow, minmay, I am again impressed by your scripting skills! :o

Thank you so much for these scripts, that was exactly what I needed!
I did not even think about a solution with a dummy monster. Brilliant! :geek: :D
User avatar
Eleven Warrior
Posts: 746
Joined: Thu Apr 18, 2013 2:32 pm
Location: Australia

Re: Ask a simple question, get a simple answer

Post by Eleven Warrior »

You call that easy!! If your a rocket scientist yes :)
Post Reply