seanohue / fantasy-time-crunch

A way of handling time and time-related state changes in a highly customizable way, for use with games and virtual worlds
8 stars 6 forks source link

accessing unit states from returned object #5

Open ratacat opened 4 years ago

ratacat commented 4 years ago

Here's my current config, it seems like this.states.is('winter') isn't working from the returned object.

"use strict"
const TimeCrunch = require("~bundles/timecrunch/lib/TimeCrunch")
const { Logger } = require("ranvier")

module.exports = {
    listeners: {
        startup: state => function () {
            const config = {
                // One and only one unit is the smallest measured subdivision of time, defined as a 'tick'
                minute: {
                    tick: true,
                    makes: { hour: 60 },
                },

                // Optionally one can define a function to be called when
                // a unit increments (having a bell toll, etc.)
                hour: {
                    makes: { day: 24 },
                    onIncrement() {
                        state.GameServer.emit("gamehour",this.time)
                    },
                    // Units can be divided into multiple state changes. For example, a day has two or more states defined
                    // by how many hours have passed.
                    // 'states' can be an object or a function.
                    // In this case, dawn and dusk are different depending
                    // on the season
                    states() {
                        if (this.states.is("winter")) {
                            return {
                                day: 9, // 0900 -- by default this number represents hours. however, each property returned can also be a function that has access to any time unit.
                                night: 20, // 2000
                            }
                        }
                        return {
                            day: 6, // 0900
                            night: 23, // 2200
                        }
                    }
                },
                day: {
                    makes() {
                        const days = this.time.month % 2 ? 31 : 30
                        return { month: days }
                    },
                    onIncrement() {
                        state.GameServer.emit("gameday",this.time)
                    },
                },
                month: {
                    // The 'of' property can also be a function called
                    // In this case, even months have 30 days and odd have 31.
                    makes: { year: 12 },

                    // For simpler state changes, an object marking the
                    // transitional thresholds is fine.
                    states: {
                        winter: 11,
                        spring: 3,
                        summer: 5,
                        fall: 9
                    },
                    onIncrement(){
                        state.GameServer.emit("gamemonth",this.time)
                    }
                },
                year: {
                    makes: {season: 50},
                    onIncrement(){
                        state.GameServer.emit("gameyear",this.time)
                    }
                }
            }

            state.TimeCrunch = new TimeCrunch(config)

            let sync = getSynchronize(Date.now())
            for (let [k,v] of Object.entries(sync)) {
                loadUnit.call(state.TimeCrunch,k,v)
            }

            setInterval(function () {
                state.GameServer.emit("gameminute")
            }, 1250)

        },
        gameminute: state => () => {
            let obj = state.TimeCrunch.tick("minute",1)
            for (let [name,area] of state.AreaManager.areas){
                area.emit("gameminute",obj)
            }
        },
        gamehour: state => function(time){
            for (let [name,area] of state.AreaManager.areas){
                area.emit("gamehour",time)
            }
        },
        gameday: state => function(time){
            for (let [name,area] of state.AreaManager.areas){
                area.emit("gameday",time)
            }
        },
        gamemonth: state => function(time){
            for (let [name,area] of state.AreaManager.areas){
                area.emit("gamemonth",time)
            }
        },
        gameyear: state => function(time){
            for (let [name,area] of state.AreaManager.areas){
                area.emit("gameyear",time)
            }
        }
    }
}

function loadUnit(id, amount){
    this.time[id] = amount
}

function getSynchronize(datetime){
    let yfloat = (datetime * 48) / 31536000000
    let ywhole = Math.floor(yfloat)
    let yremainder = yfloat - ywhole

    let mfloat = yremainder * 12
    let mwhole = Math.floor(mfloat)
    let mremainder = mfloat - mwhole

    let dfloat = mremainder * 30
    let dwhole = Math.floor(dfloat)
    let dremainder = dfloat - dwhole

    let hfloat = dremainder * 24
    let hwhole = Math.floor(hfloat)
    let hremainder = hfloat - hwhole

    let ifloat = hremainder * 60
    let iwhole = Math.floor(ifloat)
    let iremainder = ifloat - iwhole

    return {minute: iwhole, hour: hwhole, day: dwhole, month: mwhole, year: ywhole - 2000}
}