Calendar woes -- in need of a simple calendar [SOLVED]

Discuss how to use the Ren'Py engine to create visual novels and story-based games. New releases are announced in this section.
Forum rules
This is the right place for Ren'Py help. Please ask one question per thread, use a descriptive subject like 'NotFound error in option.rpy' , and include all the relevant information - especially any relevant code and traceback messages. Use the code tag to format scripts.
Message
Author
User avatar
katamaris
Newbie
Posts: 3
Joined: Tue Feb 04, 2014 5:41 pm
Contact:

Calendar woes -- in need of a simple calendar [SOLVED]

#1 Post by katamaris »

Let me preface this by saying I'm sorry I'm coming here with such a simple question! I've been at this problem for a day and a half now and run out of solutions to try. I'm very new to python and I've been trying to work through this on my own, but it's beginning to drive me loopy. I'm in need of a simple calendar system and I've tried the "slightly complex digital calendar" from the Ren'Py cookbook (here), and it worked great aside from the fact that the month never changed (the days would cycle through properly but at the end of the month, the day would just switch back to 1 and the month would remain the same). I also tried the calendar system here, but that one didn't work either?

So I have this lovely little day-of-the-week system with an image overlay going on here:

Code: Select all

init python:

    show_date = False
    day = 1
    month = 4
    monthname = "April"
    theyear = 2014
    daylim = 30
    daynames = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
    theweekday =  daynames[(day%7)]
    
    def date_overlay():
        if show_date:
            ui.image ("%s" % theweekday + ".png", xalign=1.0, yalign=0.0)
            ui.text("(%s) - %s %d %d" % (theweekday, monthname, day, theyear), xalign=0.7, size=20)
            
    
    config.overlay_functions.append(date_overlay)
The ui.image works great and shows my day of the week with nice a little graphic I made. That text one is there just so I can visually see if my calendar is working or not while I've been experimenting with it. I've tried experimenting with simple variables to change the month ([if day == "30": monthname = "March"] type of thing, but obviously properly placed) but those didn't work either... so I must have done those wrong, but I'm not sure how. I feel like I'm missing something so simple, but I've been at it for so long that I just don't think I can work through it. I really just need a calendar that can cycle through... three or four months, and able to display the way I have the day-of-the-week overlay right now. I don't even need a year system! It seems so simple, so I feel embarrassed asking but... can anyone assist me? :oops:
Last edited by katamaris on Tue Feb 04, 2014 9:36 pm, edited 1 time in total.

User avatar
xela
Lemma-Class Veteran
Posts: 2481
Joined: Sun Sep 18, 2011 10:13 am
Contact:

Re: Calendar woes -- in need of a simple calendar

#2 Post by xela »

In your code, you're missing an array of month and another array of days in month + some basic logic.

It should be at least a function (you can put it in your day overlay and keep some variables global).

I have a decent and simple to use calendar as a python class with single day variable on store's namespace that will count days, weeks, month, years and moodphase. I'll find it for you if you don't want to mess with the function/globals.
Like what we're doing? Support us at:
Image

User avatar
katamaris
Newbie
Posts: 3
Joined: Tue Feb 04, 2014 5:41 pm
Contact:

Re: Calendar woes -- in need of a simple calendar

#3 Post by katamaris »

Yeah, every time I stuck a code in or tried coding one myself and it didn't work, I just pulled it back out, so that code there is missing any... actual coding that would even attempt to support a monthly calendar system, lol, but I left some of the variables there that I had been trying to manipulate or was using in other codes (such as the daylim) as well as my current day-of-the-week code I'm using without incident.

And thanks! I'll give anything a try :oops:

User avatar
xela
Lemma-Class Veteran
Posts: 2481
Joined: Sun Sep 18, 2011 10:13 am
Contact:

Re: Calendar woes -- in need of a simple calendar

#4 Post by xela »

Code: Select all

init python:
    def date_overlay():
        if show_date:
            ui.image ("".join([calendar.weekday(), ".png"]), xalign=1.0, yalign=0.0)
            ui.text(calendar.string(), xalign=0.7, size=20)
            
    
    config.overlay_functions.append(date_overlay)


    class Calendar(object):
        '''Provides time-related information based on a sequence of day names.
        Most class methods take a daycount parameter, which is assumed to be a count
        of passed days, starting with 1 for the first day.
        newmoonday is the daycount of the first new moon, e.g. 1 for the first
        day.
        Provides date based on different logic (counter).
        '''
        def __init__(self, day=1, month=1, year=1):
            self.day = day
            self.month = month
            self.year = year
            
            self.days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
            self.month_names = ['', 'January', 'February', 'March', 'April', 'May', 'June', 'July',
                                               'August', 'September', 'October', 'November', 'December']
            self.days_count = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
            self.mooncycle = 29
            self.newmoonday = 1
            
        def string(self):
            return "(%s) - %s %d %d"%(self.weekday(), self.month_names[self.month], self.day, self.year)
            
        def next(self):
            global day
            day = day + 1
            
            self.day += 1
            if self.day > self.days_count[self.month]:
                self.month += 1
                if self.month > 12: 
                    self.month = 1
                    self.year += 1
                self.day = 1

        def weekday(self):
            '''Returns the name of the current day according to daycount.'''
            dayidx = day - 1
            daylistidx = dayidx % len(self.days)
            return self.days[daylistidx]

Code: Select all

label start:
    python:
        day = 1
        calendar = Calendar(month=4, year=2014)
        show_date = True

Code: Select all

label next_day: #(or whatever)
    $ calendar.next() # For the next day

Should work for you "plug and play", unless I made spelling errors. Sorry for the mess in code, when I've started with my game, the only thing I knew how to do is $ day and $ day += 1, rest of the game kinda wrapped around that so I had to build this class over that day global variable.

Tell me if this is working.

Edit: I removed half of the class to make it less confusing since it isn't used anywhere AND corrected 2 errors so copy/paste it again.
Last edited by xela on Tue Feb 04, 2014 8:46 pm, edited 1 time in total.
Like what we're doing? Support us at:
Image

User avatar
noeinan
Eileen-Class Veteran
Posts: 1153
Joined: Sun Apr 04, 2010 10:10 pm
Projects: Ren'Py QuickStart, Crimson Rue
Organization: Statistically Unlikely Games
Deviantart: noeinan
Github: noeinan
Location: Washington State, USA
Contact:

Re: Calendar woes -- in need of a simple calendar

#5 Post by noeinan »

This is super useful! xela, do you mind if I use this code as well?
Image

Image
Image

User avatar
xela
Lemma-Class Veteran
Posts: 2481
Joined: Sun Sep 18, 2011 10:13 am
Contact:

Re: Calendar woes -- in need of a simple calendar

#6 Post by xela »

daikiraikimi wrote:This is super useful! xela, do you mind if I use this code as well?
Yeah sure, just copy/paste it AGAIN...

Next method was set up for a week so you could get a day like -2 :)

I'll see if I can make a proper class out of this (without day variable) and post it again.
Like what we're doing? Support us at:
Image

User avatar
noeinan
Eileen-Class Veteran
Posts: 1153
Joined: Sun Apr 04, 2010 10:10 pm
Projects: Ren'Py QuickStart, Crimson Rue
Organization: Statistically Unlikely Games
Deviantart: noeinan
Github: noeinan
Location: Washington State, USA
Contact:

Re: Calendar woes -- in need of a simple calendar

#7 Post by noeinan »

Woot, woot! If you're okay with defining how you'd like the code to be used, I'd even advocate moving this thread to the cookbook...
Image

Image
Image

User avatar
katamaris
Newbie
Posts: 3
Joined: Tue Feb 04, 2014 5:41 pm
Contact:

Re: Calendar woes -- in need of a simple calendar

#8 Post by katamaris »

I feel really bad; I actually ended up working out a different code just minutes before you posted your's, xela! :( I found the code at the end of this post and worked it into my coding and it all seems to be working for me. It's really basic though, so thank you for providing your's! I'm sure I'll need to upgrade x:

I'll post the basic code I'm using right now

Code: Select all

init python:

    show_date = False
    day = 1
    month = 4
    day_max = 30
    daynames = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
    theweekday =  daynames[(day%7)]
    
    month_information={
        1:("January",31),
        2:("February",28),
        3:("March",31),
        4:("April",30),
        5:("May",31),
        6:("June",30),
        7:("July",31),
        8:("August",31),
        9:("September",30),
        10:("October",31),
        11:("November",30),
        12:("December",31)}
    
    def date_overlay():
        if show_date:
            ui.image ("%s" % theweekday + ".png", xalign=1.0, yalign=0.035)
            ui.image ("%s" % month + ".png", xalign=0.965, yalign=0.0)
            ui.image ("%s" % day + "d.png", xalign=1.0, yalign=0.0)
            
    
    config.overlay_functions.append(date_overlay)

Code: Select all

label day:
    scene bedroom with fade
    if day==day_max:
        $day=0  
        $month+=1
        $month_name,day_max=month_information[month]#look up the dictionary
    $day+=1


    H "It's day %(day)d. It's %(theweekday)s."
I'll attach a picture of the nice little corner calendar this code is providing for me! Thank you so much for your super speedy reply, Xela
Attachments
lilcalendar.jpg
lilcalendar.jpg (48.75 KiB) Viewed 9947 times

User avatar
xela
Lemma-Class Veteran
Posts: 2481
Joined: Sun Sep 18, 2011 10:13 am
Contact:

Re: Calendar woes -- in need of a simple calendar

#9 Post by xela »

katamaris wrote:I feel really bad;
I need this for my game as well so there is no need for that :)
katamaris wrote: I'll attach a picture of the nice little corner calendar this code is providing for me! Thank you so much for your super speedy reply, Xela
I managed to improve that code somewhat, string() method can be modified to relay any data:

Code: Select all

init python:
    
    class Execute(Action):
        """
        Well... it executes... :)
        This has NOTHING to do with calendar, just makes using it with screen language easier.
        """
        def __init__(self, func, *args, **kwargs):
            self.func = func
            self.args = args
            self.kwargs = kwargs
        
        def __call__(self):
            self.func(*self.args, **self.kwargs)
            return False
    
    class Calendar(object):
        '''Provides time-related information.
        Cheers to Rudi for mooncalendar calculations.
        '''
        def __init__(self, day=1, month=1, year=1, leapyear=False):
            """
            Expects day/month/year as they are numbered in normal calender.
            If you wish to add leapyear, specify a number of the first Leap year to come.
            """
            self.day = day
            self.month = month - 1
            self.year = year
            if not leapyear:
                self.leapyear = self.year + 4
            else:    
                self.leapyear = leapyear
            
            self.daycount_from_gamestart = 0
            
            self.days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
            self.month_names = ['January', 'February', 'March', 'April', 'May', 'June', 'July',
                                               'August', 'September', 'October', 'November', 'December']
            self.days_count = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
            
            self.mooncycle = 29
            self.newmoonday = 1
            
        def game_day(self):
            """
            Returns amount of days player has spent in game.
            Counts first day as day 1.
            """
            return self.daycount_from_gamestart + 1
            
        def string(self):
            return "(%s) - %s %d %d"%(self.weekday(), self.month_names[self.month], self.day, self.year)
            
        def next(self, days=1):
            """
            Next day counter.
            Now supports skipping.
            """
            self.daycount_from_gamestart += days
            while days:
                self.day += 1
                days -= 1
                if self.leapyear == self.year and self.month == 1:
                    if self.day > self.days_count[self.month] + 1:
                        self.month += 1
                        self.day = 1
                        self.leapyear += 4
                elif self.day > self.days_count[self.month]:
                    self.month += 1
                    self.day = 1
                    if self.month > 11: 
                        self.month = 0
                        self.year += 1
                        

        def weekday(self):
            '''Returns the name of the current day according to daycount.'''
            daylistidx = self.daycount_from_gamestart % len(self.days)
            return self.days[daylistidx]

        def week(self):
            '''Returns the number of weeks, starting at 1 for the first week.
            '''
            weekidx = self.daycount_from_gamestart / len(self.days)
            return weekidx + 1

        def lunarprogress(self):
            '''Returns the progress in the lunar cycle since new moon as percentage.
            '''
            newmoonidx = self.newmoonday - 1
            dayidx = self.daycount_from_gamestart - newmoonidx
            moonidx = dayidx % self.mooncycle
            moondays = moonidx + 1
            percentage = moondays * 100.0 / self.mooncycle
            return int(round(percentage))

        def moonphase(self):
            '''Returns the lunar phase according to daycount.

            Phases:
            new moon -> waxing crescent -> first quater -> waxing moon ->
                full moon -> waning moon -> last quarter -> waning crescent -> ...
            '''
            # calculate days into the cycle
            newmoonidx = self.newmoonday - 1
            dayidx = self.daycount_from_gamestart - newmoonidx
            moonidx = dayidx % self.mooncycle
            moondays = moonidx + 1
            # substract the number of named days
            unnamed_days = self.mooncycle - 4
            # calculate the days per quarter
            quarter = unnamed_days / 4.0
            # determine phase
            if moonidx<1:
                phase = "new moon"
            elif moonidx<(quarter+1):
                phase = "waxing crescent"
            elif moonidx<(quarter+2):
                phase = "first quarter"
            elif moonidx<(2*quarter+2):
                phase = "waxing moon"
            elif moonidx<(2*quarter+3):
                phase = "full moon"
            elif moonidx<(3*quarter+3):
                phase = "waning moon"
            elif moonidx<(3*quarter+4):
                phase = "last quarter"
            else:
                phase = "waning crescent"
            return phase

            
screen calendar_testing:
    vbox:
        xminimum 500
        xfill True
        spacing 10
        align(0.5, 0.1)
        text "Day: %d"%calendar.game_day()
        text "Week: %d"%calendar.week()
        text "Date: %s"%calendar.string()
        text "Next Leap Year: %s"%calendar.leapyear
        text "Lunar Progress: %d%%"%calendar.lunarprogress()
        text "Moon Phase: %s"%calendar.moonphase().capitalize()
        
    hbox:
        spacing 10
        align (0.5, 0.7)
        textbutton "+1 Day":
            action Execute(calendar.next, 1)
        textbutton "+1 Week":
            action Execute(calendar.next, 7)
        textbutton "+100 Days":
            action Execute(calendar.next, 100)
            
label start:
    $ calendar = Calendar(5, 2, 2014, 2016) # Calendar(day, month, year, first leap year (can be ignored))
    # $ calendar.next() <--- This will cause your calendar to advance by one day.
    # $ calendar.next(days=7) <--- By one week, if one turn of your game is a week.
    
    show screen calendar_testing
    
    while True: # This has nothing to do with calendar, just to make sure that we can toy with it without leaving the game.
        $ result = ui.interact()
Like what we're doing? Support us at:
Image

User avatar
noeinan
Eileen-Class Veteran
Posts: 1153
Joined: Sun Apr 04, 2010 10:10 pm
Projects: Ren'Py QuickStart, Crimson Rue
Organization: Statistically Unlikely Games
Deviantart: noeinan
Github: noeinan
Location: Washington State, USA
Contact:

Re: Calendar woes -- in need of a simple calendar [SOLVED]

#10 Post by noeinan »

Tried your new code, xela, but I'm getting this error message...

Code: Select all

I'm sorry, but errors were detected in your script. Please correct the
errors listed below, and try again.


File "game/script.rpy", line 148: expected a keyword argument, colon, or end of line.
    text "Day: %d"%calendar.game_day()
                  ^

Ren'Py Version: Ren'Py 6.16.5.525
Image

Image
Image

User avatar
xela
Lemma-Class Veteran
Posts: 2481
Joined: Sun Sep 18, 2011 10:13 am
Contact:

Re: Calendar woes -- in need of a simple calendar [SOLVED]

#11 Post by xela »

Try:

Code: Select all

        text ("Day: %d"%calendar.game_day())
        text ("Week: %d"%calendar.week())
        text ("Date: %s"%calendar.string())
        text ("Next Leap Year: %s"%calendar.leapyear)
        text ("Lunar Progress: %d%%"%calendar.lunarprogress())
        text ("Moon Phase: %s"%calendar.moonphase().capitalize())
in the screen.

I've tested that code in the new project EXACTLY as I've posted it and have already put it in my game, there were no glitches. I am on pre-Release channel version of Ren'Py (which is by the way amazing.)
Like what we're doing? Support us at:
Image

User avatar
noeinan
Eileen-Class Veteran
Posts: 1153
Joined: Sun Apr 04, 2010 10:10 pm
Projects: Ren'Py QuickStart, Crimson Rue
Organization: Statistically Unlikely Games
Deviantart: noeinan
Github: noeinan
Location: Washington State, USA
Contact:

Re: Calendar woes -- in need of a simple calendar [SOLVED]

#12 Post by noeinan »

That works perfectly, thanks a bunch! :D

I'm using 6.16.5 which was released in December... Is there a newer version I don't know of? This one is already awesome, especially since RAPT is rolled into it.

[EDIT]

So, I have a question regarding this code-- sorry, I don't know python and it's a little hard to decipher.

I want to use the variables for what day of the week it is, what month it is, etc. but I'm not completely sure how to address them? They aren't just plain Ren'Py named variables, so I don't want to mess everything up by not using them right. (The ones you use are full of % and d or s, which I think has something to do with the type of variable and strings?) Here are some examples of how I want to use those variables:

In an overlay: (Sorry for the cruddy example on this one, I just tried to imitate the way the other code used the variables, but I don't totally understand it.)

Code: Select all

init python: #Want to change this block so it works with your code

    show_date = False
    
    def date_overlay():
        if show_date:
            ui.image ("%d" %calendar.game_day + ".png", xalign=1.0, yalign=0.035)
            ui.image ("%d" % self.month + ".png", xalign=0.965, yalign=0.0)
            ui.image ("%s" %calendar.string + ".png", xalign=1.0, yalign=0.0)
            ui.image ("%s" %calendar.moonphase + ".png", xalign=0.0, yalign=0.0)
            ui.text(self.year(), xalign=0.7, size=20)
           
   
    config.overlay_functions.append(date_overlay)
To make sure I always return from a weekly activity if it's the last day of the month:

Code: Select all

##############################################################################
# Weekly Activities
#
# This file is used to store the players activity choice for each week. Events
# are called from within each activity.


## SCHOOL

label Art:

    $ calendar.next() #This will causes the calendar to advance by one day.
    
    "You go to the forest in the back of the school to draw."
    
    call check_events #check to see if any events have been triggered.
    
    if current_day < 7: #want to make this if the current day < 7 AND it is not the last day of the month.
        $ current_day += 1
        jump Art
    
    return
And in the event checker:

Code: Select all

label check_events:
    
    "This function checks to see if any events have been triggered."
    # if it is September 30th:
    # jump Harvest_Festival
    
    # if moon_phase = "full moon":
    # insanity += 5
    
    return
Thank you very much for posting your code, and all your help. :)
Image

Image
Image

User avatar
xela
Lemma-Class Veteran
Posts: 2481
Joined: Sun Sep 18, 2011 10:13 am
Contact:

Re: Calendar woes -- in need of a simple calendar [SOLVED]

#13 Post by xela »

Oki, one thing at a time :)

Code: Select all

    class Calendar(object):
        '''Provides time-related information.
        Cheers to Rudi for mooncalendar calculations.
        '''
        def __init__(self, day=1, month=1, year=1, leapyear=False):
            """
            Expects day/month/year as they are numbered in normal calender.
            If you wish to add leapyear, specify a number of the first Leap year to come.
            """
            self.day = day
            self._month = month - 1
            self.year = year
            if not leapyear:
                self.leapyear = self.year + 4
            else:   
                self.leapyear = leapyear
           
            self.daycount_from_gamestart = 0
           
            self.days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
            self.month_names = ['January', 'February', 'March', 'April', 'May', 'June', 'July',
                                               'August', 'September', 'October', 'November', 'December']
            self.days_count = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
           
            self.mooncycle = 29
            self.newmoonday = 1
           
        @property    
        def game_day(self):
            """
            Returns amount of days player has spent in game.
            Counts first day as day 1.
            """
            return self.daycount_from_gamestart + 1
        
        @property    
        def game_week(self):
            '''Returns the number of weeks, starting at 1 for the first week.
            '''
            weekidx = self.daycount_from_gamestart / len(self.days)
            return weekidx + 1

        @property    
        def weekday(self):
            '''Returns the name of the current day according to daycount.'''
            daylistidx = self.daycount_from_gamestart % len(self.days)
            return self.days[daylistidx]
            
        @property
        def month_number(self):
            return self._month + 1
            
        @property
        def month(self):
            return self.month_names[self._month]
            
        @property    
        def lunarprogress(self):
            '''Returns the progress in the lunar cycle since new moon as percentage.
            '''
            newmoonidx = self.newmoonday - 1
            dayidx = self.daycount_from_gamestart - newmoonidx
            moonidx = dayidx % self.mooncycle
            moondays = moonidx + 1
            percentage = moondays * 100.0 / self.mooncycle
            return int(round(percentage))

        @property    
        def moonphase(self):
            '''Returns the lunar phase according to daycount.

            Phases:
            new moon -> waxing crescent -> first quater -> waxing moon ->
                full moon -> waning moon -> last quarter -> waning crescent -> ...
            '''
            # calculate days into the cycle
            newmoonidx = self.newmoonday - 1
            dayidx = self.daycount_from_gamestart - newmoonidx
            moonidx = dayidx % self.mooncycle
            moondays = moonidx + 1
            # substract the number of named days
            unnamed_days = self.mooncycle - 4
            # calculate the days per quarter
            quarter = unnamed_days / 4.0
            # determine phase
            if moonidx<1:
                phase = "new moon"
            elif moonidx<(quarter+1):
                phase = "waxing crescent"
            elif moonidx<(quarter+2):
                phase = "first quarter"
            elif moonidx<(2*quarter+2):
                phase = "waxing moon"
            elif moonidx<(2*quarter+3):
                phase = "full moon"
            elif moonidx<(3*quarter+3):
                phase = "waning moon"
            elif moonidx<(3*quarter+4):
                phase = "last quarter"
            else:
                phase = "waning crescent"
            return phase
            
        @property
        def last_day_of_the_month(self):
            if self.leapyear == self.year and self._month == 1:
                return self.day == self.days_count[self._month] + 1
            else:    
                return self.day == self.days_count[self._month]
            
        @property        
        def string(self):
            return "(%s) - %s %d %d"%(self.weekday, self.month, self.day, self.year)
        
        def next(self, days=1):
            """
            Next day counter.
            Now supports skipping.
            """
            self.daycount_from_gamestart += days
            while days:
                self.day += 1
                days -= 1
                if self.leapyear == self.year and self._month == 1:
                    if self.day > self.days_count[self._month] + 1:
                        self._month += 1
                        self.day = 1
                        self.leapyear += 4
                elif self.day > self.days_count[self._month]:
                    self._month += 1
                    self.day = 1
                    if self._month > 11:
                        self._month = 0
                        self.year += 1
                       
           
screen calendar_testing:
    vbox:
        xminimum 500
        xfill True
        spacing 10
        align(0.5, 0.1)
        text ("Day: %d"%calendar.game_day)
        text ("Week: %d"%calendar.game_week)
        text ("Date: %s"%calendar.string)
        text ("Next Leap Year: %s"%calendar.leapyear)
        text ("Lunar Progress: %d%%"%calendar.lunarprogress)
        text ("Moon Phase: %s"%calendar.moonphase.capitalize())
        text ("Last day of the month: %s"%calendar.last_day_of_the_month)
You will need pictures, representing stuff for images (just confirming if you are aware of that). If you just want text, that overlay should be different. (ui.text only) This does make a hell of a sense to do for the moonphase. Rest is likely to look better with nice font and a transform, less work as well.

I find it hard to believe that you have image for every possibly of what the string returns, it doesn't seem possible. Also, using overlay is outdated, screen will do the same with better syntax.

With new code:

calendar.game_day # Days player spent in game
calendar.game_week # Weeks player spent in game
calendar.weekday # Day of week in English
calendar.month_number # Number of a month
calendar.month # Name of the month
calendar.lunarprogress # Percent of the lunar progress as a number
calendar.moonphase # phase of a moon in English, without capitals
calendar.last_day_of_the_month # boolean (True/False)

calendar.string # date in a format as you see on the screen.

Code: Select all

init python: #Want to change this block so it works with your code

    show_date = False
    
    def date_overlay():
        if show_date:
            ui.image ("%d" %calendar.game_day + ".png", xalign=1.0, yalign=0.035)
            ui.image ("%d" %calendar.month + ".png", xalign=0.965, yalign=0.0)
            # ui.image ("%s" %calendar.string + ".png", xalign=1.0, yalign=0.0) < -- Does not seem possible, to many pictures... unless it's a short game.
            ui.text(calendar.string, xalign=1.0, yalign=0.0)
            ui.image ("%s" %calendar.moonphase + ".png", xalign=0.0, yalign=0.0)
            ui.text(calendar.year, xalign=0.7, size=20)
           
   
    config.overlay_functions.append(date_overlay)
Fixed code.
daikiraikimi wrote: To make sure I always return from a weekly activity if it's the last day of the month:

Code: Select all

##############################################################################
# Weekly Activities
#
# This file is used to store the players activity choice for each week. Events
# are called from within each activity.


## SCHOOL

label Art:

    $ calendar.next() #This will causes the calendar to advance by one day.
    
    "You go to the forest in the back of the school to draw."
    
    call check_events #check to see if any events have been triggered.
    
    if current_day < 7: #want to make this if the current day < 7 AND it is not the last day of the month.
        $ current_day += 1
        jump Art
    
    return
Maybe:

Code: Select all

    if calendar.game_day % 7 != 0 and not calendar.last_day_of_the_month:
        jump Art
This code will make sure that game jumps to Art as long as it is not last day of the month and it's not 7th, 14th, 23rd etc. day since player has started the game.

============
Having said that:
To make sure I always return from a weekly activity if it's the last day of the month:
if calendar.last_day_of_the_month:
jump (or call) Month_Report

Code: Select all

    if current_day < 7: #want to make this if the current day < 7 AND it is not the last day of the month.
        $ current_day += 1
        jump Art
I do not understand this code, bigger than 7 of what? Maybe you've meant something like:

Code: Select all

if calendar.weekday != "Sunday":
    ...
? So every 7th day of the week, you get to pick something again (this should not be in Art label than, should be in the control label).
daikiraikimi wrote: And in the event checker:

Code: Select all

label check_events:
    
    "This function checks to see if any events have been triggered."
    # if it is September 30th:
    # jump Harvest_Festival
    
    # if moon_phase = "full moon":
    # insanity += 5
    
    return
Very easy to understand what you want here:

Code: Select all

if calendar.moonphase == "full moon":
    $ insanity += 5

Code: Select all

if calendar.month == "September" and calendar.day == 30:
    jump Harvest_Festival
daikiraikimi wrote:I'm using 6.16.5 which was released in December... Is there a newer version I don't know of? This one is already awesome, especially since RAPT is rolled into it.
Yeap, but still only on the release channel.
Like what we're doing? Support us at:
Image

User avatar
xela
Lemma-Class Veteran
Posts: 2481
Joined: Sun Sep 18, 2011 10:13 am
Contact:

Re: Calendar woes -- in need of a simple calendar [SOLVED]

#14 Post by xela »

Oki, one thing at a time :)

Code: Select all

    class Calendar(object):
        '''Provides time-related information.
        Cheers to Rudi for mooncalendar calculations.
        '''
        def __init__(self, day=1, month=1, year=1, leapyear=False):
            """
            Expects day/month/year as they are numbered in normal calender.
            If you wish to add leapyear, specify a number of the first Leap year to come.
            """
            self.day = day
            self._month = month - 1
            self.year = year
            if not leapyear:
                self.leapyear = self.year + 4
            else:   
                self.leapyear = leapyear
           
            self.daycount_from_gamestart = 0
           
            self.days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
            self.month_names = ['January', 'February', 'March', 'April', 'May', 'June', 'July',
                                               'August', 'September', 'October', 'November', 'December']
            self.days_count = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
           
            self.mooncycle = 29
            self.newmoonday = 1
           
        @property    
        def game_day(self):
            """
            Returns amount of days player has spent in game.
            Counts first day as day 1.
            """
            return self.daycount_from_gamestart + 1
        
        @property    
        def game_week(self):
            '''Returns the number of weeks, starting at 1 for the first week.
            '''
            weekidx = self.daycount_from_gamestart / len(self.days)
            return weekidx + 1

        @property    
        def weekday(self):
            '''Returns the name of the current day according to daycount.'''
            daylistidx = self.daycount_from_gamestart % len(self.days)
            return self.days[daylistidx]
            
        @property
        def month_number(self):
            return self._month + 1
            
        @property
        def month(self):
            return self.month_names[self._month]
            
        @property    
        def lunarprogress(self):
            '''Returns the progress in the lunar cycle since new moon as percentage.
            '''
            newmoonidx = self.newmoonday - 1
            dayidx = self.daycount_from_gamestart - newmoonidx
            moonidx = dayidx % self.mooncycle
            moondays = moonidx + 1
            percentage = moondays * 100.0 / self.mooncycle
            return int(round(percentage))

        @property    
        def moonphase(self):
            '''Returns the lunar phase according to daycount.

            Phases:
            new moon -> waxing crescent -> first quater -> waxing moon ->
                full moon -> waning moon -> last quarter -> waning crescent -> ...
            '''
            # calculate days into the cycle
            newmoonidx = self.newmoonday - 1
            dayidx = self.daycount_from_gamestart - newmoonidx
            moonidx = dayidx % self.mooncycle
            moondays = moonidx + 1
            # substract the number of named days
            unnamed_days = self.mooncycle - 4
            # calculate the days per quarter
            quarter = unnamed_days / 4.0
            # determine phase
            if moonidx<1:
                phase = "new moon"
            elif moonidx<(quarter+1):
                phase = "waxing crescent"
            elif moonidx<(quarter+2):
                phase = "first quarter"
            elif moonidx<(2*quarter+2):
                phase = "waxing moon"
            elif moonidx<(2*quarter+3):
                phase = "full moon"
            elif moonidx<(3*quarter+3):
                phase = "waning moon"
            elif moonidx<(3*quarter+4):
                phase = "last quarter"
            else:
                phase = "waning crescent"
            return phase
            
        @property
        def last_day_of_the_month(self):
            if self.leapyear == self.year and self._month == 1:
                return self.day == self.days_count[self._month] + 1
            else:    
                return self.day == self.days_count[self._month]
            
        @property        
        def string(self):
            return "(%s) - %s %d %d"%(self.weekday, self.month, self.day, self.year)
        
        def next(self, days=1):
            """
            Next day counter.
            Now supports skipping.
            """
            self.daycount_from_gamestart += days
            while days:
                self.day += 1
                days -= 1
                if self.leapyear == self.year and self._month == 1:
                    if self.day > self.days_count[self._month] + 1:
                        self._month += 1
                        self.day = 1
                        self.leapyear += 4
                elif self.day > self.days_count[self._month]:
                    self._month += 1
                    self.day = 1
                    if self._month > 11:
                        self._month = 0
                        self.year += 1
                       
           
screen calendar_testing:
    vbox:
        xminimum 500
        xfill True
        spacing 10
        align(0.5, 0.1)
        text ("Day: %d"%calendar.game_day)
        text ("Week: %d"%calendar.game_week)
        text ("Date: %s"%calendar.string)
        text ("Next Leap Year: %s"%calendar.leapyear)
        text ("Lunar Progress: %d%%"%calendar.lunarprogress)
        text ("Moon Phase: %s"%calendar.moonphase.capitalize())
        text ("Last day of the month: %s"%calendar.last_day_of_the_month)
You will need pictures, representing stuff for images (just confirming if you are aware of that). If you just want text, that overlay should be different. (ui.text only) Images make a hell of a sense for the moonphase. Rest is likely to look better with a nice font and a transform, less work as well.

I find it hard to believe that you have image for every possibly of what the string returns, it doesn't seem possible. Also, using overlay is outdated, screen will do the same with better syntax.

With new code:

calendar.game_day # Days player spent in game
calendar.game_week # Weeks player spent in game
calendar.weekday # Day of week in English
calendar.month_number # Number of a month
calendar.month # Name of the month
calendar.lunarprogress # Percent of the lunar progress as a number
calendar.moonphase # phase of a moon in English, without capitals
calendar.last_day_of_the_month # boolean (True/False)

calendar.string # date in a format as you see on the screen.

Code: Select all

init python: #Want to change this block so it works with your code

    show_date = False
    
    def date_overlay():
        if show_date:
            ui.image ("%d" %calendar.game_day + ".png", xalign=1.0, yalign=0.035)
            ui.image ("%d" %calendar.month + ".png", xalign=0.965, yalign=0.0)
            # ui.image ("%s" %calendar.string + ".png", xalign=1.0, yalign=0.0) < -- Does not seem possible, to many pictures... unless it's a short game.
            ui.text(calendar.string, xalign=1.0, yalign=0.0)
            ui.image ("%s" %calendar.moonphase + ".png", xalign=0.0, yalign=0.0)
            ui.text(calendar.year, xalign=0.7, size=20)
           
   
    config.overlay_functions.append(date_overlay)
Fixed code.
daikiraikimi wrote: To make sure I always return from a weekly activity if it's the last day of the month:

Code: Select all

##############################################################################
# Weekly Activities
#
# This file is used to store the players activity choice for each week. Events
# are called from within each activity.


## SCHOOL

label Art:

    $ calendar.next() #This will causes the calendar to advance by one day.
    
    "You go to the forest in the back of the school to draw."
    
    call check_events #check to see if any events have been triggered.
    
    if current_day < 7: #want to make this if the current day < 7 AND it is not the last day of the month.
        $ current_day += 1
        jump Art
    
    return
Maybe:

Code: Select all

    if calendar.game_day % 7 != 0 and not calendar.last_day_of_the_month:
        jump Art
This code will make sure that game jumps to Art as long as it is not last day of the month and it's not 7th, 14th, 23rd etc. day since player has started the game.

============
Having said that:
To make sure I always return from a weekly activity if it's the last day of the month:

Code: Select all

if calendar.last_day_of_the_month:
    call Month_Report

Code: Select all

    if current_day < 7: #want to make this if the current day < 7 AND it is not the last day of the month.
        $ current_day += 1
        jump Art
I do not understand this code, bigger than 7 of what? Maybe you've meant something like:

Code: Select all

if calendar.weekday != "Sunday":
    ...
? So every 7th day of the week, you get to pick something again (this should not be in Art label than, should be in the control label).
daikiraikimi wrote: And in the event checker:

Code: Select all

label check_events:
    
    "This function checks to see if any events have been triggered."
    # if it is September 30th:
    # jump Harvest_Festival
    
    # if moon_phase = "full moon":
    # insanity += 5
    
    return
Very easy to understand what you want here:

Code: Select all

if calendar.moonphase == "full moon":
    $ insanity += 5

Code: Select all

if calendar.month == "September" and calendar.day == 30:
    jump Harvest_Festival
daikiraikimi wrote:I'm using 6.16.5 which was released in December... Is there a newer version I don't know of? This one is already awesome, especially since RAPT is rolled into it.
Yeap, but still only on the release channel.
Like what we're doing? Support us at:
Image

User avatar
noeinan
Eileen-Class Veteran
Posts: 1153
Joined: Sun Apr 04, 2010 10:10 pm
Projects: Ren'Py QuickStart, Crimson Rue
Organization: Statistically Unlikely Games
Deviantart: noeinan
Github: noeinan
Location: Washington State, USA
Contact:

Re: Calendar woes -- in need of a simple calendar [SOLVED]

#15 Post by noeinan »

Thank you! I will clarify some things as we go along. :)

First, in the code block here, is there a reason to add the @property before each def? Just curious.
xela wrote:Oki, one thing at a time :)

You will need pictures, representing stuff for images (just confirming if you are aware of that). If you just want text, that overlay should be different. (ui.text only) This does make a hell of a sense to do for the moonphase. Rest is likely to look better with nice font and a transform, less work as well.

I find it hard to believe that you have image for every possibly of what the string returns, it doesn't seem possible. Also, using overlay is outdated, screen will do the same with better syntax.
I was thinking I would have layered images or something? Like, for each month I'd have a themed picture, and then a picture of the day of the week name, looking like fancy text. Also possibly the day number is its own image that sits on top of the "month background" something like this:

Image

Text would probably work for most of this, but I was thinking of having more artistic text, and with the "monthly background" each having their own little embellishments. Figured I could do this better with images?
xela wrote:With new code:

calendar.game_day # Days player spent in game
calendar.game_week # Weeks player spent in game
calendar.weekday # Day of week in English
calendar.month_number # Number of a month
calendar.month # Name of the month
calendar.lunarprogress # Percent of the lunar progress as a number
calendar.moonphase # phase of a moon in English, without capitals
calendar.last_day_of_the_month # boolean (True/False)

calendar.string # date in a format as you see on the screen.

Fixed code.
daikiraikimi wrote: To make sure I always return from a weekly activity if it's the last day of the month:

Code: Select all

##############################################################################
# Weekly Activities
#
# This file is used to store the players activity choice for each week. Events
# are called from within each activity.


## SCHOOL

label Art:

    $ calendar.next() #This will causes the calendar to advance by one day.
    
    "You go to the forest in the back of the school to draw."
    
    call check_events #check to see if any events have been triggered.
    
    if current_day < 7: #want to make this if the current day < 7 AND it is not the last day of the month.
        $ current_day += 1
        jump Art
    
    return
Maybe:

Code: Select all

    if calendar.game_day % 7 != 0 and not calendar.last_day_of_the_month:
        jump Art
This code will make sure that game jumps to Art as long as it is not last day of the month and it's not 7th, 14th, 23rd etc. day since player has started the game.

============
Having said that:
To make sure I always return from a weekly activity if it's the last day of the month:
if calendar.last_day_of_the_month:
jump (or call) Month_Report

Code: Select all

    if current_day < 7: #want to make this if the current day < 7 AND it is not the last day of the month.
        $ current_day += 1
        jump Art
I do not understand this code, bigger than 7 of what? Maybe you've meant something like:

Code: Select all

if calendar.weekday != "Sunday":
    ...
? So every 7th day of the week, you get to pick something again (this should not be in Art label than, should be in the control label).
Sorry for the confusion! I made a counter called "current_day" and I set the original variable in a different part of the code. Basically, it goes up one every time the player goes through this event and doesn't let them go more than 7 times.

I have a calendar that allows the player to choose one event for each week of the month. "Art" is one of the activities they can choose, and I wanted to use this calendar to allow me to have the player go through all seven days of each weekly event.

So, they would choose Art, and then they would see "Sunday, Feb. 2" at the top. Then Ren'Py checks to see if they've triggered any events, and depending on their "art" stat they get a different message. Like, maybe on Monday they aren't doing well, but by Friday their art stat has raised and the little text changes. I haven't added stats yet, but that's my intention.

The player chooses all four weeks at the beginning of the month, and then the game flows from one week into the next without stopping. So, they choose "art" "farm" "explore" "rest"-- the calendar goes through a week of art, a week of farming, a week of exploring, and a week of rest.

I hope that makes sense? But since the last week might roll into the next month without finishing a seven day week, I needed to add the part where if you hit the end of the month it just goes to the next activity.

In any case, now that you've added calendar.last_day_of_the_month I think I can do this! :D

xela wrote:
daikiraikimi wrote: And in the event checker:

Code: Select all

label check_events:
    
    "This function checks to see if any events have been triggered."
    # if it is September 30th:
    # jump Harvest_Festival
    
    # if moon_phase = "full moon":
    # insanity += 5
    
    return
Very easy to understand what you want here:

Code: Select all

if calendar.moonphase == "full moon":
    $ insanity += 5

Code: Select all

if calendar.month == "September" and calendar.day == 30:
    jump Harvest_Festival
daikiraikimi wrote:I'm using 6.16.5 which was released in December... Is there a newer version I don't know of? This one is already awesome, especially since RAPT is rolled into it.
Yeap, but still only on the release channel.
Thanks! I just wasn't sure how I was supposed to use the variables, but I understand it better now.

And that makes sense-- I'm not using the pre-release version.
Image

Image
Image

Post Reply

Who is online

Users browsing this forum: Google [Bot]