001/* 002 * Trident - A Multithreaded Server Alternative 003 * Copyright 2014 The TridentSDK Team 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package net.tridentsdk.world.settings; 018 019import net.tridentsdk.docs.AccessNoDoc; 020 021import javax.annotation.concurrent.Immutable; 022 023/** 024 * Gamerules are applied on a per-world basis and are options for more advanced/low-level properties of the world 025 * such as command blocks, drops, and inventory modifiers 026 * 027 * <p>The default value for all game rules is {@code true} except for {@link #REDUCED_DEBUG_INFO} and 028 * {@link #KEEP_INVENTORY}, which are both {@code false} by default</p> 029 * 030 * @author The TridentSDK Team 031 * @since 0.4-alpha 032 */ 033public enum GameRule { 034 /** 035 * Whether command blocks should notify admins when they perform commands 036 */ 037 COMMAND_BLOCK_OUTPUT("commandBlockOutput", Value.of(true)), 038 /** 039 * Whether time progresses 040 */ 041 DO_DAYLIGHT_CYCLE("doDaylightCycle", Value.of(true)), 042 /** 043 * Whether entities that are not mobs should have drops 044 */ 045 DO_ENTITY_DROPS("doEntityDrops", Value.of(true)), 046 /** 047 * Whether fire should spread and naturally extinguish 048 */ 049 DO_FIRE_TICK("doFireTick", Value.of(true)), 050 /** 051 * Whether mobs should drop items 052 */ 053 DO_MOB_LOOT("doMobLoot", Value.of(true)), 054 /** 055 * Whether mobs should naturally spawn 056 */ 057 DO_MOB_SPAWNING("doMobSpawning", Value.of(true)), 058 /** 059 * Whether blocks should have drops 060 */ 061 DO_TILE_DROPS("doTileDrops", Value.of(true)), 062 /** 063 * Whether the player should keep items in their inventory after death 064 */ 065 KEEP_INVENTORY("keepInventory", Value.of(false)), 066 /** 067 * Whether to log admin commands to server log 068 */ 069 LOG_ADMIN_COMMANDS("logAdminCommands", Value.of(true)), 070 /** 071 * Whether creepers, zombies, endermen, ghasts, withers, ender dragons, rabbits, sheep, 072 * and villagers should be able to change blocks and whether villagers, zombies, skeletons, 073 * and zombie pigmen can pick up items 074 */ 075 MOB_GRIEFING("mobGriefing", Value.of(true)), 076 /** 077 * Whether the player can regenerate health naturally if their hunger is full enough (doesn't affect external 078 * healing, such as golden apples, the Regeneration effect, etc.) 079 */ 080 NATURAL_REGENERATION("naturalRegeneration", Value.of(true)), 081 /** 082 * How often a random block tick occurs (such as plant growth, leaf decay, etc.) per chunk section per game tick. 083 * 084 * <p>Default value: {@code 3}</p> 085 * 086 * <p>0 will disable random ticks, higher numbers will increase random ticks</p> 087 */ 088 RANDOM_TICK_SPEED("randomTickSpeed", Value.of(3)), 089 /** 090 * Whether the debug screen shows all or reduced information 091 */ 092 REDUCED_DEBUG_INFO("reducedDebugInfo", Value.of(false)), 093 /** 094 * Whether the feedback from commands executed by a player should show up in chat. Also affects the default behavior 095 * of whether command blocks store their output text 096 */ 097 SEND_COMMAND_FEEDBACK("sendCommandFeedback", Value.of(true)), 098 /** 099 * Whether a message appears in chat when a player dies 100 */ 101 SHOW_DEATH_MESSAGES("showDeathMessages", Value.of(true)), 102 /** 103 * Whether players in spectator mode can generate chunks 104 */ 105 SPECTATORS_GENERATE_CHUNKS("spectatorsGenerateChunks", Value.of(true)); 106 107 private final Value defValue; 108 private final String raw; 109 GameRule(String raw, Value defValue) { 110 this.raw = raw; 111 this.defValue = defValue; 112 } 113 114 /** 115 * Obtains the default value of the game rule 116 * 117 * @return the default value 118 */ 119 public Value defaultValue() { 120 return defValue; 121 } 122 123 /** 124 * Checks if the argument matches the default value 125 * 126 * @param b the boolean to check 127 * @return {@code true} if it matches, {@code false} otherwise 128 */ 129 public boolean boolEqualToValue(boolean b) { 130 if (defValue.isInteger()) { 131 throw new IllegalStateException("Value is an integer"); 132 } 133 134 return defValue.asBoolean() == b; 135 } 136 137 /** 138 * Checks if the argument matches the default value 139 * 140 * @param i the integer to check 141 * @return {@code true} if it matches, {@code false} otherwise 142 */ 143 public boolean intEqualToValue(int i) { 144 if (defValue.isBoolean()) { 145 throw new IllegalStateException("Value is a boolean"); 146 } 147 148 return defValue.asInt() == i; 149 } 150 151 @Override 152 public String toString() { 153 return raw; 154 } 155 156 /** 157 * Represents a value which can be possessed by the game rule 158 * 159 * @author The TridentSDK Team 160 */ 161 @Immutable 162 public static class Value { 163 private final ValueType type; 164 private final boolean bool; 165 private final int integer; 166 167 private Value(boolean bool) { 168 this.type = ValueType.BOOLEAN; 169 this.bool = bool; 170 this.integer = 0; 171 } 172 173 private Value(int integer) { 174 this.type = ValueType.INTEGER; 175 this.integer = integer; 176 this.bool = false; 177 } 178 179 /** 180 * Creates a new game rule value that takes an integer parameter 181 * 182 * @param integer the game rule parameter 183 * @return the wrapped value 184 */ 185 public static Value of(int integer) { 186 return new Value(integer); 187 } 188 189 /** 190 * Creates a new game rule value that takes a boolean parameter 191 * 192 * @param bool the game rule parameter 193 * @return the wrapped value 194 */ 195 public static Value of(boolean bool) { 196 return new Value(bool); 197 } 198 199 /** 200 * Checks to see whether this value is an integer 201 * 202 * @return {@code true} if it is an integer, {@code false} if it is a boolean 203 */ 204 public boolean isInteger() { 205 return type == ValueType.INTEGER; 206 } 207 208 /** 209 * Checks to see whether this value is a boolean 210 * 211 * @return {@code true} if it is a boolean, {@code false} if it is an integer 212 */ 213 public boolean isBoolean() { 214 return type == ValueType.BOOLEAN; 215 } 216 217 /** 218 * Obtains the boolean value 219 * 220 * @return the boolean value 221 */ 222 public boolean asBoolean() { 223 if (type != ValueType.BOOLEAN) { 224 throw new IllegalStateException("Value type not a boolean"); 225 } 226 return bool; 227 } 228 229 /** 230 * Obtains the integer value 231 * 232 * @return the integer value 233 */ 234 public int asInt() { 235 if (type != ValueType.INTEGER) { 236 throw new IllegalStateException("Value type not an integer"); 237 } 238 return integer; 239 } 240 } 241 242 @AccessNoDoc 243 private enum ValueType { 244 INTEGER, BOOLEAN 245 } 246}