├── src └── main │ ├── resources │ ├── version.properties │ ├── assets │ │ └── sereneseasons │ │ │ ├── models │ │ │ ├── item │ │ │ │ ├── greenhouse_glass.json │ │ │ │ ├── season_sensor_autumn.json │ │ │ │ ├── season_sensor_spring.json │ │ │ │ ├── season_sensor_summer.json │ │ │ │ ├── season_sensor_winter.json │ │ │ │ ├── ss_icon.json │ │ │ │ ├── season_clock_00.json │ │ │ │ ├── season_clock_01.json │ │ │ │ ├── season_clock_02.json │ │ │ │ ├── season_clock_03.json │ │ │ │ ├── season_clock_04.json │ │ │ │ ├── season_clock_05.json │ │ │ │ ├── season_clock_06.json │ │ │ │ ├── season_clock_07.json │ │ │ │ ├── season_clock_08.json │ │ │ │ ├── season_clock_09.json │ │ │ │ ├── season_clock_10.json │ │ │ │ ├── season_clock_11.json │ │ │ │ ├── season_clock_12.json │ │ │ │ ├── season_clock_13.json │ │ │ │ ├── season_clock_14.json │ │ │ │ ├── season_clock_15.json │ │ │ │ ├── season_clock_16.json │ │ │ │ ├── season_clock_17.json │ │ │ │ ├── season_clock_18.json │ │ │ │ ├── season_clock_19.json │ │ │ │ ├── season_clock_20.json │ │ │ │ ├── season_clock_21.json │ │ │ │ ├── season_clock_22.json │ │ │ │ ├── season_clock_23.json │ │ │ │ ├── season_clock_24.json │ │ │ │ ├── season_clock_25.json │ │ │ │ ├── season_clock_26.json │ │ │ │ ├── season_clock_27.json │ │ │ │ ├── season_clock_28.json │ │ │ │ ├── season_clock_29.json │ │ │ │ ├── season_clock_30.json │ │ │ │ ├── season_clock_31.json │ │ │ │ ├── season_clock_32.json │ │ │ │ ├── season_clock_33.json │ │ │ │ ├── season_clock_34.json │ │ │ │ ├── season_clock_35.json │ │ │ │ ├── season_clock_36.json │ │ │ │ ├── season_clock_37.json │ │ │ │ ├── season_clock_38.json │ │ │ │ ├── season_clock_39.json │ │ │ │ ├── season_clock_40.json │ │ │ │ ├── season_clock_41.json │ │ │ │ ├── season_clock_42.json │ │ │ │ ├── season_clock_43.json │ │ │ │ ├── season_clock_44.json │ │ │ │ ├── season_clock_45.json │ │ │ │ ├── season_clock_46.json │ │ │ │ ├── season_clock_47.json │ │ │ │ ├── season_clock_48.json │ │ │ │ ├── season_clock_49.json │ │ │ │ ├── season_clock_50.json │ │ │ │ ├── season_clock_51.json │ │ │ │ ├── season_clock_52.json │ │ │ │ ├── season_clock_53.json │ │ │ │ ├── season_clock_54.json │ │ │ │ ├── season_clock_55.json │ │ │ │ ├── season_clock_56.json │ │ │ │ ├── season_clock_57.json │ │ │ │ ├── season_clock_58.json │ │ │ │ ├── season_clock_59.json │ │ │ │ ├── season_clock_60.json │ │ │ │ ├── season_clock_61.json │ │ │ │ ├── season_clock_62.json │ │ │ │ ├── season_clock_63.json │ │ │ │ └── season_clock.json │ │ │ └── block │ │ │ │ ├── greenhouse_glass.json │ │ │ │ ├── season_sensor_autumn.json │ │ │ │ ├── season_sensor_spring.json │ │ │ │ ├── season_sensor_summer.json │ │ │ │ └── season_sensor_winter.json │ │ │ ├── blockstates │ │ │ ├── greenhouse_glass.json │ │ │ ├── season_sensor_autumn.json │ │ │ ├── season_sensor_spring.json │ │ │ ├── season_sensor_summer.json │ │ │ └── season_sensor_winter.json │ │ │ ├── textures │ │ │ ├── gui │ │ │ │ └── logo.png │ │ │ ├── items │ │ │ │ ├── ss_icon.png │ │ │ │ ├── season_clock_00.png │ │ │ │ ├── season_clock_01.png │ │ │ │ ├── season_clock_02.png │ │ │ │ ├── season_clock_03.png │ │ │ │ ├── season_clock_04.png │ │ │ │ ├── season_clock_05.png │ │ │ │ ├── season_clock_06.png │ │ │ │ ├── season_clock_07.png │ │ │ │ ├── season_clock_08.png │ │ │ │ ├── season_clock_09.png │ │ │ │ ├── season_clock_10.png │ │ │ │ ├── season_clock_11.png │ │ │ │ ├── season_clock_12.png │ │ │ │ ├── season_clock_13.png │ │ │ │ ├── season_clock_14.png │ │ │ │ ├── season_clock_15.png │ │ │ │ ├── season_clock_16.png │ │ │ │ ├── season_clock_17.png │ │ │ │ ├── season_clock_18.png │ │ │ │ ├── season_clock_19.png │ │ │ │ ├── season_clock_20.png │ │ │ │ ├── season_clock_21.png │ │ │ │ ├── season_clock_22.png │ │ │ │ ├── season_clock_23.png │ │ │ │ ├── season_clock_24.png │ │ │ │ ├── season_clock_25.png │ │ │ │ ├── season_clock_26.png │ │ │ │ ├── season_clock_27.png │ │ │ │ ├── season_clock_28.png │ │ │ │ ├── season_clock_29.png │ │ │ │ ├── season_clock_30.png │ │ │ │ ├── season_clock_31.png │ │ │ │ ├── season_clock_32.png │ │ │ │ ├── season_clock_33.png │ │ │ │ ├── season_clock_34.png │ │ │ │ ├── season_clock_35.png │ │ │ │ ├── season_clock_36.png │ │ │ │ ├── season_clock_37.png │ │ │ │ ├── season_clock_38.png │ │ │ │ ├── season_clock_39.png │ │ │ │ ├── season_clock_40.png │ │ │ │ ├── season_clock_41.png │ │ │ │ ├── season_clock_42.png │ │ │ │ ├── season_clock_43.png │ │ │ │ ├── season_clock_44.png │ │ │ │ ├── season_clock_45.png │ │ │ │ ├── season_clock_46.png │ │ │ │ ├── season_clock_47.png │ │ │ │ ├── season_clock_48.png │ │ │ │ ├── season_clock_49.png │ │ │ │ ├── season_clock_50.png │ │ │ │ ├── season_clock_51.png │ │ │ │ ├── season_clock_52.png │ │ │ │ ├── season_clock_53.png │ │ │ │ ├── season_clock_54.png │ │ │ │ ├── season_clock_55.png │ │ │ │ ├── season_clock_56.png │ │ │ │ ├── season_clock_57.png │ │ │ │ ├── season_clock_58.png │ │ │ │ ├── season_clock_59.png │ │ │ │ ├── season_clock_60.png │ │ │ │ ├── season_clock_61.png │ │ │ │ ├── season_clock_62.png │ │ │ │ └── season_clock_63.png │ │ │ └── blocks │ │ │ │ ├── greenhouse_glass.png │ │ │ │ ├── season_sensor_side.png │ │ │ │ ├── season_sensor_autumn_top.png │ │ │ │ ├── season_sensor_spring_top.png │ │ │ │ ├── season_sensor_summer_top.png │ │ │ │ └── season_sensor_winter_top.png │ │ │ ├── recipes │ │ │ ├── season_clock.json │ │ │ ├── greenhouse_glass.json │ │ │ └── season_sensor.json │ │ │ ├── lang │ │ │ ├── zh_CN.lang │ │ │ ├── de_DE.lang │ │ │ ├── en_US.lang │ │ │ ├── ru_RU.lang │ │ │ ├── pl_PL.lang │ │ │ ├── es_ES.lang │ │ │ ├── fr_FR.lang │ │ │ ├── it_IT.lang │ │ │ └── pt_BR.lang │ │ │ └── advancements │ │ │ └── recipes │ │ │ ├── redstone │ │ │ └── season_sensor.json │ │ │ ├── tools │ │ │ └── season_clock.json │ │ │ └── buildingBlocks │ │ │ └── greenhouse_glass.json │ ├── pack.mcmeta │ ├── mcmod.info │ └── META-INF │ │ └── sereneseasons_at.cfg │ └── java │ └── sereneseasons │ ├── api │ ├── SSBlocks.java │ ├── ISSBlock.java │ ├── config │ │ ├── ISyncedOption.java │ │ ├── SeasonsOption.java │ │ └── SyncedConfig.java │ ├── SSItems.java │ └── season │ │ ├── ISeasonColorProvider.java │ │ ├── SeasonHelper.java │ │ ├── BiomeHooks.java │ │ ├── WorldHooks.java │ │ ├── ISeasonState.java │ │ └── Season.java │ ├── core │ ├── CommonProxy.java │ ├── SereneSeasons.java │ └── ClientProxy.java │ ├── season │ ├── ISeasonedWorld.java │ ├── SeasonSavedData.java │ └── SeasonTime.java │ ├── handler │ ├── PacketHandler.java │ └── season │ │ ├── SeasonSleepHandler.java │ │ ├── BirchColorHandler.java │ │ ├── SeasonalCropGrowthHandler.java │ │ ├── RandomUpdateHandler.java │ │ └── SeasonHandler.java │ ├── tileentity │ └── TileEntitySeasonSensor.java │ ├── config │ ├── json │ │ └── BiomeData.java │ ├── ConfigHandler.java │ ├── SeasonsConfig.java │ └── BiomeConfig.java │ ├── asm │ ├── SSLoadingPlugin.java │ ├── ObfHelper.java │ └── ASMHelper.java │ ├── init │ ├── ModItems.java │ ├── ModConfig.java │ ├── ModHandlers.java │ ├── ModBlocks.java │ └── ModFertility.java │ ├── util │ ├── inventory │ │ └── CreativeTabSS.java │ ├── config │ │ └── JsonUtil.java │ ├── SeasonColourUtil.java │ └── BlockStateUtils.java │ ├── network │ └── message │ │ ├── MessageSyncSeasonCycle.java │ │ └── MessageSyncConfigs.java │ ├── item │ ├── ItemSSBlock.java │ └── ItemSeasonClock.java │ ├── block │ ├── BlockGreenhouseGlass.java │ └── BlockSeasonSensor.java │ └── command │ └── SSCommand.java ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .gitignore ├── README.md ├── gradlew.bat └── gradlew /src/main/resources/version.properties: -------------------------------------------------------------------------------- 1 | ${modid}.version=${mod_version} 2 | ${modid}.build_number=${build_number} -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/greenhouse_glass.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "sereneseasons:block/greenhouse_glass" 3 | } 4 | -------------------------------------------------------------------------------- /src/main/resources/pack.mcmeta: -------------------------------------------------------------------------------- 1 | { 2 | "pack": { 3 | "pack_format": 2, 4 | "description": "Resources used for Serene Seasons" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_sensor_autumn.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "sereneseasons:block/season_sensor_autumn" 3 | } 4 | 5 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_sensor_spring.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "sereneseasons:block/season_sensor_spring" 3 | } 4 | 5 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_sensor_summer.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "sereneseasons:block/season_sensor_summer" 3 | } 4 | 5 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_sensor_winter.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "sereneseasons:block/season_sensor_winter" 3 | } 4 | 5 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/blockstates/greenhouse_glass.json: -------------------------------------------------------------------------------- 1 | { 2 | "variants": { 3 | "normal": { "model": "sereneseasons:greenhouse_glass" } 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/gui/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/gui/logo.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/blockstates/season_sensor_autumn.json: -------------------------------------------------------------------------------- 1 | { 2 | "variants": { 3 | "normal": { "model": "sereneseasons:season_sensor_autumn" } 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/blockstates/season_sensor_spring.json: -------------------------------------------------------------------------------- 1 | { 2 | "variants": { 3 | "normal": { "model": "sereneseasons:season_sensor_spring" } 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/blockstates/season_sensor_summer.json: -------------------------------------------------------------------------------- 1 | { 2 | "variants": { 3 | "normal": { "model": "sereneseasons:season_sensor_summer" } 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/blockstates/season_sensor_winter.json: -------------------------------------------------------------------------------- 1 | { 2 | "variants": { 3 | "normal": { "model": "sereneseasons:season_sensor_winter" } 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/ss_icon.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/ss_icon" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/ss_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/ss_icon.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/block/greenhouse_glass.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "block/cube_all", 3 | "textures": { 4 | "all": "sereneseasons:blocks/greenhouse_glass" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_00.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_00" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_01.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_01" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_02.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_02" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_03.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_03" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_04.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_04" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_05.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_05" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_06.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_06" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_07.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_07" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_08.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_08" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_09.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_09" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_10.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_10" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_11.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_11" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_12.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_12" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_13.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_13" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_14.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_14" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_15.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_15" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_16.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_16" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_17.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_17" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_18.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_18" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_19.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_19" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_20.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_20" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_21.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_21" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_22.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_22" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_23.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_23" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_24.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_24" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_25.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_25" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_26.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_26" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_27.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_27" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_28.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_28" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_29.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_29" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_30.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_30" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_31.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_31" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_32.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_32" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_33.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_33" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_34.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_34" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_35.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_35" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_36.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_36" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_37.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_37" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_38.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_38" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_39.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_39" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_40.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_40" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_41.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_41" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_42.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_42" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_43.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_43" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_44.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_44" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_45.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_45" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_46.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_46" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_47.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_47" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_48.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_48" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_49.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_49" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_50.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_50" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_51.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_51" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_52.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_52" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_53.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_53" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_54.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_54" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_55.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_55" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_56.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_56" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_57.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_57" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_58.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_58" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_59.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_59" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_60.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_60" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_61.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_61" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_62.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_62" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock_63.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_63" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_00.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_00.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_01.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_02.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_03.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_04.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_05.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_06.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_06.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_07.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_07.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_08.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_08.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_09.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_09.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_10.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_11.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_12.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_13.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_14.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_15.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_16.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_17.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_18.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_19.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_20.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_21.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_22.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_22.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_23.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_23.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_24.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_25.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_26.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_26.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_27.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_27.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_28.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_28.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_29.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_29.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_30.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_30.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_31.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_31.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_32.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_33.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_33.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_34.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_34.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_35.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_35.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_36.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_37.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_37.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_38.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_38.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_39.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_39.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_40.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_41.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_41.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_42.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_42.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_43.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_43.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_44.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_44.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_45.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_45.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_46.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_46.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_47.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_47.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_48.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_49.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_49.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_50.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_51.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_51.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_52.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_52.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_53.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_53.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_54.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_54.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_55.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_55.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_56.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_56.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_57.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_58.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_58.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_59.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_59.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_60.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_61.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_61.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_62.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_62.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/items/season_clock_63.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/items/season_clock_63.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/blocks/greenhouse_glass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/blocks/greenhouse_glass.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/blocks/season_sensor_side.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/blocks/season_sensor_side.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/blocks/season_sensor_autumn_top.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/blocks/season_sensor_autumn_top.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/blocks/season_sensor_spring_top.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/blocks/season_sensor_spring_top.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/blocks/season_sensor_summer_top.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/blocks/season_sensor_summer_top.png -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/textures/blocks/season_sensor_winter_top.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DarkShadow44/SereneSeasons/HEAD/src/main/resources/assets/sereneseasons/textures/blocks/season_sensor_winter_top.png -------------------------------------------------------------------------------- /src/main/java/sereneseasons/api/SSBlocks.java: -------------------------------------------------------------------------------- 1 | package sereneseasons.api; 2 | 3 | import net.minecraft.block.Block; 4 | 5 | public class SSBlocks 6 | { 7 | public static Block greenhouse_glass; 8 | 9 | public static Block[] season_sensors = new Block[4]; 10 | } 11 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Thu Nov 17 11:57:30 EST 2016 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.9-bin.zip 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /build/ 2 | /bin/ 3 | /out/ 4 | /repo/ 5 | /run/ 6 | .idea/* 7 | /.gradle/ 8 | /.settings/ 9 | /.classpath 10 | /.project 11 | 12 | # OS generated files 13 | *.DS_Store 14 | 15 | # IntelliJ project files 16 | *.iml 17 | *.ipr 18 | *.iws 19 | src/main/resources/META-INF/biomesoplenty_at.cfg 20 | *.launch 21 | -------------------------------------------------------------------------------- /src/main/resources/mcmod.info: -------------------------------------------------------------------------------- 1 | [{ 2 | "modid": "sereneseasons", 3 | "name": "Serene Seasons", 4 | "description": "Adds seasons with changing colors, temperature shifting, and more!", 5 | "version": "${mod_version}", 6 | "mcversion": "${minecraft_version}", 7 | "authorList": ["Adubbz", "Forstride"], 8 | "logoFile": "assets/sereneseasons/textures/gui/logo.png" 9 | }] 10 | -------------------------------------------------------------------------------- /src/main/java/sereneseasons/core/CommonProxy.java: -------------------------------------------------------------------------------- 1 | package sereneseasons.core; 2 | 3 | import net.minecraft.block.Block; 4 | import net.minecraft.item.Item; 5 | 6 | public class CommonProxy 7 | { 8 | public void registerRenderers() {} 9 | public void registerItemVariantModel(Item item, String name, int metadata) {} 10 | public void registerBlockSided(Block block) {} 11 | public void registerItemSided(Item item) {} 12 | } -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/recipes/season_clock.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "forge:ore_shaped", 3 | "pattern": [ 4 | " # ", 5 | "#R#", 6 | " # " 7 | ], 8 | "key": { 9 | "#": { 10 | "type": "forge:ore_dict", 11 | "ore": "gemQuartz" 12 | }, 13 | "R": { 14 | "type": "forge:ore_dict", 15 | "ore": "dustRedstone" 16 | } 17 | }, 18 | "result": { 19 | "item": "sereneseasons:season_clock" 20 | } 21 | } -------------------------------------------------------------------------------- /src/main/java/sereneseasons/api/ISSBlock.java: -------------------------------------------------------------------------------- 1 | package sereneseasons.api; 2 | 3 | import net.minecraft.block.properties.IProperty; 4 | import net.minecraft.block.state.IBlockState; 5 | import net.minecraft.item.ItemBlock; 6 | 7 | public interface ISSBlock { 8 | 9 | public Class getItemClass(); 10 | public IProperty[] getPresetProperties(); 11 | public IProperty[] getNonRenderingProperties(); 12 | public String getStateName(IBlockState state); 13 | 14 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | **Serene Seasons** is a **Minecraft mod** that adds **seasons** with **changing colors, temperature shifting, and more!** 4 | 5 | ----------------- 6 | 7 | [](http://creativecommons.org/licenses/by-nc-nd/4.0/deed.en_US) 8 | 9 | Serene Seasons is licensed under a [Creative Commons Attribution-NonCommercial-NoDerivs 4.0 Unported License](http://creativecommons.org/licenses/by-nc-nd/4.0/deed.en_US). 10 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/recipes/greenhouse_glass.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "forge:ore_shaped", 3 | "pattern": [ 4 | "#G#", 5 | "GWG", 6 | "#G#" 7 | ], 8 | "key": { 9 | "#": { 10 | "type": "forge:ore_dict", 11 | "ore": "dyeCyan" 12 | }, 13 | "W": { 14 | "type": "forge:ore_dict", 15 | "ore": "plankWood" 16 | }, 17 | "G": { 18 | "type": "forge:ore_dict", 19 | "ore": "blockGlass" 20 | } 21 | }, 22 | "result": { 23 | "item": "sereneseasons:greenhouse_glass", 24 | "data": 0 25 | } 26 | } -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/lang/zh_CN.lang: -------------------------------------------------------------------------------- 1 | commands.sereneseasons.usage=/sereneseasons [季节] 2 | commands.sereneseasons.setseason.success=已将季节设置为:%s 3 | commands.sereneseasons.setseason.fail=无效的季节参数:%s 4 | commands.sereneseasons.setseason.disabled=季节变化当前已禁用! 5 | 6 | itemGroup.tabSereneSeasons=静谧四季 7 | 8 | tile.greenhouse_glass.name=温室玻璃 9 | tile.season_sensor_spring.name=季节传感器(春) 10 | tile.season_sensor_summer.name=季节传感器(夏) 11 | tile.season_sensor_autumn.name=季节传感器(秋) 12 | tile.season_sensor_winter.name=季节传感器(冬) 13 | item.ss_icon.name=静谧四季图标 14 | 15 | item.season_clock.name=季节指示仪 16 | -------------------------------------------------------------------------------- /src/main/java/sereneseasons/api/config/ISyncedOption.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2016, the Biomes O' Plenty Team 3 | * 4 | * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Public License. 5 | * 6 | * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/. 7 | ******************************************************************************/ 8 | package sereneseasons.api.config; 9 | 10 | public interface ISyncedOption 11 | { 12 | String getOptionName(); 13 | } 14 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/recipes/season_sensor.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "forge:ore_shaped", 3 | "pattern": [ 4 | "GGG", 5 | "QSQ", 6 | "###" 7 | ], 8 | "key": { 9 | "#": { 10 | "item": "minecraft:stone_slab", 11 | "data": 3 12 | }, 13 | "S": { 14 | "item": "sereneseasons:season_clock" 15 | }, 16 | "Q": { 17 | "type": "forge:ore_dict", 18 | "ore": "gemQuartz" 19 | }, 20 | "G": { 21 | "type": "forge:ore_dict", 22 | "ore": "blockGlass" 23 | } 24 | }, 25 | "result": { 26 | "item": "sereneseasons:season_sensor_spring", 27 | "data": 0 28 | } 29 | } -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/lang/de_DE.lang: -------------------------------------------------------------------------------- 1 | commands.sereneseasons.setseason.success=Jahreszeit auf %s gesetzt 2 | commands.sereneseasons.setseason.fail=Ungültige Jahreszeit %s 3 | commands.sereneseasons.setseason.disabled=Jahreszeiten sind aktuell deaktiviert! 4 | 5 | itemGroup.tabSereneSeasons=Serene Seasons 6 | 7 | tile.greenhouse_glass.name=Gewächshausglas 8 | tile.season_sensor_spring.name=Jahreszeitensensor 9 | tile.season_sensor_summer.name=Jahreszeitensensor 10 | tile.season_sensor_autumn.name=Jahreszeitensensor 11 | tile.season_sensor_winter.name=Jahreszeitensensor 12 | item.ss_icon.name=SS-Icon 13 | 14 | item.season_clock.name=Jahreszeitenuhr 15 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/lang/en_US.lang: -------------------------------------------------------------------------------- 1 | commands.sereneseasons.usage=/sereneseasons [args] 2 | commands.sereneseasons.setseason.success=Set season to %s 3 | commands.sereneseasons.setseason.fail=Invalid season %s 4 | commands.sereneseasons.setseason.disabled=Seasons are currently disabled! 5 | 6 | itemGroup.tabSereneSeasons=Serene Seasons 7 | 8 | tile.greenhouse_glass.name=Greenhouse Glass 9 | tile.season_sensor_spring.name=Season Sensor 10 | tile.season_sensor_summer.name=Season Sensor 11 | tile.season_sensor_autumn.name=Season Sensor 12 | tile.season_sensor_winter.name=Season Sensor 13 | item.ss_icon.name=SS Icon 14 | 15 | item.season_clock.name=Season Clock -------------------------------------------------------------------------------- /src/main/java/sereneseasons/api/SSItems.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2014-2017, the Biomes O' Plenty Team 3 | * 4 | * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Public License. 5 | * 6 | * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/. 7 | ******************************************************************************/ 8 | package sereneseasons.api; 9 | 10 | import net.minecraft.item.Item; 11 | 12 | public class SSItems 13 | { 14 | public static Item season_clock; 15 | public static Item ss_icon; 16 | } 17 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/lang/ru_RU.lang: -------------------------------------------------------------------------------- 1 | commands.sereneseasons.usage=/sereneseasons [args] 2 | commands.sereneseasons.setseason.success=Установить сезон на %s 3 | commands.sereneseasons.setseason.fail=Неверный сезон %s 4 | commands.sereneseasons.setseason.disabled=Сезоны в настоящее время отключены! 5 | 6 | itemGroup.tabSereneSeasons=Serene Seasons 7 | 8 | tile.greenhouse_glass.name=Тепличное стекло 9 | tile.season_sensor_spring.name=Сезонный датчик 10 | tile.season_sensor_summer.name=Сезонный датчик 11 | tile.season_sensor_autumn.name=Сезонный датчик 12 | tile.season_sensor_winter.name=Сезонный датчик 13 | item.ss_icon.name=СС иконка 14 | 15 | item.season_clock.name=Сезонные часы 16 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/lang/pl_PL.lang: -------------------------------------------------------------------------------- 1 | commands.sereneseasons.usage=/sereneseasons [args] 2 | commands.sereneseasons.setseason.success=Ustawiono porę roku na %s 3 | commands.sereneseasons.setseason.fail=Nieprawidłowa pora roku %s 4 | commands.sereneseasons.setseason.disabled=Pory roku są obecnie wyłączone! 5 | 6 | itemGroup.tabSereneSeasons=Serene Seasons 7 | 8 | tile.greenhouse_glass.name=Szkło Szklarniowe 9 | tile.season_sensor_spring.name=Wiosenny Czujnik 10 | tile.season_sensor_summer.name=Letni Czujnik 11 | tile.season_sensor_autumn.name=Jesienny Czujnik 12 | tile.season_sensor_winter.name=Zimowy Czujnik 13 | item.ss_icon.name=SS Icon 14 | 15 | item.season_clock.name=egar Pór Roku 16 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/lang/es_ES.lang: -------------------------------------------------------------------------------- 1 | commands.sereneseasons.usage=/sereneseasons [args] 2 | commands.sereneseasons.setseason.success=Estación establecida a %s 3 | commands.sereneseasons.setseason.fail=Estación inválida %s 4 | commands.sereneseasons.setseason.disabled=Las estaciones se encuentran deshabilitadas! 5 | 6 | itemGroup.tabSereneSeasons=Serene Seasons 7 | 8 | tile.greenhouse_glass.name=Cristal de invernadero 9 | tile.season_sensor_spring.name=Sensor de estación 10 | tile.season_sensor_summer.name=Sensor de estación 11 | tile.season_sensor_autumn.name=Sensor de estación 12 | tile.season_sensor_winter.name=Sensor de estación 13 | item.ss_icon.name=Icono SS 14 | 15 | item.season_clock.name=Reloj de estaciones -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/advancements/recipes/redstone/season_sensor.json: -------------------------------------------------------------------------------- 1 | { 2 | "rewards": { 3 | "recipes": [ 4 | "sereneseasons:season_sensor" 5 | ] 6 | }, 7 | "criteria": { 8 | "has_the_recipe": { 9 | "trigger": "minecraft:recipe_unlocked", 10 | "conditions": { 11 | "recipe": "sereneseasons:season_sensor" 12 | } 13 | }, 14 | "has_quartz": { 15 | "trigger": "minecraft:inventory_changed", 16 | "conditions": { 17 | "items": [ 18 | { 19 | "item": "minecraft:quartz" 20 | } 21 | ] 22 | } 23 | } 24 | }, 25 | "requirements": [ 26 | [ 27 | "has_the_recipe", 28 | "has_quartz" 29 | ] 30 | ] 31 | } -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/advancements/recipes/tools/season_clock.json: -------------------------------------------------------------------------------- 1 | { 2 | "rewards": { 3 | "recipes": [ 4 | "sereneseasons:season_clock" 5 | ] 6 | }, 7 | "criteria": { 8 | "has_redstone": { 9 | "trigger": "minecraft:inventory_changed", 10 | "conditions": { 11 | "items": [ 12 | { 13 | "item": "minecraft:redstone" 14 | } 15 | ] 16 | } 17 | }, 18 | "has_the_recipe": { 19 | "trigger": "minecraft:recipe_unlocked", 20 | "conditions": { 21 | "recipe": "sereneseasons:season_clock" 22 | } 23 | } 24 | }, 25 | "requirements": [ 26 | [ 27 | "has_redstone", 28 | "has_the_recipe" 29 | ] 30 | ] 31 | } -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/lang/fr_FR.lang: -------------------------------------------------------------------------------- 1 | commands.sereneseasons.usage=/sereneseasons [arguments] 2 | commands.sereneseasons.setseason.success=La saison a été définie à %s 3 | commands.sereneseasons.setseason.fail=La saison %s est invalide 4 | commands.sereneseasons.setseason.disabled=Les saisons sont actuellement désactivées ! 5 | 6 | itemGroup.tabSereneSeasons=Serene Seasons 7 | 8 | tile.greenhouse_glass.name=Verre de serre 9 | tile.season_sensor_spring.name=Capteur de saison 10 | tile.season_sensor_summer.name=Capteur de saison 11 | tile.season_sensor_autumn.name=Capteur de saison 12 | tile.season_sensor_winter.name=Capteur de saison 13 | item.ss_icon.name=Icône SS 14 | 15 | item.season_clock.name=Horloge de saison 16 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/lang/it_IT.lang: -------------------------------------------------------------------------------- 1 | commands.sereneseasons.usage=/sereneseasons [argomenti] 2 | commands.sereneseasons.setseason.success=Cambiata la stagione a %s 3 | commands.sereneseasons.setseason.fail=Stagione non valida %s 4 | commands.sereneseasons.setseason.disabled=Le stagioni sono attualmente disabilitate 5 | 6 | itemGroup.tabSereneSeasons=Serene Seasons 7 | 8 | tile.greenhouse_glass.name=Vetro per Serra 9 | tile.season_sensor_spring.name=Sensore Stagionale 10 | tile.season_sensor_summer.name=Sensore Stagionale 11 | tile.season_sensor_autumn.name=Sensore Stagionale 12 | tile.season_sensor_winter.name=Sensore Stagionale 13 | item.ss_icon.name=Icona SS 14 | 15 | item.season_clock.name=Orologio Stagionale 16 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/advancements/recipes/buildingBlocks/greenhouse_glass.json: -------------------------------------------------------------------------------- 1 | { 2 | "rewards": { 3 | "recipes": [ 4 | "sereneseasons:greenhouse_glass" 5 | ] 6 | }, 7 | "criteria": { 8 | "has_glass": { 9 | "trigger": "minecraft:inventory_changed", 10 | "conditions": { 11 | "items": [ 12 | { 13 | "item": "minecraft:glass" 14 | } 15 | ] 16 | } 17 | }, 18 | "has_the_recipe": { 19 | "trigger": "minecraft:recipe_unlocked", 20 | "conditions": { 21 | "recipe": "sereneseasons:greenhouse_glass" 22 | } 23 | } 24 | }, 25 | "requirements": [ 26 | [ 27 | "has_glass", 28 | "has_the_recipe" 29 | ] 30 | ] 31 | } -------------------------------------------------------------------------------- /src/main/resources/META-INF/sereneseasons_at.cfg: -------------------------------------------------------------------------------- 1 | #Season colouring 2 | public-f net.minecraft.world.biome.BiomeColorHelper field_180291_a #GRASS_COLOR 3 | public-f net.minecraft.world.biome.BiomeColorHelper field_180289_b #FOLIAGE_COLOR 4 | public net.minecraft.world.biome.BiomeColorHelper$ColorResolver 5 | 6 | #Seasonal melting 7 | public net.minecraft.world.World field_73005_l #updateLCG 8 | public net.minecraft.block.BlockIce func_185679_b(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;)V 9 | 10 | #Seasonal freezing 11 | public net.minecraft.world.World func_175696_F(Lnet/minecraft/util/math/BlockPos;)Z #isWater 12 | 13 | public net.minecraft.item.crafting.ShapedRecipes func_192402_a([Ljava/lang/String;Ljava/util/Map;II)Lnet/minecraft/util/NonNullList; 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/lang/pt_BR.lang: -------------------------------------------------------------------------------- 1 | commands.sereneseasons.usage=/sereneseasons [argumentos] 2 | commands.sereneseasons.setseason.success=Estação do ano alterada para %s 3 | commands.sereneseasons.setseason.fail=A estação "%s" é inválida 4 | commands.sereneseasons.setseason.disabled=As estações do ano estão desativadas! 5 | 6 | itemGroup.tabSereneSeasons=Serene Seasons 7 | 8 | tile.greenhouse_glass.name=Vidro de estufa 9 | tile.season_sensor_spring.name=Sensor de estações do ano 10 | tile.season_sensor_summer.name=Sensor de estações do ano 11 | tile.season_sensor_autumn.name=Sensor de estações do ano 12 | tile.season_sensor_winter.name=Sensor de estações do ano 13 | item.ss_icon.name=Ícone do SS 14 | 15 | item.season_clock.name=Relógio de estações do ano 16 | -------------------------------------------------------------------------------- /src/main/java/sereneseasons/api/season/ISeasonColorProvider.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2014-2017, the Biomes O' Plenty Team 3 | * 4 | * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Public License. 5 | * 6 | * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/. 7 | ******************************************************************************/ 8 | package sereneseasons.api.season; 9 | 10 | public interface ISeasonColorProvider 11 | { 12 | int getGrassOverlay(); 13 | float getGrassSaturationMultiplier(); 14 | int getFoliageOverlay(); 15 | float getFoliageSaturationMultiplier(); 16 | int getBirchColor(); 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/sereneseasons/season/ISeasonedWorld.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2016, the Biomes O' Plenty Team 3 | * 4 | * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Public License. 5 | * 6 | * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/. 7 | ******************************************************************************/ 8 | package sereneseasons.season; 9 | 10 | import net.minecraft.util.math.BlockPos; 11 | import sereneseasons.api.season.Season; 12 | 13 | /** Now with extra seasoning*/ 14 | public interface ISeasonedWorld 15 | { 16 | boolean canSnowAtInSeason(BlockPos pos, boolean checkLight, Season season); 17 | boolean canBlockFreezeInSeason(BlockPos pos, boolean noWaterAdj, Season season); 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/sereneseasons/handler/PacketHandler.java: -------------------------------------------------------------------------------- 1 | package sereneseasons.handler; 2 | 3 | import net.minecraftforge.fml.common.network.NetworkRegistry; 4 | import net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper; 5 | import net.minecraftforge.fml.relauncher.Side; 6 | import sereneseasons.core.SereneSeasons; 7 | import sereneseasons.network.message.MessageSyncConfigs; 8 | import sereneseasons.network.message.MessageSyncSeasonCycle; 9 | 10 | public class PacketHandler 11 | { 12 | public static final SimpleNetworkWrapper instance = NetworkRegistry.INSTANCE.newSimpleChannel(SereneSeasons.MOD_ID); 13 | 14 | public static void init() 15 | { 16 | instance.registerMessage(MessageSyncSeasonCycle.class, MessageSyncSeasonCycle.class, 3, Side.CLIENT); 17 | instance.registerMessage(MessageSyncConfigs.class, MessageSyncConfigs.class, 4, Side.CLIENT); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/block/season_sensor_autumn.json: -------------------------------------------------------------------------------- 1 | { "parent": "block/thin_block", 2 | "textures": { 3 | "particle": "sereneseasons:blocks/season_sensor_autumn_top", 4 | "top": "sereneseasons:blocks/season_sensor_autumn_top", 5 | "side": "sereneseasons:blocks/season_sensor_side" 6 | }, 7 | "elements": [ 8 | { "from": [ 0, 0, 0 ], 9 | "to": [ 16, 6, 16 ], 10 | "faces": { 11 | "down": { "uv": [ 0, 0, 16, 16 ], "texture": "#side", "cullface": "down" }, 12 | "up": { "uv": [ 0, 0, 16, 16 ], "texture": "#top" }, 13 | "north": { "uv": [ 0, 10, 16, 16 ], "texture": "#side", "cullface": "north" }, 14 | "south": { "uv": [ 0, 10, 16, 16 ], "texture": "#side", "cullface": "south" }, 15 | "west": { "uv": [ 0, 10, 16, 16 ], "texture": "#side", "cullface": "west" }, 16 | "east": { "uv": [ 0, 10, 16, 16 ], "texture": "#side", "cullface": "east" } 17 | } 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/block/season_sensor_spring.json: -------------------------------------------------------------------------------- 1 | { "parent": "block/thin_block", 2 | "textures": { 3 | "particle": "sereneseasons:blocks/season_sensor_spring_top", 4 | "top": "sereneseasons:blocks/season_sensor_spring_top", 5 | "side": "sereneseasons:blocks/season_sensor_side" 6 | }, 7 | "elements": [ 8 | { "from": [ 0, 0, 0 ], 9 | "to": [ 16, 6, 16 ], 10 | "faces": { 11 | "down": { "uv": [ 0, 0, 16, 16 ], "texture": "#side", "cullface": "down" }, 12 | "up": { "uv": [ 0, 0, 16, 16 ], "texture": "#top" }, 13 | "north": { "uv": [ 0, 10, 16, 16 ], "texture": "#side", "cullface": "north" }, 14 | "south": { "uv": [ 0, 10, 16, 16 ], "texture": "#side", "cullface": "south" }, 15 | "west": { "uv": [ 0, 10, 16, 16 ], "texture": "#side", "cullface": "west" }, 16 | "east": { "uv": [ 0, 10, 16, 16 ], "texture": "#side", "cullface": "east" } 17 | } 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/block/season_sensor_summer.json: -------------------------------------------------------------------------------- 1 | { "parent": "block/thin_block", 2 | "textures": { 3 | "particle": "sereneseasons:blocks/season_sensor_summer_top", 4 | "top": "sereneseasons:blocks/season_sensor_summer_top", 5 | "side": "sereneseasons:blocks/season_sensor_side" 6 | }, 7 | "elements": [ 8 | { "from": [ 0, 0, 0 ], 9 | "to": [ 16, 6, 16 ], 10 | "faces": { 11 | "down": { "uv": [ 0, 0, 16, 16 ], "texture": "#side", "cullface": "down" }, 12 | "up": { "uv": [ 0, 0, 16, 16 ], "texture": "#top" }, 13 | "north": { "uv": [ 0, 10, 16, 16 ], "texture": "#side", "cullface": "north" }, 14 | "south": { "uv": [ 0, 10, 16, 16 ], "texture": "#side", "cullface": "south" }, 15 | "west": { "uv": [ 0, 10, 16, 16 ], "texture": "#side", "cullface": "west" }, 16 | "east": { "uv": [ 0, 10, 16, 16 ], "texture": "#side", "cullface": "east" } 17 | } 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/block/season_sensor_winter.json: -------------------------------------------------------------------------------- 1 | { "parent": "block/thin_block", 2 | "textures": { 3 | "particle": "sereneseasons:blocks/season_sensor_winter_top", 4 | "top": "sereneseasons:blocks/season_sensor_winter_top", 5 | "side": "sereneseasons:blocks/season_sensor_side" 6 | }, 7 | "elements": [ 8 | { "from": [ 0, 0, 0 ], 9 | "to": [ 16, 6, 16 ], 10 | "faces": { 11 | "down": { "uv": [ 0, 0, 16, 16 ], "texture": "#side", "cullface": "down" }, 12 | "up": { "uv": [ 0, 0, 16, 16 ], "texture": "#top" }, 13 | "north": { "uv": [ 0, 10, 16, 16 ], "texture": "#side", "cullface": "north" }, 14 | "south": { "uv": [ 0, 10, 16, 16 ], "texture": "#side", "cullface": "south" }, 15 | "west": { "uv": [ 0, 10, 16, 16 ], "texture": "#side", "cullface": "west" }, 16 | "east": { "uv": [ 0, 10, 16, 16 ], "texture": "#side", "cullface": "east" } 17 | } 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/sereneseasons/api/config/SeasonsOption.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2014-2017, the Biomes O' Plenty Team 3 | * 4 | * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Public License. 5 | * 6 | * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/. 7 | ******************************************************************************/ 8 | package sereneseasons.api.config; 9 | 10 | public enum SeasonsOption implements ISyncedOption 11 | { 12 | DAY_DURATION("Day Duration"), 13 | SUB_SEASON_DURATION("Sub Season Duration"), 14 | STARTING_SUB_SEASON("Starting Sub Season"), 15 | PROGRESS_SEASON_WHILE_OFFLINE("Progress Season While Offline"); 16 | 17 | private final String optionName; 18 | 19 | SeasonsOption(String name) 20 | { 21 | this.optionName = name; 22 | } 23 | 24 | @Override 25 | public String getOptionName() 26 | { 27 | return this.optionName; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/sereneseasons/tileentity/TileEntitySeasonSensor.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2016, the Biomes O' Plenty Team 3 | * 4 | * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Public License. 5 | * 6 | * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/. 7 | ******************************************************************************/ 8 | package sereneseasons.tileentity; 9 | 10 | import net.minecraft.tileentity.TileEntity; 11 | import net.minecraft.util.ITickable; 12 | import sereneseasons.api.season.SeasonHelper; 13 | import sereneseasons.block.BlockSeasonSensor; 14 | 15 | public class TileEntitySeasonSensor extends TileEntity implements ITickable 16 | { 17 | @Override 18 | public void update() 19 | { 20 | if (this.world != null && !this.world.isRemote && SeasonHelper.getSeasonState(this.world).getSeasonCycleTicks() % 20L == 0L) 21 | { 22 | ((BlockSeasonSensor)this.getBlockType()).updatePower(this.world, this.pos); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/sereneseasons/config/json/BiomeData.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2014-2017, the Biomes O' Plenty Team 3 | * 4 | * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Public License. 5 | * 6 | * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/. 7 | ******************************************************************************/ 8 | package sereneseasons.config.json; 9 | 10 | import com.google.gson.annotations.SerializedName; 11 | 12 | public class BiomeData 13 | { 14 | @SerializedName("enable_seasonal_effects") 15 | public boolean enableSeasonalEffects; 16 | 17 | @SerializedName("use_tropical_seasons") 18 | public boolean useTropicalSeasons; 19 | 20 | @SerializedName("disable_crops") 21 | public boolean disableCrops; 22 | 23 | public BiomeData(boolean enableSeasonalEffects, boolean useTropicalSeasons, boolean disableCrops) 24 | { 25 | this.enableSeasonalEffects = enableSeasonalEffects; 26 | this.useTropicalSeasons = useTropicalSeasons; 27 | this.disableCrops = disableCrops; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/sereneseasons/asm/SSLoadingPlugin.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2016, the Biomes O' Plenty Team 3 | * 4 | * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Public License. 5 | * 6 | * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/. 7 | ******************************************************************************/ 8 | package sereneseasons.asm; 9 | 10 | import java.util.Map; 11 | 12 | import net.minecraftforge.fml.relauncher.IFMLLoadingPlugin; 13 | 14 | public class SSLoadingPlugin implements IFMLLoadingPlugin 15 | { 16 | @Override 17 | public String[] getASMTransformerClass() 18 | { 19 | return new String[] { "sereneseasons.asm.transformer.EntityRendererTransformer", "sereneseasons.asm.transformer.WorldTransformer" }; 20 | } 21 | 22 | @Override 23 | public String getModContainerClass() 24 | { 25 | return null; 26 | } 27 | 28 | @Override 29 | public String getSetupClass() 30 | { 31 | return null; 32 | } 33 | 34 | @Override 35 | public void injectData(Map data) 36 | { 37 | } 38 | 39 | @Override 40 | public String getAccessTransformerClass() 41 | { 42 | return null; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/sereneseasons/api/season/SeasonHelper.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2016, the Biomes O' Plenty Team 3 | * 4 | * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Public License. 5 | * 6 | * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/. 7 | ******************************************************************************/ 8 | package sereneseasons.api.season; 9 | 10 | import net.minecraft.world.World; 11 | import sereneseasons.init.ModConfig; 12 | 13 | public class SeasonHelper 14 | { 15 | public static ISeasonDataProvider dataProvider; 16 | 17 | /** 18 | * Obtains data about the state of the season cycle in the world. This works both on 19 | * the client and the server. 20 | */ 21 | public static ISeasonState getSeasonState(World world) 22 | { 23 | ISeasonState data; 24 | 25 | if (!world.isRemote) 26 | { 27 | data = dataProvider.getServerSeasonState(world); 28 | } 29 | else 30 | { 31 | data = dataProvider.getClientSeasonState(); 32 | } 33 | 34 | return data; 35 | } 36 | 37 | public interface ISeasonDataProvider 38 | { 39 | ISeasonState getServerSeasonState(World world); 40 | ISeasonState getClientSeasonState(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/sereneseasons/api/season/BiomeHooks.java: -------------------------------------------------------------------------------- 1 | package sereneseasons.api.season; 2 | 3 | import net.minecraft.util.math.BlockPos; 4 | import net.minecraft.world.World; 5 | import net.minecraft.world.biome.Biome; 6 | 7 | public class BiomeHooks 8 | { 9 | /** 10 | * An override of {@link Biome#getFloatTemperature(BlockPos)} 11 | */ 12 | public static float getFloatTemperature(World world, Biome biome, BlockPos pos) 13 | { 14 | try 15 | { 16 | return (float)Class.forName("sereneseasons.season.SeasonASMHelper").getMethod("getFloatTemperature", World.class, Biome.class, BlockPos.class).invoke(null, world, biome, pos); 17 | } 18 | catch (Exception e) 19 | { 20 | throw new RuntimeException("An error occurred calling getFloatTemperature", e); 21 | } 22 | } 23 | 24 | /** 25 | * An override of {@link Biome#getFloatTemperature(BlockPos)} 26 | */ 27 | public static float getFloatTemperature(Season.SubSeason subSeason, Biome biome, BlockPos pos) 28 | { 29 | try 30 | { 31 | return (float)Class.forName("sereneseasons.season.SeasonASMHelper").getMethod("getFloatTemperature", Season.SubSeason.class, Biome.class, BlockPos.class).invoke(null, subSeason, biome, pos); 32 | } 33 | catch (Exception e) 34 | { 35 | throw new RuntimeException("An error occurred calling getFloatTemperature", e); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/sereneseasons/season/SeasonSavedData.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2016, the Biomes O' Plenty Team 3 | * 4 | * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Public License. 5 | * 6 | * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/. 7 | ******************************************************************************/ 8 | package sereneseasons.season; 9 | 10 | import net.minecraft.nbt.NBTTagCompound; 11 | import net.minecraft.world.storage.WorldSavedData; 12 | 13 | public class SeasonSavedData extends WorldSavedData 14 | { 15 | public static final String DATA_IDENTIFIER = "seasons"; 16 | 17 | public int seasonCycleTicks; 18 | 19 | public SeasonSavedData() 20 | { 21 | this(DATA_IDENTIFIER); 22 | } 23 | 24 | //This specific constructor is required for saving to occur 25 | public SeasonSavedData(String identifier) 26 | { 27 | super(identifier); 28 | } 29 | 30 | @Override 31 | public void readFromNBT(NBTTagCompound nbt) 32 | { 33 | this.seasonCycleTicks = nbt.getInteger("SeasonCycleTicks"); 34 | } 35 | 36 | @Override 37 | public NBTTagCompound writeToNBT(NBTTagCompound nbt) 38 | { 39 | nbt.setInteger("SeasonCycleTicks", this.seasonCycleTicks); 40 | 41 | return nbt; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/sereneseasons/api/config/SyncedConfig.java: -------------------------------------------------------------------------------- 1 | package sereneseasons.api.config; 2 | 3 | import com.google.common.collect.Maps; 4 | 5 | import java.util.Map; 6 | 7 | public class SyncedConfig 8 | { 9 | public static Map optionsToSync = Maps.newHashMap(); 10 | 11 | public static void addOption(ISyncedOption option, String defaultValue) 12 | { 13 | optionsToSync.put(option.getOptionName(), new SyncedConfigEntry(defaultValue)); 14 | } 15 | 16 | public static boolean getBooleanValue(ISyncedOption option) 17 | { 18 | return Boolean.valueOf(getValue(option)); 19 | } 20 | 21 | public static int getIntValue(ISyncedOption option) 22 | { 23 | return Integer.valueOf(getValue(option)); 24 | } 25 | 26 | public static String getValue(ISyncedOption option) 27 | { 28 | return optionsToSync.get(option.getOptionName()).value; 29 | } 30 | 31 | public static void restoreDefaults() 32 | { 33 | for (SyncedConfigEntry entry : optionsToSync.values()) 34 | { 35 | entry.value = entry.defaultValue; 36 | } 37 | } 38 | 39 | public static class SyncedConfigEntry 40 | { 41 | public String value; 42 | public final String defaultValue; 43 | 44 | public SyncedConfigEntry(String defaultValue) 45 | { 46 | this.defaultValue = defaultValue; 47 | this.value = defaultValue; 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/sereneseasons/asm/ObfHelper.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2016, the Biomes O' Plenty Team 3 | * 4 | * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Public License. 5 | * 6 | * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/. 7 | ******************************************************************************/ 8 | package sereneseasons.asm; 9 | 10 | import net.minecraftforge.fml.common.asm.transformers.deobf.FMLDeobfuscatingRemapper; 11 | 12 | public class ObfHelper 13 | { 14 | public static String createMethodDescriptor(boolean obfuscated, String returnType, String... types) 15 | { 16 | String result = "("; 17 | 18 | for (String type : types) 19 | { 20 | if (type.length() == 1) result += type; 21 | else 22 | { 23 | result += "L" + (obfuscated ? FMLDeobfuscatingRemapper.INSTANCE.unmap(type) : type) + ";"; 24 | } 25 | } 26 | 27 | if (returnType.length() > 1) 28 | { 29 | returnType = "L" + unmapType(obfuscated, returnType) + ";"; 30 | } 31 | 32 | result += ")" + returnType; 33 | 34 | return result; 35 | } 36 | 37 | public static String unmapType(boolean obfuscated, String type) 38 | { 39 | return obfuscated ? FMLDeobfuscatingRemapper.INSTANCE.unmap(type) : type; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/sereneseasons/init/ModItems.java: -------------------------------------------------------------------------------- 1 | package sereneseasons.init; 2 | 3 | import net.minecraft.creativetab.CreativeTabs; 4 | import net.minecraft.item.Item; 5 | import net.minecraft.util.ResourceLocation; 6 | import net.minecraftforge.fml.common.registry.ForgeRegistries; 7 | import sereneseasons.core.SereneSeasons; 8 | import sereneseasons.item.ItemSeasonClock; 9 | import sereneseasons.util.inventory.CreativeTabSS; 10 | 11 | import static sereneseasons.api.SSItems.*; 12 | 13 | public class ModItems 14 | { 15 | public static void init() 16 | { 17 | registerItems(); 18 | //setupModels(); 19 | } 20 | 21 | public static void registerItems() 22 | { 23 | // SS Creative Tab Icon 24 | ss_icon = registerItem(new Item(), "ss_icon"); 25 | ss_icon.setCreativeTab(null); 26 | 27 | // Main Items 28 | season_clock = registerItem(new ItemSeasonClock(), "season_clock"); 29 | } 30 | 31 | public static Item registerItem(Item item, String name) 32 | { 33 | return registerItem(item, name, CreativeTabSS.instance); 34 | } 35 | 36 | public static Item registerItem(Item item, String name, CreativeTabs tab) 37 | { 38 | item.setUnlocalizedName(name); 39 | if (tab != null) 40 | { 41 | item.setCreativeTab(CreativeTabSS.instance); 42 | } 43 | 44 | item.setRegistryName(new ResourceLocation(SereneSeasons.MOD_ID, name)); 45 | ForgeRegistries.ITEMS.register(item); 46 | SereneSeasons.proxy.registerItemSided(item); 47 | 48 | return item; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/sereneseasons/util/inventory/CreativeTabSS.java: -------------------------------------------------------------------------------- 1 | package sereneseasons.util.inventory; 2 | 3 | import net.minecraft.creativetab.CreativeTabs; 4 | import net.minecraft.entity.EntityList; 5 | import net.minecraft.init.Items; 6 | import net.minecraft.item.ItemMonsterPlacer; 7 | import net.minecraft.item.ItemStack; 8 | import net.minecraft.util.NonNullList; 9 | import net.minecraftforge.fml.relauncher.Side; 10 | import net.minecraftforge.fml.relauncher.SideOnly; 11 | import sereneseasons.api.SSItems; 12 | import sereneseasons.core.SereneSeasons; 13 | 14 | public class CreativeTabSS extends CreativeTabs 15 | { 16 | public static final CreativeTabs instance = new CreativeTabSS(CreativeTabs.getNextID(), "tabSereneSeasons"); 17 | 18 | private CreativeTabSS(int index, String label) 19 | { 20 | super(index, label); 21 | } 22 | 23 | @Override 24 | public ItemStack getTabIconItem() 25 | { 26 | return new ItemStack(SSItems.ss_icon); 27 | } 28 | 29 | @Override 30 | @SideOnly(Side.CLIENT) 31 | public void displayAllRelevantItems(NonNullList itemList) 32 | { 33 | super.displayAllRelevantItems(itemList); 34 | for (EntityList.EntityEggInfo eggInfo : EntityList.ENTITY_EGGS.values()) 35 | { 36 | if (eggInfo.spawnedID.getResourceDomain().equals(SereneSeasons.MOD_ID)) 37 | { 38 | ItemStack itemstack = new ItemStack(Items.SPAWN_EGG, 1); 39 | ItemMonsterPlacer.applyEntityIdToItemStack(itemstack, eggInfo.spawnedID); 40 | itemList.add(itemstack); 41 | } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/sereneseasons/init/ModConfig.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2014-2017, the Biomes O' Plenty Team 3 | * 4 | * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Public License. 5 | * 6 | * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/. 7 | ******************************************************************************/ 8 | package sereneseasons.init; 9 | 10 | import com.google.common.collect.Lists; 11 | import com.google.common.collect.Maps; 12 | import com.google.gson.reflect.TypeToken; 13 | import net.minecraft.util.ResourceLocation; 14 | import net.minecraftforge.fml.common.registry.ForgeRegistries; 15 | import sereneseasons.config.BiomeConfig; 16 | import sereneseasons.config.ConfigHandler; 17 | import sereneseasons.config.SeasonsConfig; 18 | import sereneseasons.config.json.BiomeData; 19 | import sereneseasons.core.SereneSeasons; 20 | import sereneseasons.util.SeasonColourUtil; 21 | import sereneseasons.util.config.JsonUtil; 22 | 23 | import java.io.File; 24 | import java.util.ArrayList; 25 | import java.util.List; 26 | import java.util.Map; 27 | 28 | public class ModConfig 29 | { 30 | public static List configHandlers = Lists.newArrayList(); 31 | 32 | public static SeasonsConfig seasons; 33 | 34 | public static void preInit(File configDir) 35 | { 36 | seasons = new SeasonsConfig(new File(configDir, "seasons.cfg")); 37 | } 38 | 39 | public static void init(File configDir) 40 | { 41 | BiomeConfig.init(configDir); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/sereneseasons/handler/season/SeasonSleepHandler.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2016, the Biomes O' Plenty Team 3 | * 4 | * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Public License. 5 | * 6 | * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/. 7 | ******************************************************************************/ 8 | package sereneseasons.handler.season; 9 | 10 | import net.minecraft.world.WorldServer; 11 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 12 | import net.minecraftforge.fml.common.gameevent.TickEvent; 13 | import net.minecraftforge.fml.common.gameevent.TickEvent.Phase; 14 | import net.minecraftforge.fml.relauncher.Side; 15 | import sereneseasons.api.config.SeasonsOption; 16 | import sereneseasons.api.config.SyncedConfig; 17 | import sereneseasons.season.SeasonSavedData; 18 | 19 | public class SeasonSleepHandler 20 | { 21 | @SubscribeEvent 22 | public void onWorldTick(TickEvent.WorldTickEvent event) 23 | { 24 | if (event.phase == Phase.START && event.side == Side.SERVER) 25 | { 26 | WorldServer world = (WorldServer)event.world; 27 | 28 | //Called before all players are awoken for the next day 29 | if (world.areAllPlayersAsleep()) 30 | { 31 | SeasonSavedData seasonData = SeasonHandler.getSeasonSavedData(world); 32 | long timeDiff = 24000L - ((world.getWorldInfo().getWorldTime() + 24000L) % 24000L); 33 | seasonData.seasonCycleTicks += timeDiff; 34 | seasonData.markDirty(); 35 | SeasonHandler.sendSeasonUpdate(world); 36 | } 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/sereneseasons/util/config/JsonUtil.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2014-2017, the Biomes O' Plenty Team 3 | * 4 | * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Public License. 5 | * 6 | * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/. 7 | ******************************************************************************/ 8 | package sereneseasons.util.config; 9 | 10 | 11 | import com.google.gson.Gson; 12 | import com.google.gson.GsonBuilder; 13 | import org.apache.commons.io.FileUtils; 14 | import sereneseasons.core.SereneSeasons; 15 | 16 | import java.io.File; 17 | import java.lang.reflect.Type; 18 | 19 | public class JsonUtil 20 | { 21 | public static final Gson SERIALIZER = new GsonBuilder().setPrettyPrinting().create(); 22 | 23 | public static T getOrCreateConfigFile(File configDir, String configName, T defaults, Type type) 24 | { 25 | File configFile = new File(configDir, configName); 26 | 27 | //No config file, so create default config: 28 | if (!configFile.exists()) 29 | { 30 | writeFile(configFile, defaults); 31 | } 32 | 33 | try 34 | { 35 | return (T)SERIALIZER.fromJson(FileUtils.readFileToString(configFile), type); 36 | } 37 | catch (Exception e) 38 | { 39 | SereneSeasons.logger.error("Error parsing config from json: " + configFile.toString(), e); 40 | } 41 | 42 | return null; 43 | } 44 | 45 | protected static boolean writeFile(File outputFile, Object obj) 46 | { 47 | try 48 | { 49 | FileUtils.write(outputFile, SERIALIZER.toJson(obj)); 50 | return true; 51 | } 52 | catch (Exception e) 53 | { 54 | SereneSeasons.logger.error("Error writing config file " + outputFile.getAbsolutePath() + ": " + e.getMessage()); 55 | return false; 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/sereneseasons/api/season/WorldHooks.java: -------------------------------------------------------------------------------- 1 | package sereneseasons.api.season; 2 | 3 | import net.minecraft.util.math.BlockPos; 4 | import net.minecraft.world.World; 5 | 6 | public class WorldHooks 7 | { 8 | /** 9 | * An override of {@link World#canSnowAt(BlockPos, boolean)} 10 | */ 11 | public static boolean canSnowAtInSeason(World world, BlockPos pos, boolean checkLight, ISeasonState seasonState) 12 | { 13 | try 14 | { 15 | return (Boolean)Class.forName("sereneseasons.season.SeasonASMHelper").getMethod("canSnowAtInSeason", World.class, BlockPos.class, Boolean.class, ISeasonState.class).invoke(null, world, pos, checkLight, seasonState); 16 | } 17 | catch (Exception e) 18 | { 19 | throw new RuntimeException("An error occurred calling canSnowAtInSeason", e); 20 | } 21 | } 22 | 23 | /** 24 | * An override of {@link World#canBlockFreeze(BlockPos, boolean)} 25 | */ 26 | public static boolean canBlockFreezeInSeason(World world, BlockPos pos, boolean noWaterAdj, ISeasonState seasonState) 27 | { 28 | try 29 | { 30 | return (Boolean)Class.forName("sereneseasons.season.SeasonASMHelper").getMethod("canBlockFreezeInSeason", World.class, BlockPos.class, Boolean.class, ISeasonState.class).invoke(null, world, pos, noWaterAdj, seasonState); 31 | } 32 | catch (Exception e) 33 | { 34 | throw new RuntimeException("An error occurred calling canBlockFreezeInSeason", e); 35 | } 36 | } 37 | 38 | /** 39 | * An override of {@link World#isRainingAt(BlockPos)} 40 | */ 41 | public static boolean isRainingAtInSeason(World world, BlockPos pos, ISeasonState seasonState) 42 | { 43 | try 44 | { 45 | return (Boolean)Class.forName("sereneseasons.season.SeasonASMHelper").getMethod("isRainingAtInSeason", World.class, BlockPos.class, ISeasonState.class).invoke(null, world, pos, seasonState); 46 | } 47 | catch (Exception e) 48 | { 49 | throw new RuntimeException("An error occurred calling isRainingAtInSeason", e); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/sereneseasons/api/season/ISeasonState.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2016, the Biomes O' Plenty Team 3 | * 4 | * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Public License. 5 | * 6 | * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/. 7 | ******************************************************************************/ 8 | package sereneseasons.api.season; 9 | 10 | import sereneseasons.api.season.Season.SubSeason; 11 | 12 | public interface ISeasonState 13 | { 14 | /** 15 | * Get the duration of a single day. Normally this is 16 | * 24000 ticks. 17 | * 18 | * @return The duration in ticks 19 | */ 20 | int getDayDuration(); 21 | 22 | /** 23 | * Get the duration of a single sub season. 24 | * 25 | * @return The duration in ticks 26 | */ 27 | int getSubSeasonDuration(); 28 | 29 | /** 30 | * Get the duration of a single season. 31 | * 32 | * @return The duration in ticks 33 | */ 34 | int getSeasonDuration(); 35 | 36 | /** 37 | * Get the duration of an entire cycle (a 'year') 38 | * 39 | * @return The duration in ticks 40 | */ 41 | int getCycleDuration(); 42 | 43 | /** 44 | * The time elapsed in ticks for the current overall cycle. 45 | * A cycle can be considered equivalent to a year, and is comprised 46 | * of Summer, Autumn, Winter and Spring. 47 | * 48 | * @return The time in ticks 49 | */ 50 | int getSeasonCycleTicks(); 51 | 52 | /** 53 | * Get the number of days elapsed. 54 | * 55 | * @return The current day 56 | */ 57 | int getDay(); 58 | 59 | /** 60 | * Get the current sub season. 61 | * 62 | * @return The current sub season 63 | */ 64 | SubSeason getSubSeason(); 65 | 66 | /** 67 | * Get the current season. This method is 68 | * mainly for convenience. 69 | * 70 | * @return The current season 71 | */ 72 | Season getSeason(); 73 | 74 | /** 75 | * Get the current tropical season. This method is 76 | * mainly for convenience. 77 | * 78 | * @return The current tropical season 79 | */ 80 | Season.TropicalSeason getTropicalSeason(); 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/sereneseasons/network/message/MessageSyncSeasonCycle.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2016, the Biomes O' Plenty Team 3 | * 4 | * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Public License. 5 | * 6 | * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/. 7 | ******************************************************************************/ 8 | package sereneseasons.network.message; 9 | 10 | import io.netty.buffer.ByteBuf; 11 | import net.minecraft.client.Minecraft; 12 | import net.minecraftforge.fml.common.network.simpleimpl.IMessage; 13 | import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; 14 | import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; 15 | import net.minecraftforge.fml.relauncher.Side; 16 | import sereneseasons.handler.season.SeasonHandler; 17 | 18 | public class MessageSyncSeasonCycle implements IMessage, IMessageHandler 19 | { 20 | public int dimension; 21 | public int seasonCycleTicks; 22 | 23 | public MessageSyncSeasonCycle() {} 24 | 25 | public MessageSyncSeasonCycle(int dimension, int seasonCycleTicks) 26 | { 27 | this.dimension = dimension; 28 | this.seasonCycleTicks = seasonCycleTicks; 29 | } 30 | 31 | @Override 32 | public void fromBytes(ByteBuf buf) 33 | { 34 | this.dimension = buf.readInt(); 35 | this.seasonCycleTicks = buf.readInt(); 36 | } 37 | 38 | @Override 39 | public void toBytes(ByteBuf buf) 40 | { 41 | buf.writeInt(this.dimension); 42 | buf.writeInt(this.seasonCycleTicks); 43 | } 44 | 45 | @Override 46 | public IMessage onMessage(MessageSyncSeasonCycle message, MessageContext ctx) 47 | { 48 | if (ctx.side == Side.CLIENT) 49 | { 50 | if (Minecraft.getMinecraft().player == null) return null; 51 | int playerDimension = Minecraft.getMinecraft().player.dimension; 52 | 53 | if (playerDimension == message.dimension) 54 | SeasonHandler.clientSeasonCycleTicks.replace(playerDimension, message.seasonCycleTicks); 55 | } 56 | 57 | return null; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/sereneseasons/network/message/MessageSyncConfigs.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2016, the Biomes O' Plenty Team 3 | * 4 | * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Public License. 5 | * 6 | * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/. 7 | ******************************************************************************/ 8 | package sereneseasons.network.message; 9 | 10 | import io.netty.buffer.ByteBuf; 11 | import net.minecraft.nbt.NBTTagCompound; 12 | import net.minecraftforge.fml.common.network.ByteBufUtils; 13 | import net.minecraftforge.fml.common.network.simpleimpl.IMessage; 14 | import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler; 15 | import net.minecraftforge.fml.common.network.simpleimpl.MessageContext; 16 | import net.minecraftforge.fml.relauncher.Side; 17 | import sereneseasons.api.config.SyncedConfig; 18 | import sereneseasons.core.SereneSeasons; 19 | 20 | public class MessageSyncConfigs implements IMessage, IMessageHandler 21 | { 22 | public NBTTagCompound nbtOptions; 23 | 24 | public MessageSyncConfigs() {} 25 | 26 | public MessageSyncConfigs(NBTTagCompound nbtOptions) 27 | { 28 | this.nbtOptions = nbtOptions; 29 | } 30 | 31 | @Override 32 | public void fromBytes(ByteBuf buf) 33 | { 34 | this.nbtOptions = ByteBufUtils.readTag(buf); 35 | } 36 | 37 | @Override 38 | public void toBytes(ByteBuf buf) 39 | { 40 | ByteBufUtils.writeTag(buf, nbtOptions); 41 | } 42 | 43 | @Override 44 | public IMessage onMessage(MessageSyncConfigs message, MessageContext ctx) 45 | { 46 | if (ctx.side == Side.CLIENT) 47 | { 48 | for (String key : message.nbtOptions.getKeySet()) 49 | { 50 | SyncedConfig.SyncedConfigEntry entry = SyncedConfig.optionsToSync.get(key); 51 | 52 | if (entry == null) SereneSeasons.logger.error("Option " + key + " does not exist locally!"); 53 | 54 | entry.value = message.nbtOptions.getString(key); 55 | SereneSeasons.logger.info("SS configuration synchronized with the server"); 56 | } 57 | } 58 | 59 | return null; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/sereneseasons/core/SereneSeasons.java: -------------------------------------------------------------------------------- 1 | package sereneseasons.core; 2 | 3 | import java.io.File; 4 | 5 | import org.apache.logging.log4j.LogManager; 6 | import org.apache.logging.log4j.Logger; 7 | 8 | import net.minecraftforge.fml.common.Mod; 9 | import net.minecraftforge.fml.common.Mod.EventHandler; 10 | import net.minecraftforge.fml.common.Mod.Instance; 11 | import net.minecraftforge.fml.common.SidedProxy; 12 | import net.minecraftforge.fml.common.event.FMLInitializationEvent; 13 | import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; 14 | import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; 15 | import net.minecraftforge.fml.common.event.FMLServerStartingEvent; 16 | import sereneseasons.command.SSCommand; 17 | import sereneseasons.init.ModBlocks; 18 | import sereneseasons.init.ModConfig; 19 | import sereneseasons.init.ModFertility; 20 | import sereneseasons.init.ModHandlers; 21 | import sereneseasons.init.ModItems; 22 | 23 | @Mod(modid = SereneSeasons.MOD_ID, version = SereneSeasons.MOD_VERSION, name = SereneSeasons.MOD_NAME, dependencies = "required-after:forge@[1.0.0.0,)") 24 | public class SereneSeasons 25 | { 26 | public static final String MOD_NAME = "Serene Seasons"; 27 | public static final String MOD_ID = "sereneseasons"; 28 | public static final String MOD_VERSION = "@MOD_VERSION@"; 29 | 30 | @Instance(MOD_ID) 31 | public static SereneSeasons instance; 32 | 33 | @SidedProxy(clientSide = "sereneseasons.core.ClientProxy", serverSide = "sereneseasons.core.CommonProxy") 34 | public static CommonProxy proxy; 35 | 36 | public static Logger logger = LogManager.getLogger(MOD_ID); 37 | public static File configDirectory; 38 | 39 | @EventHandler 40 | public void preInit(FMLPreInitializationEvent event) 41 | { 42 | configDirectory = new File(event.getModConfigurationDirectory(), "sereneseasons"); 43 | 44 | ModConfig.preInit(configDirectory); 45 | ModBlocks.init(); 46 | ModItems.init(); 47 | ModHandlers.init(); 48 | 49 | proxy.registerRenderers(); 50 | } 51 | 52 | @EventHandler 53 | public void init(FMLInitializationEvent event) 54 | { 55 | ModConfig.init(configDirectory); 56 | } 57 | 58 | @EventHandler 59 | public void postInit(FMLPostInitializationEvent event) 60 | { 61 | ModFertility.init(); 62 | ModHandlers.postInit(); 63 | } 64 | 65 | @EventHandler 66 | public void serverStarting(FMLServerStartingEvent event) 67 | { 68 | event.registerServerCommand(new SSCommand()); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/sereneseasons/season/SeasonTime.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2016, the Biomes O' Plenty Team 3 | * 4 | * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Public License. 5 | * 6 | * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/. 7 | ******************************************************************************/ 8 | package sereneseasons.season; 9 | 10 | import com.google.common.base.Preconditions; 11 | import sereneseasons.api.config.SeasonsOption; 12 | import sereneseasons.api.config.SyncedConfig; 13 | import sereneseasons.api.season.ISeasonState; 14 | import sereneseasons.api.season.Season; 15 | 16 | public final class SeasonTime implements ISeasonState 17 | { 18 | public static final SeasonTime ZERO = new SeasonTime(0); 19 | public final int time; 20 | 21 | public SeasonTime(int time) 22 | { 23 | Preconditions.checkArgument(time >= 0, "Time cannot be negative!"); 24 | this.time = time; 25 | } 26 | 27 | @Override 28 | public int getDayDuration() 29 | { 30 | return SyncedConfig.getIntValue(SeasonsOption.DAY_DURATION); 31 | } 32 | 33 | @Override 34 | public int getSubSeasonDuration() 35 | { 36 | return getDayDuration() * SyncedConfig.getIntValue(SeasonsOption.SUB_SEASON_DURATION); 37 | } 38 | 39 | @Override 40 | public int getSeasonDuration() 41 | { 42 | return getSubSeasonDuration() * 3; 43 | } 44 | 45 | @Override 46 | public int getCycleDuration() 47 | { 48 | return getSubSeasonDuration() * Season.SubSeason.VALUES.length; 49 | } 50 | 51 | @Override 52 | public int getSeasonCycleTicks() 53 | { 54 | return this.time; 55 | } 56 | 57 | @Override 58 | public int getDay() 59 | { 60 | return this.time / getDayDuration(); 61 | } 62 | 63 | @Override 64 | public Season.SubSeason getSubSeason() 65 | { 66 | int index = (this.time / getSubSeasonDuration()) % Season.SubSeason.VALUES.length; 67 | return Season.SubSeason.VALUES[index]; 68 | } 69 | 70 | @Override 71 | public Season getSeason() 72 | { 73 | return this.getSubSeason().getSeason(); 74 | } 75 | 76 | @Override 77 | public Season.TropicalSeason getTropicalSeason() 78 | { 79 | int index = ((((this.time / getSubSeasonDuration()) + 11) / 2) + 5) % Season.TropicalSeason.VALUES.length; 80 | return Season.TropicalSeason.VALUES[index]; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /src/main/java/sereneseasons/item/ItemSSBlock.java: -------------------------------------------------------------------------------- 1 | package sereneseasons.item; 2 | 3 | import java.util.List; 4 | 5 | import com.google.common.collect.ImmutableSet; 6 | 7 | import net.minecraft.block.Block; 8 | import net.minecraft.block.state.IBlockState; 9 | import net.minecraft.creativetab.CreativeTabs; 10 | import net.minecraft.item.Item; 11 | import net.minecraft.item.ItemBlock; 12 | import net.minecraft.item.ItemStack; 13 | import net.minecraft.util.NonNullList; 14 | import net.minecraftforge.fml.relauncher.Side; 15 | import net.minecraftforge.fml.relauncher.SideOnly; 16 | import sereneseasons.api.ISSBlock; 17 | import sereneseasons.util.BlockStateUtils; 18 | 19 | public class ItemSSBlock extends ItemBlock 20 | { 21 | 22 | public ISSBlock tanBlock; 23 | 24 | public ItemSSBlock(Block block) 25 | { 26 | super(block); 27 | if (block instanceof ISSBlock) 28 | { 29 | this.tanBlock = (ISSBlock)block; 30 | } 31 | else 32 | { 33 | throw new IllegalArgumentException("ItemBOPBlock must be created with a block implementing IBOPBlock"); 34 | } 35 | this.setHasSubtypes(true); 36 | } 37 | 38 | // define the items which will appear in the creative tab (called by ItemBlock class) 39 | @Override 40 | @SideOnly(Side.CLIENT) 41 | public void getSubItems(CreativeTabs tab, NonNullList subItems) 42 | { 43 | if (this.isInCreativeTab(tab)) 44 | { 45 | ImmutableSet presets = BlockStateUtils.getBlockPresets(this.block); 46 | if (presets.isEmpty()) { 47 | subItems.add(new ItemStack(this.block, 1, 0)); 48 | } else { 49 | for (IBlockState state : presets) { 50 | subItems.add(new ItemStack(this.block, 1, this.block.getMetaFromState(state))); 51 | } 52 | } 53 | } 54 | } 55 | 56 | @Override 57 | public int getMetadata(int metadata) 58 | { 59 | return metadata; 60 | } 61 | 62 | @Override 63 | public String getUnlocalizedName(ItemStack stack) 64 | { 65 | ImmutableSet presets = BlockStateUtils.getBlockPresets(this.block); 66 | if (presets.isEmpty()) 67 | { 68 | return super.getUnlocalizedName(); 69 | } 70 | else 71 | { 72 | int meta = stack.getMetadata(); 73 | IBlockState oldState = block.getStateFromMeta(meta); 74 | IBlockState newState = BlockStateUtils.getPresetState(oldState); 75 | 76 | return super.getUnlocalizedName() + "." + tanBlock.getStateName(newState); 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/main/java/sereneseasons/block/BlockGreenhouseGlass.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2016, the Biomes O' Plenty Team 3 | * 4 | * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Public License. 5 | * 6 | * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/. 7 | ******************************************************************************/ 8 | package sereneseasons.block; 9 | 10 | import java.util.Random; 11 | 12 | import net.minecraft.block.BlockBreakable; 13 | import net.minecraft.block.SoundType; 14 | import net.minecraft.block.material.Material; 15 | import net.minecraft.block.properties.IProperty; 16 | import net.minecraft.block.state.IBlockState; 17 | import net.minecraft.item.ItemBlock; 18 | import net.minecraft.util.BlockRenderLayer; 19 | import net.minecraftforge.fml.relauncher.Side; 20 | import net.minecraftforge.fml.relauncher.SideOnly; 21 | import sereneseasons.api.ISSBlock; 22 | import sereneseasons.item.ItemSSBlock; 23 | 24 | public class BlockGreenhouseGlass extends BlockBreakable implements ISSBlock 25 | { 26 | // implement ISSBlock 27 | @Override 28 | public Class getItemClass() { return ItemSSBlock.class; } 29 | @Override 30 | public IProperty[] getPresetProperties() { return new IProperty[] {}; } 31 | @Override 32 | public IProperty[] getNonRenderingProperties() { return null; } 33 | @Override 34 | public String getStateName(IBlockState state) {return "";} 35 | 36 | public BlockGreenhouseGlass() 37 | { 38 | super(Material.GLASS, false); 39 | this.setHardness(0.3F); 40 | this.setHarvestLevel("pickaxe", 0); 41 | this.setSoundType(SoundType.GLASS); 42 | } 43 | 44 | /** 45 | * Returns the quantity of items to drop on block destruction. 46 | */ 47 | @Override 48 | public int quantityDropped(Random random) 49 | { 50 | return 0; 51 | } 52 | 53 | /** 54 | * Gets the render layer this block will render on. SOLID for solid blocks, CUTOUT or CUTOUT_MIPPED for on-off 55 | * transparency (glass, reeds), TRANSLUCENT for fully blended transparency (stained glass) 56 | */ 57 | @Override 58 | @SideOnly(Side.CLIENT) 59 | public BlockRenderLayer getBlockLayer() 60 | { 61 | return BlockRenderLayer.TRANSLUCENT; 62 | } 63 | 64 | @Override 65 | public boolean isFullCube(IBlockState state) 66 | { 67 | return false; 68 | } 69 | 70 | @Override 71 | protected boolean canSilkHarvest() 72 | { 73 | return true; 74 | } 75 | 76 | } -------------------------------------------------------------------------------- /src/main/java/sereneseasons/handler/season/BirchColorHandler.java: -------------------------------------------------------------------------------- 1 | package sereneseasons.handler.season; 2 | 3 | import javax.annotation.Nullable; 4 | 5 | import net.minecraft.block.BlockOldLeaf; 6 | import net.minecraft.block.BlockPlanks; 7 | import net.minecraft.block.state.IBlockState; 8 | import net.minecraft.client.Minecraft; 9 | import net.minecraft.client.renderer.color.IBlockColor; 10 | import net.minecraft.init.Blocks; 11 | import net.minecraft.util.math.BlockPos; 12 | import net.minecraft.world.ColorizerFoliage; 13 | import net.minecraft.world.IBlockAccess; 14 | import net.minecraft.world.biome.Biome; 15 | import net.minecraft.world.biome.BiomeColorHelper; 16 | import sereneseasons.api.season.ISeasonColorProvider; 17 | import sereneseasons.config.BiomeConfig; 18 | import sereneseasons.config.SeasonsConfig; 19 | import sereneseasons.init.ModConfig; 20 | import sereneseasons.season.SeasonTime; 21 | 22 | public class BirchColorHandler 23 | { 24 | public static void init() 25 | { 26 | Minecraft.getMinecraft().getBlockColors().registerBlockColorHandler(new IBlockColor() 27 | { 28 | public int colorMultiplier(IBlockState state, @Nullable IBlockAccess worldIn, @Nullable BlockPos pos, int tintIndex) 29 | { 30 | BlockPlanks.EnumType plankstype = (BlockPlanks.EnumType)state.getValue(BlockOldLeaf.VARIANT); 31 | 32 | if (plankstype == BlockPlanks.EnumType.SPRUCE) 33 | { 34 | return ColorizerFoliage.getFoliageColorPine(); 35 | } 36 | else if (plankstype == BlockPlanks.EnumType.BIRCH) 37 | { 38 | int birchColor = ColorizerFoliage.getFoliageColorBirch(); 39 | int dimension = Minecraft.getMinecraft().player.dimension; 40 | 41 | if (worldIn != null && pos != null && ModConfig.seasons.changeBirchColour && SeasonsConfig.isDimensionWhitelisted(dimension)) 42 | { 43 | Biome biome = worldIn.getBiome(pos); 44 | 45 | if (BiomeConfig.enablesSeasonalEffects(biome)) 46 | { 47 | SeasonTime calendar = SeasonHandler.getClientSeasonTime(); 48 | ISeasonColorProvider colorProvider = BiomeConfig.usesTropicalSeasons(biome) ? calendar.getTropicalSeason() : calendar.getSubSeason(); 49 | birchColor = colorProvider.getBirchColor(); 50 | } 51 | } 52 | 53 | return birchColor; 54 | } 55 | else 56 | { 57 | return worldIn != null && pos != null ? BiomeColorHelper.getFoliageColorAtPos(worldIn, pos) : ColorizerFoliage.getFoliageColorBasic(); 58 | } 59 | } 60 | }, Blocks.LEAVES); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/sereneseasons/config/ConfigHandler.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2014-2017, the Biomes O' Plenty Team 3 | * 4 | * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Public License. 5 | * 6 | * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/. 7 | ******************************************************************************/ 8 | package sereneseasons.config; 9 | 10 | import net.minecraftforge.common.MinecraftForge; 11 | import net.minecraftforge.common.config.Configuration; 12 | import net.minecraftforge.fml.client.event.ConfigChangedEvent; 13 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 14 | import sereneseasons.api.config.ISyncedOption; 15 | import sereneseasons.api.config.SyncedConfig; 16 | import sereneseasons.core.SereneSeasons; 17 | import sereneseasons.init.ModConfig; 18 | 19 | import java.io.File; 20 | 21 | public abstract class ConfigHandler 22 | { 23 | public Configuration config; 24 | public final String description; 25 | 26 | protected ConfigHandler(File configFile, String description) 27 | { 28 | config = new Configuration(configFile); 29 | loadConfiguration(); 30 | 31 | MinecraftForge.EVENT_BUS.register(this); 32 | this.description = description; 33 | ModConfig.configHandlers.add(this); 34 | } 35 | 36 | protected abstract void loadConfiguration(); 37 | 38 | protected void addSyncedValue(ISyncedOption option, T defaultValue, String category, String comment, T... args) 39 | { 40 | String value = ""; 41 | 42 | if (defaultValue instanceof String) 43 | { 44 | value = config.getString(option.getOptionName(), category, defaultValue.toString(), comment); 45 | } 46 | else if (defaultValue instanceof Integer) 47 | { 48 | value = "" + config.getInt(option.getOptionName(), category, (Integer)defaultValue, (Integer)args[0], (Integer)args[1], comment); 49 | } 50 | else if (defaultValue instanceof Boolean) 51 | { 52 | value = "" + config.getBoolean(option.getOptionName(), category, (Boolean)defaultValue, comment); 53 | } 54 | else if (defaultValue instanceof Float) 55 | { 56 | value = "" + config.getFloat(option.getOptionName(), category, (Float)defaultValue, (Float)args[0], (Float)args[1], comment); 57 | } 58 | 59 | SyncedConfig.addOption(option, value); 60 | } 61 | 62 | @SubscribeEvent 63 | public void onConfigurationChangedEvent(ConfigChangedEvent.OnConfigChangedEvent event) 64 | { 65 | if (event.getModID().equalsIgnoreCase(SereneSeasons.MOD_ID)) 66 | { 67 | loadConfiguration(); 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/sereneseasons/handler/season/SeasonalCropGrowthHandler.java: -------------------------------------------------------------------------------- 1 | package sereneseasons.handler.season; 2 | 3 | import net.minecraft.block.Block; 4 | import net.minecraft.block.BlockCocoa; 5 | import net.minecraft.block.BlockGrass; 6 | import net.minecraft.block.BlockReed; 7 | import net.minecraft.block.BlockSapling; 8 | import net.minecraft.util.math.BlockPos; 9 | import net.minecraft.world.World; 10 | import net.minecraftforge.event.entity.player.BonemealEvent; 11 | import net.minecraftforge.event.entity.player.ItemTooltipEvent; 12 | import net.minecraftforge.event.world.BlockEvent; 13 | import net.minecraftforge.fml.common.eventhandler.Event; 14 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 15 | import net.minecraftforge.fml.relauncher.Side; 16 | import net.minecraftforge.fml.relauncher.SideOnly; 17 | import sereneseasons.api.SSBlocks; 18 | import sereneseasons.config.FertilityConfig; 19 | import sereneseasons.init.ModFertility; 20 | 21 | public class SeasonalCropGrowthHandler 22 | { 23 | @SubscribeEvent 24 | @SideOnly(Side.CLIENT) 25 | public void onItemTooltipAdded(ItemTooltipEvent event) 26 | { 27 | ModFertility.setupTooltips(event); 28 | } 29 | 30 | @SubscribeEvent 31 | public void onCropGrowth(BlockEvent.CropGrowEvent event) 32 | { 33 | Block plant = event.getState().getBlock(); 34 | boolean isFertile = ModFertility.isCropFertile(plant.getRegistryName().toString(), event.getWorld(), event.getPos()); 35 | 36 | if (FertilityConfig.general_category.seasonal_crops && !isFertile && !isGreenhouseGlassAboveBlock(event.getWorld(), event.getPos())) 37 | { 38 | if (FertilityConfig.general_category.crops_break && !(plant instanceof BlockGrass) && !(plant instanceof BlockReed)) 39 | { 40 | event.getWorld().destroyBlock(event.getPos(), true); 41 | } 42 | else 43 | { 44 | event.setResult(Event.Result.DENY); 45 | } 46 | } 47 | } 48 | 49 | @SubscribeEvent 50 | public void onApplyBonemeal(BonemealEvent event) 51 | { 52 | Block plant = event.getBlock().getBlock(); 53 | boolean isFertile = ModFertility.isCropFertile(plant.getRegistryName().toString(), event.getWorld(), event.getPos()); 54 | 55 | if (FertilityConfig.general_category.seasonal_crops && !isFertile && !isGreenhouseGlassAboveBlock(event.getWorld(), event.getPos())) 56 | { 57 | if (FertilityConfig.general_category.crops_break && !(plant instanceof BlockGrass) && !(plant instanceof BlockReed)) 58 | { 59 | event.getWorld().destroyBlock(event.getPos(), true); 60 | } 61 | 62 | event.setCanceled(true); 63 | } 64 | } 65 | 66 | private boolean isGreenhouseGlassAboveBlock(World world, BlockPos cropPos) 67 | { 68 | for (int i = 0; i < FertilityConfig.general_category.greenhouse_glass_max_height; i++) 69 | { 70 | if (world.getBlockState(cropPos.add(0, i + 1, 0)).getBlock().equals(SSBlocks.greenhouse_glass)) 71 | { 72 | return true; 73 | } 74 | } 75 | 76 | return false; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/main/java/sereneseasons/command/SSCommand.java: -------------------------------------------------------------------------------- 1 | package sereneseasons.command; 2 | 3 | import com.google.common.collect.Lists; 4 | import net.minecraft.command.CommandBase; 5 | import net.minecraft.command.CommandException; 6 | import net.minecraft.command.ICommandSender; 7 | import net.minecraft.command.WrongUsageException; 8 | import net.minecraft.entity.player.EntityPlayerMP; 9 | import net.minecraft.server.MinecraftServer; 10 | import net.minecraft.util.math.BlockPos; 11 | import net.minecraft.util.text.TextComponentTranslation; 12 | import sereneseasons.api.config.SeasonsOption; 13 | import sereneseasons.api.config.SyncedConfig; 14 | import sereneseasons.api.season.Season; 15 | import sereneseasons.handler.season.SeasonHandler; 16 | import sereneseasons.season.SeasonSavedData; 17 | import sereneseasons.season.SeasonTime; 18 | 19 | import java.util.List; 20 | 21 | public class SSCommand extends CommandBase 22 | { 23 | @Override 24 | public String getName() 25 | { 26 | return "sereneseasons"; 27 | } 28 | 29 | @Override 30 | public List getAliases() 31 | { 32 | return Lists.newArrayList("ss"); 33 | } 34 | 35 | @Override 36 | public String getUsage(ICommandSender sender) 37 | { 38 | return "commands.sereneseasons.usage"; 39 | } 40 | 41 | @Override 42 | public int getRequiredPermissionLevel() 43 | { 44 | return 2; 45 | } 46 | 47 | @Override 48 | public void execute(MinecraftServer server, ICommandSender sender, String[] args) throws CommandException 49 | { 50 | if (args.length < 1) 51 | { 52 | throw new WrongUsageException("commands.sereneseasons.usage"); 53 | } 54 | else if ("setseason".equals(args[0])) 55 | { 56 | setSeason(sender, args); 57 | } 58 | } 59 | 60 | private void setSeason(ICommandSender sender, String[] args) throws CommandException 61 | { 62 | EntityPlayerMP player = getCommandSenderAsPlayer(sender); 63 | Season.SubSeason newSeason = null; 64 | 65 | for (Season.SubSeason season : Season.SubSeason.VALUES) 66 | { 67 | if (season.toString().toLowerCase().equals(args[1].toLowerCase())) 68 | { 69 | newSeason = season; 70 | break; 71 | } 72 | } 73 | 74 | if (newSeason != null) 75 | { 76 | SeasonSavedData seasonData = SeasonHandler.getSeasonSavedData(player.world); 77 | seasonData.seasonCycleTicks = SeasonTime.ZERO.getSubSeasonDuration() * newSeason.ordinal(); 78 | seasonData.markDirty(); 79 | SeasonHandler.sendSeasonUpdate(player.world); 80 | sender.sendMessage(new TextComponentTranslation("commands.sereneseasons.setseason.success", args[1])); 81 | } 82 | else 83 | { 84 | sender.sendMessage(new TextComponentTranslation("commands.sereneseasons.setseason.fail", args[1])); 85 | } 86 | } 87 | 88 | @Override 89 | public List getTabCompletions(MinecraftServer server, ICommandSender sender, String[] args, BlockPos pos) 90 | { 91 | if (args.length == 1) 92 | { 93 | return getListOfStringsMatchingLastWord(args, "setseason"); 94 | } 95 | 96 | return null; 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/main/java/sereneseasons/item/ItemSeasonClock.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2016, the Biomes O' Plenty Team 3 | * 4 | * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Public License. 5 | * 6 | * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/. 7 | ******************************************************************************/ 8 | package sereneseasons.item; 9 | 10 | import net.minecraft.entity.Entity; 11 | import net.minecraft.entity.EntityLivingBase; 12 | import net.minecraft.item.IItemPropertyGetter; 13 | import net.minecraft.item.Item; 14 | import net.minecraft.item.ItemStack; 15 | import net.minecraft.util.ResourceLocation; 16 | import net.minecraft.util.math.MathHelper; 17 | import net.minecraft.world.World; 18 | import net.minecraftforge.fml.relauncher.Side; 19 | import net.minecraftforge.fml.relauncher.SideOnly; 20 | import sereneseasons.api.season.SeasonHelper; 21 | import sereneseasons.config.SeasonsConfig; 22 | import sereneseasons.init.ModConfig; 23 | import sereneseasons.season.SeasonTime; 24 | 25 | public class ItemSeasonClock extends Item 26 | { 27 | public ItemSeasonClock() 28 | { 29 | this.addPropertyOverride(new ResourceLocation("time"), new IItemPropertyGetter() 30 | { 31 | @SideOnly(Side.CLIENT) 32 | double field_185088_a; 33 | @SideOnly(Side.CLIENT) 34 | double field_185089_b; 35 | @SideOnly(Side.CLIENT) 36 | int ticks; 37 | @Override 38 | @SideOnly(Side.CLIENT) 39 | public float apply(ItemStack stack, World world, EntityLivingBase entity) 40 | { 41 | Entity holder = (Entity)(entity != null ? entity : stack.getItemFrame()); 42 | 43 | if (world == null && holder != null) 44 | { 45 | world = holder.world; 46 | } 47 | 48 | if (world == null) 49 | { 50 | return 0.0F; 51 | } 52 | else 53 | { 54 | double d0; 55 | 56 | if (SeasonsConfig.isDimensionWhitelisted(world.provider.getDimension())) 57 | { 58 | int seasonCycleTicks = SeasonHelper.getSeasonState(world).getSeasonCycleTicks(); 59 | d0 = (double)((float)seasonCycleTicks / (float) SeasonTime.ZERO.getCycleDuration()); 60 | } 61 | else 62 | { 63 | d0 = Math.random(); 64 | } 65 | 66 | d0 = this.actualFrame(world, d0); 67 | return MathHelper.positiveModulo((float)d0, 1.0F); 68 | } 69 | } 70 | @SideOnly(Side.CLIENT) 71 | private double actualFrame(World world, double frame) 72 | { 73 | if (world.getTotalWorldTime() != this.ticks) 74 | { 75 | this.ticks = (int)world.getTotalWorldTime(); 76 | double newFrame = frame - this.field_185088_a; 77 | 78 | if (newFrame < -0.5D) 79 | { 80 | ++newFrame; 81 | } 82 | 83 | this.field_185089_b += newFrame * 0.1D; 84 | this.field_185089_b *= 0.9D; 85 | this.field_185088_a += this.field_185089_b; 86 | } 87 | 88 | return this.field_185088_a; 89 | } 90 | }); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/main/java/sereneseasons/init/ModHandlers.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2014-2017, the Biomes O' Plenty Team 3 | * 4 | * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Public License. 5 | * 6 | * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/. 7 | ******************************************************************************/ 8 | package sereneseasons.init; 9 | 10 | import net.minecraft.world.biome.BiomeColorHelper; 11 | import net.minecraftforge.common.MinecraftForge; 12 | import net.minecraftforge.fml.common.FMLCommonHandler; 13 | import net.minecraftforge.fml.relauncher.Side; 14 | import net.minecraftforge.fml.relauncher.SideOnly; 15 | import sereneseasons.api.season.ISeasonColorProvider; 16 | import sereneseasons.api.season.SeasonHelper; 17 | import sereneseasons.config.BiomeConfig; 18 | import sereneseasons.handler.PacketHandler; 19 | import sereneseasons.handler.season.BirchColorHandler; 20 | import sereneseasons.handler.season.RandomUpdateHandler; 21 | import sereneseasons.handler.season.SeasonHandler; 22 | import sereneseasons.handler.season.SeasonSleepHandler; 23 | import sereneseasons.handler.season.SeasonalCropGrowthHandler; 24 | import sereneseasons.season.SeasonTime; 25 | import sereneseasons.util.SeasonColourUtil; 26 | 27 | public class ModHandlers 28 | { 29 | private static final SeasonHandler SEASON_HANDLER = new SeasonHandler(); 30 | 31 | public static void init() 32 | { 33 | PacketHandler.init(); 34 | 35 | //Handlers for functionality related to seasons 36 | MinecraftForge.EVENT_BUS.register(SEASON_HANDLER); 37 | MinecraftForge.TERRAIN_GEN_BUS.register(SEASON_HANDLER); 38 | SeasonHelper.dataProvider = SEASON_HANDLER; 39 | 40 | MinecraftForge.EVENT_BUS.register(new RandomUpdateHandler()); 41 | 42 | MinecraftForge.EVENT_BUS.register(new SeasonSleepHandler()); 43 | 44 | MinecraftForge.EVENT_BUS.register(new SeasonalCropGrowthHandler()); 45 | 46 | if (FMLCommonHandler.instance().getEffectiveSide() == Side.CLIENT) 47 | { 48 | registerSeasonColourHandlers(); 49 | } 50 | } 51 | 52 | @SideOnly(Side.CLIENT) 53 | private static BiomeColorHelper.ColorResolver originalGrassColorResolver; 54 | @SideOnly(Side.CLIENT) 55 | private static BiomeColorHelper.ColorResolver originalFoliageColorResolver; 56 | 57 | @SideOnly(Side.CLIENT) 58 | private static void registerSeasonColourHandlers() 59 | { 60 | originalGrassColorResolver = BiomeColorHelper.GRASS_COLOR; 61 | originalFoliageColorResolver = BiomeColorHelper.FOLIAGE_COLOR; 62 | 63 | BiomeColorHelper.GRASS_COLOR = (biome, blockPosition) -> 64 | { 65 | SeasonTime calendar = SeasonHandler.getClientSeasonTime(); 66 | ISeasonColorProvider colorProvider = BiomeConfig.usesTropicalSeasons(biome) ? calendar.getTropicalSeason() : calendar.getSubSeason(); 67 | return SeasonColourUtil.applySeasonalGrassColouring(colorProvider, biome, originalGrassColorResolver.getColorAtPos(biome, blockPosition)); 68 | }; 69 | 70 | BiomeColorHelper.FOLIAGE_COLOR = (biome, blockPosition) -> 71 | { 72 | SeasonTime calendar = SeasonHandler.getClientSeasonTime(); 73 | ISeasonColorProvider colorProvider = BiomeConfig.usesTropicalSeasons(biome) ? calendar.getTropicalSeason() : calendar.getSubSeason(); 74 | return SeasonColourUtil.applySeasonalFoliageColouring(colorProvider, biome, originalFoliageColorResolver.getColorAtPos(biome, blockPosition)); 75 | }; 76 | } 77 | 78 | public static void postInit() 79 | { 80 | if (FMLCommonHandler.instance().getEffectiveSide() == Side.CLIENT) 81 | { 82 | BirchColorHandler.init(); 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/main/java/sereneseasons/config/SeasonsConfig.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2014-2017, the Biomes O' Plenty Team 3 | * 4 | * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Public License. 5 | * 6 | * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/. 7 | ******************************************************************************/ 8 | package sereneseasons.config; 9 | 10 | import java.io.File; 11 | 12 | import sereneseasons.api.config.SeasonsOption; 13 | import sereneseasons.core.SereneSeasons; 14 | import sereneseasons.init.ModConfig; 15 | 16 | public class SeasonsConfig extends ConfigHandler 17 | { 18 | public static final String TIME_SETTINGS = "Time Settings"; 19 | public static final String WEATHER_SETTINGS = "Weather Settings"; 20 | public static final String AESTHETIC_SETTINGS = "Aesthetic Settings"; 21 | public static final String DIMENSION_SETTINGS = "Dimension Settings"; 22 | 23 | public boolean generateSnowAndIce; 24 | public boolean changeWeatherFrequency; 25 | 26 | public boolean changeGrassColour; 27 | public boolean changeFoliageColour; 28 | public boolean changeBirchColour; 29 | 30 | public String[] whitelistedDimensions; 31 | 32 | public SeasonsConfig(File configFile) 33 | { 34 | super(configFile, "Seasons Settings"); 35 | } 36 | 37 | @Override 38 | protected void loadConfiguration() 39 | { 40 | try 41 | { 42 | addSyncedValue(SeasonsOption.DAY_DURATION, 24000, TIME_SETTINGS, "The duration of a Minecraft day in ticks", 20, Integer.MAX_VALUE); 43 | addSyncedValue(SeasonsOption.SUB_SEASON_DURATION, 7, TIME_SETTINGS, "The duration of a sub season in days", 1, Integer.MAX_VALUE); 44 | addSyncedValue(SeasonsOption.STARTING_SUB_SEASON, 5, TIME_SETTINGS, "The starting sub season for new worlds. 0 = Random, 1 - 3 = Early/Mid/Late Spring, 4 - 6 = Early/Mid/Late Summer, 7 - 9 = Early/Mid/Late Autumn, 10 - 12 = Early/Mid/Late Winter", 0, 12); 45 | addSyncedValue(SeasonsOption.PROGRESS_SEASON_WHILE_OFFLINE, true, TIME_SETTINGS, "If the season should progress on a server with no players online"); 46 | 47 | generateSnowAndIce = config.getBoolean("Generate Snow and Ice", WEATHER_SETTINGS, true, "Generate snow and ice during the Winter season"); 48 | changeWeatherFrequency = config.getBoolean("Change Weather Frequency", WEATHER_SETTINGS, true, "Change the frequency of rain/snow/storms based on the season"); 49 | 50 | // Client-only. The server shouldn't get to decide these. 51 | changeGrassColour = config.getBoolean("Change Grass Colour Seasonally", AESTHETIC_SETTINGS, true, "Change the grass colour based on the current season"); 52 | changeFoliageColour = config.getBoolean("Change Foliage Colour Seasonally", AESTHETIC_SETTINGS, true, "Change the foliage colour based on the current season"); 53 | changeBirchColour = config.getBoolean("Change Birch Colour Seasonally", AESTHETIC_SETTINGS, true, "Change the birch colour based on the current season"); 54 | 55 | whitelistedDimensions = config.getStringList("Whitelisted Dimensions", DIMENSION_SETTINGS, new String[] { "0" }, "Seasons will only apply to dimensons listed here"); 56 | } 57 | catch (Exception e) 58 | { 59 | SereneSeasons.logger.error("Serene Seasons has encountered a problem loading seasons.cfg", e); 60 | } 61 | finally 62 | { 63 | if (config.hasChanged()) config.save(); 64 | } 65 | } 66 | 67 | public static boolean isDimensionWhitelisted(int dimension) 68 | { 69 | for (String dimensions : ModConfig.seasons.whitelistedDimensions) 70 | { 71 | if (dimension == Integer.valueOf(dimensions)) 72 | { 73 | return true; 74 | } 75 | } 76 | 77 | return false; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/main/java/sereneseasons/util/SeasonColourUtil.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2016, the Biomes O' Plenty Team 3 | * 4 | * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Public License. 5 | * 6 | * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/. 7 | ******************************************************************************/ 8 | package sereneseasons.util; 9 | 10 | 11 | import com.google.common.collect.Lists; 12 | 13 | import net.minecraft.client.Minecraft; 14 | import net.minecraft.world.biome.Biome; 15 | import org.lwjgl.util.Color; 16 | 17 | import sereneseasons.api.config.SeasonsOption; 18 | import sereneseasons.api.config.SyncedConfig; 19 | import sereneseasons.api.season.ISeasonColorProvider; 20 | import sereneseasons.api.season.Season; 21 | import sereneseasons.config.BiomeConfig; 22 | import sereneseasons.config.SeasonsConfig; 23 | import sereneseasons.init.ModConfig; 24 | 25 | import java.util.List; 26 | 27 | public class SeasonColourUtil 28 | { 29 | public static int multiplyColours(int colour1, int colour2) 30 | { 31 | //Convert each colour to a scale between 0 and 1 and multiply them 32 | //Multiply by 255 to bring back between 0 and 255 33 | return (int)((colour1 / 255.0F) * (colour2 / 255.0F) * 255.0F); 34 | } 35 | 36 | public static int overlayBlendChannel(int underColour, int overColour) 37 | { 38 | int retVal; 39 | if (underColour < 128) 40 | { 41 | retVal = multiplyColours(2 * underColour, overColour); 42 | } 43 | else 44 | { 45 | retVal = multiplyColours(2 * (255 - underColour), 255 - overColour); 46 | retVal = 255 - retVal; 47 | } 48 | return retVal; 49 | } 50 | 51 | public static int overlayBlend(int underColour, int overColour) 52 | { 53 | int r = overlayBlendChannel((underColour >> 16) & 255, (overColour >> 16) & 255); 54 | int g = overlayBlendChannel((underColour >> 8) & 255, (overColour >> 8) & 255); 55 | int b = overlayBlendChannel(underColour & 255, overColour & 255); 56 | 57 | return (r & 255) << 16 | (g & 255) << 8 | (b & 255); 58 | } 59 | 60 | public static int saturateColour(int colour, float saturationMultiplier) 61 | { 62 | Color newColour = getColourFromInt(colour); 63 | float[] hsb = newColour.toHSB(null); 64 | hsb[1] *= saturationMultiplier; 65 | newColour.fromHSB(hsb[0], hsb[1], hsb[2]); 66 | return getIntFromColour(newColour); 67 | } 68 | 69 | public static int applySeasonalGrassColouring(ISeasonColorProvider colorProvider, Biome biome, int originalColour) 70 | { 71 | if (!BiomeConfig.enablesSeasonalEffects(biome) || !SeasonsConfig.isDimensionWhitelisted(Minecraft.getMinecraft().player.dimension)) 72 | return originalColour; 73 | 74 | int overlay = colorProvider.getGrassOverlay(); 75 | float saturationMultiplier = colorProvider.getGrassSaturationMultiplier(); 76 | if (!ModConfig.seasons.changeGrassColour) 77 | { 78 | overlay = Season.SubSeason.MID_SUMMER.getGrassOverlay(); 79 | saturationMultiplier = Season.SubSeason.MID_SUMMER.getGrassSaturationMultiplier(); 80 | } 81 | int newColour = overlay == 0xFFFFFF ? originalColour : overlayBlend(originalColour, overlay); 82 | return saturationMultiplier != -1 ? saturateColour(newColour, saturationMultiplier) : newColour; 83 | } 84 | 85 | public static int applySeasonalFoliageColouring(ISeasonColorProvider colorProvider, Biome biome, int originalColour) 86 | { 87 | if (!BiomeConfig.enablesSeasonalEffects(biome) || !SeasonsConfig.isDimensionWhitelisted(Minecraft.getMinecraft().player.dimension)) 88 | return originalColour; 89 | 90 | int overlay = colorProvider.getFoliageOverlay(); 91 | float saturationMultiplier = colorProvider.getFoliageSaturationMultiplier(); 92 | if (!ModConfig.seasons.changeFoliageColour) 93 | { 94 | overlay = Season.SubSeason.MID_SUMMER.getFoliageOverlay(); 95 | saturationMultiplier = Season.SubSeason.MID_SUMMER.getFoliageSaturationMultiplier(); 96 | } 97 | int newColour = overlay == 0xFFFFFF ? originalColour : overlayBlend(originalColour, overlay); 98 | return saturationMultiplier != -1 ? saturateColour(newColour, saturationMultiplier) : newColour; 99 | } 100 | 101 | private static Color getColourFromInt(int colour) 102 | { 103 | return new Color((colour >> 16) & 255, (colour >> 8) & 255, colour & 255); 104 | } 105 | 106 | private static int getIntFromColour(Color colour) 107 | { 108 | return (colour.getRed() & 255) << 16 | (colour.getGreen() & 255) << 8 | colour.getBlue() & 255; 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/main/java/sereneseasons/core/ClientProxy.java: -------------------------------------------------------------------------------- 1 | package sereneseasons.core; 2 | 3 | import com.google.common.base.Preconditions; 4 | import net.minecraft.block.Block; 5 | import net.minecraft.block.properties.IProperty; 6 | import net.minecraft.client.renderer.block.model.ModelResourceLocation; 7 | import net.minecraft.client.renderer.block.statemap.IStateMapper; 8 | import net.minecraft.client.renderer.block.statemap.StateMap; 9 | import net.minecraft.client.renderer.entity.Render; 10 | import net.minecraft.client.renderer.entity.RenderManager; 11 | import net.minecraft.entity.Entity; 12 | import net.minecraft.init.Items; 13 | import net.minecraft.item.Item; 14 | import net.minecraft.item.ItemStack; 15 | import net.minecraft.util.NonNullList; 16 | import net.minecraft.util.ResourceLocation; 17 | import net.minecraftforge.client.model.ModelLoader; 18 | import net.minecraftforge.fml.client.registry.IRenderFactory; 19 | import net.minecraftforge.fml.client.registry.RenderingRegistry; 20 | import sereneseasons.api.ISSBlock; 21 | import sereneseasons.util.inventory.CreativeTabSS; 22 | 23 | public class ClientProxy extends CommonProxy 24 | { 25 | @Override 26 | public void registerRenderers() 27 | { 28 | } 29 | 30 | @Override 31 | public void registerItemVariantModel(Item item, String name, int metadata) 32 | { 33 | Preconditions.checkNotNull(item, "Cannot register models for null item " + name); 34 | Preconditions.checkArgument(item != Items.AIR, "Cannot register models for air (" + name + ")"); 35 | 36 | ModelLoader.registerItemVariants(item, new ResourceLocation("sereneseasons:" + name)); 37 | ModelLoader.setCustomModelResourceLocation(item, metadata, new ModelResourceLocation(SereneSeasons.MOD_ID + ":" + name, "inventory")); 38 | } 39 | 40 | @Override 41 | public void registerBlockSided(Block block) 42 | { 43 | if (block instanceof ISSBlock) 44 | { 45 | ISSBlock bopBlock = (ISSBlock) block; 46 | 47 | //Register non-rendering properties 48 | IProperty[] nonRenderingProperties = bopBlock.getNonRenderingProperties(); 49 | 50 | if (nonRenderingProperties != null) 51 | { 52 | // use a custom state mapper which will ignore the properties specified in the block as being non-rendering 53 | IStateMapper custom_mapper = (new StateMap.Builder()).ignore(nonRenderingProperties).build(); 54 | ModelLoader.setCustomStateMapper(block, custom_mapper); 55 | } 56 | } 57 | } 58 | 59 | @Override 60 | public void registerItemSided(Item item) 61 | { 62 | // register sub types if there are any 63 | if (item.getHasSubtypes()) 64 | { 65 | NonNullList subItems = NonNullList.create(); 66 | item.getSubItems(CreativeTabSS.instance, subItems); 67 | for (ItemStack subItem : subItems) 68 | { 69 | String subItemName = item.getUnlocalizedName(subItem); 70 | subItemName = subItemName.substring(subItemName.indexOf(".") + 1); // remove 'item.' from the front 71 | 72 | ModelLoader.registerItemVariants(item, new ResourceLocation(SereneSeasons.MOD_ID, subItemName)); 73 | ModelLoader.setCustomModelResourceLocation(item, subItem.getMetadata(), new ModelResourceLocation(SereneSeasons.MOD_ID + ":" + subItemName, "inventory")); 74 | } 75 | } 76 | else 77 | { 78 | ModelLoader.setCustomModelResourceLocation(item, 0, new ModelResourceLocation(SereneSeasons.MOD_ID + ":" + item.delegate.name().getResourcePath(), "inventory")); 79 | } 80 | } 81 | 82 | // 83 | // The below method and class is used as part of Forge 1668+'s workaround for render manager being null during preinit 84 | // 85 | 86 | private static void registerEntityRenderer(Class entityClass, Class> renderClass) 87 | { 88 | RenderingRegistry.registerEntityRenderingHandler(entityClass, new EntityRenderFactory(renderClass)); 89 | } 90 | 91 | private static class EntityRenderFactory implements IRenderFactory 92 | { 93 | private Class> renderClass; 94 | 95 | private EntityRenderFactory(Class> renderClass) 96 | { 97 | this.renderClass = renderClass; 98 | } 99 | 100 | @Override 101 | public Render createRenderFor(RenderManager manager) 102 | { 103 | Render renderer = null; 104 | 105 | try 106 | { 107 | renderer = renderClass.getConstructor(RenderManager.class).newInstance(manager); 108 | } 109 | catch (Exception e) 110 | { 111 | e.printStackTrace(); 112 | } 113 | 114 | return renderer; 115 | } 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /src/main/java/sereneseasons/util/BlockStateUtils.java: -------------------------------------------------------------------------------- 1 | package sereneseasons.util; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Iterator; 5 | import java.util.List; 6 | import java.util.Map.Entry; 7 | import java.util.Stack; 8 | 9 | import com.google.common.collect.ImmutableSet; 10 | 11 | import net.minecraft.block.Block; 12 | import net.minecraft.block.properties.IProperty; 13 | import net.minecraft.block.state.IBlockState; 14 | import sereneseasons.api.ISSBlock; 15 | 16 | public class BlockStateUtils 17 | { 18 | 19 | // utility function for dumping block state info to a string 20 | public static String getStateInfoAsString(IBlockState state) 21 | { 22 | String desc = state.getBlock().getClass().getName() + "["; 23 | Iterator it = state.getProperties().entrySet().iterator(); 24 | boolean first = true; 25 | while (it.hasNext()) 26 | { 27 | if (!first) {desc = desc + ",";} 28 | Entry entry = (Entry)it.next(); 29 | IProperty iproperty = (IProperty)entry.getKey(); 30 | Comparable comparable = (Comparable)entry.getValue(); 31 | desc = desc + iproperty.getName() + "=" + iproperty.getName(comparable); 32 | first = false; 33 | } 34 | desc = desc + "]"; 35 | return desc; 36 | } 37 | 38 | 39 | // returns a set of states, one for every possible combination of values from the provided properties 40 | public static ImmutableSet getStatesSet(IBlockState baseState, IProperty... properties) 41 | { 42 | Stack propStack = new Stack(); 43 | List states = new ArrayList(); 44 | for (IProperty prop : properties) {propStack.push(prop);} 45 | if (!propStack.isEmpty()) 46 | { 47 | addStatesToList(baseState, states, propStack); 48 | } 49 | ImmutableSet ret = ImmutableSet.copyOf(states); 50 | return ret; 51 | } 52 | 53 | // recursively add state values to a list 54 | private static void addStatesToList(IBlockState state, List list, Stack stack) 55 | { 56 | if (stack.empty()) 57 | { 58 | list.add(state); 59 | return; 60 | } 61 | else 62 | { 63 | IProperty prop = stack.pop(); 64 | for (Object value : prop.getAllowedValues()) 65 | { 66 | addStatesToList(state.withProperty(prop, (Comparable)value), list, stack); 67 | } 68 | stack.push(prop); 69 | } 70 | } 71 | 72 | // return all of the different 'preset' variants of a block 73 | // works by looping through all the different values of the properties specified in block.getPresetProperties() 74 | // only works on blocks supporting IBOPBlock - returns an empty set for vanilla blocks 75 | public static ImmutableSet getBlockPresets(Block block) 76 | { 77 | if (!(block instanceof ISSBlock)) {return ImmutableSet.of();} 78 | IBlockState defaultState = block.getDefaultState(); 79 | if (defaultState == null) {defaultState = block.getBlockState().getBaseState();} 80 | return getStatesSet(defaultState, ((ISSBlock)block).getPresetProperties()); 81 | } 82 | 83 | /**Discards additional block information to retrieve a state equivalent to those in the inventory**/ 84 | public static IBlockState getPresetState(IBlockState state) 85 | { 86 | IBlockState outState = state.getBlock().getDefaultState(); 87 | 88 | if (state.getBlock() instanceof ISSBlock) 89 | { 90 | ISSBlock bopBlock = (ISSBlock)state.getBlock(); 91 | 92 | for (IProperty property : bopBlock.getPresetProperties()) 93 | { 94 | outState = outState.withProperty(property, state.getValue(property)); 95 | } 96 | } 97 | 98 | return outState; 99 | } 100 | 101 | public static IProperty getPropertyByName(IBlockState blockState, String propertyName) 102 | { 103 | for (IProperty property : (ImmutableSet>) blockState.getProperties().keySet()) 104 | { 105 | if (property.getName().equals(propertyName)) 106 | return property; 107 | } 108 | 109 | return null; 110 | } 111 | 112 | public static boolean isValidPropertyName(IBlockState blockState, String propertyName) 113 | { 114 | return getPropertyByName(blockState, propertyName) != null; 115 | } 116 | 117 | public static Comparable getPropertyValueByName(IBlockState blockState, IProperty property, String valueName) 118 | { 119 | for (Comparable value : (ImmutableSet) property.getAllowedValues()) 120 | { 121 | if (value.toString().equals(valueName)) 122 | return value; 123 | } 124 | 125 | return null; 126 | } 127 | 128 | 129 | } -------------------------------------------------------------------------------- /src/main/java/sereneseasons/handler/season/RandomUpdateHandler.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2016, the Biomes O' Plenty Team 3 | * 4 | * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Public License. 5 | * 6 | * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/. 7 | ******************************************************************************/ 8 | package sereneseasons.handler.season; 9 | 10 | import java.util.Iterator; 11 | 12 | import net.minecraft.block.Block; 13 | import net.minecraft.block.BlockIce; 14 | import net.minecraft.init.Blocks; 15 | import net.minecraft.util.math.BlockPos; 16 | import net.minecraft.world.WorldServer; 17 | import net.minecraft.world.biome.Biome; 18 | import net.minecraft.world.chunk.Chunk; 19 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 20 | import net.minecraftforge.fml.common.gameevent.TickEvent; 21 | import net.minecraftforge.fml.common.gameevent.TickEvent.Phase; 22 | import net.minecraftforge.fml.relauncher.Side; 23 | import sereneseasons.api.season.Season; 24 | import sereneseasons.api.season.SeasonHelper; 25 | import sereneseasons.config.BiomeConfig; 26 | import sereneseasons.config.SeasonsConfig; 27 | import sereneseasons.init.ModConfig; 28 | import sereneseasons.season.SeasonASMHelper; 29 | 30 | public class RandomUpdateHandler 31 | { 32 | //Randomly melt ice and snow when it isn't winter 33 | @SubscribeEvent 34 | public void onWorldTick(TickEvent.WorldTickEvent event) 35 | { 36 | if (event.phase == Phase.END && event.side == Side.SERVER) 37 | { 38 | 39 | Season.SubSeason subSeason = SeasonHelper.getSeasonState(event.world).getSubSeason(); 40 | Season season = subSeason.getSeason(); 41 | 42 | if (season == Season.WINTER) 43 | { 44 | if (ModConfig.seasons.changeWeatherFrequency) 45 | { 46 | if (event.world.getWorldInfo().isThundering()) 47 | { 48 | event.world.getWorldInfo().setThundering(false);; 49 | } 50 | if (!event.world.getWorldInfo().isRaining() && event.world.getWorldInfo().getRainTime() > 36000) 51 | { 52 | event.world.getWorldInfo().setRainTime(event.world.rand.nextInt(24000) + 12000); 53 | } 54 | } 55 | } 56 | else 57 | { 58 | if (ModConfig.seasons.changeWeatherFrequency) 59 | { 60 | if (season == Season.SPRING) 61 | { 62 | if (!event.world.getWorldInfo().isRaining() && event.world.getWorldInfo().getRainTime() > 96000) 63 | { 64 | event.world.getWorldInfo().setRainTime(event.world.rand.nextInt(84000) + 12000); 65 | } 66 | } 67 | else if (season == Season.SUMMER) 68 | { 69 | if (!event.world.getWorldInfo().isThundering() && event.world.getWorldInfo().getThunderTime() > 36000) 70 | { 71 | event.world.getWorldInfo().setThunderTime(event.world.rand.nextInt(24000) + 12000); 72 | } 73 | } 74 | } 75 | 76 | if (ModConfig.seasons.generateSnowAndIce && SeasonsConfig.isDimensionWhitelisted(event.world.provider.getDimension())) 77 | { 78 | WorldServer world = (WorldServer)event.world; 79 | for (Iterator iterator = world.getPersistentChunkIterable(world.getPlayerChunkMap().getChunkIterator()); iterator.hasNext();) 80 | { 81 | Chunk chunk = iterator.next(); 82 | int x = chunk.x << 4; 83 | int z = chunk.z << 4; 84 | 85 | int rand; 86 | switch (subSeason) 87 | { 88 | case EARLY_SPRING: 89 | rand = 16; 90 | break; 91 | case MID_SPRING: 92 | rand = 12; 93 | break; 94 | case LATE_SPRING: 95 | rand = 8; 96 | break; 97 | default: 98 | rand = 4; 99 | break; 100 | } 101 | 102 | if (world.rand.nextInt(rand) == 0) 103 | { 104 | world.updateLCG = world.updateLCG * 3 + 1013904223; 105 | int randOffset = world.updateLCG >> 2; 106 | BlockPos pos = world.getPrecipitationHeight(new BlockPos(x + (randOffset & 15), 0, z + (randOffset >> 8 & 15))); 107 | Biome biome = world.getBiome(pos); 108 | 109 | if(!BiomeConfig.enablesSeasonalEffects(biome)) 110 | continue; 111 | 112 | boolean first = true; 113 | for (int y = pos.getY(); y >= 0; y--) 114 | { 115 | Block block = chunk.getBlockState(pos.getX(), y, pos.getZ()).getBlock(); 116 | 117 | if (block == Blocks.SNOW_LAYER) 118 | { 119 | pos = new BlockPos(pos.getX(), y, pos.getZ()); 120 | if (SeasonASMHelper.getFloatTemperature(world, biome, pos) >= 0.15F) 121 | { 122 | world.setBlockToAir(pos); 123 | break; 124 | } 125 | } 126 | 127 | if(!first) 128 | { 129 | if(block == Blocks.ICE) 130 | { 131 | pos = new BlockPos(pos.getX(), y, pos.getZ()); 132 | if (SeasonASMHelper.getFloatTemperature(world, biome, pos) >= 0.15F) 133 | { 134 | ((BlockIce)Blocks.ICE).turnIntoWater(world, pos); 135 | break; 136 | } 137 | } 138 | } 139 | else 140 | first = false; 141 | } 142 | } 143 | } 144 | } 145 | } 146 | } 147 | } 148 | } -------------------------------------------------------------------------------- /src/main/java/sereneseasons/api/season/Season.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2016, the Biomes O' Plenty Team 3 | * 4 | * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Public License. 5 | * 6 | * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/. 7 | ******************************************************************************/ 8 | package sereneseasons.api.season; 9 | 10 | public enum Season 11 | { 12 | SPRING, SUMMER, AUTUMN, WINTER; 13 | 14 | public enum SubSeason implements ISeasonColorProvider 15 | { 16 | EARLY_SPRING(SPRING, 0x778087, 0.85F, 0x6F818F, 0.85F, 0x869A68), 17 | MID_SPRING(SPRING, 0x6F818F, 0x5F849F, 0x7EA271), 18 | LATE_SPRING(SPRING, 0x678297, 0x3F89BF, 0x6EB283), 19 | EARLY_SUMMER(SUMMER, 0x73808B, 0x5F849F, 0x76AC6C), 20 | MID_SUMMER(SUMMER, 0xFFFFFF, 0xFFFFFF, 0x80A755), 21 | LATE_SUMMER(SUMMER, 0x877777, 0x9F5F5F, 0x98A54B), 22 | EARLY_AUTUMN(AUTUMN, 0x8F6F6F, 0xC44040, 0xB1A442), 23 | MID_AUTUMN(AUTUMN, 0x9F5F5F, 0xEF2121, 0xE2A231), 24 | LATE_AUTUMN(AUTUMN, 0xAF4F4F, 0.85F, 0xDB3030, 0.85F, 0xC98A35), 25 | EARLY_WINTER(WINTER, 0xAF4F4F, 0.60F, 0xDB3030, 0.60F, 0xB1723B), 26 | MID_WINTER(WINTER, 0xAF4F4F, 0.45F, 0xDB3030, 0.45F, 0xA0824D), 27 | LATE_WINTER(WINTER, 0x8E8181, 0.60F, 0xA57070, 0.60F, 0x8F925F); 28 | 29 | public static final SubSeason[] VALUES = SubSeason.values(); 30 | 31 | private Season season; 32 | private int grassOverlay; 33 | private float grassSaturationMultiplier; 34 | private int foliageOverlay; 35 | private float foliageSaturationMultiplier; 36 | private int birchColor; 37 | 38 | SubSeason(Season season, int grassColour, float grassSaturation, int foliageColour, float foliageSaturation, int birchColor) 39 | { 40 | this.season = season; 41 | this.grassOverlay = grassColour; 42 | this.grassSaturationMultiplier = grassSaturation; 43 | this.foliageOverlay = foliageColour; 44 | this.foliageSaturationMultiplier = foliageSaturation; 45 | this.birchColor = birchColor; 46 | } 47 | 48 | SubSeason(Season season, int grassColour, int foliageColour, int birchColor) 49 | { 50 | this(season, grassColour, -1, foliageColour, -1, birchColor); 51 | } 52 | 53 | public Season getSeason() 54 | { 55 | return this.season; 56 | } 57 | 58 | public int getGrassOverlay() 59 | { 60 | return this.grassOverlay; 61 | } 62 | 63 | public float getGrassSaturationMultiplier() 64 | { 65 | return this.grassSaturationMultiplier; 66 | } 67 | 68 | public int getFoliageOverlay() 69 | { 70 | return this.foliageOverlay; 71 | } 72 | 73 | public float getFoliageSaturationMultiplier() 74 | { 75 | return this.foliageSaturationMultiplier; 76 | } 77 | 78 | public int getBirchColor() 79 | { 80 | return this.birchColor; 81 | } 82 | } 83 | 84 | public enum TropicalSeason implements ISeasonColorProvider 85 | { 86 | EARLY_DRY(0xFFFFFF, 0xFFFFFF, 0x80A755), 87 | MID_DRY(0xA58668, 0.8F, 0xB7867C, 0.95F, 0x98A54B), 88 | LATE_DRY(0x8E7B6D, 0.9F, 0xA08B86, 0.975F, 0x80A755), 89 | EARLY_WET(0x758C8A, 0x728C91, 0x80A755), 90 | MID_WET(0x548384, 0x2498AE, 0x76AC6C), 91 | LATE_WET(0x658989, 0x4E8893, 0x80A755); 92 | 93 | public static final TropicalSeason[] VALUES = TropicalSeason.values(); 94 | 95 | private int grassOverlay; 96 | private float grassSaturationMultiplier; 97 | private int foliageOverlay; 98 | private float foliageSaturationMultiplier; 99 | private int birchColor; 100 | 101 | TropicalSeason(int grassColour, float grassSaturation, int foliageColour, float foliageSaturation, int birchColor) 102 | { 103 | this.grassOverlay = grassColour; 104 | this.grassSaturationMultiplier = grassSaturation; 105 | this.foliageOverlay = foliageColour; 106 | this.foliageSaturationMultiplier = foliageSaturation; 107 | this.birchColor = birchColor; 108 | } 109 | 110 | TropicalSeason(int grassColour, int foliageColour, int birchColor) 111 | { 112 | this(grassColour, -1, foliageColour, -1, birchColor); 113 | } 114 | 115 | public int getGrassOverlay() 116 | { 117 | return this.grassOverlay; 118 | } 119 | 120 | public float getGrassSaturationMultiplier() 121 | { 122 | return this.grassSaturationMultiplier; 123 | } 124 | 125 | public int getFoliageOverlay() 126 | { 127 | return this.foliageOverlay; 128 | } 129 | 130 | public float getFoliageSaturationMultiplier() 131 | { 132 | return this.foliageSaturationMultiplier; 133 | } 134 | 135 | public int getBirchColor() 136 | { 137 | return this.birchColor; 138 | } 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # Attempt to set APP_HOME 46 | # Resolve links: $0 may be a link 47 | PRG="$0" 48 | # Need this for relative symlinks. 49 | while [ -h "$PRG" ] ; do 50 | ls=`ls -ld "$PRG"` 51 | link=`expr "$ls" : '.*-> \(.*\)$'` 52 | if expr "$link" : '/.*' > /dev/null; then 53 | PRG="$link" 54 | else 55 | PRG=`dirname "$PRG"`"/$link" 56 | fi 57 | done 58 | SAVED="`pwd`" 59 | cd "`dirname \"$PRG\"`/" >/dev/null 60 | APP_HOME="`pwd -P`" 61 | cd "$SAVED" >/dev/null 62 | 63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 64 | 65 | # Determine the Java command to use to start the JVM. 66 | if [ -n "$JAVA_HOME" ] ; then 67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 68 | # IBM's JDK on AIX uses strange locations for the executables 69 | JAVACMD="$JAVA_HOME/jre/sh/java" 70 | else 71 | JAVACMD="$JAVA_HOME/bin/java" 72 | fi 73 | if [ ! -x "$JAVACMD" ] ; then 74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 75 | 76 | Please set the JAVA_HOME variable in your environment to match the 77 | location of your Java installation." 78 | fi 79 | else 80 | JAVACMD="java" 81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 82 | 83 | Please set the JAVA_HOME variable in your environment to match the 84 | location of your Java installation." 85 | fi 86 | 87 | # Increase the maximum file descriptors if we can. 88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 89 | MAX_FD_LIMIT=`ulimit -H -n` 90 | if [ $? -eq 0 ] ; then 91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 92 | MAX_FD="$MAX_FD_LIMIT" 93 | fi 94 | ulimit -n $MAX_FD 95 | if [ $? -ne 0 ] ; then 96 | warn "Could not set maximum file descriptor limit: $MAX_FD" 97 | fi 98 | else 99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 100 | fi 101 | fi 102 | 103 | # For Darwin, add options to specify how the application appears in the dock 104 | if $darwin; then 105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 106 | fi 107 | 108 | # For Cygwin, switch paths to Windows format before running java 109 | if $cygwin ; then 110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 112 | JAVACMD=`cygpath --unix "$JAVACMD"` 113 | 114 | # We build the pattern for arguments to be converted via cygpath 115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 116 | SEP="" 117 | for dir in $ROOTDIRSRAW ; do 118 | ROOTDIRS="$ROOTDIRS$SEP$dir" 119 | SEP="|" 120 | done 121 | OURCYGPATTERN="(^($ROOTDIRS))" 122 | # Add a user-defined pattern to the cygpath arguments 123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 125 | fi 126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 127 | i=0 128 | for arg in "$@" ; do 129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 131 | 132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 134 | else 135 | eval `echo args$i`="\"$arg\"" 136 | fi 137 | i=$((i+1)) 138 | done 139 | case $i in 140 | (0) set -- ;; 141 | (1) set -- "$args0" ;; 142 | (2) set -- "$args0" "$args1" ;; 143 | (3) set -- "$args0" "$args1" "$args2" ;; 144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 150 | esac 151 | fi 152 | 153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 154 | function splitJvmOpts() { 155 | JVM_OPTS=("$@") 156 | } 157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 159 | 160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 161 | -------------------------------------------------------------------------------- /src/main/java/sereneseasons/asm/ASMHelper.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2016, the Biomes O' Plenty Team 3 | * 4 | * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Public License. 5 | * 6 | * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/. 7 | ******************************************************************************/ 8 | package sereneseasons.asm; 9 | 10 | import java.io.PrintWriter; 11 | import java.io.StringWriter; 12 | import java.util.ArrayList; 13 | import java.util.Iterator; 14 | import java.util.List; 15 | 16 | import org.apache.commons.codec.digest.DigestUtils; 17 | import org.apache.logging.log4j.LogManager; 18 | import org.apache.logging.log4j.Logger; 19 | import org.objectweb.asm.tree.AbstractInsnNode; 20 | import org.objectweb.asm.tree.MethodInsnNode; 21 | import org.objectweb.asm.tree.MethodNode; 22 | import org.objectweb.asm.util.Printer; 23 | import org.objectweb.asm.util.Textifier; 24 | import org.objectweb.asm.util.TraceMethodVisitor; 25 | 26 | import com.google.common.collect.Lists; 27 | 28 | public class ASMHelper 29 | { 30 | public static final Logger LOGGER = LogManager.getLogger("SereneSeasons Transformer"); 31 | 32 | public static boolean methodEquals(MethodNode methodNode, String[] names, String desc) 33 | { 34 | boolean nameMatches = false; 35 | 36 | for (String name : names) 37 | { 38 | if (methodNode.name.equals(name)) 39 | { 40 | nameMatches = true; 41 | break; 42 | } 43 | } 44 | 45 | return nameMatches && methodNode.desc.equals(desc); 46 | } 47 | 48 | public static void clearNextInstructions(MethodNode methodNode, AbstractInsnNode insnNode) 49 | { 50 | Iterator iterator = methodNode.instructions.iterator(methodNode.instructions.indexOf(insnNode)); 51 | 52 | while (iterator.hasNext()) 53 | { 54 | iterator.next(); 55 | iterator.remove(); 56 | } 57 | } 58 | 59 | public static void clearNextInstructions(MethodNode methodNode, AbstractInsnNode insnNode, int count) 60 | { 61 | Iterator iterator = methodNode.instructions.iterator(methodNode.instructions.indexOf(insnNode)); 62 | 63 | while (iterator.hasNext() && count > 0) 64 | { 65 | iterator.next(); 66 | iterator.remove(); 67 | count--; 68 | } 69 | } 70 | 71 | public static MethodInsnNode getUniqueMethodInsnNode(MethodNode methodNode, int opcode, String owner, String[] names, String desc) 72 | { 73 | List matchedMethodNodes = matchMethodInsnNodes(methodNode, opcode, owner, names, desc); 74 | 75 | if (matchedMethodNodes.isEmpty()) throw new RuntimeException("No method instruction node found matching " + owner + " " + names[0] + " " + desc); 76 | if (matchedMethodNodes.size() > 1) LOGGER.warn("Too many matched instructions were found in " + methodNode.name + " for " + owner + " " + names[0] + " " + desc + ". Crashes or bugs may occur!"); 77 | 78 | return matchedMethodNodes.get(matchedMethodNodes.size() - 1); 79 | } 80 | 81 | public static List matchMethodInsnNodes(MethodNode methodNode, int opcode, String owner, String[] names, String desc) 82 | { 83 | ArrayList matches = Lists.newArrayList(); 84 | ArrayList validMethodNames = Lists.newArrayList(names); 85 | 86 | for (AbstractInsnNode insnNode : methodNode.instructions.toArray()) 87 | { 88 | if (insnNode instanceof MethodInsnNode && insnNode.getOpcode() == opcode) 89 | { 90 | MethodInsnNode methodInsnNode = (MethodInsnNode)insnNode; 91 | 92 | if (methodInsnNode.owner.equals(owner) & validMethodNames.contains(methodInsnNode.name) && methodInsnNode.desc.equals(desc)) 93 | { 94 | matches.add(methodInsnNode); 95 | } 96 | } 97 | } 98 | 99 | return matches; 100 | } 101 | 102 | public static void verifyClassHash(String className, byte[] bytes, String... expectedHashes) 103 | { 104 | String currentHash = DigestUtils.md5Hex(bytes); 105 | 106 | if (!Lists.newArrayList(expectedHashes).contains(currentHash)) 107 | { 108 | String error = String.format("Unexpected hash %s detected for class %s. Crashes or bugs may occur!", currentHash, className); 109 | LOGGER.error(error); 110 | } 111 | else 112 | { 113 | LOGGER.info(String.format("Valid hash %s found for class %s.", currentHash, className)); 114 | } 115 | } 116 | 117 | private static Printer printer = new Textifier(); 118 | private static TraceMethodVisitor methodVisitor = new TraceMethodVisitor(printer); 119 | 120 | public static void printMethod(MethodNode methodNode, int startIndex, int count) 121 | { 122 | Iterator it = methodNode.instructions.iterator(startIndex); 123 | 124 | LOGGER.info("----- Printing " + methodNode.name + "... -----"); 125 | 126 | while (it.hasNext() && (count > 0 || count == -1)) 127 | { 128 | it.next().accept(methodVisitor); 129 | StringWriter stringWriter = new StringWriter(); 130 | printer.print(new PrintWriter(stringWriter)); 131 | printer.getText().clear(); 132 | 133 | LOGGER.info(stringWriter.toString().replace("\n", "")); 134 | 135 | if (count != -1) 136 | count--; 137 | } 138 | 139 | LOGGER.info("----- Finished! -----"); 140 | } 141 | 142 | public static void printMethod(MethodNode methodNode) 143 | { 144 | printMethod(methodNode, 0, -1); 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /src/main/java/sereneseasons/init/ModBlocks.java: -------------------------------------------------------------------------------- 1 | package sereneseasons.init; 2 | 3 | import static sereneseasons.api.SSBlocks.greenhouse_glass; 4 | import static sereneseasons.api.SSBlocks.season_sensors; 5 | 6 | import com.google.common.base.Preconditions; 7 | import com.google.common.collect.ImmutableSet; 8 | 9 | import net.minecraft.block.Block; 10 | import net.minecraft.block.state.IBlockState; 11 | import net.minecraft.creativetab.CreativeTabs; 12 | import net.minecraft.item.Item; 13 | import net.minecraft.item.ItemBlock; 14 | import net.minecraft.util.ResourceLocation; 15 | import net.minecraftforge.fml.common.registry.ForgeRegistries; 16 | import net.minecraftforge.fml.common.registry.GameRegistry; 17 | import sereneseasons.api.ISSBlock; 18 | import sereneseasons.block.BlockGreenhouseGlass; 19 | import sereneseasons.block.BlockSeasonSensor; 20 | import sereneseasons.core.SereneSeasons; 21 | import sereneseasons.tileentity.TileEntitySeasonSensor; 22 | import sereneseasons.util.BlockStateUtils; 23 | import sereneseasons.util.inventory.CreativeTabSS; 24 | 25 | public class ModBlocks 26 | { 27 | public static void init() 28 | { 29 | greenhouse_glass = registerBlock( new BlockGreenhouseGlass(), "greenhouse_glass" ); 30 | 31 | season_sensors[0] = registerBlock( new BlockSeasonSensor(BlockSeasonSensor.DetectorType.SPRING), "season_sensor_spring" ); 32 | season_sensors[1] = registerBlock( new BlockSeasonSensor(BlockSeasonSensor.DetectorType.SUMMER), "season_sensor_summer" ).setCreativeTab(null); 33 | season_sensors[2] = registerBlock( new BlockSeasonSensor(BlockSeasonSensor.DetectorType.AUTUMN), "season_sensor_autumn" ).setCreativeTab(null); 34 | season_sensors[3] = registerBlock( new BlockSeasonSensor(BlockSeasonSensor.DetectorType.WINTER), "season_sensor_winter" ).setCreativeTab(null); 35 | 36 | GameRegistry.registerTileEntity(TileEntitySeasonSensor.class, "season_sensor"); 37 | } 38 | 39 | public static void registerBlockItemModel(Block block, String stateName, int stateMeta) 40 | { 41 | Item item = Item.getItemFromBlock(block); 42 | SereneSeasons.proxy.registerItemVariantModel(item, stateName, stateMeta); 43 | } 44 | 45 | public static Block registerBlock(Block block, String blockName) 46 | { 47 | // by default, set the creative tab for all blocks added in BOP to CreativeTabBOP.instance 48 | return registerBlock(block, blockName, CreativeTabSS.instance); 49 | } 50 | 51 | public static Block registerBlock(Block block, String blockName,CreativeTabs tab) 52 | { 53 | return registerBlock(block, blockName, tab, true); 54 | } 55 | 56 | public static Block registerBlock(Block block, String blockName, CreativeTabs tab, boolean registerItemModels) 57 | { 58 | Preconditions.checkNotNull(block, "Cannot register a null block"); 59 | block.setUnlocalizedName(blockName); 60 | block.setCreativeTab(tab); 61 | 62 | if (block instanceof ISSBlock) 63 | { 64 | // if this block supports the IBOPBlock interface then we can determine the item block class, and sub-blocks automatically 65 | ISSBlock bopBlock = (ISSBlock) block; 66 | 67 | registerBlockWithItem(block, blockName, bopBlock.getItemClass()); 68 | SereneSeasons.proxy.registerBlockSided(block); 69 | 70 | // check for missing default states 71 | IBlockState defaultState = block.getDefaultState(); 72 | if (defaultState == null) 73 | { 74 | defaultState = block.getBlockState().getBaseState(); 75 | SereneSeasons.logger.error("Missing default state for " + block.getUnlocalizedName()); 76 | } 77 | 78 | // Some blocks such as doors and slabs register their items after the blocks (getItemClass returns null) 79 | if (registerItemModels) 80 | { 81 | // get the preset blocks variants 82 | ImmutableSet presets = BlockStateUtils.getBlockPresets(block); 83 | if (presets.isEmpty()) 84 | { 85 | // block has no sub-blocks to register 86 | registerBlockItemModel(block, blockName, 0); 87 | } else 88 | { 89 | // register all the sub-blocks 90 | for (IBlockState state : presets) 91 | { 92 | String stateName = bopBlock.getStateName(state); 93 | int stateMeta = block.getMetaFromState(state); 94 | registerBlockItemModel(block, stateName, stateMeta); 95 | } 96 | } 97 | } 98 | } 99 | else 100 | { 101 | // for vanilla blocks, just register a single variant with meta=0 and assume ItemBlock for the item class 102 | registerBlockWithItem(block, blockName, ItemBlock.class); 103 | registerBlockItemModel(block, blockName, 0); 104 | } 105 | 106 | return block; 107 | } 108 | 109 | private static void registerBlockWithItem(Block block, String blockName, Class clazz) 110 | { 111 | try 112 | { 113 | Item itemBlock = clazz != null ? (Item)clazz.getConstructor(Block.class).newInstance(block) : null; 114 | ResourceLocation location = new ResourceLocation(SereneSeasons.MOD_ID, blockName); 115 | 116 | block.setRegistryName(new ResourceLocation(SereneSeasons.MOD_ID, blockName)); 117 | 118 | ForgeRegistries.BLOCKS.register(block); 119 | if (itemBlock != null) 120 | { 121 | itemBlock.setRegistryName(new ResourceLocation(SereneSeasons.MOD_ID, blockName)); 122 | ForgeRegistries.ITEMS.register(itemBlock); 123 | } 124 | } 125 | catch (Exception e) 126 | { 127 | throw new RuntimeException("An error occurred associating an item block during registration of " + blockName, e); 128 | } 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /src/main/resources/assets/sereneseasons/models/item/season_clock.json: -------------------------------------------------------------------------------- 1 | { 2 | "parent": "item/generated", 3 | "textures": { 4 | "layer0": "sereneseasons:items/season_clock_00" 5 | }, 6 | "overrides": [ 7 | { "predicate": { "time": 0.0000000 }, "model": "sereneseasons:item/season_clock" }, 8 | { "predicate": { "time": 0.0078125 }, "model": "sereneseasons:item/season_clock_01" }, 9 | { "predicate": { "time": 0.0234375 }, "model": "sereneseasons:item/season_clock_02" }, 10 | { "predicate": { "time": 0.0390625 }, "model": "sereneseasons:item/season_clock_03" }, 11 | { "predicate": { "time": 0.0546875 }, "model": "sereneseasons:item/season_clock_04" }, 12 | { "predicate": { "time": 0.0703125 }, "model": "sereneseasons:item/season_clock_05" }, 13 | { "predicate": { "time": 0.0859375 }, "model": "sereneseasons:item/season_clock_06" }, 14 | { "predicate": { "time": 0.1015625 }, "model": "sereneseasons:item/season_clock_07" }, 15 | { "predicate": { "time": 0.1171875 }, "model": "sereneseasons:item/season_clock_08" }, 16 | { "predicate": { "time": 0.1328125 }, "model": "sereneseasons:item/season_clock_09" }, 17 | { "predicate": { "time": 0.1484375 }, "model": "sereneseasons:item/season_clock_10" }, 18 | { "predicate": { "time": 0.1640625 }, "model": "sereneseasons:item/season_clock_11" }, 19 | { "predicate": { "time": 0.1796875 }, "model": "sereneseasons:item/season_clock_12" }, 20 | { "predicate": { "time": 0.1953125 }, "model": "sereneseasons:item/season_clock_13" }, 21 | { "predicate": { "time": 0.2109375 }, "model": "sereneseasons:item/season_clock_14" }, 22 | { "predicate": { "time": 0.2265625 }, "model": "sereneseasons:item/season_clock_15" }, 23 | { "predicate": { "time": 0.2421875 }, "model": "sereneseasons:item/season_clock_16" }, 24 | { "predicate": { "time": 0.2578125 }, "model": "sereneseasons:item/season_clock_17" }, 25 | { "predicate": { "time": 0.2734375 }, "model": "sereneseasons:item/season_clock_18" }, 26 | { "predicate": { "time": 0.2890625 }, "model": "sereneseasons:item/season_clock_19" }, 27 | { "predicate": { "time": 0.3046875 }, "model": "sereneseasons:item/season_clock_20" }, 28 | { "predicate": { "time": 0.3203125 }, "model": "sereneseasons:item/season_clock_21" }, 29 | { "predicate": { "time": 0.3359375 }, "model": "sereneseasons:item/season_clock_22" }, 30 | { "predicate": { "time": 0.3515625 }, "model": "sereneseasons:item/season_clock_23" }, 31 | { "predicate": { "time": 0.3671875 }, "model": "sereneseasons:item/season_clock_24" }, 32 | { "predicate": { "time": 0.3828125 }, "model": "sereneseasons:item/season_clock_25" }, 33 | { "predicate": { "time": 0.3984375 }, "model": "sereneseasons:item/season_clock_26" }, 34 | { "predicate": { "time": 0.4140625 }, "model": "sereneseasons:item/season_clock_27" }, 35 | { "predicate": { "time": 0.4296875 }, "model": "sereneseasons:item/season_clock_28" }, 36 | { "predicate": { "time": 0.4453125 }, "model": "sereneseasons:item/season_clock_29" }, 37 | { "predicate": { "time": 0.4609375 }, "model": "sereneseasons:item/season_clock_30" }, 38 | { "predicate": { "time": 0.4765625 }, "model": "sereneseasons:item/season_clock_31" }, 39 | { "predicate": { "time": 0.4921875 }, "model": "sereneseasons:item/season_clock_32" }, 40 | { "predicate": { "time": 0.5078125 }, "model": "sereneseasons:item/season_clock_33" }, 41 | { "predicate": { "time": 0.5234375 }, "model": "sereneseasons:item/season_clock_34" }, 42 | { "predicate": { "time": 0.5390625 }, "model": "sereneseasons:item/season_clock_35" }, 43 | { "predicate": { "time": 0.5546875 }, "model": "sereneseasons:item/season_clock_36" }, 44 | { "predicate": { "time": 0.5703125 }, "model": "sereneseasons:item/season_clock_37" }, 45 | { "predicate": { "time": 0.5859375 }, "model": "sereneseasons:item/season_clock_38" }, 46 | { "predicate": { "time": 0.6015625 }, "model": "sereneseasons:item/season_clock_39" }, 47 | { "predicate": { "time": 0.6171875 }, "model": "sereneseasons:item/season_clock_40" }, 48 | { "predicate": { "time": 0.6328125 }, "model": "sereneseasons:item/season_clock_41" }, 49 | { "predicate": { "time": 0.6484375 }, "model": "sereneseasons:item/season_clock_42" }, 50 | { "predicate": { "time": 0.6640625 }, "model": "sereneseasons:item/season_clock_43" }, 51 | { "predicate": { "time": 0.6796875 }, "model": "sereneseasons:item/season_clock_44" }, 52 | { "predicate": { "time": 0.6953125 }, "model": "sereneseasons:item/season_clock_45" }, 53 | { "predicate": { "time": 0.7109375 }, "model": "sereneseasons:item/season_clock_46" }, 54 | { "predicate": { "time": 0.7265625 }, "model": "sereneseasons:item/season_clock_47" }, 55 | { "predicate": { "time": 0.7421875 }, "model": "sereneseasons:item/season_clock_48" }, 56 | { "predicate": { "time": 0.7578125 }, "model": "sereneseasons:item/season_clock_49" }, 57 | { "predicate": { "time": 0.7734375 }, "model": "sereneseasons:item/season_clock_50" }, 58 | { "predicate": { "time": 0.7890625 }, "model": "sereneseasons:item/season_clock_51" }, 59 | { "predicate": { "time": 0.8046875 }, "model": "sereneseasons:item/season_clock_52" }, 60 | { "predicate": { "time": 0.8203125 }, "model": "sereneseasons:item/season_clock_53" }, 61 | { "predicate": { "time": 0.8359375 }, "model": "sereneseasons:item/season_clock_54" }, 62 | { "predicate": { "time": 0.8515625 }, "model": "sereneseasons:item/season_clock_55" }, 63 | { "predicate": { "time": 0.8671875 }, "model": "sereneseasons:item/season_clock_56" }, 64 | { "predicate": { "time": 0.8828125 }, "model": "sereneseasons:item/season_clock_57" }, 65 | { "predicate": { "time": 0.8984375 }, "model": "sereneseasons:item/season_clock_58" }, 66 | { "predicate": { "time": 0.9140625 }, "model": "sereneseasons:item/season_clock_59" }, 67 | { "predicate": { "time": 0.9296875 }, "model": "sereneseasons:item/season_clock_60" }, 68 | { "predicate": { "time": 0.9453125 }, "model": "sereneseasons:item/season_clock_61" }, 69 | { "predicate": { "time": 0.9609375 }, "model": "sereneseasons:item/season_clock_62" }, 70 | { "predicate": { "time": 0.9765625 }, "model": "sereneseasons:item/season_clock_63" }, 71 | { "predicate": { "time": 0.9921875 }, "model": "sereneseasons:item/season_clock" } 72 | ] 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/sereneseasons/init/ModFertility.java: -------------------------------------------------------------------------------- 1 | package sereneseasons.init; 2 | 3 | import java.util.HashMap; 4 | import java.util.HashSet; 5 | 6 | import net.minecraft.block.Block; 7 | import net.minecraft.block.IGrowable; 8 | import net.minecraft.init.Blocks; 9 | import net.minecraft.item.Item; 10 | import net.minecraft.util.ResourceLocation; 11 | import net.minecraft.util.math.BlockPos; 12 | import net.minecraft.util.text.TextFormatting; 13 | import net.minecraft.world.World; 14 | import net.minecraft.world.biome.Biome; 15 | import net.minecraftforge.common.IPlantable; 16 | import net.minecraftforge.event.entity.player.ItemTooltipEvent; 17 | import net.minecraftforge.fml.common.registry.ForgeRegistries; 18 | import net.minecraftforge.fml.relauncher.Side; 19 | import net.minecraftforge.fml.relauncher.SideOnly; 20 | import sereneseasons.api.season.Season; 21 | import sereneseasons.api.season.SeasonHelper; 22 | import sereneseasons.config.BiomeConfig; 23 | import sereneseasons.config.FertilityConfig; 24 | import sereneseasons.config.SeasonsConfig; 25 | 26 | /** 27 | * Constructs efficient data structures to process, store, and give access to data from the FertilityConfig file 28 | */ 29 | public class ModFertility 30 | { 31 | 32 | private static HashSet springPlants = new HashSet(); 33 | private static HashSet summerPlants = new HashSet(); 34 | private static HashSet autumnPlants = new HashSet(); 35 | private static HashSet winterPlants = new HashSet(); 36 | private static HashSet allListedPlants = new HashSet(); 37 | 38 | //Maps seed name to all fertile seasons via byte 39 | private static HashMap seedSeasons = new HashMap(); 40 | 41 | public static void init() 42 | { 43 | //Store crops in hash sets for quick and easy retrieval 44 | initSeasonCrops(FertilityConfig.seasonal_fertility.spring_crops, springPlants, 1); 45 | initSeasonCrops(FertilityConfig.seasonal_fertility.summer_crops, summerPlants, 2); 46 | initSeasonCrops(FertilityConfig.seasonal_fertility.autumn_crops, autumnPlants, 4); 47 | initSeasonCrops(FertilityConfig.seasonal_fertility.winter_crops, winterPlants, 8); 48 | } 49 | 50 | public static boolean isCropFertile(String cropName, World world, BlockPos pos) 51 | { 52 | //Get season 53 | Season season = SeasonHelper.getSeasonState(world).getSeason(); 54 | Biome biome = world.getBiome(pos); 55 | 56 | if (BiomeConfig.disablesCrops(biome)) 57 | { 58 | return false; 59 | } 60 | else if (!FertilityConfig.general_category.seasonal_crops || !BiomeConfig.enablesSeasonalEffects(biome) || !SeasonsConfig.isDimensionWhitelisted(world.provider.getDimension())) 61 | { 62 | return true; 63 | } 64 | 65 | if (BiomeConfig.usesTropicalSeasons(biome)) 66 | { 67 | if (summerPlants.contains(cropName) || !(allListedPlants.contains(cropName))) 68 | { 69 | return true; 70 | } 71 | else 72 | { 73 | return false; 74 | } 75 | } 76 | else 77 | { 78 | if (biome.getTemperature(pos) < 0.15F) 79 | { 80 | if (winterPlants.contains(cropName)) 81 | { 82 | return true; 83 | } 84 | else 85 | { 86 | return false; 87 | } 88 | } 89 | else 90 | { 91 | if (season == Season.SPRING && springPlants.contains(cropName)) 92 | { 93 | return true; 94 | } 95 | else if (season == Season.SUMMER && summerPlants.contains(cropName)) 96 | { 97 | return true; 98 | } 99 | else if (season == Season.AUTUMN && autumnPlants.contains(cropName)) 100 | { 101 | return true; 102 | } 103 | else if (season == Season.WINTER && winterPlants.contains(cropName)) 104 | { 105 | return true; 106 | } 107 | 108 | //Check if unspecified crops are by default fertile in non-winter, and that it's not winter 109 | if (!allListedPlants.contains(cropName)) 110 | { 111 | if (season == Season.WINTER) 112 | { 113 | return (FertilityConfig.general_category.ignore_unlisted_crops); 114 | } 115 | else 116 | { 117 | return true; 118 | } 119 | } 120 | } 121 | } 122 | 123 | return false; 124 | } 125 | 126 | /** 127 | * Initializes the crops for a particular season. User's responsibility to match seeds and cropSet to be of the 128 | * same season (eg. String [] spring_seeds, HashSet springPlants) 129 | * @param seeds String array of seeds that are fertile during the chosen season 130 | * @param cropSet HashSet that will store the list of crops fertile during the chosen season 131 | */ 132 | private static void initSeasonCrops(String [] seeds, HashSet cropSet, int bitmask) 133 | { 134 | for (String seed : seeds) 135 | { 136 | Item item = ForgeRegistries.ITEMS.getValue(new ResourceLocation(seed)); 137 | 138 | if (item instanceof IPlantable) 139 | { 140 | String plantName = ((IPlantable) item).getPlant(null, null).getBlock().getRegistryName().toString(); 141 | cropSet.add(plantName); 142 | 143 | if (bitmask != 0) 144 | { 145 | allListedPlants.add(plantName); 146 | } 147 | else 148 | { 149 | continue; 150 | } 151 | 152 | //Add to seedSeasons 153 | if (seedSeasons.containsKey(seed)) 154 | { 155 | int seasons = seedSeasons.get(seed); 156 | seedSeasons.put(seed, seasons | bitmask); 157 | } 158 | else 159 | { 160 | seedSeasons.put(seed, bitmask); 161 | } 162 | } 163 | else 164 | { 165 | Block block = ForgeRegistries.BLOCKS.getValue(new ResourceLocation(seed)); 166 | 167 | if (block != null && block != Blocks.AIR) 168 | { 169 | String plantName = block.getRegistryName().toString(); 170 | cropSet.add(plantName); 171 | 172 | if (bitmask != 0) 173 | { 174 | allListedPlants.add(plantName); 175 | } 176 | else 177 | { 178 | continue; 179 | } 180 | 181 | //Add to seedSeasons 182 | if (seedSeasons.containsKey(seed)) 183 | { 184 | int seasons = seedSeasons.get(seed); 185 | seedSeasons.put(seed, seasons | bitmask); 186 | } 187 | else 188 | { 189 | seedSeasons.put(seed, bitmask); 190 | } 191 | } 192 | } 193 | } 194 | } 195 | 196 | @SideOnly(Side.CLIENT) 197 | public static void setupTooltips(ItemTooltipEvent event) 198 | { 199 | //Set up tooltips if enabled and on client side 200 | if (FertilityConfig.general_category.crop_tooltips && FertilityConfig.general_category.seasonal_crops) 201 | { 202 | String name = event.getItemStack().getItem().getRegistryName().toString(); 203 | if (seedSeasons.containsKey(name)) 204 | { 205 | int mask = seedSeasons.get(name); 206 | 207 | event.getToolTip().add("Fertile Seasons:"); 208 | 209 | if ((mask & 1) != 0 && (mask & 2) != 0 && (mask & 4) != 0 && (mask & 8) != 0) 210 | { 211 | event.getToolTip().add(TextFormatting.LIGHT_PURPLE + " Year-Round"); 212 | } 213 | else 214 | { 215 | if ((mask & 1) != 0) 216 | { 217 | event.getToolTip().add(TextFormatting.GREEN + " Spring"); 218 | } 219 | if ((mask & 2) != 0) 220 | { 221 | event.getToolTip().add(TextFormatting.YELLOW + " Summer"); 222 | } 223 | if ((mask & 4) != 0) 224 | { 225 | event.getToolTip().add(TextFormatting.GOLD + " Autumn"); 226 | } 227 | if ((mask & 8) != 0) 228 | { 229 | event.getToolTip().add(TextFormatting.AQUA + " Winter"); 230 | } 231 | } 232 | } 233 | } 234 | } 235 | } 236 | -------------------------------------------------------------------------------- /src/main/java/sereneseasons/block/BlockSeasonSensor.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2016, the Biomes O' Plenty Team 3 | * 4 | * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Public License. 5 | * 6 | * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/. 7 | ******************************************************************************/ 8 | package sereneseasons.block; 9 | 10 | import java.util.Random; 11 | 12 | import net.minecraft.block.Block; 13 | import net.minecraft.block.BlockContainer; 14 | import net.minecraft.block.SoundType; 15 | import net.minecraft.block.material.Material; 16 | import net.minecraft.block.properties.IProperty; 17 | import net.minecraft.block.properties.PropertyInteger; 18 | import net.minecraft.block.state.BlockStateContainer; 19 | import net.minecraft.block.state.IBlockState; 20 | import net.minecraft.entity.player.EntityPlayer; 21 | import net.minecraft.item.Item; 22 | import net.minecraft.item.ItemBlock; 23 | import net.minecraft.tileentity.TileEntity; 24 | import net.minecraft.util.EnumBlockRenderType; 25 | import net.minecraft.util.EnumFacing; 26 | import net.minecraft.util.EnumHand; 27 | import net.minecraft.util.IStringSerializable; 28 | import net.minecraft.util.math.AxisAlignedBB; 29 | import net.minecraft.util.math.BlockPos; 30 | import net.minecraft.world.IBlockAccess; 31 | import net.minecraft.world.World; 32 | import sereneseasons.api.ISSBlock; 33 | import sereneseasons.api.SSBlocks; 34 | import sereneseasons.api.season.SeasonHelper; 35 | import sereneseasons.config.SeasonsConfig; 36 | import sereneseasons.init.ModConfig; 37 | import sereneseasons.item.ItemSSBlock; 38 | import sereneseasons.season.SeasonTime; 39 | import sereneseasons.tileentity.TileEntitySeasonSensor; 40 | 41 | public class BlockSeasonSensor extends BlockContainer implements ISSBlock 42 | { 43 | public static final PropertyInteger POWER = PropertyInteger.create("power", 0, 15); 44 | public static final AxisAlignedBB BOUNDING_BOX = new AxisAlignedBB(0.0D, 0.0D, 0.0D, 1.0D, 0.375D, 1.0D); 45 | 46 | // implement ITANBlock 47 | @Override 48 | public Class getItemClass() { return ItemSSBlock.class; } 49 | @Override 50 | public IProperty[] getPresetProperties() { return new IProperty[] {}; } 51 | @Override 52 | public IProperty[] getNonRenderingProperties() { return new IProperty[] { POWER }; } 53 | @Override 54 | public String getStateName(IBlockState state) 55 | { 56 | return type.getName(); 57 | } 58 | 59 | private final DetectorType type; 60 | 61 | public BlockSeasonSensor(DetectorType type) 62 | { 63 | super(Material.WOOD); 64 | this.type = type; 65 | this.setHardness(0.2F); 66 | this.setSoundType(SoundType.WOOD); 67 | this.setDefaultState( this.blockState.getBaseState().withProperty(POWER, Integer.valueOf(0)) ); 68 | } 69 | 70 | @Override 71 | public AxisAlignedBB getBoundingBox(IBlockState state, IBlockAccess source, BlockPos pos) 72 | { 73 | return BOUNDING_BOX; 74 | } 75 | 76 | @Override 77 | public int getWeakPower(IBlockState blockState, IBlockAccess blockAccess, BlockPos pos, EnumFacing side) 78 | { 79 | return ((Integer)blockState.getValue(POWER)).intValue(); 80 | } 81 | 82 | public void updatePower(World world, BlockPos pos) 83 | { 84 | if (SeasonsConfig.isDimensionWhitelisted(world.provider.getDimension())) 85 | { 86 | IBlockState currentState = world.getBlockState(pos); 87 | 88 | int power = 0; 89 | int startTicks = this.type.ordinal() * SeasonTime.ZERO.getSeasonDuration(); 90 | int endTicks = (this.type.ordinal() + 1) * SeasonTime.ZERO.getSeasonDuration(); 91 | int currentTicks = SeasonHelper.getSeasonState(world).getSeasonCycleTicks(); 92 | 93 | if (currentTicks >= startTicks && currentTicks <= endTicks) 94 | { 95 | float delta = (float)(currentTicks - startTicks) / (float)SeasonTime.ZERO.getSeasonDuration(); 96 | power = (int)Math.min(delta * 15.0F + 1.0F, 15.0F); 97 | } 98 | 99 | //Only update the state if the power level has actually changed 100 | if (((Integer)currentState.getValue(POWER)).intValue() != power) 101 | { 102 | world.setBlockState(pos, currentState.withProperty(POWER, Integer.valueOf(power)), 3); 103 | } 104 | } 105 | } 106 | 107 | @Override 108 | public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer player, EnumHand hand, EnumFacing side, float hitX, float hitY, float hitZ) 109 | { 110 | if (player.isAllowEdit()) 111 | { 112 | if (world.isRemote) 113 | { 114 | return true; 115 | } 116 | else 117 | { 118 | Block nextBlock = SSBlocks.season_sensors[(this.type.ordinal() + 1) % DetectorType.values().length]; 119 | world.setBlockState(pos, nextBlock.getDefaultState().withProperty(POWER, state.getValue(POWER)), 4); 120 | ((BlockSeasonSensor)nextBlock).updatePower(world, pos); 121 | return true; 122 | } 123 | } 124 | else 125 | { 126 | return super.onBlockActivated(world, pos, state, player, hand, side, hitX, hitY, hitZ); 127 | } 128 | } 129 | 130 | @Override 131 | public Item getItemDropped(IBlockState state, Random rand, int fortune) 132 | { 133 | return Item.getItemFromBlock(SSBlocks.season_sensors[0]); 134 | } 135 | 136 | @Override 137 | public boolean isFullCube(IBlockState state) 138 | { 139 | return false; 140 | } 141 | 142 | @Override 143 | public boolean isOpaqueCube(IBlockState state) 144 | { 145 | return false; 146 | } 147 | 148 | @Override 149 | public EnumBlockRenderType getRenderType(IBlockState state) 150 | { 151 | return EnumBlockRenderType.MODEL; 152 | } 153 | 154 | @Override 155 | public boolean canProvidePower(IBlockState state) 156 | { 157 | return true; 158 | } 159 | 160 | @Override 161 | public TileEntity createNewTileEntity(World world, int meta) 162 | { 163 | return new TileEntitySeasonSensor(); 164 | } 165 | 166 | // map from state to meta and vice verca 167 | @Override 168 | public IBlockState getStateFromMeta(int meta) 169 | { 170 | return this.getDefaultState().withProperty(POWER, meta); 171 | } 172 | 173 | @Override 174 | public int getMetaFromState(IBlockState state) 175 | { 176 | return state.getValue(POWER); 177 | } 178 | 179 | @Override 180 | protected BlockStateContainer createBlockState() 181 | { 182 | return new BlockStateContainer(this, new IProperty[] { POWER }); 183 | } 184 | 185 | public static enum DetectorType implements IStringSerializable 186 | { 187 | SPRING, SUMMER, AUTUMN, WINTER; 188 | @Override 189 | public String getName() 190 | { 191 | return this.name().toLowerCase(); 192 | } 193 | @Override 194 | public String toString() 195 | { 196 | return this.getName(); 197 | } 198 | }; 199 | } 200 | -------------------------------------------------------------------------------- /src/main/java/sereneseasons/config/BiomeConfig.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2014-2017, the Biomes O' Plenty Team 3 | * 4 | * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Public License. 5 | * 6 | * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/. 7 | ******************************************************************************/ 8 | package sereneseasons.config; 9 | 10 | import com.google.common.collect.Lists; 11 | import com.google.common.collect.Maps; 12 | import com.google.gson.reflect.TypeToken; 13 | import net.minecraft.util.ResourceLocation; 14 | import net.minecraft.world.biome.Biome; 15 | import net.minecraftforge.fml.common.registry.ForgeRegistries; 16 | import sereneseasons.config.json.BiomeData; 17 | import sereneseasons.util.SeasonColourUtil; 18 | import sereneseasons.util.config.JsonUtil; 19 | 20 | import java.io.File; 21 | import java.util.HashMap; 22 | import java.util.List; 23 | import java.util.Map; 24 | 25 | public class BiomeConfig 26 | { 27 | // We use a HashMap for maximum performance as JsonUtil#getOrCreateConfigFile will return a LinkedHashMap 28 | public static final Map biomeDataMap = Maps.newHashMap(); 29 | 30 | public static void init(File configDir) 31 | { 32 | Map defaultBiomeData = Maps.newHashMap(); 33 | addBlacklistedBiomes(defaultBiomeData); 34 | addTropicalBiomes(defaultBiomeData); 35 | addDisabledCropBiomes(defaultBiomeData); 36 | 37 | biomeDataMap.clear(); 38 | 39 | Map tmpBiomeDataMap = JsonUtil.getOrCreateConfigFile(configDir, "biome_info.json", defaultBiomeData, new TypeToken>(){}.getType()); 40 | 41 | if (tmpBiomeDataMap != null && !tmpBiomeDataMap.isEmpty()) 42 | { 43 | // We convert our keys to ResourceLocations here as to avoid calling `ResourceLocation#toString()` everywhere 44 | // This reduces CPU overhead and garbage collector pressure 45 | for (Map.Entry entry : tmpBiomeDataMap.entrySet()) 46 | { 47 | biomeDataMap.put(new ResourceLocation(entry.getKey()), entry.getValue()); 48 | } 49 | } 50 | } 51 | 52 | public static boolean enablesSeasonalEffects(Biome biome) 53 | { 54 | ResourceLocation name = biome.getRegistryName(); 55 | 56 | if (biomeDataMap.containsKey(name)) 57 | { 58 | return biomeDataMap.get(name).enableSeasonalEffects; 59 | } 60 | 61 | return true; 62 | } 63 | 64 | public static boolean usesTropicalSeasons(Biome biome) 65 | { 66 | ResourceLocation name = biome.getRegistryName(); 67 | 68 | if (biomeDataMap.containsKey(name)) 69 | { 70 | return biomeDataMap.get(name).useTropicalSeasons; 71 | } 72 | 73 | return false; 74 | } 75 | 76 | public static boolean disablesCrops(Biome biome) 77 | { 78 | ResourceLocation name = biome.getRegistryName(); 79 | 80 | if (biomeDataMap.containsKey(name)) 81 | { 82 | return biomeDataMap.get(name).disableCrops; 83 | } 84 | 85 | return false; 86 | } 87 | 88 | private static void addBlacklistedBiomes(Map map) 89 | { 90 | List blacklistedBiomes = Lists.newArrayList("minecraft:mushroom_island", "minecraft:mushroom_island_shore", "minecraft:ocean", 91 | "minecraft:deep_ocean", "minecraft:river", 92 | "biomesoplenty:mystic_grove", "biomesoplenty:ominous_woods", "biomesoplenty:wasteland", "biomesoplenty:flower_island", 93 | "biomesoplenty:coral_reef", "biomesoplenty:kelp_forest", 94 | "thaumcraft:magical_forest", "integrateddynamics:biome_meneglin", "abyssalcraft:darklands", "abyssalcraft:darklands_forest", 95 | "abyssalcraft:darklands_plains", "abyssalcraft:darklands_hills", "abyssalcraft:darklands_mountains", "abyssalcraft:coralium_infested_swamp"); 96 | 97 | for (String biomeName : blacklistedBiomes) 98 | { 99 | if (!map.containsKey(biomeName)) 100 | map.put(biomeName, new BiomeData(false, false, false)); 101 | else 102 | map.get(biomeName).enableSeasonalEffects = false; 103 | } 104 | } 105 | 106 | private static void addTropicalBiomes(Map map) 107 | { 108 | List tropicalBiomes = Lists.newArrayList("minecraft:desert", "minecraft:desert_hills", 109 | "minecraft:mutated_desert", "minecraft:jungle", "minecraft:jungle_hills", "minecraft:jungle_edge", 110 | "minecraft:mutated_jungle", "minecraft:mutated_jungle_edge", "minecraft:mesa", "minecraft:mesa_rock", 111 | "minecraft:mesa_clear_rock", "minecraft:mutated_mesa", "minecraft:mutated_mesa_rock", 112 | "minecraft:mutated_mesa_clear_rock", "minecraft:savanna", "minecraft:savanna_rock", 113 | "minecraft:mutated_savanna", "minecraft:mutated_savanna_rock", "minecraft:mushroom_island", "minecraft:mushroom_island_shore", 114 | 115 | "biomesoplenty:bamboo_forest", "biomesoplenty:bayou", "biomesoplenty:brushland", "biomesoplenty:eucalyptus_forest", 116 | "biomesoplenty:floodplains", "biomesoplenty:lush_desert", "biomesoplenty:mangrove", "biomesoplenty:outback", 117 | "biomesoplenty:overgrown_cliffs", "biomesoplenty:rainforest", "biomesoplenty:sacred_springs", "biomesoplenty:scrubland", 118 | "biomesoplenty:tropical_rainforest", "biomesoplenty:wasteland", "biomesoplenty:xeric_shrubland", "biomesoplenty:flower_island", 119 | "biomesoplenty:tropical_island", "biomesoplenty:volcanic_island", "biomesoplenty:oasis", "biomesoplenty:white_beach", 120 | 121 | "traverse:arid_highland", "traverse:badlands", "traverse:canyon", "traverse:desert_shrubland", "traverse:mini_jungle", 122 | "traverse:mountainous_desert", "traverse:red_desert", 123 | "conquest:bamboo_forest", "conquest:desert_mod", "conquest:jungle_mod", "conquest:mesa_extreme_mod", "conquest:red_desert", 124 | 125 | "climaticbiomesjbg:subtropical_forest", "climaticbiomesjbg:subtropical_forest_hills", "climaticbiomesjbg:tropical_forest", 126 | "climaticbiomesjbg:tropical_forest_hills", "climaticbiomesjbg:pine_swamp", "climaticbiomesjbg:dense_scrub", 127 | "climaticbiomesjbg:dense_scrub_hills", "climaticbiomesjbg:dense_scrub_hills", "climaticbiomesjbg:dry_scrub", 128 | "climaticbiomesjbg:dry_scrub_hills", "climaticbiomesjbg:hot_mountain", "climaticbiomesjbg:hot_mountain_trees"); 129 | 130 | for (String biomeName : tropicalBiomes) 131 | { 132 | if (!map.containsKey(biomeName)) 133 | map.put(biomeName, new BiomeData(true, true, false)); 134 | else 135 | map.get(biomeName).useTropicalSeasons = true; 136 | } 137 | } 138 | 139 | private static void addDisabledCropBiomes(Map map) 140 | { 141 | List disabledCropBiomes = Lists.newArrayList("biomesoplenty:crag", "biomesoplenty:wasteland", "biomesoplenty:volcanic_island"); 142 | 143 | for (String biomeName : disabledCropBiomes) 144 | { 145 | if (!map.containsKey(biomeName)) 146 | map.put(biomeName, new BiomeData(false, false, true)); 147 | else 148 | map.get(biomeName).disableCrops = true; 149 | } 150 | } 151 | } 152 | -------------------------------------------------------------------------------- /src/main/java/sereneseasons/handler/season/SeasonHandler.java: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright 2016, the Biomes O' Plenty Team 3 | * 4 | * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Public License. 5 | * 6 | * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/. 7 | ******************************************************************************/ 8 | package sereneseasons.handler.season; 9 | 10 | import java.util.HashMap; 11 | 12 | import net.minecraft.client.Minecraft; 13 | import net.minecraft.entity.player.EntityPlayer; 14 | import net.minecraft.init.Blocks; 15 | import net.minecraft.server.MinecraftServer; 16 | import net.minecraft.util.math.BlockPos; 17 | import net.minecraft.world.World; 18 | import net.minecraft.world.storage.MapStorage; 19 | import net.minecraftforge.event.terraingen.PopulateChunkEvent; 20 | import net.minecraftforge.fml.common.eventhandler.Event; 21 | import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; 22 | import net.minecraftforge.fml.common.gameevent.PlayerEvent.PlayerLoggedInEvent; 23 | import net.minecraftforge.fml.common.gameevent.TickEvent; 24 | import sereneseasons.api.config.SeasonsOption; 25 | import sereneseasons.api.config.SyncedConfig; 26 | import sereneseasons.api.season.ISeasonState; 27 | import sereneseasons.api.season.Season; 28 | import sereneseasons.api.season.SeasonHelper; 29 | import sereneseasons.config.SeasonsConfig; 30 | import sereneseasons.handler.PacketHandler; 31 | import sereneseasons.network.message.MessageSyncSeasonCycle; 32 | import sereneseasons.season.SeasonASMHelper; 33 | import sereneseasons.season.SeasonSavedData; 34 | import sereneseasons.season.SeasonTime; 35 | 36 | public class SeasonHandler implements SeasonHelper.ISeasonDataProvider 37 | { 38 | @SubscribeEvent 39 | public void onWorldTick(TickEvent.WorldTickEvent event) 40 | { 41 | World world = event.world; 42 | 43 | if (event.phase == TickEvent.Phase.END && !world.isRemote) 44 | { 45 | if (!SyncedConfig.getBooleanValue(SeasonsOption.PROGRESS_SEASON_WHILE_OFFLINE)) 46 | { 47 | MinecraftServer server = world.getMinecraftServer(); 48 | if (server != null && server.getPlayerList().getCurrentPlayerCount() == 0) 49 | return; 50 | } 51 | 52 | SeasonSavedData savedData = getSeasonSavedData(world); 53 | 54 | if (savedData.seasonCycleTicks++ > SeasonTime.ZERO.getCycleDuration()) 55 | { 56 | savedData.seasonCycleTicks = 0; 57 | } 58 | 59 | if (savedData.seasonCycleTicks % 20 == 0) 60 | { 61 | sendSeasonUpdate(world); 62 | } 63 | 64 | savedData.markDirty(); 65 | } 66 | } 67 | 68 | @SubscribeEvent 69 | public void onPlayerLogin(PlayerLoggedInEvent event) 70 | { 71 | EntityPlayer player = event.player; 72 | World world = player.world; 73 | 74 | sendSeasonUpdate(world); 75 | } 76 | 77 | private Season.SubSeason lastSeason = null; 78 | public static final HashMap clientSeasonCycleTicks = new HashMap<>(); 79 | public static SeasonTime getClientSeasonTime() { 80 | Integer i = clientSeasonCycleTicks.get(0); 81 | return new SeasonTime(i == null ? 0 : i); 82 | } 83 | 84 | @SubscribeEvent 85 | public void onClientTick(TickEvent.ClientTickEvent event) 86 | { 87 | //Only do this when in the world 88 | if (Minecraft.getMinecraft().player == null) return; 89 | 90 | int dimension = Minecraft.getMinecraft().player.dimension; 91 | 92 | if (event.phase == TickEvent.Phase.END && SeasonsConfig.isDimensionWhitelisted(dimension)) 93 | { 94 | clientSeasonCycleTicks.compute(dimension, (k, v) -> v == null ? 0 : v + 1); 95 | 96 | //Keep ticking as we're synchronized with the server only every second 97 | if (clientSeasonCycleTicks.get(dimension) > SeasonTime.ZERO.getCycleDuration()) 98 | { 99 | clientSeasonCycleTicks.put(dimension, 0); 100 | } 101 | 102 | SeasonTime calendar = new SeasonTime(clientSeasonCycleTicks.get(dimension)); 103 | 104 | if (calendar.getSubSeason() != lastSeason) 105 | { 106 | Minecraft.getMinecraft().renderGlobal.loadRenderers(); 107 | lastSeason = calendar.getSubSeason(); 108 | } 109 | } 110 | } 111 | 112 | @SubscribeEvent 113 | public void onPopulateChunk(PopulateChunkEvent.Populate event) 114 | { 115 | if (!event.getWorld().isRemote && event.getType() != PopulateChunkEvent.Populate.EventType.ICE || !SeasonsConfig.isDimensionWhitelisted(event.getWorld().provider.getDimension())) 116 | return; 117 | 118 | event.setResult(Event.Result.DENY); 119 | BlockPos blockpos = new BlockPos(event.getChunkX() * 16, 0, event.getChunkZ() * 16).add(8, 0, 8); 120 | 121 | for (int k2 = 0; k2 < 16; ++k2) 122 | { 123 | for (int j3 = 0; j3 < 16; ++j3) 124 | { 125 | BlockPos blockpos1 = event.getWorld().getPrecipitationHeight(blockpos.add(k2, 0, j3)); 126 | BlockPos blockpos2 = blockpos1.down(); 127 | 128 | if (SeasonASMHelper.canBlockFreezeInSeason(event.getWorld(), blockpos2, false, SeasonHelper.getSeasonState(event.getWorld()), true)) 129 | { 130 | event.getWorld().setBlockState(blockpos2, Blocks.ICE.getDefaultState(), 2); 131 | } 132 | 133 | if (SeasonASMHelper.canSnowAtInSeason(event.getWorld(), blockpos1, true, SeasonHelper.getSeasonState(event.getWorld()), true)) 134 | { 135 | event.getWorld().setBlockState(blockpos1, Blocks.SNOW_LAYER.getDefaultState(), 2); 136 | } 137 | } 138 | } 139 | } 140 | 141 | public static void sendSeasonUpdate(World world) 142 | { 143 | if (!world.isRemote) 144 | { 145 | SeasonSavedData savedData = getSeasonSavedData(world); 146 | PacketHandler.instance.sendToAll(new MessageSyncSeasonCycle(world.provider.getDimension(), savedData.seasonCycleTicks)); 147 | } 148 | } 149 | 150 | public static SeasonSavedData getSeasonSavedData(World world) 151 | { 152 | MapStorage mapStorage = world.getPerWorldStorage(); 153 | SeasonSavedData savedData = (SeasonSavedData)mapStorage.getOrLoadData(SeasonSavedData.class, SeasonSavedData.DATA_IDENTIFIER); 154 | 155 | //If the saved data file hasn't been created before, create it 156 | if (savedData == null) 157 | { 158 | savedData = new SeasonSavedData(SeasonSavedData.DATA_IDENTIFIER); 159 | 160 | int startingSeason = SyncedConfig.getIntValue(SeasonsOption.STARTING_SUB_SEASON); 161 | 162 | if (startingSeason == 0) 163 | { 164 | savedData.seasonCycleTicks = (world.rand.nextInt(12)) * SeasonTime.ZERO.getSubSeasonDuration(); 165 | } 166 | if (startingSeason > 0) 167 | { 168 | savedData.seasonCycleTicks = (startingSeason - 1) * SeasonTime.ZERO.getSubSeasonDuration(); 169 | } 170 | 171 | mapStorage.setData(SeasonSavedData.DATA_IDENTIFIER, savedData); 172 | savedData.markDirty(); //Mark for saving 173 | } 174 | 175 | return savedData; 176 | } 177 | 178 | // 179 | // Used to implement getSeasonState in the API 180 | // 181 | 182 | public ISeasonState getServerSeasonState(World world) 183 | { 184 | SeasonSavedData savedData = getSeasonSavedData(world); 185 | return new SeasonTime(savedData.seasonCycleTicks); 186 | } 187 | 188 | public ISeasonState getClientSeasonState() 189 | { 190 | Integer i = clientSeasonCycleTicks.get(0); 191 | return new SeasonTime(i == null ? 0 : i); 192 | } 193 | } 194 | --------------------------------------------------------------------------------