Skip to main content

Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
Tags

Disable drop

A topic by Artem Flo / aturbidflow / kubikámi created Feb 09, 2020 Views: 205 Replies: 17
Viewing posts 1 to 4
Submitted

I've trying to disable drop in some rooms. I've wrote this code:

: match "drop _"  {
    : print "Can't do here." ;
}

But it prints "Can't do here" for each object that trying to be dropped. How I can prevent duplicate messages from being displayed?

Submitted

Add :done; after the print statement, otherwise it falls through and does the normal processing.

Get into the habit of doing this everywhere. As soon as you've finished processing and there's nothing more to do, use :done; except after :redescribe;

Host

The done is not required here, I think the question is about stopping iterations inside a GET ALL or DROP ALL, currently there is no way to do this (other than disabling get all and drop all entirely via game_settings), but I'll bump it up the list now I've seen this issue in the wild.

Submitted

The question was how to disable drop in some rooms. If the code was implemented in a location handler (hence the absence of is_at) , it would say "You can't do that", then it would go ahead and do it anyway, hence the need for :done; to prevent the drop taking place.

I missed the implication behind the last paragraph, but the same reasoning applies. If you tried to DROP ALL, you would get multiple "You can't do that" messages, but the items would still be dropped, so you still need the :done; to prevent the items being dropped.

Host

You don't need a DONE to prevent the default drop handler from triggering.

Any non masked action that executes will prevent execution of the default handler, including a lowly print.

Host

How ALL statements work ...

When an ALL (or EVERYTHING) noun is detected, on certain verbs (default only works on GET, DROP, PUT, and REMOVE), then Adventuron uses the ALL as a replacement token, and finds all matching items that make sense (GET scans objects in the current room, DROP scans inventory, etc), then it submits multiple sentences to the engine GET ALL in a room with a ROPE and a LAMP and a TRACTOR, would only try to get the ROPE and the LAMP (as they are the only conveyable objects).

Adventuron would then executure two on_command {} loops, and two on_tick{} loops, one for each exploded sentence "GET ROPE" (round 1), and "GET LAMP" (round 2).

Each of those statements would have a default handler ready to run if there is nothing to override the GET statement in the on_command {} block.

Submitted

Not in my experience. Have you changed something? When I first started with Adventuron, I used to get surprised when I printed a message, then it fell through to the default handler and it printed something extra. As a result, I got into the habit of always using :done; to prevent this happening. (I think Gareth might have pointed this out.) I still rely on handling specific situations within my handler and letting it fall through to the default handler when none of those conditions are met.

Wait  minute. Are you saying that if you've done anything at all other than match or if...else tests, then it stops processing further handlers from that point on? That might make sense. I would have to test it.

Host (1 edit)

Yes .. to the question raised in your last paragraph. If you do anything "not masked", then it does not run the default handler. If conditions, match conditions and while conditions are naturally masked. Anything inside a : mask {} command are masked too. I think I documented this somewhere.

Ah, here it is:

https://adventuron.io/docs/tut/index3.html#MaskingCommands

Everything is an override by default. You only need to use : done; if you absolutely want to stop processing, but done is quite often not required to stop the system handler for a system command running. Doing a print of set_integer, or set_boolean, or any non passive command is enough to stop the system command handler dead in its tracks.

Submitted

Well, the only thing I've get from this thread that I have to wait for fix. Am I right?)

Host

This should work:

game_settings {
   // Switches off Adventuron's standard 'all' behaviour.
   enable_standard_all_behaviour = false
}
on_command {
      /// Your command handlers here !
      : match "drop _" {
         : if (is_at "my_location") {
            : print "NOT HERE!" ;
            : done ;
         }
      }
      // Make sure this is the last item in the on_command{} block
      : if (noun1_is "all") {
         : if (verb_is "get")    { : do_all target="current_location_objects";}
         : if (verb_is "drop")   { : do_all target="inventory_notworn";}
         : if (verb_is "wear")   { : do_all target="inventory_notworn";}
         : if (verb_is "remove") { : do_all target="inventory_worn";}
      }
}

... the standard all behaviour is to override everything then intercept get, drop, wear and remove commands per item. By moving the all handler to the bottom, then you can override all these commands before they are exploded by the standard all handlers.

Sorry if it's hard to understand, I'll work to make this very simple.

Submitted

No, it's very simple. Thank you, will give it a try.

Submitted

And here. Everything works as expected. Thanks.

Submitted (6 edits)

Surely this is a better way to do it, less complex....

Create a zone. With a list of your 'no drop' rooms.

zones {
    no_drop : zone {
        locations = [ main_chamber,under_chamber,strange_room ]
    }
}

Then under the On Command list....

: match "drop _;drop all"  {
      : if (no_drop) {
      : print "CAN'T DO THAT HERE!" ;
      : done ;
      }
   }

Would that not work? Seems simpler than the above stuff. I've not tested this btw. ;-)

This seems quite flexible too as you can add whatever locations you like to the list and you can add additional equations to the IF statement for things like if you're holding a particular item, then you are allowed to drop things. That kind of stuff. :-)

Submitted

On the surface, that looks like it will work. Probably a good idea, actually.

Host

Looks good, but the condition should be


: if (is_at "no_drop") {
}
Submitted

Nice one... I knew I'd do something wrong. LOL and that's why I should test stuff first before typing it in. hee hee. 

Submitted

Interesting. But the rule "don't touch if it works". But thanks anyway, knowledge for the future.

Submitted

Totally understand Artem. If ain't broke an all that. :) Still it got us thinking, and gave multiple solutions to the same thing. :)