Page 1 of 17

Editor Tutorials on YouTube - part 14 is out

Posted: Thu Oct 16, 2014 3:33 am
by Skuggasveinn
I've created some tutorials for the new Dungeon Editor
Please note that I'm just learning this stuff myself, and I've not seen the lua code behind the assets so I reserve the right to be complete wrong about what I'm talking about :D


Part 1 - http://youtu.be/vMMBC9B2qjM GUI and new features
Part 2 - http://youtu.be/eDaeqUUOuSc Elevations inside dungeons
Part 3 - http://youtu.be/6cv3P8dxCgY Coordinates and level transition
Part 4 - http://youtu.be/hVpY60Ptjdk Creating Water and Reflections
Part 5 - http://youtu.be/bLwSL8mhJOk Outdoor scenario
Part 6 - http://youtu.be/dxonfsoRYOY Bossfight
Code from part 6
SpoilerShow

Code: Select all

function startBrothersBossFight()
	boss_fight_brothers.bossfight:addMonster(skeleton_commander_1.monster)
	boss_fight_brothers.bossfight:addMonster(skeleton_commander_2.monster)
	boss_fight_brothers.bossfight:activate()
end

function startMedusaBossFight()
	boss_fight_medusa.bossfight:addMonster(medusa_1.monster)
	boss_fight_medusa.bossfight:activate()

end
Part 7 http://youtu.be/-YlAZwqcptc Firetrap
Code from part 7
SpoilerShow
the firetrap code

Code: Select all

function startmagmacontdown()
	magma_countdown.bossfight:addMonster(magma_golem_1.monster)
	magma_countdown.bossfight:activate()
	timer_1.timer:start()

end

timecount = 1

function shakeitbaby()
	party.party:shakeCamera(0.05,60)
	dungeon_fire_pit_1.particle:enable()
	dungeon_fire_pit_2.particle:enable()
	dungeon_fire_pit_3.particle:enable()
	dungeon_fire_pit_4.particle:enable()
	dungeon_fire_pit_5.particle:enable()
	dungeon_fire_pit_6.particle:enable()
	dungeon_fire_pit_7.particle:enable()
	dungeon_fire_pit_8.particle:enable()
	dungeon_fire_pit_9.particle:enable()
	dungeon_fire_pit_10.particle:enable()
	dungeon_fire_pit_11.particle:enable()
	
end


function hurtgolem()


  if timecount == 1 then

  elseif timecount == 2 then


  elseif timecount == 3 then
    magma_golem_1.monster:setHealth(950)
		
  elseif timecount == 4 then
    magma_golem_1.monster:setHealth(900)
		
  elseif timecount == 5 then
    magma_golem_1.monster:setHealth(850)

  elseif timecount == 6 then
	magma_golem_1.monster:setHealth(800)
	
  elseif timecount == 7 then
	magma_golem_1.monster:setHealth(750)
  
  elseif timecount == 8 then
	magma_golem_1.monster:setHealth(700)
	
  elseif timecount == 9 then
	magma_golem_1.monster:setHealth(650)
	
  elseif timecount == 10 then
	magma_golem_1.monster:setHealth(600)
	
  elseif timecount == 11 then
	magma_golem_1.monster:setHealth(550)
	
  elseif timecount == 12 then
	magma_golem_1.monster:setHealth(500)
	
  elseif timecount == 13 then
	magma_golem_1.monster:setHealth(450)
	
  elseif timecount == 14 then
	magma_golem_1.monster:setHealth(400)
	
  elseif timecount == 15 then
	magma_golem_1.monster:setHealth(350)
	
  elseif timecount == 16 then
	magma_golem_1.monster:setHealth(300)
	
  elseif timecount == 17 then
	magma_golem_1.monster:setHealth(250)
	
  elseif timecount == 18 then
	magma_golem_1.monster:setHealth(200)
	
  elseif timecount == 19 then
	magma_golem_1.monster:setHealth(150)
	
  elseif timecount == 20 then
	magma_golem_1.monster:setHealth(100)
	
  elseif timecount == 21 then
	magma_golem_1.monster:setHealth(50)
		
  elseif timecount == 22 then
	magma_golem_1.monster:setHealth(0)
	
  elseif timecount == 23 then
	magma_countdown.bossfight:deactivate()
	magma_golem_1.monster:die();
    die = true;
	spawn("flame_wave", 1, 17, 24, 1, 0)
	spawn("flame_wave", 1, 17, 26, 1, 0)
	spawn("flame_wave", 1, 18, 25, 1, 0)
	spawn("flame_wave", 1, 19, 24, 1, 0)
	spawn("flame_wave", 1, 19, 26, 1, 0)
	spawn("flame_wave", 1, 20, 25, 1, 0)
	spawn("flame_wave", 1, 21, 24, 1, 0)
	spawn("flame_wave", 1, 21, 26, 1, 0)
	spawn("flame_wave", 1, 22, 25, 1, 0)
	spawn("flame_wave", 1, 23, 24, 1, 0)
	spawn("flame_wave", 1, 23, 26, 1, 0)
	timer_1.timer:stop()
	
  	timecount = 1
   	return
  end
    timecount = timecount + 1
end
The lever puzzle code

Code: Select all

function firetrappuzzle1()

	--local count1 = firecounter_1.counter:getValue()
	--local count2 = firecounter_2.counter:getValue()
	--local count3 = firecounter_3.counter:getValue()

	if firecounter_1.counter:getValue() == 0 and
	firecounter_2.counter:getValue() == 1 and
	firecounter_3.counter:getValue() == 0 then

	--hudPrint("firecounter_1 has "..count1.." in value")
	--hudPrint("firecounter_2 has "..count2.." in value")
	--hudPrint("firecounter_3 has "..count3.." in value")
	mine_door_spear_1.door:open()

	else
	mine_door_spear_1.door:close()
	--hudPrint("firecounter_1 has "..count1.." in value")
	--hudPrint("firecounter_2 has "..count2.." in value")
	--hudPrint("firecounter_3 has "..count3.." in value")
	end
	
end


function firetrappuzzle2()

	--local count1 = firecounter_1.counter:getValue()
	--local count2 = firecounter_2.counter:getValue()
	--local count3 = firecounter_3.counter:getValue()

	if firecounter_1.counter:getValue() == 1 and
	firecounter_2.counter:getValue() == 0 and
	firecounter_3.counter:getValue() == 0 then

	--hudPrint("firecounter_1 has "..count1.." in value")
	--hudPrint("firecounter_2 has "..count2.." in value")
	--hudPrint("firecounter_3 has "..count3.." in value")
	mine_door_spear_2.door:open()

	else
	mine_door_spear_2.door:close()
	--hudPrint("firecounter_1 has "..count1.." in value")
	--hudPrint("firecounter_2 has "..count2.." in value")
	--hudPrint("firecounter_3 has "..count3.." in value")
	end
	
end

function resetdoors()
	
	if mine_door_spear_1.door:isOpen() == true or
	mine_door_spear_2.door:isOpen() == true then
	mine_door_spear_1.door:close()
	mine_door_spear_2.door:close()
	
	else
	
	end
	
end
Part 8 http://youtu.be/T9vM91bLUY8- Buried Treasures
Code from part 8
SpoilerShow
how we spawn stuff that's bound to the coordinates of the script entity

Code: Select all

function hiddencorpse()
      self.go:spawn("floor_corpse")
      self.go:spawn("skull")
      self.go:spawn("rapier")
      hudPrint("You have found a buried body")
      for i = 1, 4, 1 do
      party.party:getChampion(i):gainExp(250)
      end
      hudPrint("250 exp")
      playSound("secret")
end
How we assign the treasure map texture to our scroll entity

Code: Select all

treasure_map_1.scrollitem:setScrollImage("mod_assets/textures/treasure_map_1.dds")
Part 9 http://youtu.be/lRJCie3uWw0 Day and Night cycle
Code from part 9
SpoilerShow

Code: Select all

function whattimeisit()  -- prints out the current time of day for debug
	wtii = GameMode.getTimeOfDay()
	hudPrint(""..wtii.."")
end


function nightbridge()  -- turnes the bridge on during night
	if GameMode.getTimeOfDay() > 1.04 and GameMode.getTimeOfDay() < 1.97 then
	magic_bridge_1.controller:activate()
	magic_bridge_2.controller:activate()
	else
	magic_bridge_1.controller:deactivate()
	magic_bridge_2.controller:deactivate()
	end
end

function movetime()   -- moves the time forward by 0.0001
	wtii = GameMode.getTimeOfDay()
	GameMode.setTimeOfDay(wtii + 0.0001)
end

function fireflies()   -- enables light and particales on fireflies during the night
	if GameMode.getTimeOfDay() > 1.04 and GameMode.getTimeOfDay() < 1.97 then
	forest_fireflies_1.particle:enable()
	forest_fireflies_1.light:enable()
	forest_fireflies_2.particle:enable()
	forest_fireflies_2.light:enable()
	else
	forest_fireflies_1.particle:disable()
	forest_fireflies_1.light:disable()
	forest_fireflies_2.particle:disable()
	forest_fireflies_2.light:disable()
	end
end
Part 10 http://youtu.be/WfAi31AScgw - Alcove Puzzles
code from part 10
SpoilerShow
Alcove that counts how many consumables you have placed.

Code: Select all

function checkItems(alcove)
	local count = 0
	
	for v,i in alcove:contents() do
	if i :hasTrait("consumable") then
	count = count + 1
	end
end

	if count >= 3 then
	dungeon_secret_door_1.door:open()
	else
	dungeon_secret_door_1.door:close()
	end
end
Alcoves the need to correct figures placed into the correct alcoves.

Code: Select all

function surfaceContains(surface, item)
	for v,i in surface:contents() do
	if i.go.name == item then return true
	end
end
end

function openPowerGemDoor()
	if surfaceContains(dungeon_alcove_2.surface, "figure_ogre") and
	surfaceContains(dungeon_alcove_3.surface, "figure_crowern") and
	surfaceContains(dungeon_alcove_4.surface, "figure_skeleton") and
	surfaceContains(dungeon_alcove_5.surface, "figure_snail") then
	dungeon_door_iron_barred_1.door:open()
	else
	dungeon_door_iron_barred_1.door:close()
	end
end
Part 11 http://youtu.be/tCwR1VXa4Xg - Breakable Walls
code from part 11 -- Download the breakable walls, sound and scripts to use within your dungeon here http://www.zorglubb.net/grimrock/dropzo ... _walls.zip
SpoilerShow
The 3 walls needed to create the breakable wall

Code: Select all

defineObject{
   name = "dungeon_breakable_wall",
   baseObject = "base_obstacle",
   components = {
      {
         class = "Model",
         model = "mod_assets/models/sx_dungeon_breakable_wall_hard.fbx",
      },
	   
       {
         class = "Obstacle",
         hitSound = "impact_blunt",
         hitEffect = "hit_dust",
      },
      {
         class = "Health",
         health = 15,
         spawnOnDeath = "dungeon_breakable_wall_damaged",
		 onDie = function(self)
               playSound("wall_breaking")
			   party.party:shakeCamera(0.02,2)
        end,
      },
      {
         class = "Controller",
      },
   },
   placement = "wall",
   automapTile = "wall",
   editorIcon = 120,
}

defineObject{
   name = "dungeon_breakable_wall_damaged",
   components = {
      {
         class = "Model",
         model = "mod_assets/models/sx_dungeon_breakable_wall_damaged.fbx",
      },
       {
         class = "Obstacle",
         hitSound = "impact_blunt",
         hitEffect = "hit_dust",
      },
      {
         class = "Health",
         health = 15,
         spawnOnDeath = "dungeon_breakable_wall_broken",
		 onDie = function(self)
               playSound("wall_breaking")
			   party.party:shakeCamera(0.02,2)
        end,
      },
      {
         class = "Controller",
      },
   },
   placement = "wall",
   automapTile = "grassy_ground",
   editorIcon = 120,
}

defineObject{
   name = "dungeon_breakable_wall_broken",
   components = {
      {
         class = "Model",
         model = "mod_assets/models/sx_dungeon_breakable_wall_broken.fbx",
      },  
       {
         class = "Controller",
      },
   },
   placement = "wall",
   editorIcon = 120,
}
The sound defenition

Code: Select all

defineSound{
	name = "wall_breaking",
	filename = "mod_assets/sounds/sx_wallbreaking.wav",
	loop = false,
	volume = 1.00,
	minDistance = 2,
	maxDistance = 2,
}
Part 12 http://youtu.be/7L8Epmsqg_Q - Creating our own Weapons
code from part 12 -- Download the Heartseeker asset and scripts here http://www.zorglubb.net/grimrock/dropzo ... seeker.zip
SpoilerShow
The Heartseeker and the Elemental Bow

Code: Select all

defineObject{
      name = "heartseeker",
      baseObject = "base_item",
      components = {
      {
         class = "Model",
         model = "mod_assets/models/heartseeker.fbx",
      },
      {
         class ="Item",
         uiName = "Heartseeker",
         gfxAtlas = "mod_assets/textures/items_atlas.dds",
         gfxIndex = 0,
		 GfxIndexPowerAttack = 1,
         secondaryAction = "slice",
         weight = 2.7,
         impactSound = "impact_blade",
         traits = { "bow", "missile_weapon" },
         description = "Sublime Longbow obviously made with love and care."
      },
      {
         class = "RangedAttack",
         attackPower = 5,
         accuracy = 10,
		 Ammo = "arrow",
         attackSound = "swipe_bow",
         cooldown = 2.0,
         baseDamageStat = "dexterity",
         damageType = "physical",
         --requirements = {"missile_weapons" ,3},
      },
	{
        class = "MeleeAttack",         
        name = "slice",
		uiName = "Slice",
		repeatCount = 0,
		attackPower = 26,
		swipe = "horizontal",
		attackSound = "swipe_special",
		baseDamageStat = "dexterity",
        cooldown = 0.2,
        energyCost = 5,
		--requirements = { "accuracy", 2},
                
        },
   }
}

defineObject{
        name = "elemental_bow",
        baseObject = "base_item",
        components = {
   {
        class = "Model",
        model = "mod_assets/models/heartseeker.fbx",   
        },
        {
              class ="Item",
              uiName = "Bow of the Elements",
			  gfxAtlas = "mod_assets/textures/items_atlas.dds",
              gfxIndex = 0,
			  GfxIndexPowerAttack = 1,
              weight = 2.7,
              impactSound = "impact_blade",
              secondaryAction = "elementalstorm",
              traits = { "bow", "missile_weapon" },
              description = "Sublime Longbow obviously made with love and care."
        },
        {
              class = "CastSpell",
			  spell = "fireball",
              cooldown = 2.2,

        },
        {
              class = "CastSpell",
			  name = "elementalstorm",
			  uiName = "Elemental Storm",
			  chainAction = "elementalstorm1",
		      chainActionDelay = 0.2,
			  spell = "fireball",

        },
        {
              class = "CastSpell",
			  name = "elementalstorm1",
			  uiName = "Elemental Storm",
			  chainAction = "elementalstorm2",
		      chainActionDelay = 0.2,
			  spell = "frostbolt",

        },
        {
              class = "CastSpell",
			  name = "elementalstorm2",
			  uiName = "Elemental Storm",
			  chainAction = "elementalstorm3",
		      chainActionDelay = 0.2,
			  spell = "poison_bolt",
        },
		{
              class = "CastSpell",
			  name = "elementalstorm3",
			  uiName = "Elemental Storm",
			  chainAction = "elementalstorm4",
		      chainActionDelay = 0.2,
			  spell = "lightning_bolt",
        },
        {
              class = "CastSpell",
			  name = "elementalstorm4",
			  uiName = "Elemental Storm",
			  spell = "darkbolt",
        },
   }
 }   
Part 13 - http://youtu.be/b9h7nCI1rQk Simple animations for custom 3D objects

Part 14 - https://youtu.be/xAj65MM2lww Occluders

Playlist link https://www.youtube.com/playlist?list=P ... B7joLG52Nc

Hope that this will help someone get started.
Maybe I will add to these in the future.

Skuggasveinn.

Re: Editor Tutorials on YouTube

Posted: Thu Oct 16, 2014 5:04 am
by RixSolstice
my god, this is just awesome. Would mods maybe sticky this for a while?

Re: Editor Tutorials on YouTube

Posted: Thu Oct 16, 2014 7:25 am
by cromcrom
Thank you so much for these great tuts, they are amazing :-)

Re: Editor Tutorials on YouTube

Posted: Thu Oct 16, 2014 7:28 am
by Drakkan
thanks for vidoes Skugg, please do more ! :)

Re: Editor Tutorials on YouTube

Posted: Thu Oct 16, 2014 7:33 am
by antti
Hey, could you make a youtube playlist of the videos for easier linking? While we're still working on the official modding guide, it's good to have something to link to for the more impatient modders on twitter and elsewhere :)

Re: Editor Tutorials on YouTube

Posted: Thu Oct 16, 2014 9:38 am
by Mysterious
Hi Skuggs the videos are grate :)

I tried the joining of levels as you said but now I am have a problem.

Here are the levels so far:

0,0,0 start
0,0,1 down
1,0,0 right
-1,0,0 left + exit object (just like your video)

The problem is how do you make a level join at the bottom or top etc.... with exit object? I tried this as a new level to join with (left)
-1,0,-1 left down (This does not work for some reason it just stops me on the left level, I have put the 2 exit objects on both levels but to no avail lol.

I am trying hard to figure out how each level can join to each other using the Exit Object, but am having problems with the x,y,z thing. Thxs for any help :)

Re: Editor Tutorials on YouTube

Posted: Thu Oct 16, 2014 11:08 am
by Skuggasveinn
The original topic has been update with a link to a playlist.
Mysterious wrote: The problem is how do you make a level join at the bottom or top etc.... with exit object? I tried this as a new level to join with (left)
-1,0,-1 left down (This does not work for some reason it just stops me on the left level, I have put the 2 exit objects on both levels but to no avail lol.
I am trying hard to figure out how each level can join to each other using the Exit Object, but am having problems with the x,y,z thing. Thxs for any help :)
When going up and down you use stairs, the easiest way is to place stairs in the same grid on both levels,then the party will just go up and down, you can also use the custom target field for stairs then you can simply choose where the party comes out, but personally I like how AH did this in the main campaign, everything just flows naturally between levels.

If you are having problems with how the coordinates stack up (or maybe my rumblings didn't make sense in the video :) ) I created a picture that hopefully explains this in more detail.
Image

Hope that helps.

Skuggasveinn.

Re: Editor Tutorials on YouTube

Posted: Thu Oct 16, 2014 2:09 pm
by Ciccipicci
Thanks both for the vids and the pic.

Re: Editor Tutorials on YouTube

Posted: Thu Oct 16, 2014 10:29 pm
by Mysterious
Hi Skuggs.

Thank you for the picture it makes sense now I have created mulitiple ways around the map :)

Re: Editor Tutorials on YouTube

Posted: Sun Oct 19, 2014 3:36 pm
by A100N
I would have asked for a tutorial for the scripts :(
for LoG 2