Accessing Object Properties

Talk about creating Grimrock 1 levels and mods here. Warning: forum contains spoilers!
Post Reply
chaoscommencer
Posts: 119
Joined: Sun Jan 05, 2014 7:48 pm

Accessing Object Properties

Post by chaoscommencer »

Hello, I was wondering if anyone has run into any issues accessing certain object properties? I would like to obtain an object's "placement" property for instance, however, even objects that have "placement" as a property, such as instances of pressure_plate_hidden, return nil when trying to access it... Is it possible to obtain that value, or are some such properties hidden/inaccessible? If so, any advice would be appreciated.
Working on a dungeon that displays a massive collection of assets while sorting them into convenient reusable plugin format (concept from some of leki's mods). Will contribute some of my own models as well eventually and follow that with custom dungeon.
chaoscommencer
Posts: 119
Joined: Sun Jan 05, 2014 7:48 pm

Re: Accessing Object Properties

Post by chaoscommencer »

Hello, I've run into another instance of this issue. I am trying to access user-defined properties of objects. Please find some example code below:

Code: Select all

defineObject{
	name = "cc_hidden_alcove",
	class = "Alcove",
	model = "mod_assets/plugins/clear_walls/models/clear_wall.fbx",
	replacesWall = false,
	anchorPos = vec(0, 0.85, 0.2),
	targetPos = vec(0,1.3,0),
	targetSize = vec(0.6, 0.5, 0.6),
	placement = "wall",
	editorIcon = 8,
}

cloneObject{
	name = "cc_thieves_tools_hidden_alcove",
	baseObject = "cc_hidden_alcove",
	targetPos = vec(0,0.45,0),
    detectableID = "dungeon_pressure_plate_1", --nil,
    onInsertItem = function(self, item)
        print("hi!")
        if (item.name == "torch") or (item.name == "torch_everburning") then
            print("item is a torch!")
        else
            print("Inserted item name is:", item.name)
        end
        if self.detectableID then
            print("DetectableID:", self.detectableID)
        else
            print("DetectableID is nil") --this line is printed, so I can't find the desired entity
            --to destroy and have to manually enter the id as in the following if statement
        end
        --if detectableID and ((item.name == "torch") or (item.name == "torch_everburning")) then
        if ((item.name == "torch") or (item.name == "torch_everburning")) then
            local detectable = findEntity("dungeon_pressure_plate_1")
            print("destroying...")
            detectable:destroy()
            self:destroy()
            print("destroyed.")
        end
        return false
    end,
}
The idea here is to access the detectable object's ID (in this case, a pressure plate) and deactivate it. Ultimately the detectableID will be set by an external script when the alcove is created (the alcove gets created dynamically when the trap is detected). It would populate the detectableID with that of the trap so the onInsertItem script could determine what trap to deactivate and to do so.
Yes, I happen to be working on a disarm trap script ;). Any ideas on how to access the object properties (or perhaps on another way to achieve the same outcome) would be supremely helpful!
Working on a dungeon that displays a massive collection of assets while sorting them into convenient reusable plugin format (concept from some of leki's mods). Will contribute some of my own models as well eventually and follow that with custom dungeon.
alois
Posts: 112
Joined: Mon Feb 18, 2013 7:29 am

Re: Accessing Object Properties

Post by alois »

chaoscommencer wrote:Any ideas on how to access the object properties (or perhaps on another way to achieve the same outcome) would be supremely helpful!
I do not think you can add new object properties besides those which are already there... :(

alois :)
User avatar
JohnWordsworth
Posts: 1397
Joined: Fri Sep 14, 2012 4:19 pm
Location: Devon, United Kingdom
Contact:

Re: Accessing Object Properties

Post by JohnWordsworth »

Unless you see an entry for a given property in the Scripting Reference then I'm afraid it's not possible to get these properties directly.

SOLUTION 1 (Easy but Messy)

The simple solution (although tedious and error prone as you need to duplicate information) is to just have one massive table with all of the values that you need stored in a script somewhere. So you might have a script entity like this;

Script Entity: objectProperties

Code: Select all

local properties = { };
properties["cc_hidden_alcove" ] = {
  replacesWall = false,
  placement = "wall", 
}

function getProperty(objectName, key) 
  if ( objectName == nil or key == nil ) then
    return nil;
  end

  if ( properties[objectName] == nil ) then 
    return nil;
  end

  return properties[objectName][property];
end
You would only need to code in the properties you need, but you would have to make more sure whenever you change a property in a lua file, you also mirror that change in the script entity. Still, it's a fairly easy solution.

SOLUTION 2 (Better but Complicated)

This is a random off the top of my head thought which might not work (there are some issues I've thought about, but haven't thought about long enough to think if/how they can be solved). However, you should be able to define your own method in a lua script 'customDefineObject'. This method would come at the top of your first init script (before you need to use it) and would simply do the following;

Code: Select all

function customDefineObject(description) 
  if ( description == nil ) then
    return;
  end 

  defineObject(description);

  if ( description.name ) then
    gObjectProperties[description.name] = description;
  end
end
So this would store all of the object descriptions in a big table that's accessible from within the 'init' scripts. The challenge is then getting that information available in the game (as the init scripts all run when the dungeon is built, but then that lua state is presumably discarded and new ones are used by the script entities). However, the log_framework has solved this before - you would have to create a door (or something similar) which generates a script_entity when it's opened (which you would do with a quick one-liner in a script entity). You would then have to generate lua code as a big long string and use the undocumented 'setSource(code)' method on a script_entity to pass the information from the dungeon building phase to the game.

There's a lot of work involved in this method and I've just posted an overview of it here. If you're seriously interested in this method because this is something you need to do a lot - let me know and I can post some more code snippets to help implement it. However, if you just need to get one or two properties of some objects, I would just go with option 1 and save yourself an hour or two of coding (or potentially a lot of hours if you're new to Lua and scripting).
My Grimrock Projects Page with links to the Grimrock Model Toolkit, GrimFBX, Atlas Toolkit, QuickBar, NoteBook and the Oriental Weapons Pack.
chaoscommencer
Posts: 119
Joined: Sun Jan 05, 2014 7:48 pm

Re: Accessing Object Properties

Post by chaoscommencer »

Thanks for the tip alois. I suppose I was too hopeful to think the objects might work like tables in that way...

Thanks for the thoughts John. I actually do have an external script entity that holds a table of all the detectable objects by I'd as well as whether they've been detected or triggered. Another property for each detectable object will be a table of ids of the entities spawned when the object was detected. I'm not sure how persistence through saves will work yet or if perhaps it already does.

By the way I love making my life more complicated ;). So if you get a chance to post a link to some of that code you referred to that would be cool. I do intend to write this the best way whether or not it's more difficult.
Working on a dungeon that displays a massive collection of assets while sorting them into convenient reusable plugin format (concept from some of leki's mods). Will contribute some of my own models as well eventually and follow that with custom dungeon.
chaoscommencer
Posts: 119
Joined: Sun Jan 05, 2014 7:48 pm

Re: Accessing Object Properties

Post by chaoscommencer »

Does anyone know if it is possible to define custom ScriptEntity-based objects with the script in them? For example:

Code: Select all

cloneObject{
	name = "spawner_script",
	baseObject = "script_entity",
	script = "--write script here",
}
Also, if you get a chance to post some of those snippets you mentioned John, that would be great :).

Inside the script property for example, you could put something like

Code: Select all

function auto_exec(self)
	spawnEntity("", self.level, self.x - 1, self.y - 1, self.facing)
	spawnEntity("", self.level, self.x, self.y - 1, self.facing)
	spawnEntity("", self.level, self.x + 1, self.y - 1, self.facing)
	spawnEntity("", self.level, self.x + 1, self.y, self.facing)

	spawnEntity("", self.level, self.x + 1, self.y + 1, self.facing)
	spawnEntity("", self.level, self.x, self.y + 1, self.facing)
	spawnEntity("", self.level, self.x - 1, self.y + 1, self.facing)
	spawnEntity("", self.level, self.x - 1, self.y, self.facing)
end
In this way you could spawn several objects with one script or just one if you so chose, and spawning one of these script entities would spawn all the objects you wanted. I am seeing alternatives to this, but I would still like to have something like this available if anyone knows how to initialize that script property. Thanks!
Working on a dungeon that displays a massive collection of assets while sorting them into convenient reusable plugin format (concept from some of leki's mods). Will contribute some of my own models as well eventually and follow that with custom dungeon.
Post Reply