Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
Tags

Restricting items on the ground

A topic by Pixelman created Sep 16, 2019 Views: 147 Replies: 14
Viewing posts 1 to 4
Submitted

so is it possible to make the game only accept 2 or 3 items in one room? Like if there is 2 items on the ground and max is 2, when player drops another item the first item goes back to players inventory

Host (1 edit)

There are two future upcoming features that will help here, the first is a function that counts the number of children of a node (a node is an entity or a location or the ether). The second is per-node attributes / stats. I may have already added the first experimentally, I need to check it. The second I kind of half added experimentally again, but the api is awful at the moment, and it's not been tested at all. I add a lot of things experimentally until I understand if they are hard to use or easy to use, before I document them and they become "supported".

There may be a brute force way of implementing this logic using dynamic booleans or dynamic ints. Maybe Gareth can think it through using the standard functions. He's very good at novel solutions using the basic functions.

Limiting the amount you can drop somewhere would be straightforward (just a case of custom get/drop with a counter) but what you're talking about would be an interesting challenge, especially if you wanted the behaviour where objects are returned to you in the order they're dropped.  [I'm not sure what the game world logic would be for this behaviour... perhaps knowing that might suggest an easier solution]

I guess if you gave each object a number you could store the appropriate number of the two items dropped in two integers, say drop1 and drop2. Then when the third object is dropped, you return the object numbered drop1 to the player, copy the value of drop2 over to drop1, and place the number of the new object into drop2.

How much code you'd need would depend on how many objects you had... it wouldn't be too bad for these short mini games.

It would be easier to do in an old 8-bit system like the PAWs or Quill, because all the objects are referred to by numbers there anyway, so you don't need code to assign a value to each one. 

Submitted (1 edit)

i wanted it for the riddle puzzle but if it gets a lot of time i think it would be easier to make a "give ITEM1 and ITEM2" command

Edit: "and" is reserved by system so im thinking about another solution. If there is something to get all things on the ground i have another way to solve this problem

(1 edit)

Ah, I can see why you might want that then. Because the easiest solution to that puzzle, at the moment, is just to DROP ALL on the ground and, providing you've got the item, then you've solved it.

There are a few ways around it, I think...

One would be to use a counter that counts how many objects you've dropped and stops you from dropping any more when the limit of 2 is reached. You'd need to pick up one of the objects (decresing the counter) to allow you to drop more. That would work fine, I think.

Another would be to use the GIVE object, to give each item you're trying in turn. Maybe this could be linked to the container system and a counter, again, to make sure you can only give him two. The "container" could be a "large wooden table" in front of the Riddle-man.

GIVE ROCK... "The man takes it off you and puts it on the table in front of him."

EXAMINE TABLE... "On the table is: A rock and a handle."

GET ROCK... "You get the rock." 

GIVE ROD... "The man takes it off you and puts it on the table in front of him."

"Yes, that's right," says the man.... etc.... etc.... 

Submitted (1 edit)

I agree with Gareth on this one. If you were able to do a generic check on objects in your inventory (which you can't), then you'd be able to override the drop routine just for this room with something like (in pseudo code):

if (object in inventory) then
   if (room counter < MAX) then
      increment room counter
      drop object
      print "You place the (object) on the table."
   else
      print "There's no room left on the table."
   endif
else
   print "You don't have that."
endif

Add decrement room counter when you get an object, but this requires a generic check on whether the object is in the room (which you can't do) prior to getting the object. It is some of these really basic limitations that make Adventuron hard to use.

This is the same puzzle where I'm currently stuck (I think I'm missing an object). In this case, I think it makes more sense to GIVE OBJECT, rather than DROP OBJECT. For each of the two required objects, you can check if it's in your inventory and, if it is, give it to the riddlemaker, check if he's got both objects and give an appropriate response. However, you still run into troubles handling the generic case because of Adventuron's inability to check whether the generic object is in your inventory.

Host

What's wrong with : if (parent_of "my_object" == current_location()) {}

Submitted

If you have 100 objects in your game, you have to check 100 objects. Unless you're saying "my_object" IS a generic object, i.e. the object referred to in your input.

Host

In Adventuron, there are already a sub-optimal of handling loops and scanning within a container (location, entity, etc).

The look_inside command, in addition to collections,  along with the while loop is a long winded way of achieving things.

As I alluded to, I suspect this would be technically work, but it's sub optimal.

A dedicated all-in-one scanning command was something I was going to work on after finishing attributes + stats.

I may move it forward if there is a demand.

The scanning construct will ultimately look a bit like this.

// Not yet working ... 
: scan (current_location()) {
  : if (is_carried(item()) { 
       // Do something here
   }
}
Submitted

What I'm hoping for is something like:

: match  "throw -" {
   : if (is_carried(noun1)) {
      : drop;
      : print {("You throw the " + original_noun1() + ", but it doesn't go very far.")}
   }
   : else {
      : print "You don't have that.";
   }
}

Being able to reference noun1 and noun2 are the things that are desperately missing. Perhaps these would be noun1() and noun2() in Adventuron syntax. noun1 or noun1() is probably similar to item() in your example.

Submitted

Incidentally, no need for loops with this approach.

Right, this is probably how I would do it. You have to manually add code for each object, but in a small game like yours that's not too much of an issue.

There are lots of tweaks you could add, such as custom drop/get messages. But this will work similar to how it currently functions in your game.

Please see...  http://8bitag.com/temp/riddle.html ...for a demo. Code is below... 


######################################
#  Adventuron                        #
######################################

start_at                 = riddle_room

######################################
#  Locations                         #
######################################

locations {

   riddle_room : location "You are in the riddle room. The Riddle Master is here.";
   
}

######################################
#  Connections                       #
######################################

connections {

   from, direction, to = [
      
   ]
   
}

######################################
#  Objects                           #
######################################

objects {

   rock : object "A small rock" start_at = "inventory";
   crystal : object "A crystal" start_at = "inventory";
   apple : object "An apple" start_at = "inventory";
   rod : object "A fishing rod" start_at = "inventory";
   blade : object "An axe blade" start_at ="inventory";
   
}
######################################
#  Booleans                          #
######################################

booleans {
   
   riddle_solved : boolean "false" ;
   objects_checked : boolean "false";
   
}
######################################
#  Integers                          #
######################################

integers {
   
   object_counter : integer "0" ;
      
}

//increment decrement

######################################
#  On Command                        #
######################################

on_command {
   
   : match "drop _;give _"  {
      : if (is_at "riddle_room" && riddle_solved == false) {
         : if (object_counter > 1) {
            : print "You can only present two objects to the Riddle Master.";
            : done;}
         : else {
            : gosub "riddle_drop_object";
            : done;}}}

      : match "get _"  {
      : if (is_at "riddle_room" && riddle_solved == false) {
         : gosub "riddle_get_object";
            : done;}}      
   }

######################################
#  On Tick                           #
######################################

on_tick {
   
   : if (is_at "riddle_room" && riddle_solved == false && object_counter == 2 && objects_checked == false) {
      : if (is_beside "rod" && is_beside "blade") {
         : print "\"Yes,\" says the Riddle Master, \"That's correct! Well done!\"";
         : set_true "riddle_solved";
         : done;}
      : else {
         : print "\"No,\" says the Riddle Master, \"Those objects are incorrect.";
         : set_true "objects_checked";
         : done;}}
}
   
   
######################################
#  Subroutines                       #
######################################

subroutines {
   
   riddle_drop_object : subroutine {
   
      : match "_ rock" {
         : if (is_carried "rock") {
            : drop;
            : increment "object_counter";
            : done;}}
      : match "_ crystal" {
         : if (is_carried "crystal") {
            : drop;
            : increment "object_counter";
            : done;}}
      : match "_ apple" {
         : if (is_carried "apple") {
            : drop;
            : increment "object_counter";
            : done;}}
      : match "_ rod" {
         : if (is_carried "rod") {
            : drop;
            : increment "object_counter";
            : done;}}
      : match "_ blade" {
         : if (is_carried "blade") {
            : drop;
            : increment "object_counter";
            : done;}}
            
      : print "You are not carrying that.";
   }
   
   riddle_get_object : subroutine {
   
      : match "_ rock" {
         : if (is_beside "rock") {
            : get;
            : decrement "object_counter";
            : set_false "objects_checked";
            : done;}}
      : match "_ crystal" {
         : if (is_beside "crystal") {
            : get;
            : decrement "object_counter";
            : set_false "objects_checked";
            : done;}}
      : match "_ apple" {
         : if (is_beside "apple") {
            : get;
            : decrement "object_counter";
            : set_false "objects_checked";
            : done;}}
      : match "_ rod" {
         : if (is_beside "rod") {
            : get;
            : decrement "object_counter";
            : set_false "objects_checked";
            : done;}}
      : match "_ blade" {
         : if (is_beside "blade") {
            : get;
            : decrement "object_counter";
            : set_false "objects_checked";
            : done;}}
            
      : print "You've not presented that to the Riddle Master.";
   }
   
}

Submitted

wow thanks a lot. I wasn't expecting that someone would write a whole code for me

Well, that's just how I would probably do it. I'm not a coder, so I'm sure there are better ways.

Host

Wow.

Very impressive Gareth.