Another bunch of 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!
Post Reply
User avatar
Drakkan
Posts: 1318
Joined: Mon Dec 31, 2012 12:25 am

Another bunch of questions

Post by Drakkan »

Hello folks. ANother challenge for scripters. Whoever will help will be credited which is the smallest thanks I can give you.

1. I´d like to define some spell to be castable just by any particular champion (based on name or trait will do) I think just some condition IF champion(name...) could work.

2. Script help. I have swamp_ground2 tile in the editor (eleveation floor is -1). When party dig here, I need that tile to be changed for beach_ground_stones with -2 floor elevation. So in real you will just dig regular pit (the same as placing one tile with different elevation).

3. Script help. I would like to define blob object (flying blob), which when party get hit, it moves whole party 1 square back (similar to air_elemental attack)

4. SOLVED- define creature (for now for example ogre clone), which will be indestructible by any regular attack, spell or whatever. Maybe some air elemental clone ?
Solved by Doridion
just adjust air_elemental imminuties to spell
SpoilerShow

Code: Select all

    defineObject{
       baseObject = "base_monster",
       name = "air_elemental",
       components = {
          {
             class = "Model"
             name = "model",
             model = "assets/models/monsters/uggardian.fbx",
             enabled = false,
             storeSourceData = true,
          },
          {
             class = "Animation",
             name = "animation",
             animations = {
                fall = "assets/animations/monsters/uggardian/uggardian_get_hit.fbx",
                attack = "assets/animations/monsters/air_elemental/air_elemental_attack.fbx",
                turnRight = "assets/animations/monsters/uggardian/uggardian_turn_right.fbx",
                getHitFrontLeft = "assets/animations/monsters/uggardian/uggardian_get_hit_front_left.fbx",
                getHitRight = "assets/animations/monsters/uggardian/uggardian_get_hit_right.fbx",
                getHitBack = "assets/animations/monsters/uggardian/uggardian_get_hit_back.fbx",
                strafeRight = "assets/animations/monsters/uggardian/uggardian_strafe_right.fbx",
                getHitFrontRight = "assets/animations/monsters/uggardian/uggardian_get_hit_front_right.fbx",
                moveForward = "assets/animations/monsters/uggardian/uggardian_walk.fbx",
                turnLeft = "assets/animations/monsters/uggardian/uggardian_turn_left.fbx",
                idle = "assets/animations/monsters/uggardian/uggardian_idle.fbx",
                getHitLeft = "assets/animations/monsters/uggardian/uggardian_get_hit_left.fbx",
                strafeLeft = "assets/animations/monsters/uggardian/uggardian_strafe_left.fbx"
             },
             currentLevelOnly = true
          },
          {
             class = "Monster",
             name = "monster",
             meshName = "uggardian_mesh",
             traits = { "elemental" },
             hitEffect = "hit_goo",
             hitSound = "air_elemental_hit",
             dieSound = "air_elemental_die",
             immunities = { "sleep", "blinded", "frozen" },
             resistances = {
                poison = "immune",
                fire = "immune",
                physical = "immune",
                cold = "immune",
                shock = "absorb"
             },
             health = 170,
             exp = 400,
             protection = 0,
             evasion = 0,
             capsuleHeight = 0.6,
             capsuleRadius = 0.3,
             collisionRadius = 0.8
             flying = true,
             onDie = function() print('Cannot Scrape Functions'); end,
          },
          {
             class = "MeleeBrain",
             name = "brain",
             sight = 5
             seeInvisible = true,
          },
          {
             class = "MonsterMove",
             name = "move"
             sound = "air_elemental_walk",
             animationSpeed = 1.3,
             cooldown = 3,
          },
          {
             class = "MonsterTurn",
             name = "turn",
             sound = "air_elemental_walk"
             animationSpeed = 1.5,
          },
          {
             class = "MonsterAttack",
             name = "basicAttack",
             damageType = "pure",
             sound = "air_elemental_attack",
             screenEffect = "leafburst_screen",
             woundChance = 25,
             animationSpeed = 1.5,
             cooldown = 6,
             accuracy = 100,
             attackPower = 30
             knockback = true,
             cameraShake = true,
          },
          {
             class = "UggardianFlames",
             name = "uggardianflames",
             emitFromMaterial = "*",
             particleSystem = "air_elemental"
          },
          {
             class = "Sound",
             name = "sound",
             parentNode = "head"
             sound = "air_elemental_wind",
          }
       }
    }
5. SOLVED - I have spawner mummy1,mummy2 and mummy3 triggered by plate. What I need this plate to re-spawn these mummies just in case they are all dead (otherwise that trigger will do nothing)
Solved by Batty
SpoilerShow

Code: Select all

Instead of using spawners, have the plate trigger this function, just fill in the spawner locations:

    function mSpawn()
       if not findEntity('mummy_spawn1') and not findEntity('mummy_spawn2') and not findEntity('mummy_spawn3') then
          spawn('mummy', level, x, y, facing, elevation, 'mummy_spawn1')
          spawn('mummy', level, x, y, facing, elevation, 'mummy_spawn2')
          spawn('mummy', level, x, y, facing, elevation, 'mummy_spawn3')
       end
    end
6. SOLVED - weight puzzle where you need put items with certain weight in each alcove. voontrag already helped me to rewrite part of the script however still not working. In case you want create it from scratch no prob.
Solved by mahric, adviced by Isaac
SpoilerShow

Code: Select all

    weight = 0
    weight2 = 0
    weight3 = 0
    weight4 = 0
    finish = 0

function weightcheck()

    if finish == 0 then

    weight = 0
    weight2 = 0
    weight3 = 0
    weight4 = 0

    -- following part already rewritten
           for _, i in alcw1.surface:contents() do
           weight = weight + i:getWeight()
           end
         
           for _, j in alcw2.surface:contents() do
           weight2 = weight2 + j:getWeight()
           end
         
           for _, k in alcw3.surface:contents() do
           weight3 = weight3 + k:getWeight()
           end
         
           for _, l in alcw4.surface:contents() do
           weight4 = weight4 + l:getWeight()
           end
    --end of rewritten part
       
       check()

    end
    end


    function check()

    if finish == 0 then

    if weight == 1 and
       weight2 == 0 and
       weight3 == 0 and
       weight4 == 0 then
       
       iron_weight.door:open()
       playSound("secret")
     
  finish = 1
       else
       iron_weight.door:close()
    end
    end
    end
thanks for any help
Last edited by Drakkan on Sun Nov 30, 2014 11:46 pm, edited 16 times in total.
Breath from the unpromising waters.
Eye of the Atlantis
User avatar
mahric
Posts: 192
Joined: Sun Nov 04, 2012 3:05 pm

Re: Another bunch of questions

Post by mahric »

2.

You can replace the part of script below and the weight puzzle should work.
The underscore in the for loops is a variable that isn't used. And the function to get the items in an alcove was :contents(), but it wasn't written at the 2nd to 4th alcove.

Code: Select all

    -- following part already rewritten
           for _, i in alcw1.surface:contents() do
           weight = weight + i:getWeight()
           end
         
           for _, j in alcw2.surface:contents() do
           weight2 = weight2 + j:getWeight()
           end
         
           for _, k in alcw3.surface:contents() do
           weight3 = weight3 + k:getWeight()
           end
         
           for _, l in alcw4.surface:contents() do
           weight4 = weight4 + l:getWeight()
           end
    --end of rewritten part
No need to credit me, glad to help.

I'm looking forward to your mod. At least I know how to solve 1 of your puzzles... :lol:
Did you visit the Wine Merchant's Basement? And heard about the Awakening of Taarnab?
User avatar
Drakkan
Posts: 1318
Joined: Mon Dec 31, 2012 12:25 am

Re: Another bunch of questions

Post by Drakkan »

mahric wrote:2.
No need to credit me, glad to help.

I'm looking forward to your mod. At least I know how to solve 1 of your puzzles... :lol:
working correclty Sir, thanks a lot ! Dont worry crediting you is rlly the smallest thing I can do.
Breath from the unpromising waters.
Eye of the Atlantis
User avatar
Drakkan
Posts: 1318
Joined: Mon Dec 31, 2012 12:25 am

Re: Another bunch of questions

Post by Drakkan »

one more question up
Breath from the unpromising waters.
Eye of the Atlantis
Batty
Posts: 509
Joined: Sun Apr 15, 2012 7:04 pm

Re: Another bunch of questions

Post by Batty »

Drakkan wrote:4. script help - I have spawner mummy1,mummy2 and mummy3 triggered by plate. What I need this plate to re-spawn these mummies just in case they are all dead (otherwise that trigger will do nothing)
Instead of using spawners, have the plate trigger this function, just fill in the spawner locations:

Code: Select all

function mSpawn()
   if not findEntity('mummy_spawn1') and not findEntity('mummy_spawn2') and not findEntity('mummy_spawn3') then
      spawn('mummy', level, x, y, facing, elevation, 'mummy_spawn1')
      spawn('mummy', level, x, y, facing, elevation, 'mummy_spawn2')
      spawn('mummy', level, x, y, facing, elevation, 'mummy_spawn3')
   end
end
I gave the mummies unique names so they don't get confused with editor created mummies you may have elsewhere.
Tested it quickly, seems to work, remember that monsters aren't technically dead until the death particle effect finishes.

OR just looked at the reference, keep the spawners and have the plate call this:

Code: Select all

function mSpawn()
   if not findEntity(spawner_1.spawner:getSpawnedEntity()) and not
   findEntity(spawner_2.spawner:getSpawnedEntity()) and not
   findEntity(spawner_3.spawner:getSpawnedEntity()) then
      spawner_1.spawner:activate()
      spawner_2.spawner:activate()
      spawner_3.spawner:activate()
   end
end
EDIT: cancel the second code, getSpawnedEntity() only returns the name, not id or table.
Last edited by Batty on Mon Nov 24, 2014 9:08 pm, edited 1 time in total.
User avatar
Doridion
Posts: 256
Joined: Tue Jun 10, 2014 9:23 pm

Re: Another bunch of questions

Post by Doridion »

3. Drakan, for your "indestructible" monster, there's already one in the original asset panel :
SpoilerShow

Code: Select all

defineObject{
	baseObject = "base_monster",
	name = "air_elemental",
	components = {
		{
			class = "Model"
			name = "model",
			model = "assets/models/monsters/uggardian.fbx",
			enabled = false,
			storeSourceData = true,
		},
		{
			class = "Animation",
			name = "animation",
			animations = {
				fall = "assets/animations/monsters/uggardian/uggardian_get_hit.fbx",
				attack = "assets/animations/monsters/air_elemental/air_elemental_attack.fbx",
				turnRight = "assets/animations/monsters/uggardian/uggardian_turn_right.fbx",
				getHitFrontLeft = "assets/animations/monsters/uggardian/uggardian_get_hit_front_left.fbx",
				getHitRight = "assets/animations/monsters/uggardian/uggardian_get_hit_right.fbx",
				getHitBack = "assets/animations/monsters/uggardian/uggardian_get_hit_back.fbx",
				strafeRight = "assets/animations/monsters/uggardian/uggardian_strafe_right.fbx",
				getHitFrontRight = "assets/animations/monsters/uggardian/uggardian_get_hit_front_right.fbx",
				moveForward = "assets/animations/monsters/uggardian/uggardian_walk.fbx",
				turnLeft = "assets/animations/monsters/uggardian/uggardian_turn_left.fbx",
				idle = "assets/animations/monsters/uggardian/uggardian_idle.fbx",
				getHitLeft = "assets/animations/monsters/uggardian/uggardian_get_hit_left.fbx",
				strafeLeft = "assets/animations/monsters/uggardian/uggardian_strafe_left.fbx"
			},
			currentLevelOnly = true
		},
		{
			class = "Monster",
			name = "monster",
			meshName = "uggardian_mesh",
			traits = { "elemental" },
			hitEffect = "hit_goo",
			hitSound = "air_elemental_hit",
			dieSound = "air_elemental_die",
			immunities = { "sleep", "blinded", "frozen" },
			resistances = {
				poison = "immune",
				fire = "immune",
				physical = "immune",
				cold = "immune",
				shock = "absorb"
			},
			health = 170,
			exp = 400,
			protection = 0,
			evasion = 0,
			capsuleHeight = 0.6,
			capsuleRadius = 0.3,
			collisionRadius = 0.8
			flying = true,
			onDie = function() print('Cannot Scrape Functions'); end,
		},
		{
			class = "MeleeBrain",
			name = "brain",
			sight = 5
			seeInvisible = true,
		},
		{
			class = "MonsterMove",
			name = "move"
			sound = "air_elemental_walk",
			animationSpeed = 1.3,
			cooldown = 3,
		},
		{
			class = "MonsterTurn",
			name = "turn",
			sound = "air_elemental_walk"
			animationSpeed = 1.5,
		},
		{
			class = "MonsterAttack",
			name = "basicAttack",
			damageType = "pure",
			sound = "air_elemental_attack",
			screenEffect = "leafburst_screen",
			woundChance = 25,
			animationSpeed = 1.5,
			cooldown = 6,
			accuracy = 100,
			attackPower = 30
			knockback = true,
			cameraShake = true,
		},
		{
			class = "UggardianFlames",
			name = "uggardianflames",
			emitFromMaterial = "*",
			particleSystem = "air_elemental"
		},
		{
			class = "Sound",
			name = "sound",
			parentNode = "head"
			sound = "air_elemental_wind",
		}
	}
}
This part is really important and can make your monster "invulnerable" :

Code: Select all

resistances = {
	poison = "immune",
	fire = "immune",
	physical = "immune",
	cold = "immune",
	shock = "absorb"
},
Hope this helps you ;)
minmay
Posts: 2790
Joined: Mon Sep 23, 2013 2:24 am

Re: Another bunch of questions

Post by minmay »

Immunities will not prevent the monster being destroyed by the party jumping or teleporting onto it. I know the incarnations of the Trickster in the main campaign can't be killed by teleporting, so I'd suggest looking at those.

Also, the air elemental is still vulnerable to the "dispel" damage type, so you'd want to add that to the immunities if you go with that approach anyway.
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
Drakkan
Posts: 1318
Joined: Mon Dec 31, 2012 12:25 am

Re: Another bunch of questions

Post by Drakkan »

Batty wrote:
Drakkan wrote:4. script help -
Instead of using spawners, have the plate trigger this function, just fill in the spawner locations:

Code: Select all

function mSpawn()
   if not findEntity('mummy_spawn1') and not findEntity('mummy_spawn2') and not findEntity('mummy_spawn3') then
      spawn('mummy', level, x, y, facing, elevation, 'mummy_spawn1')
      spawn('mummy', level, x, y, facing, elevation, 'mummy_spawn2')
      spawn('mummy', level, x, y, facing, elevation, 'mummy_spawn3')
   end
end

tested first one and working corectly, thanks a lot Batty
Doridion wrote:3. Drakan, for your "indestructible" monster, there's already one in the original asset panel :

Code: Select all

resistances = {
	poison = "immune",
	fire = "immune",
	physical = "immune",
	cold = "immune",
	shock = "absorb"
},
Hope this helps you ;)
perfect, I think it would work, thanks a lot. I need that creature to be destroyable only be triggered script (I think some easy destroy.monster will be ok)
Breath from the unpromising waters.
Eye of the Atlantis
Post Reply