Help needed in creating a 50 day-cycle

Started by rongel, Mon 18/05/2015 18:39:49

Previous topic - Next topic

rongel

Hi!

I'm starting to build a game which is based on days. There will be about 50 days, each one will have it's own events, for example you can buy a newspaper and read days news. I have currently a working system (at least it seems to work) where day ends and another starts when you go to bed. The player has a calendar at home, and by looking at it, it should tell current date but I can't figure out how to do it/which is the best way to do it. Also I'm not sure if my day-cycle system is any good, I would like to have a solid ground where to build on. And I have tried to keep it simple, because my scripting skills are quite limited!

Anyway, here is my current day-changing code:

I have a global variable called Day_counter set to 1, and a room script when you go to bed:

Code: ags

function hBed_Interact()
{
Display("You go to sleep.");
Day_counter += 1;
}


Then in Global script I have this under repeatedly execute:
Code: ags

          if (Day_counter == 1) day1();
          if (Day_counter == 3) day2();
          if (Day_counter == 5) day3();
          if (Day_counter == 7) day4();
          if (Day_counter == 9) day5();
          if (Day_counter == 11) day7();
          if (Day_counter == 13) day8();
          if (Day_counter == 15) day9();
          if (Day_counter == 17) day10();
          if (Day_counter == 19) day11();
          if (Day_counter == 21) day12();
          if (Day_counter == 23) day13();
          if (Day_counter == 27) day14();


So that activates my days:

Code: ags

function day1()
{
  Display("March 1st");
  Day_counter +=1;  
}

function day2()
{
  Display("March 2nd");
  Day_counter +=1;
}

function day3()
{
  Display("March 3rd");
  Day_counter +=1;  
}

function day4()
{
  Display("March 4th");
  Day_counter +=1;  
}

function day5()
{
  Display("March 5th");
  Day_counter +=1;
}

function day6()
{
  Display("March 6th");
  Day_counter +=1;  
}


Every day adds one to Day_counter so that it stops the repeatedly execute command. This seems to work, allthough I bet there is a nicer way to do this. My real problem is how can I make day sensitive text to my calendar and newspaper. I guess I could use the same Day_counter in it, but it doesn't seem very elegant way. Something like this:

Code: ags

function hCalendar_Look()
{
  if (Day_counter == 2) Display("It's March 1st.");
  if (Day_counter == 4) Display ("It's March 2nd.");
  if (Day_counter == 6) Display ("It's March 3rd.");
}


I tried to use Strings and more advanced stuff, but got nowhere. So which is the best way to get the calendar/newspaper to use the right text for current day? And is my current system any good? Any help is appreciated, thanks! :smiley:







Dreams in the Witch House on Steam & GOG

Grok

I'm not quite sure exactly what you want to do, but it looks like, "if, else if, else" is something that would be useful to you


Code: ags
function WhatDate()
{
    if(Day_Counter==1)
        Display("March 1st");
    else if (Day_Counter==2)
        Display("March 2nd");
    else if (Day_Counter==3)
        Display("March 3de");
    else if (Day_Counter>3 && Day_counter<21)
        Display("March %dth", Day_Counter); //will replace d% with value of Day_Counter, i.e. "March 4th" if Day_Counter==4, for values between 4 and 20
     ----

}



You can put the function in your global script and import it to any room script where you want to use it.

import function WhatDate();

at the top of the script


You should probably not use repeatedly execute for something you only intend to run one time. I'm not quite sure what it is you want to  do with that piece of code.
I hope this is of some help to you. :)

Snarky

#2
OK, a couple of things:

The repeatedly_execute() snippet is really not the best way to do what you're trying. It's ingenious, the way you use odd numbers to keep it from running more than once and switching on increment, but if something doesn't need to run every game cycle it doesn't belong in repeatedly_execute().

This is a problem because it means the day counter doesn't simply hold the day number (as you would usually expect), so it makes any kind of calculation more difficult. (It's not too difficult to convert, but let's do this properly!)

Instead, let's get rid of the lines in repeatedly_execute(), and just have a function called day_increment():

Code: ags

function hBed_Interact()
{
    Display("You go to sleep.");
    day_increment();
}

void day_increment()
{
    Day_counter++; // This is a more common way to write Day_counter += 1
    // TODO: Display date
}


Isn't that much simpler?

OK, so how do we actually display the date? Well, it's not too hard. What you want to do is to first calculate what month and day of the month it is, then find the right number suffix (st., nd., rd., th.) depending on the date. So let's write a function that produces the date string from the day number:

Code: ags

String get_number_suffix(int date)
{
    String suffix;
    if(date == 1 || date == 21 || date == 31)
        suffix = "st.";
    else if(date == 2 || date == 22)
        suffix = "nd.";
    else if(date == 3 || date == 23)
        suffix = "rd.";
    else
        suffix = "th.";

    return suffix;
}

String get_date_string(int dayNum)
{
    String month;
    int dayOfMonth;

    if(dayNum <= 31)
    {
        month = "March";
        dayOfMonth = dayNum;
    }
    else if(dayNum + 31 <= 30)
    {
        month = "April";
        dayOfMonth = dayNum - 31;
    }
    // If you're only going up to 50 that should do it, but you can add more conditions here otherwise

    return String.Format("%s %d%s", month, dayOfMonth, get_number_suffix(dayOfMonth));    // This is the magic that combines these three values into one string
}


And now you can change both day_increment() and hCalendar_Look() to use this function:

Code: ags

void day_increment()
{
    Day_counter++; // This is a more common way to write Day_counter += 1
    Display("%s",get_date_string(Day_counter));
}

function hCalendar_Look()
{
    Display("It's %s", get_date_string(Day_counter));
}


Edited because Khris reminded me Display() does inline string formatting.

Khris

You don't need the repeatedly_execute for this, and you don't need all those day functions (unless lots of preparation is needed for some days; in that case you should probably use a separate function, example below).

I'd use something like this:
Code: ags
// global header
import String TheDate();
import function AdvanceDay();

// global script
String TheDate() {
  String month = "March";
  int day = Day_counter;
  if (day > 31) {
    month = "April";
    day -= 31;
  }
  String t = "th";
  if (day % 10 == 1 && day != 11) t = "st";
  if (day == 2 || day == 22) t = "nd";
  if (day == 3 || day == 23) t = "rd";
  return String.Format("%s %d%s", month, day, t);
}

function AdvanceDay() {
  Day_counter++;
  Display(TheDate());

  // day event stuff
  if (Day_counter == 7) day7();  // call special day function
  if (Day_counter == 23) CallRoomScript(1); // make something happen in room's on_call(int p)
}


Then do this:
Code: ags
function hBed_Interact()
{
  Display("You go to sleep.");
  AdvanceDay();
}

function hCalendar_Look()
{
  Display ("It's %s.", TheDate());
}

Snarky

You forgot about the 31st, Khris. ;) Nope, ignore that! :-[

Khris

I noticed it in your code after posting and fixed it :)

rongel

Wow, that was fast, thanks for the help!

I'm going to try out these now and figure them out. New question are coming probably soon! 
Dreams in the Witch House on Steam & GOG

SMF spam blocked by CleanTalk