TTLG|Jukebox|Thief|Bioshock|System Shock|Deus Ex|Mobile
Page 3 of 3 FirstFirst 123
Results 51 to 52 of 52

Thread: Understanding Squirrel Scripts

  1. #51
    Member
    Registered: Jan 2001
    Location: 27430 Cells
    I've just been trying to write a script that, among other things, changes the colours of 'bitmap disks' of a particle effect. I thought the data type of the value would be a vector with r, g, b values. Turns out it's a string. Thought I'd post this in case anyone else gets puzzled by the same situation.

    e.g, to set the first bitmap disk colour to blue:
    Code:
    class ParticleColour extends SqRootScript
    {
    	function OnTurnOn()
    	{
    		SetProperty("ParticleGroup", "bm-disk rgb" , "0, 0, 255");
    	}
    }
    edit: inserting the word 'color' in case Americans do a search!
    Last edited by R Soul; 14th Apr 2024 at 10:07.

  2. #52
    ZylonBane
    Registered: Sep 2000
    Location: ZylonBane
    One of the annoying shortcomings of Dark's script API is that it doesn't expose access to the object query engines that native code can use. This makes it near-impossible for Squirrel to perform global operations on objects that haven't already been helpfully set up with names or links. Or so I thought...

    Turns out, you can get pretty darn close to arbitrary global object queries by using archetypes, which implement inheritance to their concretes as hidden metaproperty links, which scripts CAN access. I've written this function to demonstrate:

    Code:
    function GetConcretes(archetype, filter = null, arg = null) {
    	local obj, lnk;
    	local objList = [];
    	foreach (lnk in Link.GetAll("~MetaProp", archetype)) {
    		obj = LinkDest(lnk);
    		if (obj < 0) {
    			objList.extend(GetConcretes(obj, filter, arg));
    		}
    		else if (filter == null || (arg == null ? filter(obj) : filter(obj, arg))) {
    			objList.push(obj);
    		}
    	}
    	return objList;
    }
    Normally this would be embedded in a library class so all scripts could access it.

    So using this function, you could for example write this to get a list of every patrol point in the entire mission.
    Code:
    local trolList = lib.GetConcretes("TrolPt");
    Or if you want a list of every human guard, but only the living ones, you can pass in a filter function:
    Code:
    local gList = lib.GetConcretes("guard", filterGuards);
    
    function filterGuards(obj) {
    	return Property.Get(obj, "HitPoints") > 0;
    }
    Or using the more compact lambda syntax...
    Code:
    local gList = lib.GetConcretes("guard", @(obj) Property.Get(obj, "HitPoints") > 0);
    Note that "self" isn't preserved in functions called in other classes, so if the filter function needs it, or any other dynamic data, it can be passed in as an optional third argument.
    Last edited by ZylonBane; 16th Apr 2024 at 11:18.

Page 3 of 3 FirstFirst 123

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •