Results 1 to 17 of 17

Thread: How To Use Scripting Zones?

  1. #1

    How To Use Scripting Zones?

    When I add a scripting zone I see that it does not have any option to add a script to it. As such I assume that the intention is to use scripting zones with the onObjectEnterScriptingZone and onObjectLeavingScriptingZone events. However, as far as I know, there is no function to cause the player to drop the current object and thus any onObjectEnterScriptingZone or onObjectLeavingScriptingZone scripts can't manipulate (position or rotation) the object being carried into or out of the zone.

    Consider a game like UNO or Crazy Eights. Lets say we want to create a play area (scripting zone) where players can play their cards and the script would evaluate if the play is legal and return the card if not.

    If I trigger the script on onObjectEnterScriptingZone and then discover that the card being played is invalid then I cannot, as far as I can tell, return it because the user still has a hold of it.

    As far as I can see, the work around would be to run a script on onObjectEnterScriptingZone which sets a global saying that the object is in the scripting zone. Then run a second script on onObjectLeavingScriptingZone and reset the global to indicate that the object is not in the scripting zone. Lastly create a third script that triggers on onObjectDropped which would perform the evaluation only if the global is set. This way, the evaluation gets performed after the object has been dropped and thus it could get returned if necessary.

    Am I on the right track or is there a simpler way to do this that I am missing?

    EDIT:

    It occurs to me that if this is the case then it might be easier to use a simple onObjectDropped event and then just check the position against the bounds of the "scripting area" without actually using a scripting area.
    Last edited by LordAshes; 07-19-2016 at 07:11 PM. Reason: Added alternative solution

  2. #2
    Join Date
    Mar 2016
    Posts
    182
    What I (and I think many?) use them for is to get the objects in the zone and then spin through that array of objects and do things with some/all of them. Because you can spawn (and destroy) them, you can create them where you want on the fly, and then get the objects inside.

    You might check my mod for Raptor and see if the way I handle the card playing/evaluation there is useful to you.

  3. #3
    Quote Originally Posted by dig65 View Post
    What I (and I think many?) use them for is to get the objects in the zone and then spin through that array of objects and do things with some/all of them.
    So you get the GUID of the zone and then getObjects() like a container with the advantage that all of the objects inside the zone are actually instanced (as opposed to a real container where they are no). Correct?

    Quote Originally Posted by dig65 View Post
    You might check my mod for Raptor and see if the way I handle the card playing/evaluation there is useful to you.
    I re-read the API events and discovered the onObjectDropped() as opposed to onDropped(). This makes the play area much easier to implement since it is one global event as opposed to an function on each object. I trap the onObjectPickedUp to store the object original position and then in the onObjectDropped event I do my evaluation and potentially use the original object position to send it back. No scripting zone at all. Just wrote myself a little isInside() function and text against some board points. Works like a charm.

  4. #4
    I use scripting zones just as you originally described, but I edit the savegame.JSON file to keep them short (y = 0.5) so that the onObjectEnterScriptingZone only fires when a card is dropped in the bounding area, not just dragged through it. Anything else seemed overly complicated.

  5. #5
    Quote Originally Posted by dizneyguy View Post
    I use scripting zones just as you originally described, but I edit the savegame.JSON file to keep them short (y = 0.5) so that the onObjectEnterScriptingZone only fires when a card is dropped in the bounding area, not just dragged through it. Anything else seemed overly complicated.
    Interesting. But what is the real advantage, in that case, over a single onObjectDropped() event in the Global space and then a check to see if the dropped item was in the desired area (instead of using a scripting area). The only advantage that I see is that if you use a scripting area, the GM can see it when modifying the game whereas script coded coordinates of the area are not visible. However, if your solution requires modifying the scripting area anyway then you, somewhat, lose the benefit because you still can't fully set the areas from the GUI.

    Please don't get me wrong, I appreciate your information...I am just trying to realize the benefits (of scripting areas) over other implementations (such as my current one).

  6. #6
    Quote Originally Posted by LordAshes View Post
    Interesting. But what is the real advantage, in that case, over a single onObjectDropped() event in the Global space and then a check to see if the dropped item was in the desired area (instead of using a scripting area). The only advantage that I see is that if you use a scripting area, the GM can see it when modifying the game whereas script coded coordinates of the area are not visible. However, if your solution requires modifying the scripting area anyway then you, somewhat, lose the benefit because you still can't fully set the areas from the GUI.
    I usually have at least a dozen script zones on the table. My last mod (684408391) had 63. I name them so that I know which zone had something dropped into it within 3 lines of entering the onObjectEnterScriptingZone function. I've also put GUIDs of associated objects as part of the name to make my coding life easier.

    Agreed, the kind of manipulation I want of a scripting zone can only be done by editing the savegame json file.

  7. #7
    My issue with the onObjectEnterScriptingZone event is that the object is not necessarily dropped at that point. You suggested to set the y component to a small value (which requires a save game edit) but I wonder if that would work if the user lowered his object raise height. For example, if a user lowered his object raise height to 0 (or whatever the minimum is), isn't it possible that they could drag a object through the scripting zone (and thus have the event fire) even though they were still holding on to the object?

  8. #8
    Join Date
    May 2016
    Posts
    1,072
    You could have a table called objectsInZone. Any time an object enters the zone, its entity (the object itself) and its GUID both are added to objectsInZone. table.insert(objectsInZone, {object = objectEntity, GUID = '43253'}. When an object leaves a scripting zone, run a for loop on objectsInZone and, if the GUID matches an entry, use table.remove(objectsInZone, i) to remove it.

    Then, any time that onObjectDropped is triggered, have it run a for loop checking if the dropped object is in objectsInZone. If so, then have it activate whatever code on an object dropped on that zone.

    Come to think of it, you wouldn't even need the GUID. I am not testing this code, but here is the basic idea

    Code:
    objectsInZoneYouWant = {}
    
    function onObjectEnterScriptingZone(zone, enter_object)
        if zone == zoneYouWant then
            table.insert(objectsInZoneYouWant, enter_object)
        end
    end
    
    function onObjectLeaveScriptingZone(zone, leave_object)
        if zone == zoneYouWant then
            for i, v in pairs(objectsInZoneYouWant) do
                if v == leave_object then
                    table.remove(objectsInZoneYouWant, i)
                end
            end
        end
    end
    
    function onObjectDropped(player_color, dropped_object)
        for i, v in pairs(objectsInZoneYouWant) do
            if v == dropped_object then
                --Insert code you want to have happen if an object is dropped inside of your zone
            end
        end
    end

  9. #9
    Quote Originally Posted by LordAshes View Post
    My issue with the onObjectEnterScriptingZone event is that the object is not necessarily dropped at that point. You suggested to set the y component to a small value (which requires a save game edit) but I wonder if that would work if the user lowered his object raise height. For example, if a user lowered his object raise height to 0 (or whatever the minimum is), isn't it possible that they could drag a object through the scripting zone (and thus have the event fire) even though they were still holding on to the object?
    Yep - you are absolutely right. If people screw with the lift height, they will cause havoc in the game.

  10. #10
    You can use Object.held_by_color to check if someone is still holding it (== nil when dropped). To catch the cards that entered the zone in a player hand and were dropped then you can use the onObjectDropped event and Zone.getObjects() to check if the object was dropped in the zone.

  11. #11
    Could I add a fairly basic question to the end of this thread - how would I return the GUID of a spawned scripting zone? I think I've said somewhere else that my enthusiasm far outstrips my knowledge so I apologise to and thank anyone kind enough to indulge me in advance.

  12. #12
    I've pasted in *some* of my code verbatim, not all variables are defined etc...

    Code:
    function spawnScriptingZone()
        local params = {}
        params.position = {0,1.2,0}
        params.rotation = {0.1,180,0.1}
        params.callback = "cbSpawnUnlock"  -- all the callback does is set gSpawnLock to false
        params.callback_owner = Global
        params.type = "ScriptingTrigger"
        params.position = {xPos,1.2,zPos}
        gSpawnLock = true
        local zoneObj = spawnObject(params)
        while gSpawnLock do
            coroutine.yield(0)
        end
        zoneObj.setName("MyZone")
        zoneObj.setScale({6.2, 0.5, 6.2})
        local zoneGUID = zoneObj.getGUID()     -- added this to get the GUID value
        return(zoneGUID)
    end
    The code that calls the spawning function just needs to look for the returned GUID
    Code:
        local scriptZoneGUID = spawnScriptingZone()

  13. #13
    From what I heard: if you right click on a scripting zone, the GUID is automatically copied to the clipboard. I have not tested this...I just saw someone mention it in another post.

  14. #14
    Quote Originally Posted by Huffel View Post
    You can use Object.held_by_color to check if someone is still holding it (== nil when dropped). To catch the cards that entered the zone in a player hand and were dropped then you can use the onObjectDropped event and Zone.getObjects() to check if the object was dropped in the zone.
    The onObjectDropped is what I am using now. But in that case you don't really need the scripting zone. You can check the dropped object's position against either hard coded positions or positions based on other objects (which is where the scripting zone can come in again). I wrote myself a very simple isInside() function which simplifies this for me. So when the object is dropped I first check what type it is and then run it against a bunch of isInside() check to see where it was dropped.

    As I suggested in another post, having a onDroppedInto() function which would provide both the dropped object and the object on which it was dropped would simplify this process.

  15. #15
    I meant it like this:
    a) normal case: You have a low scripting zone that catches 99% of the objects that are put into it (because the player releases them above the zone) -> you just use the onEnter function to handle any new objects.
    b) A player has a super low lift height or moves an object into the zone while pressing right mouse (object is directly on the table): You can ignore the onEnter event while the object still has Object.held_by_color set. Instead write the objects that enter while being held into a table and use onObjectDropped to see if one of these objects was just dropped and if it is inside the scripting zone. That way you script would only react to the new object when it is released inside the zone.

    I hope it is clearer what I meant now and I hope I understood your requirement correctly

  16. #16
    I'm in favor of solving the short scripting zone and lift height issue with a Notebook entry that in effect says,

    "Don't screw with the lift height. There's no reason to, and if you do the scripting will not work correctly. So don't."

  17. #17
    +1 for Keyboard events

    One thing that doesn't seem to work / hasn't been implemented yet is onCollision* events on card objects? I'm guessing these aren't 'proper' objects in that sense but without that I can't tell when a card is touching another card

Tags for this Thread

Posting Permissions

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