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
Isaac
Posts: 3185
Joined: Fri Mar 02, 2012 10:02 pm

Re: Ask a simple question, get a simple answer

Post by Isaac »

@zimberzimber

This is the updated object. It places the item models, and has limited support for distance checking and item stacking.

*This version does require facing == 0; and it aligns itself on init. If the offsets are wrong, they should be adjustable to suit.
I have a version of it with support for arbitrary facing [0-3], but it has a bug that I don't understand yet. :(

Code: Select all

defineObject{
   name = "river_sockets",
   baseObject = "base_floor_decoration",
   components = {
        {
           class = "Null", 
           onInit = function(self) self.go:setPosition(self.go.x, self.go.y, 0, self.go.elevation, self.go.level)
                    self.go.script:setSource([[

                       function distanceCheck(self, offset, target)
                          local range = 2.5
                          local partyX, null ,partyY = unpack(party:getWorldPosition()) null = nil  --party X/Y world position
                          local worldX, null ,worldY = unpack(self.go:getWorldPosition()) null = nil --object X/Y world position
                     local modelX, modelY = worldX + offset[1] ,worldY + offset[3] 
                          if target then
                             range = .5
                             partyX, null ,partyY = unpack(target:getWorldPosition()) null = nil  --item X/Y world position
                          end   
                          local distance = math.sqrt((partyX-modelX)^2 + (partyY-modelY)^2)
                          if distance < range then
                             return true
                          end   
                       end

                       function stackCheck(self, item)
                          local itemCount = 1
                          local stackable = false
                          for each in self.go.map:entitiesAt(self.go.x, self.go.y) do
                             if each.name == item then
                                if each.item:getStackable() then
                                   stackable = true
                                   if self.go.script:distanceCheck(self.go[item]:getOffset(), each) then
                                      itemCount = itemCount + each.item:getStackSize()
                                      each:destroy()
                                   end
                                end
                             end   
                          end
                          item = spawn(item)
                          if stackable then
                             item.item:setStackSize(itemCount)
                          end
                              return item.item
                       end
                    ]])
           end,   
        },
        {
           class = "Script",
        },
      {
         class = "Model", --"crystal_flower"
         name = "s1",
         offset = vec(0.35, 0, 1.49),
       model = "assets/models/items/crystal_flower.fbx",
      },
      {
         class = "Clickable", 
         name = "crystal_flower",
         offset = vec(0.35, 0, 1.49),
         size = vec(.2,.2,.2),
         frontFacing = false,
         --debugDraw = true,
         maxDistance = 1,
         onClick = function(self) if not getMouseItem() then 
         							if self.go.script:distanceCheck(self.go.s1:getOffset()) then
          								self.go.s1:disable() self.go[self:getName()]:disable()  setMouseItem(self.go.script:stackCheck(self:getName())) 
          							end
               					  end
           end,
     },

      {
         class = "Model", --"blooddrop_cap"
         name = "s2",
         offset = vec(-0.35, 0, 1.1),
       model = "assets/models/items/blooddrop_cap.fbx",
      },
      {
         class = "Clickable", 
         name = "blooddrop_cap",
               offset = vec(-0.35, 0, 1.1),
         size = vec(.2,.2,.2),
         frontFacing = false,
         --debugDraw = true,
         maxDistance = 1,
         onClick = function(self) if not getMouseItem() then 
         							if self.go.script:distanceCheck(self.go.s2:getOffset()) then
          								self.go.s2:disable() self.go[self:getName()]:disable()  setMouseItem(self.go.script:stackCheck(self:getName())) 
          							end
               					  end
           end,
     },

      {
         class = "Model", --"etherweed"
         name = "s3",
         offset = vec(-0.35, 0, 0.4),
       model = "assets/models/items/milkreed.fbx",
      },
      {
         class = "Clickable", 
         name = "etherweed",
            offset = vec(-0.35, 0, 0.4),
         size = vec(.2,.8,.2),
         frontFacing = false,
         --debugDraw = true,
         maxDistance = 1,
         onClick = function(self) if not getMouseItem() then 
         							if self.go.script:distanceCheck(self.go.s3:getOffset()) then
          								self.go.s3:disable() self.go[self:getName()]:disable()  setMouseItem(self.go.script:stackCheck(self:getName())) 
          							end
               					  end
           end,         
     },

      {
         class = "Model", --"brass_key"
         name = "s4",
         offset = vec(0.8, -0.05, 0.55),
       model = "assets/models/items/key_brass.fbx",
      },
      {
         class = "Clickable", 
         name = "brass_key",
            offset = vec(0.8, -0.05, 0.55),
         size = vec(.2,.2,.2),
         frontFacing = false,
         --debugDraw = true,
         maxDistance = 1,
         onClick = function(self) if not getMouseItem() then 
         							if self.go.script:distanceCheck(self.go.s4:getOffset()) then
          								self.go.s4:disable() self.go[self:getName()]:disable()  setMouseItem(self.go.script:stackCheck(self:getName())) 
          							end
               					  end
           end,      
     },

      {
         class = "Model", --"skull"
         name = "s5",
         offset = vec(-0.5, 0, -0.85),
    model = "assets/models/items/skull.fbx",
      },
      {
         class = "Clickable", 
         name = "skull",
               offset = vec(-0.5, 0, -0.85),
         size = vec(.2,.3,.2),
         frontFacing = false,
         --debugDraw = true,
         maxDistance = 1,
         onClick = function(self) if not getMouseItem() then 
         							if self.go.script:distanceCheck(self.go.s5:getOffset()) then
          								self.go.s5:disable() self.go[self:getName()]:disable()  setMouseItem(self.go.script:stackCheck(self:getName())) 
          							end
               					  end
           end,            
     },

   },
   placement = "floor",
   editorIcon = 104,
}
*Updated
zdenekhoub
Posts: 53
Joined: Fri Aug 26, 2016 11:56 am

Re: Ask a simple question, get a simple answer

Post by zdenekhoub »

Hello!

I need help with minimalSaveState please! I have many many objects using setSubtileOffset in my mod. The mod is about 8 hours playtime and it took me over 700 hours to make it. It is almost complete but I have one serious problem. Alas I have found minmay's thread about dangers of minimalSaveState too late in the making of my mod. I have used his script he posted to try and fix my problem. The script is:

Code: Select all

defineObject{
  name = "reload_detector",
  placement = "floor",
  minimalSaveState = true,
  components = {
    {
      class = "Null",
      onInit = function(self) -- whenever this onInit hook executes, it means the game was started or loaded
        reloadScript.script.onReload()
      end,
    },
  },
  editorIcon = 1,
}
But when I insert this script into objects.lua and then insert on the map "reload_detector" object and run the editor - I get this error:

Image

I am no programmer, I have learned all I needed to make my mod in these forums and tutorials on YT and this is beyond my programming skill, can someone please help me fix this?

Screens of minimalSaveState problem before saving/loading the game, note the pillars only:
Image

And after player loads a game the pillars and their "handmade" created flags and statues made from wyvern models are misplaced:
Image
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 »

Instead of setting an offset through a function, you're better off integrating it directly into the component.
Like this:

Code: Select all

class = "Model",
name = "skull",
offset = vec(-0.5, 0, -0.85),
model = "assets/models/items/skull.fbx",
The offset field modifies the location of the component in comparison to its origin in the object, be it a model, a light source, or a clickable area.
There is also a rotation field that rotates the component. Not sure if this can be used with other component types (light, particles, etc), don't see a reason to.
My asset pack [v1.10]
Features a bit of everything! :D
User avatar
THOM
Posts: 1274
Joined: Wed Nov 20, 2013 11:35 pm
Location: Germany - Cologne
Contact:

Re: Ask a simple question, get a simple answer

Post by THOM »

AFAIK the reload detector is just a tool to see, if your dungeon was reloaded. Nothing else. This can be important for something like storytelling, savestate-altering and so on. I cannot see, where it could help you with the problem of the minimalsavestate.

Concering that: It is good for avoiding perfomance-issues during the saving/reloading process to keep the number of objects with minimalsavestate = false small. It is not necessary to avoid completely giving objects the false-state. For many objects it is absolutely important having minimalsavestate = false. For example altars, alcoves and all objects with surface- and socket-components need that absolutely.

Objects with minimalsavestate will loose after a reload all alterations made to them. Including inserting items, switching components on/off, changeing positions.

If the number of your objects is small, there is no danger, if you give them minimalsavestate = false. After a reload the positioning of your object will be kept then.

Or you can give an offset entry to the object-definition, as zimberzimber mentioned.
THOM formaly known as tschrage
_______________________________________________
My MOD (LoG1): Castle Ringfort Thread
My MOD (LoG2): Journey To Justice Thread | Download
User avatar
THOM
Posts: 1274
Joined: Wed Nov 20, 2013 11:35 pm
Location: Germany - Cologne
Contact:

Re: Ask a simple question, get a simple answer

Post by THOM »

BTW: The problem with the "reload_detector" you have tried to use is, that it wants to execute a function named "onReload" in the script-entity "reloadScript".

Both must be present in your mod - otherwise you will get that error.
THOM formaly known as tschrage
_______________________________________________
My MOD (LoG1): Castle Ringfort Thread
My MOD (LoG2): Journey To Justice Thread | Download
zdenekhoub
Posts: 53
Joined: Fri Aug 26, 2016 11:56 am

Re: Ask a simple question, get a simple answer

Post by zdenekhoub »

THOM wrote: If the number of your objects is small, there is no danger, if you give them minimalsavestate = false. After a reload the positioning of your object will be kept then.
Thank you both for your answers! Please can you be more specific on how/where I can put a line giving an object minimalsavestate = false? If the object is for example mine_support_beam_01 how will the whole line of code setting minimalsavestate = false put together?

What would completely save my mod is a script - or solution where I could put names of all the objects I need to stay in minimalsavestate = false - one by one by pasting their names from editor - or paste whole list of such objects in one script.

I am sure there must be a way to do this, can someone help me please?
User avatar
THOM
Posts: 1274
Joined: Wed Nov 20, 2013 11:35 pm
Location: Germany - Cologne
Contact:

Re: Ask a simple question, get a simple answer

Post by THOM »

Have you downloaded the asset-pack of LoG2? You will find in there all definitions for all game-objects.

There is also the one for the support beam:

Code: Select all

defineObject{
	name = "mine_support_beam_01",
	baseObject = "base_wall_decoration",
	components = {
		{
			class = "Model",
			model = "assets/models/env/mine_support_beam_01.fbx",
			staticShadow = true,
		}
	},
	editorIcon = 188,
	minimalSaveState = true,
}
As you can see, it already has a statement for minimalsavestate. Replace "true" with "false" - that's all.

(Well - you know how to replace an existing definition of an LoG2 object?)
THOM formaly known as tschrage
_______________________________________________
My MOD (LoG1): Castle Ringfort Thread
My MOD (LoG2): Journey To Justice Thread | Download
zdenekhoub
Posts: 53
Joined: Fri Aug 26, 2016 11:56 am

Re: Ask a simple question, get a simple answer

Post by zdenekhoub »

I didnt downloaded the asset pack, didnt need it so far - I just sat down and started making my mod and keep going for 700 hours, silly me :)
As you can see, it already has a statement for minimalsavestate. Replace "true" with "false" - that's all.
Yes that is the easy part I understand now from your example, thank you! But I have to make this definition in objects.lua for each of the object I moved by setSubtileOffset, one by one?
(Well - you know how to replace an existing definition of an LoG2 object?)
I am not sure I thought if I wanted to change an object or make a new one, I put the new definition in objects.lua and thats it and then insert such an object in editor.
User avatar
THOM
Posts: 1274
Joined: Wed Nov 20, 2013 11:35 pm
Location: Germany - Cologne
Contact:

Re: Ask a simple question, get a simple answer

Post by THOM »

zdenekhoub wrote: I have to make this definition in objects.lua for each of the object I moved by setSubtileOffset, one by one?
Yes.
zdenekhoub wrote: I thought if I wanted to change an object or make a new one, I put the new definition in objects.lua and thats it and then insert such an object in editor.
Yes, that's possible.

I by myself redirected the loading process of the original asset-pack.

In the init-file I've exchanged the line

Code: Select all

import "assets/scripts/standard_assets.lua"
by

Code: Select all

import "mod_assets/scripts/standard_assets.lua"
and made sure, that the file standard_assets.lua from the asset-pack is in my mod_assets folder. Then I've copied also all the definitions of the original pack into my mod_assets folder and changed every path written in standard_assets.lua so they are pointing now to my definition files. It's a bit work - but now you can edit everything directly in the original-definition before it gets loaded into the editor and don't have to overwrite an already loaded one.
THOM formaly known as tschrage
_______________________________________________
My MOD (LoG1): Castle Ringfort Thread
My MOD (LoG2): Journey To Justice Thread | Download
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 »

About minimal save state - The default minimalSaveState is set to false, so you can just remove that line.
My asset pack [v1.10]
Features a bit of everything! :D
Post Reply