001/*
002 * This file is part of Baritone.
003 *
004 * Baritone is free software: you can redistribute it and/or modify
005 * it under the terms of the GNU Lesser General Public License as published by
006 * the Free Software Foundation, either version 3 of the License, or
007 * (at your option) any later version.
008 *
009 * Baritone is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
012 * GNU Lesser General Public License for more details.
013 *
014 * You should have received a copy of the GNU Lesser General Public License
015 * along with Baritone.  If not, see <https://www.gnu.org/licenses/>.
016 */
017
018package baritone.api;
019
020import baritone.api.utils.NotificationHelper;
021import baritone.api.utils.SettingsUtil;
022import baritone.api.utils.TypeUtils;
023import baritone.api.utils.gui.BaritoneToast;
024import net.minecraft.block.Block;
025import net.minecraft.client.Minecraft;
026import net.minecraft.init.Blocks;
027import net.minecraft.item.Item;
028import net.minecraft.util.math.Vec3i;
029import net.minecraft.util.text.ITextComponent;
030
031import java.awt.*;
032import java.lang.reflect.Field;
033import java.lang.reflect.ParameterizedType;
034import java.lang.reflect.Type;
035import java.util.List;
036import java.util.*;
037import java.util.function.Consumer;
038import java.util.function.BiConsumer;
039
040/**
041 * Baritone's settings. Settings apply to all Baritone instances.
042 *
043 * @author leijurv
044 */
045public final class Settings {
046
047    /**
048     * Allow Baritone to break blocks
049     */
050    public final Setting<Boolean> allowBreak = new Setting<>(true);
051
052    /**
053     * Blocks that baritone will be allowed to break even with allowBreak set to false
054     */
055    public final Setting<List<Block>> allowBreakAnyway = new Setting<>(new ArrayList<>());
056
057    /**
058     * Allow Baritone to sprint
059     */
060    public final Setting<Boolean> allowSprint = new Setting<>(true);
061
062    /**
063     * Allow Baritone to place blocks
064     */
065    public final Setting<Boolean> allowPlace = new Setting<>(true);
066
067    /**
068     * Allow Baritone to move items in your inventory to your hotbar
069     */
070    public final Setting<Boolean> allowInventory = new Setting<>(false);
071
072    /**
073     * Disable baritone's auto-tool at runtime, but still assume that another mod will provide auto tool functionality
074     * <p>
075     * Specifically, path calculation will still assume that an auto tool will run at execution time, even though
076     * Baritone itself will not do that.
077     */
078    public final Setting<Boolean> assumeExternalAutoTool = new Setting<>(false);
079
080    /**
081     * Automatically select the best available tool
082     */
083    public final Setting<Boolean> autoTool = new Setting<>(true);
084
085    /**
086     * It doesn't actually take twenty ticks to place a block, this cost is so high
087     * because we want to generally conserve blocks which might be limited.
088     * <p>
089     * Decrease to make Baritone more often consider paths that would require placing blocks
090     */
091    public final Setting<Double> blockPlacementPenalty = new Setting<>(20D);
092
093    /**
094     * This is just a tiebreaker to make it less likely to break blocks if it can avoid it.
095     * For example, fire has a break cost of 0, this makes it nonzero, so all else being equal
096     * it will take an otherwise equivalent route that doesn't require it to put out fire.
097     */
098    public final Setting<Double> blockBreakAdditionalPenalty = new Setting<>(2D);
099
100    /**
101     * Additional penalty for hitting the space bar (ascend, pillar, or parkour) because it uses hunger
102     */
103    public final Setting<Double> jumpPenalty = new Setting<>(2D);
104
105    /**
106     * Walking on water uses up hunger really quick, so penalize it
107     */
108    public final Setting<Double> walkOnWaterOnePenalty = new Setting<>(3D);
109
110    /**
111     * Allow Baritone to fall arbitrary distances and place a water bucket beneath it.
112     * Reliability: questionable.
113     */
114    public final Setting<Boolean> allowWaterBucketFall = new Setting<>(true);
115
116    /**
117     * Allow Baritone to assume it can walk on still water just like any other block.
118     * This functionality is assumed to be provided by a separate library that might have imported Baritone.
119     */
120    public final Setting<Boolean> assumeWalkOnWater = new Setting<>(false);
121
122    /**
123     * If you have Fire Resistance and Jesus then I guess you could turn this on lol
124     */
125    public final Setting<Boolean> assumeWalkOnLava = new Setting<>(false);
126
127    /**
128     * Assume step functionality; don't jump on an Ascend.
129     */
130    public final Setting<Boolean> assumeStep = new Setting<>(false);
131
132    /**
133     * Assume safe walk functionality; don't sneak on a backplace traverse.
134     * <p>
135     * Warning: if you do something janky like sneak-backplace from an ender chest, if this is true
136     * it won't sneak right click, it'll just right click, which means it'll open the chest instead of placing
137     * against it. That's why this defaults to off.
138     */
139    public final Setting<Boolean> assumeSafeWalk = new Setting<>(false);
140
141    /**
142     * If true, parkour is allowed to make jumps when standing on blocks at the maximum height, so player feet is y=256
143     * <p>
144     * Defaults to false because this fails on constantiam. Please let me know if this is ever disabled. Please.
145     */
146    public final Setting<Boolean> allowJumpAt256 = new Setting<>(false);
147
148    /**
149     * This should be monetized it's so good
150     * <p>
151     * Defaults to true, but only actually takes effect if allowParkour is also true
152     */
153    public final Setting<Boolean> allowParkourAscend = new Setting<>(true);
154
155    /**
156     * Allow descending diagonally
157     * <p>
158     * Safer than allowParkour yet still slightly unsafe, can make contact with unchecked adjacent blocks, so it's unsafe in the nether.
159     * <p>
160     * For a generic "take some risks" mode I'd turn on this one, parkour, and parkour place.
161     */
162    public final Setting<Boolean> allowDiagonalDescend = new Setting<>(false);
163
164    /**
165     * Allow diagonal ascending
166     * <p>
167     * Actually pretty safe, much safer than diagonal descend tbh
168     */
169    public final Setting<Boolean> allowDiagonalAscend = new Setting<>(false);
170
171    /**
172     * Allow mining the block directly beneath its feet
173     * <p>
174     * Turn this off to force it to make more staircases and less shafts
175     */
176    public final Setting<Boolean> allowDownward = new Setting<>(true);
177
178    /**
179     * Blocks that Baritone is allowed to place (as throwaway, for sneak bridging, pillaring, etc.)
180     */
181    public final Setting<List<Item>> acceptableThrowawayItems = new Setting<>(new ArrayList<>(Arrays.asList(
182            Item.getItemFromBlock(Blocks.DIRT),
183            Item.getItemFromBlock(Blocks.COBBLESTONE),
184            Item.getItemFromBlock(Blocks.NETHERRACK),
185            Item.getItemFromBlock(Blocks.STONE)
186    )));
187
188    /**
189     * Blocks that Baritone will attempt to avoid (Used in avoidance)
190     */
191    public final Setting<List<Block>> blocksToAvoid = new Setting<>(new ArrayList<>(
192            // Leave Empty by Default
193    ));
194
195    /**
196     * Blocks that Baritone is not allowed to break
197     */
198    public final Setting<List<Block>> blocksToDisallowBreaking = new Setting<>(new ArrayList<>(
199        // Leave Empty by Default
200    ));
201
202    /**
203     * blocks that baritone shouldn't break, but can if it needs to.
204     */
205    public final Setting<List<Block>> blocksToAvoidBreaking = new Setting<>(new ArrayList<>(Arrays.asList( // TODO can this be a HashSet or ImmutableSet?
206            Blocks.CRAFTING_TABLE,
207            Blocks.FURNACE,
208            Blocks.LIT_FURNACE,
209            Blocks.CHEST,
210            Blocks.TRAPPED_CHEST,
211            Blocks.STANDING_SIGN,
212            Blocks.WALL_SIGN
213    )));
214
215    /**
216     * this multiplies the break speed, if set above 1 it's "encourage breaking" instead
217     */
218    public final Setting<Double> avoidBreakingMultiplier = new Setting<>(.1);
219
220    /**
221     * A list of blocks to be treated as if they're air.
222     * <p>
223     * If a schematic asks for air at a certain position, and that position currently contains a block on this list, it will be treated as correct.
224     */
225    public final Setting<List<Block>> buildIgnoreBlocks = new Setting<>(new ArrayList<>(Arrays.asList(
226
227    )));
228
229    /**
230     * A list of blocks to be treated as correct.
231     * <p>
232     * If a schematic asks for any block on this list at a certain position, it will be treated as correct, regardless of what it currently is.
233     */
234    public final Setting<List<Block>> buildSkipBlocks = new Setting<>(new ArrayList<>(Arrays.asList(
235
236    )));
237
238    /**
239     * A mapping of blocks to blocks treated as correct in their position
240     * <p>
241     * If a schematic asks for a block on this mapping, all blocks on the mapped list will be accepted at that location as well
242     * <p>
243     * Syntax same as <a href="https://baritone.leijurv.com/baritone/api/Settings.html#buildSubstitutes">buildSubstitutes</a>
244     */
245    public final Setting<Map<Block, List<Block>>> buildValidSubstitutes = new Setting<>(new HashMap<>());
246
247    /**
248     * A mapping of blocks to blocks to be built instead
249     * <p>
250     * If a schematic asks for a block on this mapping, Baritone will place the first placeable block in the mapped list
251     * <p>
252     * Usage Syntax:
253     * <pre>
254     *      sourceblockA->blockToSubstituteA1,blockToSubstituteA2,...blockToSubstituteAN,sourceBlockB->blockToSubstituteB1,blockToSubstituteB2,...blockToSubstituteBN,...sourceBlockX->blockToSubstituteX1,blockToSubstituteX2...blockToSubstituteXN
255     * </pre>
256     * Example:
257     * <pre>
258     *     stone->cobblestone,andesite,oak_planks->birch_planks,acacia_planks,glass
259     * </pre>
260     */
261    public final Setting<Map<Block, List<Block>>> buildSubstitutes = new Setting<>(new HashMap<>());
262
263    /**
264     * A list of blocks to become air
265     * <p>
266     * If a schematic asks for a block on this list, only air will be accepted at that location (and nothing on buildIgnoreBlocks)
267     */
268    public final Setting<List<Block>> okIfAir = new Setting<>(new ArrayList<>(Arrays.asList(
269
270    )));
271
272    /**
273     * If this is true, the builder will treat all non-air blocks as correct. It will only place new blocks.
274     */
275    public final Setting<Boolean> buildIgnoreExisting = new Setting<>(false);
276
277    /**
278     * If this is true, the builder will ignore directionality of certain blocks like glazed terracotta.
279     */
280    public final Setting<Boolean> buildIgnoreDirection = new Setting<>(false);
281
282    /**
283     * A list of names of block properties the builder will ignore.
284     */
285    public final Setting<List<String>> buildIgnoreProperties = new Setting<>(new ArrayList<>(Arrays.asList(
286    )));
287
288    /**
289     * If this setting is true, Baritone will never break a block that is adjacent to an unsupported falling block.
290     * <p>
291     * I.E. it will never trigger cascading sand / gravel falls
292     */
293    public final Setting<Boolean> avoidUpdatingFallingBlocks = new Setting<>(true);
294
295    /**
296     * Enables some more advanced vine features. They're honestly just gimmicks and won't ever be needed in real
297     * pathing scenarios. And they can cause Baritone to get trapped indefinitely in a strange scenario.
298     * <p>
299     * Almost never turn this on lol
300     */
301    public final Setting<Boolean> allowVines = new Setting<>(false);
302
303    /**
304     * Slab behavior is complicated, disable this for higher path reliability. Leave enabled if you have bottom slabs
305     * everywhere in your base.
306     */
307    public final Setting<Boolean> allowWalkOnBottomSlab = new Setting<>(true);
308
309    /**
310     * You know what it is
311     * <p>
312     * But it's very unreliable and falls off when cornering like all the time so.
313     * <p>
314     * It also overshoots the landing pretty much always (making contact with the next block over), so be careful
315     */
316    public final Setting<Boolean> allowParkour = new Setting<>(false);
317
318    /**
319     * Actually pretty reliable.
320     * <p>
321     * Doesn't make it any more dangerous compared to just normal allowParkour th
322     */
323    public final Setting<Boolean> allowParkourPlace = new Setting<>(false);
324
325    /**
326     * For example, if you have Mining Fatigue or Haste, adjust the costs of breaking blocks accordingly.
327     */
328    public final Setting<Boolean> considerPotionEffects = new Setting<>(true);
329
330    /**
331     * Sprint and jump a block early on ascends wherever possible
332     */
333    public final Setting<Boolean> sprintAscends = new Setting<>(true);
334
335    /**
336     * If we overshoot a traverse and end up one block beyond the destination, mark it as successful anyway.
337     * <p>
338     * This helps with speed exceeding 20m/s
339     */
340    public final Setting<Boolean> overshootTraverse = new Setting<>(true);
341
342    /**
343     * When breaking blocks for a movement, wait until all falling blocks have settled before continuing
344     */
345    public final Setting<Boolean> pauseMiningForFallingBlocks = new Setting<>(true);
346
347    /**
348     * How many ticks between right clicks are allowed. Default in game is 4
349     */
350    public final Setting<Integer> rightClickSpeed = new Setting<>(4);
351
352    /**
353     * Block reach distance
354     */
355    public final Setting<Float> blockReachDistance = new Setting<>(4.5f);
356
357    /**
358     * How many degrees to randomize the pitch and yaw every tick. Set to 0 to disable
359     */
360    public final Setting<Double> randomLooking = new Setting<>(0.01d);
361
362    /**
363     * This is the big A* setting.
364     * As long as your cost heuristic is an *underestimate*, it's guaranteed to find you the best path.
365     * 3.5 is always an underestimate, even if you are sprinting.
366     * If you're walking only (with allowSprint off) 4.6 is safe.
367     * Any value below 3.5 is never worth it. It's just more computation to find the same path, guaranteed.
368     * (specifically, it needs to be strictly slightly less than ActionCosts.WALK_ONE_BLOCK_COST, which is about 3.56)
369     * <p>
370     * Setting it at 3.57 or above with sprinting, or to 4.64 or above without sprinting, will result in
371     * faster computation, at the cost of a suboptimal path. Any value above the walk / sprint cost will result
372     * in it going straight at its goal, and not investigating alternatives, because the combined cost / heuristic
373     * metric gets better and better with each block, instead of slightly worse.
374     * <p>
375     * Finding the optimal path is worth it, so it's the default.
376     */
377    public final Setting<Double> costHeuristic = new Setting<>(3.563);
378
379    // a bunch of obscure internal A* settings that you probably don't want to change
380    /**
381     * The maximum number of times it will fetch outside loaded or cached chunks before assuming that
382     * pathing has reached the end of the known area, and should therefore stop.
383     */
384    public final Setting<Integer> pathingMaxChunkBorderFetch = new Setting<>(50);
385
386    /**
387     * Set to 1.0 to effectively disable this feature
388     *
389     * @see <a href="https://github.com/cabaletta/baritone/issues/18">Issue #18</a>
390     */
391    public final Setting<Double> backtrackCostFavoringCoefficient = new Setting<>(0.5);
392
393    /**
394     * Toggle the following 4 settings
395     * <p>
396     * They have a noticeable performance impact, so they default off
397     * <p>
398     * Specifically, building up the avoidance map on the main thread before pathing starts actually takes a noticeable
399     * amount of time, especially when there are a lot of mobs around, and your game jitters for like 200ms while doing so
400     */
401    public final Setting<Boolean> avoidance = new Setting<>(false);
402
403    /**
404     * Set to 1.0 to effectively disable this feature
405     * <p>
406     * Set below 1.0 to go out of your way to walk near mob spawners
407     */
408    public final Setting<Double> mobSpawnerAvoidanceCoefficient = new Setting<>(2.0);
409
410    /**
411     * Distance to avoid mob spawners.
412     */
413    public final Setting<Integer> mobSpawnerAvoidanceRadius = new Setting<>(16);
414
415    /**
416     * Set to 1.0 to effectively disable this feature
417     * <p>
418     * Set below 1.0 to go out of your way to walk near mobs
419     */
420    public final Setting<Double> mobAvoidanceCoefficient = new Setting<>(1.5);
421
422    /**
423     * Distance to avoid mobs.
424     */
425    public final Setting<Integer> mobAvoidanceRadius = new Setting<>(8);
426
427    /**
428     * When running a goto towards a container block (chest, ender chest, furnace, etc),
429     * right click and open it once you arrive.
430     */
431    public final Setting<Boolean> rightClickContainerOnArrival = new Setting<>(true);
432
433    /**
434     * When running a goto towards a nether portal block, walk all the way into the portal
435     * instead of stopping one block before.
436     */
437    public final Setting<Boolean> enterPortal = new Setting<>(true);
438
439    /**
440     * Don't repropagate cost improvements below 0.01 ticks. They're all just floating point inaccuracies,
441     * and there's no point.
442     */
443    public final Setting<Boolean> minimumImprovementRepropagation = new Setting<>(true);
444
445    /**
446     * After calculating a path (potentially through cached chunks), artificially cut it off to just the part that is
447     * entirely within currently loaded chunks. Improves path safety because cached chunks are heavily simplified.
448     * <p>
449     * This is much safer to leave off now, and makes pathing more efficient. More explanation in the issue.
450     *
451     * @see <a href="https://github.com/cabaletta/baritone/issues/114">Issue #114</a>
452     */
453    public final Setting<Boolean> cutoffAtLoadBoundary = new Setting<>(false);
454
455    /**
456     * If a movement's cost increases by more than this amount between calculation and execution (due to changes
457     * in the environment / world), cancel and recalculate
458     */
459    public final Setting<Double> maxCostIncrease = new Setting<>(10D);
460
461    /**
462     * Stop 5 movements before anything that made the path COST_INF.
463     * For example, if lava has spread across the path, don't walk right up to it then recalculate, it might
464     * still be spreading lol
465     */
466    public final Setting<Integer> costVerificationLookahead = new Setting<>(5);
467
468    /**
469     * Static cutoff factor. 0.9 means cut off the last 10% of all paths, regardless of chunk load state
470     */
471    public final Setting<Double> pathCutoffFactor = new Setting<>(0.9);
472
473    /**
474     * Only apply static cutoff for paths of at least this length (in terms of number of movements)
475     */
476    public final Setting<Integer> pathCutoffMinimumLength = new Setting<>(30);
477
478    /**
479     * Start planning the next path once the remaining movements tick estimates sum up to less than this value
480     */
481    public final Setting<Integer> planningTickLookahead = new Setting<>(150);
482
483    /**
484     * Default size of the Long2ObjectOpenHashMap used in pathing
485     */
486    public final Setting<Integer> pathingMapDefaultSize = new Setting<>(1024);
487
488    /**
489     * Load factor coefficient for the Long2ObjectOpenHashMap used in pathing
490     * <p>
491     * Decrease for faster map operations, but higher memory usage
492     */
493    public final Setting<Float> pathingMapLoadFactor = new Setting<>(0.75f);
494
495    /**
496     * How far are you allowed to fall onto solid ground (without a water bucket)?
497     * 3 won't deal any damage. But if you just want to get down the mountain quickly and you have
498     * Feather Falling IV, you might set it a bit higher, like 4 or 5.
499     */
500    public final Setting<Integer> maxFallHeightNoWater = new Setting<>(3);
501
502    /**
503     * How far are you allowed to fall onto solid ground (with a water bucket)?
504     * It's not that reliable, so I've set it below what would kill an unarmored player (23)
505     */
506    public final Setting<Integer> maxFallHeightBucket = new Setting<>(20);
507
508    /**
509     * Is it okay to sprint through a descend followed by a diagonal?
510     * The player overshoots the landing, but not enough to fall off. And the diagonal ensures that there isn't
511     * lava or anything that's !canWalkInto in that space, so it's technically safe, just a little sketchy.
512     * <p>
513     * Note: this is *not* related to the allowDiagonalDescend setting, that is a completely different thing.
514     */
515    public final Setting<Boolean> allowOvershootDiagonalDescend = new Setting<>(true);
516
517    /**
518     * If your goal is a GoalBlock in an unloaded chunk, assume it's far enough away that the Y coord
519     * doesn't matter yet, and replace it with a GoalXZ to the same place before calculating a path.
520     * Once a segment ends within chunk load range of the GoalBlock, it will go back to normal behavior
521     * of considering the Y coord. The reasoning is that if your X and Z are 10,000 blocks away,
522     * your Y coordinate's accuracy doesn't matter at all until you get much much closer.
523     */
524    public final Setting<Boolean> simplifyUnloadedYCoord = new Setting<>(true);
525
526    /**
527     * Whenever a block changes, repack the whole chunk that it's in
528     */
529    public final Setting<Boolean> repackOnAnyBlockChange = new Setting<>(true);
530
531    /**
532     * If a movement takes this many ticks more than its initial cost estimate, cancel it
533     */
534    public final Setting<Integer> movementTimeoutTicks = new Setting<>(100);
535
536    /**
537     * Pathing ends after this amount of time, but only if a path has been found
538     * <p>
539     * If no valid path (length above the minimum) has been found, pathing continues up until the failure timeout
540     */
541    public final Setting<Long> primaryTimeoutMS = new Setting<>(500L);
542
543    /**
544     * Pathing can never take longer than this, even if that means failing to find any path at all
545     */
546    public final Setting<Long> failureTimeoutMS = new Setting<>(2000L);
547
548    /**
549     * Planning ahead while executing a segment ends after this amount of time, but only if a path has been found
550     * <p>
551     * If no valid path (length above the minimum) has been found, pathing continues up until the failure timeout
552     */
553    public final Setting<Long> planAheadPrimaryTimeoutMS = new Setting<>(4000L);
554
555    /**
556     * Planning ahead while executing a segment can never take longer than this, even if that means failing to find any path at all
557     */
558    public final Setting<Long> planAheadFailureTimeoutMS = new Setting<>(5000L);
559
560    /**
561     * For debugging, consider nodes much much slower
562     */
563    public final Setting<Boolean> slowPath = new Setting<>(false);
564
565    /**
566     * Milliseconds between each node
567     */
568    public final Setting<Long> slowPathTimeDelayMS = new Setting<>(100L);
569
570    /**
571     * The alternative timeout number when slowPath is on
572     */
573    public final Setting<Long> slowPathTimeoutMS = new Setting<>(40000L);
574
575
576    /**
577     * allows baritone to save bed waypoints when interacting with beds
578     */
579    public final Setting<Boolean> doBedWaypoints = new Setting<>(true);
580
581    /**
582     * allows baritone to save death waypoints
583     */
584    public final Setting<Boolean> doDeathWaypoints = new Setting<>(true);
585
586    /**
587     * The big one. Download all chunks in simplified 2-bit format and save them for better very-long-distance pathing.
588     */
589    public final Setting<Boolean> chunkCaching = new Setting<>(true);
590
591    /**
592     * On save, delete from RAM any cached regions that are more than 1024 blocks away from the player
593     * <p>
594     * Temporarily disabled
595     * <p>
596     * Temporarily reenabled
597     *
598     * @see <a href="https://github.com/cabaletta/baritone/issues/248">Issue #248</a>
599     */
600    public final Setting<Boolean> pruneRegionsFromRAM = new Setting<>(true);
601
602    /**
603     * Fill in blocks behind you
604     */
605    public final Setting<Boolean> backfill = new Setting<>(false);
606
607    /**
608     * Shows popup message in the upper right corner, similarly to when you make an advancement
609     */
610    public final Setting<Boolean> logAsToast = new Setting<>(false);
611
612    /**
613     * The time of how long the message in the pop-up will display
614     * <p>
615     * If below 1000L (1sec), it's better to disable this
616     */
617    public final Setting<Long> toastTimer = new Setting<>(5000L);
618
619    /**
620     * Print all the debug messages to chat
621     */
622    public final Setting<Boolean> chatDebug = new Setting<>(false);
623
624    /**
625     * Allow chat based control of Baritone. Most likely should be disabled when Baritone is imported for use in
626     * something else
627     */
628    public final Setting<Boolean> chatControl = new Setting<>(true);
629
630    /**
631     * Some clients like Impact try to force chatControl to off, so here's a second setting to do it anyway
632     */
633    public final Setting<Boolean> chatControlAnyway = new Setting<>(false);
634
635    /**
636     * Render the path
637     */
638    public final Setting<Boolean> renderPath = new Setting<>(true);
639
640    /**
641     * Render the path as a line instead of a frickin thingy
642     */
643    public final Setting<Boolean> renderPathAsLine = new Setting<>(false);
644
645    /**
646     * Render the goal
647     */
648    public final Setting<Boolean> renderGoal = new Setting<>(true);
649
650    /**
651     * Render the goal as a sick animated thingy instead of just a box
652     * (also controls animation of GoalXZ if {@link #renderGoalXZBeacon} is enabled)
653     */
654    public final Setting<Boolean> renderGoalAnimated = new Setting<>(true);
655
656    /**
657     * Render selection boxes
658     */
659    public final Setting<Boolean> renderSelectionBoxes = new Setting<>(true);
660
661    /**
662     * Ignore depth when rendering the goal
663     */
664    public final Setting<Boolean> renderGoalIgnoreDepth = new Setting<>(true);
665
666    /**
667     * Renders X/Z type Goals with the vanilla beacon beam effect. Combining this with
668     * {@link #renderGoalIgnoreDepth} will cause strange render clipping.
669     */
670    public final Setting<Boolean> renderGoalXZBeacon = new Setting<>(false);
671
672    /**
673     * Ignore depth when rendering the selection boxes (to break, to place, to walk into)
674     */
675    public final Setting<Boolean> renderSelectionBoxesIgnoreDepth = new Setting<>(true);
676
677    /**
678     * Ignore depth when rendering the path
679     */
680    public final Setting<Boolean> renderPathIgnoreDepth = new Setting<>(true);
681
682    /**
683     * Line width of the path when rendered, in pixels
684     */
685    public final Setting<Float> pathRenderLineWidthPixels = new Setting<>(5F);
686
687    /**
688     * Line width of the goal when rendered, in pixels
689     */
690    public final Setting<Float> goalRenderLineWidthPixels = new Setting<>(3F);
691
692    /**
693     * Start fading out the path at 20 movements ahead, and stop rendering it entirely 30 movements ahead.
694     * Improves FPS.
695     */
696    public final Setting<Boolean> fadePath = new Setting<>(false);
697
698    /**
699     * Move without having to force the client-sided rotations
700     */
701    public final Setting<Boolean> freeLook = new Setting<>(true);
702
703    /**
704     * Will cause some minor behavioral differences to ensure that Baritone works on anticheats.
705     * <p>
706     * At the moment this will silently set the player's rotations when using freeLook so you're not sprinting in
707     * directions other than forward, which is picken up by more "advanced" anticheats like AAC, but not NCP.
708     */
709    public final Setting<Boolean> antiCheatCompatibility = new Setting<>(true);
710
711    /**
712     * Exclusively use cached chunks for pathing
713     * <p>
714     * Never turn this on
715     */
716    public final Setting<Boolean> pathThroughCachedOnly = new Setting<>(false);
717
718    /**
719     * Continue sprinting while in water
720     */
721    public final Setting<Boolean> sprintInWater = new Setting<>(true);
722
723    /**
724     * When GetToBlockProcess or MineProcess fails to calculate a path, instead of just giving up, mark the closest instance
725     * of that block as "unreachable" and go towards the next closest. GetToBlock expands this search to the whole "vein"; MineProcess does not.
726     * This is because MineProcess finds individual impossible blocks (like one block in a vein that has gravel on top then lava, so it can't break)
727     * Whereas GetToBlock should blacklist the whole "vein" if it can't get to any of them.
728     */
729    public final Setting<Boolean> blacklistClosestOnFailure = new Setting<>(true);
730
731    /**
732     * 😎 Render cached chunks as semitransparent. Doesn't work with OptiFine 😭 Rarely randomly crashes, see <a href="https://github.com/cabaletta/baritone/issues/327">this issue</a>.
733     * <p>
734     * Can be very useful on servers with low render distance. After enabling, you may need to reload the world in order for it to have an effect
735     * (e.g. disconnect and reconnect, enter then exit the nether, die and respawn, etc). This may literally kill your FPS and CPU because
736     * every chunk gets recompiled twice as much as normal, since the cached version comes into range, then the normal one comes from the server for real.
737     * <p>
738     * Note that flowing water is cached as AVOID, which is rendered as lava. As you get closer, you may therefore see lava falls being replaced with water falls.
739     * <p>
740     * SOLID is rendered as stone in the overworld, netherrack in the nether, and end stone in the end
741     */
742    public final Setting<Boolean> renderCachedChunks = new Setting<>(false);
743
744    /**
745     * 0.0f = not visible, fully transparent (instead of setting this to 0, turn off renderCachedChunks)
746     * 1.0f = fully opaque
747     */
748    public final Setting<Float> cachedChunksOpacity = new Setting<>(0.5f);
749
750    /**
751     * Whether or not to allow you to run Baritone commands with the prefix
752     */
753    public final Setting<Boolean> prefixControl = new Setting<>(true);
754
755    /**
756     * The command prefix for chat control
757     */
758    public final Setting<String> prefix = new Setting<>("#");
759
760    /**
761     * Use a short Baritone prefix [B] instead of [Baritone] when logging to chat
762     */
763    public final Setting<Boolean> shortBaritonePrefix = new Setting<>(false);
764
765    /**
766     * Echo commands to chat when they are run
767     */
768    public final Setting<Boolean> echoCommands = new Setting<>(true);
769
770    /**
771     * Censor coordinates in goals and block positions
772     */
773    public final Setting<Boolean> censorCoordinates = new Setting<>(false);
774
775    /**
776     * Censor arguments to ran commands, to hide, for example, coordinates to #goal
777     */
778    public final Setting<Boolean> censorRanCommands = new Setting<>(false);
779
780    /**
781     * Stop using tools just before they are going to break.
782     */
783    public final Setting<Boolean> itemSaver = new Setting<>(false);
784
785    /**
786     * Durability to leave on the tool when using itemSaver
787     */
788    public final Setting<Integer> itemSaverThreshold = new Setting<>(10);
789
790    /**
791     * Always prefer silk touch tools over regular tools. This will not sacrifice speed, but it will always prefer silk
792     * touch tools over other tools of the same speed. This includes always choosing ANY silk touch tool over your hand.
793     */
794    public final Setting<Boolean> preferSilkTouch = new Setting<>(false);
795
796    /**
797     * Don't stop walking forward when you need to break blocks in your way
798     */
799    public final Setting<Boolean> walkWhileBreaking = new Setting<>(true);
800
801    /**
802     * When a new segment is calculated that doesn't overlap with the current one, but simply begins where the current segment ends,
803     * splice it on and make a longer combined path. If this setting is off, any planned segment will not be spliced and will instead
804     * be the "next path" in PathingBehavior, and will only start after this one ends. Turning this off hurts planning ahead,
805     * because the next segment will exist even if it's very short.
806     *
807     * @see #planningTickLookahead
808     */
809    public final Setting<Boolean> splicePath = new Setting<>(true);
810
811    /**
812     * If we are more than 300 movements into the current path, discard the oldest segments, as they are no longer useful
813     */
814    public final Setting<Integer> maxPathHistoryLength = new Setting<>(300);
815
816    /**
817     * If the current path is too long, cut off this many movements from the beginning.
818     */
819    public final Setting<Integer> pathHistoryCutoffAmount = new Setting<>(50);
820
821    /**
822     * Rescan for the goal once every 5 ticks.
823     * Set to 0 to disable.
824     */
825    public final Setting<Integer> mineGoalUpdateInterval = new Setting<>(5);
826
827    /**
828     * After finding this many instances of the target block in the cache, it will stop expanding outward the chunk search.
829     */
830    public final Setting<Integer> maxCachedWorldScanCount = new Setting<>(10);
831
832    /**
833     * Sets the minimum y level whilst mining - set to 0 to turn off.
834     */
835    public final Setting<Integer> minYLevelWhileMining = new Setting<>(0);
836
837    /**
838     * This will only allow baritone to mine exposed ores, can be used to stop ore obfuscators on servers that use them.
839     */
840    public final Setting<Boolean> allowOnlyExposedOres = new Setting<>(false);
841
842    /**
843     * When allowOnlyExposedOres is enabled this is the distance around to search.
844     * <p>
845     * It is recommended to keep this value low, as it dramatically increases calculation times.
846     */
847    public final Setting<Integer> allowOnlyExposedOresDistance = new Setting<>(1);
848
849    /**
850     * When GetToBlock or non-legit Mine doesn't know any locations for the desired block, explore randomly instead of giving up.
851     */
852    public final Setting<Boolean> exploreForBlocks = new Setting<>(true);
853
854    /**
855     * While exploring the world, offset the closest unloaded chunk by this much in both axes.
856     * <p>
857     * This can result in more efficient loading, if you set this to the render distance.
858     */
859    public final Setting<Integer> worldExploringChunkOffset = new Setting<>(0);
860
861    /**
862     * Take the 10 closest chunks, even if they aren't strictly tied for distance metric from origin.
863     */
864    public final Setting<Integer> exploreChunkSetMinimumSize = new Setting<>(10);
865
866    /**
867     * Attempt to maintain Y coordinate while exploring
868     * <p>
869     * -1 to disable
870     */
871    public final Setting<Integer> exploreMaintainY = new Setting<>(64);
872
873    /**
874     * Replant normal Crops while farming and leave cactus and sugarcane to regrow
875     */
876    public final Setting<Boolean> replantCrops = new Setting<>(true);
877
878    /**
879     * Replant nether wart while farming. This setting only has an effect when replantCrops is also enabled
880     */
881    public final Setting<Boolean> replantNetherWart = new Setting<>(false);
882
883    /**
884     * When the cache scan gives less blocks than the maximum threshold (but still above zero), scan the main world too.
885     * <p>
886     * Only if you have a beefy CPU and automatically mine blocks that are in cache
887     */
888    public final Setting<Boolean> extendCacheOnThreshold = new Setting<>(false);
889
890    /**
891     * Don't consider the next layer in builder until the current one is done
892     */
893    public final Setting<Boolean> buildInLayers = new Setting<>(false);
894
895    /**
896     * false = build from bottom to top
897     * <p>
898     * true = build from top to bottom
899     */
900    public final Setting<Boolean> layerOrder = new Setting<>(false);
901
902    /**
903     * How high should the individual layers be?
904     */
905    public final Setting<Integer> layerHeight = new Setting<>(1);
906
907    /**
908     * Start building the schematic at a specific layer.
909     * Can help on larger builds when schematic wants to break things its already built
910     */
911    public final Setting<Integer> startAtLayer = new Setting<>(0);
912
913    /**
914     * If a layer is unable to be constructed, just skip it.
915     */
916    public final Setting<Boolean> skipFailedLayers = new Setting<>(false);
917
918    /**
919     * Only build the selected part of schematics
920     */
921     public final Setting<Boolean> buildOnlySelection = new Setting<>(false);
922
923    /**
924     * How far to move before repeating the build. 0 to disable repeating on a certain axis, 0,0,0 to disable entirely
925     */
926    public final Setting<Vec3i> buildRepeat = new Setting<>(new Vec3i(0, 0, 0));
927
928    /**
929     * How many times to buildrepeat. -1 for infinite.
930     */
931    public final Setting<Integer> buildRepeatCount = new Setting<>(-1);
932
933    /**
934     * Don't notify schematics that they are moved.
935     * e.g. replacing will replace the same spots for every repetition
936     * Mainly for backward compatibility.
937     */
938    public final Setting<Boolean> buildRepeatSneaky = new Setting<>(true);
939
940    /**
941     * Allow standing above a block while mining it, in BuilderProcess
942     * <p>
943     * Experimental
944     */
945    public final Setting<Boolean> breakFromAbove = new Setting<>(false);
946
947    /**
948     * As well as breaking from above, set a goal to up and to the side of all blocks to break.
949     * <p>
950     * Never turn this on without also turning on breakFromAbove.
951     */
952    public final Setting<Boolean> goalBreakFromAbove = new Setting<>(false);
953
954    /**
955     * Build in map art mode, which makes baritone only care about the top block in each column
956     */
957    public final Setting<Boolean> mapArtMode = new Setting<>(false);
958
959    /**
960     * Override builder's behavior to not attempt to correct blocks that are currently water
961     */
962    public final Setting<Boolean> okIfWater = new Setting<>(false);
963
964    /**
965     * The set of incorrect blocks can never grow beyond this size
966     */
967    public final Setting<Integer> incorrectSize = new Setting<>(100);
968
969    /**
970     * Multiply the cost of breaking a block that's correct in the builder's schematic by this coefficient
971     */
972    public final Setting<Double> breakCorrectBlockPenaltyMultiplier = new Setting<>(10d);
973
974    /**
975     * When this setting is true, build a schematic with the highest X coordinate being the origin, instead of the lowest
976     */
977    public final Setting<Boolean> schematicOrientationX = new Setting<>(false);
978
979    /**
980     * When this setting is true, build a schematic with the highest Y coordinate being the origin, instead of the lowest
981     */
982    public final Setting<Boolean> schematicOrientationY = new Setting<>(false);
983
984    /**
985     * When this setting is true, build a schematic with the highest Z coordinate being the origin, instead of the lowest
986     */
987    public final Setting<Boolean> schematicOrientationZ = new Setting<>(false);
988
989    /**
990     * The fallback used by the build command when no extension is specified. This may be useful if schematics of a
991     * particular format are used often, and the user does not wish to have to specify the extension with every usage.
992     */
993    public final Setting<String> schematicFallbackExtension = new Setting<>("schematic");
994
995    /**
996     * Distance to scan every tick for updates. Expanding this beyond player reach distance (i.e. setting it to 6 or above)
997     * is only necessary in very large schematics where rescanning the whole thing is costly.
998     */
999    public final Setting<Integer> builderTickScanRadius = new Setting<>(5);
1000
1001    /**
1002     * While mining, should it also consider dropped items of the correct type as a pathing destination (as well as ore blocks)?
1003     */
1004    public final Setting<Boolean> mineScanDroppedItems = new Setting<>(true);
1005
1006    /**
1007     * While mining, wait this number of milliseconds after mining an ore to see if it will drop an item
1008     * instead of immediately going onto the next one
1009     * <p>
1010     * Thanks Louca
1011     */
1012    public final Setting<Long> mineDropLoiterDurationMSThanksLouca = new Setting<>(250L);
1013
1014    /**
1015     * Trim incorrect positions too far away, helps performance but hurts reliability in very large schematics
1016     */
1017    public final Setting<Boolean> distanceTrim = new Setting<>(true);
1018
1019    /**
1020     * Cancel the current path if the goal has changed, and the path originally ended in the goal but doesn't anymore.
1021     * <p>
1022     * Currently only runs when either MineBehavior or FollowBehavior is active.
1023     * <p>
1024     * For example, if Baritone is doing "mine iron_ore", the instant it breaks the ore (and it becomes air), that location
1025     * is no longer a goal. This means that if this setting is true, it will stop there. If this setting were off, it would
1026     * continue with its path, and walk into that location. The tradeoff is if this setting is true, it mines ores much faster
1027     * since it doesn't waste any time getting into locations that no longer contain ores, but on the other hand, it misses
1028     * some drops, and continues on without ever picking them up.
1029     * <p>
1030     * Also on cosmic prisons this should be set to true since you don't actually mine the ore it just gets replaced with stone.
1031     */
1032    public final Setting<Boolean> cancelOnGoalInvalidation = new Setting<>(true);
1033
1034    /**
1035     * The "axis" command (aka GoalAxis) will go to a axis, or diagonal axis, at this Y level.
1036     */
1037    public final Setting<Integer> axisHeight = new Setting<>(120);
1038
1039    /**
1040     * Disconnect from the server upon arriving at your goal
1041     */
1042    public final Setting<Boolean> disconnectOnArrival = new Setting<>(false);
1043
1044    /**
1045     * Disallow MineBehavior from using X-Ray to see where the ores are. Turn this option on to force it to mine "legit"
1046     * where it will only mine an ore once it can actually see it, so it won't do or know anything that a normal player
1047     * couldn't. If you don't want it to look like you're X-Raying, turn this on
1048     * This will always explore, regardless of exploreForBlocks
1049     */
1050    public final Setting<Boolean> legitMine = new Setting<>(false);
1051
1052    /**
1053     * What Y level to go to for legit strip mining
1054     */
1055    public final Setting<Integer> legitMineYLevel = new Setting<>(11);
1056
1057    /**
1058     * Magically see ores that are separated diagonally from existing ores. Basically like mining around the ores that it finds
1059     * in case there's one there touching it diagonally, except it checks it un-legit-ly without having the mine blocks to see it.
1060     * You can decide whether this looks plausible or not.
1061     * <p>
1062     * This is disabled because it results in some weird behavior. For example, it can """see""" the top block of a vein of iron_ore
1063     * through a lava lake. This isn't an issue normally since it won't consider anything touching lava, so it just ignores it.
1064     * However, this setting expands that and allows it to see the entire vein so it'll mine under the lava lake to get the iron that
1065     * it can reach without mining blocks adjacent to lava. This really defeats the purpose of legitMine since a player could never
1066     * do that lol, so thats one reason why its disabled
1067     */
1068    public final Setting<Boolean> legitMineIncludeDiagonals = new Setting<>(false);
1069
1070    /**
1071     * When mining block of a certain type, try to mine two at once instead of one.
1072     * If the block above is also a goal block, set GoalBlock instead of GoalTwoBlocks
1073     * If the block below is also a goal block, set GoalBlock to the position one down instead of GoalTwoBlocks
1074     */
1075    public final Setting<Boolean> forceInternalMining = new Setting<>(true);
1076
1077    /**
1078     * Modification to the previous setting, only has effect if forceInternalMining is true
1079     * If true, only apply the previous setting if the block adjacent to the goal isn't air.
1080     */
1081    public final Setting<Boolean> internalMiningAirException = new Setting<>(true);
1082
1083    /**
1084     * The actual GoalNear is set this distance away from the entity you're following
1085     * <p>
1086     * For example, set followOffsetDistance to 5 and followRadius to 0 to always stay precisely 5 blocks north of your follow target.
1087     */
1088    public final Setting<Double> followOffsetDistance = new Setting<>(0D);
1089
1090    /**
1091     * The actual GoalNear is set in this direction from the entity you're following. This value is in degrees.
1092     */
1093    public final Setting<Float> followOffsetDirection = new Setting<>(0F);
1094
1095    /**
1096     * The radius (for the GoalNear) of how close to your target position you actually have to be
1097     */
1098    public final Setting<Integer> followRadius = new Setting<>(3);
1099
1100    /**
1101     * Turn this on if your exploration filter is enormous, you don't want it to check if it's done,
1102     * and you are just fine with it just hanging on completion
1103     */
1104    public final Setting<Boolean> disableCompletionCheck = new Setting<>(false);
1105
1106    /**
1107     * Cached chunks (regardless of if they're in RAM or saved to disk) expire and are deleted after this number of seconds
1108     * -1 to disable
1109     * <p>
1110     * I would highly suggest leaving this setting disabled (-1).
1111     * <p>
1112     * The only valid reason I can think of enable this setting is if you are extremely low on disk space and you play on multiplayer,
1113     * and can't take (average) 300kb saved for every 512x512 area. (note that more complicated terrain is less compressible and will take more space)
1114     * <p>
1115     * However, simply discarding old chunks because they are old is inadvisable. Baritone is extremely good at correcting
1116     * itself and its paths as it learns new information, as new chunks load. There is no scenario in which having an
1117     * incorrect cache can cause Baritone to get stuck, take damage, or perform any action it wouldn't otherwise, everything
1118     * is rechecked once the real chunk is in range.
1119     * <p>
1120     * Having a robust cache greatly improves long distance pathfinding, as it's able to go around large scale obstacles
1121     * before they're in render distance. In fact, when the chunkCaching setting is disabled and Baritone starts anew
1122     * every time, or when you enter a completely new and very complicated area, it backtracks far more often because it
1123     * has to build up that cache from scratch. But after it's gone through an area just once, the next time will have zero
1124     * backtracking, since the entire area is now known and cached.
1125     */
1126    public final Setting<Long> cachedChunksExpirySeconds = new Setting<>(-1L);
1127
1128    /**
1129     * The function that is called when Baritone will log to chat. This function can be added to
1130     * via {@link Consumer#andThen(Consumer)} or it can completely be overriden via setting
1131     * {@link Setting#value};
1132     */
1133    public final Setting<Consumer<ITextComponent>> logger = new Setting<>(msg -> Minecraft.getMinecraft().ingameGUI.getChatGUI().printChatMessage(msg));
1134
1135    /**
1136     * The function that is called when Baritone will send a desktop notification. This function can be added to
1137     * via {@link Consumer#andThen(Consumer)} or it can completely be overriden via setting
1138     * {@link Setting#value};
1139     */
1140    public final Setting<BiConsumer<String, Boolean>> notifier = new Setting<>(NotificationHelper::notify);
1141
1142    /**
1143     * The function that is called when Baritone will show a toast. This function can be added to
1144     * via {@link Consumer#andThen(Consumer)} or it can completely be overriden via setting
1145     * {@link Setting#value};
1146     */
1147    public final Setting<BiConsumer<ITextComponent, ITextComponent>> toaster = new Setting<>(BaritoneToast::addOrUpdate);
1148
1149    /**
1150     * The size of the box that is rendered when the current goal is a GoalYLevel
1151     */
1152    public final Setting<Double> yLevelBoxSize = new Setting<>(15D);
1153
1154    /**
1155     * The color of the current path
1156     */
1157    public final Setting<Color> colorCurrentPath = new Setting<>(Color.RED);
1158
1159    /**
1160     * The color of the next path
1161     */
1162    public final Setting<Color> colorNextPath = new Setting<>(Color.MAGENTA);
1163
1164    /**
1165     * The color of the blocks to break
1166     */
1167    public final Setting<Color> colorBlocksToBreak = new Setting<>(Color.RED);
1168
1169    /**
1170     * The color of the blocks to place
1171     */
1172    public final Setting<Color> colorBlocksToPlace = new Setting<>(Color.GREEN);
1173
1174    /**
1175     * The color of the blocks to walk into
1176     */
1177    public final Setting<Color> colorBlocksToWalkInto = new Setting<>(Color.MAGENTA);
1178
1179    /**
1180     * The color of the best path so far
1181     */
1182    public final Setting<Color> colorBestPathSoFar = new Setting<>(Color.BLUE);
1183
1184    /**
1185     * The color of the path to the most recent considered node
1186     */
1187    public final Setting<Color> colorMostRecentConsidered = new Setting<>(Color.CYAN);
1188
1189    /**
1190     * The color of the goal box
1191     */
1192    public final Setting<Color> colorGoalBox = new Setting<>(Color.GREEN);
1193
1194    /**
1195     * The color of the goal box when it's inverted
1196     */
1197    public final Setting<Color> colorInvertedGoalBox = new Setting<>(Color.RED);
1198
1199    /**
1200     * The color of all selections
1201     */
1202    public final Setting<Color> colorSelection = new Setting<>(Color.CYAN);
1203
1204    /**
1205     * The color of the selection pos 1
1206     */
1207    public final Setting<Color> colorSelectionPos1 = new Setting<>(Color.BLACK);
1208
1209    /**
1210     * The color of the selection pos 2
1211     */
1212    public final Setting<Color> colorSelectionPos2 = new Setting<>(Color.ORANGE);
1213
1214    /**
1215     * The opacity of the selection. 0 is completely transparent, 1 is completely opaque
1216     */
1217    public final Setting<Float> selectionOpacity = new Setting<>(.5f);
1218
1219    /**
1220     * Line width of the goal when rendered, in pixels
1221     */
1222    public final Setting<Float> selectionLineWidth = new Setting<>(2F);
1223
1224    /**
1225     * Render selections
1226     */
1227    public final Setting<Boolean> renderSelection = new Setting<>(true);
1228
1229    /**
1230     * Ignore depth when rendering selections
1231     */
1232    public final Setting<Boolean> renderSelectionIgnoreDepth = new Setting<>(true);
1233
1234    /**
1235     * Render selection corners
1236     */
1237    public final Setting<Boolean> renderSelectionCorners = new Setting<>(true);
1238
1239    /**
1240     * Use sword to mine.
1241     */
1242    public final Setting<Boolean> useSwordToMine = new Setting<>(true);
1243
1244    /**
1245     * Desktop notifications
1246     */
1247    public final Setting<Boolean> desktopNotifications = new Setting<>(false);
1248
1249    /**
1250     * Desktop notification on path complete
1251     */
1252    public final Setting<Boolean> notificationOnPathComplete = new Setting<>(true);
1253
1254    /**
1255     * Desktop notification on farm fail
1256     */
1257    public final Setting<Boolean> notificationOnFarmFail = new Setting<>(true);
1258
1259    /**
1260     * Desktop notification on build finished
1261     */
1262    public final Setting<Boolean> notificationOnBuildFinished = new Setting<>(true);
1263
1264    /**
1265     * Desktop notification on explore finished
1266     */
1267    public final Setting<Boolean> notificationOnExploreFinished = new Setting<>(true);
1268
1269    /**
1270     * Desktop notification on mine fail
1271     */
1272    public final Setting<Boolean> notificationOnMineFail = new Setting<>(true);
1273
1274    /**
1275     * A map of lowercase setting field names to their respective setting
1276     */
1277    public final Map<String, Setting<?>> byLowerName;
1278
1279    /**
1280     * A list of all settings
1281     */
1282    public final List<Setting<?>> allSettings;
1283
1284    public final Map<Setting<?>, Type> settingTypes;
1285
1286    public final class Setting<T> {
1287
1288        public T value;
1289        public final T defaultValue;
1290        private String name;
1291
1292        @SuppressWarnings("unchecked")
1293        private Setting(T value) {
1294            if (value == null) {
1295                throw new IllegalArgumentException("Cannot determine value type class from null");
1296            }
1297            this.value = value;
1298            this.defaultValue = value;
1299        }
1300
1301        /**
1302         * Deprecated! Please use .value directly instead
1303         *
1304         * @return the current setting value
1305         */
1306        @Deprecated
1307        public final T get() {
1308            return value;
1309        }
1310
1311        public final String getName() {
1312            return name;
1313        }
1314
1315        public Class<T> getValueClass() {
1316            // noinspection unchecked
1317            return (Class<T>) TypeUtils.resolveBaseClass(getType());
1318        }
1319
1320        @Override
1321        public String toString() {
1322            return SettingsUtil.settingToString(this);
1323        }
1324
1325        /**
1326         * Reset this setting to its default value
1327         */
1328        public void reset() {
1329            value = defaultValue;
1330        }
1331
1332        public final Type getType() {
1333            return settingTypes.get(this);
1334        }
1335    }
1336
1337    // here be dragons
1338
1339    Settings() {
1340        Field[] temp = getClass().getFields();
1341
1342        Map<String, Setting<?>> tmpByName = new HashMap<>();
1343        List<Setting<?>> tmpAll = new ArrayList<>();
1344        Map<Setting<?>, Type> tmpSettingTypes = new HashMap<>();
1345
1346        try {
1347            for (Field field : temp) {
1348                if (field.getType().equals(Setting.class)) {
1349                    Setting<?> setting = (Setting<?>) field.get(this);
1350                    String name = field.getName();
1351                    setting.name = name;
1352                    name = name.toLowerCase();
1353                    if (tmpByName.containsKey(name)) {
1354                        throw new IllegalStateException("Duplicate setting name");
1355                    }
1356                    tmpByName.put(name, setting);
1357                    tmpAll.add(setting);
1358                    tmpSettingTypes.put(setting, ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0]);
1359                }
1360            }
1361        } catch (IllegalAccessException e) {
1362            throw new IllegalStateException(e);
1363        }
1364        byLowerName = Collections.unmodifiableMap(tmpByName);
1365        allSettings = Collections.unmodifiableList(tmpAll);
1366        settingTypes = Collections.unmodifiableMap(tmpSettingTypes);
1367    }
1368
1369    @SuppressWarnings("unchecked")
1370    public <T> List<Setting<T>> getAllValuesByType(Class<T> cla$$) {
1371        List<Setting<T>> result = new ArrayList<>();
1372        for (Setting<?> setting : allSettings) {
1373            if (setting.getValueClass().equals(cla$$)) {
1374                result.add((Setting<T>) setting);
1375            }
1376        }
1377        return result;
1378    }
1379}