[SOLVED]Looping a day + use of Boolean att.

XanMag
11 Jan 2016, 19:29
I realize you are all probably annoyed with me right now, but trust me, I'm trying to figure this out and I can't!

I want to loop a day. I have morning, noon, afternoon, dusk, evening, midnight, and dawn - each taking fifteen turns a piece.

I want to be able to loop back from dawn to morning and repeat the cycle.

I'm guessing it is somewhere in the "For" each script and loop variable?

Thanks.

HegemonKhan
11 Jan 2016, 20:20
since you mention them being based upon 15 turns each, here's just one way (out of many) of doing it:

<turnscript name="global_turnscript">
<enabled />
<script>
hour_string_function
// mass code of everything you else you want to do in your turn goes here
game.turns = game.turns + 1
</script>
</turnscript>

<function name="hour_string_function">
if (game.turns <= 0 or game.turns > 105) {
game.turns = 1
}
if (game.turns > 0 and game.turns <= 15) {
game.hour_string = "morning"
} else if (game.turns > 15 and game.turns <= 30) {
game.hour_string = "noon"
} else if (game.turns > 30 and game.turns <= 45) {
game.hour_string = "afternoon"
} else if (game.turns > 45 and game.turns <= 60) {
game.hour_string = "dusk"
} else if (game.turns > 60 and game.turns <= 75) {
game.hour_string = "evening"
} else if (game.turns > 75 and game.turns <= 90) {
game.hour_string = "midnight"
} else if (game.turns > 90 and game.turns <= 105) {
game.hour_string = "dawn"
}
</function>

<game name="xxx">
<attr name="turns" type="int">1</attr>
<attr name="hour_string" type="string">morning</attr>
<statusattributes type="simplestringdictionary">turns = Turn: !; hour_string = Hour String: !</statusattributes>
</game>

jaynabonne
11 Jan 2016, 20:27
Here is a way to do it (game is attached as well). Only the pertinent bits are shown:

  <game name="daytest">
<timesOfDay type="stringlist">
<value>morning</value>
<value>noon</value>
<value>afternoon</value>
<value>dusk</value>
<value>evening</value>
<value>midnight</value>
<value>dawn</value>
</timesOfDay>
<timeOfDayCounter type="int">0</timeOfDayCounter>
</game>

<turnscript name="time of day">
<enabled />
<script>
timesCount = ListCount(game.timesOfDay)

msg("It is " + StringListItem(game.timesOfDay, (game.timeOfDayCounter/15) % timesCount) + ".")

game.timeOfDayCounter = game.timeOfDayCounter + 1
</script>
</turnscript>


Dividing the counter by 15 (or however many steps you want) gives you the index, since it truncates. 0-14 -> 0, 15-29 -> 1, etc. You need to do the "%" (mod) to keep the index from running off the end of the list. It makes the index wrap back to zero when it goes off the end.

jaynabonne
11 Jan 2016, 20:32
HK, in case it helps, you can simplify your code slightly (and I'll ignore the other simplification of keeping it zero-based instead of one-based):


if (game.turns <= 15) {
game.hour_string = "morning"
} else if (game.turns <= 30) {
game.hour_string = "noon"
} else if (game.turns <= 45) {
game.hour_string = "afternoon"
} else if (game.turns <= 60) {
game.hour_string = "dusk"
} else if (game.turns <= 75) {
game.hour_string = "evening"
} else if (game.turns <= 90) {
game.hour_string = "midnight"
} else {
game.hour_string = "dawn"
}

You know game.turns will always be greater than 0. So you don't need to check for it. Similarly, once you've established in the first "if" that it's not <= 15, there is no need to check for greater than 15 in the next "if". And so on. And the last else doesn't even need an "if". You're already keeping the game turns within bounds. All it can be at that point is "dusk".

XanMag
11 Jan 2016, 21:01
Okay. So I got impatient. What I did was below and you can tell me if there's an easy fix or if I should scrap it and start anew...

I have an object in the game tab called 'twentyfourhours' and gave it an integer attribute called 'HoursCount' and set it at 105.

I have a changedHoursCount attribute as well. I added a script to that --> If object attribute equals 1, then... If 'inside' print message, Else print message. I set a changed script at 15, 30, 45, 60, 75, 90, and 105. I have an 'If' nested in there because I want a different message to appear at those turns. I also raise a flag in there as well to add a random chance event at different times of day.

I created a turnscript... that looks like this: twentyfourhours.HoursCount = twentyfourhours.HoursCount + 1

Let me know if I can alter this simply and keep it as is or if I should scrap it and go with your proposal. Of course, I would need to reset the counter after turn 105, but that can't be too hard, right? I appreciate your helps!

Below is the code for it if you need to check it out.

The twentyfourhours changedHoursCount code:

if (twentyfourhours.HoursCount = 1) {
if (GetBoolean(Xanadu, "inside")) {
msg ("Even being inside, you can tell that the morning sun has risen in the sky. The air in here is noticeably warmer.")
SetObjectFlagOff (twentyfourhours, "morning")
SetObjectFlagOn (twentyfourhours, "noon")
}
else {
msg ("The shadows have grown shorter and the sun hangs directly over your head. It's hot out here.")
SetObjectFlagOff (twentyfourhours, "morning")
SetObjectFlagOn (twentyfourhours, "noon")
}
}
else if (twentyfourhours.HoursCount = 30) {
if (GetBoolean(Xanadu, "inside")) {
msg ("It's still hot, but the heat seems to be fading a bit in here and a breeze gently brushes the walls outside.")
SetObjectFlagOff (twentyfourhours, "noon")
SetObjectFlagOn (twentyfourhours, "afternoon")
}
else {
msg ("You have noticed the shadows have grown longer and a slight breeze gives reprieve to your hot skin.")
SetObjectFlagOff (twentyfourhours, "noon")
SetObjectFlagOn (twentyfourhours, "afternoon")
}
}
else if (twentyfourhours.HoursCount = 45) {
if (GetBoolean(Xanadu, "inside")) {
msg ("The light in the room seems to be retreating. The shadows grow darker and the room colder.")
SetObjectFlagOff (twentyfourhours, "afternoon")
SetObjectFlagOn (twentyfourhours, "dusk")
}
else {
msg ("The sun is shrinking on the horizon and the once bright sky is rapidly darkening. A chill is ushered in by a whistling wind.")
SetObjectFlagOff (twentyfourhours, "afternoon")
SetObjectFlagOn (twentyfourhours, "dusk")
}
}
else if (twentyfourhours.HoursCount = 60) {
if (GetBoolean(Xanadu, "inside")) {
msg ("The room has grown quite cold. Despite the growing darkness in the room, you can see a cloud of microscopic water crystals every time you exhale.")
SetObjectFlagOff (twentyfourhours, "dusk")
SetObjectFlagOn (twentyfourhours, "evening")
}
else {
msg ("The sun has fully retreated leaving the dark sky and their stars to keep you company. It is quite chilly out here now.")
SetObjectFlagOff (twentyfourhours, "dusk")
SetObjectFlagOn (twentyfourhours, "evening")
}
}
else if (twentyfourhours.HoursCount = 75) {
if (GetBoolean(Xanadu, "inside")) {
SetObjectFlagOff (twentyfourhours, "evening")
SetObjectFlagOn (twentyfourhours, "midnight")
SetObjectFlagOn (twentyfourhours, "dark")
if (GetBoolean(Xanadu, "light")) {
msg ("The darkness in the room would be absolute now if it wasn't for your light source. Your light, however, does nothing for the bitter cold.")
}
else {
msg ("The moonlight offers insufficient light. It is now pitch black in here. If you have a lightsource, you better get to using it.")
}
}
else {
msg ("It is uncomfortably cold now and the only light you can use to travel by is supplied by the moon and the faint stars overhead.")
SetObjectFlagOff (twentyfourhours, "evening")
SetObjectFlagOn (twentyfourhours, "midnight")
}
}
else if (twentyfourhours.HoursCount = 90) {
if (GetBoolean(Xanadu, "inside")) {
msg ("The room brightens a bit and warmth begins to return to the air.")
SetObjectFlagOff (twentyfourhours, "midnight")
SetObjectFlagOn (twentyfourhours, "dawn")
SetObjectFlagOff (twentyfourhours, "dark")
}
else {
msg ("The warming sun has peaked over the horizon and its light casts long shadow across the ground.")
SetObjectFlagOff (twentyfourhours, "midnight")
SetObjectFlagOn (twentyfourhours, "dawn")
SetObjectFlagOff (twentyfourhours, "dark")
}
}
else if (twentyfourhours.HoursCount = 105) {
if (GetBoolean(Xanadu, "inside")) {
msg ("The room has become a little brighter and warmer.")
SetObjectFlagOff (twentyfourhours, "dawn")
SetObjectFlagOn (twentyfourhours, "morning")
}
else {
msg ("Thankfully, the stars have become invisible, the winds subsided, and the air has warmed.")
SetObjectFlagOff (twentyfourhours, "dawn")
SetObjectFlagOn (twentyfourhours, "morning")
}
}
else if (twentyfourhours.HoursCount = 15) {
if (GetBoolean(Xanadu, "inside")) {
msg ("It's still hot, but the heat seems to be fading a bit in here and a breeze gently brushes the walls outside.")
SetObjectFlagOff (twentyfourhours, "noon")
SetObjectFlagOn (twentyfourhours, "afternoon")
}
else {
msg ("You have noticed the shadows have grown longer and a slight breeze gives reprieve to your hot skin.")
SetObjectFlagOff (twentyfourhours, "noon")
SetObjectFlagOn (twentyfourhours, "afternoon")
}
}


And the TS code that is supposed to add one to the HoursCount attribute each time:

twentyfourhours.HoursCount = twentyfourhours.HoursCount + 1

jaynabonne
11 Jan 2016, 21:19
If you only want a single message when the time of day changes, then what you have is fine!

The only thing I would do is move the flag management outside the if/else in each time handler. If you look, those two lines are common to the if/else, so if you move them out, you can just have them once after the if/else instead of being duplicated in each:

if (twentyfourhours.HoursCount = 1) {
if (GetBoolean(Xanadu, "inside")) {
msg ("Even being inside, you can tell that the morning sun has risen in the sky. The air in here is noticeably warmer.")
}
else {
msg ("The shadows have grown shorter and the sun hangs directly over your head. It's hot out here.")
}
SetObjectFlagOff (twentyfourhours, "morning")
SetObjectFlagOn (twentyfourhours, "noon")
}

XanMag
11 Jan 2016, 21:23
Now that I have the messages working, is there a way that at turn 105, after the last message prints that I reset the counter? Thanks!

jaynabonne
11 Jan 2016, 21:30
This might work. Add:

else if (twentyfourhours.HoursCount = 120) {
twentyfourhours.HoursCount = 1
}


The other way to do it (which I think is less clear) is that after you print the last message, you set:

    twentyfourhours.HoursCount = -14

Then 15 ticks later, it will be 1 again.

Or...

Change your turnscript to be:

twentyfourhours.HoursCount = (twentyfourhours.HoursCount + 1) % 120


(I hope it's clear that the full cycle is 120 long, 105 + another 15.)

XanMag
11 Jan 2016, 22:09
Yeah! Thanks so much. That took me way too long to do despite your easy to follow directions!! Been at it too long! Time for a break.

Thanks a ton!

XanMag
12 Jan 2016, 19:39
Here is code I have for a certain time of day (dawn):

if (GetBoolean(Xanadu, "inside")) {
if (GetBoolean(bats, "presentin")) {
if (RandomChance(20)) {
firsttime {
msg ("<br/>The incessant gnawing and flapping outside have subsided for now.")
SetObjectFlagOff (bats, "presentin")
}
}
}
else {
if (RandomChance(80)) {
firsttime {
msg ("<br/>A terrible chewing and scuttling noise can be heard from beyond the outermost wall.")
SetObjectFlagOn (bats, "presentin")
}
}
}
}


I have the first time script there because I only want the message to pop-up just that one time instead of repeating every time. But, if it triggers to pop-up once, then the bats go away that message will trigger once, and then if it goes back again to triggering that they came back, it does not trigger the message again. So, I want the message to trigger one time each time they arrive and each time they leave. And does the first time only trigger the message the very first time ever, or will it pop back up again when I cycle back to this time of day??!? Does that make sense?

Thanks!

jaynabonne
12 Jan 2016, 19:49
It will only pop up the first time ever. You'd probably be better off with a "seenbats" boolean attribute. You'd set it to false when the bats are present but not seen. Then you'd check if it's still false ("not game.seenbats") and then print the message and set it to true when it's meant to show, to indicate it has been shown. That way you can reset it back to false if the bats ever come back. :)

XanMag
12 Jan 2016, 20:00
So... :smile:

if (GetBoolean(Xanadu, "inside")) {
if (bats.presentin = true) {
if (RandomChance(20)) {
msg ("<br/>The incessant gnawing and flapping outside have subsided for now.")
bats.presentin = false
}
}
else {
if (RandomChance(80)) {
msg ("<br/>A terrible chewing and scuttling noise can be heard from beyond the outmost wall.")
bats.presentin = true
}
}
}


This should work, right? I have to also do this with the bats being 'presentout'. It seems to work, but I have SEVEN times of day I have to do this with so I'd hate to do them all and then learn I'm an idiot...(as if I haven't learned that already!!)

Also, I have NEVER intentionally used 'set a variable or attribute' in the GUI! This will come in handy. Stuck it to my useful posts thread! Thanks!

jaynabonne
12 Jan 2016, 20:26
That should work! (But it would be good to give it a go, to be sure it's what you want.)

XanMag
12 Jan 2016, 20:37
Done and done. Thanks again!