Water Supply

OurJud
NB - Many thanks to all who helped me tidy up my code, especially Pertex, whose revised scripts you see here.

These scripts don't deal with a gradually diminishing supply (I ain't clever enough for that), but they do handle a number of factors.

It uses two objects ('full bottle of water' and 'empty bottle of water'), one flag ('water' - on rooms with water source), an 'offstage' room, and two custom commands (added to 'game' to make them global); 'drink water' and 'fill bottle' (feel free to add variations)

Script features (in no particular order):

[list]
Checks to see if player is carrying water bottle
Swaps between 'full bottle of water' and 'empty bottle of water' in inventory

COMMAND - DRINK:
If there IS a source of water in a given location, the command of 'drink' will not take the water from the bottle. It will take it from the source.
If there is NO water source and the bottle is FULL, the command of 'drink' will replace the 'full bottle of water in your inventory with 'empty bottle of water'
If player is NOT carrying bottle and there's NO water source, return response "There's no water here."
If player is carrying EMPTY bottle and there's NO water source, return response "Your bottle is empty."

COMMAND - FILL:
If player is carrying EMPTY bottle and there IS a water source, the command 'fill bottle' will replace 'empty bottle of water' with 'full bottle of water' in your inventory.
If player is carrying FULL bottle and there IS a water source, the command 'fill bottle' will get the response "The bottle is already full."[/list:u]

Remember, a flag (''water' in the case of this script) must be set on the 'player', on any location with a water source.
Also remember to unset the 'water' flag on any exits from the room with a water source.


COMMAND SCRIPT ('drink water; drink; etc etc etc)

if (GetBoolean(player, "water")) {
msg ("You drink the water.")
} else if (Got(empty water bottle)) {
msg ("Your bottle is empty.")
} else if (Got(full water bottle)) {
msg ("You drink the water.")
MoveObject (full water bottle, offstage)
MoveObject (empty water bottle, player)
} else {
msg("There's no water here")
}

COMMAND SCRIPTS ('fill bottle; gather water; collect water etc etc etc)

  if (not GetBoolean(player, "water")) {
msg ("There's no water here.")
}
else if (not Got(empty water bottle)) {
msg ("You don't have a bottle.")
}
else if (Got(full water bottle)) {
msg ("It's already full.")
}
else {
msg ("You fill the bottle.")
MoveObject (empty water bottle, offstage)
MoveObject (full water bottle, player)
}

Pertex
Wouldn't it possible to shorten your scripts e.g the drink script like this:

if (GetBoolean(player, "water")) {
msg ("You drink the water.")
} else if (Got(empty water bottle)) {
msg ("Your bottle is empty.")
} else if (Got(full water bottle)) {
msg ("You drink the water.")
MoveObject (full water bottle, offstage)
MoveObject (empty water bottle, player)
}

OurJud
Possibly, Pertex, but would that shortened version cover all the permutations?

Let me see if I can run through all the possibilities required for 'drink':

FULL water bottle AND water source = grants drink, but doesn't take it from the bottle.
FULL water bottle and NO water source = grants drink (from the bottle) AND replaces full bottle in inventory with empty bottle.
EMPTY water bottle AND water source = grants drink (from source) but keeps bottle empty (unless players 'fills bottle')
EMPTY water bottle and NO source - denies drink.

If the shortened version covers all this, then great, but if I'm understanding it properly, your code wouldn't allow the player to drink from the source if their bottle was empty.

Tell you what, I'll whack it in and see.

Seems to work, Pertex, but for one thing. If the player drops the bottle outside of a water source, 'drink' should return 'There's no water here', but with your script it returns a null.

OurJud
Can't get my head around this, which isn't helped because I don't know the difference between 'ifs', 'else ifs' and 'else' !!!

If the player types "fill bottle" in succession, I want the response, "It's already full." But when I test it, I get:
"It's already full.
You don't have the bottle."

This is the script:

if (Got(full water bottle)) {
if (GetBoolean(player, "water")) {
msg ("It's already full.")
}
}
if (Got(empty water bottle)) {
if (GetBoolean(player, "water")) {
msg ("You fill the bottle.")
MoveObject (empty water bottle, offstage)
MoveObject (full water bottle, player)
}
}
if (Got(empty water bottle)) {
if (not GetBoolean(player, "water")) {
msg ("There's no water here.")
}
}
else if (Got(empty water bottle)) {
if (not GetBoolean(player, "water")) {
msg ("There is no water here.")
}
}
else if (Got(full water bottle)) {
if (not GetBoolean(player, "water")) {
msg ("It's already full.")
}
}
else if (not Got(empty water bottle)) {
if (not GetBoolean(player, "water")) {
msg ("You don't have a bottle.")
}
}
else if (not Got(full water bottle)) {
if (not GetBoolean(player, "water")) {
msg ("You don't have a bottle.")
}
}
else if (not Got(empty water bottle)) {
if (GetBoolean(player, "water")) {
msg ("You don't have a bottle.")
}
}
else if (not Got(full water bottle)) {
if (GetBoolean(player, "water")) {
msg ("You don't have a bottle.")
}
}

Anonynn
I dealt with it like this...

create two objects:

clean_water
dirty_water.

then drink verbs:

Clean Drink
msg ("<br/>The cool water glides downs your throat; not only refreshing you but it also makes you feel better. <br/>")
player.health = player.health + 3
RemoveObject (fresh_water)


Dirty Drink
if (RandomChance(50)) {
msg ("<br/>The warm, dirty water glides downs your throat making you gag a little; it's not very refreshing you but it did manage to quench some of your thirst. <br/>")
player.health = player.health + 5
RemoveObject (dirty_water)
}
else {
player.health = player.health - 5
msg ("<br/>After drinking the dirty water, you suddenly feel sick to your stomach. Moments later, your stomach turns which causes you to vomit! Ugh!! You feel worse now...<br/>")
RemoveObject (dirty_water)
}


And then in situations where there is like a lake or a source of water, you can clone either of the objects so they have a large resource to utilize.

and then containers that can hold water, and containers that cannot hold water.

Hold Water (and other objects) make NO special parameters. Anything with a certain volume can be put inside the bottle.
small_bottle
medium_bottle
etc.

And NOT Hold Water (only regular objects) make special parameters. Anything can be placed inside this container, except water or watery substances.
Example:
small_sack

After Opening Object:
if (Contains (small_sack,fresh_water)) {
msg ("<br/>You cannot store liquids in this small sack! <br/>")
RemoveObject (fresh_water)
}
else if (Contains (small_sack,dirty_water)) {
msg ("<br/>You cannot store liquids in this small sack! <br/>")
RemoveObject (dirty_water)
}


After Closing Object:
if (Contains (small_sack,fresh_water)) {
msg ("<br/>You cannot store liquids in this small sack! <br/>")
RemoveObject (fresh_water)
}
else if (Contains (small_sack,dirty_water)) {
msg ("<br/>You cannot store liquids in this small sack! <br/>")
RemoveObject (dirty_water)
}


And as you create more water objects, you can just add them to each of the objects. Or create "Types" if you want to make it easier. Water-Type Container, Dry Container.

If the player DOES NOT have any of these containers...you make one for fresh and dirty water under the "Take" You just have to put in any objects that CAN hold water and update it as you go.
Take
Run script
Fresh Water
MoveObject (fresh_water, waterskin)
if (Contains (waterskin,fresh_water)) {
msg ("It is already full. ")
}
else if (not waterskin.isopen) {
msg ("You must open the waterskin first!")
}
else if (not Got(waterskin)) {
msg ("You cannot hold onto this. ")
msg ("You drop it. ")
RemoveObject (fresh_water)
}
else if (Contains (waterskin,dirty_water)) {
msg ("It is already full. ")
}
MoveObject (fresh_water, small_bottle)
if (Contains (small_bottle,fresh_water)) {
msg ("It is already full. ")
}
else if (not Got(small_bottle)) {
msg ("You cannot hold onto this. ")
msg ("You drop it. ")
RemoveObject (fresh_water)
}
else if (Contains (small_bottle,dirty_water)) {
msg ("It is already full. ")
}
MoveObject (fresh_water, medium_bottle)
if (Contains (medium_bottle,fresh_water)) {
msg ("It is already full. ")
}
else if (not Got(medium_bottle)) {
msg ("You cannot hold onto this. ")
msg ("You drop it. ")
RemoveObject (fresh_water)
}
else if (Contains (medium_bottle,dirty_water)) {
msg ("It is already full. ")
}
MoveObject (fresh_water, large_bottle)
if (Contains (large_bottle,fresh_water)) {
msg ("It is already full. ")
}
else if (not Got(large_bottle)) {
msg ("You cannot hold onto this. ")
msg ("You drop it. ")
RemoveObject (fresh_water)
}
else if (Contains (large_bottle,dirty_water)) {
msg ("It is already full. ")
}


Dirty Water
Take
Run Script
MoveObject (dirty_water, waterskin)
if (Contains (waterskin,fresh_water)) {
msg ("It is already full. ")
}
else if (not waterskin.isopen) {
msg ("You must open the waterskin first!")
}
else if (not Got(waterskin)) {
msg ("You cannot hold onto this. ")
msg ("You drop it. ")
RemoveObject (dirty_water)
}
else if (Contains (waterskin,fresh_water)) {
msg ("It is already full. ")
}
MoveObject (dirty_water, small_bottle)
if (Contains (small_bottle,dirty_water)) {
msg ("It is already full. ")
}
else if (not Got(small_bottle)) {
msg ("You cannot hold onto this. ")
msg ("You drop it. ")
RemoveObject (dirty_water)
}
else if (Contains (small_bottle,fresh_water)) {
msg ("It is already full. ")
}
MoveObject (dirty_water, medium_bottle)
if (Contains (medium_bottle,fresh_water)) {
msg ("It is already full. ")
}
else if (not Got(medium_bottle)) {
msg ("You cannot hold onto this. ")
msg ("You drop it. ")
RemoveObject (dirty_water)
}
else if (Contains (medium_bottle,fresh_water)) {
msg ("It is already full. ")
}
MoveObject (dirty_water, large_bottle)
if (Contains (large_bottle,dirty_water)) {
msg ("It is already full. ")
}
else if (not Got(large_bottle)) {
msg ("You cannot hold onto this. ")
msg ("You drop it. ")
RemoveObject (dirty_water)
}
else if (Contains (large_bottle,fresh_water)) {
msg ("It is already full. ")
}


Hope that helps!


------------------------------

If-Scripts

How I understand it is ...

If (this scenario) = blah blah
then (do this)

else if (this scenario) = blah blah
then (do this)

else (this scenario ((meaning none of the other scenarios have happened))) = blah blah
then (do this)

Does that clarify that?

Pertex
OurJud wrote:
Seems to work, Pertex, but for one thing. If the player drops the bottle outside of a water source, 'drink' should return 'There's no water here', but with your script it returns a null.


THen this should work:

if (GetBoolean(player, "water")) {
msg ("You drink the water.")
} else if (Got(empty water bottle)) {
msg ("Your bottle is empty.")
} else if (Got(full water bottle)) {
msg ("You drink the water.")
MoveObject (full water bottle, offstage)
MoveObject (empty water bottle, player)
} else {
msg("There's no water here")
}


And the fill-script should look like this

if (not GetBoolean(player, "water")) {
msg ("There's no water here.")
}
else if (not Got(empty water bottle)) {
msg ("You don't have a bottle.")
}
else if (Got(full water bottle)) {
msg ("It's already full.")
}
else {
msg ("You fill the bottle.")
MoveObject (empty water bottle, offstage)
MoveObject (full water bottle, player)
}

OurJud
Neonayon wrote:
Hope that helps!


------------------------------

If-Scripts

How I understand it is ...

If (this scenario) = blah blah
then (do this)

else if (this scenario) = blah blah
then (do this)

else (this scenario ((meaning none of the other scenarios have happened))) = blah blah
then (do this)

Does that clarify that?

Thanks, Neonayon. I think what your script does and how I want my water supply to work are a little bit too different to cross over in any way.

As for if-Scripts, what you say kind of make sense, but when I should use which is still a bit of a mystery. When I was trying to get my scripts to work and avoid double response outputs etc, I was just blindly tossing 'ifs' and 'else ifs' all over the place until it did what I wanted it to do.

Pertex wrote:

"OurJud"


Seems to work, Pertex, but for one thing. If the player drops the bottle outside of a water source, 'drink' should return 'There's no water here', but with your script it returns a null.



THen this should work:


Thanks, Pertex. Mine still isn't perfect, so next time I'm working on it, I'll throw these two scripts in place and see how well they work.

It really annoys me that I can't see a simple and logical way to do this, like you so obviously have. Your scripts are a fraction the length of mine, and three times as economical.

Forgewright
I saw a post earlier referring to the water container needing an diminishing integer to calculate the the amount of water in it. Your refill scripts only account for empty or full containers. If the container's integer is less than it's max integer shouldn't it be set to max again at a given "fill" command?

HegemonKhan
@ Ourjud (and others):

here's a guide~explanation thread that I've started for you and others struggling with the IF block:

viewtopic.php?f=18&t=5705

(I'll have it finished up definately after finals: ~ 3 weeks from now)

Anonynn

As for if-Scripts, what you say kind of make sense, but when I should use which is still a bit of a mystery. When I was trying to get my scripts to work and avoid double response outputs etc, I was just blindly tossing 'ifs' and 'else ifs' all over the place until it did what I wanted it to do.



Another thing that helps me with the "IF" scripts is...

The first IF is your primary scenario.
If (list of different possible scenarios: we'll go with "if player is carrying" for the example)

If (player is carrying blah blah object)
then
do blah blah

the "else if's" are basically for secondary things that could happen if the player isn't carrying that object, or it can be the "else". For example...

If (player is carrying blah blah object) <----- your main scenario
then
do blah blah.

else ((player is not carrying blah blah object)) <---- "else" acts as a default to your main scenario not happening.
do blah blah.

Now let's say you have a secondary scenario that could happen. Let's do "random chance" now.

If (random chance 25%) <------ main scenario (best scenario let's say)
then
addtoinventory golden coin

else if (random chance 25%) <---- secondary scenario (so-so scenario)
then
addtoinventory silver coin.

else (if neither of those fire) <----- default scenario (the other two didn't fire! Oh noes!)
then
addtoinventory bronze coin


So see --- you don't even NEED to use "else", and you can use "else if" for the same thing as "else" if you really want. The "else" script just allows you to "close out" events with something being said, where "else if's" allow you to keep adding events that could happen other than your main scenario. Like variations. Basically, if you don't use "else" --- this will happen....


If (random chance 25%) <------ main scenario (best scenario let's say)
then
addtoinventory golden coin
msg ("You can now move on!")

else if (random chance 25%) <---- secondary scenario (so-so scenario)
then
addtoinventory silver coin.
msg ("You can now move on!")

else (let's say neither of the above two fire. So when this event happens, the player will receive no information. So you could just go...)
--------------------------------------------



If (random chance 25%) <------ main scenario (best scenario let's say)
then
addtoinventory golden coin

else if (random chance 25%) <---- secondary scenario (so-so scenario)
then
addtoinventory silver coin.

else (if neither of those fire) <----- default scenario (the other two didn't fire! Oh noes!)
then
msg ("Oh! Sorry about your luck! You didn't get either coin")

Now when the other two scenarios don't fire, the "else" script will give this information to the player...
"Oh! Sorry about your luck! You didn't get either coin"

Does that help?

OurJud
Forgewright wrote:I saw a post earlier referring to the water container needing an diminishing integer to calculate the the amount of water in it. Your refill scripts only account for empty or full containers. If the container's integer is less than it's max integer shouldn't it be set to max again at a given "fill" command?

That was the original plan, Forgewright, but I scrapped the idea when TP started talking about integers. I don't even know what the word means, let alone how to script them. If I'd used a diminishing supply, I would also have wanted it to be reflected in the inventory, rather than by some floating value on the screen. This would have meant creating at least four water bottle objects; empty, 1/4 full, 1/2 full, 3/4 full, and full. I was thrashing around in the dark as it was, so further complications like that had to be scrapped.

Neonayon wrote:

As for if-Scripts, what you say kind of make sense, but when I should use which is still a bit of a mystery. When I was trying to get my scripts to work and avoid double response outputs etc, I was just blindly tossing 'ifs' and 'else ifs' all over the place until it did what I wanted it to do.



Another thing that helps me with the "IF" scripts is...


That's slightly clearer, Neon. Thanks.

I think I'd still get a bit confused if I was trying to offer multiple outcomes to an action or situation. Take my script for the water supply, for instance. I've got it working pretty much how I want using my messed-up scripts, but there are still certain scenarios where the game spits out two responses (either two identical responses or two conflicting ones). They don't get flagged as errors, but it's still not right.

If I try and fill the bottle in rapid succession, I should get "It's already full." Instead I get "It's already full." AND "You don't have a bottle."

I can see what's happening in the script, but not how to avoid it. It's something to do with the line that swaps the empty bottle in my inventory with the full one. It sees that and says "It's already full." BUT then it finds another 'if' condition which tells it to output a "You don't have a bottle" too.

Another one is if I "drop" the bottle outside a room with the 'water' source flag, and then type "fill bottle". I should get "You don't have a bottle." but instead I get a null return (blank).

The Pixie
A useful approach with "if" scripts is to check each of the conditions when the command would fail, and if you get to the end, then you actually do the command (though sometimes you cannot do it this). For your FILL command, you want it to fail if (1) there is no water source present; (2) the container is full; and (3) the player has no container.

Then you set up a series of if/else if/else like this.
// Check water source in the current room (player.parent)
if (not GetBoolean(player.parent, "watersource")) {
msg("There is no water source here")
}
// Check container is not full
else if (full water bottle.parent = player) {
msg("You water bottle is full already")
}
// Check player has the empty container
else if (empty water bottle.parent = player) {
msg("You have no water bottle")
}
// Everything is okay, so fill the bottle
else {
msg("You fill your water bottle")
MoveObject (empty water bottle, offstage)
MoveObject (full water bottle, player)
}

OurJud
Pertex wrote:THen this should work:

Those two scripts work perfectly, Pertex. I'll update the original post and credit you. Thanks.

TP, thanks. I've no doubt your script is just as effective, but I'm wrapping this up while I'm ahead.

HegemonKhan
I don't know if this will help ya OurJud, but I'm giving it a try, lol

you got two conditionals: 'water' and 'canteen'

this means you got 4 factors:

1. have water
2. don't have water
3. have canteen
4. don't have canteen

so, you got 4 combinations:

if (have water and have canteen)
else if (have water and don't have canteen)
else if (don't have water and have canteen)
else if (don't have water and don't have canteen)

this can then be simplified (which is what Pertex did) due to order of operations: top to bottom, and made more code efficient:

if (have water and have canteen)
else if (have water)
else if (have canteen)
else // (you have neither water nor canteen)

----------

err... just realized your scenario is a bit different, but this is still the same base design as your scenerio, I think...

Pertex
HK: not completely true. It depends on what should happen in the script block of the if.If you have the same commands when water is true and canteen is false you need other if clauses

OurJud
Pertex wrote:HK: not completely true. It depends on what should happen in the script block of the if.If you have the same commands when water is true and canteen is false you need other if clauses

Indeed. The script as it stands does exactly what I need it to, and handles several possibilities:

NEGATIVES:
1. No water source AND no bottle (no drink given)
2. No water source and EMPTY bottle (no drink given)
POSITIVES:
3. Water source AND no bottle (drink given from source)
4. Water source AND full bottle (drink given from source)
5. Water source and EMPTY bottle (drink given from source, bottle can be filled - replace empty bottle with full bottle in inventory)
6. No water source BUT full bottle (drink given from bottle - replace full bottle with empty bottle in inventory)

HegemonKhan
ya, not quite the same, but the good news is, is that you seem to understand it quite well, hehe. That was the intent of my lazy (as I didn't check exactly what your scenerio was, mssing that it involved 'full vs empty' and not 'have canteen vs don't have canteen', lol) post, in trying to help you understand what was happening in Pertex' code, in case you didn't, but you definately understand it already.

OurJud
HegemonKhan wrote:ya, not quite the same, but the good news is, is that you seem to understand it quite well, hehe.

I wouldn't say that, HK.

I understand what I wanted the script to do... and I did get there in my own unique way, but it needed better coders like yourself and others to get it down to the tidy little block I have now.

This topic is now closed. Topics are closed after 60 days of inactivity.

Support

Forums