Repository: skyblueyoshi/TerraCraft
Branch: master
Commit: dabeb2789995
Files: 3382
Total size: 2.7 MB
Directory structure:
gitextract_ll5d4bnt/
├── DebugHelper.lua
├── DebugHelperConfig.lua
├── LICENSE
├── README.md
├── advancements/
│ ├── AdvancementTriggers.lua
│ ├── ancient_ingot.json
│ ├── ancient_wear.json
│ ├── blaze_rod.json
│ ├── bow.json
│ ├── bread.json
│ ├── brew.json
│ ├── bronze.json
│ ├── cake.json
│ ├── crafting_table.json
│ ├── crison_eye.json
│ ├── crison_eye_killed.json
│ ├── crossbow.json
│ ├── diamond.json
│ ├── diamond_ingot.json
│ ├── diamond_wear.json
│ ├── dungeon_eater.json
│ ├── dungeon_eater_killed.json
│ ├── enchant.json
│ ├── ender_chest.json
│ ├── ender_pearl.json
│ ├── farm.json
│ ├── flesh_ingot.json
│ ├── flesh_wear.json
│ ├── furnace.json
│ ├── ghast.json
│ ├── ghost.json
│ ├── ghost_crystal.json
│ ├── go_bone_dungeon.json
│ ├── go_dark_dungeon.json
│ ├── go_deep_snow.json
│ ├── go_desert_dungeon.json
│ ├── go_ghost_house.json
│ ├── go_ice_dungeon.json
│ ├── go_lava_dungeon.json
│ ├── gold.json
│ ├── gold_wear.json
│ ├── guardian.json
│ ├── gun.json
│ ├── hunter.json
│ ├── ice_element_ball.json
│ ├── inventory.json
│ ├── iron.json
│ ├── knight_ingot.json
│ ├── knight_wear.json
│ ├── lava.json
│ ├── leather.json
│ ├── magic_gold_wear.json
│ ├── magic_limit.json
│ ├── mine.json
│ ├── mine_bronze.json
│ ├── mine_copper.json
│ ├── mine_diamond.json
│ ├── mine_gold.json
│ ├── mine_iron.json
│ ├── mine_netherite.json
│ ├── mine_up.json
│ ├── mirror.json
│ ├── nether.json
│ ├── nether_destroyer.json
│ ├── nether_destroyer_killed.json
│ ├── netherite.json
│ ├── netherite_full_wear.json
│ ├── portal.json
│ ├── pumpkin_helmet.json
│ ├── recipe_book.json
│ ├── redstone.json
│ ├── redstone_wire.json
│ ├── repair.json
│ ├── rocket_boost.json
│ ├── snow_guard.json
│ ├── snow_queen.json
│ ├── snow_queen_killed.json
│ ├── staff.json
│ ├── star_wear.json
│ ├── steel.json
│ ├── stone.json
│ ├── strange_len.json
│ ├── super_diamond_sword.json
│ ├── super_diamond_wear.json
│ ├── sword.json
│ └── wood.json
├── api.lua
├── apis/
│ ├── Account.lua
│ ├── AccountUtils.lua
│ ├── Advancement.lua
│ ├── AdvancementUtils.lua
│ ├── Attack.lua
│ ├── BiomeData.lua
│ ├── BiomeUtils.lua
│ ├── BlockData.lua
│ ├── BlockEntity.lua
│ ├── BlockUtils.lua
│ ├── Buff.lua
│ ├── ClientBoundPacketWriter.lua
│ ├── ClientState.lua
│ ├── ClientStateManager.lua
│ ├── Container.lua
│ ├── DataWatcher.lua
│ ├── DeathReason.lua
│ ├── Defense.lua
│ ├── Direction.lua
│ ├── Effect.lua
│ ├── EffectUtils.lua
│ ├── Enchantment.lua
│ ├── EnchantmentData.lua
│ ├── EnchantmentUtils.lua
│ ├── Entity.lua
│ ├── EntityIndex.lua
│ ├── GameMode.lua
│ ├── GlobalBlock.lua
│ ├── GlobalNpc.lua
│ ├── GlobalPlayer.lua
│ ├── GuiContainer.lua
│ ├── Hitbox.lua
│ ├── Inventory.lua
│ ├── Item.lua
│ ├── ItemRegistry.lua
│ ├── ItemStack.lua
│ ├── ItemType.lua
│ ├── ItemUtils.lua
│ ├── JoinData.lua
│ ├── LangUtils.lua
│ ├── LightingUtils.lua
│ ├── MapPos.lua
│ ├── MapUtils.lua
│ ├── MiscUtils.lua
│ ├── Mod.lua
│ ├── ModBlock.lua
│ ├── ModBlockEntity.lua
│ ├── ModItem.lua
│ ├── ModNpc.lua
│ ├── ModProjectile.lua
│ ├── ModTextureData.lua
│ ├── ModTextureUtils.lua
│ ├── Npc.lua
│ ├── NpcType.lua
│ ├── NpcUtils.lua
│ ├── OreDataGroup.lua
│ ├── ParameterClick.lua
│ ├── ParameterDestroy.lua
│ ├── ParameterPlace.lua
│ ├── ParameterStrike.lua
│ ├── Player.lua
│ ├── PlayerUtils.lua
│ ├── Point.lua
│ ├── Projectile.lua
│ ├── ProjectileUtils.lua
│ ├── Recipe.lua
│ ├── RecipeConfig.lua
│ ├── RecipeSearchAction.lua
│ ├── RecipeUtils.lua
│ ├── Rectangle.lua
│ ├── Reg.lua
│ ├── ServerBoundPacketWriter.lua
│ ├── Shape.lua
│ ├── Skeleton.lua
│ ├── Skin.lua
│ ├── SkinUtils.lua
│ ├── Slot.lua
│ ├── SlotCommandQueue.lua
│ ├── SmartMode.lua
│ ├── SoundUtils.lua
│ ├── SpriteEx.lua
│ ├── Type.lua
│ ├── Utils.lua
│ ├── WorldData.lua
│ ├── WorldDataUtils.lua
│ ├── WorldGenArea.lua
│ ├── WorldGenChunkBuffer.lua
│ ├── WorldGenCode.lua
│ ├── WorldGenNoise.lua
│ └── engine_api/
│ ├── AnimationEvent.lua
│ ├── Animator2D.lua
│ ├── AnimatorData2D.lua
│ ├── App.lua
│ ├── Array.lua
│ ├── AssetBundle.lua
│ ├── AssetManager.lua
│ ├── AtlasInfos.lua
│ ├── AtlasLoader.lua
│ ├── Audio.lua
│ ├── ByteStream.lua
│ ├── Bytes.lua
│ ├── CameraComponentWrapper.lua
│ ├── CameraProjection.lua
│ ├── CanvasComponentWrapper.lua
│ ├── CanvasDisplayMode.lua
│ ├── ClipCollection2D.lua
│ ├── Color.lua
│ ├── ComponentID.lua
│ ├── ComponentWrapper.lua
│ ├── DateTime.lua
│ ├── FadingState.lua
│ ├── File.lua
│ ├── FileTimeType.lua
│ ├── FontManager.lua
│ ├── FontSprite.lua
│ ├── GameObject.lua
│ ├── GameWindow.lua
│ ├── GlobalHook.lua
│ ├── GraphicsDevice.lua
│ ├── HotKeyCombination.lua
│ ├── Hotfix.lua
│ ├── Image.lua
│ ├── ImageInfo.lua
│ ├── Input.lua
│ ├── IntegratedClient.lua
│ ├── IntegratedEnv.lua
│ ├── Joint2D.lua
│ ├── JointBody2D.lua
│ ├── JointCollection2D.lua
│ ├── Joystick.lua
│ ├── JoystickDevice.lua
│ ├── JsonUtil.lua
│ ├── KeyTrigger.lua
│ ├── Keyboard.lua
│ ├── Keys.lua
│ ├── ListenerID.lua
│ ├── Log.lua
│ ├── MathHelper.lua
│ ├── Matrix.lua
│ ├── MeshFilterComponentWrapper.lua
│ ├── MeshRendererComponentWrapper.lua
│ ├── Mouse.lua
│ ├── NetMode.lua
│ ├── ObbDouble.lua
│ ├── Path.lua
│ ├── Quaternion.lua
│ ├── Random.lua
│ ├── Rect.lua
│ ├── RectFloat.lua
│ ├── RectFloatEx.lua
│ ├── Registry.lua
│ ├── Rigidbody.lua
│ ├── Schedule.lua
│ ├── ScheduleID.lua
│ ├── SerializableType.lua
│ ├── Size.lua
│ ├── SliderDirection.lua
│ ├── Sprite.lua
│ ├── SpriteExData.lua
│ ├── TextAlignment.lua
│ ├── TextBuffer.lua
│ ├── TextEditLineType.lua
│ ├── TextHorizontalOverflow.lua
│ ├── TextStyle.lua
│ ├── TextVerticalOverflow.lua
│ ├── Texture.lua
│ ├── TextureLocation.lua
│ ├── TextureManager.lua
│ ├── TexturePacker.lua
│ ├── Time.lua
│ ├── TimeDiff.lua
│ ├── Touch.lua
│ ├── Transform.lua
│ ├── Transform2D.lua
│ ├── TransformComponentWrapper.lua
│ ├── UIButton.lua
│ ├── UICanvas.lua
│ ├── UIImage.lua
│ ├── UIInputField.lua
│ ├── UIJoystick.lua
│ ├── UINode.lua
│ ├── UINodeDrawLayer.lua
│ ├── UIPanel.lua
│ ├── UIScrollView.lua
│ ├── UISerializable.lua
│ ├── UISlices9.lua
│ ├── UISlider.lua
│ ├── UISprite.lua
│ ├── UISpriteStyle.lua
│ ├── UISwitch.lua
│ ├── UIText.lua
│ ├── UITexturePool.lua
│ ├── Vector2.lua
│ ├── Vector3.lua
│ ├── Vector4.lua
│ ├── cls.lua
│ └── utf8string.lua
├── atlas_config.json
├── biome_types/
│ ├── Nether.json
│ ├── Radiation.json
│ ├── Space.json
│ ├── Surface.json
│ ├── TwilightForest.json
│ └── Underground.json
├── biomes/
│ ├── nethers/
│ │ └── nether.json
│ ├── surfaces/
│ │ ├── badland.json
│ │ ├── desert.json
│ │ ├── flesh.json
│ │ ├── forest.json
│ │ ├── jungle.json
│ │ ├── mushroom_fields.json
│ │ ├── ocean.json
│ │ ├── snow_land.json
│ │ ├── soft_snow_land.json
│ │ ├── super_volcano.json
│ │ ├── tainted_land.json
│ │ └── volcano.json
│ └── undergrounds/
│ ├── andesite_cave.json
│ ├── blue_cave.json
│ ├── blue_mushroom_cave.json
│ ├── deep_ice_cave.json
│ ├── deep_magma_cave.json
│ ├── desert_cave.json
│ ├── diorite_cave.json
│ ├── flesh_cave.json
│ ├── granite_cave.json
│ ├── ice_cave.json
│ ├── jungle_cave.json
│ ├── lava_cave.json
│ ├── magma_cave.json
│ ├── mud_cave.json
│ ├── mushroom_cave.json
│ ├── normal_cave.json
│ ├── stone_cave.json
│ ├── tainted_cave.json
│ └── waste_cave.json
├── block_entity_ai/
│ ├── BrewingEntity.json
│ ├── BrewingEntity.lua
│ ├── Chest30Entity.json
│ ├── Chest30Entity.lua
│ ├── IChestEntity.lua
│ ├── IShooterEntity.lua
│ ├── Shooter9Entity.json
│ ├── Shooter9Entity.lua
│ ├── SmeltEntity.json
│ └── SmeltEntity.lua
├── block_presets/
│ ├── Anvil.json
│ ├── Anvil.lua
│ ├── Bed.json
│ ├── Brewing.json
│ ├── BurnerTower.json
│ ├── Button.json
│ ├── Cake.json
│ ├── Cobweb.json
│ ├── Cobweb.lua
│ ├── CraftingTable.json
│ ├── CraftingTable.lua
│ ├── Crop.json
│ ├── CrystalTower.json
│ ├── DaylightTrigger.json
│ ├── DoorClosed.json
│ ├── DoorOpened.json
│ ├── Enchantment.json
│ ├── EnchantmentTable.lua
│ ├── EndRod.json
│ ├── EnderStorage.json
│ ├── EnderStorage.lua
│ ├── Facing.json
│ ├── Farmland.json
│ ├── Furnace.json
│ ├── Furnace.lua
│ ├── Grass.json
│ ├── GrowGrass.json
│ ├── HeartCrystal.json
│ ├── HeartCrystal.lua
│ ├── IceSmelt.json
│ ├── InsideStorage.json
│ ├── Kelp.json
│ ├── MagmaBlock.json
│ ├── MagmaBlock.lua
│ ├── Melon.json
│ ├── MelonStem.json
│ ├── MoonlightTrigger.json
│ ├── NetherAltar.json
│ ├── NetherAltar.lua
│ ├── Painting.json
│ ├── PortalDoor.json
│ ├── Pot.json
│ ├── Pumpkin.json
│ ├── RandomDisplay.json
│ ├── RedstoneLamp.json
│ ├── RedstonePlate.json
│ ├── RedstonePlate.lua
│ ├── RedstoneTorch.json
│ ├── Sapling.json
│ ├── Shooter.json
│ ├── SnowQueenBall.json
│ ├── SnowQueenBall.lua
│ ├── SoulSand.json
│ ├── SoulSand.lua
│ ├── Sponge.json
│ ├── Stalactite.json
│ ├── Storage.json
│ ├── Sugarcane.json
│ ├── TNT.json
│ ├── Torch.json
│ ├── TrapStorage.json
│ ├── Vine.json
│ └── WetSponge.json
├── blocks/
│ ├── furnitures/
│ │ ├── beds/
│ │ │ ├── wooden_bed_black.json
│ │ │ ├── wooden_bed_blue.json
│ │ │ ├── wooden_bed_brown.json
│ │ │ ├── wooden_bed_cyan.json
│ │ │ ├── wooden_bed_gray.json
│ │ │ ├── wooden_bed_green.json
│ │ │ ├── wooden_bed_light_blue.json
│ │ │ ├── wooden_bed_light_gray.json
│ │ │ ├── wooden_bed_lime.json
│ │ │ ├── wooden_bed_magenta.json
│ │ │ ├── wooden_bed_orange.json
│ │ │ ├── wooden_bed_pink.json
│ │ │ ├── wooden_bed_purple.json
│ │ │ ├── wooden_bed_red.json
│ │ │ ├── wooden_bed_white.json
│ │ │ └── wooden_bed_yellow.json
│ │ ├── benches/
│ │ │ ├── bench_acacia.json
│ │ │ ├── bench_birch.json
│ │ │ ├── bench_dark_oak.json
│ │ │ ├── bench_jungle.json
│ │ │ ├── bench_nether.json
│ │ │ ├── bench_oak.json
│ │ │ ├── bench_palm.json
│ │ │ ├── bench_spruce.json
│ │ │ ├── bench_tainted.json
│ │ │ └── bench_volcano.json
│ │ ├── bookcases/
│ │ │ ├── bookcase_acacia.json
│ │ │ ├── bookcase_birch.json
│ │ │ ├── bookcase_dark_oak.json
│ │ │ ├── bookcase_jungle.json
│ │ │ ├── bookcase_nether.json
│ │ │ ├── bookcase_oak.json
│ │ │ ├── bookcase_palm.json
│ │ │ ├── bookcase_spruce.json
│ │ │ ├── bookcase_tainted.json
│ │ │ └── bookcase_volcano.json
│ │ ├── bosses/
│ │ │ ├── nether_altar.json
│ │ │ └── snow_glass_ball.json
│ │ ├── cabinet/
│ │ │ ├── cabinet_acacia.json
│ │ │ ├── cabinet_birch.json
│ │ │ ├── cabinet_dark_oak.json
│ │ │ ├── cabinet_jungle.json
│ │ │ ├── cabinet_nether.json
│ │ │ ├── cabinet_oak.json
│ │ │ ├── cabinet_palm.json
│ │ │ ├── cabinet_spruce.json
│ │ │ ├── cabinet_tainted.json
│ │ │ └── cabinet_volcano.json
│ │ ├── chairs/
│ │ │ ├── chair_acacia.json
│ │ │ ├── chair_birch.json
│ │ │ ├── chair_dark_oak.json
│ │ │ ├── chair_jungle.json
│ │ │ ├── chair_nether.json
│ │ │ ├── chair_oak.json
│ │ │ ├── chair_palm.json
│ │ │ ├── chair_spruce.json
│ │ │ ├── chair_tainted.json
│ │ │ └── chair_volcano.json
│ │ ├── chests/
│ │ │ ├── barrel.json
│ │ │ ├── chest.json
│ │ │ ├── ender_chest.json
│ │ │ ├── nether_chest.json
│ │ │ ├── shulker_box.json
│ │ │ ├── stone_chest.json
│ │ │ └── trapped_chest.json
│ │ ├── doors/
│ │ │ ├── door_nether.json
│ │ │ ├── door_nether_open.json
│ │ │ ├── iron_door.json
│ │ │ ├── iron_door_open.json
│ │ │ ├── wooden_door_acacia.json
│ │ │ ├── wooden_door_acacia_open.json
│ │ │ ├── wooden_door_birch.json
│ │ │ ├── wooden_door_birch_open.json
│ │ │ ├── wooden_door_dark_oak.json
│ │ │ ├── wooden_door_dark_oak_open.json
│ │ │ ├── wooden_door_jungle.json
│ │ │ ├── wooden_door_jungle_open.json
│ │ │ ├── wooden_door_oak.json
│ │ │ ├── wooden_door_oak_open.json
│ │ │ ├── wooden_door_palm.json
│ │ │ ├── wooden_door_palm_open.json
│ │ │ ├── wooden_door_spruce.json
│ │ │ ├── wooden_door_spruce_open.json
│ │ │ ├── wooden_door_tainted.json
│ │ │ ├── wooden_door_tainted_open.json
│ │ │ ├── wooden_door_volcano.json
│ │ │ └── wooden_door_volcano_open.json
│ │ ├── farms/
│ │ │ ├── carrot.json
│ │ │ ├── melon_stem.json
│ │ │ ├── nether_wart.json
│ │ │ ├── potato.json
│ │ │ ├── pumpkin.json
│ │ │ ├── pumpkin_carved.json
│ │ │ ├── pumpkin_stem.json
│ │ │ ├── sugar_cane.json
│ │ │ ├── watermelon.json
│ │ │ └── wheat.json
│ │ ├── flowers/
│ │ │ ├── allium.json
│ │ │ ├── azure_bluet.json
│ │ │ ├── blue_orchid.json
│ │ │ ├── dandelion.json
│ │ │ ├── fern.json
│ │ │ ├── lilac.json
│ │ │ ├── orange_tulip.json
│ │ │ ├── peony.json
│ │ │ ├── pink_tulip.json
│ │ │ ├── poppy.json
│ │ │ ├── red_tulip.json
│ │ │ ├── rose_bush.json
│ │ │ ├── sunflower.json
│ │ │ └── white_tulip.json
│ │ ├── grasses/
│ │ │ ├── blood_grass.json
│ │ │ ├── eyeball_grass.json
│ │ │ ├── grass.json
│ │ │ ├── large_eyeball_grass.json
│ │ │ └── tainted_grass.json
│ │ ├── lightings/
│ │ │ ├── candle.json
│ │ │ ├── candle_holder.json
│ │ │ ├── chandeliers.json
│ │ │ ├── fire_lamp.json
│ │ │ ├── jack_o_lantern.json
│ │ │ ├── lantern.json
│ │ │ └── nether_lamp.json
│ │ ├── misc/
│ │ │ ├── anvil.json
│ │ │ ├── book.json
│ │ │ ├── brewing_stand.json
│ │ │ ├── cake.json
│ │ │ ├── campfire.json
│ │ │ ├── cauldron.json
│ │ │ ├── cobweb.json
│ │ │ ├── crafting_table.json
│ │ │ ├── enchantment_table.json
│ │ │ ├── flower_pot.json
│ │ │ ├── flower_pot_large.json
│ │ │ ├── furnace.json
│ │ │ ├── health_crystal.json
│ │ │ ├── jukebox.json
│ │ │ ├── pot.json
│ │ │ ├── potion.json
│ │ │ ├── sign.json
│ │ │ ├── skull.json
│ │ │ └── thorn.json
│ │ ├── mushrooms/
│ │ │ ├── brown_mushroom.json
│ │ │ ├── glowing_mushroom.json
│ │ │ ├── large_brown_mushroom.json
│ │ │ ├── large_poison_mushroom.json
│ │ │ ├── large_red_mushroom.json
│ │ │ ├── poison_mushroom.json
│ │ │ └── red_mushroom.json
│ │ ├── paintings/
│ │ │ ├── painting.json
│ │ │ ├── painting_2x2.json
│ │ │ ├── painting_2x4.json
│ │ │ ├── painting_4x2.json
│ │ │ ├── painting_4x4.json
│ │ │ ├── painting_8x4.json
│ │ │ ├── painting_8x6.json
│ │ │ └── painting_8x8.json
│ │ ├── plants/
│ │ │ └── bush.json
│ │ ├── redstones/
│ │ │ ├── daylight_sensor.json
│ │ │ ├── daylight_sensor_inverted.json
│ │ │ ├── dispenser.json
│ │ │ ├── lever.json
│ │ │ ├── pressure_plates/
│ │ │ │ ├── pressure_plate_golden.json
│ │ │ │ ├── pressure_plate_iron.json
│ │ │ │ ├── pressure_plate_stone.json
│ │ │ │ └── pressure_plate_wooden.json
│ │ │ ├── redstone_lamp.json
│ │ │ ├── stone_button.json
│ │ │ └── wooden_button.json
│ │ ├── rocks/
│ │ │ ├── rock.json
│ │ │ └── rock_waste.json
│ │ ├── saplings/
│ │ │ ├── sapling_acacia.json
│ │ │ ├── sapling_bare_oak.json
│ │ │ ├── sapling_birch.json
│ │ │ ├── sapling_cactus.json
│ │ │ ├── sapling_dark_oak.json
│ │ │ ├── sapling_jungle.json
│ │ │ ├── sapling_oak.json
│ │ │ ├── sapling_palm.json
│ │ │ ├── sapling_spruce.json
│ │ │ ├── sapling_tainted.json
│ │ │ └── sapling_volcano.json
│ │ ├── seas/
│ │ │ ├── coral.json
│ │ │ ├── kelp.json
│ │ │ ├── sea_grass.json
│ │ │ └── sea_shell.json
│ │ ├── small_trees/
│ │ │ ├── small_tree_desert.json
│ │ │ ├── small_tree_normal.json
│ │ │ ├── small_tree_snowy.json
│ │ │ ├── small_tree_tainted.json
│ │ │ └── small_tree_waste.json
│ │ ├── stabs/
│ │ │ ├── stab_hanging_tainted.json
│ │ │ └── stab_tainted.json
│ │ ├── stalactites/
│ │ │ ├── stalactite_andesite.json
│ │ │ ├── stalactite_desert.json
│ │ │ ├── stalactite_diorite.json
│ │ │ ├── stalactite_granite.json
│ │ │ ├── stalactite_hanging_andesite.json
│ │ │ ├── stalactite_hanging_desert.json
│ │ │ ├── stalactite_hanging_diorite.json
│ │ │ ├── stalactite_hanging_granite.json
│ │ │ ├── stalactite_hanging_ice.json
│ │ │ ├── stalactite_hanging_small_andesite.json
│ │ │ ├── stalactite_hanging_small_desert.json
│ │ │ ├── stalactite_hanging_small_diorite.json
│ │ │ ├── stalactite_hanging_small_granite.json
│ │ │ ├── stalactite_hanging_small_ice.json
│ │ │ ├── stalactite_hanging_small_stone.json
│ │ │ ├── stalactite_hanging_small_tainted.json
│ │ │ ├── stalactite_hanging_small_waste.json
│ │ │ ├── stalactite_hanging_stone.json
│ │ │ ├── stalactite_hanging_tainted.json
│ │ │ ├── stalactite_hanging_waste.json
│ │ │ ├── stalactite_ice.json
│ │ │ ├── stalactite_small_andesite.json
│ │ │ ├── stalactite_small_desert.json
│ │ │ ├── stalactite_small_diorite.json
│ │ │ ├── stalactite_small_granite.json
│ │ │ ├── stalactite_small_ice.json
│ │ │ ├── stalactite_small_stone.json
│ │ │ ├── stalactite_small_tainted.json
│ │ │ ├── stalactite_small_waste.json
│ │ │ ├── stalactite_stone.json
│ │ │ ├── stalactite_tainted.json
│ │ │ └── stalactite_waste.json
│ │ ├── stone_decoses/
│ │ │ ├── stone_decos_ice.json
│ │ │ ├── stone_decos_mossy.json
│ │ │ ├── stone_decos_normal.json
│ │ │ ├── stone_decos_tainted.json
│ │ │ └── stone_decos_waste.json
│ │ ├── stone_pillars/
│ │ │ ├── stone_pillar_desert.json
│ │ │ ├── stone_pillar_ice.json
│ │ │ ├── stone_pillar_normal.json
│ │ │ └── stone_pillar_tainted.json
│ │ ├── tables/
│ │ │ ├── table_acacia.json
│ │ │ ├── table_birch.json
│ │ │ ├── table_dark_oak.json
│ │ │ ├── table_jungle.json
│ │ │ ├── table_nether.json
│ │ │ ├── table_oak.json
│ │ │ ├── table_palm.json
│ │ │ ├── table_spruce.json
│ │ │ ├── table_tainted.json
│ │ │ └── table_volcano.json
│ │ ├── tentacles/
│ │ │ ├── flesh_tentacle.json
│ │ │ └── flesh_tentacle_hanging.json
│ │ ├── torches/
│ │ │ ├── blue_torch.json
│ │ │ ├── end_rod.json
│ │ │ ├── green_torch.json
│ │ │ ├── red_torch.json
│ │ │ ├── redstone_torch.json
│ │ │ ├── torch.json
│ │ │ ├── white_torch.json
│ │ │ └── yellow_torch.json
│ │ └── vines/
│ │ ├── eyeball_vine.json
│ │ ├── tainted_vine.json
│ │ └── vine.json
│ └── tiles/
│ ├── andesites/
│ │ ├── andesite.json
│ │ └── andesite_polished.json
│ ├── auroras/
│ │ ├── aurora_block.json
│ │ └── aurora_pillar.json
│ ├── diorites/
│ │ ├── diorite.json
│ │ └── diorite_polished.json
│ ├── ends/
│ │ ├── end_stone.json
│ │ └── end_stone_brick.json
│ ├── fences/
│ │ ├── cobblestone_fence.json
│ │ ├── fence_acacia.json
│ │ ├── fence_birch.json
│ │ ├── fence_dark_oak.json
│ │ ├── fence_jungle.json
│ │ ├── fence_nether.json
│ │ ├── fence_oak.json
│ │ ├── fence_palm.json
│ │ ├── fence_spruce.json
│ │ ├── fence_tainted.json
│ │ ├── fence_volcano.json
│ │ ├── iron_bar.json
│ │ └── mossy_cobblestone_fence.json
│ ├── fleshes/
│ │ ├── flesh_dirt.json
│ │ ├── flesh_gut.json
│ │ └── flesh_stone.json
│ ├── glasses/
│ │ ├── glass.json
│ │ ├── stained_glass_black.json
│ │ ├── stained_glass_blue.json
│ │ ├── stained_glass_brown.json
│ │ ├── stained_glass_cyan.json
│ │ ├── stained_glass_gray.json
│ │ ├── stained_glass_green.json
│ │ ├── stained_glass_light_blue.json
│ │ ├── stained_glass_light_gray.json
│ │ ├── stained_glass_lime.json
│ │ ├── stained_glass_magenta.json
│ │ ├── stained_glass_orange.json
│ │ ├── stained_glass_pink.json
│ │ ├── stained_glass_purple.json
│ │ ├── stained_glass_red.json
│ │ ├── stained_glass_white.json
│ │ └── stained_glass_yellow.json
│ ├── granites/
│ │ ├── granite.json
│ │ └── granite_polished.json
│ ├── ices/
│ │ ├── blue_ice.json
│ │ ├── ice.json
│ │ ├── ice_brick.json
│ │ ├── ice_cobblestone.json
│ │ ├── ice_packed.json
│ │ └── ice_thin.json
│ ├── misc/
│ │ ├── bedrock.json
│ │ ├── bone_block.json
│ │ ├── brick.json
│ │ ├── clay.json
│ │ ├── coarse_dirt.json
│ │ ├── dirt.json
│ │ ├── dirt.mdp
│ │ ├── dirt2.mdp
│ │ ├── dried_kelp_block.json
│ │ ├── farmland.json
│ │ ├── gravel.json
│ │ ├── hay_bale.json
│ │ ├── obsidian.json
│ │ ├── slime_block.json
│ │ └── tnt.json
│ ├── mushrooms/
│ │ ├── brown_mushroom_block.json
│ │ ├── mushroom_stem.json
│ │ ├── mycelium.json
│ │ └── red_mushroom_block.json
│ ├── nethers/
│ │ ├── glowstone.json
│ │ ├── nether_brick.json
│ │ ├── netherrack.json
│ │ ├── red_nether_brick.json
│ │ └── soul_sand.json
│ ├── ore_blocks/
│ │ ├── block_coal.json
│ │ ├── block_diamond.json
│ │ ├── block_emerald.json
│ │ ├── block_gold.json
│ │ ├── block_iron.json
│ │ ├── block_lapis.json
│ │ ├── block_netherite.json
│ │ ├── block_quartz.json
│ │ └── block_redstone.json
│ ├── ores/
│ │ ├── ore_ancient_debris.json
│ │ ├── ore_coal.json
│ │ ├── ore_copper.json
│ │ ├── ore_diamond.json
│ │ ├── ore_emerald.json
│ │ ├── ore_gold.json
│ │ ├── ore_iron.json
│ │ ├── ore_lapis.json
│ │ ├── ore_lead.json
│ │ ├── ore_nether_quartz.json
│ │ ├── ore_redstone.json
│ │ ├── ore_silver.json
│ │ └── ore_tin.json
│ ├── planks/
│ │ ├── plank_acacia.json
│ │ ├── plank_birch.json
│ │ ├── plank_dark_oak.json
│ │ ├── plank_jungle.json
│ │ ├── plank_oak.json
│ │ ├── plank_palm.json
│ │ ├── plank_spruce.json
│ │ ├── plank_tainted.json
│ │ └── plank_volcano.json
│ ├── platforms/
│ │ ├── platform_acacia.json
│ │ ├── platform_birch.json
│ │ ├── platform_dark_oak.json
│ │ ├── platform_end_stone.json
│ │ ├── platform_jungle.json
│ │ ├── platform_nether_brick.json
│ │ ├── platform_oak.json
│ │ ├── platform_palm.json
│ │ ├── platform_prismarine.json
│ │ ├── platform_prismarine_dark.json
│ │ ├── platform_purpur.json
│ │ ├── platform_quartz.json
│ │ ├── platform_red_sand_stone.json
│ │ ├── platform_sandstone.json
│ │ ├── platform_spruce.json
│ │ ├── platform_stone_brick.json
│ │ ├── platform_tainted.json
│ │ └── platform_volcano.json
│ ├── prismarines/
│ │ ├── prismarine.json
│ │ ├── prismarine_brick.json
│ │ ├── prismarine_dark.json
│ │ ├── prismarine_mud.json
│ │ └── sea_lantern.json
│ ├── purpurs/
│ │ └── purpur_block.json
│ ├── red_sands/
│ │ ├── red_sand.json
│ │ ├── red_sand_carved.json
│ │ ├── red_sand_smooth.json
│ │ └── red_sand_stone.json
│ ├── sands/
│ │ ├── sand.json
│ │ ├── sandstone.json
│ │ ├── sandstone_carved.json
│ │ └── sandstone_smooth.json
│ ├── snows/
│ │ ├── snow.json
│ │ └── snow_brick.json
│ ├── sponges/
│ │ ├── sponge.json
│ │ └── wet_sponge.json
│ ├── stones/
│ │ ├── cobblestone.json
│ │ ├── cobblestone_mossy.json
│ │ ├── stone.json
│ │ ├── stone_brick.json
│ │ ├── stone_brick_carved.json
│ │ ├── stone_brick_cracked.json
│ │ └── stone_brick_mossy.json
│ ├── tainted/
│ │ ├── tainted_dirt.json
│ │ └── tainted_stone.json
│ ├── terracottas/
│ │ ├── terracotta_black.json
│ │ ├── terracotta_blue.json
│ │ ├── terracotta_brown.json
│ │ ├── terracotta_cyan.json
│ │ ├── terracotta_gray.json
│ │ ├── terracotta_green.json
│ │ ├── terracotta_light_blue.json
│ │ ├── terracotta_light_gray.json
│ │ ├── terracotta_lime.json
│ │ ├── terracotta_magenta.json
│ │ ├── terracotta_orange.json
│ │ ├── terracotta_pink.json
│ │ ├── terracotta_purple.json
│ │ ├── terracotta_red.json
│ │ ├── terracotta_white.json
│ │ └── terracotta_yellow.json
│ ├── test/
│ │ ├── blue_mushroom.json
│ │ ├── blue_mushroom_dirt.json
│ │ ├── blue_mushroom_stem.json
│ │ ├── ice_cobblestone_hard.json
│ │ ├── large_blue_mushroom.json
│ │ ├── lava_block_pile.json
│ │ ├── pile_cobblestone.json
│ │ ├── snow_soft.json
│ │ ├── volcano_burn_stone.json
│ │ └── volcano_cobblestone.json
│ ├── volcanos/
│ │ ├── magma_block.json
│ │ ├── volcano_dirt.json
│ │ └── volcano_stone.json
│ ├── woods/
│ │ ├── wood_acacia.json
│ │ ├── wood_birch.json
│ │ ├── wood_dark_oak.json
│ │ ├── wood_jungle.json
│ │ ├── wood_oak.json
│ │ ├── wood_palm.json
│ │ ├── wood_spruce.json
│ │ ├── wood_stripped_acacia.json
│ │ ├── wood_stripped_birch.json
│ │ ├── wood_stripped_dark_oak.json
│ │ ├── wood_stripped_jungle.json
│ │ ├── wood_stripped_oak.json
│ │ ├── wood_stripped_palm.json
│ │ ├── wood_stripped_spruce.json
│ │ ├── wood_stripped_tainted.json
│ │ ├── wood_stripped_volcano.json
│ │ ├── wood_tainted.json
│ │ └── wood_volcano.json
│ └── wools/
│ ├── wool_black.json
│ ├── wool_blue.json
│ ├── wool_brown.json
│ ├── wool_cyan.json
│ ├── wool_gray.json
│ ├── wool_green.json
│ ├── wool_light_blue.json
│ ├── wool_light_gray.json
│ ├── wool_lime.json
│ ├── wool_magenta.json
│ ├── wool_orange.json
│ ├── wool_pink.json
│ ├── wool_purple.json
│ ├── wool_red.json
│ ├── wool_white.json
│ └── wool_yellow.json
├── bone2d/
│ ├── ItemJointHelper.lua
│ ├── NpcHumanAnimator.lua
│ ├── NpcHumanBoneInfo.lua
│ ├── NpcHumanClips.lua
│ ├── NpcHumanJoints.lua
│ ├── NpcHumanJointsTall.lua
│ ├── PlayerAnimator.lua
│ ├── PlayerBoneInfo.lua
│ ├── PlayerClips.lua
│ └── PlayerJoints.lua
├── buffs/
│ ├── BaseBuffProxy.lua
│ ├── BuffBlindness.lua
│ ├── BuffFire.lua
│ ├── BuffGlowing.lua
│ ├── BuffHappiness.lua
│ ├── BuffHealthBoost.lua
│ ├── BuffHunger.lua
│ ├── BuffHurt.lua
│ ├── BuffInvisibility.lua
│ ├── BuffJumpBoost.lua
│ ├── BuffLevitation.lua
│ ├── BuffMiningFatigue.lua
│ ├── BuffPoison.lua
│ ├── BuffProxies.lua
│ ├── BuffRegeneration.lua
│ ├── BuffResistance.lua
│ ├── BuffSadness.lua
│ ├── BuffSlowFalling.lua
│ ├── BuffSlowMining.lua
│ ├── BuffSlowness.lua
│ ├── BuffSpeed.lua
│ ├── BuffStrength.lua
│ ├── BuffVision.lua
│ ├── BuffWeak.lua
│ ├── BuffWither.lua
│ ├── absorption.json
│ ├── blindness.json
│ ├── fire.json
│ ├── fire_defense.json
│ ├── glowing.json
│ ├── happiness.json
│ ├── health_boost.json
│ ├── health_cold.json
│ ├── hunger.json
│ ├── hurt.json
│ ├── invisibility.json
│ ├── jump_boost.json
│ ├── levitation.json
│ ├── luck.json
│ ├── mining_fatique.json
│ ├── nausea.json
│ ├── poison.json
│ ├── regeneration.json
│ ├── resistance.json
│ ├── sadness.json
│ ├── slow_falling.json
│ ├── slow_mining.json
│ ├── slowness.json
│ ├── speed.json
│ ├── strength.json
│ ├── vision.json
│ ├── water_breathing.json
│ ├── weak.json
│ └── wither.json
├── buildings/
│ ├── aurora_palace/
│ │ └── aurora_palace.json
│ ├── by_house/
│ │ └── by_house.json
│ ├── desert_house/
│ │ └── desert_house.json
│ ├── end_outpost/
│ │ └── end_outpost.json
│ ├── forest_house/
│ │ └── forest_house.json
│ ├── fossils/
│ │ └── fossils.json
│ ├── heart/
│ │ └── heart.json
│ ├── jungle_temple/
│ │ └── jungle_temple.json
│ ├── mineshaft/
│ │ └── mineshaft.json
│ ├── mini_house/
│ │ └── mini_house.json
│ ├── monument_ocean/
│ │ └── monument_ocean.json
│ ├── nether_fortress/
│ │ └── nether_fortress.json
│ ├── pyramid/
│ │ └── pyramid.json
│ ├── under_dark_oak_cabin/
│ │ └── under_dark_oak_cabin.json
│ ├── under_desert_cabin/
│ │ └── under_desert_cabin.json
│ ├── under_jungle_cabin/
│ │ └── under_jungle_cabin.json
│ ├── under_oak_cabin/
│ │ └── under_oak_cabin.json
│ ├── under_spruce_cabin/
│ │ └── under_spruce_cabin.json
│ ├── under_stone_cabin/
│ │ └── under_stone_cabin.json
│ └── under_tainted_cabin/
│ └── under_tainted_cabin.json
├── client/
│ ├── CameraInGame.lua
│ ├── ControlAimMode.lua
│ ├── InputControl.lua
│ ├── MenuJoinInfo.lua
│ ├── ModClient.lua
│ ├── ModMusicSceneProxy.lua
│ ├── MusicCopyright.lua
│ ├── MusicPool.lua
│ ├── MusicScene.lua
│ ├── MusicSceneProxy.lua
│ └── MusicSystem.lua
├── constants/
│ └── Constants.lua
├── contents/
│ ├── IGNORE_THIS_FOLDER.txt
│ └── commands/
│ ├── admin.json
│ ├── admin.lua
│ ├── autosave-off.json
│ ├── autosave-on.json
│ ├── autosaveoff.lua
│ ├── autosaveon.lua
│ ├── banip.json
│ ├── banip.lua
│ ├── blacklist.json
│ ├── blacklist.lua
│ ├── blueyoshiiscool.json
│ ├── buff.json
│ ├── buff.lua
│ ├── buffp.json
│ ├── byiscool.lua
│ ├── clear.json
│ ├── clear.lua
│ ├── clearp.json
│ ├── day.json
│ ├── day.lua
│ ├── dayf.json
│ ├── dayf.lua
│ ├── daylock.json
│ ├── daylock.lua
│ ├── dayspeed.json
│ ├── dayspeed.lua
│ ├── dayunlock.json
│ ├── dayunlock.lua
│ ├── effect.json
│ ├── effect.lua
│ ├── enchant.json
│ ├── enchant.lua
│ ├── ex.json
│ ├── ex.lua
│ ├── exp.json
│ ├── gamemode.json
│ ├── gamemodep.json
│ ├── gamemodep.lua
│ ├── gamemodew.json
│ ├── gamemodew.lua
│ ├── give.json
│ ├── give.lua
│ ├── givep.json
│ ├── home.json
│ ├── home.lua
│ ├── kick.json
│ ├── kick.lua
│ ├── kickall.json
│ ├── kickall.lua
│ ├── kill.json
│ ├── kill.lua
│ ├── killp.json
│ ├── master.json
│ ├── master.lua
│ ├── me.json
│ ├── me.lua
│ ├── msg.json
│ ├── msg.lua
│ ├── noadmin.json
│ ├── noadmin.lua
│ ├── nobanip.json
│ ├── nobanip.lua
│ ├── nomaster.json
│ ├── nomaster.lua
│ ├── npc.json
│ ├── npc.lua
│ ├── players.json
│ ├── players.lua
│ ├── port.json
│ ├── port.lua
│ ├── pvp-off.json
│ ├── pvp-on.json
│ ├── pvpoff.lua
│ ├── pvpon.lua
│ ├── safeblow-off.json
│ ├── safeblow-on.json
│ ├── safeblowoff.lua
│ ├── safeblowon.lua
│ ├── save.json
│ ├── save.lua
│ ├── say.json
│ ├── say.lua
│ ├── spawn.json
│ ├── spawn.lua
│ ├── state.json
│ ├── stopwea.json
│ ├── stopwea.lua
│ ├── tp.json
│ ├── tp.lua
│ ├── tpp.json
│ ├── wea.json
│ └── wea.lua
├── data/
│ ├── backgrounds.json
│ ├── block_config.json
│ ├── item_config.json
│ ├── sound_config.json
│ └── sounds.json
├── effect_ai/
│ ├── Explosion.json
│ ├── GlowingFlow.json
│ ├── Gore.json
│ └── Smoke.json
├── effects/
│ ├── arrow_paticular.json
│ ├── chasting_word.json
│ ├── chip.json
│ ├── chip_fast.json
│ ├── circle.json
│ ├── ender_flash.json
│ ├── exp_paticular.json
│ ├── explosion.json
│ ├── fallen_flame_star.json
│ ├── fire.json
│ ├── fire_flame.json
│ ├── fire_flame_long.json
│ ├── fire_smoke.json
│ ├── flame_star.json
│ ├── flash.json
│ ├── flash2.json
│ ├── flow_particular.json
│ ├── gores/
│ │ ├── gore_angry_skeleton.json
│ │ ├── gore_arrow_zombie.json
│ │ ├── gore_bald_zombie.json
│ │ ├── gore_bat.json
│ │ ├── gore_black_rabbit.json
│ │ ├── gore_black_skeleton.json
│ │ ├── gore_blood_bat.json
│ │ ├── gore_blood_eye.json
│ │ ├── gore_blood_skeleton.json
│ │ ├── gore_bone_lee.json
│ │ ├── gore_bone_officer.json
│ │ ├── gore_bone_sniper.json
│ │ ├── gore_boney_skeleton.json
│ │ ├── gore_brown_mushroom_cow.json
│ │ ├── gore_brown_rabbit.json
│ │ ├── gore_chicken.json
│ │ ├── gore_cow.json
│ │ ├── gore_creeper.json
│ │ ├── gore_cursed_skull.json
│ │ ├── gore_dark_mage.json
│ │ ├── gore_dead_mage.json
│ │ ├── gore_doge_zombie.json
│ │ ├── gore_dolphin.json
│ │ ├── gore_drowned.json
│ │ ├── gore_dungeon_creeper.json
│ │ ├── gore_dungeon_knight.json
│ │ ├── gore_eagle.json
│ │ ├── gore_enderman.json
│ │ ├── gore_evil.json
│ │ ├── gore_evoker.json
│ │ ├── gore_eye_guard.json
│ │ ├── gore_eye_guard_laser.json
│ │ ├── gore_flower_creeper.json
│ │ ├── gore_fly_eye.json
│ │ ├── gore_fly_mouth.json
│ │ ├── gore_fly_skeleton.json
│ │ ├── gore_giant_cursed_skull.json
│ │ ├── gore_grass_walker.json
│ │ ├── gore_grim_reaper.json
│ │ ├── gore_husk.json
│ │ ├── gore_ice_sprite_girl.json
│ │ ├── gore_iron_zombie.json
│ │ ├── gore_jungle_bat.json
│ │ ├── gore_large_bat.json
│ │ ├── gore_large_jungle_bat.json
│ │ ├── gore_large_spider.json
│ │ ├── gore_lava_snake_body.json
│ │ ├── gore_lava_snake_head.json
│ │ ├── gore_lava_snake_tail.json
│ │ ├── gore_mad_skeleton.json
│ │ ├── gore_mad_skeleton_armed.json
│ │ ├── gore_mad_skeleton_tall.json
│ │ ├── gore_mad_skeleton_tall_armed.json
│ │ ├── gore_mad_skeleton_tall_helmet_armed.json
│ │ ├── gore_magma_birdo.json
│ │ ├── gore_man_eater.json
│ │ ├── gore_mummy.json
│ │ ├── gore_paimon.json
│ │ ├── gore_phantom.json
│ │ ├── gore_pig.json
│ │ ├── gore_ragged_mage.json
│ │ ├── gore_red_mage.json
│ │ ├── gore_red_mushroom_cow.json
│ │ ├── gore_red_phantom.json
│ │ ├── gore_rock_man.json
│ │ ├── gore_sheep.json
│ │ ├── gore_shulker.json
│ │ ├── gore_skeleton_assaulter.json
│ │ ├── gore_skeleton_blue_armed.json
│ │ ├── gore_skeleton_blue_armed_masked.json
│ │ ├── gore_skeleton_blue_knight.json
│ │ ├── gore_skeleton_fire_armed.json
│ │ ├── gore_skeleton_fire_armed_swordsman.json
│ │ ├── gore_skeleton_guard.json
│ │ ├── gore_skeleton_kid.json
│ │ ├── gore_skull.json
│ │ ├── gore_small_hell_eater.json
│ │ ├── gore_snow_guner.json
│ │ ├── gore_spider.json
│ │ ├── gore_squid.json
│ │ ├── gore_tainted_creeper.json
│ │ ├── gore_tainted_skeleton.json
│ │ ├── gore_turtle.json
│ │ ├── gore_undead_miner.json
│ │ ├── gore_vampire_miner.json
│ │ ├── gore_villager_zombie.json
│ │ ├── gore_waste_mummy.json
│ │ ├── gore_white_rabbit.json
│ │ ├── gore_wither_skeleton.json
│ │ ├── gore_worm_body.json
│ │ ├── gore_worm_head.json
│ │ ├── gore_worm_tail.json
│ │ ├── gore_yellow_rabbit.json
│ │ ├── gore_zombie.json
│ │ └── gore_zombie_pigman.json
│ ├── heal.json
│ ├── laser_flash.json
│ ├── liquid_paticular.json
│ ├── poison.json
│ ├── pot_break.json
│ ├── redstone_smoke.json
│ ├── smoke.json
│ ├── star.json
│ └── white_smoke.json
├── enchantments/
│ ├── BaseEnchantmentProxy.lua
│ ├── EnchantmentAquaAffinity.lua
│ ├── EnchantmentBlastProtection.lua
│ ├── EnchantmentDepthStrider.lua
│ ├── EnchantmentFeatherFalling.lua
│ ├── EnchantmentFireProtection.lua
│ ├── EnchantmentFrostWalker.lua
│ ├── EnchantmentKnockBack.lua
│ ├── EnchantmentPhyton.lua
│ ├── EnchantmentProjectileProtection.lua
│ ├── EnchantmentProtection.lua
│ ├── EnchantmentProxies.lua
│ ├── EnchantmentRespiration.lua
│ ├── EnchantmentSharpness.lua
│ ├── EnchantmentThorns.lua
│ ├── aqua_affinity.json
│ ├── bane_of_arthropods.json
│ ├── blast_protection.json
│ ├── curse_of_binding.json
│ ├── curse_of_vanishing.json
│ ├── depth_strider.json
│ ├── efficiency.json
│ ├── feather_falling.json
│ ├── fire_aspect.json
│ ├── fire_protection.json
│ ├── flame.json
│ ├── fortune.json
│ ├── frost_walker.json
│ ├── infinity.json
│ ├── knockback.json
│ ├── looting.json
│ ├── luck_of_the_sea.json
│ ├── lure.json
│ ├── multishot.json
│ ├── phyton.json
│ ├── piercing.json
│ ├── power.json
│ ├── projectile_protection.json
│ ├── protection.json
│ ├── punch.json
│ ├── quick_charge.json
│ ├── respiration.json
│ ├── sharpness.json
│ ├── silk_touch.json
│ ├── smite.json
│ ├── thorns.json
│ └── unbreaking.json
├── game_debug.json
├── init.lua
├── item_ai/
│ ├── Axe.json
│ ├── Axe.lua
│ ├── BaseAccessory.lua
│ ├── BaseRangedWeapon.lua
│ ├── BaseTool.lua
│ ├── BlueTalisman.json
│ ├── BlueTalisman.lua
│ ├── BossCaller.json
│ ├── BossCaller.lua
│ ├── Bow.json
│ ├── Bow.lua
│ ├── CrisonEye.json
│ ├── CrisonEye.lua
│ ├── DungeonEater.json
│ ├── DungeonEater.lua
│ ├── EnderMirror.json
│ ├── EnderMirror.lua
│ ├── Food.json
│ ├── Food.lua
│ ├── Gun.json
│ ├── Gun.lua
│ ├── InfBow.json
│ ├── InfBow.lua
│ ├── Ingot.json
│ ├── Ingot.lua
│ ├── LavaNecklace.json
│ ├── LavaNecklace.lua
│ ├── LavaSword.json
│ ├── LavaSword.lua
│ ├── LightingTalisman.json
│ ├── LightingTalisman.lua
│ ├── Pickaxe.json
│ ├── Pickaxe.lua
│ ├── Potion.json
│ ├── Potion.lua
│ ├── RedTalisman.json
│ ├── RedTalisman.lua
│ ├── RocketBoost.json
│ ├── RocketBoost.lua
│ ├── Staff.json
│ ├── Staff.lua
│ ├── Sword.json
│ ├── Sword.lua
│ ├── Torch.json
│ ├── Torch.lua
│ ├── cross_bow.json
│ ├── cross_bow.lua
│ ├── dirt.json
│ ├── dirt.lua
│ ├── drill.json
│ ├── drill.lua
│ ├── fire_gun.json
│ ├── fishing_rod.json
│ ├── fishing_rod.lua
│ ├── laser_gun.json
│ ├── magic_sword.json
│ ├── rocket_launcher.json
│ ├── saw.json
│ ├── swordA.json
│ └── swordA.lua
├── items/
│ ├── accessory/
│ │ ├── blue_talisman.json
│ │ ├── gold_talisman.json
│ │ ├── heart_talisman.json
│ │ ├── lava_necklace.json
│ │ ├── lighting_talisman.json
│ │ └── rocket_boost.json
│ ├── armors/
│ │ ├── ancient/
│ │ │ ├── ancient_chestplate.json
│ │ │ ├── ancient_helmet.json
│ │ │ └── ancient_leggings.json
│ │ ├── bronze/
│ │ │ ├── bronze_chestplate.json
│ │ │ ├── bronze_helmet.json
│ │ │ └── bronze_leggings.json
│ │ ├── copper/
│ │ │ ├── copper_chestplate.json
│ │ │ ├── copper_helmet.json
│ │ │ └── copper_leggings.json
│ │ ├── diamond/
│ │ │ ├── diamond_chestplate.json
│ │ │ ├── diamond_helmet.json
│ │ │ └── diamond_leggings.json
│ │ ├── fine_tin/
│ │ │ ├── fine_tin_chestplate.json
│ │ │ ├── fine_tin_helmet.json
│ │ │ └── fine_tin_leggings.json
│ │ ├── flesh/
│ │ │ ├── flesh_chestplate.json
│ │ │ ├── flesh_helmet.json
│ │ │ └── flesh_leggings.json
│ │ ├── gold/
│ │ │ ├── golden_chestplate.json
│ │ │ ├── golden_helmet.json
│ │ │ └── golden_leggings.json
│ │ ├── iron/
│ │ │ ├── iron_chestplate.json
│ │ │ ├── iron_helmet.json
│ │ │ └── iron_leggings.json
│ │ ├── knight/
│ │ │ ├── knight_chestplate.json
│ │ │ ├── knight_helmet.json
│ │ │ └── knight_leggings.json
│ │ ├── lava/
│ │ │ ├── lava_chestplate.json
│ │ │ ├── lava_helmet.json
│ │ │ └── lava_leggings.json
│ │ ├── lead/
│ │ │ ├── lead_chestplate.json
│ │ │ ├── lead_helmet.json
│ │ │ └── lead_leggings.json
│ │ ├── leather/
│ │ │ ├── leather_chestplate.json
│ │ │ ├── leather_helmet.json
│ │ │ └── leather_leggings.json
│ │ ├── magic_gold/
│ │ │ ├── magic_gold_chestplate.json
│ │ │ ├── magic_gold_helmet.json
│ │ │ └── magic_gold_leggings.json
│ │ ├── magic_shadow/
│ │ │ ├── magic_shadow_chestplate.json
│ │ │ ├── magic_shadow_helmet.json
│ │ │ └── magic_shadow_leggings.json
│ │ ├── magic_silver/
│ │ │ ├── magic_silver_chestplate.json
│ │ │ ├── magic_silver_helmet.json
│ │ │ └── magic_silver_leggings.json
│ │ ├── nether/
│ │ │ ├── nether_chestplate.json
│ │ │ ├── nether_helmet.json
│ │ │ └── nether_leggings.json
│ │ ├── pumpkin/
│ │ │ └── pumpkin_helmet.json
│ │ ├── shadow/
│ │ │ ├── shadow_chestplate.json
│ │ │ ├── shadow_helmet.json
│ │ │ └── shadow_leggings.json
│ │ ├── silver/
│ │ │ ├── silver_chestplate.json
│ │ │ ├── silver_helmet.json
│ │ │ └── silver_leggings.json
│ │ ├── star/
│ │ │ ├── star_chestplate.json
│ │ │ ├── star_helmet.json
│ │ │ └── star_leggings.json
│ │ ├── steel/
│ │ │ ├── steel_chestplate.json
│ │ │ ├── steel_helmet.json
│ │ │ └── steel_leggings.json
│ │ ├── super_diamond/
│ │ │ ├── super_diamond_chestplate.json
│ │ │ ├── super_diamond_helmet.json
│ │ │ └── super_diamond_leggings.json
│ │ └── tin/
│ │ ├── tin_chestplate.json
│ │ ├── tin_helmet.json
│ │ └── tin_leggings.json
│ ├── arrows/
│ │ ├── blood_arrow.json
│ │ ├── blue_arrow.json
│ │ ├── ice_arrow.json
│ │ ├── lighting_arrow.json
│ │ ├── star_arrow.json
│ │ ├── sword_arrow.json
│ │ └── wooden_arrow.json
│ ├── axes/
│ │ ├── bronze_axe.json
│ │ ├── copper_axe.json
│ │ ├── diamond_axe.json
│ │ ├── golden_axe.json
│ │ ├── grass_axe.json
│ │ ├── iron_axe.json
│ │ ├── lead_axe.json
│ │ ├── nether_axe.json
│ │ ├── silver_axe.json
│ │ ├── steel_axe.json
│ │ ├── stone_axe.json
│ │ ├── tin_axe.json
│ │ └── wooden_axe.json
│ ├── bombs/
│ │ ├── bomb.json
│ │ ├── glow_bomb.json
│ │ └── grenade.json
│ ├── boomerangs/
│ │ ├── boomerang.json
│ │ ├── fire_boomerang.json
│ │ └── wooden_boomerang.json
│ ├── bows/
│ │ ├── blood_bow.json
│ │ ├── blue_shot_bow.json
│ │ ├── blue_stone_bow.json
│ │ ├── chast_bow.json
│ │ ├── cross_bow.json
│ │ ├── curse_bow.json
│ │ ├── ice_bow.json
│ │ ├── lighting_bow.json
│ │ ├── shot_bow.json
│ │ ├── super_cross_bow.json
│ │ ├── super_fire_shot_bow.json
│ │ ├── super_spike_shot_bow.json
│ │ └── wooden_bow.json
│ ├── buckets/
│ │ ├── bucket_empty.json
│ │ ├── bucket_lava.json
│ │ ├── bucket_milk.json
│ │ └── bucket_water.json
│ ├── bullets/
│ │ ├── fire_bullet.json
│ │ ├── iron_bullet.json
│ │ └── silver_bullet.json
│ ├── dyes/
│ │ ├── dye_black.json
│ │ ├── dye_blue.json
│ │ ├── dye_brown.json
│ │ ├── dye_cyan.json
│ │ ├── dye_gray.json
│ │ ├── dye_green.json
│ │ ├── dye_light_blue.json
│ │ ├── dye_light_gray.json
│ │ ├── dye_lime.json
│ │ ├── dye_magenta.json
│ │ ├── dye_orange.json
│ │ ├── dye_pink.json
│ │ ├── dye_purple.json
│ │ ├── dye_red.json
│ │ ├── dye_white.json
│ │ └── dye_yellow.json
│ ├── foods/
│ │ ├── apple.json
│ │ ├── baked_potato.json
│ │ ├── beetroot.json
│ │ ├── bread.json
│ │ ├── cake_piece.json
│ │ ├── carrot.json
│ │ ├── chorus_fruit.json
│ │ ├── cooked_chicken.json
│ │ ├── cooked_cod.json
│ │ ├── cooked_mutton.json
│ │ ├── cooked_porkchop.json
│ │ ├── cooked_rabbit.json
│ │ ├── cooked_salmon.json
│ │ ├── cookie.json
│ │ ├── golden_apple.json
│ │ ├── golden_carrot.json
│ │ ├── melon_slice.json
│ │ ├── mushroom_stew.json
│ │ ├── potato.json
│ │ ├── pufferfish.json
│ │ ├── pumpkin_pie.json
│ │ ├── raw_beef.json
│ │ ├── raw_chicken.json
│ │ ├── raw_cod.json
│ │ ├── raw_mutton.json
│ │ ├── raw_porkchop.json
│ │ ├── raw_rabbit.json
│ │ ├── raw_salmon.json
│ │ └── steak.json
│ ├── guns/
│ │ ├── fire_gun.json
│ │ ├── fire_shooter.json
│ │ ├── handgun.json
│ │ ├── rifle.json
│ │ ├── rocket_launcher.json
│ │ ├── shotgun.json
│ │ └── sniper.json
│ ├── hoes/
│ │ ├── stone_hoe.json
│ │ └── wooden_hoe.json
│ ├── ingots/
│ │ ├── aluminum_ingot.json
│ │ ├── antimony_ingot.json
│ │ ├── beryllium_ingot.json
│ │ ├── bismuth_ingot.json
│ │ ├── bronze_ingot.json
│ │ ├── chromium_ingot.json
│ │ ├── cobalt_ingot.json
│ │ ├── copper_ingot.json
│ │ ├── gallium_ingot.json
│ │ ├── gold_ingot.json
│ │ ├── indium_ingot.json
│ │ ├── iridium_ingot.json
│ │ ├── iron_ingot.json
│ │ ├── lead_ingot.json
│ │ ├── lithium_ingot.json
│ │ ├── magnesium_ingot.json
│ │ ├── manganese_ingot.json
│ │ ├── molybdenum_ingot.json
│ │ ├── netherite_ingot.json
│ │ ├── nickel_ingot.json
│ │ ├── niobium_ingot.json
│ │ ├── osmium_ingot.json
│ │ ├── palladium_ingot.json
│ │ ├── platinum_ingot.json
│ │ ├── redstone_ingot.json
│ │ ├── rhenium_ingot.json
│ │ ├── silver_ingot.json
│ │ ├── sodium_ingot.json
│ │ ├── steel_ingot.json
│ │ ├── tantalum_ingot.json
│ │ ├── tin_ingot.json
│ │ ├── titanium_ingot.json
│ │ ├── vanadium_ingot.json
│ │ ├── vibranium_ingot.json
│ │ ├── wolfram_ingot.json
│ │ ├── yttrium_ingot.json
│ │ └── zinc_ingot.json
│ ├── loots/
│ │ ├── guardian.json
│ │ ├── nether_destroyer_loot.json
│ │ └── snow_queen_loot.json
│ ├── magic/
│ │ ├── bone_gun.json
│ │ ├── dark_staff.json
│ │ ├── fire_book.json
│ │ ├── mini_laser_gun.json
│ │ ├── mini_rocket_launcher.json
│ │ ├── soul_laserer.json
│ │ ├── super_shark.json
│ │ ├── super_shark_ghost.json
│ │ ├── sword_fish.json
│ │ ├── sword_fish_gun.json
│ │ └── water_book.json
│ ├── misc/
│ │ ├── blaze_powder.json
│ │ ├── blaze_rod.json
│ │ ├── bone.json
│ │ ├── bone_meal.json
│ │ ├── book.json
│ │ ├── bowl.json
│ │ ├── charcoal.json
│ │ ├── clay.json
│ │ ├── coal.json
│ │ ├── cocoa_bean.json
│ │ ├── diamond.json
│ │ ├── dried_kelp.json
│ │ ├── egg.json
│ │ ├── emerald.json
│ │ ├── enchanted_book.json
│ │ ├── ender_eye.json
│ │ ├── ender_pearl.json
│ │ ├── feather.json
│ │ ├── fermented_spider_eye.json
│ │ ├── fire_charge.json
│ │ ├── firework_rocket.json
│ │ ├── fishing_rod.json
│ │ ├── flint.json
│ │ ├── ghast_tear.json
│ │ ├── glistering_melon_slice.json
│ │ ├── glow_ball.json
│ │ ├── glowstone_dust.json
│ │ ├── gray_feather.json
│ │ ├── gunpowder.json
│ │ ├── heart_of_sea.json
│ │ ├── ink_sac.json
│ │ ├── kelp.json
│ │ ├── lapis_lazuli.json
│ │ ├── leather.json
│ │ ├── lighter.json
│ │ ├── magma_cream.json
│ │ ├── mana_piece.json
│ │ ├── map_paper.json
│ │ ├── nautilus_shell.json
│ │ ├── nether_brick.json
│ │ ├── nether_star.json
│ │ ├── nether_wart.json
│ │ ├── netherite_scrap.json
│ │ ├── paper.json
│ │ ├── phantom_membrane.json
│ │ ├── popped_chorus_fruits.json
│ │ ├── prismarine_crystals.json
│ │ ├── prismarine_shard.json
│ │ ├── quartz.json
│ │ ├── rabbit_foot.json
│ │ ├── rabbit_hide.json
│ │ ├── red_brick.json
│ │ ├── redstone.json
│ │ ├── rocket.json
│ │ ├── rotten_flesh.json
│ │ ├── scute.json
│ │ ├── shears.json
│ │ ├── shulker_shell.json
│ │ ├── slimeball.json
│ │ ├── snowball.json
│ │ ├── spider_eye.json
│ │ ├── stick.json
│ │ ├── string.json
│ │ ├── sugar_cane.json
│ │ ├── suger.json
│ │ ├── totem_of_undying.json
│ │ ├── vine.json
│ │ ├── wheat.json
│ │ └── wire_cutter.json
│ ├── misc2/
│ │ ├── ancient_ingot.json
│ │ ├── ancient_sample.json
│ │ ├── blood.json
│ │ ├── blue_crystal.json
│ │ ├── dark_shadow_ingot.json
│ │ ├── dark_shadow_part.json
│ │ ├── diamond_ingot.json
│ │ ├── ender_mirror.json
│ │ ├── evil_part.json
│ │ ├── flesh_ingot.json
│ │ ├── flesh_machine_part.json
│ │ ├── flesh_part.json
│ │ ├── ghost.json
│ │ ├── ghost_crystal.json
│ │ ├── ghost_element.json
│ │ ├── ice_element.json
│ │ ├── ice_element_ball.json
│ │ ├── knight_ingot.json
│ │ ├── machine_part.json
│ │ ├── magic_cell.json
│ │ ├── magic_cell_group.json
│ │ ├── magic_crystal.json
│ │ ├── magic_silver_ingot.json
│ │ ├── magma_gold_ingot.json
│ │ ├── nether_destroyer.json
│ │ ├── pure_red_stone.json
│ │ ├── red_crystal.json
│ │ ├── red_gold_ingot.json
│ │ ├── soul_element.json
│ │ ├── star_ingot.json
│ │ ├── strange_eye.json
│ │ ├── strange_len.json
│ │ ├── tower_core.json
│ │ ├── white_crystal.json
│ │ └── yellow_crystal.json
│ ├── nuggets/
│ │ ├── gold_nugget.json
│ │ └── iron_nugget.json
│ ├── pickaxes/
│ │ ├── bronze_pickaxe.json
│ │ ├── copper_pickaxe.json
│ │ ├── diamond_pickaxe.json
│ │ ├── golden_pickaxe.json
│ │ ├── grass_pickaxe.json
│ │ ├── iron_pickaxe.json
│ │ ├── lead_pickaxe.json
│ │ ├── nether_pickaxe.json
│ │ ├── silver_pickaxe.json
│ │ ├── steel_pickaxe.json
│ │ ├── stone_pickaxe.json
│ │ ├── tin_pickaxe.json
│ │ └── wooden_pickaxe.json
│ ├── potions/
│ │ ├── glass_bottle.json
│ │ ├── potion_awkward.json
│ │ ├── potion_fire_resistance.json
│ │ ├── potion_fire_resistance_long.json
│ │ ├── potion_glowing.json
│ │ ├── potion_glowing_long.json
│ │ ├── potion_harming.json
│ │ ├── potion_harming_super.json
│ │ ├── potion_healing.json
│ │ ├── potion_healing_super.json
│ │ ├── potion_invisibility.json
│ │ ├── potion_invisibility_long.json
│ │ ├── potion_leaping.json
│ │ ├── potion_leaping_long.json
│ │ ├── potion_night_vision.json
│ │ ├── potion_night_vision_long.json
│ │ ├── potion_poison.json
│ │ ├── potion_poison_long.json
│ │ ├── potion_regeneration.json
│ │ ├── potion_regeneration_long.json
│ │ ├── potion_slow_falling.json
│ │ ├── potion_slow_falling_long.json
│ │ ├── potion_slowness.json
│ │ ├── potion_slowness_long.json
│ │ ├── potion_strength.json
│ │ ├── potion_strength_long.json
│ │ ├── potion_swiftness.json
│ │ ├── potion_swiftness_long.json
│ │ ├── potion_water.json
│ │ ├── potion_water_breathing.json
│ │ ├── potion_water_breathing_long.json
│ │ ├── potion_weakness.json
│ │ └── potion_weakness_long.json
│ ├── seeds/
│ │ ├── melon_seed.json
│ │ ├── pumpkin_seed.json
│ │ └── seed.json
│ ├── staffs/
│ │ ├── amethyst_staff.json
│ │ ├── fire_staff.json
│ │ ├── frosen_staff.json
│ │ ├── ice_staff.json
│ │ ├── lighting_staff.json
│ │ ├── shadow_staff.json
│ │ ├── soul_staff.json
│ │ └── water_staff.json
│ ├── swords/
│ │ ├── air_sword.json
│ │ ├── bronze_sword.json
│ │ ├── copper_sword.json
│ │ ├── diamond_sword.json
│ │ ├── ghost_sword.json
│ │ ├── golden_sword.json
│ │ ├── grass_sword.json
│ │ ├── iron_sword.json
│ │ ├── lava_sword.json
│ │ ├── lead_sword.json
│ │ ├── nether_sword.json
│ │ ├── silver_sword.json
│ │ ├── steel_sword.json
│ │ ├── stone_sword.json
│ │ ├── super_air_sword.json
│ │ ├── super_bronze_sword.json
│ │ ├── super_copper_sword.json
│ │ ├── super_diamond_sword.json
│ │ ├── super_golden_sword.json
│ │ ├── super_iron_sword.json
│ │ ├── super_lead_sword.json
│ │ ├── super_nether_sword.json
│ │ ├── super_silver_sword.json
│ │ ├── super_steel_sword.json
│ │ ├── super_tin_sword.json
│ │ ├── tin_sword.json
│ │ └── wooden_sword.json
│ └── wires/
│ ├── blue_wire.json
│ ├── green_wire.json
│ ├── red_wire.json
│ └── yellow_wire.json
├── languages/
│ ├── Locale.lua
│ ├── LocaleHelper.lua
│ ├── chinese.json
│ └── english.json
├── liquids/
│ ├── lava.json
│ └── water.json
├── mod_textures/
│ ├── ModTextures.lua
│ ├── blade.json
│ ├── candle_fire.json
│ ├── candle_fire_blue.json
│ ├── crack.json
│ ├── electric_direction.json
│ ├── fire.json
│ ├── flesh_grass.json
│ ├── fly_book.json
│ ├── grass.json
│ ├── mycelium_grass.json
│ ├── tainted_grass.json
│ ├── torch_fire.json
│ ├── torch_fire_blue.json
│ ├── torch_fire_green.json
│ ├── torch_fire_red.json
│ ├── torch_fire_white.json
│ ├── torch_fire_yellow.json
│ └── torch_redstone.json
├── network/
│ ├── ClientBoundResponse.lua
│ ├── ModNetworkProxyHandler.lua
│ ├── NetworkProxy.lua
│ ├── RPC_ID.lua
│ └── TCNetworkProxyHandler.lua
├── npc_ai/
│ ├── AngrySkeleton.json
│ ├── AngrySkeleton.lua
│ ├── Animal.json
│ ├── Animal.lua
│ ├── Archer.json
│ ├── Archer.lua
│ ├── BallMagic.json
│ ├── BallMagic.lua
│ ├── BaseSnake.lua
│ ├── BaseSnakeBody.lua
│ ├── Bat.json
│ ├── Bat.lua
│ ├── BlackSkeleton.json
│ ├── BlackSkeleton.lua
│ ├── Blaze.json
│ ├── Blaze.lua
│ ├── BlockSlime.json
│ ├── BlockSlime.lua
│ ├── BloodSkeleton.json
│ ├── BloodSkeleton.lua
│ ├── BloodyEye.json
│ ├── BloodyEye.lua
│ ├── BoneArcher.json
│ ├── BoneArcher.lua
│ ├── BoneLee.json
│ ├── BoneLee.lua
│ ├── BoneOfficer.json
│ ├── BoneOfficer.lua
│ ├── BoneSniper.json
│ ├── BoneSniper.lua
│ ├── BoneySkeleton.json
│ ├── BoneySkeleton.lua
│ ├── BouncySlime.json
│ ├── BouncySlime.lua
│ ├── Butterfly.json
│ ├── Butterfly.lua
│ ├── Cat.json
│ ├── Cat.lua
│ ├── Chicken.json
│ ├── Chicken.lua
│ ├── Creeper.json
│ ├── Creeper.lua
│ ├── CrisonEye.json
│ ├── CrisonEye.lua
│ ├── CrystalMonster.json
│ ├── CrystalMonster.lua
│ ├── CursedSkull.json
│ ├── CursedSkull.lua
│ ├── DarkMage.json
│ ├── DarkMage.lua
│ ├── DeadMage.json
│ ├── DeadMage.lua
│ ├── Dolphin.json
│ ├── Dolphin.lua
│ ├── DungeonCreeper.json
│ ├── DungeonCreeper.lua
│ ├── DungeonEater.lua
│ ├── DungeonEaterBody.lua
│ ├── DungeonEater_Body.json
│ ├── DungeonEater_Head.json
│ ├── DungeonKnight.json
│ ├── DungeonKnight.lua
│ ├── DungeonSkeleton.json
│ ├── DungeonSkeleton.lua
│ ├── DungeonSoul.json
│ ├── DungeonSoul.lua
│ ├── Eagle.json
│ ├── Eagle.lua
│ ├── Ender_Dragon.json
│ ├── Enderman.json
│ ├── Enderman.lua
│ ├── Evil.json
│ ├── Evil.lua
│ ├── Evoker.json
│ ├── Evoker.lua
│ ├── EyeGuard.json
│ ├── EyeGuard.lua
│ ├── EyeGuardLaser.json
│ ├── EyeGuardLaser.lua
│ ├── Fighter.json
│ ├── Fighter.lua
│ ├── FireHellEater.json
│ ├── FireHellEater.lua
│ ├── FlameSoul.json
│ ├── FlameSoul.lua
│ ├── FlyEye.json
│ ├── FlyEye.lua
│ ├── FlySkeleton.json
│ ├── FlySkeleton.lua
│ ├── Ghast.json
│ ├── Ghast.lua
│ ├── GhostGunner.json
│ ├── GhostGunner.lua
│ ├── GhostSoul.json
│ ├── GhostSoul.lua
│ ├── GiantCursedSkull.json
│ ├── GiantCursedSkull.lua
│ ├── GrimReaper.json
│ ├── GrimReaper.lua
│ ├── Guardian.json
│ ├── Guardian.lua
│ ├── HellDestroyer.lua
│ ├── HellDestroyer_Head.json
│ ├── HellEater.json
│ ├── HellEater.lua
│ ├── HumanFighter.json
│ ├── HumanFighter.lua
│ ├── IceElf.json
│ ├── IceElf.lua
│ ├── JungleSnake.lua
│ ├── JungleSnake_Head.json
│ ├── LargeBat.json
│ ├── LargeBat.lua
│ ├── LargeSpider.json
│ ├── LargeSpider.lua
│ ├── MagmaBirdo.json
│ ├── MagmaBirdo.lua
│ ├── MagmaElf.json
│ ├── MagmaElf.lua
│ ├── MagmaSlime.json
│ ├── MagmaSlime.lua
│ ├── ManEater.json
│ ├── ManEater.lua
│ ├── Meteor.json
│ ├── Meteor.lua
│ ├── MiniGhast.json
│ ├── MiniGhast.lua
│ ├── Paimon.json
│ ├── Paimon.lua
│ ├── Phantom.json
│ ├── Phantom.lua
│ ├── Pufferfish.json
│ ├── Pufferfish.lua
│ ├── RaggedMage.json
│ ├── RaggedMage.lua
│ ├── RedMage.json
│ ├── RedMage.lua
│ ├── RedPhantom.json
│ ├── RedPhantom.lua
│ ├── RockMan.json
│ ├── RockMan.lua
│ ├── RollingFireBall.json
│ ├── RollingFireBall.lua
│ ├── Sheep.json
│ ├── Shulker.json
│ ├── Shulker.lua
│ ├── SkeletonAssaulter.json
│ ├── SkeletonAssaulter.lua
│ ├── SkeletonGuard.json
│ ├── SkeletonGuard.lua
│ ├── Slime.json
│ ├── Slime.lua
│ ├── Snake_Body.json
│ ├── Snake_Head.json
│ ├── SnowGuardian.json
│ ├── SnowGuardian.lua
│ ├── SnowGuardianArcher.json
│ ├── SnowGuardianArcher.lua
│ ├── SnowQueen.json
│ ├── SnowQueen.lua
│ ├── Squid.json
│ ├── Squid.lua
│ ├── SwordHumanFighter.lua
│ ├── TaintedSlime.json
│ ├── TaintedSlime.lua
│ ├── UndeadMiner.json
│ ├── UndeadMiner.lua
│ ├── Villager.json
│ ├── WasteGhost.json
│ ├── WasteGhost.lua
│ ├── WitherSkeleton.json
│ ├── WitherSkeleton.lua
│ ├── Wolf.json
│ ├── Wolf.lua
│ ├── Zombie.json
│ ├── Zombie.lua
│ ├── Zpig.json
│ └── Zpig.lua
├── npc_ai_global/
│ ├── GNpc.lua
│ └── GlobalNpc.json
├── npcs/
│ ├── angry_skeleton.json
│ ├── arrow_zombie.json
│ ├── bald_zombie.json
│ ├── bat.json
│ ├── black_rabbit.json
│ ├── black_skeleton.json
│ ├── blaze.json
│ ├── block_slime.json
│ ├── blood_bat.json
│ ├── blood_eye.json
│ ├── blood_skeleton.json
│ ├── blood_slime.json
│ ├── blue_slime.json
│ ├── bone_lee.json
│ ├── bone_officer.json
│ ├── bone_sniper.json
│ ├── boney_skeleton.json
│ ├── bouncy_slime.json
│ ├── brown_mushroom_cow.json
│ ├── brown_rabbit.json
│ ├── cat.json
│ ├── chicken.json
│ ├── cow.json
│ ├── creeper.json
│ ├── crison_eye.json
│ ├── crystal_monster.json
│ ├── cursed_skull.json
│ ├── dark_mage.json
│ ├── dead_mage.json
│ ├── desert_slime.json
│ ├── doge_zombie.json
│ ├── dolphin.json
│ ├── dragon_skull.json
│ ├── drowned.json
│ ├── dungeon_creeper.json
│ ├── dungeon_eater_body.json
│ ├── dungeon_eater_head.json
│ ├── dungeon_eater_tail.json
│ ├── dungeon_knight.json
│ ├── dungeon_slime.json
│ ├── dungeon_soul.json
│ ├── eagle.json
│ ├── ender_dragon.json
│ ├── enderman.json
│ ├── evil.json
│ ├── evoker.json
│ ├── eye_guard.json
│ ├── eye_guard_laser.json
│ ├── flame_soul.json
│ ├── flower_creeper.json
│ ├── fly_eye.json
│ ├── fly_mouth.json
│ ├── fly_skeleton.json
│ ├── ghast.json
│ ├── ghost_gunner.json
│ ├── ghost_soul.json
│ ├── giant_cursed_skull.json
│ ├── green_slime.json
│ ├── grim_reaper.json
│ ├── guardian.json
│ ├── husk.json
│ ├── ice_elf.json
│ ├── ice_slime.json
│ ├── iron_zombie.json
│ ├── jungle_bat.json
│ ├── large_bat.json
│ ├── large_black_slime.json
│ ├── large_block_slime.json
│ ├── large_desert_slime.json
│ ├── large_green_slime.json
│ ├── large_ice_slime.json
│ ├── large_jungle_bat.json
│ ├── large_spider.json
│ ├── large_tainted_slime.json
│ ├── large_waste_block_slime.json
│ ├── large_waste_slime.json
│ ├── light_blue_butterfly.json
│ ├── mad_skeleton.json
│ ├── mad_skeleton_armed.json
│ ├── mad_skeleton_tall.json
│ ├── mad_skeleton_tall_armed.json
│ ├── mad_skeleton_tall_helmet_armed.json
│ ├── magma_birdo.json
│ ├── magma_elf.json
│ ├── magma_slime.json
│ ├── man_eater.json
│ ├── meteor.json
│ ├── mini_ghast.json
│ ├── mummy.json
│ ├── phantom.json
│ ├── pig.json
│ ├── pufferfish.json
│ ├── purple_slime.json
│ ├── ragged_mage.json
│ ├── red_butterfly.json
│ ├── red_mage.json
│ ├── red_mushroom_cow.json
│ ├── red_phantom.json
│ ├── rock_man.json
│ ├── rolling_fire_ball.json
│ ├── sheep.json
│ ├── shulker.json
│ ├── skeleton.json
│ ├── skeleton_assaulter.json
│ ├── skeleton_blue_armed.json
│ ├── skeleton_blue_armed_masked.json
│ ├── skeleton_blue_knight.json
│ ├── skeleton_fire_armed.json
│ ├── skeleton_fire_armed_swordsman.json
│ ├── skeleton_guard.json
│ ├── small_fire_hell_eater.json
│ ├── small_hell_eater.json
│ ├── snow_guardian.json
│ ├── snow_guardian_archer.json
│ ├── snow_queen.json
│ ├── snow_slime.json
│ ├── spider.json
│ ├── squid.json
│ ├── tainted_creeper.json
│ ├── tainted_skeleton.json
│ ├── tainted_slime.json
│ ├── turtle.json
│ ├── undead_miner.json
│ ├── vampire_miner.json
│ ├── villager_zombie.json
│ ├── vine_man_eater_body.json
│ ├── vine_man_eater_head.json
│ ├── vine_man_eater_tail.json
│ ├── waste_block_slime.json
│ ├── waste_ghost.json
│ ├── waste_mummy.json
│ ├── white_rabbit.json
│ ├── wither_skeleton.json
│ ├── wolf.json
│ ├── worm_body.json
│ ├── worm_head.json
│ ├── worm_tail.json
│ ├── yellow_butterfly.json
│ ├── yellow_rabbit.json
│ ├── yellow_slime.json
│ ├── zombie.json
│ └── zombie_pigman.json
├── package.json
├── player/
│ ├── GPlayer.lua
│ ├── GlobalPlayer.json
│ └── PlayerConstants.lua
├── projectile_ai/
│ ├── AirBullet.json
│ ├── AirBullet.lua
│ ├── AirWave.json
│ ├── AirWave.lua
│ ├── AmethystMagic.json
│ ├── AmethystMagic.lua
│ ├── Arrow.json
│ ├── Arrow.lua
│ ├── BlackHole.json
│ ├── BlackHole.lua
│ ├── BlazeRod.json
│ ├── BlazeRod.lua
│ ├── BloodArrow.json
│ ├── BloodArrow.lua
│ ├── BlueArrow.json
│ ├── BlueArrow.lua
│ ├── BlueBullet.json
│ ├── BlueBullet.lua
│ ├── BlueWave.json
│ ├── BlueWave.lua
│ ├── Bomb.json
│ ├── Bomb.lua
│ ├── Boomerang.json
│ ├── Boomerang.lua
│ ├── Bullet.json
│ ├── Bullet.lua
│ ├── CrystalMagic.json
│ ├── CrystalMagic.lua
│ ├── CursedArrow.json
│ ├── CursedArrow.lua
│ ├── Fire.json
│ ├── Fire.lua
│ ├── FireArrow.json
│ ├── FireArrow.lua
│ ├── FireElement.json
│ ├── FireElement.lua
│ ├── FireFlow.json
│ ├── FireFlow.lua
│ ├── FireFlowLarge.json
│ ├── FireFlowLarge.lua
│ ├── FireMagic.json
│ ├── FireMagic.lua
│ ├── Fireball.json
│ ├── Fireball.lua
│ ├── GlowBomb.json
│ ├── GlowBomb.lua
│ ├── Glowball.json
│ ├── Glowball.lua
│ ├── Grenade.json
│ ├── Grenade.lua
│ ├── IceArrow.json
│ ├── IceArrow.lua
│ ├── IceBullet.json
│ ├── IceBullet.lua
│ ├── IceMagic.json
│ ├── IceMagic.lua
│ ├── LaserBullet.json
│ ├── LaserBullet.lua
│ ├── LightingArrow.json
│ ├── LightingArrow.lua
│ ├── LightingBulletYellow.json
│ ├── LightingBulletYellow.lua
│ ├── LightingWheel.json
│ ├── LightingWheel.lua
│ ├── MagicWave.json
│ ├── MagicWave.lua
│ ├── MiniRocket.json
│ ├── MiniRocket.lua
│ ├── RedSpeedUp.json
│ ├── RedSpeedUp.lua
│ ├── Rocket.json
│ ├── Rocket.lua
│ ├── ShadowMagic.json
│ ├── ShadowMagic.lua
│ ├── ShulkerBullet.json
│ ├── ShulkerBullet.lua
│ ├── SnowFlake.json
│ ├── SnowFlake.lua
│ ├── Spike.json
│ ├── Spike.lua
│ ├── StarArrow.json
│ ├── StarArrow.lua
│ ├── StarMagic.json
│ ├── StarMagic.lua
│ ├── SuperBullet.json
│ ├── SuperBullet.lua
│ ├── SuperFire.json
│ ├── SuperFire.lua
│ ├── SwordArrow.json
│ ├── SwordArrow.lua
│ ├── WaterFlow.json
│ ├── WaterFlow.lua
│ ├── WaterMagic.json
│ └── WaterMagic.lua
├── projectile_ai_global/
│ ├── GProjectile.lua
│ └── GlobalProjectile.json
├── projectiles/
│ ├── air_bullet.json
│ ├── air_wave.json
│ ├── amethyst_magic.json
│ ├── black_hole.json
│ ├── blaze_rod.json
│ ├── blood_arrow.json
│ ├── blue_arrow.json
│ ├── bomb.json
│ ├── bone.json
│ ├── boomerang.json
│ ├── bullet.json
│ ├── bullet_laser.json
│ ├── bullet_super.json
│ ├── crystal_magic.json
│ ├── cursed_arrow.json
│ ├── fire_arrow.json
│ ├── fire_boomerang.json
│ ├── fire_charge.json
│ ├── fire_element.json
│ ├── fire_flow.json
│ ├── fire_flow_large.json
│ ├── fire_magic.json
│ ├── fire_wave.json
│ ├── glow_ball.json
│ ├── glow_bomb.json
│ ├── grenade.json
│ ├── gun_fire.json
│ ├── ice_arrow.json
│ ├── ice_bullet.json
│ ├── ice_magic.json
│ ├── light_bullet_laser.json
│ ├── lighting_arrow.json
│ ├── lighting_bullet_blue.json
│ ├── lighting_bullet_red_invert2.json
│ ├── lighting_bullet_yellow.json
│ ├── lighting_wheel.json
│ ├── magic_wave.json
│ ├── magic_wave3.json
│ ├── mini_rocket.json
│ ├── rocket.json
│ ├── shadow_magic.json
│ ├── shulker_bullet.json
│ ├── small_air_bullet.json
│ ├── snow_flake.json
│ ├── spike.json
│ ├── star.json
│ ├── star_arrow.json
│ ├── super_fire.json
│ ├── sword_arrow.json
│ ├── tnt.json
│ ├── water_flow.json
│ ├── water_magic.json
│ ├── wooden_arrow.json
│ └── wooden_boomerang.json
├── recipe_config/
│ ├── Brew.json
│ ├── Craft3x.json
│ ├── Repair.json
│ └── Smelt.json
├── recipes/
│ ├── brew/
│ │ ├── potion_awkward.json
│ │ ├── potion_fire_resistance.json
│ │ ├── potion_fire_resistance_long.json
│ │ ├── potion_glowing.json
│ │ ├── potion_harming.json
│ │ ├── potion_harming_2.json
│ │ ├── potion_harming_super.json
│ │ ├── potion_healing.json
│ │ ├── potion_healing_super.json
│ │ ├── potion_invisibility.json
│ │ ├── potion_invisibility_long.json
│ │ ├── potion_leaping.json
│ │ ├── potion_leaping_long.json
│ │ ├── potion_night_vision.json
│ │ ├── potion_night_vision_long.json
│ │ ├── potion_poison.json
│ │ ├── potion_poison_2.json
│ │ ├── potion_poison_long.json
│ │ ├── potion_regeneration.json
│ │ ├── potion_regeneration_long.json
│ │ ├── potion_slow_falling.json
│ │ ├── potion_slow_falling_long.json
│ │ ├── potion_slowness.json
│ │ ├── potion_slowness_2.json
│ │ ├── potion_slowness_long.json
│ │ ├── potion_strength.json
│ │ ├── potion_strength_long.json
│ │ ├── potion_swiftness.json
│ │ ├── potion_swiftness_long.json
│ │ ├── potion_water_breathing.json
│ │ ├── potion_water_breathing_long.json
│ │ ├── potion_weakness.json
│ │ ├── potion_weakness_2.json
│ │ └── potion_weakness_long.json
│ ├── craft3x/
│ │ ├── acacia_plank.json
│ │ ├── amethyst_staff.json
│ │ ├── amethyst_staff_2.json
│ │ ├── ancient_ingot.json
│ │ ├── andesite.json
│ │ ├── andesite_polished.json
│ │ ├── anvil.json
│ │ ├── barrel.json
│ │ ├── bench_acacia.json
│ │ ├── bench_birch.json
│ │ ├── bench_dark_oak.json
│ │ ├── bench_jungle.json
│ │ ├── bench_nether.json
│ │ ├── bench_oak.json
│ │ ├── bench_palm.json
│ │ ├── bench_spruce.json
│ │ ├── bench_tainted.json
│ │ ├── bench_volcano.json
│ │ ├── birch_plank.json
│ │ ├── blaze_powder.json
│ │ ├── block_coal.json
│ │ ├── block_diamond.json
│ │ ├── block_emerald.json
│ │ ├── block_gold.json
│ │ ├── block_iron.json
│ │ ├── block_lapis.json
│ │ ├── block_netherite.json
│ │ ├── block_quartz.json
│ │ ├── block_redstone.json
│ │ ├── blood_arrow.json
│ │ ├── blood_arrow_2.json
│ │ ├── blood_bow.json
│ │ ├── blue_ice.json
│ │ ├── blue_stone_bow.json
│ │ ├── blue_torch.json
│ │ ├── blue_wire.json
│ │ ├── bomb.json
│ │ ├── bomb_2.json
│ │ ├── bone_block.json
│ │ ├── bone_meal.json
│ │ ├── bone_meal_2.json
│ │ ├── book.json
│ │ ├── book_block.json
│ │ ├── bookcase_acacia.json
│ │ ├── bookcase_birch.json
│ │ ├── bookcase_dark_oak.json
│ │ ├── bookcase_jungle.json
│ │ ├── bookcase_nether.json
│ │ ├── bookcase_oak.json
│ │ ├── bookcase_palm.json
│ │ ├── bookcase_spruce.json
│ │ ├── bookcase_tainted.json
│ │ ├── bookcase_volcano.json
│ │ ├── boomerang.json
│ │ ├── boomerang_2.json
│ │ ├── bowl.json
│ │ ├── bread.json
│ │ ├── brewing_stand.json
│ │ ├── brick.json
│ │ ├── bronze_axe.json
│ │ ├── bronze_chestplate.json
│ │ ├── bronze_helmet.json
│ │ ├── bronze_ingot.json
│ │ ├── bronze_leggings.json
│ │ ├── bronze_pickaxe.json
│ │ ├── bronze_sword.json
│ │ ├── brown_mushroom.json
│ │ ├── brown_mushroom_2.json
│ │ ├── bucket_empty.json
│ │ ├── cabinet_acacia.json
│ │ ├── cabinet_birch.json
│ │ ├── cabinet_dark_oak.json
│ │ ├── cabinet_jungle.json
│ │ ├── cabinet_nether.json
│ │ ├── cabinet_oak.json
│ │ ├── cabinet_palm.json
│ │ ├── cabinet_spruce.json
│ │ ├── cabinet_tainted.json
│ │ ├── cabinet_volcano.json
│ │ ├── cake.json
│ │ ├── cake_piece.json
│ │ ├── campfire.json
│ │ ├── campfire_2.json
│ │ ├── campfire_3.json
│ │ ├── campfire_4.json
│ │ ├── candle.json
│ │ ├── candle_holder.json
│ │ ├── cauldron.json
│ │ ├── chair_acacia.json
│ │ ├── chair_birch.json
│ │ ├── chair_dark_oak.json
│ │ ├── chair_jungle.json
│ │ ├── chair_nether.json
│ │ ├── chair_oak.json
│ │ ├── chair_palm.json
│ │ ├── chair_spruce.json
│ │ ├── chair_tainted.json
│ │ ├── chair_volcano.json
│ │ ├── chandeliers.json
│ │ ├── chest.json
│ │ ├── clay.json
│ │ ├── clay_block.json
│ │ ├── coal.json
│ │ ├── coarse_dirt.json
│ │ ├── cobblestone_fence.json
│ │ ├── cobblestone_mossy.json
│ │ ├── cobweb.json
│ │ ├── cookie.json
│ │ ├── copper_axe.json
│ │ ├── copper_chestplate.json
│ │ ├── copper_helmet.json
│ │ ├── copper_leggings.json
│ │ ├── copper_pickaxe.json
│ │ ├── copper_sword.json
│ │ ├── crafting_table.json
│ │ ├── cross_bow.json
│ │ ├── dark_oak_plank.json
│ │ ├── dark_shadow_ingot.json
│ │ ├── daylight_sensor.json
│ │ ├── daylight_sensor_inverted.json
│ │ ├── diamond.json
│ │ ├── diamond_axe.json
│ │ ├── diamond_chestplate.json
│ │ ├── diamond_helmet.json
│ │ ├── diamond_ingot.json
│ │ ├── diamond_leggings.json
│ │ ├── diamond_pickaxe.json
│ │ ├── diamond_sword.json
│ │ ├── diorite.json
│ │ ├── diorite_polished.json
│ │ ├── dirt.json
│ │ ├── door_nether.json
│ │ ├── dried_kelp.json
│ │ ├── dried_kelp_block.json
│ │ ├── dungeon_eater.json
│ │ ├── dye_black.json
│ │ ├── dye_blue.json
│ │ ├── dye_brown.json
│ │ ├── dye_cyan.json
│ │ ├── dye_cyan_2.json
│ │ ├── dye_gray.json
│ │ ├── dye_light_blue.json
│ │ ├── dye_light_blue_2.json
│ │ ├── dye_light_blue_3.json
│ │ ├── dye_light_gray.json
│ │ ├── dye_light_gray_2.json
│ │ ├── dye_light_gray_3.json
│ │ ├── dye_light_gray_4.json
│ │ ├── dye_lime.json
│ │ ├── dye_lime_2.json
│ │ ├── dye_magenta.json
│ │ ├── dye_magenta_2.json
│ │ ├── dye_magenta_3.json
│ │ ├── dye_magenta_4.json
│ │ ├── dye_magenta_5.json
│ │ ├── dye_orange.json
│ │ ├── dye_orange_2.json
│ │ ├── dye_pink.json
│ │ ├── dye_pink_2.json
│ │ ├── dye_pink_3.json
│ │ ├── dye_pink_4.json
│ │ ├── dye_purple.json
│ │ ├── dye_purple_2.json
│ │ ├── dye_red.json
│ │ ├── dye_red_2.json
│ │ ├── dye_red_3.json
│ │ ├── dye_white.json
│ │ ├── dye_yellow.json
│ │ ├── dye_yellow_2.json
│ │ ├── emerald.json
│ │ ├── enchantment_table.json
│ │ ├── end_rod.json
│ │ ├── end_stone_brick.json
│ │ ├── ender_chest.json
│ │ ├── ender_eye.json
│ │ ├── ender_mirror.json
│ │ ├── farmland.json
│ │ ├── farmland_2.json
│ │ ├── fence_acacia.json
│ │ ├── fence_birch.json
│ │ ├── fence_dark_oak.json
│ │ ├── fence_jungle.json
│ │ ├── fence_nether.json
│ │ ├── fence_oak.json
│ │ ├── fence_palm.json
│ │ ├── fence_spruce.json
│ │ ├── fence_tainted.json
│ │ ├── fence_volcano.json
│ │ ├── fermented_spider_eye.json
│ │ ├── fire_boomerang.json
│ │ ├── fire_boomerang_2.json
│ │ ├── fire_bullet.json
│ │ ├── fire_bullet_2.json
│ │ ├── fire_charge.json
│ │ ├── fire_charge_2.json
│ │ ├── fire_lamp.json
│ │ ├── flesh_chestplate.json
│ │ ├── flesh_helmet.json
│ │ ├── flesh_ingot.json
│ │ ├── flesh_leggings.json
│ │ ├── flesh_machine_part.json
│ │ ├── flower_pot.json
│ │ ├── flower_pot_large.json
│ │ ├── furnace.json
│ │ ├── ghost.json
│ │ ├── glass_bottle.json
│ │ ├── glistering_melon_slice.json
│ │ ├── glow_ball.json
│ │ ├── glow_bomb.json
│ │ ├── glowing_mushroom.json
│ │ ├── glowing_mushroom_2.json
│ │ ├── glowstone.json
│ │ ├── gold_ingot.json
│ │ ├── gold_ingot_2.json
│ │ ├── gold_nugget.json
│ │ ├── golden_apple.json
│ │ ├── golden_axe.json
│ │ ├── golden_carrot.json
│ │ ├── golden_chestplate.json
│ │ ├── golden_helmet.json
│ │ ├── golden_leggings.json
│ │ ├── golden_pickaxe.json
│ │ ├── golden_pressure_plate.json
│ │ ├── golden_sword.json
│ │ ├── granite.json
│ │ ├── granite_polished.json
│ │ ├── grass_axe.json
│ │ ├── grass_pickaxe.json
│ │ ├── grass_sword.json
│ │ ├── green_torch.json
│ │ ├── green_wire.json
│ │ ├── grenade.json
│ │ ├── grenade_2.json
│ │ ├── hay_bale.json
│ │ ├── ice_arrow.json
│ │ ├── ice_bow.json
│ │ ├── ice_brick.json
│ │ ├── ice_element_ball.json
│ │ ├── ice_packed.json
│ │ ├── ice_staff.json
│ │ ├── iron_axe.json
│ │ ├── iron_bar.json
│ │ ├── iron_bullet.json
│ │ ├── iron_bullet_2.json
│ │ ├── iron_chestplate.json
│ │ ├── iron_door.json
│ │ ├── iron_helmet.json
│ │ ├── iron_ingot.json
│ │ ├── iron_ingot_2.json
│ │ ├── iron_leggings.json
│ │ ├── iron_nugget.json
│ │ ├── iron_pickaxe.json
│ │ ├── iron_pressure_plate.json
│ │ ├── iron_sword.json
│ │ ├── jack_o_lantern.json
│ │ ├── jukebox.json
│ │ ├── jungle_plank.json
│ │ ├── knight_chestplate.json
│ │ ├── knight_helmet.json
│ │ ├── knight_leggings.json
│ │ ├── lantern.json
│ │ ├── lapis_lazuli.json
│ │ ├── lava_chestplate.json
│ │ ├── lava_helmet.json
│ │ ├── lava_leggings.json
│ │ ├── lead_axe.json
│ │ ├── lead_chestplate.json
│ │ ├── lead_helmet.json
│ │ ├── lead_leggings.json
│ │ ├── lead_pickaxe.json
│ │ ├── lead_sword.json
│ │ ├── leather.json
│ │ ├── leather_chestplate.json
│ │ ├── leather_helmet.json
│ │ ├── leather_leggings.json
│ │ ├── lever.json
│ │ ├── lighter.json
│ │ ├── lighting_arrow.json
│ │ ├── lighting_bow.json
│ │ ├── lighting_staff.json
│ │ ├── machine_part.json
│ │ ├── magic_cell_group.json
│ │ ├── magic_gold_chestplate.json
│ │ ├── magic_gold_helmet.json
│ │ ├── magic_gold_leggings.json
│ │ ├── magic_silver_chestplate.json
│ │ ├── magic_silver_helmet.json
│ │ ├── magic_silver_ingot.json
│ │ ├── magic_silver_leggings.json
│ │ ├── magma_block.json
│ │ ├── magma_cream.json
│ │ ├── magma_gold_ingot.json
│ │ ├── melon_seed.json
│ │ ├── mossy_cobblestone_fence.json
│ │ ├── mushroom_stew.json
│ │ ├── nether_brick_block.json
│ │ ├── nether_chest.json
│ │ ├── nether_lamp.json
│ │ ├── netherite_ingot.json
│ │ ├── netherite_ingot_2.json
│ │ ├── oak_plank.json
│ │ ├── painting_2x2.json
│ │ ├── painting_2x2_2.json
│ │ ├── painting_2x4.json
│ │ ├── painting_4x2.json
│ │ ├── painting_4x4.json
│ │ ├── painting_8x4.json
│ │ ├── painting_8x6.json
│ │ ├── painting_8x8.json
│ │ ├── palm_plank.json
│ │ ├── paper.json
│ │ ├── platform_acacia.json
│ │ ├── platform_birch.json
│ │ ├── platform_dark_oak.json
│ │ ├── platform_end_stone.json
│ │ ├── platform_jungle.json
│ │ ├── platform_nether_brick.json
│ │ ├── platform_oak.json
│ │ ├── platform_palm.json
│ │ ├── platform_prismarine.json
│ │ ├── platform_prismarine_dark.json
│ │ ├── platform_purpur.json
│ │ ├── platform_quartz.json
│ │ ├── platform_red_sand_stone.json
│ │ ├── platform_sandstone.json
│ │ ├── platform_spruce.json
│ │ ├── platform_stone_brick.json
│ │ ├── platform_tainted.json
│ │ ├── platform_volcano.json
│ │ ├── poison_mushroom.json
│ │ ├── prismarine.json
│ │ ├── prismarine_brick.json
│ │ ├── prismarine_dark.json
│ │ ├── prismarine_dark_2.json
│ │ ├── pumpkin_helmet.json
│ │ ├── pumpkin_pie.json
│ │ ├── pumpkin_seed.json
│ │ ├── purpur_block.json
│ │ ├── quartz.json
│ │ ├── red_gold_ingot.json
│ │ ├── red_mushroom.json
│ │ ├── red_mushroom_2.json
│ │ ├── red_nether_brick.json
│ │ ├── red_sand_carved.json
│ │ ├── red_sand_stone.json
│ │ ├── red_torch.json
│ │ ├── red_wire.json
│ │ ├── redstone.json
│ │ ├── redstone_lamp.json
│ │ ├── redstone_torch.json
│ │ ├── rocket.json
│ │ ├── rocket_boost.json
│ │ ├── rotten_flesh.json
│ │ ├── sandstone.json
│ │ ├── sandstone_carved.json
│ │ ├── sea_lantern.json
│ │ ├── shadow_staff.json
│ │ ├── shears.json
│ │ ├── shot_bow.json
│ │ ├── shot_bow_2.json
│ │ ├── shulker_box.json
│ │ ├── sign.json
│ │ ├── silver_axe.json
│ │ ├── silver_bullet.json
│ │ ├── silver_chestplate.json
│ │ ├── silver_helmet.json
│ │ ├── silver_leggings.json
│ │ ├── silver_pickaxe.json
│ │ ├── silver_sword.json
│ │ ├── slime_block.json
│ │ ├── slimeball.json
│ │ ├── snow.json
│ │ ├── snow_brick.json
│ │ ├── snowball.json
│ │ ├── spruce_plank.json
│ │ ├── stained_glass_black.json
│ │ ├── stained_glass_blue.json
│ │ ├── stained_glass_brown.json
│ │ ├── stained_glass_cyan.json
│ │ ├── stained_glass_gray.json
│ │ ├── stained_glass_green.json
│ │ ├── stained_glass_light_blue.json
│ │ ├── stained_glass_light_gray.json
│ │ ├── stained_glass_lime.json
│ │ ├── stained_glass_magenta.json
│ │ ├── stained_glass_orange.json
│ │ ├── stained_glass_pink.json
│ │ ├── stained_glass_purple.json
│ │ ├── stained_glass_red.json
│ │ ├── stained_glass_white.json
│ │ ├── stained_glass_yellow.json
│ │ ├── star_arrow.json
│ │ ├── star_chestplate.json
│ │ ├── star_helmet.json
│ │ ├── star_leggings.json
│ │ ├── steel_axe.json
│ │ ├── steel_chestplate.json
│ │ ├── steel_helmet.json
│ │ ├── steel_leggings.json
│ │ ├── steel_pickaxe.json
│ │ ├── steel_sword.json
│ │ ├── stick.json
│ │ ├── stone.json
│ │ ├── stone_2.json
│ │ ├── stone_axe.json
│ │ ├── stone_brick.json
│ │ ├── stone_brick_carved.json
│ │ ├── stone_brick_mossy.json
│ │ ├── stone_button.json
│ │ ├── stone_chest.json
│ │ ├── stone_hoe.json
│ │ ├── stone_pickaxe.json
│ │ ├── stone_pressure_plate.json
│ │ ├── stone_sword.json
│ │ ├── strange_eye.json
│ │ ├── string.json
│ │ ├── suger.json
│ │ ├── super_bronze_sword.json
│ │ ├── super_copper_sword.json
│ │ ├── super_cross_bow.json
│ │ ├── super_diamond_chestplate.json
│ │ ├── super_diamond_helmet.json
│ │ ├── super_diamond_leggings.json
│ │ ├── super_diamond_sword.json
│ │ ├── super_golden_sword.json
│ │ ├── super_iron_sword.json
│ │ ├── super_lead_sword.json
│ │ ├── super_silver_sword.json
│ │ ├── super_steel_sword.json
│ │ ├── super_tin_sword.json
│ │ ├── sword_arrow.json
│ │ ├── sword_arrow_2.json
│ │ ├── sword_arrow_3.json
│ │ ├── table_acacia.json
│ │ ├── table_birch.json
│ │ ├── table_dark_oak.json
│ │ ├── table_jungle.json
│ │ ├── table_nether.json
│ │ ├── table_oak.json
│ │ ├── table_palm.json
│ │ ├── table_spruce.json
│ │ ├── table_tainted.json
│ │ ├── table_volcano.json
│ │ ├── tainted_plank.json
│ │ ├── terracotta_black.json
│ │ ├── terracotta_black_2.json
│ │ ├── terracotta_blue.json
│ │ ├── terracotta_blue_2.json
│ │ ├── terracotta_brown.json
│ │ ├── terracotta_cyan.json
│ │ ├── terracotta_gray.json
│ │ ├── terracotta_green.json
│ │ ├── terracotta_light_blue.json
│ │ ├── terracotta_light_gray.json
│ │ ├── terracotta_lime.json
│ │ ├── terracotta_magenta.json
│ │ ├── terracotta_orange.json
│ │ ├── terracotta_pink.json
│ │ ├── terracotta_purple.json
│ │ ├── terracotta_red.json
│ │ ├── terracotta_white.json
│ │ ├── terracotta_white_2.json
│ │ ├── terracotta_yellow.json
│ │ ├── tin_axe.json
│ │ ├── tin_chestplate.json
│ │ ├── tin_helmet.json
│ │ ├── tin_leggings.json
│ │ ├── tin_pickaxe.json
│ │ ├── tin_sword.json
│ │ ├── tnt.json
│ │ ├── tnt_2.json
│ │ ├── torch.json
│ │ ├── torch_2.json
│ │ ├── torch_3.json
│ │ ├── tower_core.json
│ │ ├── trapped_chest.json
│ │ ├── volcano_plank.json
│ │ ├── water_staff.json
│ │ ├── watermelon.json
│ │ ├── wheat.json
│ │ ├── white_torch.json
│ │ ├── wire_cutter.json
│ │ ├── wooden_arrow.json
│ │ ├── wooden_arrow_2.json
│ │ ├── wooden_arrow_3.json
│ │ ├── wooden_arrow_4.json
│ │ ├── wooden_axe.json
│ │ ├── wooden_bed_black.json
│ │ ├── wooden_bed_black_2.json
│ │ ├── wooden_bed_blue.json
│ │ ├── wooden_bed_blue_2.json
│ │ ├── wooden_bed_brown.json
│ │ ├── wooden_bed_brown_2.json
│ │ ├── wooden_bed_cyan.json
│ │ ├── wooden_bed_cyan_2.json
│ │ ├── wooden_bed_gray.json
│ │ ├── wooden_bed_gray_2.json
│ │ ├── wooden_bed_green.json
│ │ ├── wooden_bed_green_2.json
│ │ ├── wooden_bed_light_blue.json
│ │ ├── wooden_bed_light_blue_2.json
│ │ ├── wooden_bed_light_gray.json
│ │ ├── wooden_bed_light_gray_2.json
│ │ ├── wooden_bed_lime.json
│ │ ├── wooden_bed_lime_2.json
│ │ ├── wooden_bed_magenta.json
│ │ ├── wooden_bed_magenta_2.json
│ │ ├── wooden_bed_orange.json
│ │ ├── wooden_bed_orange_2.json
│ │ ├── wooden_bed_pink.json
│ │ ├── wooden_bed_pink_2.json
│ │ ├── wooden_bed_purple.json
│ │ ├── wooden_bed_purple_2.json
│ │ ├── wooden_bed_red.json
│ │ ├── wooden_bed_red_2.json
│ │ ├── wooden_bed_white.json
│ │ ├── wooden_bed_yellow.json
│ │ ├── wooden_bed_yellow_2.json
│ │ ├── wooden_boomerang.json
│ │ ├── wooden_bow.json
│ │ ├── wooden_button.json
│ │ ├── wooden_door_acacia.json
│ │ ├── wooden_door_birch.json
│ │ ├── wooden_door_dark_oak.json
│ │ ├── wooden_door_jungle.json
│ │ ├── wooden_door_oak.json
│ │ ├── wooden_door_palm.json
│ │ ├── wooden_door_spruce.json
│ │ ├── wooden_door_tainted.json
│ │ ├── wooden_door_volcano.json
│ │ ├── wooden_hoe.json
│ │ ├── wooden_pickaxe.json
│ │ ├── wooden_pressure_plate.json
│ │ ├── wooden_sword.json
│ │ ├── wool_black.json
│ │ ├── wool_black_2.json
│ │ ├── wool_blue.json
│ │ ├── wool_blue_2.json
│ │ ├── wool_brown.json
│ │ ├── wool_cyan.json
│ │ ├── wool_gray.json
│ │ ├── wool_green.json
│ │ ├── wool_light_blue.json
│ │ ├── wool_light_gray.json
│ │ ├── wool_lime.json
│ │ ├── wool_magenta.json
│ │ ├── wool_orange.json
│ │ ├── wool_pink.json
│ │ ├── wool_purple.json
│ │ ├── wool_red.json
│ │ ├── wool_white.json
│ │ ├── wool_yellow.json
│ │ ├── yellow_torch.json
│ │ └── yellow_wire.json
│ ├── repair/
│ │ ├── ancient_chestplate.json
│ │ ├── ancient_chestplate_2.json
│ │ ├── ancient_helmet.json
│ │ ├── ancient_helmet_2.json
│ │ ├── ancient_leggings.json
│ │ ├── ancient_leggings_2.json
│ │ ├── bronze_axe.json
│ │ ├── bronze_chestplate.json
│ │ ├── bronze_helmet.json
│ │ ├── bronze_leggings.json
│ │ ├── bronze_pickaxe.json
│ │ ├── bronze_sword.json
│ │ ├── copper_axe.json
│ │ ├── copper_chestplate.json
│ │ ├── copper_helmet.json
│ │ ├── copper_leggings.json
│ │ ├── copper_pickaxe.json
│ │ ├── copper_sword.json
│ │ ├── diamond_axe.json
│ │ ├── diamond_chestplate.json
│ │ ├── diamond_helmet.json
│ │ ├── diamond_leggings.json
│ │ ├── diamond_pickaxe.json
│ │ ├── diamond_sword.json
│ │ ├── golden_axe.json
│ │ ├── golden_chestplate.json
│ │ ├── golden_helmet.json
│ │ ├── golden_leggings.json
│ │ ├── golden_pickaxe.json
│ │ ├── golden_sword.json
│ │ ├── iron_axe.json
│ │ ├── iron_chestplate.json
│ │ ├── iron_helmet.json
│ │ ├── iron_leggings.json
│ │ ├── iron_pickaxe.json
│ │ ├── iron_sword.json
│ │ ├── lead_axe.json
│ │ ├── lead_chestplate.json
│ │ ├── lead_helmet.json
│ │ ├── lead_leggings.json
│ │ ├── lead_pickaxe.json
│ │ ├── lead_sword.json
│ │ ├── leather_chestplate.json
│ │ ├── leather_helmet.json
│ │ ├── leather_leggings.json
│ │ ├── nether_axe.json
│ │ ├── nether_axe_2.json
│ │ ├── nether_chestplate.json
│ │ ├── nether_chestplate_2.json
│ │ ├── nether_helmet.json
│ │ ├── nether_helmet_2.json
│ │ ├── nether_helmet_3.json
│ │ ├── nether_leggings.json
│ │ ├── nether_leggings_2.json
│ │ ├── nether_pickaxe.json
│ │ ├── nether_pickaxe_2.json
│ │ ├── nether_sword.json
│ │ ├── nether_sword_2.json
│ │ ├── silver_axe.json
│ │ ├── silver_chestplate.json
│ │ ├── silver_helmet.json
│ │ ├── silver_leggings.json
│ │ ├── silver_pickaxe.json
│ │ ├── silver_sword.json
│ │ ├── steel_axe.json
│ │ ├── steel_chestplate.json
│ │ ├── steel_helmet.json
│ │ ├── steel_leggings.json
│ │ ├── steel_pickaxe.json
│ │ ├── steel_sword.json
│ │ ├── stone_axe.json
│ │ ├── stone_hoe.json
│ │ ├── stone_pickaxe.json
│ │ ├── stone_sword.json
│ │ ├── super_bronze_sword.json
│ │ ├── super_copper_sword.json
│ │ ├── super_diamond_sword.json
│ │ ├── super_golden_sword.json
│ │ ├── super_iron_sword.json
│ │ ├── super_lead_sword.json
│ │ ├── super_nether_sword.json
│ │ ├── super_nether_sword_2.json
│ │ ├── super_silver_sword.json
│ │ ├── super_steel_sword.json
│ │ ├── super_tin_sword.json
│ │ ├── tin_axe.json
│ │ ├── tin_chestplate.json
│ │ ├── tin_helmet.json
│ │ ├── tin_leggings.json
│ │ ├── tin_pickaxe.json
│ │ └── tin_sword.json
│ └── smelt/
│ ├── baked_potato.json
│ ├── charcoal.json
│ ├── charcoal_10.json
│ ├── charcoal_11.json
│ ├── charcoal_12.json
│ ├── charcoal_13.json
│ ├── charcoal_14.json
│ ├── charcoal_15.json
│ ├── charcoal_16.json
│ ├── charcoal_17.json
│ ├── charcoal_18.json
│ ├── charcoal_2.json
│ ├── charcoal_3.json
│ ├── charcoal_4.json
│ ├── charcoal_5.json
│ ├── charcoal_6.json
│ ├── charcoal_7.json
│ ├── charcoal_8.json
│ ├── charcoal_9.json
│ ├── coal.json
│ ├── cooked_chicken.json
│ ├── cooked_cod.json
│ ├── cooked_mutton.json
│ ├── cooked_porkchop.json
│ ├── cooked_rabbit.json
│ ├── cooked_salmon.json
│ ├── copper_ingot.json
│ ├── diamond.json
│ ├── dried_kelp.json
│ ├── dye_green.json
│ ├── emerald.json
│ ├── glass.json
│ ├── glass_2.json
│ ├── glass_3.json
│ ├── gold_ingot.json
│ ├── iron_ingot.json
│ ├── lapis_lazuli.json
│ ├── lead_ingot.json
│ ├── nether_brick.json
│ ├── netherite_scrap.json
│ ├── popped_chorus_fruits.json
│ ├── quartz.json
│ ├── red_brick.json
│ ├── red_sand_smooth.json
│ ├── redstone.json
│ ├── sandstone_smooth.json
│ ├── silver_ingot.json
│ ├── sponge.json
│ ├── steak.json
│ ├── steel_ingot.json
│ ├── stone.json
│ ├── stone_brick_cracked.json
│ ├── terracotta_pink.json
│ └── tin_ingot.json
├── record/
│ └── RecordData.lua
├── settings/
│ ├── Settings.lua
│ └── SettingsData.lua
├── skins/
│ ├── skin_22.json
│ ├── skin_33.json
│ ├── skin_my.json
│ ├── skin_plin.json
│ ├── skin_redust.json
│ ├── skin_steve.json
│ ├── skin_ym.json
│ ├── skin_yy.json
│ ├── skin_zk.json
│ ├── xqz/
│ │ ├── cloth.mdp
│ │ └── hair.mdp
│ └── xqz.json
├── sounds/
│ ├── README.txt
│ ├── affectionate_scream.ogg
│ ├── anvil_land.ogg
│ ├── anvil_use.ogg
│ ├── attack1.ogg
│ ├── attack2.ogg
│ ├── barrel_open.ogg
│ ├── bat_death.ogg
│ ├── bat_hurt1.ogg
│ ├── bat_hurt2.ogg
│ ├── bat_hurt3.ogg
│ ├── bazooka_fire.ogg
│ ├── blaze_death.ogg
│ ├── blaze_hit1.ogg
│ ├── blaze_hit2.ogg
│ ├── blaze_hit3.ogg
│ ├── bow.ogg
│ ├── bowhit.ogg
│ ├── bowhit2.ogg
│ ├── broken.ogg
│ ├── button1.ogg
│ ├── cannon.ogg
│ ├── cat_hit1.ogg
│ ├── cat_hit2.ogg
│ ├── cat_hit3.ogg
│ ├── cat_meow1.ogg
│ ├── cat_meow2.ogg
│ ├── cat_meow3.ogg
│ ├── chain_gun_fire.ogg
│ ├── chest.ogg
│ ├── chestclosed.ogg
│ ├── chicken_hurt1.ogg
│ ├── chicken_hurt2.ogg
│ ├── chicken_say1.ogg
│ ├── chicken_say2.ogg
│ ├── chicken_say3.ogg
│ ├── click.ogg
│ ├── cloth1.ogg
│ ├── cloth2.ogg
│ ├── cloth3.ogg
│ ├── cow_hurt1.ogg
│ ├── cow_hurt2.ogg
│ ├── cow_hurt3.ogg
│ ├── cow_say1.ogg
│ ├── cow_say2.ogg
│ ├── cow_say3.ogg
│ ├── creeper1.ogg
│ ├── creeper2.ogg
│ ├── creeper3.ogg
│ ├── creeper_death.ogg
│ ├── dirt1.ogg
│ ├── dirt2.ogg
│ ├── dirt3.ogg
│ ├── dolphin_death.ogg
│ ├── dolphin_hurt1.ogg
│ ├── dolphin_hurt2.ogg
│ ├── dolphin_hurt3.ogg
│ ├── dolphin_play1.ogg
│ ├── dolphin_play2.ogg
│ ├── door1.ogg
│ ├── door2.ogg
│ ├── drink.ogg
│ ├── eat1.ogg
│ ├── eat2.ogg
│ ├── eat3.ogg
│ ├── enchant1.ogg
│ ├── enchant2.ogg
│ ├── enchant3.ogg
│ ├── enderman_death.ogg
│ ├── enderman_hit1.ogg
│ ├── enderman_hit2.ogg
│ ├── enderman_hit3.ogg
│ ├── enderman_idle1.ogg
│ ├── enderman_idle2.ogg
│ ├── enderman_idle3.ogg
│ ├── explode1.ogg
│ ├── explode2.ogg
│ ├── explode3.ogg
│ ├── explode4.ogg
│ ├── female_hit1.ogg
│ ├── female_hit2.ogg
│ ├── female_hit3.ogg
│ ├── fireball.ogg
│ ├── fireball2.ogg
│ ├── fizz.ogg
│ ├── fuse.ogg
│ ├── ghast_charge.ogg
│ ├── ghast_death.ogg
│ ├── ghast_moan1.ogg
│ ├── ghast_moan2.ogg
│ ├── ghast_moan3.ogg
│ ├── ghast_moan4.ogg
│ ├── glass1.ogg
│ ├── glass2.ogg
│ ├── glass3.ogg
│ ├── gore1.ogg
│ ├── gore2.ogg
│ ├── gore3.ogg
│ ├── grass.ogg
│ ├── grass1.ogg
│ ├── grass2.ogg
│ ├── grass3.ogg
│ ├── grenade_fire.ogg
│ ├── hit1.ogg
│ ├── hit2.ogg
│ ├── hit3.ogg
│ ├── laser.ogg
│ ├── launch.ogg
│ ├── lavapop.ogg
│ ├── levelup.ogg
│ ├── monster.ogg
│ ├── orb.ogg
│ ├── phantom_death.ogg
│ ├── phantom_hurt1.ogg
│ ├── phantom_hurt2.ogg
│ ├── phantom_hurt3.ogg
│ ├── pig_death.ogg
│ ├── pig_say1.ogg
│ ├── pig_say2.ogg
│ ├── pig_say3.ogg
│ ├── pistol_fire.ogg
│ ├── pop.ogg
│ ├── portal.ogg
│ ├── portal2.ogg
│ ├── pufferfish_blow_out.ogg
│ ├── pufferfish_blow_up.ogg
│ ├── pufferfish_death.ogg
│ ├── pufferfish_hurt1.ogg
│ ├── pufferfish_hurt2.ogg
│ ├── rabbit_hurt1.ogg
│ ├── rabbit_hurt2.ogg
│ ├── rabbit_hurt3.ogg
│ ├── rain1.ogg
│ ├── rain2.ogg
│ ├── rain3.ogg
│ ├── rain4.ogg
│ ├── rifle_fire.ogg
│ ├── sand1.ogg
│ ├── sand2.ogg
│ ├── sand3.ogg
│ ├── shatter.ogg
│ ├── shatter1.ogg
│ ├── shatter2.ogg
│ ├── shatter3.ogg
│ ├── shear.ogg
│ ├── sheep_say1.ogg
│ ├── sheep_say2.ogg
│ ├── sheep_say3.ogg
│ ├── shotgun_fire.ogg
│ ├── shulker_ambient1.ogg
│ ├── shulker_box_open.ogg
│ ├── shulker_close.ogg
│ ├── shulker_death.ogg
│ ├── shulker_hit1.ogg
│ ├── shulker_hit2.ogg
│ ├── shulker_hit3.ogg
│ ├── shulker_hurt1.ogg
│ ├── shulker_hurt2.ogg
│ ├── shulker_hurt3.ogg
│ ├── shulker_open.ogg
│ ├── shulker_shoot.ogg
│ ├── skeleton1.ogg
│ ├── skeleton2.ogg
│ ├── skeleton3.ogg
│ ├── skeleton_death.ogg
│ ├── slime_attack1.ogg
│ ├── slime_attack2.ogg
│ ├── snow1.ogg
│ ├── snow2.ogg
│ ├── snow3.ogg
│ ├── spider_death.ogg
│ ├── spider_say1.ogg
│ ├── spider_say2.ogg
│ ├── spider_say3.ogg
│ ├── splash.ogg
│ ├── step_cloth.ogg
│ ├── step_grass1.ogg
│ ├── step_grass2.ogg
│ ├── step_grass3.ogg
│ ├── step_grass4.ogg
│ ├── step_grass5.ogg
│ ├── step_grass6.ogg
│ ├── step_ladder.ogg
│ ├── step_sand.ogg
│ ├── step_snow1.ogg
│ ├── step_snow2.ogg
│ ├── step_snow3.ogg
│ ├── step_snow4.ogg
│ ├── step_stone1.ogg
│ ├── step_stone2.ogg
│ ├── step_stone3.ogg
│ ├── step_stone4.ogg
│ ├── step_stone5.ogg
│ ├── step_stone6.ogg
│ ├── step_wood1.ogg
│ ├── step_wood2.ogg
│ ├── step_wood3.ogg
│ ├── step_wood4.ogg
│ ├── step_wood5.ogg
│ ├── step_wood6.ogg
│ ├── stone1.ogg
│ ├── stone2.ogg
│ ├── stone3.ogg
│ ├── strip1.ogg
│ ├── strip2.ogg
│ ├── strip3.ogg
│ ├── strip4.ogg
│ ├── swim1.ogg
│ ├── swim2.ogg
│ ├── swim3.ogg
│ ├── swim4.ogg
│ ├── sys3.ogg
│ ├── system1.ogg
│ ├── system2.ogg
│ ├── thorns_hit1.ogg
│ ├── thorns_hit2.ogg
│ ├── thorns_hit3.ogg
│ ├── thorns_hit4.ogg
│ ├── thunder1.ogg
│ ├── thunder2.ogg
│ ├── thunder3.ogg
│ ├── tink1.ogg
│ ├── tink2.ogg
│ ├── tink3.ogg
│ ├── travel.ogg
│ ├── trigger.ogg
│ ├── turtle_death.ogg
│ ├── turtle_hurt1.ogg
│ ├── turtle_hurt2.ogg
│ ├── turtle_hurt3.ogg
│ ├── villager_death.ogg
│ ├── villager_hit1.ogg
│ ├── villager_hit2.ogg
│ ├── villager_hit3.ogg
│ ├── villager_say1.ogg
│ ├── villager_say2.ogg
│ ├── villager_say3.ogg
│ ├── wand1.ogg
│ ├── wand2.ogg
│ ├── wand3.ogg
│ ├── wandfail.ogg
│ ├── weapon.ogg
│ ├── wolf_bark1.ogg
│ ├── wolf_bark2.ogg
│ ├── wolf_bark3.ogg
│ ├── wolf_death.ogg
│ ├── wolf_hurt1.ogg
│ ├── wolf_hurt2.ogg
│ ├── wolf_hurt3.ogg
│ ├── wood1.ogg
│ ├── wood2.ogg
│ ├── wood3.ogg
│ ├── zombie_death.ogg
│ ├── zombie_hurt1.ogg
│ ├── zombie_hurt2.ogg
│ ├── zombie_say1.ogg
│ ├── zombie_say2.ogg
│ ├── zombie_say3.ogg
│ ├── zpig1.ogg
│ ├── zpig2.ogg
│ ├── zpig3.ogg
│ ├── zpigdeath.ogg
│ ├── zpighurt1.ogg
│ └── zpighurt2.ogg
├── spawns/
│ ├── aurora_palace.json
│ ├── end_outpost.json
│ └── monument_ocean.json
├── textures/
│ └── backgrounds/
│ └── atlas_config.json
├── trees/
│ ├── acacia/
│ │ └── acacia.json
│ ├── bare_oak/
│ │ └── bare_oak.json
│ ├── birch/
│ │ ├── birch.json
│ │ └── leaf.mdp
│ ├── blue_mushroom/
│ │ └── blue_mushroom.json
│ ├── cactus/
│ │ └── cactus.json
│ ├── dark_oak/
│ │ └── dark_oak.json
│ ├── jungle/
│ │ └── jungle.json
│ ├── oak/
│ │ ├── leaf.mdp
│ │ └── oak.json
│ ├── palm/
│ │ └── palm.json
│ ├── spruce/
│ │ └── spruce.json
│ ├── tainted/
│ │ └── tainted.json
│ └── volcano_oak/
│ └── volcano_oak.json
├── ui/
│ ├── ContainerHelper.lua
│ ├── DeathUI.lua
│ ├── GuiID.lua
│ ├── GuiLoader.lua
│ ├── GuiLoaderProxy.lua
│ ├── HotkeyUIHelper.lua
│ ├── InfoPopupUI.lua
│ ├── LanguageUI.lua
│ ├── ModListUI.lua
│ ├── MouseItemData.lua
│ ├── NewPlayerUI.lua
│ ├── NewServerUI.lua
│ ├── NewWorldUI.lua
│ ├── OptionUI.lua
│ ├── PendingUI.lua
│ ├── PlayerListUI.lua
│ ├── RawHotkeyUIHelper.lua
│ ├── ServerListUI.lua
│ ├── SettingUI.lua
│ ├── StartUI.lua
│ ├── TipUI.lua
│ ├── TipsOfTheDay.lua
│ ├── UIDefault.lua
│ ├── UIDesign.lua
│ ├── UILayerDefine.lua
│ ├── UIManager.lua
│ ├── UISlotOp.lua
│ ├── UISpritePool.lua
│ ├── UIUtil.lua
│ ├── UIWindow.lua
│ ├── WorldListUI.lua
│ ├── advancement/
│ │ ├── AdvancementContainerClient.lua
│ │ ├── AdvancementTree.lua
│ │ ├── AdvancementUI.lua
│ │ └── AdvancementUIData.lua
│ ├── backpack/
│ │ ├── BackpackContainerClient.lua
│ │ ├── BackpackContainerServer.lua
│ │ ├── BackpackUI.lua
│ │ └── BackpackUIData.lua
│ ├── brewing/
│ │ ├── BrewingContainerClient.lua
│ │ ├── BrewingContainerServer.lua
│ │ ├── BrewingUI.lua
│ │ └── BrewingUIData.lua
│ ├── chest/
│ │ ├── Chest30ContainerClient.lua
│ │ ├── Chest30ContainerServer.lua
│ │ ├── Chest30UI.lua
│ │ ├── ChestUIData.lua
│ │ ├── EnderChest30ContainerServer.lua
│ │ ├── EnderChest30UI.lua
│ │ ├── IChestContainerClient.lua
│ │ ├── IChestContainerServer.lua
│ │ └── IChestUI.lua
│ ├── craft3x/
│ │ ├── Craft3xContainerClient.lua
│ │ ├── Craft3xContainerServer.lua
│ │ ├── Craft3xHelper.lua
│ │ ├── Craft3xUI.lua
│ │ └── Craft3xUIData.lua
│ ├── enchant/
│ │ ├── EnchantContainerClient.lua
│ │ ├── EnchantContainerServer.lua
│ │ ├── EnchantUI.lua
│ │ └── EnchantUIData.lua
│ ├── hud/
│ │ └── HudUI.lua
│ ├── nei/
│ │ ├── NeiDataBrewing.lua
│ │ ├── NeiDataCrafting.lua
│ │ ├── NeiDataProxy.lua
│ │ ├── NeiDataRepairing.lua
│ │ ├── NeiDataSmelting.lua
│ │ └── NeiUI.lua
│ ├── recipe_book/
│ │ ├── RecipeBookServer.lua
│ │ └── RecipeBookUI.lua
│ ├── repair/
│ │ ├── RepairContainerClient.lua
│ │ ├── RepairContainerServer.lua
│ │ ├── RepairUI.lua
│ │ └── RepairUIData.lua
│ ├── shooter/
│ │ ├── IShooterContainerClient.lua
│ │ ├── IShooterContainerServer.lua
│ │ ├── IShooterUI.lua
│ │ ├── Shooter9ContainerClient.lua
│ │ ├── Shooter9ContainerServer.lua
│ │ └── Shooter9UI.lua
│ └── smelt/
│ ├── SmeltContainerClient.lua
│ ├── SmeltContainerServer.lua
│ ├── SmeltUI.lua
│ └── SmeltUIData.lua
├── ui_res/
│ ├── advance_tip.json
│ ├── advancement_cell.json
│ ├── base.json
│ ├── base2.json
│ ├── base3.json
│ ├── base_list_cell.json
│ ├── base_list_cell_highlight.json
│ ├── base_list_cell_highlight_2.json
│ ├── black.json
│ ├── button_disabled.json
│ ├── button_highlight.json
│ ├── button_normal.json
│ ├── button_pressed.json
│ ├── cell_empty.json
│ ├── cell_empty_2.json
│ ├── cell_empty_3.json
│ ├── cell_empty_4.json
│ ├── cell_normal.json
│ ├── cell_selected.json
│ ├── cell_selected_2.json
│ ├── cell_selected_3.json
│ ├── cell_selected_4.json
│ ├── cursor.cur
│ ├── round_rect_white.json
│ ├── tab.json
│ ├── tab_clicked.json
│ ├── tipbox.json
│ ├── white.json
│ ├── white_circle.json
│ └── window_frame_01.json
├── util/
│ ├── Algorithm.lua
│ ├── DictUtil.lua
│ ├── MiscHelper.lua
│ ├── OrderedArray.lua
│ ├── PhysicsUtil.lua
│ ├── SnakeModel.lua
│ ├── StringUtil.lua
│ └── ValidChecker.lua
├── world/
│ ├── Portals.lua
│ └── TCModWorldData.lua
├── world_gen/
│ ├── ChunkGenerator.lua
│ ├── ModChunkGenerator.lua
│ ├── SpecialTerrainProxies.lua
│ ├── TerrainProxies.lua
│ ├── TransitionProxies.lua
│ └── WorldGenDefine.lua
└── world_gen_init.lua
================================================
FILE CONTENTS
================================================
================================================
FILE: DebugHelper.lua
================================================
local DebugHelper = class("DebugHelper")
local DebugHelperConfig = require("DebugHelperConfig")
local function PrintRecipe(rid)
local s = "recipe: "
local recipe = RecipeUtils.GetRecipe(rid)
if recipe.configID == Reg.RecipeConfigID("Craft3x") then
---@param e RecipeInputSlot
for i, e in each(recipe.inputs) do
if e.type == RecipeInputSlotType.Item then
s = s .. string.format("[%s(%d)]",
e.itemStack:GetItem().idName, e.itemStack.stackSize)
elseif e.type == RecipeInputSlotType.OreDictionary then
s = s .. string.format("[%s(%d)]",
Reg.OreDictionaryIDName(e.id), e.stackSize)
else
s = s .. "[]"
end
end
s = s .. " -> "
---@param e Slot
for i, e in each(recipe.outputs) do
if e.hasStack then
s = s .. string.format("[%s(%d)]",
e:GetStack():GetItem().idName, e:GetStack().stackSize)
else
s = s .. "[]"
end
end
print(s)
end
end
function DebugHelper.RunDebug(player)
if not DebugHelperConfig.Enable then
return
end
if NetMode.current == NetMode.Server then
DebugHelper.DebugNpc(player)
DebugHelper.DebugDay()
DebugHelper.DebugWeather()
else
DebugHelper.DebugFly(player)
end
end
function DebugHelper.RunDebugStart(player)
if not DebugHelperConfig.Enable then
return
end
if NetMode.current == NetMode.Server then
DebugHelper.DebugItemStart(player)
end
end
---@param player Player
function DebugHelper.RunDebugProp(player)
if not DebugHelperConfig.Enable then
return
end
local propDebug = DebugHelperConfig.PropDebug
if not propDebug.Enable then
return
end
local TEST_ATTACK = propDebug.Attack
local TEST_DEFENSE = propDebug.Defense
player.baseAttack.attack = player.baseAttack.attack + TEST_ATTACK.attack
player.baseAttack.knockBack = player.baseAttack.knockBack + TEST_ATTACK.knockBack
player.baseAttack.crit = player.baseAttack.crit + TEST_ATTACK.crit
player.baseDefense.defense = player.baseDefense.defense + TEST_DEFENSE.defense
player.baseDefense.blastDefense = player.baseDefense.blastDefense + TEST_DEFENSE.blastDefense
player.baseDefense.flameDefense = player.baseDefense.flameDefense + TEST_DEFENSE.flameDefense
player.baseDefense.projectileDefense = player.baseDefense.projectileDefense + TEST_DEFENSE.projectileDefense
player.baseDefense.breathDefense = player.baseDefense.breathDefense + TEST_DEFENSE.breathDefense
player.baseDefense.fallDefense = player.baseDefense.fallDefense + TEST_DEFENSE.fallDefense
player.baseDefense.knockBackDefense = player.baseDefense.knockBackDefense + TEST_DEFENSE.knockBackDefense
if propDebug.FullFood then
player.foodLevel = 100
player.foodSaturationLevel = 100
end
end
local s_tmpTickFly = 0
function DebugHelper.DebugFly(player)
local flyDebug = DebugHelperConfig.FlyDebug
if s_tmpTickFly == nil then
s_tmpTickFly = 0
end
s_tmpTickFly = s_tmpTickFly + 1
if s_tmpTickFly >= 60 and Input.keyboard:isKeyPressed(flyDebug.HotKey) then
s_tmpTickFly = 0
local g = require("player.GPlayer").GetInstance(player)
g.observeMode = not g.observeMode
end
end
function DebugHelper.DebugDay()
local dayDebug = DebugHelperConfig.DayDebug
if Input.keyboard:isKeyPressed(dayDebug.HotKeySub) then
MiscUtils.SetDayTime(MiscUtils.GetDayTime() - dayDebug.SubTime)
elseif Input.keyboard:isKeyPressed(dayDebug.HotKeyAdd) then
MiscUtils.SetDayTime(MiscUtils.GetDayTime() + dayDebug.AddTime)
end
end
function DebugHelper.DebugWeather()
local weaDebug = DebugHelperConfig.WeatherDebug
if Input.keyboard:isKeyPressed(weaDebug.HotKeySub) then
MiscUtils.SetWeatherTime(MiscUtils.GetWeatherTime() - weaDebug.SubTime)
elseif Input.keyboard:isKeyPressed(weaDebug.HotKeyAdd) then
MiscUtils.SetWeatherTime(MiscUtils.GetWeatherTime() + weaDebug.AddTime)
end
end
local s_tmpTickNpc = 0
function DebugHelper.DebugNpc(player)
if s_tmpTickNpc == nil then
s_tmpTickNpc = 0
end
s_tmpTickNpc = s_tmpTickNpc + 1
local npcDebug = DebugHelperConfig.NpcDebug
if s_tmpTickNpc > 30 and Input.keyboard:isKeyPressed(npcDebug.HotKey) then
s_tmpTickNpc = 0
local cx = player.centerX - GameWindow.width / 2 + Input.mouse.position.x
local cy = player.centerY - GameWindow.height / 2 + Input.mouse.position.y
for i, idName in ipairs(npcDebug.GenList) do
NpcUtils.Create(Reg.NpcID(idName), cx - i * 20, cy)
end
end
end
---@param player Player
function DebugHelper.DebugItemStart(player)
local itemDebug = DebugHelperConfig.ItemDebug
if not itemDebug.Enable then
return
end
local items = itemDebug.StartItems
for idx, data in ipairs(items) do
local index = idx - 1
if idx < player.backpackInventory.slotCount then
local slot = player.backpackInventory:GetSlot(index)
slot:ClearStack()
slot:PushStack(ItemStack.new(ItemRegistry.GetItemByIDName(data[1]), data[2]))
end
end
local equipments = itemDebug.StartEquipments
for idx, data in ipairs(equipments) do
if data then
local index = idx - 1
if idx < player.equipmentInventory.slotCount then
local slot = player.equipmentInventory:GetSlot(index)
slot:ClearStack()
slot:PushStack(ItemStack.new(ItemRegistry.GetItemByIDName(data), 1))
end
end
end
end
return DebugHelper
================================================
FILE: DebugHelperConfig.lua
================================================
local DebugHelperConfig = {
Enable = true,
FlyDebug = {
HotKey = Keys.P,
},
DayDebug = {
HotKeyAdd = Keys.X,
HotKeySub = Keys.Z,
AddTime = 500,
SubTime = 500,
},
WeatherDebug = {
HotKeyAdd = Keys.C,
HotKeySub = Keys.V,
AddTime = 500,
SubTime = 500,
},
PropDebug = {
Enable = true,
Attack = {
attack = 0,
knockBack = 1,
crit = 10,
},
Defense = {
defense = 18,
blastDefense = 0,
flameDefense = 0,
projectileDefense = 0,
breathDefense = 0,
fallDefense = 0,
knockBackDefense = 0,
},
FullFood = true,
},
EquipmentDebug = {
Enable = true,
Equipments = {
--"i_hat_10",
--"i_cloth_10",
--"i_leg_10",
}
},
ItemDebug = {
Enable = true,
HotKey = Keys.B,
StartEquipments = {
"lava_helmet",
"lava_chestplate",
"lava_leggings",
},
StartItems = {
--{ "blue_shot_bow", 1 },
--{ "bone_gun", 1 },
--{ "curse_bow", 1 },
--{ "dark_staff", 1 },
--{ "fire_book", 1 },
--{ "fire_shooter", 1 },
--{ "fire_staff", 1 },
--{ "frosen_staff", 1 },
--{ "lava_sword", 1 },
--{ "mini_laser_gun", 1 },
{ "tc:ender_mirror", 1 },
{ "tc:blaze_rod", 11 },
{ "tc:shotgun", 1 },
{ "tc:shot_bow", 1 },
{ "tc:brewing_stand", 111 },
{ "tc:diamond_pickaxe", 1 },
{ "tc:diamond_axe", 1 },
{ "tc:diamond_sword", 1 },
{ "tc:tower_core", 1 },
{ "tc:boomerang", 1 },
{ "td:energy_tower", 11 },
{ "td:burn_tower", 15 },
{ "potion_weakness", 111 },
{ "wooden_arrow", 111 },
{ "mini_laser_gun", 1 },
{ "wooden_arrow", 111 },
{ "ender_mirror", 1 },
{ "strange_eye", 8 },
{ "air_sword", 1 },
{ "bread", 111 },
{ "crafting_table", 2 },
{ "blue_talisman", 1 },
{ "gold_talisman", 1 },
{ "heart_talisman", 1 },
{ "lava_necklace", 1 },
{ "lighting_talisman", 1 },
{ "sword_fish", 1 },
{ "sword_fish_gun", 1 },
{ "water_book", 1 },
{ "ice_bow", 1 },
{ "blue_arrow", 11 },
{ "iron_bullet", 411 },
},
Items = {
{ "iron_bullet", 21 },
},
},
NpcDebug = {
HotKey = Keys.I,
GenList = {
--"shulker",
--"skeleton",
--"crison_eye",
--"dungeon_eater_head",
--"dungeon_slime",
--"dungeon_knight",
--"dungeon_soul",
--"bone_officer",
--"dead_mage",
--"dark_mage",
--"cursed_skull",
--"dragon_skull",
--"dungeon_creeper",
--"evil",
--"eye_guard",
--"eye_guard_laser",
--"flame_soul",
--"fly_eye",
--"fly_mouth",
--"fly_skeleton",
--"ghost_gunner",
--"ghost_soul",
--"giant_cursed_skull",
--"grim_reaper",
--"ragged_mage",
--"red_mage",
--"large_bat",
--"mad_skeleton",
--"mad_skeleton_armed",
--"mad_skeleton_tall",
--"mad_skeleton_tall_armed",
--"mad_skeleton_tall_helmet_armed",
--"skeleton_blue_armed",
--"skeleton_blue_armed_masked",
--"skeleton_blue_knight",
--"skeleton_fire_armed",
--"skeleton_fire_armed_swordsman",
--"large_spider",
--"mini_ghast",
--"red_phantom",
--"rock_man",
--"rolling_fire_ball",
--"skeleton_assaulter",
--"skeleton_guard",
--"undead_miner",
--"vampire_miner",
--"bone_officer",
--"black_rabbit",
--"guardian",
--"skeleton",
--"skeleton",
--"creeper",
--"snow_queen",
}
}
}
return DebugHelperConfig
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2022 skyblueyoshi
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
# TerraCraft
The TerraCraft official vanilla mod.
================================================
FILE: advancements/AdvancementTriggers.lua
================================================
---@class TC.AdvancementTriggers
local AdvancementTriggers = class("AdvancementProxies")
local s_instance
---@return TC.AdvancementTriggers
function AdvancementTriggers.getInstance()
if s_instance == nil then
s_instance = AdvancementTriggers.new()
end
return s_instance
end
function AdvancementTriggers:__init()
self._itemTriggerProxies = {}
self._oreDictionaryTriggerProxies = {}
self._npcKillTriggerProxies = {}
self._biomeTypeTriggerProxies = {}
self._biomeTriggerProxies = {}
end
function AdvancementTriggers:TriggerEnterBiome(player, biomeID)
local biomeData = BiomeUtils.GetData(biomeID)
self:_TryTriggerProxy(player, self._biomeTriggerProxies[biomeID])
self:_TryTriggerProxy(player, self._biomeTypeTriggerProxies[biomeData.biomeType])
end
---TriggerGetItem
---@param player Player
---@param itemID int
---@param stackSize int
function AdvancementTriggers:TriggerGetItem(player, itemID, stackSize)
-- trigger by single item
self:_TryTriggerProxy(player, self._itemTriggerProxies[itemID])
-- trigger by item ore dictionary
local item = ItemRegistry.GetItemByID(itemID)
for _, oreDictionaryID in each(item.oreDictionaryIDs) do
self:_TryTriggerProxy(player, self._oreDictionaryTriggerProxies[oreDictionaryID])
end
end
---TriggerKillNpc
---@param player Player
---@param npc Npc
function AdvancementTriggers:TriggerKillNpc(player, npc)
self:_TryTriggerProxy(player, self._npcKillTriggerProxies[npc.id])
end
function AdvancementTriggers:_TryTriggerProxy(player, proxy)
if proxy ~= nil then
self:_TriggerAll(player, proxy)
end
end
---_TriggerAll
---@param player Player
---@param advancementIDs int[]
function AdvancementTriggers:_TriggerAll(player, advancementIDs)
for _, advancementID in ipairs(advancementIDs) do
player:FinishAdvancement(advancementID)
end
end
function AdvancementTriggers:_AddProxyAdvancement(triggerProxies, key, advancementIDName)
local advancementID = Reg.AdvancementID(advancementIDName)
if triggerProxies[key] == nil then
triggerProxies[key] = {}
end
local exist = false
for _, v in ipairs(triggerProxies[key]) do
if v == advancementID then
exist = true
break
end
end
if not exist then
table.insert(triggerProxies[key], advancementID)
end
end
function AdvancementTriggers:RegisterItemTrigger(advancementIDName, itemIDName)
self:_AddProxyAdvancement(self._itemTriggerProxies, Reg.ItemID(itemIDName), advancementIDName)
end
function AdvancementTriggers:RegisterOreDictionaryTrigger(advancementIDName, oreDictionaryName)
self:_AddProxyAdvancement(self._oreDictionaryTriggerProxies, Reg.OreDictionaryID(oreDictionaryName), advancementIDName)
end
function AdvancementTriggers:RegisterNpcKillTrigger(advancementIDName, npcIDName)
self:_AddProxyAdvancement(self._npcKillTriggerProxies, Reg.NpcID(npcIDName), advancementIDName)
end
function AdvancementTriggers:RegisterBiomeTypeTrigger(advancementIDName, biomeTypeIDName)
self:_AddProxyAdvancement(self._biomeTypeTriggerProxies, Reg.BiomeTypeID(biomeTypeIDName), advancementIDName)
end
function AdvancementTriggers:RegisterBiomeTrigger(advancementIDName, biomeIDName)
self:_AddProxyAdvancement(self._biomeTriggerProxies, Reg.BiomeID(biomeIDName), advancementIDName)
end
function AdvancementTriggers:RegisterAll()
self:RegisterItemTrigger("crafting_table", "crafting_table")
self:RegisterItemTrigger("ender_chest", "ender_chest")
self:RegisterItemTrigger("blaze_rod", "blaze_rod")
self:RegisterItemTrigger("crafting_table", "crafting_table")
self:RegisterItemTrigger("bow", "wooden_bow")
self:RegisterItemTrigger("crossbow", "cross_bow")
self:RegisterItemTrigger("crossbow", "shot_bow")
self:RegisterItemTrigger("bread", "bread")
self:RegisterItemTrigger("brew", "brewing_stand")
self:RegisterItemTrigger("bronze", "bronze_ingot")
self:RegisterItemTrigger("cake", "cake")
self:RegisterItemTrigger("diamond", "diamond")
self:RegisterItemTrigger("enchant", "enchantment_table")
self:RegisterItemTrigger("ender_pearl", "ender_pearl")
self:RegisterItemTrigger("furnace", "furnace")
self:RegisterItemTrigger("lava", "bucket_lava")
self:RegisterItemTrigger("leather", "leather")
self:RegisterItemTrigger("mine", "wooden_pickaxe")
self:RegisterItemTrigger("mine_up", "stone_pickaxe")
self:RegisterItemTrigger("netherite", "ore_ancient_debris")
self:RegisterItemTrigger("pumpkin_helmet", "pumpkin_helmet")
self:RegisterItemTrigger("redstone", "redstone")
self:RegisterItemTrigger("redstone_wire", "red_wire")
self:RegisterItemTrigger("steel", "steel_ingot")
self:RegisterItemTrigger("stone", "cobblestone")
self:RegisterItemTrigger("strange_len", "strange_len")
self:RegisterItemTrigger("rocket_boost", "rocket_boost")
self:RegisterItemTrigger("mine_copper", "copper_pickaxe")
self:RegisterItemTrigger("mine_copper", "tin_pickaxe")
self:RegisterItemTrigger("mine_iron", "iron_pickaxe")
self:RegisterItemTrigger("mine_iron", "lead_pickaxe")
self:RegisterItemTrigger("mine_bronze", "bronze_pickaxe")
self:RegisterItemTrigger("mine_bronze", "steel_pickaxe")
self:RegisterItemTrigger("mine_gold", "golden_pickaxe")
self:RegisterItemTrigger("mine_gold", "silver_pickaxe")
self:RegisterItemTrigger("mine_diamond", "diamond_pickaxe")
self:RegisterItemTrigger("mine_netherite", "nether_pickaxe")
self:RegisterItemTrigger("repair", "anvil")
self:RegisterItemTrigger("gold", "gold_ingot")
self:RegisterItemTrigger("super_diamond_sword", "super_diamond_sword")
self:RegisterItemTrigger("ghost_crystal", "ghost_crystal")
self:RegisterItemTrigger("ghost", "ghost")
self:RegisterItemTrigger("ice_element_ball", "ice_element_ball")
self:RegisterItemTrigger("diamond_ingot", "diamond_ingot")
self:RegisterItemTrigger("ancient_ingot", "ancient_ingot")
self:RegisterItemTrigger("knight_ingot", "knight_ingot")
self:RegisterItemTrigger("flesh_ingot", "flesh_ingot")
self:RegisterItemTrigger("gun", "handgun")
self:RegisterItemTrigger("gun", "rocket_launcher")
self:RegisterItemTrigger("gun", "shotgun")
self:RegisterItemTrigger("gun", "sniper")
self:RegisterItemTrigger("gun", "rifle")
self:RegisterItemTrigger("magic_limit", "mana_piece")
self:RegisterOreDictionaryTrigger("wood", "OD_WOOD")
self:RegisterOreDictionaryTrigger("farm", "OD_HOE")
self:RegisterOreDictionaryTrigger("sword", "OD_SWORD")
self:RegisterOreDictionaryTrigger("staff", "OD_STAFF")
self:RegisterOreDictionaryTrigger("iron", "OD_IRON_INGOT")
self:RegisterNpcKillTrigger("guardian", "guardian")
self:RegisterNpcKillTrigger("ghast", "ghast")
self:RegisterNpcKillTrigger("snow_guard", "snow_guardian")
self:RegisterNpcKillTrigger("snow_guard", "snow_guardian_archer")
self:RegisterBiomeTypeTrigger("nether", "Nether")
self:RegisterBiomeTrigger("go_ghost_house", "more_dungeons:ghost_dungeon")
self:RegisterBiomeTrigger("go_bone_dungeon", "more_dungeons:bone_dungeon")
self:RegisterBiomeTrigger("go_dark_dungeon", "more_dungeons:tr_dungeon")
self:RegisterBiomeTrigger("go_deep_snow", "deep_ice_cave")
self:RegisterBiomeTrigger("go_ice_dungeon", "more_dungeons:blue_dungeon")
self:RegisterBiomeTrigger("go_lava_dungeon", "more_dungeons:volcano_dungeon")
self:RegisterBiomeTrigger("go_desert_dungeon", "more_dungeons:desert_dungeon")
end
return AdvancementTriggers
================================================
FILE: advancements/ancient_ingot.json
================================================
{
"ancient_ingot": {
"itemId": "ancient_ingot",
"parentId": "netherite",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/ancient_wear.json
================================================
{
"ancient_wear": {
"itemId": "ancient_helmet",
"parentId": "ancient_ingot",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/blaze_rod.json
================================================
{
"blaze_rod": {
"itemId": "blaze_rod",
"parentId": "nether",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/bow.json
================================================
{
"bow": {
"itemId": "wooden_bow",
"parentId": "crafting_table",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/bread.json
================================================
{
"bread": {
"itemId": "bread",
"parentId": "farm",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/brew.json
================================================
{
"brew": {
"itemId": "brewing_stand",
"parentId": "blaze_rod",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/bronze.json
================================================
{
"bronze": {
"itemId": "bronze_ingot",
"parentId": "iron",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/cake.json
================================================
{
"cake": {
"itemId": "cake",
"parentId": "farm",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/crafting_table.json
================================================
{
"crafting_table": {
"itemId": "crafting_table",
"parentId": "wood",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/crison_eye.json
================================================
{
"crison_eye": {
"itemId": "strange_eye",
"parentId": "strange_len",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/crison_eye_killed.json
================================================
{
"crison_eye_killed": {
"itemId": "strange_eye",
"parentId": "crison_eye",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/crossbow.json
================================================
{
"crossbow": {
"itemId": "cross_bow",
"parentId": "bow",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/diamond.json
================================================
{
"diamond": {
"itemId": "diamond",
"parentId": "iron",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/diamond_ingot.json
================================================
{
"diamond_ingot": {
"itemId": "diamond_ingot",
"parentId": "diamond",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/diamond_wear.json
================================================
{
"diamond_wear": {
"itemId": "diamond_chestplate",
"parentId": "diamond",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/dungeon_eater.json
================================================
{
"dungeon_eater": {
"itemId": "dungeon_eater",
"parentId": "go_dark_dungeon",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/dungeon_eater_killed.json
================================================
{
"dungeon_eater_killed": {
"itemId": "dungeon_eater",
"parentId": "dungeon_eater",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/enchant.json
================================================
{
"enchant": {
"itemId": "enchantment_table",
"parentId": "diamond",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/ender_chest.json
================================================
{
"ender_chest": {
"itemId": "ender_chest",
"parentId": "ender_pearl",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/ender_pearl.json
================================================
{
"ender_pearl": {
"itemId": "ender_pearl",
"parentId": "hunter",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/farm.json
================================================
{
"farm": {
"itemId": "stone_hoe",
"parentId": "crafting_table",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/flesh_ingot.json
================================================
{
"flesh_ingot": {
"itemId": "flesh_ingot",
"parentId": "gold",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/flesh_wear.json
================================================
{
"flesh_wear": {
"itemId": "flesh_helmet",
"parentId": "flesh_ingot",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/furnace.json
================================================
{
"furnace": {
"itemId": "furnace",
"parentId": "stone",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/ghast.json
================================================
{
"ghast": {
"itemId": "ghast_tear",
"parentId": "nether",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/ghost.json
================================================
{
"ghost": {
"itemId": "ghost",
"parentId": "ghost_crystal",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/ghost_crystal.json
================================================
{
"ghost_crystal": {
"itemId": "ghost_crystal",
"parentId": "go_ghost_house",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/go_bone_dungeon.json
================================================
{
"go_bone_dungeon": {
"itemId": "more_dungeons:skull_block",
"parentId": "crafting_table",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/go_dark_dungeon.json
================================================
{
"go_dark_dungeon": {
"itemId": "more_dungeons:dungeon_wall_green",
"parentId": "go_ghost_house",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/go_deep_snow.json
================================================
{
"go_deep_snow": {
"itemId": "tc:snow",
"parentId": "go_ghost_house",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/go_desert_dungeon.json
================================================
{
"go_desert_dungeon": {
"itemId": "more_dungeons:castle_pile_block",
"parentId": "go_dark_dungeon",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/go_ghost_house.json
================================================
{
"go_ghost_house": {
"itemId": "more_dungeons:statue_mini_ghast",
"parentId": "crafting_table",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/go_ice_dungeon.json
================================================
{
"go_ice_dungeon": {
"itemId": "more_dungeons:dungeon_wall_blue",
"parentId": "go_deep_snow",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/go_lava_dungeon.json
================================================
{
"go_lava_dungeon": {
"itemId": "bucket_lava",
"parentId": "go_ice_dungeon",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/gold.json
================================================
{
"gold": {
"itemId": "gold_ingot",
"parentId": "iron",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/gold_wear.json
================================================
{
"gold_wear": {
"itemId": "golden_chestplate",
"parentId": "gold",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/guardian.json
================================================
{
"guardian": {
"itemId": "guardian",
"parentId": "hunter",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/gun.json
================================================
{
"gun": {
"itemId": "handgun",
"parentId": "nether",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/hunter.json
================================================
{
"hunter": {
"itemId": "bone",
"parentId": "sword",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/ice_element_ball.json
================================================
{
"ice_element_ball": {
"itemId": "ice_element_ball",
"parentId": "snow_guard",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/inventory.json
================================================
{
"inventory": {
"itemId": "book",
"showTip": true,
"broadcase": true,
"trigger": {
"name": "open_advance_ui",
"conditions": {}
}
}
}
================================================
FILE: advancements/iron.json
================================================
{
"iron": {
"itemId": "iron_ingot",
"parentId": "furnace",
"showTip": true,
"broadcase": true,
"trigger": {
"name": "get_item_group",
"conditions": {
"group": "GROUP_INGOT"
}
}
}
}
================================================
FILE: advancements/knight_ingot.json
================================================
{
"knight_ingot": {
"itemId": "knight_ingot",
"parentId": "go_dark_dungeon",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/knight_wear.json
================================================
{
"knight_wear": {
"itemId": "knight_helmet",
"parentId": "knight_ingot",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/lava.json
================================================
{
"lava": {
"itemId": "bucket_lava",
"parentId": "iron",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/leather.json
================================================
{
"leather": {
"itemId": "leather",
"parentId": "sword",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/magic_gold_wear.json
================================================
{
"magic_gold_wear": {
"itemId": "magic_gold_helmet",
"parentId": "gold",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/magic_limit.json
================================================
{
"magic_limit": {
"itemId": "mana_piece",
"parentId": "staff",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/mine.json
================================================
{
"mine": {
"itemId": "wooden_pickaxe",
"parentId": "crafting_table",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/mine_bronze.json
================================================
{
"mine_bronze": {
"itemId": "bronze_pickaxe",
"parentId": "mine_iron",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/mine_copper.json
================================================
{
"mine_copper": {
"itemId": "copper_pickaxe",
"parentId": "mine_up",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/mine_diamond.json
================================================
{
"mine_diamond": {
"itemId": "diamond_pickaxe",
"parentId": "mine_gold",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/mine_gold.json
================================================
{
"mine_gold": {
"itemId": "golden_pickaxe",
"parentId": "mine_bronze",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/mine_iron.json
================================================
{
"mine_iron": {
"itemId": "iron_pickaxe",
"parentId": "mine_copper",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/mine_netherite.json
================================================
{
"mine_netherite": {
"itemId": "nether_pickaxe",
"parentId": "mine_diamond",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/mine_up.json
================================================
{
"mine_up": {
"itemId": "stone_pickaxe",
"parentId": "stone",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/mirror.json
================================================
{
"mirror": {
"itemId": "ender_mirror",
"parentId": "ender_pearl",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/nether.json
================================================
{
"nether": {
"itemId": "soul_sand",
"parentId": "diamond",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/nether_destroyer.json
================================================
{
"nether_destroyer": {
"itemId": "nether_altar",
"parentId": "nether",
"showTip": true,
"broadcase": true,
"trigger": {
"name": "nether_destroyer_wake",
"conditions": {}
}
}
}
================================================
FILE: advancements/nether_destroyer_killed.json
================================================
{
"nether_destroyer_killed": {
"itemId": "nether_destroyer_loot",
"parentId": "nether_destroyer",
"showTip": true,
"broadcase": true,
"trigger": {
"name": "nether_destroyer_killed",
"conditions": {}
}
}
}
================================================
FILE: advancements/netherite.json
================================================
{
"netherite": {
"itemId": "ore_ancient_debris",
"parentId": "nether",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/netherite_full_wear.json
================================================
{
"netherite_full_wear": {
"itemId": "nether_helmet",
"parentId": "netherite",
"showTip": true,
"broadcase": true,
"trigger": {
"name": "full_wear_sub_group",
"conditions": {
"subGroup": "SUB_GROUP_NETHERITE"
}
}
}
}
================================================
FILE: advancements/portal.json
================================================
{
"portal": {
"itemId": "portal:nature_portal",
"parentId": "crafting_table",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/pumpkin_helmet.json
================================================
{
"pumpkin_helmet": {
"itemId": "pumpkin_helmet",
"parentId": "farm",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/recipe_book.json
================================================
{
"recipe_book": {
"itemId": "book",
"parentId": "crafting_table",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/redstone.json
================================================
{
"redstone": {
"itemId": "redstone",
"parentId": "stone",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/redstone_wire.json
================================================
{
"redstone_wire": {
"itemId": "red_wire",
"parentId": "redstone",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/repair.json
================================================
{
"repair": {
"itemId": "anvil",
"parentId": "iron",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/rocket_boost.json
================================================
{
"rocket_boost": {
"itemId": "rocket_boost",
"parentId": "crafting_table",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/snow_guard.json
================================================
{
"snow_guard": {
"itemId": "steel_helmet",
"parentId": "hunter",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/snow_queen.json
================================================
{
"snow_queen": {
"itemId": "snow_glass_ball",
"parentId": "snow_guard",
"showTip": true,
"broadcase": true,
"trigger": {
"name": "snow_queen_wake",
"conditions": {}
}
}
}
================================================
FILE: advancements/snow_queen_killed.json
================================================
{
"snow_queen_killed": {
"itemId": "snow_queen_loot",
"parentId": "snow_queen",
"showTip": true,
"broadcase": true,
"trigger": {
"name": "snow_queen_killed",
"conditions": {}
}
}
}
================================================
FILE: advancements/staff.json
================================================
{
"staff": {
"itemId": "amethyst_staff",
"parentId": "hunter",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/star_wear.json
================================================
{
"star_wear": {
"itemId": "star_helmet",
"parentId": "crison_eye_killed",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/steel.json
================================================
{
"steel": {
"itemId": "steel_ingot",
"parentId": "iron",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/stone.json
================================================
{
"stone": {
"itemId": "stone_brick",
"parentId": "mine",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/strange_len.json
================================================
{
"strange_len": {
"itemId": "strange_len",
"parentId": "hunter",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/super_diamond_sword.json
================================================
{
"super_diamond_sword": {
"itemId": "super_diamond_sword",
"parentId": "diamond",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/super_diamond_wear.json
================================================
{
"super_diamond_wear": {
"itemId": "super_diamond_helmet",
"parentId": "diamond_ingot",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/sword.json
================================================
{
"sword": {
"itemId": "wooden_sword",
"parentId": "crafting_table",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: advancements/wood.json
================================================
{
"wood": {
"itemId": "wood_oak",
"parentId": "inventory",
"showTip": true,
"broadcase": true
}
}
================================================
FILE: api.lua
================================================
---@class TC.API
local API = class("API")
local s_instance
---@return TC.API
function API.getInstance()
if s_instance == nil then
s_instance = API.new()
end
return s_instance
end
function API:__init()
self.uiModifyDict = {}
end
function API:_ModifyUI(uiClassName, modifyClass)
if self.uiModifyDict[uiClassName] == nil then
self.uiModifyDict[uiClassName] = {}
end
table.insert(self.uiModifyDict[uiClassName], modifyClass)
end
---data:
---{
--- initContentCallback=???,
---}
---@param data table
function API.ModifyUI(uiClassName, modifyClass)
API.getInstance():_ModifyUI(uiClassName, modifyClass)
end
return API
================================================
FILE: apis/Account.lua
================================================
---@API
---@class Account 描述一个账号信息。
---@field name string 当前账号的名称。
---@field skinID int 当前账号的皮肤ID。
local Account = {}
---创建一个账号对象。
---@return Account 新的账号对象。
function Account.new()
end
return Account
================================================
FILE: apis/AccountUtils.lua
================================================
---@API
---@class AccountUtils 账号通用类,封装了账号相关操作函数。
local AccountUtils = {}
---从存档中加载一个账号。
---@param accountName string 账号名称。
---@param account Account 如果成功加载账号,将把账号信息写入该参数。
---@return boolean 是否成功加载账号。
function AccountUtils.Load(accountName, account)
end
---将一个账号保存到存档中。
---@param account Account 账号。
function AccountUtils.Save(account)
end
---将一个账号从存档中移除。
---@param accountName string 账号名称。
function AccountUtils.Remove(accountName)
end
return AccountUtils
================================================
FILE: apis/Advancement.lua
================================================
---@API
---@class Advancement 描述一项成就。
---@field itemID int 成就使用的物品ID,用于在成就树界面显示物品图标。
---@field parentID int 成就在成就树的父成就ID。
---@field showTip boolean 玩家完成该成就时,是否在界面右上角弹出完成成就提示。
---@field broadcast boolean 玩家完成成就时,是否广播给所有人。
local Advancement = {}
return Advancement
================================================
FILE: apis/AdvancementUtils.lua
================================================
---@API
---@class AdvancementUtils 成就通用类。
local AdvancementUtils = {}
---由成就ID,获得一个成就信息。
---@param advancementID int 成就ID。
---@return Advancement 成就信息。
function AdvancementUtils.Get(advancementID)
end
return AdvancementUtils
================================================
FILE: apis/Attack.lua
================================================
---@API
---@class Attack 表示一个攻击属性。
---@field attack int 伤害值。
---@field knockBack int 击退值。
---@field crit int 攻击的百分暴击率。1-100表示1-100%的概率产生双倍暴击伤害,大于100表示总是产生双倍暴击伤害,小于1表示不产生暴击伤害。
local Attack = {}
--- 创建一个攻击属性对象。
---@param attack int 伤害值。
---@param knockBack int 击退值。
---@param crit int 攻击的百分暴击率。
---@return Attack 新的攻击属性对象。
function Attack.new(attack, knockBack, crit)
end
--- 重置所有攻击属性数值。
function Attack:Restore()
end
return Attack
================================================
FILE: apis/BiomeData.lua
================================================
---@API
---@class BiomeTerrain 描述一个地形信息。
---@field name string 地形名称。
---@field times double 生成次数(小于1表示概率)
---@field size int 地形大小(生成器参数)
---@field height int 地形高度(生成器参数)
local BiomeTerrain = {}
---@class BiomeTerrains 描述地形信息。
---@field terrains BiomeTerrain[] 允许出现的所有地形。
---@field specialTerrains BiomeTerrain[] 允许出现的特殊地形。
---@field transition string 过渡方式(生成器参数)
---@field transitionTag int 过渡附加值(生成器参数)
local BiomeTerrains = {}
---@class BiomeLiquidInfo 描述湖泊信息。
---@field liquidID int 液体ID。
---@field maxAllowCount int 湖泊最多有多少格子的当前液体。
local BiomeLiquidInfo = {}
---@class BiomeTreeInfo 描述树信息。
---@field styles int[] 不同数目的方块id。
---@field density double 种植密度(生成器参数)
local BiomeTreeInfo = {}
---@class BiomeMushroomInfo 描述巨型蘑菇信息。
---@field styles int[] 不同数目的方块id。
---@field density double 种植密度(生成器参数)
local BiomeMushroomInfo = {}
---@class BiomeData 描述一个群系信息。
---@field biomeType int 群系类型。
---@field scale double 群系大小(生成器参数,相对于perlin参考值)
---@field terrains BiomeTerrains 地形信息。
---@field treeInfo BiomeTreeInfo 树信息。
---@field mushroomInfo BiomeMushroomInfo 巨型蘑菇信息。
---@field oreGroupName string 当前群系指定矿物名称批量生成矿物。
local BiomeData = {}
return BiomeData
================================================
FILE: apis/BiomeUtils.lua
================================================
---@API
---@class BiomeUtils 生物群系通用类。
local BiomeUtils = {}
---由指定生物群系类型和在该生物群系类型的索引,返回生物群系数据。
---@param biomeTypeID int 生物群系类型。
---@param index int 在该生物群系类型的索引。
---@return int 生物群系数据。
function BiomeUtils.GetBiomeIDByType(biomeTypeID, index)
end
---返回指定生物群系类型的生物群系数量。
---@param biomeTypeID int 生物群系类型。
---@return int 指定生物群系类型的生物群系数量。
function BiomeUtils.GetBiomeCountByType(biomeTypeID)
end
---由生物群系ID,返回生物群系数据。
---@param biomeID int 生物群系ID。
---@return BiomeData 生物群系数据。
function BiomeUtils.GetData(biomeID)
end
return BiomeUtils
================================================
FILE: apis/BlockData.lua
================================================
---@API
---@class BlockData 描述一个方块数据。
---@field textureLocation TextureLocation 方块渲染在地图中的纹理。
---@field group int 方块组,决定渲染在地图中纹理衔接方式。
---@field subGroup int 方块子组。
---@field stepSoundId int 踩在方块上发出的音效ID。
---@field stepSoundGroupId int 踩在方块上发出的音效组ID。
---@field functionSoundId int
---@field functionSoundGroupId int
---@field functionSoundId2 int
---@field functionSoundGroupId2 int
---@field functionSoundId3 int
---@field functionSoundGroupId3 int
---@field functionSoundId4 int
---@field functionSoundGroupId4 int
---@field isRipen boolean 是否允许催熟。
---@field isDoorOpened boolean 是否为开启了的门。
---@field isDoorClosed boolean 是否为关闭了的门。
local BlockData = {}
---判断指定物品,能否种植在当前方块上。
---@param itemID int 物品ID。
---@return boolean 物品能否种植在方块上。
function BlockData:CanSeed(itemID)
end
---当前方块是否拥有动画效果。
---@return boolean 是否拥有动画效果。
function BlockData:HasAnimation()
end
return BlockData
================================================
FILE: apis/BlockEntity.lua
================================================
---@API
---@class BlockEntity
---@field id int
---@field xi int
---@field yi int
---@field dataWatcher DataWatcher
local BlockEntity = {}
---SetAnimation
---@param animationIndex int
function BlockEntity:SetAnimation(animationIndex)
end
---GetAnimation
---@return int
function BlockEntity:GetAnimation()
end
---GetModBlockEntity
---@return ModBlockEntity
function BlockEntity:GetModBlockEntity()
end
return BlockEntity
================================================
FILE: apis/BlockUtils.lua
================================================
---@class BlockUtils
---@field maxID int
---@field oreGroups OreDataGroup[]
local BlockUtils = {}
---@param blockID int
---@return BlockData
function BlockUtils.GetData(blockID)
end
return BlockUtils
================================================
FILE: apis/Buff.lua
================================================
---@class Buff
---@field id int
---@field time int
local Buff = {}
---@param id int
---@param time int
---@return Buff
function Buff.new(id, time)
end
return Buff
================================================
FILE: apis/ClientBoundPacketWriter.lua
================================================
---@class ClientBoundPacket
---@field writerBuffer ByteStream
---@field readerBuffer ByteStream
local ClientBoundPacket = {}
---Send
---@param player Player
function ClientBoundPacket:Send(player)
end
---@return ByteStream
function ClientBoundPacket:GetWriterBuffer()
end
---@return ByteStream
function ClientBoundPacket:GetReaderBuffer()
end
return ClientBoundPacket
================================================
FILE: apis/ClientState.lua
================================================
---@class ClientState
---@field LoadingResource int
---@field InMenu int
---@field Joining int
---@field LoadingWorld int
---@field SavingWorld int
---@field LosingConnection int
---@field Gaming int
---@field Exiting int
---@field current int
local ClientState = {}
return ClientState
================================================
FILE: apis/ClientStateManager.lua
================================================
---@class ClientStateManager
local ClientStateManager = class("ClientStateManager")
---StartJoining
---@param joinData JoinData
function ClientStateManager.StartJoining(joinData)
end
function ClientStateManager.SaveAndExitGaming()
end
function ClientStateManager.QuitGame()
end
return ClientStateManager
================================================
FILE: apis/Container.lua
================================================
---@class Container
local Container = {}
---AddSlotToContainer
---@overload function(inventory:Inventory,slotIndex:int):int
---@param inventory Inventory
---@param slotIndex int
---@param ownedByGui boolean
---@return int
function Container:AddSlotToContainer(inventory, slotIndex, ownedByGui)
end
---GetSlot
---@param index int
---@return Slot
function Container:GetSlot(index)
end
---@return int
function Container:GetSlotCount()
end
---CanInteractWith
---@param player Player
---@return boolean
function Container:CanInteractWith(player)
end
function Container:OnUpdate()
end
function Container:OnClose()
end
function Container:DetectAndSendChangeInteger(id, value)
end
function Container:DetectAndSendChangeDouble(id, value)
end
function Container:DetectAndSendChangeString(id, value)
end
function Container:DetectAndSendChangeBoolean(id, value)
end
function Container:OnDetectChange()
end
function Container:OnReceiveChange(id, value)
end
---OnEvent
---@param eventId int
---@param eventString string
function Container:OnEvent(eventId, eventString)
end
---EnsureSlotEmpty
---@param container Container
---@param slotIndex int
function Container:CommandEnsureSlotEmpty(container, slotIndex)
end
---EnsureSlotHasItem
---@param container Container
---@param slotIndex int
---@param itemStack ItemStack
function Container:CommandEnsureSlotHasItem(container, slotIndex, itemStack)
end
---SwapSlot
---@param containerA Container
---@param slotIndexA int
---@param containerB Container
---@param slotIndexB int
function Container:CommandSwapSlot(containerA, slotIndexA, containerB, slotIndexB)
end
---SlotMoveTo
---@param containerFrom Container
---@param slotIndexFrom int
---@param containerTo Container
---@param slotIndexTo int
---@param moveStackSize int
function Container:CommandSlotMoveTo(containerFrom, slotIndexFrom, containerTo, slotIndexTo, moveStackSize)
end
---@return int
function Container:GetID()
end
return Container
================================================
FILE: apis/DataWatcher.lua
================================================
---@API
---@class DataWatcher 数据同步类,内部封装了网络同步逻辑。
local DataWatcher = {}
---
---@overload fun(value:int):int
---@param value boolean
---@param canRemote boolean
---@return int
function DataWatcher:AddBool(value, canRemote)
end
---由指定通道,向
---@param channel int
---@param value boolean
function DataWatcher:UpdateBool(channel, value)
end
---由指定通道,从远端获取数据。
---@param channel int 通道。
---@return boolean 布尔型数据。
function DataWatcher:GetBool(channel)
end
---
---@overload fun(value:int):int
---@param value int
---@param canRemote boolean
---@return int
function DataWatcher:AddByte(value, canRemote)
end
---
---@param channel int
---@param value int
function DataWatcher:UpdateByte(channel, value)
end
---
---@param channel int
---@return int
function DataWatcher:GetByte(channel)
end
---
---@overload fun(value:int):int
---@param value int
---@param canRemote boolean
---@return int
function DataWatcher:AddShort(value, canRemote)
end
---
---@param channel int
---@param value int
function DataWatcher:UpdateShort(channel, value)
end
---
---@param channel int
---@return int
function DataWatcher:GetShort(channel)
end
---
---@overload fun(value:int):int
---@param value int
---@param canRemote boolean
---@return int
function DataWatcher:AddInteger(value, canRemote)
end
---
---@param channel int
---@param value int
function DataWatcher:UpdateInteger(channel, value)
end
---
---@param channel int
---@return int
function DataWatcher:GetInteger(channel)
end
---
---@overload fun(value:boolean):int
---@param value double
---@param canRemote boolean
---@return int
function DataWatcher:AddDouble(value, canRemote)
end
---
---@param channel int
---@param value double
function DataWatcher:UpdateDouble(channel, value)
end
---
---@param channel int
---@return double
function DataWatcher:GetDouble(channel)
end
---
---@overload fun(value:string):int
---@param value string
---@param canRemote boolean
---@return int
function DataWatcher:AddString(value, canRemote)
end
---
---@param channel int
---@param value string
function DataWatcher:UpdateString(channel, value)
end
---
---@param channel int
---@return string
function DataWatcher:GetString(channel)
end
---
---@param value Inventory
---@return int
function DataWatcher:AddInventory(value)
end
---
---@param channel int
---@param value Inventory
function DataWatcher:UpdateInventory(channel, value)
end
---
---@param channel int
---@return Inventory
function DataWatcher:GetInventory(channel)
end
return DataWatcher
================================================
FILE: apis/DeathReason.lua
================================================
---@class DeathReason
---@field UNKNOWN int
---@field SUICIDE int
---@field FALL int
---@field DROWN int
---@field BOOM int
---@field BURN int
---@field LAVA int
---@field STARVE int
---@field BUFF int
---@field POISON int
local DeathReason = {}
return DeathReason
================================================
FILE: apis/Defense.lua
================================================
-- Document
-- Defense Class: https://blueyoshi.gitbook.io/terracraft/en/mod/api/type#defense
--
-- Defense类: https://blueyoshi.gitbook.io/terracraft/cn/mod/api/type#defense
--
-- Copyright (c) 2021. BlueYoshi(blueyoshi@foxmail.com)
---@class Defense Represents a defense property. (表示一个防御属性)
---@field defense int The defense value. (防御值)
---@field blastDefense int The value of explosion defense. (爆炸防御值)
---@field flameDefense int The value of fire defense. (火焰防御值)
---@field projectileDefense int The value of projectile defense. (抛掷物防御值)
---@field breathDefense int The value of breath defense. (呼吸防御值)
---@field fallDefense int The value of fall defense. (掉落防御值)
---@field knockBackDefense int The value of knock back defense. (击退防御值)
local Defense = {}
function Defense:Restore()
end
return Defense
================================================
FILE: apis/Direction.lua
================================================
-- Document
-- Direction Enum Class: https://blueyoshi.gitbook.io/terracraft/en/mod/api/type#direction
--
-- Direction枚举类: https://blueyoshi.gitbook.io/terracraft/cn/mod/api/type#direction
--
-- Copyright (c) 2021. BlueYoshi(blueyoshi@foxmail.com)
---@class Direction Enum class (Enum Format: `DIRECTION_XXX`)
local Direction = {}
---@type Direction
DIRECTION_LEFT = nil
---@type Direction
DIRECTION_TOP = nil
---@type Direction
DIRECTION_BOTTOM = nil
---@type Direction
DIRECTION_RIGHT = nil
return Direction
================================================
FILE: apis/Effect.lua
================================================
---@class Effect:Entity
---@field decSpeed double
---@field decScale double
---@field decAlpha double
---@field decRotateSpeed double
---@field scale double
---@field alpha double
---@field rotateSpeed double
---@field gravity boolean
---@field lightAlpha int
---@field lightRed int
---@field lightGreen int
---@field lightBlue int
---@field disappearTime int
local Effect = {}
---SetDisappearTime
---@param disappearTime int
function Effect:SetDisappearTime(disappearTime)
end
--- Destroy the current effect object.
---
--- 清除当前抛射物对象。
function Effect:Kill()
end
--- If the player owner exists and is alive, return the player, otherwise return nil.
---
--- 若玩家拥有者存在且存活,返回该玩家,否则返回nil。
---@return Player|nil
function Effect:GetPlayerOwner()
end
--- If the npc owner exists and is alive, return the npc, otherwise return nil.
---
--- 若NPC拥有者存在且存活,返回该NPC,否则返回nil。
---@return Npc|nil
function Effect:GetNpcOwner()
end
--- If the player target exists and is alive, return the player, otherwise return nil.
---
--- 若当前抛射物的玩家锁定目标存在且存活,返回该玩家,否则返回nil。
---@return Player|nil
function Effect:GetPlayerTarget()
end
--- If the npc target exists and is alive, return the npc, otherwise return nil.
---
--- 若当前抛射物的NPC锁定目标存在且存活,返回该NPC,否则返回nil。
---@return Npc|nil
function Effect:GetNpcTarget()
end
--- Set the locked player target of the current effect.
---
--- 设定当前抛射物的锁定玩家目标。
---@return Player|nil
function Effect:SetPlayerTarget(player)
end
--- Set the locked NPC target of the current effect.
---
--- 设定当前抛射物的锁定NPC目标。
---@return Npc|nil
function Effect:SetNpcTarget(npc)
end
return Effect
================================================
FILE: apis/EffectUtils.lua
================================================
---@class EffectUtils
local EffectUtils = {}
---
---
---@overload fun(id:int,centerX:double,centerY:double):Effect
---@overload fun(id:int,centerX:double,centerY:double,speedX:double):Effect
---@overload fun(id:int,centerX:double,centerY:double,speedX:double,speedY:double):Effect
---@overload fun(id:int,centerX:double,centerY:double,speedX:double,speedY:double,rotateSpeed:double):Effect
---@overload fun(id:int,centerX:double,centerY:double,speedX:double,speedY:double,rotateSpeed:double,scale:double):Effect
---@overload fun(id:int,centerX:double,centerY:double,speedX:double,speedY:double,rotateSpeed:double,scale:double,alpha:double):Effect
---@overload fun(id:int,centerX:double,centerY:double,speedX:double,speedY:double,rotateSpeed:double,scale:double,alpha:double,color:Color):Effect
---@param id int
---@param centerX double
---@param centerY double
---@param speedX double
---@param speedY double
---@param rotateSpeed double
---@param scale double
---@param alpha double
---@param color Color
---@return Effect
function EffectUtils.Create(id, centerX, centerY, speedX, speedY, rotateSpeed, scale, alpha, color)
end
---@overload fun(id:int,centerX:double,centerY:double):Effect
---@overload fun(id:int,centerX:double,centerY:double,speedX:double):Effect
---@overload fun(id:int,centerX:double,centerY:double,speedX:double,speedY:double):Effect
---@overload fun(id:int,centerX:double,centerY:double,speedX:double,speedY:double,rotateSpeed:double):Effect
---@overload fun(id:int,centerX:double,centerY:double,speedX:double,speedY:double,rotateSpeed:double,scale:double):Effect
---@overload fun(id:int,centerX:double,centerY:double,speedX:double,speedY:double,rotateSpeed:double,scale:double,alpha:double):Effect
---@overload fun(id:int,centerX:double,centerY:double,speedX:double,speedY:double,rotateSpeed:double,scale:double,alpha:double,color:Color):Effect
---@param id int
---@param centerX double
---@param centerY double
---@param speedX double
---@param speedY double
---@param rotateSpeed double
---@param scale double
---@param alpha double
---@param color Color
---@return Effect
function EffectUtils.SendFromServer(id, centerX, centerY, speedX, speedY, rotateSpeed, scale, alpha, color)
end
return EffectUtils
================================================
FILE: apis/Enchantment.lua
================================================
---@class Enchantment
---@field id int
---@field level int
local Enchantment = {}
---@param id int
---@param level int
---@return Enchantment
function Enchantment.new(id, level)
end
return Enchantment
================================================
FILE: apis/EnchantmentData.lua
================================================
---@class EnchantmentData
---@field allowMaxLevel int
---@field minCreatingLevel int
---@field noCreating boolean
local EnchantmentData = {}
---IsToolTypeValid
---@param toolType string
---@return boolean
function EnchantmentData:IsToolTypeValid(toolType)
end
return EnchantmentData
================================================
FILE: apis/EnchantmentUtils.lua
================================================
---@class EnchantmentUtils
local EnchantmentUtils = {}
---@param enchantmentID int
---@return EnchantmentData
function EnchantmentUtils.GetData(enchantmentID)
end
---IsConflict
---@param enchantmentID int
---@param enchantmentID2 int
---@return boolean
function EnchantmentUtils.IsConflict(enchantmentID, enchantmentID2)
end
return EnchantmentUtils
================================================
FILE: apis/Entity.lua
================================================
---@API
---@class Entity 描述一个基本实体类。
---@field x double 实体左上角x坐标。
---@field y double 实体左上角y坐标。
---@field centerX double Read-only 返回实体正中间x坐标。
---@field centerY double Read-only 返回实体正中间y坐标。
---@field centerXi int Read-only 返回实体正中间格子横坐标。
---@field centerYi int Read-only 返回实体正中间格子纵坐标。
---@field rightX double Read-only 返回实体最右侧x坐标。
---@field bottomY double Read-only 返回实体最底部y坐标。
---@field speedX double 实体横向速度。
---@field speedY double 实体纵向速度。
---@field gravity double 实体的重力加速度。
---@field width int Read-only 返回实体碰撞箱宽度。
---@field height int Read-only 返回实体碰撞箱高度。
---@field direction boolean 实体面朝右侧为true,面朝左侧为false。
---@field rotateAngle double 实体碰撞箱的旋转角度。
---@field speedAngle double Read-only 返回当前实体运动速度的向量夹角。
---@field randX double Read-only 返回实体在x轴投影上的随机坐标。
---@field randY double Read-only 返回实体在y轴投影上的随机坐标。
---@field shape Shape Read-only 返回实体碰撞箱形状。
---@field stand boolean Read-only 返回实体是否为站立状态。
---@field isCollisionTop boolean Read-only 返回实体是否顶部发生碰撞。
---@field isCollisionLeft boolean Read-only 返回实体是否左侧发生碰撞。
---@field isCollisionRight boolean Read-only 返回实体是否右侧发生碰撞。
---@field isCollisionStuck boolean Read-only 返回实体是否卡在方块内部。
---@field isNoCollision boolean Read-only 返回实体是否没有发生任何形式的碰撞。
---@field onSlope boolean Read-only 返回实体是否站在斜坡上。
---@field hitbox Hitbox Read-only 若实体为轴对齐矩形,返回轴对齐碰撞箱,否则返回旋转矩形碰撞箱。
---@field aabb Hitbox Read-only 实体旋转角度为0的轴对齐碰撞箱。
---@field minAABB Hitbox Read-only 完全包裹实体的最小轴对齐碰撞箱。
---@field allowCheckCollision boolean 决定是否执行与方块的碰撞检测。
---@field spriteDefaultWidth int Read-only 实体默认绘制宽度。
---@field spriteDefaultHeight int Read-only 实体默认绘制高度。
---@field spriteRect Rectangle 表示实体绘制时在目标贴图的剪裁区域。
---@field spriteEx SpriteEx 实体绘制时的精灵拓展信息。
---@field spriteOffsetX int @[ default `0.0` ] 实体绘制的横向偏移量。
---@field spriteOffsetY int @[ default `0.0` ] 实体绘制的纵向偏移量。
---@field color Color @[ default `COLOR_WHITE` ] 实体绘制时的颜色。
---@field frameTickTime int 实体绘制用的帧计时器,每帧自增1。
---@field frameIndex int Read-only 当前实体帧索引。
---@field frameStyles int Read-only 实体样式数。
---@field frames int Read-only 实体总帧数。
---@field frameSpeed int Read-only 实体帧切换周期。
---@field tickTime int Read-only 实体的实际生存的时间。
---@field randSeed int Read-only 实体的随机数种子。
local Entity = {}
--- 将实体中心x坐标设为指定位置。
---@param newCenterX double
function Entity:SetCenterX(newCenterX)
end
--- 将实体中心y坐标设为指定位置。
---@param newCenterY double
function Entity:SetCenterY(newCenterY)
end
--- 返回实体中心点到目标点的角度。
---@param desX double 目标点x坐标。
---@param desY double 目标点y坐标。
---@return double
function Entity:GetAngleTo(desX, desY)
end
--- 返回来源点到实体中心点的角度。
---@param srcX double 来源点x坐标。
---@param srcY double 来源点y坐标。
---@return double
function Entity:GetAngleFrom(srcX, srcY)
end
--- 返回实体中心到指定点的距离。
---@param otherX double 目标点x坐标。
---@param otherX double 目标点y坐标。
---@return double
function Entity:GetDistance(otherX, otherY)
end
--- 在原有角度基础上继续旋转指定角度。
---@param angle double 旋转的角度。
function Entity:Rotate(angle)
end
--- 在原有速度角度基础上继续旋转指定速度角度。
---@param angle double 旋转的角度。
function Entity:RotateSpeed(angle)
end
return Entity
================================================
FILE: apis/EntityIndex.lua
================================================
---@class EntityIndex
---@field entityID int
---@field uniqueID int
local EntityIndex = {}
---@overload fun():EntityIndex
---@param entityID int
---@param uniqueID int
---@return EntityIndex
function EntityIndex.new(entityID, uniqueID)
end
return EntityIndex
================================================
FILE: apis/GameMode.lua
================================================
---@class GameMode
---@field Survival int
---@field Creative int
---@field Adventure int
local GameMode = {}
return GameMode
================================================
FILE: apis/GlobalBlock.lua
================================================
================================================
FILE: apis/GlobalNpc.lua
================================================
---@class GlobalNpc
---@field npc Npc
local GlobalNpc = {}
--- This function is called once when the NPC is spawned.
---
--- NPC生成时调用一次该函数。
function GlobalNpc:Init()
end
---
---
--- NPC每帧运行Update()函数前调用,如果返回true则执行所有Update逻辑,返回false则不执行所有Update逻辑。可在该函数写入新的逻辑,并屏蔽原有逻辑。默认返回true。
---@return boolean
function GlobalNpc:CanUpdate()
return true
end
--- Called when NPC runs every update tick, usually write logic in this function.
---
--- NPC每帧运行时调用,通常在该函数内编写运动等逻辑。
function GlobalNpc:Update()
end
--- Called before the NPC runs the `Update()` function every update tick.
--- It is usually used to insert new logic before the original logic.
---
--- NPC每帧运行`Update()`函数前调用。通常用于在原逻辑前插入新逻辑。
function GlobalNpc:PreUpdate()
end
--- Called after the NPC runs the `Update()` function every update tick.
--- It is usually used to insert new logic after the original logic.
---
--- NPC每帧运行`Update()`函数后调用。通常用于追加逻辑。
function GlobalNpc:PostUpdate()
end
--- If the NPC has a skeleton model,
--- it is called after `PostUpdate()` to process the logic of the custom skeleton model.
--- After executing this function, all joints of the skeleton model will be recalculated.
---
--- 若NPC拥有骨骼模型,每帧执行完`PostUpdate()`后调用,用于处理自定义骨骼模型逻辑。
--- 执行完该函数后,会对所有骨骼模型关节重新计算。
--- @param skeleton Skeleton Represents the skeleton model of the current NPC. (当前NPC的骨骼模型)
function GlobalNpc:UpdateSkeleton(skeleton)
end
--- Called before the NPC runs the `UpdateSkeleton(skeleton)` function every update tick.
--- It is usually used to insert new logic before the original logic.
---
--- NPC每帧运行`UpdateSkeleton(skeleton)`函数前调用。通常用于在原逻辑前插入新逻辑。
--- @param skeleton Skeleton Represents the skeleton model of the current NPC. (当前NPC的骨骼模型)
function GlobalNpc:PreUpdateSkeleton(skeleton)
end
--- Called after the NPC runs the `UpdateSkeleton(skeleton)` function every update tick.
--- It is usually used to insert new logic after the original logic.
---
--- NPC每帧运行`UpdateSkeleton(skeleton)`函数后调用。通常用于在原逻辑后追加新逻辑。
--- @param skeleton Skeleton Represents the skeleton model of the current NPC. (当前NPC的骨骼模型)
function GlobalNpc:PostUpdateSkeleton(skeleton)
end
---
---
--- NPC每帧绘制前调用,如果返回true则执行所有Draw逻辑,返回false则不执行所有Draw逻辑。可在该函数写入新的逻辑,并屏蔽原有逻辑。默认返回true。
---@return boolean
function GlobalNpc:CanDraw()
return true
end
--- Called before each tick of NPC drawing,
--- just write custom drawing behavior in this function.
---
--- NPC每帧绘制前调用,在该函数内编写自定义绘制属性。
function GlobalNpc:OnDraw()
end
--- Called when NPC was killed.
---
--- NPC死亡时调用一次该函数。
function GlobalNpc:OnKilled()
end
--- Called when NPC collides the tiles.
---
--- NPC与图块碰撞时调用该函数。
--- @param oldSpeedX double The X speed before colliding tiles. (击中图块前一帧的横向速度)
--- @param oldSpeedY double The Y speed before colliding tiles. (击中图块前一帧的纵向速度)
function GlobalNpc:OnTileCollide(oldSpeedX, oldSpeedY)
end
function GlobalNpc:OnLoot()
end
---@return table
function GlobalNpc:Save()
end
---Load
---@param tagTable table
function GlobalNpc:Load(tagTable)
end
return GlobalNpc
================================================
FILE: apis/GlobalPlayer.lua
================================================
---@class GlobalPlayer
---@field player Player
local GlobalPlayer = {}
function GlobalPlayer:Awake()
end
--- This function is called once when the player is spawned.
---
--- 玩家生成时调用一次该函数。
function GlobalPlayer:Init()
end
---
---
--- 玩家每帧运行Update()函数前调用,如果返回true则执行所有Update逻辑,返回false则不执行所有Update逻辑。可在该函数写入新的逻辑,并屏蔽原有逻辑。默认返回true。
---@return boolean
function GlobalPlayer:CanUpdate()
return true
end
function GlobalPlayer:Motion()
end
--- Called when player runs every update tick, usually write logic in this function.
---
--- 玩家每帧运行时调用,通常在该函数内编写运动等逻辑。
function GlobalPlayer:Update()
end
--- Called before the player runs the `Update()` function every update tick.
--- It is usually used to insert new logic before the original logic.
---
--- 玩家每帧运行`Update()`函数前调用。通常用于在原逻辑前插入新逻辑。
function GlobalPlayer:PreUpdate()
end
--- Called after the player runs the `Update()` function every update tick.
--- It is usually used to insert new logic after the original logic.
---
--- 玩家每帧运行`Update()`函数后调用。通常用于追加逻辑。
function GlobalPlayer:PostUpdate()
end
--- If the player has a skeleton model,
--- it is called after `PostUpdate()` to process the logic of the custom skeleton model.
--- After executing this function, all joints of the skeleton model will be recalculated.
---
--- 若玩家拥有骨骼模型,每帧执行完`PostUpdate()`后调用,用于处理自定义骨骼模型逻辑。
--- 执行完该函数后,会对所有骨骼模型关节重新计算。
--- @param skeleton Skeleton Represents the skeleton model of the current 玩家. (当前玩家的骨骼模型)
function GlobalPlayer:UpdateSkeleton(skeleton)
end
--- Called before the player runs the `UpdateSkeleton(skeleton)` function every update tick.
--- It is usually used to insert new logic before the original logic.
---
--- 玩家每帧运行`UpdateSkeleton(skeleton)`函数前调用。通常用于在原逻辑前插入新逻辑。
--- @param skeleton Skeleton Represents the skeleton model of the current 玩家. (当前玩家的骨骼模型)
function GlobalPlayer:PreUpdateSkeleton(skeleton)
end
--- Called after the player runs the `UpdateSkeleton(skeleton)` function every update tick.
--- It is usually used to insert new logic after the original logic.
---
--- 玩家每帧运行`UpdateSkeleton(skeleton)`函数后调用。通常用于在原逻辑后追加新逻辑。
--- @param skeleton Skeleton Represents the skeleton model of the current 玩家. (当前玩家的骨骼模型)
function GlobalPlayer:PostUpdateSkeleton(skeleton)
end
---
---
--- 玩家每帧绘制前调用,如果返回true则执行所有Draw逻辑,返回false则不执行所有Draw逻辑。可在该函数写入新的逻辑,并屏蔽原有逻辑。默认返回true。
---@return boolean
function GlobalPlayer:CanDraw()
return true
end
--- Called before each tick of player drawing,
--- just write custom drawing behavior in this function.
---
--- 玩家每帧绘制前调用,在该函数内编写自定义绘制属性。
function GlobalPlayer:OnDraw()
end
--- Called when player was killed.
---
--- 玩家死亡时调用一次该函数。
function GlobalPlayer:OnKilled()
end
function GlobalPlayer:OnRespawn()
end
--- Called when player collides the tiles.
---
--- 玩家与图块碰撞时调用该函数。
--- @param oldSpeedX double The X speed before colliding tiles. (击中图块前一帧的横向速度)
--- @param oldSpeedY double The Y speed before colliding tiles. (击中图块前一帧的纵向速度)
function GlobalPlayer:OnTileCollide(oldSpeedX, oldSpeedY)
end
function GlobalPlayer:OnRender()
end
function GlobalPlayer:RecalculateProperties()
end
---OnHitByNpc
---@param npc Npc
function GlobalPlayer:OnHitByNpc(npc)
end
---OnHitByProjectile
---@param projectile Projectile
function GlobalPlayer:OnHitByProjectile(projectile)
end
function GlobalPlayer:OnFirstTimeJoin()
end
function GlobalPlayer:OnInventoryChanged()
end
---OnInventoryItemAdded
---@param itemID int
---@param stackSize int
function GlobalPlayer:OnInventoryItemAdded(itemID, stackSize)
end
---OnInventoryItemRemoved
---@param itemID int
---@param stackSize int
function GlobalPlayer:OnInventoryItemRemoved(itemID, stackSize)
end
---OnAdvancementMade
---@param advancementID int
function GlobalPlayer:OnAdvancementMade(advancementID)
end
---OnAdvancementRemoved
---@param advancementID int
function GlobalPlayer:OnAdvancementRemoved(advancementID)
end
---@return table
function GlobalPlayer:Save()
end
---Load
---@param tagTable table
function GlobalPlayer:Load(tagTable)
end
---@return table
function GlobalPlayer:SaveCSC()
end
---@param tagTable table
function GlobalPlayer:LoadCSC(tagTable)
end
return GlobalPlayer
================================================
FILE: apis/GuiContainer.lua
================================================
---@class GuiContainer
---@field container Container
local GuiContainer = {}
---__init
---@param container Container
function GuiContainer:__init(container)
end
function GuiContainer:OnUpdate()
end
function GuiContainer:OnClose()
end
---TriggerClientEvent
---@overload fun(eventId:int)
---@param eventId int
---@param eventString string
function GuiContainer:TriggerClientEvent(eventId, eventString)
end
---TriggerServerEvent
---@overload fun(eventId:int)
---@param eventId int
---@param eventString string
function GuiContainer:TriggerServerEvent(eventId, eventString)
end
return GuiContainer
================================================
FILE: apis/Hitbox.lua
================================================
-- Document
-- Hitbox Class: https://blueyoshi.gitbook.io/terracraft/en/mod/api/type#hitbox
--
-- Hitbox类: https://blueyoshi.gitbook.io/terracraft/cn/mod/api/type#hitbox
--
-- Copyright (c) 2021. BlueYoshi(blueyoshi@foxmail.com)
---@class Hitbox Represents a collision box. If the angle attribute is 0, it means axis aligned collision box (AABB). Otherwise, it represents a collision box rotating around the center point. (表示一个碰撞箱。若angle属性为0,表示轴对齐碰撞箱(AABB)。否则表示一个绕中心点旋转的碰撞箱。)
---@field x double The x coordinate of the upper left corner of the hitbox when the rotation angle is 0. (碰撞箱在旋转角度为0时左上角x坐标)
---@field y double The y coordinate of the upper left corner of the hitbox when the rotation angle is 0. (碰撞箱在旋转角度为0时左上角y坐标)
---@field width int The width of the hitbox. (碰撞箱宽度)
---@field height int The height of the hitbox. (碰撞箱高度)
---@field centerX double @[ Read-only ] Returns the center x coordinate of the hitbox. (返回碰撞箱正中间x坐标)
---@field centerY double @[ Read-only ] Returns the center y coordinate of the hitbox. (返回碰撞箱正中间y坐标)
---@field angle double @[ Read-only ] Returns the rotation angle of the collision box if the collision box can be rotated. (若碰撞箱可以旋转,表示碰撞箱的旋转角度)
local Hitbox = {}
--- Returns whether the current hitbox overlaps with another hitbox.
---
--- 返回当前碰撞箱与另一个碰撞箱是否重叠。
---@param other Hitbox The other hitbox. (另一个碰撞箱)
---@return boolean
function Hitbox:Overlap(other)
end
--- Returns whether the current axis-aligned rectangle overlaps with another axis-aligned rectangle.
---
--- 返回当前轴对齐矩形与另一个轴对齐矩形是否重叠。
---@param other Hitbox The other hitbox. (另一个碰撞箱)
---@return boolean
function Hitbox:OverlapAABB(other)
end
return Hitbox
================================================
FILE: apis/Inventory.lua
================================================
---@API
---@class Inventory 描述物品格子集合。
---@field slotCount int 物品格子的总数。
local Inventory = {}
---场景一个物品格子集合对象。
---@param slotCount int 物品格子的总数。
---@return Inventory 新的物品格子集合对象。
function Inventory.new(slotCount)
end
---判断当前物品格子集合对象是否有效。
---@return boolean
function Inventory:Valid()
end
---改变格子数量,若新增了格子,则格子将默认为空格子。
---@param count int 新的格子总数。
function Inventory:SetSlotCount(count)
end
---由格子索引获取格子对象。
---@param index int 格子索引。
---@return Slot 物品格子对象。
function Inventory:GetSlot(index)
end
---往当前集合加入一组堆叠物品。
---@param itemStack ItemStack 堆叠物品。
---@return ItemStack 当放入堆叠物品后导致集合满时,返回未能放入的堆叠物品。如果能完全放入,则返回无效ItemStack。
function Inventory:AddItemStack(itemStack)
end
---为当前集合的所有物品格子进行排序。
function Inventory:SortAll()
end
---为当前集合的指定格子范围进行排序。
---@param index int 格子范围起始索引。
---@param count int 待排序的格子总数。
function Inventory:Sort(index, count)
end
---将当前集合的指定格子范围内的物品快速转移到另一个物品格子集合的指定范围。
---@overload fun(start:int,slotCount:int,inventoryTo:Inventory,inventoryToStart:int,inventoryToSlotCount:int)
---@param start int 当前集合待转移的格子范围起始索引。
---@param slotCount int 当前集合待转移的格子总数。
---@param inventoryTo Inventory 将要转移到的格子集合对象。
---@param inventoryToStart int 将要转移到的格子集合对象的格子范围起始索引。
---@param inventoryToSlotCount int 将要转移到的格子集合对象的格子总数。
---@param pushSameItemOnly boolean
function Inventory:QuickPushAllTo(start, slotCount, inventoryTo, inventoryToStart, inventoryToSlotCount, pushSameItemOnly)
end
---序列化得到lua表。
---@return table lua表。
function Inventory:Serialization()
end
---由lua表反序列化得到当前物品格子集合对象。
---@param serializedTable table lua表。
function Inventory:Deserialization(serializedTable)
end
return Inventory
================================================
FILE: apis/Item.lua
================================================
---@class Item
---@field id int
---@field idName string
---@field mod Mod
---@field type ItemType_Value
---@field maxStackSize int
---@field groupID int
---@field isBlock boolean
---@field isTool boolean
---@field isMaterial boolean
---@field isProjectile boolean
---@field isWire boolean
---@field toolType string
---@field iconTextureLocation TextureLocation
---@field entityTextureLocation TextureLocation
---@field iconColor Color
---@field iconColor2 Color
---@field iconColor3 Color
---@field iconColor4 Color
---@field iconColor5 Color
---@field iconColor6 Color
---@field maxDurable int
---@field coldTime int
---@field entityWidth int
---@field entityHeight int
---@field entityOffsetX int
---@field entityOffsetY int
---@field handX int
---@field handY int
---@field hasEntity boolean
---@field oreDictionaryIDs int[]
---@field toolGrade int
---@field toolGradeName string
---@field firePointCount int
---@field usePosture int
---@field twoHands boolean
---@field ammoID int
---@field ammoLevel int
---@field shootProjectileID int
---@field projectileID int
---@field fuelTime int
---@field fuelReturnItemID int
---@field isSeed boolean
---@field shootable boolean
---@field shootTimes int
---@field blockID int
---@field wireID int
---@field efficiency double
---@field noConsumeChance double
---@field deviation double
---@field speed double
---@field showHair boolean
---@field canThrow boolean
---@field baseAttack Attack
---@field defense int
---@field useSoundID int
---@field useSoundGroupID int
---@field eatable boolean
---@field buffs Buff[]
---@field enchantments Enchantment[]
---@field addHealth int
---@field addMagic int
---@field addMaxMagic int
---@field food int
---@field foodSaturation int
---@field consumeMana int
local Item = {}
---GetFirePoint
---@param index int
---@return Vector2
function Item:GetFirePoint(index)
end
return Item
================================================
FILE: apis/ItemRegistry.lua
================================================
---@class ItemRegistry
local ItemRegistry = {}
---GetItemByID
---@param id int
---@return Item
function ItemRegistry.GetItemByID(id)
end
---GetItemByIDName
---@param idName string
---@return Item
function ItemRegistry.GetItemByIDName(idName)
end
return ItemRegistry
================================================
FILE: apis/ItemStack.lua
================================================
---@API
---@class ItemStack 描述一组堆叠物品。
---@field stackSize int Read-only 当前堆叠数量。
---@field durable double 当前物品耐久。
---@field enchantmentCount int 当前堆叠物品挂接的附魔数量。
local ItemStack = {}
---创建一个堆叠物品对象。
---
---[Example]
-----创建堆叠234个由钻石的堆叠物品对象。
---local itemStackDiamond = ItemStack.new(ItemRegistry.GetItemByID("diamond"), 234)
-----创建一个铁剑堆叠物品对象。
---local itemStackSword = ItemStack.new(ItemRegistry.GetItemByID("iron_sword"))
---
---@overload fun(item:Item):ItemStack
---@param item Item 物品。
---@param stackSize int 堆叠数量。
---@return ItemStack 新的堆叠物品对象。
function ItemStack.new(item, stackSize)
end
---判断当前堆叠物品数据是否有效。
function ItemStack:Valid()
end
---为当前堆叠物品新增一项附魔。
---@param enchantmentId int 附魔ID。
---@param enchantmentLevel int 附魔等级。
---@return boolean 新增附魔是否有变化,当且仅当之前已经存在附魔且新增附魔等级小于之前等级则无变化。
function ItemStack:AddEnchantment(enchantmentId, enchantmentLevel)
end
---克隆返回一个新的堆叠物品对象。
---@overload fun():ItemStack
---@param stackSize int 新的堆栈数量。
---@return ItemStack 新的堆叠物品对象。
function ItemStack:Clone(stackSize)
end
---设置堆栈数量。
function ItemStack:SetStackSize(value)
end
---增加耐久值。
function ItemStack:AddDurable(value)
end
---直接设置耐久值。
function ItemStack:SetDurable(value)
end
---减少耐久值。
---@return boolean 减少后耐久是否为0。
function ItemStack:LoseDurable(value)
end
---获取当前堆栈物品指定附魔的等级。
---@param enchantmentId int 附魔ID。
---@return int 附魔等级。
function ItemStack:GetEnchantmentLevel(enchantmentId)
end
---判断当前堆叠物品是否拥有了指定附魔。
---@overload fun():boolean
---@param enchantmentId int 附魔ID。
---@return boolean
function ItemStack:HasEnchantment(enchantmentId)
end
---由附魔索引得到附魔对象。
---@param index int 附魔索引。
---@return Enchantment 附魔对象。
function ItemStack:GetEnchantmentByIndex(index)
end
---由附魔索引删除附魔对象。
---@param index int 附魔索引。
function ItemStack:RemoveEnchantmentByIndex(index)
end
---由附魔ID删除一个附魔对象。
---@param enchantmentID int 附魔ID。
function ItemStack:RemoveEnchantment(enchantmentID)
end
---清空所有附魔。
function ItemStack:ClearEnchantments()
end
---判断当前堆叠物品的物品数据是否与另一个堆叠物品的物品数据相同。
---@param itemStack ItemStack 另一个堆叠物品。
---@return boolean
function ItemStack:IsItemEqual(itemStack)
end
---判断当前堆叠物品是否与另一个堆叠物品相同。
---@overload fun(itemStack:ItemStack):boolean
---@param itemStack ItemStack 另一个堆叠物品。
---@param ignoreStackSize boolean 是否忽略堆叠物品数量判断。
---@return boolean
function ItemStack:IsItemStackEqual(itemStack, ignoreStackSize)
end
---返回当前堆叠物品与另一个堆叠物品可合并的数量。
---@param itemStack ItemStack 另一个堆叠物品。
---@return int
function ItemStack:GetMergeCount(itemStack)
end
---拆分当前堆叠物品,返回新的拆出来的堆叠物品对象。
---@param count int 拆出来的堆叠数量。
---@return ItemStack 新的拆出来的堆叠物品对象。
function ItemStack:SplitStack(count)
end
---获得当前堆叠物品的物品数据。
---@return Item
function ItemStack:GetItem()
end
---绘制当前堆叠物品。
---@param position Vector2
---@param color Color
---@param spriteExData SpriteExData
function ItemStack:Render(position, color, spriteExData)
end
---绘制当前堆叠物品的堆叠数量。
---@param position Vector2
---@param color Color
---@param spriteExData SpriteExData
function ItemStack:RenderNum(position, color, spriteExData)
end
---自定义绘制当前堆叠物品的堆叠数量。
---@param num int
---@param position Vector2
---@param color Color
---@param spriteExData SpriteExData
function ItemStack:RenderCustomNum(num, position, color, spriteExData)
end
---执行堆叠物品挂接ModItem的`OnHeld`函数。
---@param player Player 玩家
function ItemStack:RunOnHeldEvent(player)
end
---执行堆叠物品挂接ModItem的`OnHeldRender`函数。
---@param player Player 玩家
function ItemStack:RunOnHeldRenderEvent(player)
end
---执行堆叠物品挂接ModItem的`OnHeld`函数。
---@param npc Npc
function ItemStack:RunOnHeldByNpcEvent(npc)
end
---返回当前堆叠物品是否能被玩家使用。
---@param player Player 玩家
---@return boolean
function ItemStack:CanUse(player)
end
---执行堆叠物品挂接ModItem的`OnUsed`函数。
---@param player Player 玩家
function ItemStack:RunOnUsedEvent(player)
end
---执行堆叠物品挂接ModItem的`OnUsedByNpc`函数。
---@param npc Npc
function ItemStack:RunOnUsedByNpcEvent(npc)
end
---执行堆叠物品挂接ModItem的`OnDurableEmpty`函数。
---@param player Player 玩家
---@return boolean
function ItemStack:RunOnDurableEmptyEvent(player)
end
---序列化得到lua表。
---@return table lua表。
function ItemStack:Serialization()
end
---由lua表反序列化创建一个堆叠物品对象。
---@param serializedTable table lua表。
---@return ItemStack 新的堆叠物品对象。
function ItemStack.Deserialization(serializedTable)
end
---返回当前堆叠物品挂接的ModItem对象。
---@return ModItem 挂接的ModItem对象,如果无挂接,返回nil。
function ItemStack:GetModItem()
end
return ItemStack
================================================
FILE: apis/ItemType.lua
================================================
---@class ItemType_Value
---@class ItemType
---@field Block ItemType_Value
---@field Tool ItemType_Value
---@field Material ItemType_Value
---@field Projectile ItemType_Value
---@field Wire ItemType_Value
local ItemType = {}
return ItemType
================================================
FILE: apis/ItemUtils.lua
================================================
---@class ItemUtils
---@field maxRootGroupCount int
local ItemUtils = {}
---CreateDrop
---@overload fun(itemStack:ItemStack, centerX:double, centerY:double)
---@overload fun(itemStack:ItemStack, centerX:double, centerY:double, speedX:double, speedY:double)
---@param itemStack ItemStack
---@param centerX double
---@param centerY double
---@param speedX double
---@param speedY double
---@param coldTime int
function ItemUtils.CreateDrop(itemStack, centerX, centerY, speedX, speedY, coldTime)
end
---GetOreDictionaryItemIDs
---@param oreDictionaryID int
---@return int[]
function ItemUtils.GetOreDictionaryItemIDs(oreDictionaryID)
end
---GetGroupItemIDs
---@param itemGroupID int
---@return int[]
function ItemUtils.GetGroupItemIDs(itemGroupID)
end
---GetGroupIDsFromRootID
---@param rootGroupID int
---@return int[]
function ItemUtils.GetGroupIDsFromRootID(rootGroupID)
end
---GetRootGroupIconItemID
---@param rootGroupID int
---@return int
function ItemUtils.GetRootGroupIconItemID(rootGroupID)
end
return ItemUtils
================================================
FILE: apis/JoinData.lua
================================================
---@class JoinData
---@field playerName string
---@field worldName string
---@field address string
---@field port int
---@field multiplayer boolean
local JoinData = {}
---@return JoinData
function JoinData.new()
end
return JoinData
================================================
FILE: apis/LangUtils.lua
================================================
---@class LangUtils
local LangUtils = {}
---
---@param itemID int
---@return string
function LangUtils.ItemName(itemID)
end
---
---@param itemID int
---@return string
function LangUtils.ItemIntroduction(itemID)
end
---
---@param buffID int
---@return string
function LangUtils.BuffName(buffID)
end
---EnchantmentName
---@param enchantmentID int
---@return string
function LangUtils.EnchantmentName(enchantmentID)
end
---NpcName
---@param npcID int
---@return string
function LangUtils.NpcName(npcID)
end
---AdvancementName
---@param advancementID int
---@return string
function LangUtils.AdvancementName(advancementID)
end
---AdvancementDescription
---@param advancementID int
---@return string
function LangUtils.AdvancementDescription(advancementID)
end
return LangUtils
================================================
FILE: apis/LightingUtils.lua
================================================
---@class LightingUtils
local LightingUtils = {}
---Add
---@overload fun(xi:int,yi:int,alpha:int)
---@overload fun(xi:int,yi:int,alpha:int,red:int)
---@overload fun(xi:int,yi:int,alpha:int,red:int,green:int)
---@overload fun(xi:int,yi:int,alpha:int,red:int,green:int,blue:int)
---@param xi int
---@param yi int
---@param alpha int
---@param red int
---@param green int
---@param blue int
function LightingUtils.Add(xi, yi, alpha, red, green, blue)
end
---AddDelay
---@overload fun(xi:int,yi:int,delayTime:int,alpha:int)
---@overload fun(xi:int,yi:int,delayTime:int,alpha:int,red:int)
---@overload fun(xi:int,yi:int,delayTime:int,alpha:int,red:int,green:int)
---@overload fun(xi:int,yi:int,delayTime:int,alpha:int,red:int,green:int,blue:int)
---@param xi int
---@param yi int
---@param delayTime int
---@param alpha int
---@param red int
---@param green int
---@param blue int
function LightingUtils.AddDelay(xi, yi, delayTime, alpha, red, green, blue)
end
return LightingUtils
================================================
FILE: apis/MapPos.lua
================================================
---@class MapPos
---@field xi int
---@field yi int
local MapPos = {}
return MapPos
================================================
FILE: apis/MapUtils.lua
================================================
---@class MapUtils
local MapUtils = {}
---IsValid
---@param xi int
---@param yi int
---@return boolean
function MapUtils.IsValid(xi, yi)
end
---IsAreaValid
---@param xi int
---@param yi int
---@param width int
---@param height int
---@return boolean
function MapUtils.IsAreaValid(xi, yi, width, height)
end
---IsSolid
---@param xi int
---@param yi int
---@return boolean
function MapUtils.IsSolid(xi, yi)
end
---HasFront
---@param xi int
---@param yi int
---@return boolean
function MapUtils.HasFront(xi, yi)
end
---GetFrontID
---@param xi int
---@param yi int
---@return int
function MapUtils.GetFrontID(xi, yi)
end
---GetFrontCenterXY
---@param xi int
---@param yi int
---@return double,double
function MapUtils.GetFrontCenterXY(xi, yi)
end
---@param xi int
---@param yi int
---@return int,int
function MapUtils.GetBodyPos(xi, yi)
end
---GetFrontIDTag
---@param xi int
---@param yi int
---@return int,int
function MapUtils.GetFrontIDTag(xi, yi)
end
---CanSetFrontTag
---@param xi int
---@param yi int
---@return boolean
function MapUtils.CanSetFrontTag(xi, yi)
end
---SetFrontTag
---@param xi int
---@param yi int
---@param tag int
---@return boolean
function MapUtils.SetFrontTag(xi, yi, tag)
end
---CanSetFront
---@overload fun(xi:int, yi:int, frontID:int):boolean
---@overload fun(xi:int, yi:int, frontID:int, isDestroyFragile:boolean):boolean
---@param xi int
---@param yi int
---@param frontID int
---@param isDestroyFragile boolean
---@param isCheckingEntities boolean
---@return boolean
function MapUtils.CanSetFront(xi, yi, frontID, isDestroyFragile, isCheckingEntities)
end
---SetFront
---@overload fun(xi:int, yi:int, frontID:int):boolean
---@overload fun(xi:int, yi:int, frontID:int, isDestroyFragile:boolean):boolean
---@overload fun(xi:int, yi:int, frontID:int, isDestroyFragile:boolean, showEffect:boolean):boolean
---@param xi int
---@param yi int
---@param frontID int
---@param isDestroyFragile boolean
---@param showEffect boolean
---@param playSound boolean
---@return boolean
function MapUtils.SetFront(xi, yi, frontID, isDestroyFragile, showEffect, playSound)
end
---CanPlaceFront
---@overload fun(xi:int, yi:int, frontID:int):boolean
---@overload fun(xi:int, yi:int, frontID:int, isDestroyFragile:boolean):boolean
---@param xi int
---@param yi int
---@param frontID int
---@param isDestroyFragile boolean
---@param isCheckingEntities boolean
---@return boolean
function MapUtils.CanPlaceFront(xi, yi, frontID, isDestroyFragile, isCheckingEntities)
end
---PlaceFront
---@overload fun(xi:int, yi:int, frontID:int):boolean
---@overload fun(xi:int, yi:int, frontID:int, isDestroyFragile:boolean):boolean
---@overload fun(xi:int, yi:int, frontID:int, isDestroyFragile:boolean, showEffect:boolean):boolean
---@param xi int
---@param yi int
---@param frontID int
---@param isDestroyFragile boolean
---@param showEffect boolean
---@param playSound boolean
---@return boolean
function MapUtils.PlaceFront(xi, yi, frontID, isDestroyFragile, showEffect, playSound)
end
---RemoveFront
---@overload fun(xi:int, yi:int):boolean
---@overload fun(xi:int, yi:int, showEffect:boolean):boolean
---@param xi int
---@param yi int
---@param showEffect boolean
---@param playSound boolean
---@return boolean
function MapUtils.RemoveFront(xi, yi, showEffect, playSound)
end
---RemoveFrontAndDrop
---@overload fun(xi:int, yi:int):boolean
---@overload fun(xi:int, yi:int, isDropOriginal:boolean):boolean
---@overload fun(xi:int, yi:int, isDropOriginal:boolean, dropFortune:int):boolean
---@overload fun(xi:int, yi:int, isDropOriginal:boolean, dropFortune:int, showEffect:boolean):boolean
---@param xi int
---@param yi int
---@param isDropOriginal boolean
---@param dropFortune int
---@param showEffect boolean
---@param playSound boolean
---@return boolean
function MapUtils.RemoveFrontAndDrop(xi, yi, isDropOriginal, dropFortune, showEffect, playSound)
end
---HasWall
---@param xi int
---@param yi int
---@return boolean
function MapUtils.HasWall(xi, yi)
end
---GetWallID
---@param xi int
---@param yi int
---@return int
function MapUtils.GetWallID(xi, yi)
end
---CanSetWall
---@param xi int
---@param yi int
---@param wallID int
---@return boolean
function MapUtils.CanSetWall(xi, yi, wallID)
end
---SetWall
---@overload fun(xi:int,yi:int,id:int):boolean
---@overload fun(xi:int,yi:int,id:int,showEffect:boolean):boolean
---@overload fun(xi:int,yi:int,id:int,showEffect:boolean,playSound:boolean):boolean
---@param xi int
---@param yi int
---@param id int
---@param showEffect boolean
---@param playSound boolean
---@return boolean
function MapUtils.SetWall(xi, yi, id, showEffect, playSound)
end
---CanPlaceWall
---@param xi int
---@param yi int
---@param wallID int
---@return boolean
function MapUtils.CanPlaceWall(xi, yi, wallID)
end
---PlaceWall
---@overload fun(xi:int,yi:int,id:int):boolean
---@overload fun(xi:int,yi:int,id:int,showEffect:boolean):boolean
---@overload fun(xi:int,yi:int,id:int,showEffect:boolean,playSound:boolean):boolean
---@param xi int
---@param yi int
---@param id int
---@param showEffect boolean
---@param playSound boolean
---@return boolean
function MapUtils.PlaceWall(xi, yi, id, showEffect, playSound)
end
---RemoveWall
---@overload fun(xi:int,yi:int):boolean
---@overload fun(xi:int,yi:int,showEffect:boolean):boolean
---@param xi int
---@param yi int
---@param showEffect boolean
---@param playSound boolean
function MapUtils.RemoveWall(xi, yi, showEffect, playSound)
end
---RemoveWallAndDrop
---@overload fun(xi:int, yi:int):boolean
---@overload fun(xi:int, yi:int, isDropOriginal:boolean):boolean
---@overload fun(xi:int, yi:int, isDropOriginal:boolean, dropFortune:int):boolean
---@overload fun(xi:int, yi:int, isDropOriginal:boolean, dropFortune:int, showEffect:boolean):boolean
---@param xi int
---@param yi int
---@param isDropOriginal boolean
---@param dropFortune int
---@param showEffect boolean
---@param playSound boolean
---@return boolean
function MapUtils.RemoveWallAndDrop(xi, yi, isDropOriginal, dropFortune, showEffect, playSound)
end
---HasLiquid
---@param xi int
---@param yi int
---@return boolean
function MapUtils.HasLiquid(xi, yi)
end
---GetLiquidID
---@param xi int
---@param yi int
---@return int
function MapUtils.GetLiquidID(xi, yi)
end
---GetLiquidIDAmount
---@param xi int
---@param yi int
---@return int,int
function MapUtils.GetLiquidIDAmount(xi, yi)
end
---SetLiquid
---@overload fun(xi:int,yi:int,liquidID:int):boolean
---@param xi int
---@param yi int
---@param liquidID int
---@param amount int
---@return boolean
function MapUtils.SetLiquid(xi, yi, liquidID, amount)
end
---RemoveLiquid
---@param xi int
---@param yi int
---@return boolean
function MapUtils.RemoveLiquid(xi, yi)
end
---TriggerLiquid
---@param xi int
---@param yi int
function MapUtils.TriggerLiquid(xi, yi)
end
---TriggerSignal
---@param xi int
---@param yi int
---@param isTurningOn boolean
---@return boolean
function MapUtils.TriggerSignal(xi, yi, isTurningOn)
end
---DelayTriggerSignal
---@param xi int
---@param yi int
---@param isTurningOn boolean
---@param delayTicks int
---@return boolean
function MapUtils.DelayTriggerSignal(xi, yi, isTurningOn, delayTicks)
end
---GetBlockEntity
---@param blockEntityID int
---@param xi int
---@param yi int
---@return BlockEntity
function MapUtils.GetBlockEntity(blockEntityID, xi, yi)
end
---CreateBlockEntity
---@param blockEntityID int
---@param xi int
---@param yi int
function MapUtils.CreateBlockEntity(blockEntityID,xi,yi)
end
---WeaponCollideWithMap
---@param obb ObbDouble
---@param isDestroyByWeapon boolean
---@return boolean,boolean
function MapUtils.WeaponCollideWithMap(obb, isDestroyByWeapon)
end
---PlayAnimation
---@param xi int
---@param yi int
---@param startFrameIndex int
---@param totalFrames int
---@param frameSpeed int
---@param isPositiveDirection boolean
function MapUtils.PlayAnimation(xi, yi, startFrameIndex, totalFrames, frameSpeed, isPositiveDirection)
end
---SetAnimationIndex
---@param xi int
---@param yi int
---@param animationIndex int
function MapUtils.SetAnimationIndex(xi, yi, animationIndex)
end
---SyncUnit
---@param xi int
---@param yi int
function MapUtils.SyncUnit(xi, yi)
end
---SetWireVisible
---@param visible boolean
function MapUtils.SetWireVisible(visible)
end
---IsWireVisible
---@return boolean
function MapUtils.IsWireVisible()
end
---HasWire
---@param xi int
---@param yi int
---@return boolean
function MapUtils.HasWire(xi, yi)
end
---GetWireID
---@param xi int
---@param yi int
---@return int
function MapUtils.GetWireID(xi, yi)
end
---SetWire
---@param xi int
---@param yi int
---@param wireID int
---@return boolean
function MapUtils.SetWire(xi, yi, wireID)
end
---RemoveWire
---@param xi int
---@param yi int
---@return boolean
function MapUtils.RemoveWire(xi, yi)
end
---RemoveWireAndDrop
---@overload fun(xi:int,yi:int):boolean
---@param xi int
---@param yi int
---@param playSound boolean
---@return boolean
function MapUtils.RemoveWireAndDrop(xi, yi, playSound)
end
---SetWireActivate
---@param xi int
---@param yi int
---@param activated boolean
function MapUtils.SetWireActivate(xi, yi, activated)
end
---DoRandomTick
---@param xi int
---@param yi int
function MapUtils.DoRandomTick(xi, yi)
end
---SetRenderPreview
---@param blockID int
---@param xi int
---@param yi int
---@param canPlace boolean
---@param playerCenterX double
---@param playerCenterY double
function MapUtils.SetBlockRenderPreview(blockID, centerX, centerY, canPlace, playerCenterX, playerCenterY)
end
function MapUtils.ClearBlockRenderPreview()
end
return MapUtils
================================================
FILE: apis/MiscUtils.lua
================================================
---@class MiscUtils
---@field screenX double
---@field screenY double
---@field screenWidth int
---@field screenHeight int
---@field inGame boolean
---@field isSinglePlayerMode boolean
---@field isNight boolean
local MiscUtils = {}
---CreateExplosion
---@overload fun(xi:int, yi:int, power:double, hurtNpc:boolean, hurtPlayer:boolean)
---@overload fun(xi:int, yi:int, power:double, hurtNpc:boolean, hurtPlayer:boolean, killTiles:boolean)
---@overload fun(xi:int, yi:int, power:double, hurtNpc:boolean, hurtPlayer:boolean, killTiles:boolean, killBack:boolean)
---@overload fun(xi:int, yi:int, power:double, hurtNpc:boolean, hurtPlayer:boolean, killTiles:boolean, killBack:boolean, makeSound:boolean)
---@param xi int
---@param yi int
---@param power double
---@param hurtNpc boolean
---@param hurtPlayer boolean
---@param killTiles boolean
---@param killBack boolean
---@param makeSound boolean
---@param tileLimit int
function MiscUtils.CreateExplosion(xi, yi, power, hurtNpc, hurtPlayer, killTiles, killBack, makeSound, tileLimit)
end
---UnicastUTF8
---@param player Player
---@param message string
function MiscUtils.UnicastUTF8(player, message)
end
---BroadcastUTF8
---@param message string
function MiscUtils.BroadcastUTF8(message)
end
---SetDayTime
---@param dayTime int
function MiscUtils.SetDayTime(dayTime)
end
---GetDayTime
---@return int
function MiscUtils.GetDayTime()
end
---SetDaySpeed
---@param daySpeed int
function MiscUtils.SetDaySpeed(daySpeed)
end
---@return int
function MiscUtils.GetDaySpeed()
end
---SetWeatherTime
---@param weatherTime int
function MiscUtils.SetWeatherTime(weatherTime)
end
---@return int
function MiscUtils.GetWeatherTime()
end
---SetDayTimeFormat
---@param hours int
---@param minutes int
---@param seconds int
function MiscUtils.SetDayTimeFormat(hours, minutes, seconds)
end
---@return int,int,int
function MiscUtils.GetDayTimeFormat()
end
---RayDistance
---@overload fun(fromX:double, fromY:double, shootAngle:double):double
---@param fromX double
---@param fromY double
---@param shootAngle double
---@param maxDistance int
---@return double
function MiscUtils.RayDistance(fromX, fromY, shootAngle, maxDistance)
end
---RayReach
---@param fromX double
---@param fromY double
---@param toX double
---@param toY double
---@return boolean
function MiscUtils.RayReach(fromX, fromY, toX, toY)
end
function MiscUtils.SaveAll()
end
---SetAutoSaveEnabled
---@param enabled boolean
function MiscUtils.SetAutoSaveEnabled(enabled)
end
---GetPortNumber
---@return int
function MiscUtils.GetPortNumber()
end
---SetPVP
---@param enabled boolean
function MiscUtils.SetPVP(enabled)
end
---GetPVP
---@return boolean
function MiscUtils.GetPVP()
end
---SetSafeBlow
---@param enabled boolean
function MiscUtils.SetSafeBlow(enabled)
end
---GetSafeBlow
---@return boolean
function MiscUtils.GetSafeBlow()
end
---SetGameMode
---@param gameMode int
function MiscUtils.SetGameMode(gameMode)
end
---GetGameMode
---@return int
function MiscUtils.GetGameMode()
end
---@return Player[]
function MiscUtils.GetOnlinePlayerList()
end
---KickPlayer
---@param playerName string
function MiscUtils.KickPlayer(playerName)
end
---KickAllPlayers
function MiscUtils.KickAllPlayers()
end
---@return string[]
function MiscUtils.GetBlackList()
end
---Ban
---@param ip string
function MiscUtils.Ban(ip)
end
---RemoveBan
---@param id string
function MiscUtils.RemoveBan(id)
end
---AddTips
---@param x double
---@param y double
---@param tipsText string
---@param color Color
function MiscUtils.AddTips(x, y, tipsText, color)
end
---@return double
function MiscUtils.GetMapDisplayScale()
end
---SetMapDisplayScale
---@param scale double
function MiscUtils.SetMapDisplayScale(scale)
end
return MiscUtils
================================================
FILE: apis/Mod.lua
================================================
---@class Mod 描述一个模组,维护模组的基本信息。
---@field modId string 模组的命名空间。
---@field displayName string 模组显示名称。
---@field version string 模组版本号。
---@field gameVersion string 游戏版本号。
---@field assetRootPath string 模组文件夹在assets系统中的文件夹根目录。
---@field current Mod 返回当前执行的脚本环境的模组。
---@field serverBoundPacket ServerBoundPacket
---@field clientBoundPacket ClientBoundPacket
---@field registry Registry
---@field modList Array
local Mod = {}
---RegisterClientGuiLoaderCallback
---@param callback function|table
---@return ListenerID
function Mod:RegisterClientGuiLoaderCallback(callback)
end
---@param callback function|table
---@return ListenerID
function Mod:RegisterServerGuiLoaderCallback(callback)
end
---RegisterClientGuiLoaderCallback
---@param callback function|table
---@return ListenerID
function Mod:RegisterClientBoundReaderCallback(callback)
end
---@param callback function|table
---@return ListenerID
function Mod:RegisterServerBoundReaderCallback(callback)
end
---@param callback function|table
---@return ListenerID
function Mod:RegisterWorldServerLoader(callback)
end
---@param callback function|table
---@return ListenerID
function Mod:RegisterWorldServerSaver(callback)
end
---通过模组命名空间,返回已加载模组。
---@param modID string 模组的命名空间。
---@return nil|Mod 已加载的模组,如果模组不存在,返回nil。
function Mod.GetByID(modID)
end
return Mod
================================================
FILE: apis/ModBlock.lua
================================================
---@class ModBlock
local ModBlock = {}
---OnPlayerCollide
---@param xi int
---@param yi int
---@param player Player
---@param collisionDirection int
function ModBlock.OnPlayerCollide(xi, yi, player, collisionDirection)
end
---OnPlayerOverlap
---@param xi int
---@param yi int
---@param player Player
function ModBlock.OnPlayerOverlap(xi, yi, player)
end
---UpdateScreen
---@param xi int
---@param yi int
---@param tickTime int
function ModBlock.UpdateScreen(xi, yi, tickTime)
end
---RenderFurniture
---@param xi int
---@param yi int
---@param tickTime int
function ModBlock.RenderFurniture(xi, yi, tickTime)
end
---PreRenderFurniture
---@param xi int
---@param yi int
---@param tickTime int
function ModBlock.PreRenderFurniture(xi, yi, tickTime)
end
---PostRenderFurniture
---@param xi int
---@param yi int
---@param tickTime int
function ModBlock.PostRenderFurniture(xi, yi, tickTime)
end
---OnRandomTick
---@param xi int
---@param yi int
function ModBlock.OnRandomTick(xi, yi)
end
---OnPlaced
---@param xi int
---@param yi int
function ModBlock.OnPlaced(xi, yi)
end
---OnClicked
---@param xi int
---@param yi int
---@param parameterClick ParameterClick
function ModBlock.OnClicked(xi, yi, parameterClick)
end
---OnSignal
---@param xi int
---@param yi int
---@param isActivated boolean
function ModBlock.OnSignal(xi, yi, isActivated)
end
---OnDestroy
---@param xi int
---@param yi int
---@param parameterDestroy ParameterDestroy
function ModBlock.OnDestroy(xi, yi, parameterDestroy)
end
return ModBlock
================================================
FILE: apis/ModBlockEntity.lua
================================================
---@class ModBlockEntity
---@field blockEntity BlockEntity
local ModBlockEntity = {}
function ModBlockEntity:OnPlaced()
end
function ModBlockEntity:Init()
end
function ModBlockEntity:CanUpdate()
end
function ModBlockEntity:Update()
end
---OnKilled
---@param parameterDestroy ParameterDestroy
function ModBlockEntity:OnKilled(parameterDestroy)
end
---OnClicked
---@param parameterClick ParameterClick
function ModBlockEntity:OnClicked(parameterClick)
end
function ModBlockEntity:OnActivated(isActive)
end
---@return table
function ModBlockEntity:Save()
end
---Load
---@param tagTable table
function ModBlockEntity:Load(tagTable)
end
return ModBlockEntity
================================================
FILE: apis/ModItem.lua
================================================
---@class ModItem
---@field itemStack ItemStack
local ModItem = {}
function ModItem:Init()
end
---DrawIcon
---@param position Vector2
---@param color Color
---@param spriteExData SpriteExData
function ModItem:DrawIcon(position, color, spriteExData)
end
---OnHeld
---@param player Player
function ModItem:OnHeld(player)
end
---OnHeldRender
---@param player Player
function ModItem:OnHeldRender(player)
end
---OnUsed
---@param player Player
function ModItem:OnUsed(player)
end
---CanUse
---@param player Player
---@return boolean
function ModItem:CanUse(player)
end
---OnHeldByNpc
---@param npc Npc
function ModItem:OnHeldByNpc(npc)
end
---OnUsedByNpc
---@param npc Npc
function ModItem:OnUsedByNpc(npc)
end
---ModifyHitNpc
---@param npc Npc
---@param baseAttack Attack
---@return boolean
function ModItem:ModifyHitNpc(npc, baseAttack)
end
---ModifyHitPlayer
---@param player Player
---@param baseAttack Attack
---@return boolean
function ModItem:ModifyHitPlayer(player, baseAttack)
end
---Load
---@param tagTable table
function ModItem:Load(tagTable)
end
---@return table
function ModItem:Save()
end
return ModItem
================================================
FILE: apis/ModNpc.lua
================================================
---@class ModNpc
---@field npc Npc
---@field syncData table
local ModNpc = {}
--- This function is called once when the NPC is spawned.
---
--- NPC生成时调用一次该函数。
function ModNpc:Init()
end
---
---
--- NPC每帧运行Update()函数前调用,如果返回true则执行所有Update逻辑,返回false则不执行所有Update逻辑。可在该函数写入新的逻辑,并屏蔽原有逻辑。默认返回true。
---@return boolean
function ModNpc:CanUpdate()
return true
end
--- Called when NPC runs every update tick, usually write logic in this function.
---
--- NPC每帧运行时调用,通常在该函数内编写运动等逻辑。
function ModNpc:Update()
end
--- Called before the NPC runs the `Update()` function every update tick.
--- It is usually used to insert new logic before the original logic.
---
--- NPC每帧运行`Update()`函数前调用。通常用于在原逻辑前插入新逻辑。
function ModNpc:PreUpdate()
end
--- Called after the NPC runs the `Update()` function every update tick.
--- It is usually used to insert new logic after the original logic.
---
--- NPC每帧运行`Update()`函数后调用。通常用于追加逻辑。
function ModNpc:PostUpdate()
end
---
---
--- NPC每帧绘制前调用,如果返回true则执行所有Draw逻辑,返回false则不执行所有Draw逻辑。可在该函数写入新的逻辑,并屏蔽原有逻辑。默认返回true。
---@return boolean
function ModNpc:CanDraw()
return true
end
--- Called before each tick of NPC drawing,
--- just write custom drawing behavior in this function.
---
--- NPC每帧绘制前调用,在该函数内编写自定义绘制属性。
function ModNpc:OnDraw()
end
function ModNpc:OnRender()
end
--- Called when NPC was killed.
---
--- NPC死亡时调用一次该函数。
function ModNpc:OnKilled()
end
---ModifyHit
---@param attack Attack
---@return boolean
function ModNpc:ModifyHit(attack)
end
--- Called when NPC collides the tiles.
---
--- NPC与图块碰撞时调用该函数。
--- @param oldSpeedX double The X speed before colliding tiles. (击中图块前一帧的横向速度)
--- @param oldSpeedY double The Y speed before colliding tiles. (击中图块前一帧的纵向速度)
function ModNpc:OnTileCollide(oldSpeedX, oldSpeedY)
end
function ModNpc:OnLoot()
end
---@return table
function ModNpc:Save()
end
---Load
---@param tagTable table
function ModNpc:Load(tagTable)
end
return ModNpc
================================================
FILE: apis/ModProjectile.lua
================================================
---@class ModProjectile
---@field projectile Projectile
local ModProjectile = {}
return ModProjectile
================================================
FILE: apis/ModTextureData.lua
================================================
---@class ModTextureData
---@field textureLocation TextureLocation
---@field width int
---@field height int
---@field frameXs int
---@field frameYs int
---@field frameSpeed int
---@field tagUsage int
---@field loopPlay boolean
---@field userDisabled boolean
local ModTextureData = {}
return ModTextureData
================================================
FILE: apis/ModTextureUtils.lua
================================================
---@class ModTextureUtils
local ModTextureUtils = {}
---GetData
---@param modTextureID int
---@return ModTextureData
function ModTextureUtils.GetData(modTextureID)
end
return ModTextureUtils
================================================
FILE: apis/Npc.lua
================================================
---@API
---@class Npc:Entity 描述一个NPC实体。
---@field entityIndex EntityIndex
---@field id int 当前NPC的动态ID。
---@field dataWatcher DataWatcher
---@field data table
---@field texture TextureLocation
---@field baseAttack Attack 当前NPC的基础攻击属性。
---@field maxSpeed double 当前NPC的最大横向移动速度。每帧重置为所在环境(流体黏性等)决定的最大移动速度。
---@field defaultGravity double Read-only 当前NPC的默认重力加速度。
---@field gravity double 当前NPC的纵向加速度。每帧重置为作用了所在环境纵向受力以及重力后的纵向加速度。
---@field defaultMaxFallSpeed double Read-only 当前NPC的默认最大下落速度。
---@field maxFallSpeed double 当前NPC的最大下落速度。每帧重置为作用了所在环境纵向阻力后的最大下落速度。
---@field jumpForce double 当前NPC的跳跃力度。每帧重置为作用了所在环境纵向阻力后的跳跃力度。
---@field noMove boolean 决定当前NPC是否停止行走。
---@field inLiquid boolean Read-only 当前NPC是否处在流体环境中。
---@field oldInLiquid boolean Read-only 上一帧的NPC是否处在流体环境中。
---@field isEnemy boolean Read-only 当前NPC是否会伤害玩家。
---@field state int NPC当前在简单有限状态机中的状态。
---@field stateTimer int NPC的状态机计时器。
---@field hurry boolean 当前NPC是否为匆忙状态。匆忙状态下随机走模板不会停下来。
---@field maxHealth int 当前NPC的生命值上限。
---@field health int 当前NPC的生命值。
---@field angry boolean 当前NPC是否为愤怒状态。易怒的NPC在被玩家击中后会将该玩家视为目标,并置愤怒状态为true。
---@field animation int NPC当前执行的动画状态。通常用于表示骨骼模型的动画状态。
---@field animationTickTime int NPC在当前动画索引所经过的时间。每帧自动自增1,当动画状态切换时自动重置为0。
---@field watchAngle double Read-only NPC的目视角度。若NPC目标存在,则总是目视目标。否则总是根据朝向水平目视。
---@field type NpcType Read-only NPC类型。
---@field spawnCount double 占用生成量。
---@field defaultKnockBackDefenseValue double 击退抗性。
---@field toolUseRate double 工具使用概率。
---@field maxDisappearTime int 最大消失时间。
---@field defaultDefenseValue int 防御力。
---@field defaultAttackValue int 攻击力。
---@field defaultCritValue int 双倍暴击率百分比。
---@field defaultKnockBackValue int 击退力。
---@field movement int 运动方式。
---@field gfxOffsetX int 贴图偏移量X。
---@field gfxOffsetY int 贴图偏移量Y。
---@field gfxWidth int 贴图宽度。
---@field gfxHeight int 贴图高度。
---@field frameStyle int 贴图方式 0-不分左右 1-分左右。
---@field exps int 经验值。
---@field checkTargetDistance int 检测目标的半径。
---@field special int 特殊值。
---@field magicRate int 产生魔法碎片概率的反比。
---@field friendly boolean 是否友好。
---@field hasGravity boolean 是否受重力。
---@field canClimbWall boolean 是否能爬墙。
---@field isForeground boolean 是否置前。
---@field isAntiLava boolean 是否抵抗岩浆。
---@field noFixByBlock boolean 是否不根据方块修正位置。
---@field willBurnUnderSun boolean 是否白天自燃。
---@field defaultAngry boolean 是否易怒。
---@field isBoss boolean 是否作为BOSS。
---@field noShowHp boolean 是否不显示血条。
---@field noBurnSound boolean 是否不播放燃烧音效。
---@field usingBoneModule boolean Read-only 是否使用骨骼模型。
---@field isCheckPlayerTarget boolean 是否自动检测玩家目标。
---@field isVisionNoCrossTile boolean 是否视野不穿墙。
---@field isAutoSave boolean 是否保存到存档。
---@field noHurt boolean
---@field noCollisionByWeapon boolean
---@field noLooting boolean
---@field isWatchAngleForTarget boolean
---@field netUpdate boolean 是否使用逻辑网络同步。
local Npc = {}
--- 不掉落物品直接清除当前NPC对象。
function Npc:Kill()
end
---KillByStrike
---@overload fun(hitAngle:double)
---@overload fun(hitAngle:double,hurtSound:boolean)
---@param hitAngle double
---@param hurtSound boolean
---@param lootingLevel int
function Npc:KillByStrike(hitAngle, hurtSound, lootingLevel)
end
--- 制造一个对当前NPC的伤害。
---@overload fun(attack:Attack)
---@overload fun(attack:Attack,hitAngle:double)
---@overload fun(attack:Attack,hitAngle:double,immune:boolean)
---@overload fun(attack:Attack,hitAngle:double,immune:boolean,hurtSound:boolean)
---@overload fun(attack:Attack,hitAngle:double,immune:boolean,hurtSound:boolean,lootingLevel:int)
---@param attack Attack 当前伤害属性。
---@param hitAngle double @[ default `0.0` ] 产生伤害的角度。
---@param immune boolean @[ default `true` ] 产生当前伤害后是否让NPC处于无敌帧状态。
---@param hurtSound boolean @[ default `true` ] 是否播放NPC受伤音效。
---@param lootingLevel int @[ default `0` ] 掠夺等级。
function Npc:Strike(attack, hitAngle, immune, hurtSound, lootingLevel)
end
--- 制造一个某玩家对当前NPC的伤害。
---@overload fun(player:Player,attack:Attack)
---@overload fun(player:Player,attack:Attack,hitAngle:double)
---@overload fun(player:Player,attack:Attack,hitAngle:double,immune:boolean)
---@overload fun(player:Player,attack:Attack,hitAngle:double,immune:boolean,hurtSound:boolean)
---@overload fun(player:Player,attack:Attack,hitAngle:double,immune:boolean,hurtSound:boolean,lootingLevel:int)
---@param player Player 表示造成伤害的玩家。
---@param attack Attack 当前伤害属性。
---@param hitAngle double @[ default `0.0` ] 产生伤害的角度。
---@param immune boolean @[ default `true` ] 产生当前伤害后是否让NPC处于无敌帧状态。
---@param hurtSound boolean @[ default `true` ] 是否播放NPC受伤音效。
---@param lootingLevel int @[ default `0` ] 掠夺等级。
function Npc:StrikeFromPlayer(player, attack, hitAngle, immune, hurtSound, lootingLevel)
end
--- 制造一个某玩家对当前NPC的伤害。
---@overload fun(npc:Npc,attack:Attack)
---@overload fun(npc:Npc,attack:Attack,hitAngle:double)
---@overload fun(npc:Npc,attack:Attack,hitAngle:double,immune:boolean)
---@overload fun(npc:Npc,attack:Attack,hitAngle:double,immune:boolean,hurtSound:boolean)
---@overload fun(npc:Npc,attack:Attack,hitAngle:double,immune:boolean,hurtSound:boolean,lootingLevel:int)
---@param npc Npc 表示造成伤害的NPC。
---@param attack Attack 当前伤害属性。
---@param hitAngle double @[ default `0.0` ] 产生伤害的角度。
---@param immune boolean @[ default `true` ] 产生当前伤害后是否让NPC处于无敌帧状态。
---@param hurtSound boolean @[ default `true` ] 是否播放NPC受伤音效。
---@param lootingLevel int @[ default `0` ] 掠夺等级。
function Npc:StrikeFromNpc(npc, attack, hitAngle, immune, hurtSound, lootingLevel)
end
--- 为当前NPC添加一个状态效果。若原状态效果存在,以最长时间为新状态效果的持续时间。
---@param buffID int 状态效果ID。
---@param buffTime int 状态效果持续时间。
function Npc:AddBuff(buffID, buffTime)
end
--- 移除一个状态效果。
---@param buffID int
function Npc:RemoveBuff(buffID)
end
--- 移除全部状态效果。
function Npc:RemoveAllBuff()
end
--- 返回NPC是否拥有指定状态效果。
---@param buffID int 状态效果ID。
---@return boolean
function Npc:HasBuff(buffID)
end
--- 返回NPC是否存在状态效果。
---@return boolean
function Npc:HasAnyBuff()
end
--- NPC尝试发出平时声音。平均经过`tryTimes`次发出一次平时声音。
---@param tryTimes int
function Npc:TryMakeSound(tryTimes)
end
--- NPC发出平时声音。
function Npc:MakeSound()
end
--- 站立静止不动。
---@overload fun()
---@param faceToTarget boolean @[ default `true` ] 是否始终面朝玩家。
function Npc:Stand(faceToTarget)
end
--- 随机地朝一个方向行走或停下或转弯。
--- 停下时闲置`idleTime ± idleTimeOffset`范围内随机时间。
--- 朝一个方向行走时持续`walkTime ± walkTimeOffset`范围内随机时间。
--- 使用内置寻路逻辑,遇到墙壁会尝试跳跃3次。
---@overload fun()
---@overload fun(idleTime:int)
---@overload fun(idleTime:int,idleTimeOffset:int)
---@overload fun(idleTime:int,idleTimeOffset:int,walkTime:int)
---@param idleTime int @[ default `128` ]
---@param idleTimeOffset int @[ default `64` ]
---@param walkTime int @[ default `96` ]
---@param walkTimeOffset int @[ default `32` ]
function Npc:RandomWalk(idleTime, idleTimeOffset, walkTime, walkTimeOffset)
end
--- 持续行走而不停下。使用内置寻路逻辑,遇到墙壁会尝试跳跃3次。
---@overload fun()
---@param followTarget boolean @[ default `true` ] 表示在目标存在的情况下,尽可能靠近目标。
function Npc:KeepWalking(followTarget)
end
--- 目标存在时,调用`KeepWalking(followTarget)`,否则调用`RandomWalk()`。
---@overload fun()
---@param followTarget boolean @[ default `true` ] 表示在目标存在的情况下,尽可能靠近目标。
function Npc:Walk(followTarget)
end
--- 在流体中游泳,在空气中蹦跶。目标不存在时,在流体中随机运动。
---@overload fun()
---@param followTarget boolean @[ default `true` ] 表示在目标存在的情况下,尽可能靠近目标。
function Npc:Swim(followTarget)
end
--- 在空气中飞行。
---@overload fun()
---@overload fun(followTarget:boolean)
---@overload fun(followTarget:boolean,force:double)
---@param followTarget boolean @[ default `true` ] 表示在目标存在的情况下,尽可能靠近目标,否则随机飞行。
---@param force double @[ default '0.1' ] 表示飞向目标的力。
---@param gradientSpeed boolean @[ default `false` ] 表示是否使用渐变速度,否则运动速度的向量大小总是恒定的。
function Npc:Fly(followTarget, force, gradientSpeed)
end
--- 传送NPC自己到以自己为圆心的圆形区域随机位置。
---@overload fun(distance:int):boolean
---@overload fun(distance:int,noToAir:boolean):boolean
---@param distance int 圆形区域的半径。
---@param noToAir boolean @[ default `true` ] 表示是否传送到地面上。
---@param noToLiquid boolean @[ default true` ] 表示是否不传送到流体内。
---@return boolean 成功传送返回true,失败返回false。
function Npc:RandomTeleport(distance, noToAir, noToLiquid)
end
---
---
---@return ModNpc
function Npc:GetModNpc()
end
---
---
---@param globalNpcName string
---@return GlobalNpc
function Npc:GetGlobalNpc(globalNpcName)
end
function Npc:SyncAll()
end
return Npc
================================================
FILE: apis/NpcType.lua
================================================
---@class NpcType Enum class (Enum Format: `NPC_TYPE_XXX`)
local NpcType = {}
---@type NpcType
NPC_TYPE_NORMAL = nil
---@type NpcType
NPC_TYPE_ANIMAL = nil
---@type NpcType
NPC_TYPE_VILLAGER = nil
---@type NpcType
NPC_TYPE_ARTHROPODS = nil
---@type NpcType
NPC_TYPE_SMITE = nil
---@type NpcType
NPC_TYPE_BOSS = nil
return NpcType
================================================
FILE: apis/NpcUtils.lua
================================================
---@class NpcUtils @NPC Util Module (NPC通用模块)
local NpcUtils = {}
---@return Npc[]
function NpcUtils.GetAllEntities()
end
---Get
---@param entityIndex EntityIndex
---@return Npc
function NpcUtils.Get(entityIndex)
end
---IsAlive
---@param entityIndex EntityIndex
---@return boolean
function NpcUtils.IsAlive(entityIndex)
end
---Create an NPC at the specified location and return the created NPC entity.
---
---在指定位置创建一个NPC,返回创建好的NPC实体。
---@overload fun(id:int,x:double,y:double):Npc
---@overload fun(id:int,x:double,y:double,speedX:double):Npc
---@param id int
---@param x double @The x coordinate (x坐标)
---@param y double @The y coordinate (y坐标)
---@param speedX double @[ default '0.0' ] (横向速度,默认0)
---@param speedY double @[ default '0.0' ] (纵向速度,默认0)
---@return Npc @创建好的NPC实体
function NpcUtils.Create(id, x, y, speedX, speedY)
end
---WeaponCollide
---@overload fun(itemStack:ItemStack,hitAngle:double,obb:ObbDouble,attackInAndOut:Attack,outNpcIndex:EntityIndex):boolean
---@param itemStack ItemStack
---@param hitAngle double
---@param obb ObbDouble
---@param attackInAndOut Attack
---@param ignoreNpcIndex EntityIndex
---@param outNpcIndex EntityIndex
---@return boolean
function NpcUtils.WeaponCollide(itemStack, hitAngle, obb, attackInAndOut, ignoreNpcIndex, outNpcIndex)
end
---SearchByRect
---@param x double
---@param y double
---@param width int
---@param height int
---@return Npc[]
function NpcUtils.SearchByRect(x, y, width, height)
end
---SearchByCircle
---@param x double
---@param y double
---@param radius int
---@return Npc[]
function NpcUtils.SearchByCircle(x, y, radius)
end
---SearchNearestNpc
---@param x double
---@param y double
---@param radius int
---@param noCrossTiles boolean
---@return Npc
function NpcUtils.SearchNearestNpc(x, y, radius, noCrossTiles)
end
---SearchNearestEnemy
---@param x double
---@param y double
---@param radius int
---@param noCrossTiles boolean
---@return Npc
function NpcUtils.SearchNearestEnemy(x, y, radius, noCrossTiles)
end
return NpcUtils
================================================
FILE: apis/OreDataGroup.lua
================================================
---@class OreData
---@field oreID int 矿物的方块id
---@field density int 矿脉密度(每区块生成次数)
---@field radius int 矿脉半径
---@field startYi int 矿脉开始分布的Y值
---@field endYi int 矿脉结束分布的Y值
local OreData = {}
---@class OreDataGroup
---@field name string 矿物组名称
---@field dataList OreData[] 矿物列表
local OreDataGroup = {}
return OreDataGroup
================================================
FILE: apis/ParameterClick.lua
================================================
---@class ParameterClick
---@field playerEntityIndex EntityIndex
local ParameterClick = {}
return ParameterClick
================================================
FILE: apis/ParameterDestroy.lua
================================================
---@class ParameterDestroy
---@field silkTouch int
---@field fortune int
---@field boom boolean
---@field dropItem boolean
---@field showEffect boolean
---@field playSound boolean
local ParameterDestroy = {}
return ParameterDestroy
================================================
FILE: apis/ParameterPlace.lua
================================================
---@class ParameterPlace
---@field placeDir int
local ParameterPlace = {}
return ParameterPlace
================================================
FILE: apis/ParameterStrike.lua
================================================
---@class ParameterStrike
---@field lootingLevel int
local ParameterStrike = {}
return ParameterStrike
================================================
FILE: apis/Player.lua
================================================
---@class Player:Entity
---@field entityIndex EntityIndex
---@field dataWatcher DataWatcher
---@field remoteDataWatcher DataWatcher
---@field lookAngle double
---@field facingDirection boolean
---@field hostXi int
---@field hostYi int
---@field biomeType int
---@field biomeID int
---@field defaultMaxSpeed double
---@field defaultJumpTime int
---@field defaultJumpSpeed double
---@field defaultFallSpeed double
---@field speedRate double
---@field jumpRate double
---@field jumpSpeedRate double
---@field fallSpeedRate double
---@field digSpeedRate double
---@field isInvisibility boolean
---@field health int
---@field maxHealth int
---@field mana int
---@field maxMana int
---@field expLevel int
---@field remainExp int
---@field isNoBreathing boolean
---@field breathRate double
---@field foodLevel int
---@field foodSaturationLevel int
---@field touchLiquidID int
---@field inLiquid boolean
---@field oldInLiquid boolean
---@field gameMode int
---@field op int
---@field name string
---@field ip string
---@field port int
---@field isCurrentClientPlayer boolean
---@field mouseInventory Inventory
---@field backpackInventory Inventory
---@field equipmentInventory Inventory
---@field enderInventory Inventory
---@field heldSlotIndex int
---@field heldSlotIndexJustChanged boolean
---@field smartMode SmartMode_Value
---@field isSmartPositionFound boolean
---@field holdColdTime int
---@field isDownPlatform boolean
---@field baseAttack Attack
---@field baseDefense Defense
---@field ignoreCollisionWithTiles boolean
---@field dying boolean
local Player = {}
---Strike
---@overload fun(deathReason:int, attack:Attack)
---@overload fun(deathReason:int, attack:Attack, hitAngle:double)
---@overload fun(deathReason:int, attack:Attack, hitAngle:double, immune:boolean)
---@param deathReason int
---@param attack Attack
---@param hitAngle double
---@param immune boolean
---@param makeHurtSound boolean
function Player:Strike(deathReason, attack, hitAngle, immune, makeHurtSound)
end
---StrikeFromPlayer
---@overload fun(player:Player, attack:Attack)
---@overload fun(player:Player, attack:Attack, hitAngle:double)
---@overload fun(player:Player, attack:Attack, hitAngle:double, immune:boolean)
---@param player Player
---@param attack Attack
---@param hitAngle double
---@param immune boolean
---@param makeHurtSound boolean
function Player:StrikeFromPlayer(player, attack, hitAngle, immune, makeHurtSound)
end
---StrikeFromNpc
---@overload fun(npc:Npc, attack:Attack)
---@overload fun(npc:Npc, attack:Attack, hitAngle:double)
---@overload fun(npc:Npc, attack:Attack, hitAngle:double, immune:boolean)
---@param npc Npc
---@param attack Attack
---@param hitAngle double
---@param immune boolean
---@param makeHurtSound boolean
function Player:StrikeFromNpc(npc, attack, hitAngle, immune, makeHurtSound)
end
---Heal
---@overload fun(healValue:int)
---@param healValue int
---@param showTip boolean
function Player:Heal(healValue, showTip)
end
---AddMagic
---@overload fun(magicValue:int)
---@param magicValue int
---@param showTip boolean
function Player:AddMagic(magicValue, showTip)
end
---AddBreath
---@param breathValue double
function Player:AddBreath(breathValue)
end
---DecBreath
---@param breathValue double
function Player:DecBreath(breathValue)
end
---SetBreath
---@param breathValue double
function Player:SetBreath(breathValue)
end
---AddFood
---@param foodLevel int
---@param foodSaturationLevel int
function Player:AddFood(foodLevel, foodSaturationLevel)
end
---DecFood
---@overload fun(foodLevel:int)
---@param foodLevel int
---@param foodSaturationLevel int
function Player:DecFood(foodLevel, foodSaturationLevel)
end
---OpenGui
---@param mod Mod
---@param guiID int
---@param xi int
---@param yi int
function Player:OpenGui(mod, guiID, xi, yi)
end
---
---@param mod Mod
---@param guiID int
---@param xi int
---@param yi int
function Player:OpenGuiRemote(mod, guiID, xi, yi)
end
---CloseGui
---@param mod Mod
---@param guiID int
function Player:CloseGui(mod, guiID)
end
---IsGuiOpened
---@param mod Mod
---@param guiID int
---@return boolean
function Player:IsGuiOpened(mod, guiID)
end
---DropItem
---@overload fun(itemStack:ItemStack)
---@param itemStack ItemStack
---@param onlyDropOne boolean
function Player:DropItem(itemStack, onlyDropOne)
end
---RequestPlaceBlock
---@param xi int
---@param yi int
---@param slotIndex int
---@param isPlacingWall boolean
---@return boolean
function Player:RequestPlaceBlock(xi, yi, slotIndex, isPlacingWall)
end
---RequestPlaceWire
---@param xi int
---@param yi int
---@param slotIndex int
---@return boolean
function Player:RequestPlaceWire(xi, yi, slotIndex)
end
---RequestDigBlock
---@param xi int
---@param yi int
---@param slotIndex int
---@param isDiggingWall boolean
---@param toolType string
---@return boolean
function Player:RequestDigBlock(xi, yi, slotIndex, isDiggingWall, toolType)
end
---RequestClickMap
---@param xi int
---@param yi int
---@return boolean
function Player:RequestClickMap(xi, yi)
end
---SetSmartMode
---@overload fun(smartMode:SmartMode_Value)
---@param smartMode SmartMode_Value
---@param pointedXi int
---@param pointedYi int
---@param operatingWall boolean
---@param itemStack ItemStack
---@param toolType string
function Player:SetSmartMode(smartMode, pointedXi, pointedYi, operatingWall, itemStack, toolType)
end
---@return int,int
function Player:GetSmartPosition()
end
---
---
---@param globalPlayerName string
---@return GlobalPlayer
function Player:GetGlobalPlayer(globalPlayerName)
end
---FinishAdvancement
---@param advancementID int
function Player:FinishAdvancement(advancementID)
end
---ClearAdvancement
---@param advancementID int
function Player:ClearAdvancement(advancementID)
end
---ClearAllAdvancement
function Player:ClearAllAdvancement()
end
---IsAdvancementFinished
---@param advancementID int
---@return boolean
function Player:IsAdvancementFinished(advancementID)
end
---GetSaveString
---@return string
function Player:GetSaveString()
end
---GetLevelNeedExp
---@param expLevel int
---@return int
function Player:GetLevelNeedExp(expLevel)
end
---AddExperience
---@param amount int
function Player:AddExperience(amount)
end
---RemoveExpLevel
---@param level int
function Player:RemoveExpLevel(level)
end
---AddBuff
---@param buffID int
---@param buffTime int
function Player:AddBuff(buffID, buffTime)
end
---RemoveBuff
---@param buffID int
function Player:RemoveBuff(buffID)
end
---RemoveAllBuff
function Player:RemoveAllBuff()
end
function Player:RemoveAllBuffExceptHealthCold()
end
---HasBuff
---@param buffID int
function Player:HasBuff(buffID)
end
---HasAnyBuff
function Player:HasAnyBuff()
end
---@return Buff[]
function Player:GetBuffList()
end
---@return boolean
function Player:GoHome()
end
function Player:TeleportToSpawn()
end
function Player:Teleport(x, y)
end
return Player
================================================
FILE: apis/PlayerUtils.lua
================================================
---@class PlayerUtils
local PlayerUtils = {}
---@return Player
function PlayerUtils.GetCurrentClientPlayer()
end
---Get
---@param entityIndex EntityIndex
---@return Player
function PlayerUtils.Get(entityIndex)
end
---IsAlive
---@param entityIndex EntityIndex
---@return boolean
function PlayerUtils.IsAlive(entityIndex)
end
--WeaponCollide
---@overload fun(itemStack:ItemStack,hitAngle:double,obb:ObbDouble,attackInAndOut:Attack,outPlayerIndex:EntityIndex):boolean
---@param itemStack ItemStack
---@param hitAngle double
---@param obb ObbDouble
---@param attackInAndOut Attack
---@param ignorePlayerIndex EntityIndex
---@param outPlayerIndex EntityIndex
---@return boolean
function PlayerUtils.WeaponCollide(itemStack, hitAngle, obb, attackInAndOut, ignorePlayerIndex, outPlayerIndex)
end
---SearchByRect
---@param x double
---@param y double
---@param width int
---@param height int
---@return Player[]
function PlayerUtils.SearchByRect(x, y, width, height)
end
---SearchByCircle
---@param x double
---@param y double
---@param radius int
---@return Player[]
function PlayerUtils.SearchByCircle(x, y, radius)
end
---SearchNearestPlayer
---@param x double
---@param y double
---@param radius int
---@param noCrossTiles boolean
---@return Player
function PlayerUtils.SearchNearestPlayer(x, y, radius, noCrossTiles)
end
return PlayerUtils
================================================
FILE: apis/Point.lua
================================================
-- Document
-- Point Class: https://blueyoshi.gitbook.io/terracraft/en/mod/api/type#point
--
-- Point类: https://blueyoshi.gitbook.io/terracraft/cn/mod/api/type#point
--
-- Copyright (c) 2021. BlueYoshi(blueyoshi@foxmail.com)
---@class Point Represents a point. (表示一个点)
---@field x int The x coordinate of the point. (点的横坐标)
---@field y int The y coordinate of the point. (点的纵坐标)
local Point = {}
return Point
================================================
FILE: apis/Projectile.lua
================================================
---@class Projectile:Entity
---@field id int The dynamic ID of the current projectile. (当前抛射物的动态ID)
---@field entityIndex EntityIndex
---@field common ProjectileCommon The common data of current projectile. (当前抛射物的通用数据)
---@field baseAttack Attack The basic attack property of the current projectile. (当前抛射物的基础攻击属性)
---@field targetTime int The target time of the current projectile. It is generally given when it is created, and is usually used to trigger related logic after reaching the target time. (当前抛射物的目标时间。一般由创建时给定,通常用于实现达到目标时间后触发相关逻辑)
---@field isCheckNpc boolean @[ default `false` ] Whether the current projectile is acting on the NPC. It is generally specified when it is created, and determines whether to collide or damage NPCs. (当前抛射物是否作用于NPC。一般由创建时指定,决定是否碰撞、伤害NPC)
---@field isCheckPlayer boolean @[ default `false` ] Whether the current projectile is acting on the player. It is generally specified when it is created, and determines whether to collide or damage players. (当前抛射物是否作用于玩家。一般由创建时指定,决定是否碰撞、伤害玩家)
---@field state int The current state of the projectile in a simple finite state machine. (抛射物当前在简单有限状态机中的状态)
---@field stateTimer int The timer use for state machine. (抛射物的状态机计时器)
---@field playerTargetIndex EntityIndex
---@field npcTargetIndex EntityIndex
---@field special int
local Projectile = {}
--- Destroy the current projectile object.
---
--- 清除当前抛射物对象。
function Projectile:Kill()
end
return Projectile
================================================
FILE: apis/ProjectileUtils.lua
================================================
---@class ProjectileUtils
local ProjectileUtils = {}
---Get
---@param entityIndex EntityIndex
---@return Projectile
function ProjectileUtils.Get(entityIndex)
end
---IsAlive
---@param entityIndex EntityIndex
---@return boolean
function ProjectileUtils.IsAlive(entityIndex)
end
---@overload fun(id:int,x:double,y:double):Projectile
---@overload fun(id:int,x:double,y:double,speedX:double):Projectile
---@overload fun(id:int,x:double,y:double,speedX:double,speedY:double):Projectile
---@param id int
---@param x double
---@param y double
---@param speedX double
---@param speedY double
---@param attack Attack
---@return Projectile
function ProjectileUtils.Create(id, x, y, speedX, speedY, attack)
end
---@overload fun(player:Player,id:int,x:double,y:double):Projectile
---@overload fun(player:Player,id:int,x:double,y:double,speedX:double):Projectile
---@overload fun(player:Player,id:int,x:double,y:double,speedX:double,speedY:double):Projectile
---@param player Player
---@param id int
---@param x double
---@param y double
---@param speedX double
---@param speedY double
---@param attack Attack
---@return Projectile
function ProjectileUtils.CreateFromPlayer(player, id, x, y, speedX, speedY, attack)
end
---@overload fun(npc:Npc,id:int,x:double,y:double):Projectile
---@overload fun(npc:Npc,id:int,x:double,y:double,speedX:double):Projectile
---@overload fun(npc:Npc,id:int,x:double,y:double,speedX:double,speedY:double):Projectile
---@param npc Npc
---@param id int
---@param x double
---@param y double
---@param speedX double
---@param speedY double
---@param attack Attack
---@return Projectile
function ProjectileUtils.CreateFromNpc(npc, id, x, y, speedX, speedY, attack)
end
return ProjectileUtils
================================================
FILE: apis/Recipe.lua
================================================
---@class RecipeInputSlotType_Value
---@class RecipeInputSlotType
---@field Empty RecipeInputSlotType_Value
---@field Item RecipeInputSlotType_Value
---@field OreDictionary RecipeInputSlotType_Value
local RecipeInputSlotType = {}
---@class RecipeInputSlot
---@field type RecipeInputSlotType_Value
---@field id int
---@field stackSize int
---@field itemStack ItemStack
---@field isImportant boolean
local RecipeInputSlot = {}
---@class Recipe
---@field configID int
---@field inputs RecipeInputSlot[]
---@field outputs Slot[]
---@field exData table
local Recipe = {}
---GetGroupSearchAction
---@param groupIndex int
---@return int
function Recipe:GetGroupSearchAction(groupIndex)
end
---IsValidByMask
---@param mask string
---@return boolean
function Recipe:IsValidByMask(mask)
end
return Recipe
================================================
FILE: apis/RecipeConfig.lua
================================================
---@class RecipeConfig
---@field iconItemID int
---@field inputCount int
---@field outputCount int
local RecipeConfig = {}
return RecipeConfig
================================================
FILE: apis/RecipeSearchAction.lua
================================================
---@class RecipeSearchAction
---@field Fixed int
---@field Unordered int
local RecipeSearchAction = {}
return RecipeSearchAction
================================================
FILE: apis/RecipeUtils.lua
================================================
---@API
---@class RecipeUtils 配方组件。
local RecipeUtils = {}
---通过配方的ID获取配方。
---@param recipeID int 配方ID (请通过搜索配方的方法 RecipeUtils.SearchRecipe() 动态获取)。
---@return Recipe 配方。
function RecipeUtils.GetRecipe(recipeID)
end
---获取某一合成实体的配方配置。
---@param recipeConfigID int 配方配置ID (请通过Reg.RecipeConfigID()动态获取)。
---@return RecipeConfig 配方配置。
function RecipeUtils.GetConfig(recipeConfigID)
end
---搜索配方。
---[Example]
-----获取酿造台的某一配方,使用酿造台中的两个合成的格子作为输入物品
---local recipeID = RecipeUtils.SearchRecipe(Reg.RecipeConfigID("Brew"), self.inventory, 0, 2)
---@overload fun(configID:int,inventory:Inventory):int
---@param configID int 配方配置ID (请通过Reg.RecipeConfigID()动态获取)。
---@param inventory Inventory 物品格子的集合(一般为合成中使用的物品的格子的集合)。
---@param offset int 偏移值(从物品格子的哪里开始)。
---@param length int 长度(调用物品格子的数目)。
---@return int 配方ID
function RecipeUtils.SearchRecipe(configID, inventory, offset, length)
end
---检查某一物品是否有对应的配方
---@param configID int 配方配置ID (请通过Reg.RecipeConfigID()动态获取)。
---@param inputItemStack ItemStack 合成输入的堆叠物品。
---@param inputIndex int 合成输入的Index。
---@return int 配方ID。
function RecipeUtils.HasRecipe(configID, inputItemStack, inputIndex)
end
---检查某一配方配置里所有的配方中是否有对应的输入物品
---@param configID int 配方配置ID (请通过Reg.RecipeConfigID()动态获取)。
---@param inputItemStack ItemStack 搜索对应的堆叠物品。
---@return int[] 搜索到的配方ID的数组。
function RecipeUtils.SearchRecipeHasInputItem(configID, inputItemStack)
end
---检查某一配方配置里所有的配方中是否有对应的输出物品
---@param configID int 配方配置ID (请通过Reg.RecipeConfigID()动态获取)。
---@param outputItemStack ItemStack 搜索对应的堆叠物品。
---@param outputIndex int 合成输出的Index。
---@return int[] 搜索到的配方ID的数组。
function RecipeUtils.SearchRecipeHasOutputItem(configID, outputItemStack, outputIndex)
end
return RecipeUtils
================================================
FILE: apis/Rectangle.lua
================================================
-- Document
-- Rectangle Class: https://blueyoshi.gitbook.io/terracraft/en/mod/api/type#rectangle
--
-- Rectangle类: https://blueyoshi.gitbook.io/terracraft/cn/mod/api/type#rectangle
--
-- Copyright (c) 2021. BlueYoshi(blueyoshi@foxmail.com)
---@class Rectangle Represents an axis-aligned rectangle. (表示一个轴对齐矩形)
---@field x int The x coordinate of the upper left corner of the rectangle. (矩形左上角横坐标)
---@field y int The y coordinate of the upper left corner of the rectangle. (矩形左上角纵坐标)
---@field width int The width of the rectangle. (矩形宽度)
---@field height int The height of the rectangle. (矩形高度)
local Rectangle = {}
--- Set a new rectangle.
---
--- 设置新的矩形。
---@param x int
---@param y int
---@param width int
---@param height int
function Rectangle:Set(x, y, width, height)
end
return Rectangle
================================================
FILE: apis/Reg.lua
================================================
---@API
---@class Reg 描述游戏内的注册信息。
local Reg = {}
---根据物品名返回注册的动态ID。
---@param name string
---@return int
function Reg.ItemID(name)
end
---根据动态ID返回物品的全局ID名称。
---@param id int
---@return string
function Reg.ItemIDName(id)
end
---返回最大物品ID。
---@return int
function Reg.MaxItemID()
end
---根据方块名返回注册的动态ID。
---@param name string
---@return int
function Reg.BlockID(name)
end
---根据动态ID返回方块的全局ID名称。
---@param id int
---@return string
function Reg.BlockIDName(id)
end
---根据方块组名返回注册的动态ID。
---@param name string
---@return int
function Reg.BlockGroupID(name)
end
---根据动态ID返回方块组的全局ID名称。
---@param id int
---@return string
function Reg.BlockGroupIDName(id)
end
---根据方块子组名返回注册的动态ID。
---@param name string
---@return int
function Reg.BlockSubGroupID(name)
end
---根据动态ID返回方块子组的全局ID名称。
---@param id int
---@return string
function Reg.BlockSubGroupIDName(id)
end
---根据方块实体名返回注册的动态ID。
---@param name string
---@return int
function Reg.BlockEntityID(name)
end
---根据动态ID返回方块实体的全局ID名称。
---@param id int
---@return string
function Reg.BlockEntityIDName(id)
end
---根据特效名返回注册的动态ID。
---@param name string
---@return int
function Reg.EffectID(name)
end
---根据动态ID返回特效的全局ID名称。
---@param id int
---@return string
function Reg.EffectIDName(id)
end
---根据BUFF名返回注册的动态ID。
---@param name string
---@return int
function Reg.BuffID(name)
end
---根据动态ID返回BUFF的全局ID名称。
---@param id int
---@return string
function Reg.BuffIDName(id)
end
---根据附魔名返回注册的动态ID。
---@param name string
---@return int
function Reg.EnchantmentID(name)
end
---根据动态ID返回附魔的全局ID名称。
---@param id int
---@return string
function Reg.EnchantmentIDName(id)
end
---返回附魔的最大ID。
---@return int
function Reg.MaxEnchantmentID()
end
---根据NPC名返回注册的动态ID。
---@param name string
---@return int
function Reg.NpcID(name)
end
---根据动态ID返回NPC的全局ID名称。
---@param id int
---@return string
function Reg.NpcIDName(id)
end
---根据抛射物名返回注册的动态ID。
---@param name string
---@return int
function Reg.ProjectileID(name)
end
---根据动态ID返回抛射物的全局ID名称。
---@param id int
---@return string
function Reg.ProjectileIDName(id)
end
---根据音效名返回注册的动态ID。
---@param name string
---@return int
function Reg.SoundID(name)
end
---根据动态ID返回音效的全局ID名称。
---@param id int
---@return string
function Reg.SoundIDName(id)
end
---根据音效组名返回注册的动态ID。
---@param name string
---@return int
function Reg.SoundGroupID(name)
end
---根据动态ID返回音效组的全局ID名称。
---@param id int
---@return string
function Reg.SoundGroupIDName(id)
end
---根据流体名返回注册的动态ID。
---@param name string
---@return int
function Reg.LiquidID(name)
end
---根据动态ID返回流体的全局ID名称。
---@param id int
---@return string
function Reg.LiquidIDName(id)
end
---根据生物群系名返回注册的动态ID。
---@param name string
---@return int
function Reg.BiomeID(name)
end
---根据动态ID返回生物群系的全局ID名称。
---@param id int
---@return string
function Reg.BiomeIDName(id)
end
---返回最大生物群系ID。
---@return int
function Reg.MaxBiomeID()
end
---根据生物群系类型名返回注册的动态ID。
---@param name string
---@return int
function Reg.BiomeTypeID(name)
end
---根据动态ID返回生物群系类型的全局ID名称。
---@param id int
---@return string
function Reg.BiomeTypeIDName(id)
end
---返回最大生物群系类型ID。
---@return int
function Reg.MaxBiomeTypeID()
end
---根据配方配置名返回注册的动态ID。
---@param name string
---@return int
function Reg.RecipeConfigID(name)
end
---根据动态ID返回配方配置的全局ID名称。
---@param id int
---@return string
function Reg.RecipeConfigIDName(id)
end
---返回最大配方配置ID。
---@return int
function Reg.MaxRecipeConfigID()
end
---返回最大配方ID。
---@return int
function Reg.MaxRecipeID()
end
---根据动态ID返回矿物字典的全局ID名称。
---@param id int
---@return string
function Reg.OreDictionaryIDName(id)
end
---根据矿物字典名返回注册的动态ID。
---@param name string
---@return int
function Reg.OreDictionaryID(name)
end
---根据工具优先级名返回注册的动态ID。
---@param gradeName string
---@return int
function Reg.ToolGradePriority(gradeName)
end
---根据弹药名返回注册的动态ID。
---@param name string
---@return int
function Reg.AmmoID(name)
end
---根据动态ID返回弹药的全局ID名称。
---@param id int
---@return string
function Reg.AmmoIDName(id)
end
---根据成就名返回注册的动态ID。
---@param name string
---@return int
function Reg.AdvancementID(name)
end
---根据动态ID返回成就的全局ID名称。
---@param id int
---@return string
function Reg.AdvancementIDName(id)
end
---返回最大成就ID。
---@return int
function Reg.MaxAdvancementID()
end
---@param name string
---@return int
function Reg.ModTextureID(name)
end
---@param id int
---@return string
function Reg.ModTextureIDName(id)
end
---根据建筑名返回注册的动态ID。
---@param name string
---@return int
function Reg.BuildingID(name)
end
---根据动态ID返回建筑的全局ID名称。
---@param id int
---@return string
function Reg.BuildingIDName(id)
end
return Reg
================================================
FILE: apis/ServerBoundPacketWriter.lua
================================================
---@class ServerBoundPacket
---@field writerBuffer ByteStream
---@field readerBuffer ByteStream
local ServerBoundPacket = {}
function ServerBoundPacket:Send()
end
---@return ByteStream
function ServerBoundPacket:GetWriterBuffer()
end
---@return ByteStream
function ServerBoundPacket:GetReaderBuffer()
end
return ServerBoundPacket
================================================
FILE: apis/Shape.lua
================================================
-- Document
-- Shape Enum Class: https://blueyoshi.gitbook.io/terracraft/en/mod/api/type#shape
--
-- Shape枚举类: https://blueyoshi.gitbook.io/terracraft/cn/mod/api/type#shape
--
-- Copyright (c) 2021. BlueYoshi(blueyoshi@foxmail.com)
---@class Shape Enum class (Enum Format: `SHAPE_XXX`)
local Shape = {}
--- The shape of the hitbox is an axis-aligned rectangle.
---
--- 碰撞箱形状为轴对齐矩形。
---
---@type Shape
SHAPE_BOX = nil
--- The shape of the hitbox is a rotating rectangle.
---
--- 碰撞箱形状为旋转矩形。
---
---@type Shape
SHAPE_ROTATE_BOX = nil
return Shape
================================================
FILE: apis/Skeleton.lua
================================================
---@class Skeleton
local Skeleton = {}
return Skeleton
================================================
FILE: apis/Skin.lua
================================================
---@class Skin
---@field headTexture TextureLocation
---@field bodyTexture TextureLocation
---@field legTexture TextureLocation
---@field hairTexture TextureLocation
---@field clothTexture TextureLocation
---@field pantTexture TextureLocation
---@field isFemale boolean
---@field name string
---@field authors Array
---@field mod Mod
local Skin = {}
return Skin
================================================
FILE: apis/SkinUtils.lua
================================================
---@class SkinUtils
---@field maxID int
local SkinUtils = {}
---GetSkin
---@param skinID int
---@return Skin
function SkinUtils.GetSkin(skinID)
end
return SkinUtils
================================================
FILE: apis/Slot.lua
================================================
---@API
---@class Slot 描述一个物品格子,物品格子可能为空格子,也可能包含一个ItemStack。
---@field hasStack boolean 当前格子是否包含物品堆栈。
---@field tag int 格子附加值。
local Slot = {}
---判断格子是否有效。
---@return boolean
function Slot:Valid()
end
---@return ItemStack
function Slot:GetStack()
end
---PushStack
---@param stack ItemStack
function Slot:PushStack(stack)
end
---DecrStackSize
---@param value int
---@return ItemStack
function Slot:DecrStackSize(value)
end
function Slot:ClearStack()
end
---SwapStack
---@param slot Slot
function Slot:SwapStack(slot)
end
---CanPush
---@param itemStack ItemStack
---@return boolean
function Slot:CanPush(itemStack)
end
---
---@param itemStack ItemStack
---@return boolean
function Slot:CanPick(itemStack)
end
---OnPush
---@param itemStack ItemStack
function Slot:OnPush(itemStack)
end
---OnPick
---@param ItemStack ItemStack
function Slot:OnPick(ItemStack)
end
---
---@param listener table|function
---@return ListenerID
function Slot:AddCanPushListener(listener)
end
---
---@param listenerID ListenerID
function Slot:RemoveCanPushListener(listenerID)
end
---
---@param listener table|function
---@return ListenerID
function Slot:AddCanPickListener(listener)
end
---
---@param listenerID ListenerID
function Slot:RemoveCanPickListener(listenerID)
end
---
---@param listener table|function
---@return ListenerID
function Slot:AddOnPushListener(listener)
end
---
---@param listenerID ListenerID
function Slot:RemoveOnPushListener(listenerID)
end
---
---@param listener table|function
---@return ListenerID
function Slot:AddOnPickListener(listener)
end
---
---@param listenerID ListenerID
function Slot:RemoveOnPickListener(listenerID)
end
function Slot:SyncAll()
end
return Slot
================================================
FILE: apis/SlotCommandQueue.lua
================================================
---@class SlotCommandQueue
local SlotCommandQueue = {}
return SlotCommandQueue
================================================
FILE: apis/SmartMode.lua
================================================
---@class SmartMode_Value
---@class SmartMode
---@field None SmartMode_Value
---@field Digging SmartMode_Value
---@field Placing SmartMode_Value
local SmartMode = {}
return SmartMode
================================================
FILE: apis/SoundUtils.lua
================================================
---@class SoundUtils
local SoundUtils = {}
---PlaySound
---@overload fun(soundID:int)
---@param soundID int
---@param xi int
---@param yi int
function SoundUtils.PlaySound(soundID, xi, yi)
end
---PlaySoundGroup
---@overload fun(soundGroupID:int)
---@param soundGroupID int
---@param xi int
---@param yi int
function SoundUtils.PlaySoundGroup(soundGroupID, xi, yi)
end
return SoundUtils
================================================
FILE: apis/SpriteEx.lua
================================================
-- Document
-- SpriteEx Class: https://blueyoshi.gitbook.io/terracraft/en/mod/api/type#spriteex
--
-- SpriteEx类: https://blueyoshi.gitbook.io/terracraft/cn/mod/api/type#spriteex
--
-- Copyright (c) 2021. BlueYoshi(blueyoshi@foxmail.com)
---@class SpriteEx Sprite extension information, has the relevant parameters of drawing. (精灵绘制拓展信息,拥有决定绘制的相关参数)
---@field scaleRateX float @[ default `1.0` ] The horizontal zoom size when the sprite is drawn. (精灵绘制时的横向缩放尺寸)
---@field scaleRateY float @[ default `1.0` ] The vertical zoom size when the sprite is drawn. (精灵绘制时的纵向缩放尺寸)
---@field angle float @[ default `0.0` ] The rotation angle when the sprite is drawn. (精灵绘制时的旋转角度)
---@field rotateX float The center point X of the sprite's rotation. If the drawing object is an entity, the default is the center of the entity, otherwise the default is 0.0. (精灵的旋转中心点X。若绘制对象为实体,默认为实体中心,否则默认为0.0)
---@field rotateY float The center point Y of the sprite's rotation. If the drawing object is an entity, the default is the center of the entity, otherwise the default is 0.0. (精灵的旋转中心点Y。若绘制对象为实体,默认为实体中心,否则默认为0.0)
---@field flipHorizontal boolean @[ default `false` ] Whether to flip horizontally when the sprite is drawn. (精灵绘制时是否水平翻转)
---@field flipVertical boolean @[ default `false` ] Whether to flip vertically when the sprite is drawn. (精灵绘制时是否竖直翻转)
local SpriteEx = {}
--- Restore Defaults.
---
--- 恢复默认值。
function SpriteEx:SetDefault()
end
return SpriteEx
================================================
FILE: apis/Type.lua
================================================
---@class int:number
---@class double:number
---@class float:number
================================================
FILE: apis/Utils.lua
================================================
---@class Utils Util Module (通用模块)
---@field netMode int
---@field E double
---@field LOG2E double
---@field LOG10E double
---@field PI double
---@field TWO_PI double
---@field PI_OVER_2 double
---@field PI_OVER_4 double
local Utils = {}
---If n is greater than 0, return a random integer of [0, n), otherwise return 0.
---
---若n大于0,返回[0, n)的随机整数,否则返回0。
---@param n int
---@return int
function Utils.RandInt(n)
end
---If len is greater than 0, return a random integer of [begin, begin + len), otherwise return begin.
---
---若len大于0,返回[begin, begin + len)的随机整数,否则返回begin。
---@param begin int
---@param len int
---@return int
function Utils.RandIntArea(begin, len)
end
---
---
---若value大于0,返回[0, value)的随机浮点数,否则返回0。
---@param value double
---@return double
function Utils.RandDouble(value)
end
---
---
---若len大于0,返回[begin, begin + len)的随机浮点数,否则返回begin。
---@param begin double
---@param len double
---@return double
function Utils.RandDoubleArea(begin, len)
end
---
---
---返回(-value, value)的随机浮点数。
---@param value double
---@return double
function Utils.RandSym(value)
end
---
---
---当n为正数时1/n概率返回true,否则始终返回false。
---
---例1:Utils.RandTry(3)有1/3概率返回true。
---
---例2:Utils.RandTry(2)有一半概率返回true。
---@param n int
---@return boolean
function Utils.RandTry(n)
end
---
---
---返回实际横/纵坐标对应的格子横/纵坐标。注意每个格子为16像素,实际结果为除以16后向下取整。
---@param a double
---@return int
function Utils.Cell(a)
end
---
---
---返回a与b求余的非负数结果。
---
---例1:Utils.PositiveMod(5, 3)返回2。
---
---例2:Utils.PositiveMod(-5, 3)返回1。
---
---`int c = a % b;`
---
---`if (c < 0) c += b;`
---
---`return c;`
---@param a int
---@param b int
---@return int
function Utils.PositiveMod(a, b)
end
---
---
---若b非0,返回a向下取整整除b的结果,否则返回0。
---
---例1:Utils.FloorDivide(10, 3)返回3。
---
---例2:Utils.FloorDivide(-4, 3)返回-2。
---
---`return a / b - ((a < 0 && a % b != 0) ? 1 : 0);`
---@param a int
---@param b int
---@return int
function Utils.FloorDivide(a, b)
end
---
---
---返回以period为周期、以begin为初相位的正弦波在相位phase的值。
---
---`return sin(begin + 2 * PI * float(phase % period) / period);`
---@overload fun(phase:int,period:int):int
---@param phase int
---@param period int
---@param begin int @[ default `0` ]
---@return double
function Utils.SinValue(phase, period, begin)
end
---
---
---返回以period为周期、以begin为初相位的余弦波在相位phase的值。
---
---`return cos(begin + 2 * PI * float(phase % period) / period);`
---@overload fun(phase:int,period:int):int
---@param phase int
---@param period int
---@param begin int @[ default `0` ]
---@return double
function Utils.CosValue(phase, period, begin)
end
---
---
---返回start值往target值方向移动step长度的结果,若到达target值,则返回target值。
---
---例1:Utils.ToTargetValue(1, 10, 5)返回6。
---
---例2:Utils.ToTargetValue(6, 10, 5)返回10。
---@param start int
---@param target int
---@param step int
---@return int
function Utils.ToTargetValue(start, target, step)
end
---Returns the distance from point (x1, y1) to point (x2, y2).
---
---返回点(x1, y1)到点(x2, y2)的距离。
---
---例:Utils.GetPointsDistance(1.0,0.0,4.0,4.0)返回5.0。
---@param x1 double
---@param y1 double
---@param x2 double
---@param y2 double
---@return double
function Utils.GetPointsDistance(x1, y1, x2, y2)
end
---
---
---返回点(x, y)到原点(0, 0)的距离。
---
---例:Utils.GetDistance(3.0, 4.0)返回5.0。
---@param x double
---@param y double
---@return double
function Utils.GetDistance(x, y)
end
---
---
---返回点(x, y)到以点(x1, y1)和点(x2, y2)为两端点的线段的距离。
---@param x double
---@param y double
---@param x1 double
---@param y1 double
---@param x2 double
---@param y2 double
---@return double
function Utils.GetPointSegmentDistance(x, y, x1, y1, x2, y2)
end
---
---
---返回向量(x, y)与横坐标的夹角。
---
---例1:Utils.GetAngle(1, 1)返回π/4。
---
---例2:Utils.GetAngle(0, 1)返回π/2。
---@param x double
---@param y double
---@return double
function Utils.GetAngle(x, y)
end
---
---
---将角度按2π周期增加或减少,返回最终限定在区间(-π, π]内的结果。
---
---@param angle double
---@return double
function Utils.FixAngle(angle)
end
---
---
---将极坐标转换为直角坐标,返回横坐标和纵坐标。
---
---`x = length * cos(angle);`
---
---`y = length * sin(angle);`
---
---@param length double
---@param angle double
---@return double,double
function Utils.GetXYFromPolar(length, angle)
end
---
---
---将点(x, y)绕原点旋转指定角度,返回旋转后的横坐标和纵坐标。
---
---`double dx = x, dy = y;`
---
---`x = dx * cos(angle) - dy * sin(angle);`
---
---`y = dx * sin(angle) + dy * cos(angle);`
---
---@param x double
---@param y double
---@param angle double
---@return double,double
function Utils.RotateXY(x, y, angle)
end
---
---
---将一个二维速度(speedX, speedY)以恒定速度(dec)降低,返回新的横速度和纵速度。
---@param speedX double
---@param speedY double
---@param dec double
---@return double,double
function Utils.SlowSpeed2D(speedX, speedY, dec)
end
---
---
---将一个速度以恒定速度(dec)降低,返回新的速度。
---@param speed double
---@param dec double
---@return double
function Utils.SlowSpeed1D(speed, dec)
end
---
---
---将一个二维速度(speedX, speedY)进行受力,返回新的横速度和纵速度。
---@param speedX double
---@param speedY double
---@param force double
---@param forceAngle double
---@param maxSpeed double
---@return double,double
function Utils.ForceSpeed2D(speedX, speedY, force, forceAngle, maxSpeed)
end
return Utils
================================================
FILE: apis/WorldData.lua
================================================
---@class WorldData
---@field worldName string
---@field worldSeed int
---@field gameTime int
---@field dayTime int
---@field realDayTime double
---@field daySpeed double
---@field spawnXi int
---@field spawnYi int
---@field weatherTime int
---@field gameMode int
---@field windSpeed double
---@field windAcc double
---@field weatherRate double
---@field isOnWeather boolean
---@field noPvp boolean
---@field noBlowTiles boolean
---@field useLoginSystem boolean
---@field noAllowWrongFormatPlayerName boolean
---@field clientSideCharacters boolean
local WorldData = {}
---@return WorldData
function WorldData.new()
end
return WorldData
================================================
FILE: apis/WorldDataUtils.lua
================================================
---@class WorldDataUtils
local WorldDataUtils = {}
---Load
---@param worldName string
---@param worldData WorldData
---@return boolean
function WorldDataUtils.Load(worldName, worldData)
end
---Save
---@param worldData WorldData
function WorldDataUtils.Save(worldData)
end
---Remove
---@param worldName string
function WorldDataUtils.Remove(worldName)
end
---GenerateSeed
---@param seedString string
---@return int
function WorldDataUtils.GenerateSeed(seedString)
end
return WorldDataUtils
================================================
FILE: apis/WorldGenArea.lua
================================================
---@class WorldGenArea
---@field xi int
---@field yi int
---@field wi int
---@field hi int
local WorldGenArea = {}
---new
---@overload fun():WorldGenArea
---@param xi int
---@param yi int
---@param wi int
---@param hi int
---@return WorldGenArea
function WorldGenArea.new(xi, yi, wi, hi)
end
return WorldGenArea
================================================
FILE: apis/WorldGenChunkBuffer.lua
================================================
---@class WorldGenChunkBufferElement
---@field biomeType int
---@field biomeID int
---@field isFrontPreset boolean
---@field isWallPreset boolean
---@field isLiquidPreset boolean
---@field isFrontSettled boolean
---@field isWallSettled boolean
---@field isLiquidSettled boolean
---@field isGrassCoverPreset boolean
local WorldGenChunkBufferElement = {}
---@class WorldGenChunkBufferElementMask
---@field biomeType boolean
---@field biomeID boolean
---@field isFrontPreset boolean
---@field isWallPreset boolean
---@field isLiquidPreset boolean
---@field isFrontSettled boolean
---@field isWallSettled boolean
---@field isLiquidSettled boolean
---@field isGrassCoverPreset boolean
local WorldGenChunkBufferElementMask = {}
---@class WorldGenChunkBuffer
local WorldGenChunkBuffer = {}
---GetUnit
---@param xi int
---@param yi int
---@return WorldGenChunkBufferElement
function WorldGenChunkBuffer:GetUnit(xi, yi)
end
---GetSample
---@param id int
---@return WorldGenChunkBufferElement
function WorldGenChunkBuffer:GetSample(id)
end
---ClearSample
---@param id int
function WorldGenChunkBuffer:ClearSample(id)
end
---GetMask
---@param id int
---@return WorldGenChunkBufferElementMask
function WorldGenChunkBuffer:GetMask(id)
end
---ClearMask
---@param id int
function WorldGenChunkBuffer:ClearMask(id)
end
---ApplySampleByMask
---@param xi int
---@param yi int
---@param wi int
---@param hi int
---@param sampleID int
---@param maskID int
function WorldGenChunkBuffer:ApplySampleByMask(xi, yi, wi, hi, sampleID, maskID)
end
---ApplySampleByMaskByCondition
---@overload fun(xi:int,yi:int,wi:int,hi:int,sampleID:int,maskID:int,conditionMaskID:int,conditionMaskID:int)
---@param xi int
---@param yi int
---@param wi int
---@param hi int
---@param sampleID int
---@param maskID int
---@param conditionSampleID int
---@param conditionMaskID int
---@param logicOR boolean
function WorldGenChunkBuffer:ApplySampleByMaskByCondition(xi, yi, wi, hi, sampleID, maskID, conditionSampleID, conditionMaskID, logicOR)
end
---HasAreaSameSampleByMask
---@overload fun(xi:int,yi:int,wi:int,hi:int,sampleID:int,maskID:int)
---@param xi int
---@param yi int
---@param wi int
---@param hi int
---@param sampleID int
---@param maskID int
---@param logicOR boolean
function WorldGenChunkBuffer:HasAreaSameSampleByMask(xi, yi, wi, hi, sampleID, maskID, logicOR)
end
---CreateAllPlaceableByBiomeType
---@overload fun(xi:int,yi:int,wi:int,hi:int,biomeType:int)
---@param xi int
---@param yi int
---@param wi int
---@param hi int
---@param biomeType int
---@param boundaryArrayID int
function WorldGenChunkBuffer:CreateAllPlaceableByBiomeType(xi, yi, wi, hi, biomeType, boundaryArrayID)
end
---IsAreaHasSolid
---@param xi int
---@param yi int
---@param wi int
---@param hi int
---@return boolean
function WorldGenChunkBuffer:IsAreaHasSolid(xi, yi, wi, hi)
end
---AddBoundaryArray
---@param boundaryArray int[]
---@return int
function WorldGenChunkBuffer:AddBoundaryArray(boundaryArray)
end
---UpdateBoundaryArray
---@param boundaryArrayID int
---@param boundaryArray int[]
function WorldGenChunkBuffer:UpdateBoundaryArray(boundaryArrayID, boundaryArray)
end
---@return WorldGenCode
function WorldGenChunkBuffer:GetCode()
end
---RunCodeArea
---@param xi int
---@param yi int
---@param wi int
---@param hi int
function WorldGenChunkBuffer:RunCodeArea(xi, yi, wi, hi)
end
---SetBiomeArea
---@param xi int
---@param yi int
---@param wi int
---@param hi int
---@param biomeType int
---@param biomeID int
---@param isApplyFront boolean
---@param isApplyWall boolean
function WorldGenChunkBuffer:SetBiomeArea(xi, yi, wi, hi, biomeType, biomeID, isApplyFront, isApplyWall)
end
---SetBiomeIDAreaByBiomeType
---@param xi int
---@param yi int
---@param wi int
---@param hi int
---@param biomeType int
---@param biomeID int
function WorldGenChunkBuffer:SetBiomeIDAreaByBiomeType(xi, yi, wi, hi, biomeType, biomeID)
end
---SetBiomeIDFromMatrixByBiomeType
---@param biomeType int
---@param matrixTable int[]
function WorldGenChunkBuffer:SetBiomeIDFromMatrixByBiomeType(biomeType, matrixTable)
end
function WorldGenChunkBuffer:PushAllSubBlocks()
end
---SetTile
---@overload fun(xi:int,yi:int,tileID:int,tag:int)
---@param xi int
---@param yi int
---@param tileID int
---@param tag int
---@param isAllowSlope boolean
function WorldGenChunkBuffer:SetTile(xi, yi, tileID, tag, isAllowSlope)
end
---SetTileArea
---@overload fun(xi:int,yi:int,wi:int,hi:int,tileID:int,tag:int)
---@param xi int
---@param yi int
---@param wi int
---@param hi int
---@param tileID int
---@param tag int
---@param isAllowSlope boolean
function WorldGenChunkBuffer:SetTileArea(xi, yi, wi, hi, tileID, tag, isAllowSlope)
end
---SetTileAreaByCondition
---@overload fun(xi:int,yi:int,wi:int,hi:int,tileID:int,tag:int,isAllowSlope:boolean,conditionSampleID:int,conditionMaskID:int)
---@param xi int
---@param yi int
---@param wi int
---@param hi int
---@param tileID int
---@param tag int
---@param isAllowSlope boolean
---@param conditionSampleID int
---@param conditionMaskID int
---@param logicOR boolean
function WorldGenChunkBuffer:SetTileAreaByCondition(xi, yi, wi, hi, tileID, tag, isAllowSlope, conditionSampleID, conditionMaskID, logicOR)
end
---SetWall
---@overload fun(xi:int,yi:int,wallID:int)
---@param xi int
---@param yi int
---@param wallID int
---@param isAllowSlope boolean
function WorldGenChunkBuffer:SetWall(xi, yi, wallID, isAllowSlope)
end
---SetWallArea
---@overload fun(xi:int,yi:int,wi:int,hi:int,wallID:int)
---@param xi int
---@param yi int
---@param wi int
---@param hi int
---@param wallID int
---@param isAllowSlope boolean
function WorldGenChunkBuffer:SetWallArea(xi, yi, wi, hi, wallID, isAllowSlope)
end
---SetWallAreaByCondition
---@overload fun(xi:int,yi:int,wi:int,hi:int,wallID:int,isAllowSlope:boolean,conditionSampleID:int,conditionMaskID:int)
---@param xi int
---@param yi int
---@param wi int
---@param hi int
---@param wallID int
---@param isAllowSlope boolean
---@param conditionSampleID int
---@param conditionMaskID int
---@param logicOR boolean
function WorldGenChunkBuffer:SetWallAreaByCondition(xi, yi, wi, hi, wallID, isAllowSlope, conditionSampleID, conditionMaskID, logicOR)
end
---SetLiquid
---@param xi int
---@param yi int
---@param liquidID int
---@param amount int
function WorldGenChunkBuffer:SetLiquid(xi, yi, liquidID, amount)
end
---SetLiquidArea
---@param xi int
---@param yi int
---@param wi int
---@param hi int
---@param liquidID int
---@param amount int
function WorldGenChunkBuffer:SetLiquidArea(xi, yi, wi, hi, liquidID, amount)
end
---SetLiquidAreaByCondition
---@overload fun(xi:int,yi:int,wi:int,hi:int,liquidID:int,amount:int,conditionSampleID:int,conditionMaskID:int)
---@param xi int
---@param yi int
---@param wi int
---@param hi int
---@param liquidID int
---@param amount int
---@param conditionSampleID int
---@param conditionMaskID int
---@param logicOR boolean
function WorldGenChunkBuffer:SetLiquidAreaByCondition(xi, yi, wi, hi, liquidID, amount, conditionSampleID, conditionMaskID, logicOR)
end
---ClearFront
---@param xi int
---@param yi int
function WorldGenChunkBuffer:ClearFront(xi, yi)
end
---ClearFrontArea
---@param xi int
---@param yi int
---@param wi int
---@param hi int
function WorldGenChunkBuffer:ClearFrontArea(xi, yi, wi, hi)
end
---
---@param xi int
---@param yi int
function WorldGenChunkBuffer:ClearWall(xi, yi)
end
---
---@param xi int
---@param yi int
---@param wi int
---@param hi int
function WorldGenChunkBuffer:ClearWallArea(xi, yi, wi, hi)
end
---
---@param xi int
---@param yi int
function WorldGenChunkBuffer:ClearFrontAndWall(xi, yi)
end
---
---@param xi int
---@param yi int
---@param wi int
---@param hi int
function WorldGenChunkBuffer:ClearFrontAndWallArea(xi, yi, wi, hi)
end
---ClearLiquid
---@param xi int
---@param yi int
function WorldGenChunkBuffer:ClearLiquid(xi, yi)
end
---ClearLiquidArea
---@param xi int
---@param yi int
---@param wi int
---@param hi int
function WorldGenChunkBuffer:ClearLiquidArea(xi, yi, wi, hi)
end
---PerlinMakeCaveHorizontal
---@param xi int
---@param yi int
---@param size int
---@param height int
---@param scaleX double
---@param persistence double
---@param octaves int
---@param amplitude double
---@param scaleXTop double
---@param persistenceTop double
---@param octavesTop int
---@param amplitudeTop double
---@param scaleXBottom double
---@param persistenceBottom double
---@param octavesBottom int
---@param amplitudeBottom double
function WorldGenChunkBuffer:PerlinMakeCaveHorizontal(xi, yi, size, height, scaleX, persistence, octaves, amplitude, scaleXTop, persistenceTop, octavesTop, amplitudeTop, scaleXBottom, persistenceBottom, octavesBottom, amplitudeBottom)
end
---PerlinMakeCave
---@param xi int
---@param yi int
---@param wi int
---@param hi int
---@param scaleX double
---@param scaleY double
---@param caveRateBegin double
---@param caveRateEnd double
---@param mapYiFadeIn int
---@param fadeInSize int
---@param mapYiFadeOut int
---@param fadeOutSize int
function WorldGenChunkBuffer:PerlinMakeCave(xi, yi, wi, hi, scaleX, scaleY, caveRateBegin, caveRateEnd, mapYiFadeIn, fadeInSize, mapYiFadeOut, fadeOutSize)
end
---MakeCaveRandomDirection
---@param xi int
---@param yi int
function WorldGenChunkBuffer:MakeCaveRandomDirection(xi, yi)
end
---GetRandomAreas
---@param randomKey int
---@param originalWorldGenArea WorldGenArea
---@param elementWidthMin int
---@param elementWidthMax int
---@param elementHeightMin int
---@param elementHeightMax int
---@param density double
function WorldGenChunkBuffer:GetRandomAreas(randomKey, originalWorldGenArea, elementWidthMin, elementWidthMax, elementHeightMin, elementHeightMax, density)
end
---AddBlockRandomOval
---@overload fun(blockID:int,xi:int,yi:int,wi:int,hi:int)
---@overload fun(blockID:int,xi:int,yi:int,wi:int,hi:int,replaceFront:boolean)
---@overload fun(blockID:int,xi:int,yi:int,wi:int,hi:int,replaceFront:boolean,replaceLiquid:boolean)
---@overload fun(blockID:int,xi:int,yi:int,wi:int,hi:int,replaceFront:boolean,replaceLiquid:boolean,placeFrontAir:boolean)
---@overload fun(blockID:int,xi:int,yi:int,wi:int,hi:int,replaceFront:boolean,replaceLiquid:boolean,placeFrontAir:boolean,replaceWall:boolean)
---@param blockID int
---@param xi int
---@param yi int
---@param wi int
---@param hi int
---@param replaceFront boolean
---@param replaceLiquid boolean
---@param placeFrontAir boolean
---@param replaceWall boolean
---@param placeWallAir boolean
function WorldGenChunkBuffer:AddBlockRandomOval(blockID, xi, yi, wi, hi, replaceFront, replaceLiquid, placeFrontAir, replaceWall, placeWallAir)
end
---GenerateLake
---@overload fun(xi:int, yi:int, liquidID:int)
---@param xi int
---@param yi int
---@param liquidID int
---@param maxAllowCount int
---@return boolean
function WorldGenChunkBuffer:GenerateLake(xi, yi, liquidID, maxAllowCount)
end
---写入所有元素。
---
---(1)对于所有预设的前景,根据群系、主次方块信息加入方块,并标记已经放置前景。
---(2)对于所有预设的后景,根据群系、主次方块信息加入方块,并标记已经放置后景。
---(3)对于所有预设的流体,按流体ID加入流体,并标记已经放置流体。
function WorldGenChunkBuffer:SettleAllElementByBiomes()
end
---GetAllFloors
---@param xi int
---@param yi int
---@param wi int
---@param hi int
---@return MapPos[]
function WorldGenChunkBuffer:GetAllFloors(xi, yi, wi, hi)
end
---GenerateTree
---@param xi int
---@param yi int
---@param treeBlockID int
---@return boolean
function WorldGenChunkBuffer:GenerateTree(xi, yi, treeBlockID)
end
---GenerateLargeMushroom
---@param xi int
---@param yi int
---@param capID int
---@param stemID int
---@return boolean
function WorldGenChunkBuffer:GenerateLargeMushroom(xi, yi, capID, stemID)
end
---CreateBuilding
---@overload fun(buildingID:int, xi:int, yi:int)
---@overload fun(buildingID:int, xi:int, yi:int, maxTryTimes:int)
---@overload fun(buildingID:int, xi:int, yi:int, limitXi:int, limitYi:int, limitWi:int, limitHi:int)
---@param buildingID int
---@param xi int
---@param yi int
---@param limitXi int
---@param limitYi int
---@param limitWi int
---@param limitHi int
---@param maxTryTimes int
function WorldGenChunkBuffer:CreateBuilding(buildingID, xi, yi, limitXi, limitYi, limitWi, limitHi, maxTryTimes)
end
function WorldGenChunkBuffer:ApplyBuildings()
end
return WorldGenChunkBuffer
================================================
FILE: apis/WorldGenCode.lua
================================================
---@class WorldGenCodeConfig
local WorldGenCodeConfig = {}
---@class WorldGenCode
local WorldGenCode = {}
---CompileCode
---@param rawCode string
function WorldGenCode:CompileCode(rawCode)
end
---@return WorldGenCodeConfig
function WorldGenCode:GetConfig()
end
---SetConfig
---@param config WorldGenCodeConfig
function WorldGenCode:SetConfig(config)
end
return WorldGenCode
================================================
FILE: apis/WorldGenNoise.lua
================================================
---@class WorldGenNoise
local WorldGenNoise = {}
---SetData
---@param persistence double
---@param octaves int
function WorldGenNoise:SetData(persistence, octaves)
end
---Perlin2D, return (-1.0, 1.0)
---@param x double
---@param y double
---@return double
function WorldGenNoise:Perlin2D(x, y)
end
---Perlin1D, return (-1.0, 1.0)
---@param x double
---@return double
function WorldGenNoise:Perlin1D(x)
end
---GetDoubleFromInt1D, return (-1.0, 1.0)
---@param xi int
---@return double
function WorldGenNoise:GetDoubleFromInt1D(xi)
end
---GetDoubleFromInt2D, return (-1.0, 1.0)
---@param xi int
---@param yi int
---@return double
function WorldGenNoise:GetDoubleFromInt2D(xi, yi)
end
---GetByteFromInt2D, return [0, maxByte)
---@param xi int
---@param yi int
---@param maxByte int
---@return int
function WorldGenNoise:GetByteFromInt2D(xi, yi, maxByte)
end
return WorldGenNoise
================================================
FILE: apis/engine_api/AnimationEvent.lua
================================================
---@class AnimationEvent
local AnimationEvent = {}
---
---@param listener table|function
---@return ListenerID
function AnimationEvent:addListener(listener)
end
---
---@param listenerID ListenerID
function AnimationEvent:removeListener(listenerID)
end
return AnimationEvent
================================================
FILE: apis/engine_api/Animator2D.lua
================================================
---@class Animator2D
local Animator2D = {}
---setFloat
---@param parameterName string
---@param value number
function Animator2D:setFloat(parameterName, value)
end
---getFloat
---@param parameterName string
---@return number
function Animator2D:getFloat(parameterName)
end
---
---@param parameterName string
---@param value number
function Animator2D:setInteger(parameterName, value)
end
---
---@param parameterName string
---@return number
function Animator2D:getInteger(parameterName)
end
---
---@param parameterName string
---@param value boolean
function Animator2D:setBool(parameterName, value)
end
---
---@param parameterName string
---@return boolean
function Animator2D:getBool(parameterName)
end
---setTrigger
---@param parameterName string
function Animator2D:setTrigger(parameterName)
end
---createEventAtTimePoint
---@param clipName string
---@param timePoint number
---@return AnimationEvent
function Animator2D:createEventAtTimePoint(clipName, timePoint)
end
---@param clipName string
---@param timePoint number
---@return AnimationEvent
function Animator2D:getEventAtTimePoint(clipName, timePoint)
end
---@param clipName string
---@param timePoint number
function Animator2D:removeEventAtTimePoint(clipName, timePoint)
end
---setLayerTimeScale
---@param layerIndex number
---@param timeScale number
function Animator2D:setLayerTimeScale(layerIndex, timeScale)
end
---@param layerIndex number
---@return number
function Animator2D:getLayerTimeScale(layerIndex)
end
return Animator2D
================================================
FILE: apis/engine_api/AnimatorData2D.lua
================================================
---@class AnimatorData2D
local AnimatorData2D = {}
---new
---@param dataTable table
---@return AnimatorData2D
function AnimatorData2D.new(dataTable)
end
return AnimatorData2D
================================================
FILE: apis/engine_api/App.lua
================================================
---@class App
---@field appName string
---@field companyName string
---@field dataPath string
---@field persistentDataPath string
---@field engineVersion string
---@field isMobile boolean
---@field isPC boolean
local App = {}
return App
================================================
FILE: apis/engine_api/Array.lua
================================================
---@class Array
---@field count number
local Array = {}
return Array
================================================
FILE: apis/engine_api/AssetBundle.lua
================================================
---@class AssetBundle
local AssetBundle = {}
---
---@return AssetBundle
function AssetBundle.new()
end
---clone
---@param value AssetBundle
---@return AssetBundle
function AssetBundle.clone(value)
end
---
---@param abPath string
---@return string
function AssetBundle:loadFromFileSystem(abPath)
end
---
---@param abPath string
function AssetBundle:saveToFileSystem(abPath)
end
---
---@param filePath string
---@param data Bytes
---@param offset number
---@param size number
function AssetBundle:addFileData(filePath, data, offset, size)
end
---
---@param filePath string
---@return string
function AssetBundle:getFileString(filePath)
end
---
---@param filePath string
---@return Bytes
function AssetBundle:getFileBytes(filePath)
end
function AssetBundle:clear()
end
function AssetBundle:freeMemory()
end
---
---@param filePath string
---@return boolean
function AssetBundle:isFileExist(filePath)
end
---
---@param folderPath string
---@return boolean
function AssetBundle:isFolderExist(folderPath)
end
---
---@param filePath string
---@param isFullPath boolean
---@return table
function AssetBundle:getAllSubFolders(filePath, isFullPath)
end
---
---@param path string
---@param extension string
---@param resultNoExtension boolean
---@param getAbsPath boolean
---@param recursion boolean
---@return table
function AssetBundle:getAllFiles(path, extension, resultNoExtension, getAbsPath, recursion)
end
return AssetBundle
================================================
FILE: apis/engine_api/AssetManager.lua
================================================
---@class AssetManager
local AssetManager = {}
---getLastWriteTime
---@param path string
---@return DateTime
function AssetManager.getLastWriteTime(path)
end
---readAsString
---@param path string
---@return string
function AssetManager.readAsString(path)
end
---readAsBytes
---@param path string
---@return Bytes
function AssetManager.readAsBytes(path)
end
---
---@param filePath string
---@param isFullPath boolean
---@return string[]
function AssetManager.getAllSubFolders(filePath, isFullPath)
end
---
---@param path string
---@param extension string
---@param resultNoExtension boolean
---@param getAbsPath boolean
---@param recursion boolean
---@return string[]
function AssetManager.getAllFiles(path, extension, resultNoExtension, getAbsPath, recursion)
end
---isPathExist
---@param path string
---@return boolean
function AssetManager.isPathExist(path)
end
---genPackFromSource
---@param sourceParentFolderPath string
---@param folderName string
---@param assetMappingPath string
---@return string
function AssetManager.genPackFromSource(sourceParentFolderPath, folderName, assetMappingPath)
end
return AssetManager
================================================
FILE: apis/engine_api/AtlasInfos.lua
================================================
---@class AtlasInfos
local AtlasInfos = {}
return AtlasInfos
================================================
FILE: apis/engine_api/AtlasLoader.lua
================================================
---@class AtlasLoader
local AtlasLoader = {}
---saveToFileSystem
---@param atlasInfos AtlasInfos
---@param folderPath string
function AtlasLoader.saveToFileSystem(atlasInfos, folderPath)
end
---saveToAssetBundle
---@param assetBundle AssetBundle
---@param atlasInfos AtlasInfos
---@param folderPath string
function AtlasLoader.saveToAssetBundle(assetBundle, atlasInfos, folderPath)
end
---loadFromFileSystem
---@param folderPath string
---@return AtlasInfos
function AtlasLoader.loadFromFileSystem(folderPath)
end
---loadFromAssetBundle
---@param assetBundle AssetBundle
---@param folderPath string
---@return AtlasInfos
function AtlasLoader.loadFromAssetBundle(assetBundle, folderPath)
end
return AtlasLoader
================================================
FILE: apis/engine_api/Audio.lua
================================================
---@class Audio
---@field musicVolume number
local Audio = {}
---
---@param filePath string
---@return number
function Audio.loadSoundEffectFromFileSystem(filePath)
end
---
---@param assetBundle AssetBundle
---@param filePath string
---@return number
function Audio.loadSoundEffectFromAssetBundle(assetBundle, filePath)
end
---unloadSoundEffectByID
---@param soundID number
function Audio.unloadSoundEffectByID(soundID)
end
---
---@param bytes Bytes
---@param offset number
---@param size number
---@return number
function Audio.loadSoundEffectFromMemory(bytes, offset, size)
end
---
---@param filePath string
---@return number
function Audio.loadMusicEffectFromFileSystem(filePath)
end
---
---@param assetBundle AssetBundle
---@param filePath string
---@return number
function Audio.loadMusicEffectFromAssetBundle(assetBundle, filePath)
end
---
---@param bytes Bytes
---@param offset number
---@param size number
---@return number
function Audio.loadMusicEffectFromMemory(bytes, offset, size)
end
---unloadMusicEffectByID
---@param musicID number
function Audio.unloadMusicEffectByID(musicID)
end
---
---@overload fun(id:number)
---@overload fun(id:number, loops:number)
---@overload fun(id:number, loops:number, fadeInTime:number)
---@overload fun(id:number, loops:number, fadeInTime:number, beginTime:number)
---@param id number
---@param loops number
---@param fadeInTime number
---@param beginTime number
function Audio.playMusic(id, loops, fadeInTime, beginTime)
end
---stopMusic
---@param fadeOutTime number
function Audio.stopMusic(fadeOutTime)
end
function Audio.pauseMusic()
end
function Audio.resumeMusic()
end
---@return FadingState_Value
function Audio.getMusicFadingState()
end
---getMusicPlayingTimePoint
---@param musicID string
---@return string
function Audio.getMusicPlayingTimePoint(musicID)
end
---
---@param volume number
function Audio.setMusicVolume(volume)
end
---
---@param volume number
function Audio.setAllSoundEffectVolume(volume)
end
function Audio.isMusicPaused()
end
function Audio.isMusicPlaying()
end
---
---@param listener table|function
---@return ListenerID
function Audio:addMusicFinishedListener(listener)
end
---
---@param listenerID ListenerID
function Audio:removeMusicFinishedListener(listenerID)
end
return Audio
================================================
FILE: apis/engine_api/ByteStream.lua
================================================
---@class ByteStream
---@field empty boolean
---@field count number
---@field capacity number
---@field readableCount number
local ByteStream = {}
---
---@overload fun():ByteStream
---@param capacity number
---@return ByteStream
function ByteStream.new(capacity)
end
---clone
---@param value ByteStream
---@return ByteStream
function ByteStream.clone(value)
end
function ByteStream:clear()
end
function ByteStream:freeMemory()
end
---@param value number
function ByteStream:writeInt(value)
end
---@return number
function ByteStream:readInt()
end
---@param value number
function ByteStream:writeIntVarLen(value)
end
---@return number
function ByteStream:readIntVarLen()
end
---@param value number
function ByteStream:writeFloat(value)
end
---@return number
function ByteStream:readFloat()
end
---@param value number
function ByteStream:writeDouble(value)
end
---@return number
function ByteStream:readDouble()
end
---@param value boolean
function ByteStream:writeBoolean(value)
end
---@return boolean
function ByteStream:readBoolean()
end
---@param value string
function ByteStream:writeString(value)
end
---@return string
function ByteStream:readString()
end
return ByteStream
================================================
FILE: apis/engine_api/Bytes.lua
================================================
---@class Bytes
---@field empty boolean
---@field count number
---@field capacity number
local Bytes = {}
---
---@overload fun():Bytes
---@param capacity number
---@return Bytes
function Bytes.new(capacity)
end
---clone
---@param value Bytes
---@return Bytes
function Bytes.clone(value)
end
---
---@param value number
---@return number
function Bytes:add(value)
end
---
---@param index number
---@param value number
function Bytes:insert(index, value)
end
function Bytes:clear()
end
function Bytes:freeMemory()
end
---
---@overload fun(count:number)
---@param count number
---@param fill number
function Bytes:setCount(count, fill)
end
---
---@param capacity number
function Bytes:setCapacity(capacity)
end
---
---@param bytes Bytes
function Bytes:swap(bytes)
end
---
---@overload fun(bytes:Bytes)
---@param bytes Bytes
---@param offset number
---@param count number
function Bytes:addBytes(bytes, offset, count)
end
---
---@param startOverwriteOffset number
---@param sourceBytes Bytes
---@param sourceOffset number
---@param sourceCount number
function Bytes:overwrite(startOverwriteOffset, sourceBytes, sourceOffset, sourceCount)
end
return Bytes
================================================
FILE: apis/engine_api/CameraComponentWrapper.lua
================================================
---@class CameraComponentWrapper:ComponentWrapper
---@field projection CameraProjection_Value
---@field clippingPlaneNear number
---@field clippingPlaneFar number
---@field fov number
---@field viewportRect RectFloatEx
---@field targetDisplay number
local CameraComponentWrapper = {}
return CameraComponentWrapper
================================================
FILE: apis/engine_api/CameraProjection.lua
================================================
---@class CameraProjection_Value
---@class CameraProjection
---@field Perspective CameraProjection_Value
---@field Orthographic CameraProjection_Value
local CameraProjection = {}
return CameraProjection
================================================
FILE: apis/engine_api/CanvasComponentWrapper.lua
================================================
---@class CanvasComponentWrapper:ComponentWrapper
---@field uiRoot UICanvas
---@field displayMode CanvasDisplayMode
---@field targetDisplay number
local CanvasComponentWrapper = {}
return CanvasComponentWrapper
================================================
FILE: apis/engine_api/CanvasDisplayMode.lua
================================================
---@class CanvasDisplayMode_Value
---@class CanvasDisplayMode
---@field ScreenSpaceOverlay CanvasDisplayMode_Value
---@field ScreenSpaceCamera CanvasDisplayMode_Value
---@field WorldSpace CanvasDisplayMode_Value
local CanvasDisplayMode = {}
return CanvasDisplayMode
================================================
FILE: apis/engine_api/ClipCollection2D.lua
================================================
---@class ClipCollection2D
local ClipCollection2D = {}
---new
---@param jointCollection2D JointCollection2D
---@return ClipCollection2D
function ClipCollection2D.new(jointCollection2D)
end
---addClip
---@param clipTable table
function ClipCollection2D:addClip(clipTable)
end
return ClipCollection2D
================================================
FILE: apis/engine_api/Color.lua
================================================
---@API
---@class Color:SerializableType 描述一个颜色。
---@field red number 红色通道分量。取值为[0, 255]。
---@field green number 绿色通道分量。取值为[0, 255]。
---@field blue number 蓝色通道分量。取值为[0, 255]。
---@field alpha number 透明度通道分量。取值为[0, 255]。
---@field Red Color 返回红色对象。
---@field Black Color 返回黑色对象。
---@field Gray Color 返回灰色对象。
---@field Green Color 返回绿色对象。
---@field Blue Color 返回蓝色对象。
---@field LightBlue Color 返回淡蓝色对象。
---@field Yellow Color 返回黄色对象。
---@field FrenchGray Color 返回淡灰色对象。
---@field White Color 返回白色对象。
local Color = {}
---创建一个颜色对象。
---@overload fun():Color
---@overload fun(red:number,green:number,blue:number):Color
---@param red number 红色通道分量。取值为[0, 255]。
---@param green number 绿色通道分量。取值为[0, 255]。
---@param blue number 蓝色通道分量。取值为[0, 255]。
---@param alpha number 透明度通道分量。取值为[0, 255]。
---@return Color 新的颜色对象。
function Color.new(red, green, blue, alpha)
end
---@param value Color
---@return Color
function Color.clone(value)
end
return Color
================================================
FILE: apis/engine_api/ComponentID.lua
================================================
---@class ComponentID_Value:number
local ComponentID_Value = {}
---@class ComponentID
---@field Transform ComponentID_Value
---@field Rigidbody ComponentID_Value
local ComponentID = {}
return ComponentID
================================================
FILE: apis/engine_api/ComponentWrapper.lua
================================================
---@class ComponentWrapper
local ComponentWrapper = {}
function ComponentWrapper:init()
end
function ComponentWrapper:destroy()
end
return ComponentWrapper
================================================
FILE: apis/engine_api/DateTime.lua
================================================
---@class DateTime
local DateTime = {}
return DateTime
================================================
FILE: apis/engine_api/FadingState.lua
================================================
---@class FadingState_Value
---@class FadingState
---@field NoFading FadingState_Value
---@field FadingIn FadingState_Value
---@field FadingOut FadingState_Value
local FadingState = {}
return FadingState
================================================
FILE: apis/engine_api/File.lua
================================================
---@class File
local File = {}
---getLastWriteTime
---@param path string
---@return DateTime
function File.getLastWriteTime(path)
end
---
---@param filePath string
---@param isFullPath boolean
---@return string[]
function File.getAllSubFolders(filePath, isFullPath)
end
---
---@param path string
---@param extension string
---@param resultNoExtension boolean
---@param getAbsPath boolean
---@param recursion boolean
---@return string[]
function File.getAllFiles(path, extension, resultNoExtension, getAbsPath, recursion)
end
---saveString
---@param path string
---@param str string
function File.saveString(path, str)
end
---saveBytes
---@param path string
---@param bytes Bytes
function File.saveBytes(path, bytes)
end
---readAsString
---@param path string
---@return string
function File.readAsString(path)
end
---readAsBytes
---@param path string
---@return Bytes
function File.readAsBytes(path)
end
---isPathExist
---@param path string
---@return boolean
function File.isPathExist(path)
end
---openFolderWindow
---@param path string
function File.openFolderWindow(path)
end
---makeFolder
---@param path string
function File.makeFolder(path)
end
return File
================================================
FILE: apis/engine_api/FileTimeType.lua
================================================
---@class FileTimeType
local FileTimeType = {}
return FileTimeType
================================================
FILE: apis/engine_api/FontManager.lua
================================================
---@class FontManager
local FontManager = {}
---load
---@param filePath string
---@param fontName string
---@return number
function FontManager.load(filePath, fontName)
end
return FontManager
================================================
FILE: apis/engine_api/FontSprite.lua
================================================
---@class FontSprite
local FontSprite = {}
---drawText
---@param text string
---@param pos Vector2
---@param size Size
---@param textStyle TextStyle
function FontSprite.drawText(text, pos, size, textStyle)
end
---drawTextBuffer
---@param pos Vector2
---@param textBuffer TextBuffer
function FontSprite.drawTextBuffer(pos, textBuffer)
end
---getBuffer
---@param text string
---@param size Size
---@param textStyle TextStyle
---@return TextBuffer
function FontSprite.getBuffer(text, size, textStyle)
end
return FontSprite
================================================
FILE: apis/engine_api/GameObject.lua
================================================
---@class GameObject
---@field transform TransformComponentWrapper
---@field camera CameraComponentWrapper
---@field meshFilter MeshFilterComponentWrapper
---@field meshRenderer MeshRendererComponentWrapper
---@field canvas CanvasComponentWrapper
---@field rigidbody Rigidbody
---@field children table
local GameObject = {}
---
---@return GameObject
function GameObject.instantiate(gameObject)
end
---
---@param gameObject GameObject
function GameObject.destroy(gameObject)
end
function GameObject.flush()
end
---
---@param componentID ComponentID_Value
function GameObject:addComponent(componentID)
end
---
---@param componentID ComponentID_Value
function GameObject:removeComponent(componentID)
end
---
---@param gameObject GameObject
function GameObject:addChild(gameObject)
end
return GameObject
================================================
FILE: apis/engine_api/GameWindow.lua
================================================
---@class GameWindow
---@field caption string
---@field width number
---@field height number
---@field fullScreen boolean
---@field displayResolution Size
local GameWindow = {}
return GameWindow
================================================
FILE: apis/engine_api/GlobalHook.lua
================================================
---@class GlobalHook
local GlobalHook = {}
---
---@param hookName string
---@param listener table|function
function GlobalHook.add(hookName, listener)
end
return GlobalHook
================================================
FILE: apis/engine_api/GraphicsDevice.lua
================================================
---@class GraphicsDevice
---@field vendorName string
---@field rendererName string
---@field drawCalls number
---@field primitiveCount number
local GraphicsDevice = {}
---clear
---@param color Color
function GraphicsDevice.clear(color)
end
---
---@overload fun(a:Vector2,b:Vector2,color:Color)
---@param a Vector2
---@param b Vector2
---@param color Color
---@param depth number
function GraphicsDevice.drawLine2D(a, b, color, depth)
end
---
---@overload fun(point:Vector2,color:Color)
---@param point Vector2
---@param color Color
---@param depth number
function GraphicsDevice.drawPoint2D(point, color, depth)
end
---
---@overload fun(rect:RectFloat,color:Color)
---@param rect RectFloat
---@param color Color
---@param depth number
function GraphicsDevice.drawRect2D(rect, color, depth)
end
---
---@overload fun(rect:RectFloat,color:Color)
---@param rect RectFloat
---@param color Color
---@param depth number
function GraphicsDevice.drawRectHollow2D(rect, color, depth)
end
return GraphicsDevice
================================================
FILE: apis/engine_api/HotKeyCombination.lua
================================================
---@class HotKeyCombination
local HotKeyCombination = {}
---
---@param listener table|function
---@return ListenerID
function HotKeyCombination:addListener(listener)
end
---
---@param listenerID ListenerID
function HotKeyCombination:removeListener(listenerID)
end
return HotKeyCombination
================================================
FILE: apis/engine_api/Hotfix.lua
================================================
---@class Hotfix
local Hotfix = {}
---
function Hotfix.updateNextTick()
end
return Hotfix
================================================
FILE: apis/engine_api/Image.lua
================================================
---@class Image
local Image = {}
---loadPngFromMemory
---@param bytes Bytes
---@param offset number
---@param size number
---@param flip boolean
---@return ImageInfo
function Image.loadPngFromMemory(bytes, offset, size, flip)
end
---loadPngFromFileSystem
---@param filePath string
---@param flip boolean
---@return ImageInfo
function Image.loadPngFromFileSystem(filePath, flip)
end
---loadPngFromAssetBundle
---@param assetBundle AssetBundle
---@param filePath string
---@param flip boolean
---@return ImageInfo
function Image.loadPngFromAssetBundle(assetBundle, filePath, flip)
end
---saveAsPngToMemory
---@param imageInfo ImageInfo
---@param bytes Bytes
function Image.saveAsPngToMemory(imageInfo, bytes)
end
---saveAsPngToFileSystem
---@param imageInfo ImageInfo
---@param filePath string
function Image.saveAsPngToFileSystem(imageInfo, filePath)
end
---saveAsPngToAssetBundle
---@param imageInfo ImageInfo
---@param assetBundle AssetBundle
---@param filePath string
function Image.saveAsPngToAssetBundle(imageInfo, assetBundle, filePath)
end
return Image
================================================
FILE: apis/engine_api/ImageInfo.lua
================================================
---@class ImageInfo
---@field width number
---@field height number
---@field channelCount number
---@field byteData Bytes
local ImageInfo = {}
---
---@param width number
---@param height number
---@param channelCount number
---@return ImageInfo
function ImageInfo.new(width, height, channelCount)
end
---clone
---@param value ImageInfo
---@return ImageInfo
function ImageInfo.clone(value)
end
return ImageInfo
================================================
FILE: apis/engine_api/Input.lua
================================================
---@class Input
---@field mouse Mouse
---@field keyboard Keyboard
---@field joystick JoystickDevice[]
local Input = {}
return Input
================================================
FILE: apis/engine_api/IntegratedClient.lua
================================================
---@class IntegratedClient : IntegratedEnv
---@field main IntegratedClient
local IntegratedClient = {}
---
---@param listener table|function
---@return ListenerID
function IntegratedClient:addOnRenderListener(listener)
end
---
---@param listenerID ListenerID
function IntegratedClient:removeOnRenderListener(listenerID)
end
---
---@param listener table|function
---@return ListenerID
function IntegratedClient:addOnWindowResizeListener(listener)
end
---
---@param listenerID ListenerID
function IntegratedClient:removeOnWindowResizeListener(listenerID)
end
return IntegratedClient
================================================
FILE: apis/engine_api/IntegratedEnv.lua
================================================
---@class IntegratedEnv
---@field fps number
---@field gameSpeed number
---@field isMaxFPS boolean
---@field registry Registry
local IntegratedEnv = {}
---
---@param listener table|function
---@return ListenerID
function IntegratedEnv:addOnStartListener(listener)
end
---
---@param listenerID ListenerID
function IntegratedEnv:removeOnStartListener(listenerID)
end
---
---@param listener table|function
---@return ListenerID
function IntegratedEnv:addOnUpdateListener(listener)
end
---
---@param listenerID ListenerID
function IntegratedEnv:removeOnUpdateListener(listenerID)
end
---
---@overload fun():ScheduleID
---@param intervalTicks number
---@return ScheduleID
function IntegratedEnv:createSchedule(intervalTicks)
end
---getSchedule
---@param scheduleID ScheduleID
---@return Schedule
function IntegratedEnv:getSchedule(scheduleID)
end
---
---@param scheduleID ScheduleID
function IntegratedEnv:removeSchedule(scheduleID)
end
return IntegratedEnv
================================================
FILE: apis/engine_api/Joint2D.lua
================================================
---@class Joint2D
---@field transform Transform2D
---@field size Size
---@field angle number
---@field visible boolean
local Joint2D = {}
---new
---@param name string
---@param originalPos Vector2
---@param size Size
---@return Joint2D
function Joint2D.new(name, originalPos, size)
end
---addChild
---@overload fun(pos:Vector2,skeletonNode:Joint2D)
---@param pos Vector2
---@param skeletonNode Joint2D
---@param overlapping boolean
function Joint2D:addChild(pos, skeletonNode, overlapping)
end
---getChild
---@param name string
---@return Joint2D
function Joint2D:getChild(name)
end
---@return ObbDouble
function Joint2D:getWorldObb()
end
---setTexture
---@param textureName string
---@param textureLocation TextureLocation
---@param positionOffset Vector2
---@param sourceRect Rect
function Joint2D:setTexture(textureName, textureLocation, positionOffset, sourceRect)
end
return Joint2D
================================================
FILE: apis/engine_api/JointBody2D.lua
================================================
---@class JointBody2D
---@field joints JointCollection2D
---@field animator Animator2D
local JointBody2D = {}
---new
---@param jointCollection2D JointCollection2D
---@return JointBody2D
function JointBody2D.new(jointCollection2D)
end
---@return JointBody2D
function JointBody2D:clone()
end
---update
---@overload fun()
---@param withAnimation boolean
function JointBody2D:update(withAnimation)
end
---setAnimator
---@param clipCollection2D ClipCollection2D
---@param animatorData2D Animator2D
function JointBody2D:setAnimator(clipCollection2D, animatorData2D)
end
---solveIK
---@overload fun(nodeEndName:string,nodeStartName:string,targetPos:Vector2):boolean
---@param nodeStartName string
---@param nodeEndName string
---@param nodeEnd Joint2D
---@param nodeStart Joint2D
---@param targetPos Vector2
---@return boolean
function JointBody2D:solveIK(nodeEnd, nodeStart, targetPos)
end
return JointBody2D
================================================
FILE: apis/engine_api/JointCollection2D.lua
================================================
---@class JointCollection2D
---@field root Joint2D
---@field position Vector2
---@field rotation number
---@field scale Vector2
---@field flip boolean
local JointCollection2D = {}
---new
---@return JointCollection2D
function JointCollection2D.new()
end
---getJoint
---@param name string
---@return Joint2D
function JointCollection2D:getJoint(name)
end
---render
---@overload fun()
---@param camera CameraComponentWrapper
function JointCollection2D:render(camera)
end
return JointCollection2D
================================================
FILE: apis/engine_api/Joystick.lua
================================================
---@class Joystick
---@type JoystickDevice[]
---@field isSupported boolean
local Joystick = {}
return Joystick
================================================
FILE: apis/engine_api/JoystickDevice.lua
================================================
---@class JoystickDevice
---@field isConnected boolean
---@field axisCount number
local JoystickDevice = {}
---getAxis
---@param index number
---@return number
function JoystickDevice:getAxis(index)
end
return JoystickDevice
================================================
FILE: apis/engine_api/JsonUtil.lua
================================================
---@API
---@class JsonUtil Json通用类。
local JsonUtil = {}
---将一个lua表序列化为json字符串。
---@param t table
---@return string
function JsonUtil.toJson(t)
end
---将一个json字符串反序列化为lua表。
---@param json string
---@return table
function JsonUtil.fromJson(json)
end
return JsonUtil
================================================
FILE: apis/engine_api/KeyTrigger.lua
================================================
---@class KeyTrigger
local KeyTrigger = {}
---
---@param listener table|function
---@return ListenerID
function KeyTrigger:addListener(listener)
end
---
---@param listenerID ListenerID
function KeyTrigger:removeListener(listenerID)
end
return KeyTrigger
================================================
FILE: apis/engine_api/Keyboard.lua
================================================
---@class Keyboard
local Keyboard = {}
---isKeyPressed
---@param key Keys_Value
---@return boolean
function Keyboard:isKeyPressed(key)
end
---isKeyReleased
---@param key Keys_Value
---@return boolean
function Keyboard:isKeyReleased(key)
end
---getHotKeys
---@overload fun(key1:Keys_Value):HotKeyCombination
---@overload fun(key1:Keys_Value,key2:Keys_Value):HotKeyCombination
---@overload fun(key1:Keys_Value,key2:Keys_Value,key3:Keys_Value):HotKeyCombination
---@param key1 Keys_Value
---@param key2 Keys_Value
---@param key3 Keys_Value
---@return HotKeyCombination
function Keyboard:getHotKeys(key1, key2, key3)
end
---
---@param key Keys_Value
---@return KeyTrigger
function Keyboard:getPressDownTrigger(key)
end
---
---@param key Keys_Value
---@return KeyTrigger
function Keyboard:getPressUpTrigger(key)
end
return Keyboard
================================================
FILE: apis/engine_api/Keys.lua
================================================
---@API
---@class Keys_Value 描述一个键盘键值。
local Keys_Value = {}
---@class Keys 键盘键值枚举类。
---@field None Keys_Value
---@field Back Keys_Value
---@field Tab Keys_Value
---@field Enter Keys_Value
---@field CapsLock Keys_Value
---@field Escape Keys_Value
---@field Space Keys_Value
---@field PageUp Keys_Value
---@field PageDown Keys_Value
---@field End Keys_Value
---@field Home Keys_Value
---@field Left Keys_Value
---@field Up Keys_Value
---@field Right Keys_Value
---@field Down Keys_Value
---@field Select Keys_Value
---@field Print Keys_Value
---@field Execute Keys_Value
---@field PrintScreen Keys_Value
---@field Insert Keys_Value
---@field Delete Keys_Value
---@field Help Keys_Value
---@field D0 Keys_Value
---@field D1 Keys_Value
---@field D2 Keys_Value
---@field D3 Keys_Value
---@field D4 Keys_Value
---@field D5 Keys_Value
---@field D6 Keys_Value
---@field D7 Keys_Value
---@field D8 Keys_Value
---@field D9 Keys_Value
---@field A Keys_Value
---@field B Keys_Value
---@field C Keys_Value
---@field D Keys_Value
---@field E Keys_Value
---@field F Keys_Value
---@field G Keys_Value
---@field H Keys_Value
---@field I Keys_Value
---@field J Keys_Value
---@field K Keys_Value
---@field L Keys_Value
---@field M Keys_Value
---@field N Keys_Value
---@field O Keys_Value
---@field P Keys_Value
---@field Q Keys_Value
---@field R Keys_Value
---@field S Keys_Value
---@field T Keys_Value
---@field U Keys_Value
---@field V Keys_Value
---@field W Keys_Value
---@field X Keys_Value
---@field Y Keys_Value
---@field Z Keys_Value
---@field LeftWindows Keys_Value
---@field RightWindows Keys_Value
---@field Apps Keys_Value
---@field Sleep Keys_Value
---@field NumPad0 Keys_Value
---@field NumPad1 Keys_Value
---@field NumPad2 Keys_Value
---@field NumPad3 Keys_Value
---@field NumPad4 Keys_Value
---@field NumPad5 Keys_Value
---@field NumPad6 Keys_Value
---@field NumPad7 Keys_Value
---@field NumPad8 Keys_Value
---@field NumPad9 Keys_Value
---@field Multiply Keys_Value
---@field Add Keys_Value
---@field Separator Keys_Value
---@field Subtract Keys_Value
---@field Decimal Keys_Value
---@field Divide Keys_Value
---@field F1 Keys_Value
---@field F2 Keys_Value
---@field F3 Keys_Value
---@field F4 Keys_Value
---@field F5 Keys_Value
---@field F6 Keys_Value
---@field F7 Keys_Value
---@field F8 Keys_Value
---@field F9 Keys_Value
---@field F10 Keys_Value
---@field F11 Keys_Value
---@field F12 Keys_Value
---@field F13 Keys_Value
---@field F14 Keys_Value
---@field F15 Keys_Value
---@field F16 Keys_Value
---@field F17 Keys_Value
---@field F18 Keys_Value
---@field F19 Keys_Value
---@field F20 Keys_Value
---@field F21 Keys_Value
---@field F22 Keys_Value
---@field F23 Keys_Value
---@field F24 Keys_Value
---@field NumLock Keys_Value
---@field Scroll Keys_Value
---@field LeftShift Keys_Value
---@field RightShift Keys_Value
---@field LeftControl Keys_Value
---@field RightControl Keys_Value
---@field LeftAlt Keys_Value
---@field RightAlt Keys_Value
---@field BrowserBack Keys_Value
---@field BrowserForward Keys_Value
---@field BrowserRefresh Keys_Value
---@field BrowserStop Keys_Value
---@field BrowserSearch Keys_Value
---@field BrowserFavorites Keys_Value
---@field BrowserHome Keys_Value
---@field VolumeMute Keys_Value
---@field VolumeDown Keys_Value
---@field VolumeUp Keys_Value
---@field MediaNextTrack Keys_Value
---@field MediaPreviousTrack Keys_Value
---@field MediaStop Keys_Value
---@field MediaPlayPause Keys_Value
---@field LaunchMail Keys_Value
---@field SelectMedia Keys_Value
---@field LaunchApplication1 Keys_Value
---@field LaunchApplication2 Keys_Value
---@field OemSemicolon Keys_Value
---@field OemPlus Keys_Value
---@field OemComma Keys_Value
---@field OemMinus Keys_Value
---@field OemPeriod Keys_Value
---@field OemQuestion Keys_Value
---@field OemTilde Keys_Value
---@field OemOpenBrackets Keys_Value
---@field OemPipe Keys_Value
---@field OemCloseBrackets Keys_Value
---@field OemQuotes Keys_Value
---@field Oem8 Keys_Value
---@field OemBackslash Keys_Value
---@field ProcessKey Keys_Value
---@field Attn Keys_Value
---@field Crsel Keys_Value
---@field Exsel Keys_Value
---@field EraseEof Keys_Value
---@field Play Keys_Value
---@field Zoom Keys_Value
---@field Pa1 Keys_Value
---@field OemClear Keys_Value
---@field ChatPadGreen Keys_Value
---@field ChatPadOrange Keys_Value
---@field Pause Keys_Value
---@field ImeConvert Keys_Value
---@field ImeNoConvert Keys_Value
---@field Kana Keys_Value
---@field Kanji Keys_Value
---@field OemAuto Keys_Value
---@field OemCopy Keys_Value
---@field OemEnlW Keys_Value
local Keys = {}
return Keys
================================================
FILE: apis/engine_api/ListenerID.lua
================================================
---@class ListenerID
local ListenerID = {}
return ListenerID
================================================
FILE: apis/engine_api/Log.lua
================================================
---@API
---@class Log 日志类。
local Log = {}
---输出一条信息日志。
---@param msg string
function Log.info(msg)
end
---输出一条警告日志。
---@param msg string
function Log.warn(msg)
end
---输出一条崩溃日志。
---@param msg string
function Log.fatal(msg)
end
---输出一条错误日志。
---@param msg string
function Log.error(msg)
end
---输出一条调试日志。
---@param msg string
function Log.debug(msg)
end
return Log
================================================
FILE: apis/engine_api/MathHelper.lua
================================================
---@class MathHelper
---@field pi number
local MathHelper = {}
---degreeToRadian
---@param angle number
---@return number
function MathHelper.degreeToRadian(angle)
end
---radianToDegree
---@param angle number
---@return number
function MathHelper.radianToDegree(angle)
end
return MathHelper
================================================
FILE: apis/engine_api/Matrix.lua
================================================
---@API
---@class Matrix 描述一个4x4矩阵。
---@field m11 number
---@field m12 number
---@field m13 number
---@field m14 number
---@field m21 number
---@field m22 number
---@field m23 number
---@field m24 number
---@field m31 number
---@field m32 number
---@field m33 number
---@field m34 number
---@field m41 number
---@field m42 number
---@field m43 number
---@field m44 number
---@field up Vector3 上向量{M21, M22, M23}。
---@field down Vector3 下向量{-M21, -M22, -M23}。
---@field left Vector3 左向量{-M11, -M12, -M13}。
---@field right Vector3 右向量{M11, M12, M13}。
---@field forward Vector3 前向量{-M31, -M32, -M33}。
---@field backward Vector3 前向量{-M31, -M32, -M33}。
---@field translation Vector3 存储坐标{M41, M42, M43}。
---@field identity Matrix 返回单位矩阵。
local Matrix = {}
---
---@overload fun():Matrix
---@overload fun(row1:Vector4,row2:Vector4,row3:Vector4,row4:Vector4):Matrix
---@param m11 number
---@param m12 number
---@param m13 number
---@param m14 number
---@param m21 number
---@param m22 number
---@param m23 number
---@param m24 number
---@param m31 number
---@param m32 number
---@param m33 number
---@param m34 number
---@param m41 number
---@param m42 number
---@param m43 number
---@param m44 number
---@return Matrix
function Matrix.new(m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44)
end
---@param value Matrix
---@return Matrix
function Matrix.clone(value)
end
---转置矩阵,即行列交换。
---@return Matrix
function Matrix:transpose()
end
---返回包含指定矩阵中值的线性插值矩阵。
---@param matrix Matrix 原始矩阵。
---@param amount number 插值。
---@return Matrix
function Matrix:lerp(matrix, amount)
end
---矩阵逆变换。
---@return Matrix
function Matrix:invert()
end
---求矩阵行列式。
---@return number
function Matrix:determinant()
end
---
---@param position Vector2
---@return Vector2
function Matrix:transformVector2(position)
end
---
---@param position Vector3
---@return Vector3
function Matrix:transformVector3(position)
end
---
---@param vector4 Vector4
---@return Vector4
function Matrix:transformVector4(vector4)
end
---
---@param vector3 Vector3
---@return Vector4
function Matrix:transformVector4(vector3)
end
---
---@param vector2 Vector2
---@return Vector4
function Matrix:transformVector4(vector2)
end
---构造一个View矩阵。
---@param cameraPosition Vector3 摄像机坐标。
---@param cameraTarget Vector3 摄像机目标向量。
---@param cameraUpVector Vector3 摄像机上边缘方向。
---@return Matrix
function Matrix.createLookAt(cameraPosition, cameraTarget, cameraUpVector)
end
---构造一个透视投影矩阵。
---@param fieldOfView number y轴方向上的视场角度(弧度制)。
---@param aspectRatio number 视景体的宽度与高度之比。
---@param nearPlaneDistance number 沿z轴方向的两截面之间距离的近处。
---@param farPlaneDistance number 沿z轴方向的两截面之间距离的远处。
---@return Matrix
function Matrix.createPerspectiveFOV(fieldOfView, aspectRatio, nearPlaneDistance, farPlaneDistance)
end
---构造一个正视投影矩阵。
---@param width number 视图宽度。
---@param height number 视图高度。
---@param zNearPlane number 近平面深度。
---@param zFarPlane number 远平面深度
---@return Matrix
function Matrix.createOrthographicRH(width, height, zNearPlane, zFarPlane)
end
---构造一个正视投影矩阵。
---@param left number 投影区域最小x坐标。
---@param right number 投影区域最大x坐标。
---@param bottom number 投影区域最大y坐标。
---@param top number 投影区域最小y坐标。
---@param zNearPlane number 近平面深度。
---@param zFarPlane number 远平面深度。
---@return Matrix
function Matrix.createOrthographicRH(left, right, bottom, top, zNearPlane, zFarPlane)
end
---构造一个正视投影矩阵。
---@param width number 视图宽度。
---@param height number 视图高度。
---@param zNearPlane number 近平面深度。
---@param zFarPlane number 远平面深度。
---@return Matrix
function Matrix.createOrthographicLH(width, height, zNearPlane, zFarPlane)
end
---构造一个正视投影矩阵。
---@param left number 投影区域最小x坐标。
---@param right number 投影区域最大x坐标。
---@param bottom number 投影区域最大y坐标。
---@param top number 投影区域最小y坐标。
---@param zNearPlane number 近平面深度。
---@param zFarPlane number 远平面深度。
---@return Matrix
function Matrix.createOrthographicLH(left, right, bottom, top, zNearPlane, zFarPlane)
end
---构造一个绕X轴旋转的矩阵。
---@param radians number 旋转弧度。
---@return Matrix
function Matrix.createRotationX(radians)
end
---构造一个绕Y轴旋转的矩阵。
---@param radians number 旋转弧度。
---@return Matrix
function Matrix.createRotationY(radians)
end
---构造一个绕Z轴旋转的矩阵。
---@param radians number 旋转弧度。
---@return Matrix
function Matrix.createRotationZ(radians)
end
---构造一个放缩矩阵。
---@param scale number XYZ轴的放缩大小。
---@return Matrix
function Matrix.createScale(scale)
end
---构造一个放缩矩阵。
---@param scaleX number X轴的放缩大小。
---@param scaleY number Y轴的放缩大小。
---@param scaleZ number Z轴的放缩大小。
---@return Matrix
function Matrix.createScale(scaleX, scaleY, scaleZ)
end
---构造一个放缩矩阵。
---@param scales Vector3 XYZ轴的放缩向量。
---@return Matrix
function Matrix.createScale(scales)
end
return Matrix
================================================
FILE: apis/engine_api/MeshFilterComponentWrapper.lua
================================================
---@class MeshFilterComponentWrapper:ComponentWrapper
local MeshFilterComponentWrapper = {}
return MeshFilterComponentWrapper
================================================
FILE: apis/engine_api/MeshRendererComponentWrapper.lua
================================================
---@class MeshRendererComponentWrapper:ComponentWrapper
local MeshRendererComponentWrapper = {}
return MeshRendererComponentWrapper
================================================
FILE: apis/engine_api/Mouse.lua
================================================
---@class Mouse
---@field position Vector2
---@field normalizedPosition Vector2
---@field isLeftButtonPressed boolean
---@field isRightButtonPressed boolean
---@field isMiddleButtonPressed boolean
---@field isLeftButtonInstantDown boolean
---@field isRightButtonInstantDown boolean
---@field isMiddleButtonInstantDown boolean
---@field isLeftButtonInstantUp boolean
---@field isRightButtonInstantUp boolean
---@field isMiddleButtonInstantUp boolean
---@field isLeftButtonDoubleClick boolean
---@field isRightButtonDoubleClick boolean
---@field isMiddleButtonDoubleClick boolean
local Mouse = {}
---
---@param listener table|function
---@return ListenerID
function Mouse:addScrollListener(listener)
end
---
---@param listenerID ListenerID
function Mouse:removeScrollListener(listenerID)
end
---setCursorVisible
---@param visible boolean
function Mouse:setCursorVisible(visible)
end
return Mouse
================================================
FILE: apis/engine_api/NetMode.lua
================================================
---@API
---@class NetMode 网络模式类。
---@field current NetMode 获取当前线程的网络模式。
---@field Client NetMode 客户端模式。
---@field Server NetMode 服务端模式。
---@field Normal NetMode 通用模式。
local NetMode = {}
return NetMode
================================================
FILE: apis/engine_api/ObbDouble.lua
================================================
---@API
---@class ObbDouble:SerializableType 描述一个旋转矩形对象。
---@field centerX number 矩形中心点横坐标。
---@field centerY number 矩形中心点纵坐标。
---@field width number 矩形宽度。
---@field height number 矩形高度。
---@field angle number 矩形旋转角度。
local ObbDouble = {}
---创建一个旋转矩形对象。
---@param centerX number 矩形中心点横坐标。
---@param centerY number 矩形中心点纵坐标。
---@param width number 矩形宽度。
---@param height number 矩形高度。
---@param angle number 矩形旋转角度。
---@return ObbDouble 新的旋转矩形对象。
function ObbDouble.new(centerX, centerY, width, height, angle)
end
---判断当前旋转矩形是否与另一个旋转矩形重叠。
---@param otherObb ObbDouble
---@return boolean
function ObbDouble:isOverlapping(otherObb)
end
---判断指定点是否在当前旋转矩形区域内。
---@param vector2 Vector2
---@return boolean
function ObbDouble:isPointIn(vector2)
end
---获取矩形空间内的点在矩形空间外的实际坐标。
---@param xInSource number 矩形空间内的点X。
---@param yInSource number 矩形空间内的点Y。
---@return number,number
function ObbDouble:convertFromSourceRectSpace(xInSource, yInSource)
end
return ObbDouble
================================================
FILE: apis/engine_api/Path.lua
================================================
---@API
---@class Path 标准化路径处理类。本项目对于文件路径,认为形如如下的路径都是标准化的。文件夹:Folder、Folder/Folder;文件:File.ext、Folder/File.ext。
local Path = {}
---修正路径为标准化路径。
---@param path string 原始路径。
---@return string 标准化路径。
function Path.fix(path)
end
---连接路径。
---@overload fun(path1:string,path2:string):string
---@overload fun(path1:string,path2:string,path3:string):string
---@param path1 string
---@param path2 string
---@param path3 string
---@param path4 string
---@return string 标准化路径。
function Path.join(path1, path2, path3, path4)
end
---获取后缀名称。例:"abc/test.png",返回".png"。
---@param path string
---@return string
function Path.getExtension(path)
end
---获取文件名。例:"abc/test.png",返回"test.png"。
---@param path string
---@return string
function Path.getFileName(path)
end
---获取不带后缀的文件名。例:"abc/test.png",返回"test"。
---@param path string
---@return string
function Path.getFileNameWithoutExtension(path)
end
---获取相对路径。例:"folder","folder/folder2/test.txt",返回"folder2/test.txt"。
---@param relativeTo string
---@param path string
---@return string
function Path.getRelativePath(relativeTo, path)
end
---判断是否是相对路径。例:
---
---(1)"folder","folder/folder2/test.txt",返回true。
---
---(2)"folder_abc","folder/folder2/test.txt",返回false。
---
---(3)"folder","folder_abc/folder2/test.txt",返回false。
---@param relativeTo string
---@param path string
---@return boolean
function Path.isRelativePath(relativeTo, path)
end
---获取上级目录。例:"abc/def/test.txt"返回"abc/def"。
---@param path string
---@return string
function Path.getParentDirectory(path)
end
return Path
================================================
FILE: apis/engine_api/Quaternion.lua
================================================
---@API
---@class Quaternion:Vector4 描述一个四元数。
---@field identity Quaternion 返回归一化四元数。
---@field eulerAngles Vector3 返回或设置欧拉旋转轴。
---@field matrix Matrix 返回或设置其矩阵形式。
local Quaternion = {}
---返回两个四元数之间的角度。
---@param lhs Quaternion
---@param rhs Quaternion
---@return number
function Quaternion.angle(lhs, rhs)
end
---由欧拉角创建一个四元数。
---@param yaw number
---@param pitch number
---@param roll number
---@return Quaternion
function Quaternion.euler(yaw, pitch, roll)
end
---由欧拉角创建一个四元数。
---@param eulerAngles Vector3
---@return Quaternion
function Quaternion.euler(eulerAngles)
end
---创建一个绕着指定轴旋转指定角度的旋转四元数。
---@param angle number
---@param axis Vector3
---@return Quaternion
function Quaternion.angleAxis(angle, axis)
end
---获得旋转轴和旋转角度。
---@return number,Vector3
function Quaternion:toAngleAxis()
end
---在四元数a和b之间进行球形插值。
---@param a Quaternion
---@param b Quaternion
---@param t number 插值因子[0, 1]。
---@return Quaternion
function Quaternion.slerp(a, b, t)
end
---在四元数a和b之间进行插值。
---@param a Quaternion
---@param b Quaternion
---@param t number 插值因子[0, 1]。
---@return Quaternion
function Quaternion.lerp(a, b, t)
end
---创建一个从角度fromDirection到角度toDirection的旋转四元数。
---@param fromDirection Vector3
---@param toDirection Vector3
---@return Quaternion
function Quaternion.rotationFromTo(fromDirection, toDirection)
end
return Quaternion
================================================
FILE: apis/engine_api/Random.lua
================================================
---@class Random
local Random = {}
---next
---@param n number
---@return number
function Random:next(n)
end
---@return number
function Random:nextByte()
end
---nextTry
---@param n number
---@return boolean
function Random:nextTry(n)
end
---nextArea
---@param begin number
---@param len number
---@return number
function Random:nextArea(begin, len)
end
---nextFloat
---@param value number
---@return number
function Random:nextFloat(value)
end
---nextFloatArea
---@param begin number
---@param len number
---@return number
function Random:nextFloatArea(begin, len)
end
---nextSym
---@param value number
---@return number
function Random:nextSym(value)
end
return Random
================================================
FILE: apis/engine_api/Rect.lua
================================================
---@API
---@class Rect:SerializableType 描述一个矩形区域,坐标精度为int,尺寸精度为int。
---@field x number 矩形左上角横坐标。
---@field y number 矩形左上角纵坐标。
---@field width number 矩形宽度。
---@field height number 矩形高度。
---@field rightX number 矩形右边缘横坐标。
---@field bottomY number 矩形下边缘纵坐标。
---@field centerX number 矩形中心横坐标。
---@field centerY number 矩形中心纵坐标。
local Rect = {}
---创建一个矩形区域对象。
---@param x number
---@param y number
---@param width number
---@param height number
---@return Rect 新的矩形区域对象。
function Rect.new(x, y, width, height)
end
return Rect
================================================
FILE: apis/engine_api/RectFloat.lua
================================================
---@API
---@class RectFloat:SerializableType 描述一个矩形区域,坐标精度为float,尺寸精度为int。
---@field x number 矩形左上角横坐标。
---@field y number 矩形左上角纵坐标。
---@field width number 矩形宽度。
---@field height number 矩形高度。
---@field rightX number 矩形右边缘横坐标。
---@field bottomY number 矩形下边缘纵坐标。
---@field centerX number 矩形中心横坐标。
---@field centerY number 矩形中心纵坐标。
local RectFloat = {}
---创建一个矩形区域对象。
---@param x number
---@param y number
---@param width number
---@param height number
---@return RectFloat 新的矩形区域对象。
function RectFloat.new(x, y, width, height)
end
return RectFloat
================================================
FILE: apis/engine_api/RectFloatEx.lua
================================================
---@API
---@class RectFloatEx:SerializableType 描述一个矩形区域,坐标精度为float,尺寸精度为float。
---@field x number 矩形左上角横坐标。
---@field y number 矩形左上角纵坐标。
---@field width number 矩形宽度。
---@field height number 矩形高度。
---@field rightX number 矩形右边缘横坐标。
---@field bottomY number 矩形下边缘纵坐标。
---@field centerX number 矩形中心横坐标。
---@field centerY number 矩形中心纵坐标。
local RectFloatEx = {}
---创建一个矩形区域对象。
---@param x number
---@param y number
---@param width number
---@param height number
---@return RectFloatEx 新的矩形区域对象。
function RectFloatEx.new(x, y, width, height)
end
return RectFloatEx
================================================
FILE: apis/engine_api/Registry.lua
================================================
---@class Registry
local Registry = {}
---add
---@param name string
---@param any any
function Registry:add(name, any)
end
---remove
---@param name string
function Registry:remove(name)
end
---get
---@param name string
---@return any
function Registry:get(name)
end
return Registry
================================================
FILE: apis/engine_api/Rigidbody.lua
================================================
---@class Rigidbody
---@field velocity Vector3
---@field acceleration Vector3
local Rigidbody = {}
return Rigidbody
================================================
FILE: apis/engine_api/Schedule.lua
================================================
---@class Schedule
local Schedule = {}
---
---@param listener table|function
---@return ListenerID
function Schedule:addListener(listener)
end
---
---@param listenerID ListenerID
function Schedule:removeListener(listenerID)
end
return Schedule
================================================
FILE: apis/engine_api/ScheduleID.lua
================================================
---@class ScheduleID
local ScheduleID = {}
return ScheduleID
================================================
FILE: apis/engine_api/SerializableType.lua
================================================
---@API
---@class SerializableType 可序列化类型。
local SerializableType = {}
---从json字符串中,反序列化得到数据。
---@param json string json字符串。
function SerializableType:fromJson(json)
end
---将当前数据序列化得到json字符串。
---@return string json字符串。
function SerializableType:toJson()
end
return SerializableType
================================================
FILE: apis/engine_api/Size.lua
================================================
---@API
---@class Size:SerializableType 描述一个尺寸。
---@field width number 宽度。
---@field height number 高度。
local Size = {}
---创建一个尺寸对象。
---@overload fun():Size
---@param width number 宽度。
---@param height number 宽度。
---@return Size 新的尺寸对象。
function Size.new(width, height)
end
---克隆一个尺寸对象。
---@param value Size 原尺寸对象。
---@return Size 新的尺寸对象。
function Size.clone(value)
end
return Size
================================================
FILE: apis/engine_api/SliderDirection.lua
================================================
---@class SliderDirection_Value
---@class SliderDirection
---@field LeftRight SliderDirection_Value
---@field RightLeft SliderDirection_Value
---@field TopBottom SliderDirection_Value
---@field BottomTop SliderDirection_Value
local SliderDirection = {}
return SliderDirection
================================================
FILE: apis/engine_api/Sprite.lua
================================================
---@API
---@class Sprite 精灵渲染类。
local Sprite = {}
---开始一批精灵渲染。
function Sprite.beginBatch()
end
---结束一批精灵渲染。
function Sprite.endBatch()
end
---将当前缓存的所有精灵,立即绘制到帧缓存上。
function Sprite.flush()
end
---绘制一个精灵。
---@overload fun(textureLocation:TextureLocation,pos:Vector2,sourceOffset:Rect,color:Color)
---@overload fun(textureLocation:TextureLocation,pos:Vector2,sourceOffset:Rect,color:Color,depth:number)
---@param textureLocation TextureLocation 待绘制的纹理。
---@param pos Vector2 绘制在帧缓存上的坐标。
---@param sourceRect Rect 绘制纹理的剪裁区域。
---@param color Color 绘制精灵的颜色。
---@param exData SpriteExData 精灵绘制拓展信息。
---@param depth number 绘制到帧缓存上的深度。
function Sprite.draw(textureLocation, pos, sourceRect, color, exData, depth)
end
return Sprite
================================================
FILE: apis/engine_api/SpriteExData.lua
================================================
---@API
---@class SpriteExData 描述精灵绘制拓展信息。
---@field scaleRateX number 精灵绘制时横向放大比例。
---@field scaleRateY number 精灵绘制时纵向放大比例。
---@field originX number 精灵绘制原点横坐标。
---@field originY number 精灵绘制原点纵坐标。
---@field scaleRate Vector2 精灵绘制时放大比例。
---@field origin Vector2 精灵绘制原点坐标。
---@field angle number 精灵绘制的旋转角度。
---@field flipHorizontal boolean 精灵绘制时是否水平翻转。
---@field flipVertical boolean 精灵绘制时是否竖直翻转。
local SpriteExData = {}
---创建一个精灵绘制拓展信息对象。
---@return SpriteExData 新的精灵绘制拓展信息对象。
function SpriteExData.new()
end
return SpriteExData
================================================
FILE: apis/engine_api/TextAlignment.lua
================================================
---@class TextAlignment_Value
---@class TextAlignment
---@field Left TextAlignment_Value
---@field Right TextAlignment_Value
---@field HCenter TextAlignment_Value
---@field Top TextAlignment_Value
---@field Bottom TextAlignment_Value
---@field VCenter TextAlignment_Value
local TextAlignment = {}
return TextAlignment
================================================
FILE: apis/engine_api/TextBuffer.lua
================================================
---@class TextBuffer
---@field style TextStyle
---@field actualArea RectFloat
local TextBuffer = {}
return TextBuffer
================================================
FILE: apis/engine_api/TextEditLineType.lua
================================================
---@class TextEditLineType_Value
---@class TextEditLineType
---@field SingleLine TextAlignment_Value
---@field MultiLineSubmit TextAlignment_Value
---@field MultiLineNextLine TextAlignment_Value
local TextEditLineType = {}
return TextEditLineType
================================================
FILE: apis/engine_api/TextHorizontalOverflow.lua
================================================
---@class TextHorizontalOverflow_Value
---@class TextHorizontalOverflow
---@field Wrap TextHorizontalOverflow_Value
---@field Overflow TextHorizontalOverflow_Value
local TextHorizontalOverflow = {}
return TextHorizontalOverflow
================================================
FILE: apis/engine_api/TextStyle.lua
================================================
---@class TextStyle
---@field fontName string
---@field fontSize number
---@field color Color
---@field isRichText boolean
---@field horizontalAlignment TextAlignment
---@field verticalAlignment TextAlignment
---@field horizontalOverflow TextHorizontalOverflow_Value
---@field verticalOverflow TextVerticalOverflow_Value
local TextStyle = {}
return TextStyle
================================================
FILE: apis/engine_api/TextVerticalOverflow.lua
================================================
---@class TextVerticalOverflow_Value
---@class TextVerticalOverflow
---@field Truncate TextVerticalOverflow_Value
---@field Overflow TextVerticalOverflow_Value
local TextVerticalOverflow = {}
return TextVerticalOverflow
================================================
FILE: apis/engine_api/Texture.lua
================================================
---@class Texture
---@field width number
---@field height number
---@field texelWidth number
---@field texelHeight number
---@field mipmapLevel number
local Texture = {}
return Texture
================================================
FILE: apis/engine_api/TextureLocation.lua
================================================
---@API
---@class TextureLocation 描述一个纹理索引。
---@field isSingleTexture boolean 当前纹理索引是否不是来自合图。
---@field isAtlasArea boolean 当前纹理索引是否来自合图。
---@field spriteZoomInTimes number 当纹理索引用于精灵渲染时,表示渲染时纹理放大倍数。
---@field valid boolean 纹理是否有效。
local TextureLocation = {}
---创建一个纹理索引对象。
---@param format number
---@param id number
---@return TextureLocation 新的纹理索引对象。
function TextureLocation.new(format, id)
end
---克隆一个纹理索引对象。
---@param value TextureLocation 原始纹理索引对象。
---@return TextureLocation 新的纹理索引对象。
function TextureLocation.clone(value)
end
return TextureLocation
================================================
FILE: apis/engine_api/TextureManager.lua
================================================
---@class TextureManager
local TextureManager = {}
---load
---@param filePath string
---@return TextureLocation
function TextureManager.load(filePath)
end
---getSourceRect
---@field textureLocation TextureLocation
---@return Rect
function TextureManager.getSourceRect(textureLocation)
end
return TextureManager
================================================
FILE: apis/engine_api/TexturePacker.lua
================================================
---@class TexturePacker
local TexturePacker = {}
---genAtlasFromFileSystem
---@overload fun(folderPath:string,subPaths:string[],ignorePaths:string[],atlasName:string):AtlasInfos
---@param folderPath string
---@param subPaths string[]
---@param ignorePaths string[]
---@param atlasName string
---@param maxSize number
---@return AtlasInfos
function TexturePacker.genAtlasFromFileSystem(folderPath, subPaths, ignorePaths, atlasName, maxSize)
end
---genAtlasFromAssetBundle
---@overload fun(assetBundle:AssetBundle,folderPath:string,subPaths:string[],ignorePaths:string[],atlasName:string):AtlasInfos
---@param assetBundle AssetBundle
---@param folderPath string
---@param subPaths string[]
---@param ignorePaths string[]
---@param atlasName string
---@param maxSize number
---@return AtlasInfos
function TexturePacker.genAtlasFromAssetBundle(assetBundle, folderPath, subPaths, ignorePaths, atlasName, maxSize)
end
return TexturePacker
================================================
FILE: apis/engine_api/Time.lua
================================================
---@class Time
---@field deltaTime number
---@field smoothDeltaTime number
---@field frameCount number
---@field realtimeSinceStartup number
local Time = {}
return Time
================================================
FILE: apis/engine_api/TimeDiff.lua
================================================
---@class TimeDiff
local TimeDiff = {}
---new
---@return TimeDiff
function TimeDiff.new()
end
---diff
---@return number
function TimeDiff:diff()
end
return TimeDiff
================================================
FILE: apis/engine_api/Touch.lua
================================================
---@class Touch
---@field position Vector2
---@field normalizedPosition Vector2
---@field id number
local Touch = {}
return Touch
================================================
FILE: apis/engine_api/Transform.lua
================================================
---@class Transform
---@field position Vector3
---@field rotation Quaternion
---@field scale Vector3
---@field origin Vector3
---@field eulerAngles Vector3
---@field matrix Matrix
local Transform = {}
---new
---@overload fun():Transform
---@overload fun(position:Vector3):Transform
---@overload fun(position:Vector3,rotation:Quaternion):Transform
---@param position Vector3
---@param rotation Quaternion
---@param scale Vector3
---@return Transform
function Transform.new(position, rotation, scale)
end
return Transform
================================================
FILE: apis/engine_api/Transform2D.lua
================================================
---@class Transform2D
---@field position Vector2
---@field rotation number
---@field scale Vector2
---@field origin Vector2
---@field matrix Matrix
---@field worldMatrix Matrix
local Transform2D = {}
---new
---@overload fun():Transform2D
---@overload fun(position:Vector2):Transform2D
---@overload fun(position:Vector2,rotation:number):Transform2D
---@param position Vector2
---@param rotation number
---@param scale Vector2
---@return Transform2D
function Transform2D.new(position, rotation, scale)
end
return Transform2D
================================================
FILE: apis/engine_api/TransformComponentWrapper.lua
================================================
---@class TransformComponentWrapper:ComponentWrapper
---@field position Vector3
---@field rotation Quaternion
---@field scale Vector3
---@field eulerAngles Vector3
---@field localMatrix Matrix
---@field localToWorldMatrix Matrix
---@field worldToLocalMatrix Matrix
local TransformComponentWrapper = {}
return TransformComponentWrapper
================================================
FILE: apis/engine_api/UIButton.lua
================================================
---@class UIButton:UINode
---@field targetSprite UISprite
---@field highlightedSprite UISprite
---@field pressedSprite UISprite
---@field selectedSprite UISprite
---@field disabledSprite UISprite
---@field selected boolean
local UIButton = {}
---new
---@overload fun(name:string):UIButton
---@param name string
---@param x number
---@param y number
---@param width number
---@param height number
---@return UIButton
function UIButton.new(name, x, y, width, height)
end
---
---@param value UIButton
---@return UIButton
function UIButton.clone(value)
end
---case
---@param uiNode UINode
---@return UIButton
function UIButton.cast(uiNode)
end
return UIButton
================================================
FILE: apis/engine_api/UICanvas.lua
================================================
---@class UICanvas:UINode
local UICanvas = {}
---new
---@overload fun(name:string):UICanvas
---@param name string
---@param x number
---@param y number
---@param width number
---@param height number
---@return UICanvas
function UICanvas.new(name, x, y, width, height)
end
---
---@param value UICanvas
---@return UICanvas
function UICanvas.clone(value)
end
---case
---@param uiNode UINode
---@return UICanvas
function UICanvas.cast(uiNode)
end
function UICanvas:update()
end
function UICanvas:render()
end
---screenPointToCanvasPoint
---@param screenPosition Vector2
---@return Vector2
function UICanvas:screenPointToCanvasPoint(screenPosition)
end
---canvasPointToScreenPoint
---@param canvasPosition Vector2
---@return Vector2
function UICanvas:canvasPointToScreenPoint(canvasPosition)
end
return UICanvas
================================================
FILE: apis/engine_api/UIImage.lua
================================================
---@class UIImage:UINode
---@field sprite UISprite
local UIImage = {}
---new
---@overload fun(name:string):UIImage
---@param name string
---@param x number
---@param y number
---@param width number
---@param height number
---@return UIImage
function UIImage.new(name, x, y, width, height)
end
---
---@param value UIImage
---@return UIImage
function UIImage.clone(value)
end
---case
---@param uiNode UINode
---@return UIImage
function UIImage.cast(uiNode)
end
return UIImage
================================================
FILE: apis/engine_api/UIInputField.lua
================================================
---@class UIInputField:UINode
---@field horizontalAlignment TextAlignment_Value
---@field verticalAlignment TextAlignment_Value
---@field text string
---@field fontName string
---@field fontSize number
---@field color Color
---@field lineType TextEditLineType_Value
local UIInputField = {}
---new
---@overload fun(name:string):UIInputField
---@param name string
---@param x number
---@param y number
---@param width number
---@param height number
---@return UIInputField
function UIInputField.new(name, x, y, width, height)
end
---
---@param value UIInputField
---@return UIInputField
function UIInputField.clone(value)
end
---case
---@param uiNode UINode
---@return UIInputField
function UIInputField.cast(uiNode)
end
---
---@param listener table|function
---@return ListenerID
function UIInputField:addTextChangedListener(listener)
end
---
---@param listenerID ListenerID
function UIInputField:removeTextChangedListener(listenerID)
end
return UIInputField
================================================
FILE: apis/engine_api/UIJoystick.lua
================================================
---@class UIJoystick:UINode
---@field frontSprite UISprite
---@field backSprite UISprite
---@field activeDistanceRate number
---@field controlRadius number
---@field controlledDistance number
---@field controlledDistanceRate number
---@field controlledAngle number
---@field controlledCenter Vector2
local UIJoystick = {}
---new
---@overload fun(name:string):UIJoystick
---@param name string
---@param x number
---@param y number
---@param width number
---@param height number
---@return UIJoystick
function UIJoystick.new(name, x, y, width, height)
end
---
---@param value UIJoystick
---@return UIJoystick
function UIJoystick.clone(value)
end
---case
---@param uiNode UINode
---@return UIJoystick
function UIJoystick.cast(uiNode)
end
---setControl
---@overload fun(v:Vector2)
---@param x number
---@param y number
function UIJoystick:setControl(x, y)
end
---@return boolean,boolean,boolean,boolean
function UIJoystick:getControlledFourDirection()
end
return UIJoystick
================================================
FILE: apis/engine_api/UINode.lua
================================================
---@API
---@class UINode 基本的UI节点,是所有类型UI节点的基类。
---@field name string 节点名字。
---@field anchorPoint Vector2 组件锚点。
---@field anchorPointX number 锚点横坐标。
---@field anchorPointY number 锚点纵坐标。
---@field position Vector2 节点在父节点空间的坐标。
---@field positionInCanvas Vector2 节点在画布空间的坐标。
---@field positionX number 节点在父节点空间的横坐标。
---@field positionY number 节点在父节点空间的纵坐标。
---@field size Size 节点尺寸。
---@field width number 节点宽度。
---@field height number 节点高度。
---@field visible boolean 节点是否可见。
---@field leftMargin number 节点到父节点的左侧边距。
---@field rightMargin number 节点到父节点的右侧边距。
---@field topMargin number 节点到父节点的上侧边距。
---@field bottomMargin number 节点到父节点的下侧边距。
---@field leftMarginEnabled boolean 是否启用节点到父节点的左侧边距。
---@field rightMarginEnabled boolean 是否启用节点到父节点的右侧边距。
---@field topMarginEnabled boolean 是否启用节点到父节点的上侧边距。
---@field bottomMarginEnabled boolean 是否启用节点到父节点的下侧边距。
---@field autoStretchWidth boolean 是否根据左右侧边距自动拉伸适配宽度,若为false,则为根据左右侧边距水平居中。
---@field autoStretchHeight boolean 是否根据上下侧边距自动拉伸适配高度,若为false,则为根据上下侧边距竖直居中。
---@field touchable boolean 节点是否可被触碰。
---@field tag number 节点附加值。
---@field childTag number 节点作为子节点时的附加值。
---@field isContainer boolean 节点是否作为裁切容器。
---@field allowDoubleClick boolean 节点是否允许进行双击。
---@field textBatchRendering boolean
---@field enableRenderTarget boolean 节点是否开启RenderTarget纹理缓存,开启后仅在内部节点更新时重绘纹理缓存。
---@field isTouching boolean 当前节点是否被触碰中。
local UINode = {}
---new
---@return UINode
function UINode.new()
end
---clone
---@return UINode
function UINode:clone()
end
---@return boolean
function UINode:valid()
end
---setAnchorPoint
---@param x number
---@param y number
function UINode:setAnchorPoint(x, y)
end
---setPosition
---@param x number
---@param y number
function UINode:setPosition(x, y)
end
---setLocation
---@param x number
---@param y number
---@param width number
---@param height number
function UINode:setLocation(x, y, width, height)
end
---setSize
---@param width number
---@param height number
function UINode:setSize(width, height)
end
---addChild
---@overload fun(node:UINode)
---@param node UINode
---@param childTag number
function UINode:addChild(node, childTag)
end
---removeChild
---@param node UINode
function UINode:removeChild(node)
end
function UINode:removeAllChildren()
end
---applyMargin
---@param applyAllChildren boolean
function UINode:applyMargin(applyAllChildren)
end
---setLeftMargin
---@param offset number
---@param enabled boolean
function UINode:setLeftMargin(offset, enabled)
end
---setRightMargin
---@param offset number
---@param enabled boolean
function UINode:setRightMargin(offset, enabled)
end
---setTopMargin
---@param offset number
---@param enabled boolean
function UINode:setTopMargin(offset, enabled)
end
---setBottomMargin
---@param offset number
---@param enabled boolean
function UINode:setBottomMargin(offset, enabled)
end
---setMarginEnabled
---@param left boolean
---@param top boolean
---@param right boolean
---@param bottom boolean
function UINode:setMarginEnabled(left, top, right, bottom)
end
---setAutoStretch
---@param widthEnabled boolean
---@param heightEnabled boolean
function UINode:setAutoStretch(widthEnabled, heightEnabled)
end
---getChildByTag
---@param childTag number
---@return UINode
function UINode:getChildByTag(childTag)
end
---getChild
---@param name string
---@return UINode
function UINode:getChild(name)
end
---
---@param listener table|function
---@return ListenerID
function UINode:addTouchDownListener(listener)
end
---
---@param listenerID ListenerID
function UINode:removeTouchDownListener(listenerID)
end
---
---@param listener table|function
---@return ListenerID
function UINode:addTouchDoubleDownListener(listener)
end
---
---@param listenerID ListenerID
function UINode:removeTouchDoubleDownListener(listenerID)
end
---
---@param listener table|function
---@return ListenerID
function UINode:addTouchMoveListener(listener)
end
---
---@param listenerID ListenerID
function UINode:removeTouchMoveListener(listenerID)
end
---
---@param listener table|function
---@return ListenerID
function UINode:addTouchPointedMoveListener(listener)
end
---
---@param listenerID ListenerID
function UINode:removeTouchPointedMoveListener(listenerID)
end
---
---@param listener table|function
---@return ListenerID
function UINode:addTouchUpListener(listener)
end
---
---@param listenerID ListenerID
function UINode:removeTouchUpListener(listenerID)
end
---
---@param listener table|function
---@return ListenerID
function UINode:addTouchUpAfterMoveListener(listener)
end
---
---@param listenerID ListenerID
function UINode:removeTouchUpAfterMoveListener(listenerID)
end
---
---@param listener table|function
---@return ListenerID
function UINode:addTouchPointedUpListener(listener)
end
---
---@param listenerID ListenerID
function UINode:removeTouchPointedUpListener(listenerID)
end
---
---@param listener table|function
---@return ListenerID
function UINode:addMousePointedListener(listener)
end
---
---@param listenerID ListenerID
function UINode:removeMousePointedListener(listenerID)
end
---
---@param listener table|function
---@return ListenerID
function UINode:addMousePointedEnterListener(listener)
end
---
---@param listenerID ListenerID
function UINode:removeMousePointedEnterListener(listenerID)
end
---
---@param listener table|function
---@return ListenerID
function UINode:addMousePointedLeaveListener(listener)
end
---
---@param listenerID ListenerID
function UINode:removeMousePointedLeaveListener(listenerID)
end
---getPreDrawLayer
---@param layer number
---@return UINodeDrawLayer
function UINode:getPreDrawLayer(layer)
end
---getPostDrawLayer
---@param layer number
---@return UINodeDrawLayer
function UINode:getPostDrawLayer(layer)
end
---@return number
function UINode:getChildrenCount()
end
---getChildByIndex
---@param index number
---@return UINode
function UINode:getChildByIndex(index)
end
---getPointedNode
---@overload fun(canvasPosition:Vector2):UINode
---@param canvasPosition Vector2
---@param isTouching boolean
---@return UINode
function UINode:getPointedNode(canvasPosition, isTouching)
end
function UINode:flushRender()
end
return UINode
================================================
FILE: apis/engine_api/UINodeDrawLayer.lua
================================================
---@class UINodeDrawLayer
local UINodeDrawLayer = {}
---
---@param listener table|function
---@return ListenerID
function UINodeDrawLayer:addListener(listener)
end
---
---@param listenerID ListenerID
function UINodeDrawLayer:removeListener(listenerID)
end
return UINodeDrawLayer
================================================
FILE: apis/engine_api/UIPanel.lua
================================================
---@class UIPanel:UINode
---@field sprite UISprite
local UIPanel = {}
---new
---@overload fun(name:string):UIPanel
---@param name string
---@param x number
---@param y number
---@param width number
---@param height number
---@return UIPanel
function UIPanel.new(name, x, y, width, height)
end
---
---@param value UIPanel
---@return UIPanel
function UIPanel.clone(value)
end
---case
---@param uiNode UINode
---@return UIPanel
function UIPanel.cast(uiNode)
end
return UIPanel
================================================
FILE: apis/engine_api/UIScrollView.lua
================================================
---@class UIScrollView:UINode
---@field sprite UISprite
---@field viewSize Size
---@field isScrollVertical boolean
---@field isScrollHorizontal boolean
---@field isScrollable boolean
---@field isScrolling boolean
local UIScrollView = {}
---new
---@overload fun(name:string):UIScrollView
---@param name string
---@param x number
---@param y number
---@param width number
---@param height number
---@return UIScrollView
function UIScrollView.new(name, x, y, width, height)
end
---
---@param value UIScrollView
---@return UIScrollView
function UIScrollView.clone(value)
end
---case
---@param uiNode UINode
---@return UIScrollView
function UIScrollView.cast(uiNode)
end
function UIScrollView:ScrollToTop()
end
function UIScrollView:ScrollToBottom()
end
function UIScrollView:ScrollToLeft()
end
function UIScrollView:ScrollToRight()
end
function UIScrollView:StopScrolling()
end
return UIScrollView
================================================
FILE: apis/engine_api/UISerializable.lua
================================================
---@class UISerializable
local UISerializable = {}
---ToDesignString
---@param uiNode UINode
---@return string
function UISerializable.toDesignString(uiNode)
end
---LoadDesignString
---@param designString string
---@return UINode
function UISerializable.loadDesignString(designString)
end
---ToBinary
---@param uiNode UINode
---@return Bytes
function UISerializable.toBinary(uiNode)
end
---LoadBinary
---@param bytes Bytes
---@param offset number
---@param size number
---@return UINode
function UISerializable.loadBinary(bytes, offset, size)
end
return UISerializable
================================================
FILE: apis/engine_api/UISlices9.lua
================================================
---@class UISlices9:SerializableType
---@field left number
---@field right number
---@field top number
---@field bottom number
local UISlices9 = {}
---new
---@overload fun():UISlices9
---@param left number
---@param top number
---@param right number
---@param bottom number
---@return UISlices9
function UISlices9.new(left, top, right, bottom)
end
return UISlices9
================================================
FILE: apis/engine_api/UISlider.lua
================================================
---@class UISlider:UINode
---@field barSprite UISprite
---@field activeBarSprite UISprite
---@field sliderSprite UISprite
---@field sliderSize Size
---@field maxValue number
---@field minValue number
---@field value number
---@field valueStep number
---@field rate number
---@field sliderDirection SliderDirection_Value
local UISlider = {}
---new
---@overload fun(name:string):UISlider
---@param name string
---@param x number
---@param y number
---@param width number
---@param height number
---@return UISlider
function UISlider.new(name, x, y, width, height)
end
---
---@param value UISlider
---@return UISlider
function UISlider.clone(value)
end
---case
---@param uiNode UINode
---@return UISlider
function UISlider.cast(uiNode)
end
---
---@param listener table|function
---@return ListenerID
function UISlider:addValueChangedListener(listener)
end
---
---@param listenerID ListenerID
function UISlider:removeValueChangedListener(listenerID)
end
return UISlider
================================================
FILE: apis/engine_api/UISprite.lua
================================================
---@class UISprite:SerializableType
---@field textureName string
---@field textureLocation TextureLocation
---@field slices9 UISlices9
---@field color Color
---@field style UISpriteStyle_Value
---@field positionOffset Vector2
local UISprite = {}
---new
---@overload fun():UISprite
---@param textureName string
---@return UISprite
function UISprite.new(textureName)
end
---clone
---@param value UISprite
---@return UISprite
function UISprite.clone(value)
end
return UISprite
================================================
FILE: apis/engine_api/UISpriteStyle.lua
================================================
---@class UISpriteStyle_Value
---@class UISpriteStyle
---@field Simple UISpriteStyle_Value
---@field Tiled UISpriteStyle_Value
---@field Filled UISpriteStyle_Value
---@field Slices9 UISpriteStyle_Value
local UISpriteStyle = {}
return UISpriteStyle
================================================
FILE: apis/engine_api/UISwitch.lua
================================================
---@class UISwitch:UINode
---@field onBackgroundSprite UISprite
---@field offBackgroundSprite UISprite
---@field onSliderSprite UISprite
---@field offSliderSprite UISprite
---@field selected boolean
---@field fadeTime number
---@field sliderSize Size
local UISwitch = {}
---new
---@overload fun(name:string):UISwitch
---@param name string
---@param x number
---@param y number
---@param width number
---@param height number
---@return UISwitch
function UISwitch.new(name, x, y, width, height)
end
---
---@param value UISwitch
---@return UISwitch
function UISwitch.clone(value)
end
---case
---@param uiNode UINode
---@return UISwitch
function UISwitch.cast(uiNode)
end
---setSelected
---@overload fun(selected:boolean)
---@param selected boolean
---@param withAnimation boolean
function UISwitch:setSelected(selected, withAnimation)
end
---
---@param listener table|function
---@return ListenerID
function UISwitch:addSelectChangedListener(listener)
end
---
---@param listenerID ListenerID
function UISwitch:removeSelectChangedListener(listenerID)
end
return UISwitch
================================================
FILE: apis/engine_api/UIText.lua
================================================
---@class UIText:UINode
---@field horizontalAlignment TextAlignment_Value
---@field verticalAlignment TextAlignment_Value
---@field verticalOverflow TextHorizontalOverflow_Value
---@field horizontalOverflow TextVerticalOverflow_Value
---@field text string
---@field fontName string
---@field fontSize number
---@field color Color
---@field autoAdaptSize boolean
---@field displayTextSize Size
---@field preferredSize Size
---@field preferredWidth number
---@field preferredHeight number
---@field isRichText boolean
---@field outlineSize number
---@field outlineColor Color
local UIText = {}
---new
---@overload fun(name:string):UIText
---@param name string
---@param x number
---@param y number
---@param width number
---@param height number
---@return UIText
function UIText.new(name, x, y, width, height)
end
---
---@param value UIText
---@return UIText
function UIText.clone(value)
end
---case
---@param uiNode UINode
---@return UIText
function UIText.cast(uiNode)
end
---
---@param listener table|function
---@return ListenerID
function UIText:addTextChangedListener(listener)
end
---
---@param listenerID ListenerID
function UIText:removeTextChangedListener(listenerID)
end
return UIText
================================================
FILE: apis/engine_api/UITexturePool.lua
================================================
---@class UITexturePool
local UITexturePool = {}
---register
---@param name string
---@param textureLocation TextureLocation
function UITexturePool.register(name, textureLocation)
end
---unregister
---@param name string
function UITexturePool.unregister(name)
end
---registerFromFileSystem
---@param name string
---@param filePath string
function UITexturePool.registerFromFileSystem(name, filePath)
end
return UITexturePool
================================================
FILE: apis/engine_api/Vector2.lua
================================================
---@API
---@class Vector2:SerializableType 描述一个2维向量。
---@field x number
---@field y number
---@field length number 向量长度。
---@field lengthSquared number 向量长度的平方。
---@field angle number 向量到原点的角度。
---@field zero Vector2 返回零向量。
---@field one Vector2 返回全1向量。
---@field unitX Vector2 返回X轴单位向量。
---@field unitY Vector2 返回Y轴单位向量。
local Vector2 = {}
---@overload fun():Vector2
---@param x number
---@param y number
---@return Vector2
function Vector2.new(x, y)
end
---@param value Vector2
---@return Vector2
function Vector2.clone(value)
end
---获取向量到另一个向量的角度。
---@param other Vector2
---@return number
function Vector2:getAngleTo(other)
end
---获取另一个向量到当前向量的角度。
---@param other Vector2
---@return number
function Vector2:getAngleFrom(other)
end
---向量单位化。
---@param value Vector2
---@return Vector2
function Vector2.normalize(value)
end
---获取两个向量的最大值向量。
---@param value1 Vector2
---@param value2 Vector2
---@return Vector2
function Vector2.max(value1, value2)
end
---获取两个向量的最小值向量。
---@param value1 Vector2
---@param value2 Vector2
---@return Vector2
function Vector2.min(value1, value2)
end
---将每个维度向下取整。
---@param value Vector2
---@return Vector2
function Vector2.floor(value)
end
---将每个维度向上取整。
---@param value Vector2
---@return Vector2
function Vector2.ceil(value)
end
---限制向量到给定范围。
---@param value Vector2
---@param min Vector2
---@param max Vector2
---@return Vector2
function Vector2.clamp(value, min, max)
end
---获取向量之间的距离。
---@param value1 Vector2
---@param value2 Vector2
---@return number
function Vector2.getDistance(value1, value2)
end
---获取向量之间的距离平方。
---@param value1 Vector2
---@param value2 Vector2
---@return number
function Vector2.getDistanceSquared(value1, value2)
end
---将两个向量点乘,即每个维度乘积之和。
---@param value1 Vector2
---@param value2 Vector2
---@return number
function Vector2.dot(value1, value2)
end
return Vector2
================================================
FILE: apis/engine_api/Vector3.lua
================================================
---@API
---@class Vector3:SerializableType 描述一个3维向量。
---@field x number
---@field y number
---@field z number
---@field length number 向量长度。
---@field lengthSquared number 向量长度的平方。
---@field zero Vector3 返回零向量。
---@field one Vector3 返回全1向量。
---@field unitX Vector3 返回X轴单位向量。
---@field unitY Vector3 返回Y轴单位向量。
---@field unitZ Vector3 返回Z轴单位向量。
---@field up Vector3
---@field down Vector3
---@field left Vector3
---@field right Vector3
---@field forward Vector3
---@field back Vector3
local Vector3 = {}
---@overload fun():Vector3
---@overload fun(value:Vector2,z:number):Vector3
---@param x number
---@param y number
---@param z number
---@return Vector3
function Vector3.new(x, y, z)
end
---@param value Vector3
---@return Vector3
function Vector3.clone(value)
end
---向量单位化。
---@param value Vector3
---@return Vector3
function Vector3.normalize(value)
end
---获取两个向量的最大值向量。
---@param value1 Vector3
---@param value2 Vector3
---@return Vector3
function Vector3.max(value1, value2)
end
---获取两个向量的最小值向量。
---@param value1 Vector3
---@param value2 Vector3
---@return Vector3
function Vector3.min(value1, value2)
end
---将每个维度向下取整。
---@param value Vector3
---@return Vector3
function Vector3.floor(value)
end
---将每个维度向上取整。
---@param value Vector3
---@return Vector3
function Vector3.ceil(value)
end
---限制向量到给定范围。
---@param value Vector3
---@param min Vector3
---@param max Vector3
---@return Vector3
function Vector3.clamp(value, min, max)
end
---
---@param value1 Vector3
---@param value2 Vector3
---@return number
function Vector3.getDistance(value1, value2)
end
---获取向量之间的距离。
---@param value1 Vector3
---@param value2 Vector3
---@return number
function Vector3.getDistanceSquared(value1, value2)
end
---将两个向量点乘,即每个维度乘积之和。
---@param value1 Vector3
---@param value2 Vector3
---@return number
function Vector3.dot(value1, value2)
end
---返回两个向量的叉积。
---@param value1 Vector3
---@param value2 Vector3
---@return Vector3
function Vector3.cross(value1, value2)
end
return Vector3
================================================
FILE: apis/engine_api/Vector4.lua
================================================
---@API
---@class Vector4:SerializableType 描述一个4维向量。
---@field x number
---@field y number
---@field z number
---@field w number
---@field length number 向量长度。
---@field lengthSquared number 向量长度的平方。
---@field zero Vector4 返回零向量。
---@field one Vector4 返回全1向量。
---@field unitX Vector4 返回X轴单位向量。
---@field unitY Vector4 返回Y轴单位向量。
---@field unitZ Vector4 返回Z轴单位向量。
---@field unitW Vector4 返回W轴单位向量。
local Vector4 = {}
---@overload fun():Vector4
---@overload fun(value:Vector2,z:number,w:number):Vector4
---@overload fun(value:Vector3,w:number):Vector4
---@param x number
---@param y number
---@param z number
---@param w number
---@return Vector4
function Vector4.new(x, y, z, w)
end
---@param value Vector4
---@return Vector4
function Vector4.clone(value)
end
---向量单位化。
---@param value Vector4
---@return Vector4
function Vector4.normalize(value)
end
---获取两个向量的最大值向量。
---@param value1 Vector4
---@param value2 Vector4
---@return Vector4
function Vector4.max(value1, value2)
end
---获取两个向量的最小值向量。
---@param value1 Vector4
---@param value2 Vector4
---@return Vector4
function Vector4.min(value1, value2)
end
---将每个维度向下取整。
---@param value Vector4
---@return Vector4
function Vector4.floor(value)
end
---将每个维度向上取整。
---@param value Vector4
---@return Vector4
function Vector4.ceil(value)
end
---限制向量到给定范围。
---@param value Vector4
---@param min Vector4
---@param max Vector4
---@return Vector4
function Vector4.clamp(value, min, max)
end
---获取向量之间的距离。
---@param value1 Vector4
---@param value2 Vector4
---@return number
function Vector4.getDistance(value1, value2)
end
---获取向量之间的距离平方。
---@param value1 Vector4
---@param value2 Vector4
---@return number
function Vector4.getDistanceSquared(value1, value2)
end
---将两个向量点乘,即每个维度乘积之和。
---@param value1 Vector4
---@param value2 Vector4
---@return number
function Vector4.dot(value1, value2)
end
return Vector4
================================================
FILE: apis/engine_api/cls.lua
================================================
---@class cls
---@field super cls
local cls = {}
---class
---@param classname string
---@param super cls
---@return cls
function class(classname, super)
end
function cls:__init(...)
end
return cls
================================================
FILE: apis/engine_api/utf8string.lua
================================================
---https://github.com/blitmap/lua-utf8-simple
---@class utf8string
local utf8string = {}
---maps f over s's utf8 characters f can accept args: (visual_index, utf8_character, byte_index)
---
--- i is the character/letter index within the string
---
--- c is the utf8 character (string of 1 or more bytes)
---
--- b is the byte index within the string
---
---`for i, c, b in utf8string.chars('Αγαπώ τηγανίτες') do`
---
---` print(i, c, b)`
---
---`end`
---
---@overload fun(s:string):number, string, number
---@param s string
---@param no_subs boolean
---@return number, string, number
function utf8string.chars(s, no_subs)
end
---returns: (number) the number of utf8 characters in s (not the byte length)
---@param s string
---@return number
function utf8string.len(s)
end
---like string.sub() but i, j are utf8 strings
---
---a utf8-safe string.sub()
---@param s string
---@param i number
---@param j number
---@return string
function utf8string.sub(s, i, j)
end
---strip non-ascii characters from a utf8 string
---@param s string
---@return nil|string
function utf8string.strip(s)
end
---reverse a utf8 string
---@param s string
---@return string
function utf8string.reverse(s)
end
---replace all utf8 chars with mapping
---@param s string
---@return string
function utf8string.replace(s, map)
end
return utf8string
================================================
FILE: atlas_config.json
================================================
[
{
"name": "ui",
"path": "ui_res",
"size": 512
},
{
"name": "trees",
"path": "trees",
"size": 2048
},
{
"name": "skins",
"path": "skins",
"size": 1024
},
{
"name": "buffs",
"path": "buffs",
"size": 256
},
{
"name": "effects",
"path": "effects",
"size": 256,
"excludes": [ "gore_([a-zA-Z0-9_]+).png" ]
},
{
"name": "gores",
"path": "effects",
"size": 256,
"includes": [ "gore_([a-zA-Z0-9_]+).png" ]
},
{
"name": "npcs",
"path": "npcs",
"size": 1024
},
{
"name": "projectiles",
"path": "projectiles",
"size": 256
},
{
"name": "items",
"path": "items",
"size": 512,
"excludes": [ "hat([0-9]+|).png", "body([0-9]+|).png", "leg([0-9]+|).png" ]
},
{
"name": "skins",
"path": "items",
"size": 1024,
"includes": [ "hat([0-9]+|).png", "body([0-9]+|).png", "leg([0-9]+|).png" ]
},
{
"name": "furnitures",
"path": "blocks/furnitures",
"size": 512,
"excludes": [ "[a-zA-Z0-9_]+_icon.png" ]
},
{
"name": "items",
"path": "blocks/furnitures",
"size": 512,
"includes": [ "[a-zA-Z0-9_]+_icon.png" ]
},
{
"name": "tiles",
"path": "blocks/tiles",
"size": 1024,
"excludes": [ "[a-zA-Z0-9_]+_icon.png" ]
},
{
"name": "items",
"path": "blocks/tiles",
"size": 512,
"includes": [ "[a-zA-Z0-9_]+_icon.png" ]
}
]
================================================
FILE: biome_types/Nether.json
================================================
{
"Nether": {
}
}
================================================
FILE: biome_types/Radiation.json
================================================
{
"Radiation": {
}
}
================================================
FILE: biome_types/Space.json
================================================
{
"Space": {
}
}
================================================
FILE: biome_types/Surface.json
================================================
{
"Surface": {
"isSurface": true,
"hasWallGen": true,
"isWallFullGen": true
}
}
================================================
FILE: biome_types/TwilightForest.json
================================================
{
"TwilightForest": {
}
}
================================================
FILE: biome_types/Underground.json
================================================
{
"Underground": {
"hasWallGen": true,
"isWallFullGen": false
}
}
================================================
FILE: biomes/nethers/nether.json
================================================
{
"nether": {
"biomeType": "Nether",
"parallaxes": {
"deepRate": 0.9,
"base": [
{
"id": "lava_pile_hanging",
"parallel": 4.0,
"level": 2588
},
{
"id": "lava_rock_hanging",
"parallel": 2.0,
"level": 2578
},
{
"id": "lava_layer_hanging",
"parallel": 1.25,
"level": 2538
},
{
"id": "lava_pile",
"parallel": 2.5,
"level": 2642
},
{
"id": "lava_rock",
"parallel": 2.0,
"level": 2650
},
{
"id": "lava_pile",
"parallel": 1.75,
"level": 2654
},
{
"id": "lava_lake",
"parallel": 1.5,
"level": 2674
},
{
"id": "lava_layer",
"parallel": 1.25,
"level": 2676
}
],
"underground": "lava_wall",
"linked": "lava_wall_link"
},
"musics": {
"underground": [
"mcnether1"
]
},
"composition": {
"main": {
"id": "netherrack"
},
"subs": [
{
"id": "soul_sand"
},
{
"id": "glowstone"
},
{
"id": "magma_block"
}
]
},
"oreGroupName": "default",
"grass": 1,
"treeInfo": {
"styles": [
"log_volcano_oak"
],
"density": 0.25
},
"distributions": {
"airWeight": 100,
"surfacePlaceables": [
{
"id": "pot",
"tag": 4,
"weight": 20
}
],
"hangingWeight": 100,
"hangingPlaceables": []
},
"pot": [
{
"itemId": "torch",
"min": 1,
"max": 5,
"weight": 15
},
{
"itemId": "potion_healing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_night_vision",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_glowing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_strength",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "wooden_arrow",
"min": 3,
"max": 10,
"weight": 10
},
{
"itemId": "coal",
"min": 1,
"max": 2,
"weight": 10
},
{
"itemId": "flint",
"min": 1,
"max": 4,
"weight": 10
},
{
"itemId": "bomb",
"min": 1,
"max": 1,
"weight": 2
},
{
"itemId": "grenade",
"min": 1,
"max": 1,
"weight": 2
},
{
"itemId": "fire_bullet",
"min": 1,
"max": 6,
"weight": 3
}
],
"spawn": {
"mobSpeed": 140,
"maxMobSpawn": 10,
"mobs": [
{
"id": "magma_elf",
"weight": 5
},
{
"id": "magma_slime",
"weight": 4
},
{
"id": "zombie_pigman",
"weight": 12
},
{
"id": "ghast",
"weight": 1
},
{
"id": "blaze",
"weight": 2
},
{
"id": "wither_skeleton",
"weight": 2
}
]
},
"buildingInfo": [
{
"buildingId": "nether_fortress",
"density": 3.0
}
]
}
}
================================================
FILE: biomes/surfaces/badland.json
================================================
{
"badland": {
"biomeType": "Surface",
"dayLight": 1.0,
"skyColor": {
"midDayTopColor": [ 98, 170, 192 ],
"midDayBottomColor": [ 210, 226, 236 ],
"midNightTopColor": [ 5, 8, 32 ],
"midNightBottomColor": [ 20, 30, 68 ],
"transATopColor": [ 98, 170, 192 ],
"transABottomColor": [ 217, 198, 10 ],
"transBTopColor": [ 44, 33, 10 ],
"transBBottomColor": [ 155, 32, 10 ],
"transCTopColor": [ 5, 8, 32 ],
"transCBottomColor": [ 115, 32, 10 ]
},
"subBiomes": {
"subs": [
{
"biome": "jungle",
"minSize": 400,
"maxSize": 500,
"minX": 300,
"maxX": 700
},
{
"biome": "forest",
"minSize": 400,
"maxSize": 500,
"minX": 300,
"maxX": 700
},
{
"biome": "tainted_land",
"minSize": 400,
"maxSize": 500,
"minX": 300,
"maxX": 700
},
{
"biome": "ocean",
"minSize": 200,
"maxSize": 300,
"minX": 300,
"maxX": 700
},
{
"biome": "flesh",
"minSize": 200,
"maxSize": 300,
"minX": 300,
"maxX": 700
},
{
"biome": "mushroom_fields",
"minSize": 400,
"maxSize": 500,
"minX": 300,
"maxX": 700
}
]
},
"terrains": {
"terrains": [
{
"id": "MountainTerrain",
"times": 3.0,
"size": 160,
"height": 24
},
{
"id": "BasinTerrain",
"times": 3.0,
"size": 50,
"height": 12
},
{
"id": "HillTerrain",
"times": 5.0,
"size": 200,
"height": 10
},
{
"id": "HillTerrain",
"times": 6.0,
"size": 100,
"height": 8
},
{
"id": "HillTerrain",
"times": 4.0,
"size": 80,
"height": 4
},
{
"id": "PlateauTerrain",
"times": 3.0,
"size": 100,
"height": 10
}
],
"specialTerrains": [
{
"id": "Chasm",
"times": 0.5,
"size": 20,
"height": 30
},
{
"id": "SurfaceCave",
"times": 1.0,
"size": 60,
"height": 0
},
{
"id": "SurfaceCave",
"times": 3.0,
"size": 40,
"height": 0
},
{
"id": "SurfaceCave",
"times": 7.0,
"size": 30,
"height": 0
}
],
"transition": "LinerTransition",
"transitionTag": 2
},
"parallaxes": {
"deepRate": 0.9,
"base": [
{
"id": "waste_hill",
"parallel": 8.0,
"level": 360
},
{
"id": "waste_hill3",
"parallel": 6.0,
"level": 364
},
{
"id": "waste_hill2",
"parallel": 4.0,
"level": 370
},
{
"id": "waste_back",
"parallel": 3.0,
"level": 376
},
{
"id": "waste_back2",
"parallel": 2.0,
"level": 390
}
],
"underground": "red_sand_wall",
"linked": "red_sand_wall_link"
},
"musics": {
"daySurface": [
"day2",
"day3",
"day4",
"day5",
"mcday1",
"mcday2",
"mcday3",
"mcday4"
],
"nightSurface": [
"night1",
"night2",
"night3",
"night4"
]
},
"weather": "rain",
"composition": {
"main": {
"id": "red_sand_stone"
},
"subs": [
{
"id": "red_sand"
},
{
"id": "red_sand"
}
]
},
"oreGroupName": "default",
"liquidInfo": {
"liquid": "water",
"maxAllowCount": 500
},
"treeInfo": {
"styles": [
"log_bare_oak"
],
"density": 0.28
},
"grass": 0,
"distributions": {
"airWeight": 100,
"surfacePlaceables": [
{
"id": "pot",
"tag": 0,
"weight": 10
},
{
"id": "rock_waste",
"weight": 20
},
{
"id": "small_tree_waste",
"weight": 30
},
{
"id": "stone_decos_waste",
"weight": 20
},
{
"id": "sapling_cactus",
"weight": 30
}
],
"underWeight": 100,
"undergroundPlaceables": [
{
"id": "pot",
"tag": 0,
"weight": 10
},
{
"id": "rock_waste",
"weight": 10
},
{
"id": "glowing_mushroom",
"weight": 1
},
{
"id": "stalactite_waste",
"weight": 30
},
{
"id": "stalactite_small_waste",
"weight": 30
}
],
"hangingWeight": 100,
"hangingPlaceables": [
{
"id": "stalactite_hanging_waste",
"weight": 40
},
{
"id": "stalactite_hanging_small_waste",
"weight": 40
}
]
},
"pot": [
{
"itemId": "torch",
"min": 1,
"max": 5,
"weight": 15
},
{
"itemId": "potion_healing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_awkward",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_fire_resistance",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "wooden_arrow",
"min": 3,
"max": 10,
"weight": 10
},
{
"itemId": "coal",
"min": 1,
"max": 2,
"weight": 8
},
{
"itemId": "flint",
"min": 1,
"max": 4,
"weight": 6
}
],
"daySpawn": {
"mobSpeed": 500,
"maxMobSpawn": 5,
"mobs": [
{
"id": "large_waste_slime",
"weight": 5
},
{
"id": "large_waste_block_slime",
"weight": 3
},
{
"id": "waste_block_slime",
"weight": 4
},
{
"id": "waste_mummy",
"weight": 5
},
{
"id": "waste_ghost",
"weight": 4
},
{
"id": "creeper",
"weight": 2
},
{
"id": "enderman",
"weight": 1
}
],
"animalSpeed": 300,
"maxAnimalSpawn": 5,
"animals": []
},
"nightSpawn": {
"mobSpeed": 450,
"maxMobSpawn": 6,
"mobs": [
{
"id": "large_waste_slime",
"weight": 5
},
{
"id": "large_waste_block_slime",
"weight": 3
},
{
"id": "waste_mummy",
"weight": 5
},
{
"id": "waste_ghost",
"weight": 4
},
{
"id": "zombie",
"weight": 10
},
{
"id": "husk",
"weight": 10
},
{
"id": "arrow_zombie",
"weight": 8
},
{
"id": "bald_zombie",
"weight": 8
},
{
"id": "villager_zombie",
"weight": 6
},
{
"id": "skeleton",
"weight": 4
},
{
"id": "creeper",
"weight": 3
},
{
"id": "flower_creeper",
"weight": 1
},
{
"id": "phantom",
"weight": 2
},
{
"id": "enderman",
"weight": 2
}
],
"animalSpeed": 600,
"maxAnimalSpawn": 5,
"animals": []
},
"underSpawn": {
"mobSpeed": 400,
"maxMobSpawn": 6,
"mobs": [
{
"id": "waste_mummy",
"weight": 5
},
{
"id": "waste_ghost",
"weight": 4
},
{
"id": "zombie",
"weight": 5
},
{
"id": "bald_zombie",
"weight": 8
},
{
"id": "spider",
"weight": 18
},
{
"id": "skeleton",
"weight": 3
},
{
"id": "creeper",
"weight": 2
},
{
"id": "flower_creeper",
"weight": 2
},
{
"id": "enderman",
"weight": 3
}
],
"animalSpeed": 600,
"maxAnimalSpawn": 5,
"animals": []
},
"buildingInfo": [
],
"environmentBlocks": {
"total": 1000,
"blocks": [
{
"id": "red_sand",
"weight": 1
},
{
"id": "red_sand_stone",
"weight": 1
}
]
}
}
}
================================================
FILE: biomes/surfaces/desert.json
================================================
{
"desert": {
"biomeType": "Surface",
"dayLight": 1.0,
"skyColor": {
"midDayTopColor": [ 98, 170, 192 ],
"midDayBottomColor": [ 210, 226, 236 ],
"midNightTopColor": [ 5, 8, 32 ],
"midNightBottomColor": [ 20, 30, 68 ],
"transATopColor": [ 98, 170, 192 ],
"transABottomColor": [ 217, 198, 10 ],
"transBTopColor": [ 44, 33, 10 ],
"transBBottomColor": [ 155, 32, 10 ],
"transCTopColor": [ 5, 8, 32 ],
"transCBottomColor": [ 115, 32, 10 ]
},
"subBiomes": {
"subs": [
{
"biome": "jungle",
"minSize": 300,
"maxSize": 500,
"minX": 200,
"maxX": 400
},
{
"biome": "jungle",
"minSize": 300,
"maxSize": 500,
"minX": 600,
"maxX": 800
},
{
"biome": "tainted_land",
"minSize": 300,
"maxSize": 500,
"minX": 200,
"maxX": 400
},
{
"biome": "tainted_land",
"minSize": 300,
"maxSize": 500,
"minX": 600,
"maxX": 800
},
{
"biome": "flesh",
"minSize": 300,
"maxSize": 500,
"minX": 200,
"maxX": 400
},
{
"biome": "flesh",
"minSize": 300,
"maxSize": 500,
"minX": 600,
"maxX": 800
},
{
"biome": "volcano",
"minSize": 300,
"maxSize": 500,
"minX": 200,
"maxX": 400
},
{
"biome": "volcano",
"minSize": 300,
"maxSize": 500,
"minX": 600,
"maxX": 800
}
]
},
"terrains": {
"terrains": [
{
"id": "MountainTerrain",
"times": 4.0,
"size": 160,
"height": 16
},
{
"id": "BasinTerrain",
"times": 3.0,
"size": 50,
"height": 20
},
{
"id": "HillTerrain",
"times": 5.0,
"size": 60,
"height": 7
},
{
"id": "HillTerrain",
"times": 5.0,
"size": 100,
"height": 8
},
{
"id": "PlateauTerrain",
"times": 3.0,
"size": 100,
"height": 12
}
],
"specialTerrains": [
{
"id": "Chasm",
"times": 0.5,
"size": 20,
"height": 30
},
{
"id": "SurfaceCave",
"times": 2.0,
"size": 60,
"height": 0
},
{
"id": "SurfaceCave",
"times": 2.0,
"size": 40,
"height": 0
},
{
"id": "SurfaceCave",
"times": 8.0,
"size": 20,
"height": 0
}
],
"transition": "LinerTransition",
"transitionTag": 2
},
"parallaxes": {
"deepRate": 1.0,
"base": [
{
"id": "desert_hill_new_2",
"parallel": 6.0,
"level": 371
},
{
"id": "desert_hill_new",
"parallel": 4.0,
"level": 377
},
{
"id": "desert_2",
"parallel": 3.0,
"level": 387
}
],
"underground": "sand_wall",
"linked": "sand_wall_link"
},
"musics": {
"daySurface": [
"day2",
"day3",
"day4",
"day5",
"mcday1",
"mcday2",
"mcday3",
"mcday4"
],
"nightSurface": [
"night1",
"night2",
"night3",
"night4"
]
},
"weather": "overcast",
"composition": {
"main": {
"id": "sandstone"
},
"subs": [
{
"id": "sand"
},
{
"id": "cobblestone"
}
]
},
"oreGroupName": "default",
"liquidInfo": {},
"treeInfo": {
"styles": [
"log_cactus"
],
"density": 0.28
},
"grass": 0,
"distributions": {
"airWeight": 300,
"surfacePlaceables": [
{
"id": "pot",
"tag": 2,
"weight": 10
},
{
"id": "small_tree_desert",
"weight": 20
},
{
"id": "sapling_cactus",
"weight": 30
}
],
"underWeight": 200,
"undergroundPlaceables": [
{
"id": "pot",
"tag": 2,
"weight": 10
},
{
"id": "small_tree_desert",
"weight": 10
},
{
"id": "rock",
"weight": 10
},
{
"id": "stone_pillar_desert",
"weight": 10
},
{
"id": "stalactite_desert",
"weight": 20
},
{
"id": "stalactite_small_desert",
"weight": 20
},
{
"id": "glowing_mushroom",
"weight": 1
}
],
"hangingWeight": 100,
"hangingPlaceables": [
{
"id": "stalactite_hanging_desert",
"weight": 20
},
{
"id": "stalactite_hanging_small_desert",
"weight": 20
}
]
},
"pot": [
{
"itemId": "torch",
"min": 1,
"max": 3,
"weight": 15
},
{
"itemId": "potion_healing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_awkward",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_fire_resistance",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_glowing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "wooden_arrow",
"min": 3,
"max": 5,
"weight": 15
},
{
"itemId": "coal",
"min": 1,
"max": 2,
"weight": 8
},
{
"itemId": "flint",
"min": 1,
"max": 4,
"weight": 8
},
{
"itemId": "fire_bullet",
"min": 1,
"max": 4,
"weight": 8
}
],
"daySpawn": {
"mobSpeed": 500,
"maxMobSpawn": 5,
"mobs": [
{
"id": "desert_slime",
"weight": 5
},
{
"id": "large_desert_slime",
"weight": 4
},
{
"id": "eagle",
"weight": 3
},
{
"id": "mummy",
"weight": 4
},
{
"id": "creeper",
"weight": 2
},
{
"id": "husk",
"weight": 3
},
{
"id": "enderman",
"weight": 1
}
],
"animalSpeed": 300,
"maxAnimalSpawn": 5,
"animals": []
},
"nightSpawn": {
"mobSpeed": 450,
"maxMobSpawn": 6,
"mobs": [
{
"id": "large_desert_slime",
"weight": 10
},
{
"id": "eagle",
"weight": 6
},
{
"id": "mummy",
"weight": 24
},
{
"id": "zombie",
"weight": 20
},
{
"id": "husk",
"weight": 20
},
{
"id": "arrow_zombie",
"weight": 8
},
{
"id": "bald_zombie",
"weight": 8
},
{
"id": "villager_zombie",
"weight": 6
},
{
"id": "skeleton",
"weight": 4
},
{
"id": "creeper",
"weight": 3
},
{
"id": "flower_creeper",
"weight": 1
},
{
"id": "phantom",
"weight": 2
},
{
"id": "enderman",
"weight": 4
}
],
"animalSpeed": 600,
"maxAnimalSpawn": 5,
"animals": []
},
"underSpawn": {
"mobSpeed": 400,
"maxMobSpawn": 6,
"mobs": [
{
"id": "large_desert_slime",
"weight": 10
},
{
"id": "mummy",
"weight": 24
},
{
"id": "zombie",
"weight": 5
},
{
"id": "husk",
"weight": 8
},
{
"id": "bald_zombie",
"weight": 8
},
{
"id": "spider",
"weight": 18
},
{
"id": "bat",
"weight": 5
},
{
"id": "skeleton",
"weight": 3
},
{
"id": "creeper",
"weight": 2
},
{
"id": "flower_creeper",
"weight": 1
},
{
"id": "enderman",
"weight": 3
}
],
"animalSpeed": 600,
"maxAnimalSpawn": 5,
"animals": []
},
"buildingInfo": [
{
"buildingId": "pyramid",
"density": 1.0,
"fixSurfaceLine": true,
"genBeginXi": 50,
"genEndXi": 1000
},
{
"buildingId": "desert_house",
"density": 2.0,
"fixSurfaceLine": true,
"genBeginXi": 50,
"genEndXi": 1000
}
],
"environmentBlocks": {
"total": 1000,
"blocks": [
{
"id": "sandstone",
"weight": 1
},
{
"id": "sand",
"weight": 1
},
{
"id": "sandstone_smooth",
"weight": 1
}
]
}
}
}
================================================
FILE: biomes/surfaces/flesh.json
================================================
{
"flesh": {
"biomeType": "Surface",
"dayLight": 0.75,
"skyColor": {
"midDayTopColor": [ 130, 22, 22 ],
"midDayBottomColor": [ 150, 44, 44 ],
"midNightTopColor": [ 32, 8, 8 ],
"midNightBottomColor": [ 64, 16, 16 ],
"transATopColor": [ 100, 18, 18 ],
"transABottomColor": [ 100, 33, 33 ],
"transBTopColor": [ 60, 16, 16 ],
"transBBottomColor": [ 80, 24, 24 ],
"transCTopColor": [ 32, 8, 8 ],
"transCBottomColor": [ 72, 20, 20 ]
},
"subBiomes": {
"subs": [
{
"biome": "jungle",
"minSize": 200,
"maxSize": 400,
"minX": 400,
"maxX": 600
},
{
"biome": "tainted_land",
"minSize": 300,
"maxSize": 500,
"minX": 400,
"maxX": 600
},
{
"biome": "volcano",
"minSize": 200,
"maxSize": 400,
"minX": 400,
"maxX": 600
}
]
},
"terrains": {
"terrains": [
{
"id": "MountainTerrain",
"times": 2.0,
"size": 160,
"height": 24
},
{
"id": "BasinTerrain",
"times": 3.0,
"size": 50,
"height": 8
},
{
"id": "HillTerrain",
"times": 3.0,
"size": 200,
"height": 10
},
{
"id": "PlateauTerrain",
"times": 3.0,
"size": 100,
"height": 10
}
],
"specialTerrains": [
{
"id": "Chasm",
"times": 0.5,
"size": 20,
"height": 30
},
{
"id": "SurfaceCave",
"times": 1.0,
"size": 60,
"height": 0
},
{
"id": "SurfaceCave",
"times": 2.0,
"size": 40,
"height": 0
}
],
"transition": "LinerTransition",
"transitionTag": 2
},
"parallaxes": {
"deepRate": 1.0,
"base": [
{
"id": "flesh_hill",
"parallel": 8.0,
"level": 360
},
{
"id": "flesh_hill3",
"parallel": 7.0,
"level": 364
},
{
"id": "flesh_hill2",
"parallel": 6.5,
"level": 368
},
{
"id": "flesh_back",
"parallel": 6.0,
"level": 377
},
{
"id": "flesh_fossil2",
"parallel": 5.0,
"level": 368
},
{
"id": "flesh_back2",
"parallel": 4.0,
"level": 382
},
{
"id": "flesh_fossil",
"parallel": 3.0,
"level": 373
},
{
"id": "flesh_bush",
"parallel": 2.0,
"level": 393
}
],
"underground": "flesh_wall",
"linked": "flesh_wall_link"
},
"musics": {
"daySurface": [
"day2",
"day3",
"day4",
"day5",
"mcday1",
"mcday2",
"mcday3",
"mcday4"
],
"nightSurface": [
"night1",
"night2",
"night3",
"night4"
]
},
"weather": "rain",
"composition": {
"main": {
"id": "flesh_dirt"
},
"subs": [
{
"id": "flesh_stone"
},
{
"id": "flesh_gut"
},
{
"id": "flesh_gut"
}
]
},
"oreGroupName": "default",
"liquidInfo": {
"liquid": "water",
"maxAllowCount": 500
},
"treeInfo": {
"styles": [
"log_dark_oak"
],
"density": 0.18
},
"grass": 1,
"distributions": {
"airWeight": 100,
"surfacePlaceables": [
{
"id": "pot",
"tag": 4,
"weight": 40
},
{
"id": "eyeball_grass",
"weight": 40
},
{
"id": "large_eyeball_grass",
"weight": 40
},
{
"id": "flesh_tentacle",
"weight": 80
},
{
"id": "blood_grass",
"weight": 200
}
],
"underWeight": 100,
"undergroundPlaceables": [
{
"id": "pot",
"tag": 4,
"weight": 40
},
{
"id": "eyeball_grass",
"weight": 40
},
{
"id": "large_eyeball_grass",
"weight": 40
},
{
"id": "flesh_tentacle",
"weight": 80
},
{
"id": "blood_grass",
"weight": 200
}
],
"hangingWeight": 100,
"hangingPlaceables": [
{
"id": "flesh_tentacle_hanging",
"weight": 80
},
{
"id": "eyeball_vine",
"weight": 40
}
]
},
"pot": [
{
"itemId": "torch",
"min": 1,
"max": 5,
"weight": 15
},
{
"itemId": "potion_healing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_awkward",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_fire_resistance",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_swiftness",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "wooden_arrow",
"min": 3,
"max": 10,
"weight": 10
},
{
"itemId": "blood_arrow",
"min": 3,
"max": 10,
"weight": 8
},
{
"itemId": "coal",
"min": 1,
"max": 2,
"weight": 2
},
{
"itemId": "flint",
"min": 1,
"max": 4,
"weight": 2
},
{
"itemId": "grenade",
"min": 1,
"max": 2,
"weight": 3
}
],
"daySpawn": {
"mobSpeed": 200,
"maxMobSpawn": 5,
"mobs": [
{
"id": "blood_eye",
"weight": 10
},
{
"id": "blood_slime",
"weight": 8
},
{
"id": "blood_bat",
"weight": 4
},
{
"id": "blood_skeleton",
"weight": 4
},
{
"id": "creeper",
"weight": 1
},
{
"id": "vampire_miner",
"weight": 10
}
],
"animalSpeed": 240,
"maxAnimalSpawn": 5,
"animals": []
},
"nightSpawn": {
"mobSpeed": 250,
"maxMobSpawn": 6,
"mobs": [
{
"id": "blood_eye",
"weight": 14
},
{
"id": "vampire_miner",
"weight": 10
},
{
"id": "blood_slime",
"weight": 5
},
{
"id": "blood_bat",
"weight": 4
},
{
"id": "blood_skeleton",
"weight": 4
},
{
"id": "zombie",
"weight": 6
},
{
"id": "arrow_zombie",
"weight": 6
},
{
"id": "bald_zombie",
"weight": 5
},
{
"id": "villager_zombie",
"weight": 4
},
{
"id": "skeleton",
"weight": 4
},
{
"id": "creeper",
"weight": 3
},
{
"id": "flower_creeper",
"weight": 1
},
{
"id": "phantom",
"weight": 2
},
{
"id": "enderman",
"weight": 2
}
],
"animalSpeed": 600,
"maxAnimalSpawn": 5,
"animals": []
},
"underSpawn": {
"mobSpeed": 400,
"maxMobSpawn": 6,
"mobs": [
{
"id": "blood_eye",
"weight": 4
},
{
"id": "blood_slime",
"weight": 14
},
{
"id": "blood_bat",
"weight": 4
},
{
"id": "blood_skeleton",
"weight": 4
},
{
"id": "zombie",
"weight": 5
},
{
"id": "bald_zombie",
"weight": 8
},
{
"id": "spider",
"weight": 18
},
{
"id": "bat",
"weight": 5
},
{
"id": "skeleton",
"weight": 3
},
{
"id": "creeper",
"weight": 2
},
{
"id": "flower_creeper",
"weight": 1
}
],
"animalSpeed": 600,
"maxAnimalSpawn": 5,
"animals": []
},
"buildingInfo": [
],
"environmentBlocks": {
"total": 1000,
"blocks": [
{
"id": "flesh_dirt",
"weight": 1
},
{
"id": "flesh_stone",
"weight": 1
},
{
"id": "flesh_gut",
"weight": 1
}
]
}
}
}
================================================
FILE: biomes/surfaces/forest.json
================================================
{
"forest": {
"biomeType": "Surface",
"dayLight": 1.0,
"subBiomes": {
"subs": [
{
"biome": "desert",
"minSize": 160,
"maxSize": 220,
"minX": 100,
"maxX": 200
},
{
"biome": "badland",
"minSize": 160,
"maxSize": 200,
"minX": 700,
"maxX": 900
},
{
"biome": "ocean",
"minSize": 160,
"maxSize": 260,
"minX": 100,
"maxX": 200
},
{
"biome": "ocean",
"minSize": 160,
"maxSize": 260,
"minX": 700,
"maxX": 900
}
]
},
"skyColor": {
"midDayTopColor": [ 98, 170, 192 ],
"midDayBottomColor": [ 210, 226, 236 ],
"midNightTopColor": [ 5, 8, 32 ],
"midNightBottomColor": [ 20, 30, 68 ],
"transATopColor": [ 98, 170, 192 ],
"transABottomColor": [ 217, 198, 10 ],
"transBTopColor": [ 44, 33, 10 ],
"transBBottomColor": [ 155, 32, 10 ],
"transCTopColor": [ 5, 8, 32 ],
"transCBottomColor": [ 115, 32, 10 ]
},
"terrains": {
"terrains": [
{
"id": "MountainTerrain",
"times": 3.0,
"size": 200,
"height": 20
},
{
"id": "BasinTerrain",
"times": 2.0,
"size": 50,
"height": 8
},
{
"id": "HillTerrain",
"times": 1.0,
"size": 300,
"height": 10
}
],
"specialTerrains": [
{
"id": "Chasm",
"times": 0.5,
"size": 20,
"height": 30
},
{
"id": "Lake",
"times": 0.5,
"size": 60,
"height": 10
},
{
"id": "Lake",
"times": 1.0,
"size": 40,
"height": 10
},
{
"id": "SurfaceCave",
"times": 1.0,
"size": 80,
"height": 0
},
{
"id": "SurfaceCave",
"times": 3.0,
"size": 60,
"height": 0
}
],
"transition": "LinerTransition",
"transitionTag": 2
},
"parallaxes": {
"deepRate": 1.0,
"base": [
{
"id": "snowy_hill",
"parallel": 8.0,
"level": 360
},
{
"id": "snowy_hill2",
"parallel": 6.0,
"level": 364
},
{
"id": "stone_hill",
"parallel": 4.0,
"level": 372
},
{
"id": "large_grass_small_tree",
"parallel": 3.5,
"level": 363
},
{
"id": "large_grass_medium_tree",
"parallel": 3.0,
"level": 368
},
{
"id": "large_grass_tree",
"parallel": 2.0,
"level": 372
},
{
"id": "large_bush",
"parallel": 1.5,
"level": 394
}
],
"underground": "mud_wall",
"linked": "mud_wall_link"
},
"musics": {
"daySurface": [
"day1",
"day2",
"day3",
"day4",
"day5",
"mcday1",
"mcday2",
"mcday3",
"mcday4"
],
"nightSurface": [
"night1",
"night2",
"night3",
"night4"
]
},
"weather": "rain",
"composition": {
"main": {
"id": "dirt"
},
"subs": [
{
"id": "cobblestone"
},
{
"id": "clay"
}
]
},
"oreGroupName": "default",
"liquidInfo": {
"liquid": "water",
"maxAllowCount": 500
},
"treeInfo": {
"styles": [
"log_oak",
"log_birch"
],
"density": 0.18
},
"plantInfo": {
"makeSugarcane": true
},
"grass": 1,
"distributions": {
"airWeight": 200,
"surfacePlaceables": [
{
"id": "grass",
"weight": 100
},
{
"id": "dandelion",
"weight": 10
},
{
"id": "allium",
"weight": 10
},
{
"id": "sunflower",
"weight": 20
},
{
"id": "brown_mushroom",
"weight": 20
},
{
"id": "red_mushroom",
"weight": 20
},
{
"id": "large_brown_mushroom",
"weight": 5
},
{
"id": "large_red_mushroom",
"weight": 10
},
{
"id": "lilac",
"weight": 5
},
{
"id": "red_tulip",
"weight": 5
},
{
"id": "white_tulip",
"weight": 5
},
{
"id": "orange_tulip",
"weight": 5
},
{
"id": "pink_tulip",
"weight": 5
},
{
"id": "small_tree_normal",
"weight": 30
},
{
"id": "stone_decos_normal",
"weight": 15
},
{
"id": "stone_decos_mossy",
"weight": 15
},
{
"id": "rock",
"weight": 10
},
{
"id": "bush",
"weight": 20
}
],
"underWeight": 100,
"undergroundPlaceables": [
{
"id": "pot",
"tag": 0,
"weight": 40
},
{
"id": "small_tree_normal",
"weight": 3
},
{
"id": "rock",
"weight": 5
},
{
"id": "large_brown_mushroom",
"weight": 4
},
{
"id": "large_red_mushroom",
"weight": 3
}
],
"hangingWeight": 40,
"hangingPlaceables": [
{
"id": "vine",
"weight": 15
},
{
"id": "stalactite_hanging_stone",
"weight": 5
},
{
"id": "stalactite_hanging_small_stone",
"weight": 5
}
]
},
"pot": [
{
"itemId": "torch",
"min": 1,
"max": 4,
"weight": 15
},
{
"itemId": "potion_healing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_night_vision",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_strength",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_glowing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "wooden_arrow",
"min": 2,
"max": 6,
"weight": 10
},
{
"itemId": "coal",
"min": 1,
"max": 2,
"weight": 5
},
{
"itemId": "flint",
"min": 1,
"max": 4,
"weight": 6
},
{
"itemId": "fire_bullet",
"min": 1,
"max": 4,
"weight": 4
}
],
"daySpawn": {
"mobSpeed": 640,
"maxMobSpawn": 5,
"mobs": [
{
"id": "green_slime",
"weight": 10
},
{
"id": "large_green_slime",
"weight": 5
},
{
"id": "yellow_slime",
"weight": 6
},
{
"id": "blue_slime",
"weight": 2
},
{
"id": "purple_slime",
"weight": 1
},
{
"id": "enderman",
"weight": 1
}
],
"animalSpeed": 300,
"maxAnimalSpawn": 5,
"animals": [
{
"id": "chicken",
"weight": 10
},
{
"id": "cow",
"weight": 10
},
{
"id": "white_rabbit",
"weight": 10
},
{
"id": "squid",
"weight": 30
},
{
"id": "light_blue_butterfly",
"weight": 4
},
{
"id": "red_butterfly",
"weight": 4
},
{
"id": "yellow_butterfly",
"weight": 4
}
]
},
"nightSpawn": {
"mobSpeed": 460,
"maxMobSpawn": 6,
"mobs": [
{
"id": "zombie",
"weight": 20
},
{
"id": "spider",
"weight": 8
},
{
"id": "arrow_zombie",
"weight": 8
},
{
"id": "bald_zombie",
"weight": 8
},
{
"id": "villager_zombie",
"weight": 6
},
{
"id": "skeleton",
"weight": 4
},
{
"id": "creeper",
"weight": 3
},
{
"id": "flower_creeper",
"weight": 1
},
{
"id": "phantom",
"weight": 2
},
{
"id": "fly_eye",
"weight": 2
},
{
"id": "enderman",
"weight": 2
}
],
"animalSpeed": 600,
"maxAnimalSpawn": 5,
"animals": [
{
"id": "squid",
"weight": 10
},
{
"id": "black_rabbit",
"weight": 3
}
]
},
"underSpawn": {
"mobSpeed": 400,
"maxMobSpawn": 6,
"mobs": [
{
"id": "large_black_slime",
"weight": 10
},
{
"id": "zombie",
"weight": 10
},
{
"id": "spider",
"weight": 8
},
{
"id": "bald_zombie",
"weight": 8
},
{
"id": "villager_zombie",
"weight": 6
},
{
"id": "bat",
"weight": 5
},
{
"id": "skeleton",
"weight": 2
},
{
"id": "creeper",
"weight": 2
},
{
"id": "flower_creeper",
"weight": 1
},
{
"id": "enderman",
"weight": 3
}
],
"animalSpeed": 600,
"maxAnimalSpawn": 5,
"animals": [
{
"id": "squid",
"weight": 10
}
]
},
"buildingInfo": [
{
"buildingId": "mini_house",
"density": 0.5,
"isSpecificNoGen": true,
"specificChunkXi": 0,
"specificChunkYi": 0,
"fixSurfaceLine": true,
"genBeginXi": 400,
"genEndXi": 600
}
]
}
}
================================================
FILE: biomes/surfaces/jungle.json
================================================
{
"jungle": {
"biomeType": "Surface",
"dayLight": 1.0,
"skyColor": {
"midDayTopColor": [ 98, 170, 192 ],
"midDayBottomColor": [ 210, 226, 236 ],
"midNightTopColor": [ 5, 8, 32 ],
"midNightBottomColor": [ 20, 30, 68 ],
"transATopColor": [ 98, 170, 192 ],
"transABottomColor": [ 217, 198, 10 ],
"transBTopColor": [ 44, 33, 10 ],
"transBBottomColor": [ 155, 32, 10 ],
"transCTopColor": [ 5, 8, 32 ],
"transCBottomColor": [ 115, 32, 10 ]
},
"subBiomes": {
"subs": [
{
"biome": "snow_land",
"minSize": 300,
"maxSize": 500,
"minX": 200,
"maxX": 800
},
{
"biome": "tainted_land",
"minSize": 300,
"maxSize": 500,
"minX": 200,
"maxX": 800
},
{
"biome": "flesh",
"minSize": 300,
"maxSize": 500,
"minX": 200,
"maxX": 800
},
{
"biome": "volcano",
"minSize": 200,
"maxSize": 300,
"minX": 200,
"maxX": 800
},
{
"biome": "ocean",
"minSize": 200,
"maxSize": 300,
"minX": 200,
"maxX": 800
},
{
"biome": "mushroom_fields",
"minSize": 300,
"maxSize": 500,
"minX": 200,
"maxX": 800
}
]
},
"terrains": {
"terrains": [
{
"id": "MountainTerrain",
"times": 6.0,
"size": 200,
"height": 5
},
{
"id": "BasinTerrain",
"times": 4.0,
"size": 150,
"height": 8
},
{
"id": "HillTerrain",
"times": 2.0,
"size": 200,
"height": 15
}
],
"transition": "LinerTransition",
"transitionTag": 2
},
"parallaxes": {
"deepRate": 1.0,
"base": [
{
"id": "snowy_hill",
"parallel": 8.0,
"level": 358
},
{
"id": "snowy_hill2",
"parallel": 7.0,
"level": 362
},
{
"id": "dirty_hill",
"parallel": 6.0,
"level": 362
},
{
"id": "jungle_bush",
"parallel": 5.0,
"level": 376
},
{
"id": "stone_hill",
"parallel": 4.0,
"level": 377
},
{
"id": "jungle_bush",
"parallel": 3.0,
"level": 380
},
{
"id": "jungle_bush",
"parallel": 2.0,
"level": 386
},
{
"id": "jungle_bush",
"parallel": 1.5,
"level": 396
}
],
"underground": "mud_wall",
"linked": "mud_wall_link"
},
"musics": {
"daySurface": [
"day1",
"day2",
"day3",
"day4",
"day5",
"mcday1",
"mcday2",
"mcday3",
"mcday4"
],
"nightSurface": [
"night1",
"night2",
"night3",
"night4"
]
},
"weather": "rain",
"composition": {
"main": {
"id": "coarse_dirt"
},
"subs": [
{
"id": "cobblestone"
},
{
"id": "dirt"
}
]
},
"oreGroupName": "default",
"liquidInfo": {
"liquid": "water",
"maxAllowCount": 500
},
"treeInfo": {
"styles": [
"log_jungle",
"log_acacia"
],
"density": 0.88
},
"plantInfo": {
"makeSugarcane": true
},
"grass": 1,
"distributions": {
"airWeight": 50,
"surfacePlaceables": [
{
"id": "grass",
"weight": 50
},
{
"id": "azure_bluet",
"weight": 10
},
{
"id": "blue_orchid",
"weight": 10
},
{
"id": "fern",
"weight": 10
},
{
"id": "glowing_mushroom",
"weight": 10
},
{
"id": "allium",
"weight": 10
},
{
"id": "peony",
"weight": 10
},
{
"id": "large_brown_mushroom",
"weight": 5
},
{
"id": "large_red_mushroom",
"weight": 10
},
{
"id": "rose_bush",
"weight": 5
},
{
"id": "red_tulip",
"weight": 5
},
{
"id": "white_tulip",
"weight": 5
},
{
"id": "orange_tulip",
"weight": 5
},
{
"id": "pink_tulip",
"weight": 5
},
{
"id": "small_tree_normal",
"weight": 30
},
{
"id": "stone_decos_normal",
"weight": 15
},
{
"id": "stone_decos_mossy",
"weight": 15
},
{
"id": "rock",
"weight": 10
},
{
"id": "bush",
"weight": 20
},
{
"id": "watermelon",
"weight": 10
},
{
"id": "pumpkin",
"weight": 10
}
],
"underWeight": 50,
"undergroundPlaceables": [
{
"id": "grass",
"weight": 30
},
{
"id": "pot",
"tag": 0,
"weight": 40
},
{
"id": "small_tree_normal",
"weight": 3
},
{
"id": "rock",
"weight": 5
},
{
"id": "large_brown_mushroom",
"weight": 4
},
{
"id": "large_red_mushroom",
"weight": 3
},
{
"id": "pumpkin",
"weight": 2
},
{
"id": "watermelon",
"weight": 2
},
{
"id": "glowing_mushroom",
"weight": 1
}
],
"hangingWeight": 40,
"hangingPlaceables": [
{
"id": "vine",
"weight": 50
},
{
"id": "stalactite_hanging_stone",
"weight": 5
},
{
"id": "stalactite_hanging_small_stone",
"weight": 5
}
]
},
"pot": [
{
"itemId": "torch",
"min": 1,
"max": 5,
"weight": 15
},
{
"itemId": "potion_healing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_night_vision",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_strength",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_glowing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_water_breathing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "wooden_arrow",
"min": 3,
"max": 10,
"weight": 10
},
{
"itemId": "coal",
"min": 1,
"max": 2,
"weight": 10
},
{
"itemId": "fire_bullet",
"min": 3,
"max": 6,
"weight": 10
}
],
"daySpawn": {
"mobSpeed": 500,
"maxMobSpawn": 5,
"mobs": [
{
"id": "green_slime",
"weight": 5
},
{
"id": "yellow_slime",
"weight": 4
},
{
"id": "blue_slime",
"weight": 4
},
{
"id": "purple_slime",
"weight": 4
},
{
"id": "block_slime",
"weight": 2
},
{
"id": "large_block_slime",
"weight": 1
},
{
"id": "spider",
"weight": 1
},
{
"id": "jungle_bat",
"weight": 2
},
{
"id": "large_jungle_bat",
"weight": 1
},
{
"id": "enderman",
"weight": 4
}
],
"animalSpeed": 300,
"maxAnimalSpawn": 5,
"animals": [
{
"id": "chicken",
"weight": 3
},
{
"id": "cow",
"weight": 2
},
{
"id": "pig",
"weight": 3
},
{
"id": "wolf",
"weight": 1
},
{
"id": "cat",
"weight": 1
},
{
"id": "white_rabbit",
"weight": 1
},
{
"id": "black_rabbit",
"weight": 1
},
{
"id": "brown_rabbit",
"weight": 1
},
{
"id": "yellow_rabbit",
"weight": 1
},
{
"id": "squid",
"weight": 8
},
{
"id": "pufferfish",
"weight": 4
},
{
"id": "light_blue_butterfly",
"weight": 1
},
{
"id": "red_butterfly",
"weight": 1
},
{
"id": "yellow_butterfly",
"weight": 1
}
]
},
"nightSpawn": {
"mobSpeed": 400,
"maxMobSpawn": 7,
"mobs": [
{
"id": "large_jungle_bat",
"weight": 5
},
{
"id": "man_eater",
"weight": 4
},
{
"id": "zombie",
"weight": 20
},
{
"id": "arrow_zombie",
"weight": 8
},
{
"id": "bald_zombie",
"weight": 8
},
{
"id": "villager_zombie",
"weight": 6
},
{
"id": "skeleton",
"weight": 4
},
{
"id": "creeper",
"weight": 1
},
{
"id": "flower_creeper",
"weight": 2
},
{
"id": "phantom",
"weight": 2
},
{
"id": "bat",
"weight": 3
},
{
"id": "spider",
"weight": 3
},
{
"id": "doge_zombie",
"weight": 2
},
{
"id": "enderman",
"weight": 3
}
],
"animalSpeed": 400,
"maxAnimalSpawn": 5,
"animals": [
{
"id": "squid",
"weight": 8
},
{
"id": "pufferfish",
"weight": 4
}
]
},
"underSpawn": {
"mobSpeed": 400,
"maxMobSpawn": 6,
"mobs": [
{
"id": "jungle_bat",
"weight": 10
},
{
"id": "large_jungle_bat",
"weight": 6
},
{
"id": "man_eater",
"weight": 6
},
{
"id": "zombie",
"weight": 10
},
{
"id": "spider",
"weight": 8
},
{
"id": "bald_zombie",
"weight": 8
},
{
"id": "villager_zombie",
"weight": 6
},
{
"id": "skeleton",
"weight": 2
},
{
"id": "creeper",
"weight": 2
},
{
"id": "enderman",
"weight": 1
}
],
"animalSpeed": 600,
"maxAnimalSpawn": 5,
"animals": [
{
"id": "squid",
"weight": 10
}
]
},
"buildingInfo": [
{
"buildingId": "jungle_temple",
"density": 0.70,
"fixSurfaceLine": true,
"genBeginXi": 100,
"genEndXi": 900
}
],
"environmentBlocks": {
"total": 300,
"blocks": [
{
"id": "coarse_dirt",
"weight": 1
}
]
}
}
}
================================================
FILE: biomes/surfaces/mushroom_fields.json
================================================
{
"mushroom_fields": {
"biomeType": "Surface",
"dayLight": 1.0,
"skyColor": {
"midDayTopColor": [ 98, 170, 192 ],
"midDayBottomColor": [ 210, 226, 236 ],
"midNightTopColor": [ 5, 8, 32 ],
"midNightBottomColor": [ 20, 30, 68 ],
"transATopColor": [ 98, 170, 192 ],
"transABottomColor": [ 217, 198, 10 ],
"transBTopColor": [ 44, 33, 10 ],
"transBBottomColor": [ 155, 32, 10 ],
"transCTopColor": [ 5, 8, 32 ],
"transCBottomColor": [ 115, 32, 10 ]
},
"subBiomes": {
"subs": [
{
"biome": "jungle",
"minSize": 300,
"maxSize": 400,
"minX": 400,
"maxX": 600
},
{
"biome": "forest",
"minSize": 300,
"maxSize": 400,
"minX": 400,
"maxX": 600
},
{
"biome": "desert",
"minSize": 300,
"maxSize": 400,
"minX": 400,
"maxX": 600
},
{
"biome": "snow_land",
"minSize": 400,
"maxSize": 500,
"minX": 400,
"maxX": 600
},
{
"biome": "ocean",
"minSize": 100,
"maxSize": 200,
"minX": 400,
"maxX": 600
}
]
},
"terrains": {
"terrains": [
{
"id": "MountainTerrain",
"times": 3.0,
"size": 200,
"height": 20
},
{
"id": "BasinTerrain",
"times": 1.0,
"size": 50,
"height": 12
},
{
"id": "HillTerrain",
"times": 4.0,
"size": 300,
"height": 12
}
],
"specialTerrains": [
{
"id": "Chasm",
"times": 0.5,
"size": 20,
"height": 30
},
{
"id": "Lake",
"times": 0.5,
"size": 60,
"height": 10
},
{
"id": "Lake",
"times": 1.0,
"size": 40,
"height": 10
},
{
"id": "SurfaceCave",
"times": 1.0,
"size": 80,
"height": 0
},
{
"id": "SurfaceCave",
"times": 2.0,
"size": 60,
"height": 0
}
],
"transition": "LinerTransition",
"transitionTag": 2
},
"parallaxes": {
"deepRate": 1.0,
"base": [
{
"id": "dirty_hill",
"parallel": 8.0,
"level": 375
},
{
"id": "large_mushrooms",
"parallel": 6.0,
"level": 368
},
{
"id": "mushroom_grass",
"parallel": 4.0,
"level": 383
},
{
"id": "large_mushrooms2",
"parallel": 3.0,
"level": 380
},
{
"id": "mushroom_grass",
"parallel": 2.0,
"level": 392
}
],
"underground": "mud_wall",
"linked": "mud_wall_link"
},
"musics": {
"daySurface": [
"day1",
"day2",
"day3",
"day4",
"day5",
"mcday1",
"mcday2",
"mcday3",
"mcday4"
],
"nightSurface": [
"night1",
"night2",
"night3",
"night4"
]
},
"weather": "rain",
"composition": {
"main": {
"id": "mycelium"
},
"subs": [
{
"id": "cobblestone"
},
{
"id": "brown_mushroom_block"
}
]
},
"oreGroupName": "default",
"liquidInfo": {
"liquid": "water",
"maxAllowCount": 500
},
"treeInfo": {
"styles": [],
"density": 0.18
},
"mushroomInfo": {
"styles": [
"brown_mushroom_block",
"red_mushroom_block"
],
"density": 0.6
},
"grass": 1,
"distributions": {
"airWeight": 50,
"surfacePlaceables": [
{
"id": "brown_mushroom",
"weight": 20
},
{
"id": "red_mushroom",
"weight": 20
},
{
"id": "large_brown_mushroom",
"weight": 5
},
{
"id": "large_red_mushroom",
"weight": 10
}
],
"underWeight": 100,
"undergroundPlaceables": [
{
"id": "pot",
"tag": 0,
"weight": 40
},
{
"id": "brown_mushroom",
"weight": 20
},
{
"id": "red_mushroom",
"weight": 20
},
{
"id": "large_brown_mushroom",
"weight": 4
},
{
"id": "large_red_mushroom",
"weight": 3
}
],
"hangingWeight": 40,
"hangingPlaceables": []
},
"pot": [
{
"itemId": "torch",
"min": 1,
"max": 5,
"weight": 15
},
{
"itemId": "potion_healing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_night_vision",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_strength",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "wooden_arrow",
"min": 3,
"max": 10,
"weight": 12
},
{
"itemId": "coal",
"min": 1,
"max": 2,
"weight": 10
},
{
"itemId": "flint",
"min": 1,
"max": 4,
"weight": 8
},
{
"itemId": "grenade",
"min": 1,
"max": 2,
"weight": 3
}
],
"daySpawn": {
"mobSpeed": 500,
"maxMobSpawn": 5,
"mobs": [],
"animalSpeed": 300,
"maxAnimalSpawn": 5,
"animals": [
{
"id": "brown_mushroom_cow",
"weight": 10
},
{
"id": "red_mushroom_cow",
"weight": 10
}
]
},
"nightSpawn": {
"mobSpeed": 460,
"maxMobSpawn": 6,
"mobs": [],
"animalSpeed": 600,
"maxAnimalSpawn": 5,
"animals": [
{
"id": "brown_mushroom_cow",
"weight": 10
},
{
"id": "red_mushroom_cow",
"weight": 10
}
]
},
"underSpawn": {
"mobSpeed": 400,
"maxMobSpawn": 6,
"mobs": [],
"animalSpeed": 600,
"maxAnimalSpawn": 5,
"animals": [
{
"id": "brown_mushroom_cow",
"weight": 10
},
{
"id": "red_mushroom_cow",
"weight": 10
}
]
},
"buildingInfo": [
],
"environmentBlocks": {
"total": 1000,
"blocks": [
{
"id": "mycelium",
"weight": 1
}
]
}
}
}
================================================
FILE: biomes/surfaces/ocean.json
================================================
{
"ocean": {
"biomeType": "Surface",
"dayLight": 1.0,
"skyColor": {
"midDayTopColor": [ 98, 170, 192 ],
"midDayBottomColor": [ 210, 226, 236 ],
"midNightTopColor": [ 5, 8, 32 ],
"midNightBottomColor": [ 20, 30, 68 ],
"transATopColor": [ 98, 170, 192 ],
"transABottomColor": [ 217, 198, 10 ],
"transBTopColor": [ 44, 33, 10 ],
"transBBottomColor": [ 155, 32, 10 ],
"transCTopColor": [ 5, 8, 32 ],
"transCBottomColor": [ 115, 32, 10 ]
},
"terrains": {
"terrains": [],
"specialTerrains": [],
"transition": "LinerTransition",
"transitionTag": 2
},
"parallaxes": {
"deepRate": 1.0,
"base": [],
"underground": "stone_wall",
"linked": "stone_wall_link"
},
"musics": {
"daySurface": [
"day1",
"day2",
"day3",
"day4",
"day5",
"mcday1",
"mcday2",
"mcday3",
"mcday4"
],
"nightSurface": [
"night1",
"night2",
"night3",
"night4"
]
},
"weather": "rain",
"composition": {
"main": {
"id": "prismarine_mud"
},
"subs": [
{
"id": "sand"
},
{
"id": "cobblestone"
}
]
},
"oreGroupName": "default",
"liquidInfo": {
"liquid": "water",
"maxAllowCount": 500
},
"treeInfo": {
"styles": [
"log_palm"
],
"density": 0.08
},
"plantInfo": {
"makeKelp": true,
"makeSugarcane": true
},
"grass": 0,
"distributions": {
"airWeight": 100,
"surfacePlaceables": [
{
"id": "sea_shell",
"weight": 40
}
],
"underWeight": 100,
"undergroundPlaceables": [
{
"id": "pot",
"tag": 0,
"weight": 20
},
{
"id": "sea_grass",
"weight": 20
},
{
"id": "coral",
"weight": 20
},
{
"id": "sea_shell",
"weight": 20
}
]
},
"pot": [
{
"itemId": "torch",
"min": 1,
"max": 5,
"weight": 10
},
{
"itemId": "potion_healing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_leaping",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_water_breathing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "nautilus_shell",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "wooden_arrow",
"min": 3,
"max": 10,
"weight": 8
},
{
"itemId": "lighting_arrow",
"min": 3,
"max": 6,
"weight": 6
}
],
"daySpawn": {
"mobSpeed": 400,
"maxMobSpawn": 5,
"mobs": [
{
"id": "green_slime",
"weight": 2
},
{
"id": "large_green_slime",
"weight": 1
},
{
"id": "guardian",
"weight": 5
},
{
"id": "drowned",
"weight": 1
},
{
"id": "creeper",
"weight": 1
}
],
"animalSpeed": 200,
"maxAnimalSpawn": 5,
"animals": [
{
"id": "pufferfish",
"weight": 5
},
{
"id": "dolphin",
"weight": 5
},
{
"id": "squid",
"weight": 5
},
{
"id": "turtle",
"weight": 5
}
]
},
"nightSpawn": {
"mobSpeed": 300,
"maxMobSpawn": 7,
"mobs": [
{
"id": "drowned",
"weight": 3
},
{
"id": "zombie",
"weight": 20
},
{
"id": "spider",
"weight": 8
},
{
"id": "arrow_zombie",
"weight": 8
},
{
"id": "bald_zombie",
"weight": 8
},
{
"id": "villager_zombie",
"weight": 6
},
{
"id": "skeleton",
"weight": 4
},
{
"id": "creeper",
"weight": 3
},
{
"id": "flower_creeper",
"weight": 1
},
{
"id": "phantom",
"weight": 2
}
],
"animalSpeed": 200,
"maxAnimalSpawn": 5,
"animals": [
{
"id": "pufferfish",
"weight": 5
},
{
"id": "dolphin",
"weight": 5
},
{
"id": "squid",
"weight": 5
},
{
"id": "turtle",
"weight": 5
}
]
},
"underSpawn": {
"mobSpeed": 400,
"maxMobSpawn": 6,
"mobs": [],
"animalSpeed": 600,
"maxAnimalSpawn": 5,
"animals": []
},
"buildingInfo": [
{
"buildingId": "monument_ocean",
"density": 0.8,
"genBeginXi": 400,
"genEndXi": 600,
"genBeginYi": 470,
"genEndYi": 500
}
],
"environmentBlocks": {
"total": 1000,
"blocks": [
{
"id": "prismarine_mud",
"weight": 4
}
]
}
}
}
================================================
FILE: biomes/surfaces/snow_land.json
================================================
{
"snow_land": {
"biomeType": "Surface",
"dayLight": 1.0,
"skyColor": {
"midDayTopColor": [ 98, 170, 192 ],
"midDayBottomColor": [ 210, 226, 236 ],
"midNightTopColor": [ 5, 8, 32 ],
"midNightBottomColor": [ 20, 30, 68 ],
"transATopColor": [ 98, 170, 192 ],
"transABottomColor": [ 217, 198, 10 ],
"transBTopColor": [ 44, 33, 10 ],
"transBBottomColor": [ 155, 32, 10 ],
"transCTopColor": [ 5, 8, 32 ],
"transCBottomColor": [ 115, 32, 10 ]
},
"subBiomes": {
"subs": [
{
"biome": "tainted_land",
"minSize": 300,
"maxSize": 500,
"minX": 200,
"maxX": 400
},
{
"biome": "tainted_land",
"minSize": 300,
"maxSize": 500,
"minX": 600,
"maxX": 800
},
{
"biome": "jungle",
"minSize": 300,
"maxSize": 500,
"minX": 200,
"maxX": 400
},
{
"biome": "jungle",
"minSize": 300,
"maxSize": 500,
"minX": 600,
"maxX": 800
}
]
},
"terrains": {
"terrains": [
{
"id": "PlateauTerrain",
"times": 1.0,
"size": 300,
"height": 10
},
{
"id": "MountainTerrain",
"times": 3.0,
"size": 120,
"height": 24
},
{
"id": "BasinTerrain",
"times": 2.0,
"size": 66,
"height": 8
},
{
"id": "HillTerrain",
"times": 1.0,
"size": 200,
"height": 10
},
{
"id": "HillTerrain",
"times": 3.0,
"size": 160,
"height": 12
}
],
"specialTerrains": [
{
"id": "Chasm",
"times": 2.0,
"size": 20,
"height": 30
},
{
"id": "IceLake",
"times": 5.0,
"size": 80,
"height": 10
},
{
"id": "IceLake",
"times": 1.0,
"size": 100,
"height": 24
},
{
"id": "SurfaceCave",
"times": 1.0,
"size": 50,
"height": 0
},
{
"id": "SurfaceCave",
"times": 3.0,
"size": 40,
"height": 0
}
],
"transition": "LinerTransition",
"transitionTag": 2
},
"parallaxes": {
"deepRate": 0.95,
"base": [
{
"id": "snow_back",
"parallel": 8.0,
"level": 361
},
{
"id": "snow_hill",
"parallel": 7.0,
"level": 374
},
{
"id": "snow_dune",
"parallel": 5.0,
"level": 387
},
{
"id": "snow_trees3",
"parallel": 4.0,
"level": 390
},
{
"id": "snow_trees2",
"parallel": 3.0,
"level": 393
},
{
"id": "snow_trees",
"parallel": 2.0,
"level": 399
}
],
"underground": "ice_wall",
"linked": "ice_wall_link"
},
"musics": {
"daySurface": [
"mcday4",
"mcday5",
"mcday6"
],
"nightSurface": [
"night1",
"night2",
"night3",
"night4"
]
},
"weather": "snow",
"composition": {
"main": {
"id": "snow"
},
"subs": [
{
"id": "ice_cobblestone"
},
{
"id": "ice"
},
{
"id": "ice_packed"
}
]
},
"oreGroupName": "default",
"liquidInfo": {
"liquid": "water",
"maxAllowCount": 500
},
"treeInfo": {
"styles": [
"log_spruce"
],
"density": 0.22
},
"grass": 1,
"distributions": {
"airWeight": 400,
"surfacePlaceables": [
{
"id": "pot",
"tag": 1,
"weight": 5
},
{
"id": "small_tree_snowy",
"weight": 30
},
{
"id": "stone_decos_ice",
"weight": 15
},
{
"id": "stone_pillar_ice",
"weight": 15
}
],
"underWeight": 60,
"undergroundPlaceables": [
{
"id": "pot",
"tag": 1,
"weight": 20
},
{
"id": "small_tree_snowy",
"weight": 30
},
{
"id": "stalactite_ice",
"weight": 5
},
{
"id": "stalactite_small_ice",
"weight": 5
},
{
"id": "stone_decos_ice",
"weight": 15
},
{
"id": "stone_pillar_ice",
"weight": 15
}
],
"hangingWeight": 20,
"hangingPlaceables": [
{
"id": "stalactite_hanging_ice",
"weight": 5
},
{
"id": "stalactite_hanging_small_ice",
"weight": 5
}
]
},
"pot": [
{
"itemId": "torch",
"min": 1,
"max": 5,
"weight": 15
},
{
"itemId": "potion_healing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_night_vision",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_strength",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "wooden_arrow",
"min": 3,
"max": 10,
"weight": 15
},
{
"itemId": "coal",
"min": 1,
"max": 2,
"weight": 10
},
{
"itemId": "lighting_arrow",
"min": 2,
"max": 3,
"weight": 4
},
{
"itemId": "ice_arrow",
"min": 2,
"max": 3,
"weight": 5
},
{
"itemId": "grenade",
"min": 1,
"max": 2,
"weight": 3
}
],
"daySpawn": {
"mobSpeed": 550,
"maxMobSpawn": 5,
"mobs": [
{
"id": "ice_elf",
"weight": 2
},
{
"id": "snow_slime",
"weight": 4
},
{
"id": "ice_slime",
"weight": 4
},
{
"id": "large_ice_slime",
"weight": 4
},
{
"id": "blue_slime",
"weight": 3
},
{
"id": "enderman",
"weight": 1
}
],
"animalSpeed": 450,
"maxAnimalSpawn": 5,
"animals": [
{
"id": "white_rabbit",
"weight": 6
}
]
},
"nightSpawn": {
"mobSpeed": 460,
"maxMobSpawn": 7,
"mobs": [
{
"id": "ice_elf",
"weight": 2
},
{
"id": "snow_slime",
"weight": 4
},
{
"id": "ice_slime",
"weight": 4
},
{
"id": "large_ice_slime",
"weight": 4
},
{
"id": "zombie",
"weight": 10
},
{
"id": "arrow_zombie",
"weight": 8
},
{
"id": "bald_zombie",
"weight": 8
},
{
"id": "villager_zombie",
"weight": 6
},
{
"id": "skeleton",
"weight": 4
},
{
"id": "creeper",
"weight": 3
},
{
"id": "phantom",
"weight": 2
},
{
"id": "shulker",
"weight": 1
},
{
"id": "enderman",
"weight": 2
}
],
"animalSpeed": 600,
"maxAnimalSpawn": 5,
"animals": [
{
"id": "white_rabbit",
"weight": 3
}
]
},
"underSpawn": {
"mobSpeed": 400,
"maxMobSpawn": 6,
"mobs": [
{
"id": "ice_elf",
"weight": 5
},
{
"id": "large_ice_slime",
"weight": 10
},
{
"id": "zombie",
"weight": 10
},
{
"id": "spider",
"weight": 8
},
{
"id": "bald_zombie",
"weight": 8
},
{
"id": "villager_zombie",
"weight": 6
},
{
"id": "skeleton",
"weight": 2
},
{
"id": "creeper",
"weight": 2
},
{
"id": "enderman",
"weight": 1
}
],
"animalSpeed": 600,
"maxAnimalSpawn": 5,
"animals": [
{
"id": "squid",
"weight": 10
}
]
},
"buildingInfo": [
{
"buildingId": "aurora_palace",
"density": 1.5,
"fixSurfaceLine": true,
"genBeginXi": 500,
"genEndXi": 700
}
],
"environmentBlocks": {
"total": 1000,
"blocks": [
{
"id": "snow",
"weight": 1
},
{
"id": "ice_cobblestone",
"weight": 1
},
{
"id": "ice",
"weight": 1
},
{
"id": "ice_packed",
"weight": 1
},
{
"id": "aurora_block",
"weight": 4
}
]
}
}
}
================================================
FILE: biomes/surfaces/soft_snow_land.json
================================================
{
"soft_snow_land": {
"biomeType": "Surface",
"dayLight": 1.0,
"skyColor": {
"midDayTopColor": [ 98, 170, 192 ],
"midDayBottomColor": [ 210, 226, 236 ],
"midNightTopColor": [ 5, 8, 32 ],
"midNightBottomColor": [ 20, 30, 68 ],
"transATopColor": [ 98, 170, 192 ],
"transABottomColor": [ 217, 198, 10 ],
"transBTopColor": [ 44, 33, 10 ],
"transBBottomColor": [ 155, 32, 10 ],
"transCTopColor": [ 5, 8, 32 ],
"transCBottomColor": [ 115, 32, 10 ]
},
"subBiomes": {
"subs": []
},
"terrains": {
"terrains": [
{
"id": "PlateauTerrain",
"times": 1.0,
"size": 300,
"height": 10
},
{
"id": "MountainTerrain",
"times": 3.0,
"size": 120,
"height": 24
},
{
"id": "BasinTerrain",
"times": 2.0,
"size": 66,
"height": 8
},
{
"id": "HillTerrain",
"times": 1.0,
"size": 200,
"height": 10
},
{
"id": "HillTerrain",
"times": 3.0,
"size": 160,
"height": 12
}
],
"specialTerrains": [
{
"id": "Chasm",
"times": 2.0,
"size": 20,
"height": 30
},
{
"id": "IceLake",
"times": 5.0,
"size": 80,
"height": 10
},
{
"id": "IceLake",
"times": 1.0,
"size": 100,
"height": 24
},
{
"id": "SurfaceCave",
"times": 1.0,
"size": 50,
"height": 0
},
{
"id": "SurfaceCave",
"times": 3.0,
"size": 40,
"height": 0
}
],
"transition": "LinerTransition",
"transitionTag": 2
},
"parallaxes": {
"deepRate": 0.95,
"base": [
{
"id": "snow_hill",
"parallel": 7.0,
"level": 366
},
{
"id": "snow_mountain",
"parallel": 6.0,
"level": 361
},
{
"id": "snow_dune",
"parallel": 5.0,
"level": 377
},
{
"id": "snow_trees_new2",
"parallel": 3.0,
"level": 373
},
{
"id": "snow_trees_new",
"parallel": 2.0,
"level": 379
}
],
"underground": "ice_wall",
"linked": "ice_wall_link"
},
"musics": {
"daySurface": [
"mcday4",
"mcday5",
"mcday6"
],
"nightSurface": [
"night1",
"night2",
"night3",
"night4"
]
},
"weather": "snow",
"composition": {
"main": {
"id": "snow_soft"
},
"subs": [
{
"id": "ice_cobblestone"
},
{
"id": "ice"
},
{
"id": "ice_packed"
}
]
},
"oreGroupName": "default",
"liquidInfo": {
"liquid": "water",
"maxAllowCount": 500
},
"treeInfo": {
"styles": [
"log_spruce"
],
"density": 0.92
},
"grass": 1,
"distributions": {
"airWeight": 400,
"surfacePlaceables": [
{
"id": "pot",
"tag": 1,
"weight": 5
},
{
"id": "small_tree_snowy",
"weight": 30
},
{
"id": "stone_decos_ice",
"weight": 15
},
{
"id": "stone_pillar_ice",
"weight": 15
}
],
"underWeight": 60,
"undergroundPlaceables": [
{
"id": "pot",
"tag": 1,
"weight": 20
},
{
"id": "small_tree_snowy",
"weight": 30
},
{
"id": "stalactite_ice",
"weight": 5
},
{
"id": "stalactite_small_ice",
"weight": 5
},
{
"id": "stone_decos_ice",
"weight": 15
},
{
"id": "stone_pillar_ice",
"weight": 15
}
],
"hangingWeight": 20,
"hangingPlaceables": [
{
"id": "stalactite_hanging_ice",
"weight": 5
},
{
"id": "stalactite_hanging_small_ice",
"weight": 5
}
]
},
"pot": [
{
"itemId": "torch",
"min": 1,
"max": 5,
"weight": 15
},
{
"itemId": "potion_healing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_night_vision",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_strength",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "wooden_arrow",
"min": 3,
"max": 10,
"weight": 15
},
{
"itemId": "coal",
"min": 1,
"max": 2,
"weight": 10
},
{
"itemId": "lighting_arrow",
"min": 2,
"max": 3,
"weight": 4
},
{
"itemId": "ice_arrow",
"min": 2,
"max": 3,
"weight": 5
},
{
"itemId": "grenade",
"min": 1,
"max": 2,
"weight": 3
}
],
"daySpawn": {
"mobSpeed": 550,
"maxMobSpawn": 5,
"mobs": [
{
"id": "ice_elf",
"weight": 2
},
{
"id": "snow_slime",
"weight": 4
},
{
"id": "ice_slime",
"weight": 4
},
{
"id": "large_ice_slime",
"weight": 4
},
{
"id": "blue_slime",
"weight": 3
},
{
"id": "enderman",
"weight": 1
}
],
"animalSpeed": 450,
"maxAnimalSpawn": 5,
"animals": [
{
"id": "white_rabbit",
"weight": 6
}
]
},
"nightSpawn": {
"mobSpeed": 460,
"maxMobSpawn": 7,
"mobs": [
{
"id": "ice_elf",
"weight": 2
},
{
"id": "snow_slime",
"weight": 4
},
{
"id": "ice_slime",
"weight": 4
},
{
"id": "large_ice_slime",
"weight": 4
},
{
"id": "zombie",
"weight": 10
},
{
"id": "arrow_zombie",
"weight": 8
},
{
"id": "bald_zombie",
"weight": 8
},
{
"id": "villager_zombie",
"weight": 6
},
{
"id": "skeleton",
"weight": 4
},
{
"id": "creeper",
"weight": 3
},
{
"id": "phantom",
"weight": 2
},
{
"id": "shulker",
"weight": 1
},
{
"id": "enderman",
"weight": 2
}
],
"animalSpeed": 600,
"maxAnimalSpawn": 5,
"animals": [
{
"id": "white_rabbit",
"weight": 3
}
]
},
"underSpawn": {
"mobSpeed": 400,
"maxMobSpawn": 6,
"mobs": [
{
"id": "ice_elf",
"weight": 5
},
{
"id": "large_ice_slime",
"weight": 10
},
{
"id": "zombie",
"weight": 10
},
{
"id": "spider",
"weight": 8
},
{
"id": "bald_zombie",
"weight": 8
},
{
"id": "villager_zombie",
"weight": 6
},
{
"id": "skeleton",
"weight": 2
},
{
"id": "creeper",
"weight": 2
},
{
"id": "enderman",
"weight": 1
}
],
"animalSpeed": 600,
"maxAnimalSpawn": 5,
"animals": [
{
"id": "squid",
"weight": 10
}
]
},
"buildingInfo": [
{
"buildingId": "aurora_palace",
"density": 1.5,
"fixSurfaceLine": true,
"genBeginXi": 500,
"genEndXi": 700
}
],
"environmentBlocks": {
"total": 100,
"blocks": [
{
"id": "snow_soft",
"weight": 1
},
{
"id": "ice_cobblestone",
"weight": 1
},
{
"id": "ice",
"weight": 1
},
{
"id": "ice_packed",
"weight": 1
},
{
"id": "aurora_block",
"weight": 4
}
]
}
}
}
================================================
FILE: biomes/surfaces/super_volcano.json
================================================
{
"super_volcano": {
"biomeType": "Surface",
"dayLight": 0.5,
"skyColor": {
"midDayTopColor": [ 100, 22, 22 ],
"midDayBottomColor": [ 166, 44, 44 ],
"midNightTopColor": [ 32, 8, 8 ],
"midNightBottomColor": [ 64, 16, 16 ],
"transATopColor": [ 60, 22, 22 ],
"transABottomColor": [ 60, 33, 33 ],
"transBTopColor": [ 50, 16, 16 ],
"transBBottomColor": [ 50, 24, 24 ],
"transCTopColor": [ 30, 8, 8 ],
"transCBottomColor": [ 30, 20, 20 ]
},
"subBiomes": {
"subs": []
},
"terrains": {
"terrains": [
{
"id": "MountainTerrain",
"times": 2.0,
"size": 160,
"height": 24
},
{
"id": "BasinTerrain",
"times": 3.0,
"size": 50,
"height": 8
},
{
"id": "HillTerrain",
"times": 3.0,
"size": 200,
"height": 10
},
{
"id": "PlateauTerrain",
"times": 3.0,
"size": 100,
"height": 10
}
],
"specialTerrains": [
{
"id": "Chasm",
"times": 0.5,
"size": 20,
"height": 30
},
{
"id": "SurfaceCave",
"times": 1.0,
"size": 60,
"height": 0
},
{
"id": "SurfaceCave",
"times": 2.0,
"size": 40,
"height": 0
}
],
"transition": "LinerTransition",
"transitionTag": 2
},
"parallaxes": {
"deepRate": 0.95,
"base": [
{
"id": "volcano_hill",
"parallel": 4.0,
"level": 368
},
{
"id": "volcano_back",
"parallel": 3.0,
"level": 378
},
{
"id": "volcano_back2",
"parallel": 2.5,
"level": 388
}
],
"underground": "lava_wall",
"linked": "lava_wall_link"
},
"musics": {
"daySurface": [
"day2",
"day3",
"day4",
"day5",
"mcday1",
"mcday2",
"mcday3",
"mcday4"
],
"nightSurface": [
"night1",
"night2",
"night3",
"night4"
]
},
"weather": "volcano_snow",
"composition": {
"main": {
"id": "volcano_burn_stone"
},
"subs": [
{
"id": "volcano_dirt"
},
{
"id": "magma_block"
},
{
"id": "magma_block"
}
]
},
"oreGroupName": "default",
"liquidInfo": {
"liquid": "lava",
"maxAllowCount": 1000
},
"treeInfo": {
"styles": [
"log_volcano_oak"
],
"density": 0.75
},
"grass": 0,
"distributions": {
"airWeight": 100,
"surfacePlaceables": [
{
"id": "eyeball_grass",
"weight": 40
},
{
"id": "large_eyeball_grass",
"weight": 40
},
{
"id": "blood_grass",
"weight": 200
}
],
"underWeight": 100,
"undergroundPlaceables": [],
"hangingWeight": 100,
"hangingPlaceables": []
},
"pot": [
{
"itemId": "torch",
"min": 1,
"max": 5,
"weight": 15
},
{
"itemId": "potion_healing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_awkward",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_fire_resistance",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "wooden_arrow",
"min": 3,
"max": 10,
"weight": 10
},
{
"itemId": "coal",
"min": 1,
"max": 2,
"weight": 8
},
{
"itemId": "flint",
"min": 1,
"max": 4,
"weight": 8
},
{
"itemId": "grenade",
"min": 1,
"max": 3,
"weight": 6
}
],
"daySpawn": {
"mobSpeed": 500,
"maxMobSpawn": 5,
"mobs": [
{
"id": "magma_elf",
"weight": 5
},
{
"id": "zombie_pigman",
"weight": 5
},
{
"id": "magma_slime",
"weight": 5
},
{
"id": "magma_birdo",
"weight": 4
},
{
"id": "meteor",
"weight": 4
},
{
"id": "creeper",
"weight": 1
}
],
"animalSpeed": 300,
"maxAnimalSpawn": 5,
"animals": []
},
"nightSpawn": {
"mobSpeed": 450,
"maxMobSpawn": 6,
"mobs": [
{
"id": "magma_elf",
"weight": 5
},
{
"id": "zombie_pigman",
"weight": 5
},
{
"id": "magma_slime",
"weight": 5
},
{
"id": "magma_birdo",
"weight": 4
},
{
"id": "meteor",
"weight": 4
},
{
"id": "zombie",
"weight": 5
},
{
"id": "arrow_zombie",
"weight": 4
},
{
"id": "bald_zombie",
"weight": 4
},
{
"id": "villager_zombie",
"weight": 6
},
{
"id": "skeleton",
"weight": 4
},
{
"id": "creeper",
"weight": 3
}
],
"animalSpeed": 600,
"maxAnimalSpawn": 5,
"animals": []
},
"underSpawn": {
"mobSpeed": 400,
"maxMobSpawn": 6,
"mobs": [
{
"id": "magma_elf",
"weight": 5
},
{
"id": "zombie_pigman",
"weight": 5
},
{
"id": "magma_slime",
"weight": 5
},
{
"id": "meteor",
"weight": 4
},
{
"id": "zombie",
"weight": 5
},
{
"id": "husk",
"weight": 8
},
{
"id": "bald_zombie",
"weight": 8
},
{
"id": "spider",
"weight": 18
},
{
"id": "skeleton",
"weight": 3
},
{
"id": "flower_creeper",
"weight": 1
}
],
"animalSpeed": 600,
"maxAnimalSpawn": 5,
"animals": []
},
"buildingInfo": [
],
"environmentBlocks": {
"total": 400,
"blocks": [
{
"id": "volcano_burn_stone",
"weight": 10
},
{
"id": "volcano_dirt",
"weight": 10
},
{
"id": "magma_block",
"weight": 10
}
]
}
}
}
================================================
FILE: biomes/surfaces/tainted_land.json
================================================
{
"tainted_land": {
"biomeType": "Surface",
"dayLight": 0.75,
"skyColor": {
"midDayTopColor": [ 60, 70, 180 ],
"midDayBottomColor": [ 90, 100, 220 ],
"midNightTopColor": [ 5, 8, 32 ],
"midNightBottomColor": [ 20, 30, 68 ],
"transATopColor": [ 50, 60, 160 ],
"transABottomColor": [ 70, 80, 170 ],
"transBTopColor": [ 40, 50, 100 ],
"transBBottomColor": [ 60, 70, 140 ],
"transCTopColor": [ 20, 30, 60 ],
"transCBottomColor": [ 40, 50, 100 ]
},
"subBiomes": {
"subs": [
]
},
"terrains": {
"terrains": [
{
"id": "MountainTerrain",
"times": 5.0,
"size": 100,
"height": 10
},
{
"id": "BasinTerrain",
"times": 3.0,
"size": 50,
"height": 5
},
{
"id": "HillTerrain",
"times": 4.0,
"size": 200,
"height": 10
}
],
"specialTerrains": [
{
"id": "SurfaceCave",
"times": 4.0,
"size": 80,
"height": 0
},
{
"id": "SurfaceCave",
"times": 8.0,
"size": 40,
"height": 0
}
],
"transition": "LinerTransition",
"transitionTag": 2
},
"parallaxes": {
"deepRate": 0.95,
"base": [
{
"id": "tainted_hill2",
"parallel": 3.0,
"level": 358
},
{
"id": "tainted_hill",
"parallel": 2.6,
"level": 362
},
{
"id": "tainted_bush",
"parallel": 2.0,
"level": 384
},
{
"id": "tainted_bush_strick",
"parallel": 1.75,
"level": 384
},
{
"id": "tainted_rock",
"parallel": 1.25,
"level": 402
}
],
"underground": "tainted_wall",
"linked": "tainted_wall_link"
},
"musics": {
"daySurface": [
"day2",
"day3",
"day4",
"day5",
"mcday1",
"mcday2",
"mcday3",
"mcday4"
],
"nightSurface": [
"night1",
"night2",
"night3",
"night4"
]
},
"weather": "rain",
"composition": {
"main": {
"id": "tainted_dirt"
},
"subs": [
{
"id": "tainted_stone"
}
]
},
"oreGroupName": "default",
"liquidInfo": {
"liquid": "water",
"maxAllowCount": 500
},
"treeInfo": {
"styles": [
"log_tainted"
],
"density": 0.7
},
"grass": 1,
"distributions": {
"airWeight": 50,
"surfacePlaceables": [
{
"id": "tainted_grass",
"weight": 50
},
{
"id": "pot",
"tag": 3,
"weight": 10
},
{
"id": "small_tree_tainted",
"weight": 10
},
{
"id": "large_poison_mushroom",
"weight": 10
},
{
"id": "poison_mushroom",
"weight": 10
},
{
"id": "stone_decos_tainted",
"weight": 10
},
{
"id": "stone_pillar_tainted",
"weight": 10
}
],
"underWeight": 50,
"undergroundPlaceables": [
{
"id": "pot",
"tag": 3,
"weight": 10
},
{
"id": "large_poison_mushroom",
"weight": 10
},
{
"id": "poison_mushroom",
"weight": 10
},
{
"id": "stone_decos_tainted",
"weight": 10
},
{
"id": "stone_pillar_tainted",
"weight": 10
},
{
"id": "stalactite_tainted",
"weight": 10
},
{
"id": "stalactite_small_tainted",
"weight": 10
},
{
"id": "stab_tainted",
"weight": 10
}
],
"hangingWeight": 60,
"hangingPlaceables": [
{
"id": "tainted_vine",
"weight": 40
},
{
"id": "stalactite_hanging_tainted",
"weight": 10
},
{
"id": "stalactite_hanging_small_tainted",
"weight": 10
},
{
"id": "stab_hanging_tainted",
"weight": 4
}
]
},
"pot": [
{
"itemId": "torch",
"min": 1,
"max": 5,
"weight": 15
},
{
"itemId": "potion_healing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_night_vision",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_strength",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_harming",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_leaping",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_weakness",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_slow_falling",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "wooden_arrow",
"min": 3,
"max": 10,
"weight": 10
},
{
"itemId": "coal",
"min": 1,
"max": 2,
"weight": 8
},
{
"itemId": "lighting_arrow",
"min": 3,
"max": 10,
"weight": 6
},
{
"itemId": "grenade",
"min": 1,
"max": 2,
"weight": 3
}
],
"daySpawn": {
"mobSpeed": 200,
"maxMobSpawn": 5,
"mobs": [
{
"id": "tainted_slime",
"weight": 10
},
{
"id": "large_tainted_slime",
"weight": 5
},
{
"id": "enderman",
"weight": 12
},
{
"id": "tainted_creeper",
"weight": 5
},
{
"id": "flower_creeper",
"weight": 2
},
{
"id": "tainted_skeleton",
"weight": 2
}
],
"animalSpeed": 300,
"maxAnimalSpawn": 5,
"animals": []
},
"nightSpawn": {
"mobSpeed": 200,
"maxMobSpawn": 10,
"mobs": [
{
"id": "tainted_skeleton",
"weight": 6
},
{
"id": "large_tainted_slime",
"weight": 5
},
{
"id": "zombie",
"weight": 10
},
{
"id": "tainted_slime",
"weight": 20
},
{
"id": "enderman",
"weight": 8
},
{
"id": "evoker",
"weight": 3
},
{
"id": "purple_slime",
"weight": 4
},
{
"id": "arrow_zombie",
"weight": 8
},
{
"id": "skeleton",
"weight": 4
},
{
"id": "flower_creeper",
"weight": 3
},
{
"id": "phantom",
"weight": 8
}
],
"animalSpeed": 400,
"maxAnimalSpawn": 5,
"animals": []
},
"underSpawn": {
"mobSpeed": 400,
"maxMobSpawn": 6,
"mobs": [
{
"id": "tainted_slime",
"weight": 10
},
{
"id": "enderman",
"weight": 8
},
{
"id": "evoker",
"weight": 3
},
{
"id": "purple_slime",
"weight": 4
},
{
"id": "phantom",
"weight": 5
},
{
"id": "tainted_skeleton",
"weight": 5
},
{
"id": "tainted_creeper",
"weight": 2
}
],
"animalSpeed": 600,
"maxAnimalSpawn": 5,
"animals": [
{
"id": "squid",
"weight": 10
}
]
},
"buildingInfo": [
{
"buildingId": "end_outpost",
"density": 1.0,
"fixSurfaceLine": true,
"genBeginXi": 100,
"genEndXi": 900
}
],
"environmentBlocks": {
"total": 1000,
"blocks": [
{
"id": "tainted_dirt",
"weight": 1
},
{
"id": "tainted_stone",
"weight": 1
}
]
}
}
}
================================================
FILE: biomes/surfaces/volcano.json
================================================
{
"volcano": {
"biomeType": "Surface",
"dayLight": 0.5,
"skyColor": {
"midDayTopColor": [ 100, 22, 22 ],
"midDayBottomColor": [ 166, 44, 44 ],
"midNightTopColor": [ 32, 8, 8 ],
"midNightBottomColor": [ 64, 16, 16 ],
"transATopColor": [ 100, 22, 22 ],
"transABottomColor": [ 100, 33, 33 ],
"transBTopColor": [ 60, 16, 16 ],
"transBBottomColor": [ 80, 24, 24 ],
"transCTopColor": [ 32, 8, 8 ],
"transCBottomColor": [ 72, 20, 20 ]
},
"subBiomes": {
"subs": [
{
"biome": "jungle",
"minSize": 300,
"maxSize": 500,
"minX": 200,
"maxX": 800
},
{
"biome": "tainted_land",
"minSize": 300,
"maxSize": 500,
"minX": 200,
"maxX": 800
},
{
"biome": "flesh",
"minSize": 300,
"maxSize": 500,
"minX": 200,
"maxX": 800
}
]
},
"terrains": {
"terrains": [
{
"id": "MountainTerrain",
"times": 2.0,
"size": 160,
"height": 24
},
{
"id": "BasinTerrain",
"times": 3.0,
"size": 50,
"height": 8
},
{
"id": "HillTerrain",
"times": 7.0,
"size": 200,
"height": 14
},
{
"id": "PlateauTerrain",
"times": 3.0,
"size": 100,
"height": 10
}
],
"specialTerrains": [
{
"id": "Chasm",
"times": 0.5,
"size": 20,
"height": 30
},
{
"id": "SurfaceCave",
"times": 1.0,
"size": 60,
"height": 0
},
{
"id": "SurfaceCave",
"times": 2.0,
"size": 40,
"height": 0
},
{
"id": "SurfaceCave",
"times": 5.0,
"size": 20,
"height": 0
},
{
"id": "LavaLake",
"times": 4,
"size": 60,
"height": 10
},
{
"id": "LavaLake",
"times": 8.0,
"size": 40,
"height": 10
}
],
"transition": "LinerTransition",
"transitionTag": 2
},
"parallaxes": {
"deepRate": 0.95,
"base": [
{
"id": "volcano_back",
"parallel": 8.0,
"level": 366
},
{
"id": "volcano_back2",
"parallel": 6.0,
"level": 380
},
{
"id": "volcano_back3",
"parallel": 4.0,
"level": 394
}
],
"underground": "lava_wall",
"linked": "lava_wall_link"
},
"musics": {
"daySurface": [
"day2",
"day3",
"day4",
"day5",
"mcday1",
"mcday2",
"mcday3",
"mcday4"
],
"nightSurface": [
"night1",
"night2",
"night3",
"night4"
]
},
"weather": "volcano_snow",
"composition": {
"main": {
"id": "volcano_dirt"
},
"subs": [
{
"id": "volcano_stone"
},
{
"id": "magma_block"
},
{
"id": "magma_block"
}
]
},
"oreGroupName": "default",
"liquidInfo": {
"liquid": "lava",
"maxAllowCount": 500
},
"treeInfo": {
"styles": [
"log_volcano_oak"
],
"density": 0.25
},
"grass": 0,
"distributions": {
"airWeight": 100,
"surfacePlaceables": [
{
"id": "eyeball_grass",
"weight": 40
},
{
"id": "large_eyeball_grass",
"weight": 40
},
{
"id": "blood_grass",
"weight": 200
}
],
"underWeight": 100,
"undergroundPlaceables": [],
"hangingWeight": 100,
"hangingPlaceables": []
},
"pot": [
{
"itemId": "torch",
"min": 1,
"max": 5,
"weight": 15
},
{
"itemId": "potion_healing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_awkward",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_fire_resistance",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "wooden_arrow",
"min": 3,
"max": 10,
"weight": 10
},
{
"itemId": "coal",
"min": 1,
"max": 2,
"weight": 8
},
{
"itemId": "flint",
"min": 1,
"max": 4,
"weight": 8
},
{
"itemId": "grenade",
"min": 1,
"max": 3,
"weight": 6
}
],
"daySpawn": {
"mobSpeed": 500,
"maxMobSpawn": 5,
"mobs": [
{
"id": "magma_elf",
"weight": 5
},
{
"id": "zombie_pigman",
"weight": 5
},
{
"id": "magma_slime",
"weight": 5
},
{
"id": "magma_birdo",
"weight": 4
},
{
"id": "meteor",
"weight": 4
},
{
"id": "creeper",
"weight": 1
}
],
"animalSpeed": 300,
"maxAnimalSpawn": 5,
"animals": []
},
"nightSpawn": {
"mobSpeed": 450,
"maxMobSpawn": 6,
"mobs": [
{
"id": "magma_elf",
"weight": 5
},
{
"id": "zombie_pigman",
"weight": 5
},
{
"id": "magma_slime",
"weight": 5
},
{
"id": "magma_birdo",
"weight": 4
},
{
"id": "meteor",
"weight": 4
},
{
"id": "zombie",
"weight": 5
},
{
"id": "arrow_zombie",
"weight": 4
},
{
"id": "bald_zombie",
"weight": 4
},
{
"id": "villager_zombie",
"weight": 6
},
{
"id": "skeleton",
"weight": 4
},
{
"id": "creeper",
"weight": 3
}
],
"animalSpeed": 600,
"maxAnimalSpawn": 5,
"animals": []
},
"underSpawn": {
"mobSpeed": 400,
"maxMobSpawn": 6,
"mobs": [
{
"id": "magma_elf",
"weight": 5
},
{
"id": "zombie_pigman",
"weight": 5
},
{
"id": "magma_slime",
"weight": 5
},
{
"id": "meteor",
"weight": 4
},
{
"id": "zombie",
"weight": 5
},
{
"id": "husk",
"weight": 8
},
{
"id": "bald_zombie",
"weight": 8
},
{
"id": "spider",
"weight": 18
},
{
"id": "skeleton",
"weight": 3
},
{
"id": "flower_creeper",
"weight": 1
}
],
"animalSpeed": 600,
"maxAnimalSpawn": 5,
"animals": []
},
"buildingInfo": [
],
"environmentBlocks": {
"total": 1000,
"blocks": [
]
}
}
}
================================================
FILE: biomes/undergrounds/andesite_cave.json
================================================
{
"andesite_cave": {
"biomeType": "Underground",
"scale": 0.6,
"wallParallaxe": "stone_wall",
"musics": {
"underground": [
"mcunder1",
"mcunder2",
"mcunder3",
"mcunder4"
]
},
"composition": {
"main": {
"id": "andesite"
},
"subs": [
{
"id": "cobblestone"
}
]
},
"wall": {
"id": "andesite",
"full": true
},
"oreGroupName": "default",
"liquidInfo": {
"liquid": "water",
"maxAllowCount": 500
},
"distributions": {
"airWeight": 100,
"surfacePlaceables": [
{
"id": "pot",
"tag": 0,
"weight": 40
},
{
"id": "stalactite_stone",
"weight": 15
},
{
"id": "stalactite_small_stone",
"weight": 10
},
{
"id": "stalactite_andesite",
"weight": 15
},
{
"id": "stalactite_small_andesite",
"weight": 10
},
{
"id": "stone_pillar_normal",
"weight": 4
},
{
"id": "rock",
"weight": 4
},
{
"id": "stone_decos_normal",
"weight": 12
}
],
"hangingWeight": 100,
"hangingPlaceables": [
{
"id": "stalactite_hanging_stone",
"weight": 30
},
{
"id": "stalactite_hanging_small_stone",
"weight": 30
},
{
"id": "stalactite_hanging_andesite",
"weight": 30
},
{
"id": "stalactite_hanging_small_andesite",
"weight": 30
}
]
},
"pot": [
{
"itemId": "torch",
"min": 1,
"max": 5,
"weight": 15
},
{
"itemId": "potion_healing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_night_vision",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_strength",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_leaping",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_water_breathing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "wooden_arrow",
"min": 3,
"max": 10,
"weight": 12
},
{
"itemId": "lighting_arrow",
"min": 3,
"max": 10,
"weight": 5
},
{
"itemId": "coal",
"min": 1,
"max": 2,
"weight": 10
},
{
"itemId": "flint",
"min": 1,
"max": 4,
"weight": 10
},
{
"itemId": "grenade",
"min": 1,
"max": 1,
"weight": 4
},
{
"itemId": "bomb",
"min": 1,
"max": 1,
"weight": 2
}
],
"spawn": {
"mobSpeed": 300,
"maxMobSpawn": 6,
"mobs": [
{
"id": "zombie",
"weight": 20
},
{
"id": "angry_skeleton",
"weight": 12
},
{
"id": "black_skeleton",
"weight": 12
},
{
"id": "spider",
"weight": 8
},
{
"id": "bald_zombie",
"weight": 8
},
{
"id": "villager_zombie",
"weight": 6
},
{
"id": "bat",
"weight": 5
},
{
"id": "skeleton",
"weight": 2
},
{
"id": "creeper",
"weight": 2
},
{
"id": "flower_creeper",
"weight": 1
},
{
"id": "enderman",
"weight": 2
}
],
"animalSpeed": 600,
"maxAnimalSpawn": 5,
"animals": []
},
"buildingInfo": [
{
"buildingId": "fossils",
"density": 6.0
}
],
"environmentBlocks": {
"total": 100,
"blocks": [
{
"id": "andesite",
"weight": 1
}
]
}
}
}
================================================
FILE: biomes/undergrounds/blue_cave.json
================================================
{
"blue_cave": {
"biomeType": "Underground",
"scale": 1.0,
"wallParallaxe": "pile_cave_wall",
"musics": {
"underground": [
"mcunder1",
"mcunder2",
"mcunder3",
"mcunder4"
]
},
"composition": {
"main": {
"id": "cobblestone"
},
"subs": [
{
"id": "dirt"
},
{
"id": "gravel"
}
]
},
"oreGroupName": "default",
"liquidInfo": {
"liquid": "water",
"maxAllowCount": 500
},
"distributions": {
"airWeight": 100,
"surfacePlaceables": [
{
"id": "pot",
"tag": 0,
"weight": 40
},
{
"id": "stalactite_stone",
"weight": 15
},
{
"id": "stalactite_small_stone",
"weight": 10
},
{
"id": "stone_pillar_normal",
"weight": 4
},
{
"id": "rock",
"weight": 4
},
{
"id": "stone_decos_normal",
"weight": 12
}
],
"hangingWeight": 100,
"hangingPlaceables": [
{
"id": "stalactite_hanging_stone",
"weight": 30
},
{
"id": "stalactite_hanging_small_stone",
"weight": 30
}
]
},
"pot": [
{
"itemId": "torch",
"min": 1,
"max": 5,
"weight": 15
},
{
"itemId": "potion_healing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_night_vision",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_strength",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_leaping",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_water_breathing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "wooden_arrow",
"min": 3,
"max": 10,
"weight": 12
},
{
"itemId": "coal",
"min": 1,
"max": 2,
"weight": 10
},
{
"itemId": "flint",
"min": 1,
"max": 4,
"weight": 10
},
{
"itemId": "grenade",
"min": 1,
"max": 1,
"weight": 4
},
{
"itemId": "bomb",
"min": 1,
"max": 1,
"weight": 2
}
],
"spawn": {
"mobSpeed": 250,
"maxMobSpawn": 6,
"mobs": [
{
"id": "large_black_slime",
"weight": 12
},
{
"id": "boney_skeleton",
"weight": 12
},
{
"id": "black_skeleton",
"weight": 12
},
{
"id": "zombie",
"weight": 10
},
{
"id": "spider",
"weight": 8
},
{
"id": "bald_zombie",
"weight": 8
},
{
"id": "villager_zombie",
"weight": 6
},
{
"id": "bat",
"weight": 5
},
{
"id": "skeleton",
"weight": 2
},
{
"id": "creeper",
"weight": 2
},
{
"id": "flower_creeper",
"weight": 1
},
{
"id": "enderman",
"weight": 2
}
],
"animalSpeed": 600,
"maxAnimalSpawn": 5,
"animals": [
{
"id": "squid",
"weight": 10
}
]
},
"buildingInfo": [
{
"buildingId": "mineshaft",
"density": 1.0
},
{
"buildingId": "under_spruce_cabin",
"density": 1.0
},
{
"buildingId": "under_oak_cabin",
"density": 2.0
},
{
"buildingId": "under_dark_oak_cabin",
"density": 3.0
},
{
"buildingId": "under_jungle_cabin",
"density": 3.0
},
{
"buildingId": "fossils",
"density": 8.0
}
]
}
}
================================================
FILE: biomes/undergrounds/blue_mushroom_cave.json
================================================
{
"blue_mushroom_cave": {
"biomeType": "Underground",
"scale": 1.0,
"wallParallaxe": "mushroom_wall",
"musics": {
"underground": [
"mcunder1",
"mcunder2",
"mcunder3",
"mcunder4"
]
},
"composition": {
"main": {
"id": "blue_mushroom_dirt"
},
"subs": [
{
"id": "blue_mushroom_stem"
}
]
},
"wall": {
"id": "blue_mushroom_dirt",
"full": false
},
"oreGroupName": "default",
"liquidInfo": {
"liquid": "water",
"maxAllowCount": 500
},
"treeInfo": {
"styles": [
"log_blue_mushroom"
],
"density": 0.99
},
"distributions": {
"airWeight": 100,
"surfacePlaceables": [
{
"id": "pot",
"tag": 0,
"weight": 40
},
{
"id": "large_blue_mushroom",
"weight": 50
},
{
"id": "blue_mushroom",
"weight": 100
}
],
"hangingWeight": 100,
"hangingPlaceables": []
},
"pot": [
{
"itemId": "torch",
"min": 1,
"max": 5,
"weight": 15
},
{
"itemId": "potion_healing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_night_vision",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_strength",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_leaping",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_water_breathing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "wooden_arrow",
"min": 3,
"max": 10,
"weight": 12
},
{
"itemId": "lighting_arrow",
"min": 3,
"max": 10,
"weight": 5
},
{
"itemId": "coal",
"min": 1,
"max": 2,
"weight": 10
},
{
"itemId": "flint",
"min": 1,
"max": 4,
"weight": 10
},
{
"itemId": "grenade",
"min": 1,
"max": 1,
"weight": 4
},
{
"itemId": "bomb",
"min": 1,
"max": 1,
"weight": 2
}
],
"spawn": {
"mobSpeed": 200,
"maxMobSpawn": 6,
"mobs": [
{
"id": "large_bat",
"weight": 10
},
{
"id": "large_spider",
"weight": 10
},
{
"id": "grim_reaper",
"weight": 4
},
{
"id": "mad_skeleton",
"weight": 6
},
{
"id": "skeleton_blue_armed",
"weight": 5
},
{
"id": "skeleton",
"weight": 2
},
{
"id": "undead_miner",
"weight": 2
},
{
"id": "boney_skeleton",
"weight": 1
},
{
"id": "bat",
"weight": 1
},
{
"id": "enderman",
"weight": 1
}
],
"animalSpeed": 300,
"maxAnimalSpawn": 5,
"animals": [
{
"id": "squid",
"weight": 10
},
{
"id": "brown_mushroom_cow",
"weight": 10
},
{
"id": "red_mushroom_cow",
"weight": 10
}
]
},
"buildingInfo": [
{
"buildingId": "fossils",
"density": 6.0
}
],
"environmentBlocks": {
"total": 100,
"blocks": [
{
"id": "blue_mushroom_dirt",
"weight": 1
},
{
"id": "blue_mushroom_stem",
"weight": 1
}
]
}
}
}
================================================
FILE: biomes/undergrounds/deep_ice_cave.json
================================================
{
"deep_ice_cave": {
"biomeType": "Underground",
"scale": 1.0,
"wallParallaxe": "pile_ice_wall",
"musics": {
"underground": [
"mcunder1",
"mcunder2",
"mcunder3",
"mcunder4"
]
},
"composition": {
"main": {
"id": "ice_cobblestone_hard"
},
"subs": [
{
"id": "snow_soft"
},
{
"id": "ice"
},
{
"id": "ice_packed"
}
]
},
"oreGroupName": "default",
"liquidInfo": {
"liquid": "water",
"maxAllowCount": 500
},
"distributions": {
"airWeight": 100,
"surfacePlaceables": [
{
"id": "pot",
"tag": 1,
"weight": 5
},
{
"id": "small_tree_snowy",
"weight": 30
},
{
"id": "stone_decos_ice",
"weight": 15
},
{
"id": "stone_pillar_ice",
"weight": 15
},
{
"id": "stalactite_ice",
"weight": 5
},
{
"id": "stalactite_small_ice",
"weight": 5
}
],
"hangingWeight": 100,
"hangingPlaceables": [
{
"id": "stalactite_hanging_ice",
"weight": 30
},
{
"id": "stalactite_hanging_small_ice",
"weight": 30
}
]
},
"pot": [
{
"itemId": "torch",
"min": 1,
"max": 5,
"weight": 15
},
{
"itemId": "potion_healing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_night_vision",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_strength",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_leaping",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_water_breathing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "wooden_arrow",
"min": 3,
"max": 10,
"weight": 12
},
{
"itemId": "lighting_arrow",
"min": 3,
"max": 10,
"weight": 5
},
{
"itemId": "coal",
"min": 1,
"max": 2,
"weight": 10
},
{
"itemId": "flint",
"min": 1,
"max": 4,
"weight": 10
},
{
"itemId": "grenade",
"min": 1,
"max": 1,
"weight": 4
},
{
"itemId": "bomb",
"min": 1,
"max": 1,
"weight": 2
}
],
"spawn": {
"mobSpeed": 100,
"maxMobSpawn": 12,
"mobs": [
{
"id": "crystal_monster",
"weight": 22
},
{
"id": "ice_elf",
"weight": 10
},
{
"id": "zombie",
"weight": 8
},
{
"id": "large_ice_slime",
"weight": 6
},
{
"id": "skeleton",
"weight": 2
},
{
"id": "creeper",
"weight": 2
},
{
"id": "flower_creeper",
"weight": 1
},
{
"id": "boney_skeleton",
"weight": 1
},
{
"id": "enderman",
"weight": 1
}
],
"animalSpeed": 600,
"maxAnimalSpawn": 5,
"animals": [
{
"id": "squid",
"weight": 10
}
]
},
"buildingInfo": [
{
"buildingId": "fossils",
"density": 2.0
}
],
"environmentBlocks": {
"total": 100,
"blocks": [
{
"id": "ice_cobblestone_hard",
"weight": 1
},
{
"id": "snow_soft",
"weight": 1
}
]
}
}
}
================================================
FILE: biomes/undergrounds/deep_magma_cave.json
================================================
{
"deep_magma_cave": {
"biomeType": "Underground",
"scale": 1.0,
"wallParallaxe": "long_lava_wall",
"musics": {
"underground": [
"mcunder1",
"mcunder2",
"mcunder3",
"mcunder4"
]
},
"composition": {
"main": {
"id": "volcano_cobblestone"
},
"subs": [
{
"id": "soul_sand"
},
{
"id": "magma_block"
},
{
"id": "lava_block_pile"
}
]
},
"wall": {
"id": "lava_block_pile",
"full": false
},
"oreGroupName": "default",
"liquidInfo": {
"liquid": "lava",
"maxAllowCount": 500
},
"distributions": {
"airWeight": 100,
"surfacePlaceables": [
{
"id": "pot",
"tag": 4,
"weight": 40
},
{
"id": "stalactite_stone",
"weight": 15
},
{
"id": "stalactite_small_stone",
"weight": 10
},
{
"id": "stone_pillar_normal",
"weight": 4
},
{
"id": "rock",
"weight": 4
}
],
"hangingWeight": 100,
"hangingPlaceables": [
{
"id": "stalactite_hanging_stone",
"weight": 30
},
{
"id": "stalactite_hanging_small_stone",
"weight": 30
}
]
},
"pot": [
{
"itemId": "torch",
"min": 1,
"max": 5,
"weight": 15
},
{
"itemId": "potion_healing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_night_vision",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_strength",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_leaping",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_water_breathing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "wooden_arrow",
"min": 3,
"max": 10,
"weight": 12
},
{
"itemId": "lighting_arrow",
"min": 3,
"max": 10,
"weight": 5
},
{
"itemId": "coal",
"min": 1,
"max": 2,
"weight": 10
},
{
"itemId": "flint",
"min": 1,
"max": 4,
"weight": 10
},
{
"itemId": "grenade",
"min": 1,
"max": 1,
"weight": 4
},
{
"itemId": "bomb",
"min": 1,
"max": 1,
"weight": 2
}
],
"spawn": {
"mobSpeed": 240,
"maxMobSpawn": 6,
"mobs": [
{
"id": "magma_elf",
"weight": 10
},
{
"id": "magma_birdo",
"weight": 6
},
{
"id": "meteor",
"weight": 4
},
{
"id": "zombie",
"weight": 6
},
{
"id": "large_black_slime",
"weight": 5
},
{
"id": "skeleton",
"weight": 2
},
{
"id": "angry_skeleton",
"weight": 2
},
{
"id": "boney_skeleton",
"weight": 1
},
{
"id": "enderman",
"weight": 1
}
],
"animalSpeed": 600,
"maxAnimalSpawn": 5,
"animals": []
},
"buildingInfo": [
{
"buildingId": "fossils",
"density": 6.0
}
],
"environmentBlocks": {
"total": 100,
"blocks": [
{
"id": "volcano_cobblestone",
"weight": 1
},
{
"id": "lava_block_pile",
"weight": 1
}
]
}
}
}
================================================
FILE: biomes/undergrounds/desert_cave.json
================================================
{
"desert_cave": {
"biomeType": "Underground",
"scale": 1.0,
"wallParallaxe": "sand_wall",
"musics": {
"underground": [
"mcunder1",
"mcunder2",
"mcunder3",
"mcunder4"
]
},
"composition": {
"main": {
"id": "sandstone"
},
"subs": [
{
"id": "cobblestone"
},
{
"id": "sand"
},
{
"id": "gravel"
}
]
},
"wall": {
"id": "sandstone",
"full": false
},
"oreGroupName": "default",
"liquidInfo": {
"liquid": "water",
"maxAllowCount": 500
},
"distributions": {
"airWeight": 100,
"surfacePlaceables": [
{
"id": "pot",
"tag": 2,
"weight": 40
},
{
"id": "stalactite_desert",
"weight": 15
},
{
"id": "stalactite_small_desert",
"weight": 10
},
{
"id": "stone_pillar_desert",
"weight": 4
},
{
"id": "rock",
"weight": 4
},
{
"id": "small_tree_desert",
"weight": 10
},
{
"id": "glowing_mushroom",
"weight": 1
}
],
"hangingWeight": 100,
"hangingPlaceables": [
{
"id": "stalactite_hanging_desert",
"weight": 30
},
{
"id": "stalactite_hanging_small_desert",
"weight": 30
}
]
},
"pot": [
{
"itemId": "torch",
"min": 1,
"max": 5,
"weight": 15
},
{
"itemId": "potion_healing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_night_vision",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_strength",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_swiftness",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_water_breathing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "wooden_arrow",
"min": 3,
"max": 10,
"weight": 12
},
{
"itemId": "lighting_arrow",
"min": 3,
"max": 10,
"weight": 5
},
{
"itemId": "coal",
"min": 1,
"max": 2,
"weight": 10
},
{
"itemId": "flint",
"min": 1,
"max": 4,
"weight": 10
},
{
"itemId": "grenade",
"min": 1,
"max": 1,
"weight": 4
},
{
"itemId": "bomb",
"min": 1,
"max": 1,
"weight": 2
}
],
"spawn": {
"mobSpeed": 300,
"maxMobSpawn": 6,
"mobs": [
{
"id": "large_desert_slime",
"weight": 10
},
{
"id": "mummy",
"weight": 24
},
{
"id": "husk",
"weight": 20
},
{
"id": "zombie",
"weight": 10
},
{
"id": "spider",
"weight": 8
},
{
"id": "bald_zombie",
"weight": 8
},
{
"id": "villager_zombie",
"weight": 6
},
{
"id": "skeleton",
"weight": 2
},
{
"id": "creeper",
"weight": 2
},
{
"id": "flower_creeper",
"weight": 2
},
{
"id": "enderman",
"weight": 2
}
],
"animalSpeed": 600,
"maxAnimalSpawn": 5,
"animals": [
{
"id": "squid",
"weight": 10
}
]
},
"buildingInfo": [
{
"buildingId": "under_desert_cabin",
"density": 8.0
},
{
"buildingId": "fossils",
"density": 10.0
}
],
"environmentBlocks": {
"total": 100,
"blocks": [
{
"id": "sand",
"weight": 1
},
{
"id": "sandstone",
"weight": 1
},
{
"id": "sandstone_smooth",
"weight": 1
}
]
}
}
}
================================================
FILE: biomes/undergrounds/diorite_cave.json
================================================
{
"diorite_cave": {
"biomeType": "Underground",
"scale": 0.6,
"wallParallaxe": "stone_wall",
"musics": {
"underground": [
"mcunder1",
"mcunder2",
"mcunder3",
"mcunder4"
]
},
"composition": {
"main": {
"id": "diorite"
},
"subs": [
{
"id": "gravel"
}
]
},
"wall": {
"id": "diorite",
"full": true
},
"oreGroupName": "default",
"liquidInfo": {
"liquid": "water",
"maxAllowCount": 500
},
"distributions": {
"airWeight": 100,
"surfacePlaceables": [
{
"id": "pot",
"tag": 0,
"weight": 40
},
{
"id": "stalactite_stone",
"weight": 15
},
{
"id": "stalactite_small_stone",
"weight": 10
},
{
"id": "stalactite_diorite",
"weight": 15
},
{
"id": "stalactite_small_diorite",
"weight": 10
},
{
"id": "stone_pillar_normal",
"weight": 4
},
{
"id": "rock",
"weight": 4
},
{
"id": "stone_decos_normal",
"weight": 12
}
],
"hangingWeight": 100,
"hangingPlaceables": [
{
"id": "stalactite_hanging_stone",
"weight": 30
},
{
"id": "stalactite_hanging_small_stone",
"weight": 30
},
{
"id": "stalactite_hanging_diorite",
"weight": 30
},
{
"id": "stalactite_hanging_small_diorite",
"weight": 30
}
]
},
"pot": [
{
"itemId": "torch",
"min": 1,
"max": 5,
"weight": 15
},
{
"itemId": "potion_healing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_night_vision",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_strength",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_leaping",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_water_breathing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "wooden_arrow",
"min": 3,
"max": 10,
"weight": 12
},
{
"itemId": "lighting_arrow",
"min": 3,
"max": 10,
"weight": 5
},
{
"itemId": "coal",
"min": 1,
"max": 2,
"weight": 10
},
{
"itemId": "flint",
"min": 1,
"max": 4,
"weight": 10
},
{
"itemId": "grenade",
"min": 1,
"max": 1,
"weight": 4
},
{
"itemId": "bomb",
"min": 1,
"max": 1,
"weight": 2
}
],
"spawn": {
"mobSpeed": 300,
"maxMobSpawn": 6,
"mobs": [
{
"id": "zombie",
"weight": 20
},
{
"id": "angry_skeleton",
"weight": 12
},
{
"id": "boney_skeleton",
"weight": 12
},
{
"id": "spider",
"weight": 8
},
{
"id": "bald_zombie",
"weight": 8
},
{
"id": "villager_zombie",
"weight": 6
},
{
"id": "bat",
"weight": 5
},
{
"id": "skeleton",
"weight": 2
},
{
"id": "creeper",
"weight": 2
},
{
"id": "flower_creeper",
"weight": 1
},
{
"id": "enderman",
"weight": 2
}
],
"animalSpeed": 600,
"maxAnimalSpawn": 5,
"animals": []
},
"buildingInfo": [
{
"buildingId": "fossils",
"density": 6.0
}
],
"environmentBlocks": {
"total": 100,
"blocks": [
{
"id": "diorite",
"weight": 1
}
]
}
}
}
================================================
FILE: biomes/undergrounds/flesh_cave.json
================================================
{
"flesh_cave": {
"biomeType": "Underground",
"scale": 1.0,
"wallParallaxe": "flesh_wall",
"musics": {
"underground": [
"mcunder1",
"mcunder2",
"mcunder3",
"mcunder4"
]
},
"composition": {
"main": {
"id": "flesh_dirt"
},
"subs": [
{
"id": "flesh_stone"
},
{
"id": "flesh_gut"
},
{
"id": "flesh_gut"
}
]
},
"wall": {
"id": "flesh_dirt",
"full": false
},
"oreGroupName": "default",
"liquidInfo": {
"liquid": "water",
"maxAllowCount": 500
},
"distributions": {
"airWeight": 100,
"surfacePlaceables": [
{
"id": "pot",
"tag": 4,
"weight": 40
},
{
"id": "eyeball_grass",
"weight": 40
},
{
"id": "large_eyeball_grass",
"weight": 40
},
{
"id": "flesh_tentacle",
"weight": 80
},
{
"id": "blood_grass",
"weight": 200
}
],
"hangingWeight": 100,
"hangingPlaceables": [
{
"id": "flesh_tentacle_hanging",
"weight": 80
},
{
"id": "eyeball_vine",
"weight": 40
}
]
},
"pot": [
{
"itemId": "torch",
"min": 1,
"max": 5,
"weight": 15
},
{
"itemId": "potion_healing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_night_vision",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_strength",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_leaping",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_water_breathing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "wooden_arrow",
"min": 3,
"max": 10,
"weight": 12
},
{
"itemId": "lighting_arrow",
"min": 3,
"max": 10,
"weight": 5
},
{
"itemId": "coal",
"min": 1,
"max": 2,
"weight": 10
},
{
"itemId": "flint",
"min": 1,
"max": 4,
"weight": 10
},
{
"itemId": "grenade",
"min": 1,
"max": 1,
"weight": 4
},
{
"itemId": "bomb",
"min": 1,
"max": 1,
"weight": 2
}
],
"spawn": {
"mobSpeed": 240,
"maxMobSpawn": 6,
"mobs": [
{
"id": "blood_eye",
"weight": 10
},
{
"id": "iron_zombie",
"weight": 8
},
{
"id": "blood_slime",
"weight": 8
},
{
"id": "blood_skeleton",
"weight": 6
},
{
"id": "blood_bat",
"weight": 5
},
{
"id": "flower_creeper",
"weight": 1
},
{
"id": "enderman",
"weight": 1
}
],
"animalSpeed": 600,
"maxAnimalSpawn": 5,
"animals": [
{
"id": "squid",
"weight": 10
}
]
},
"buildingInfo": [
{
"buildingId": "fossils",
"density": 16.0
}
],
"environmentBlocks": {
"total": 100,
"blocks": [
{
"id": "flesh_dirt",
"weight": 1
},
{
"id": "flesh_stone",
"weight": 1
}
]
}
}
}
================================================
FILE: biomes/undergrounds/granite_cave.json
================================================
{
"granite_cave": {
"biomeType": "Underground",
"scale": 0.6,
"wallParallaxe": "stone_wall",
"musics": {
"underground": [
"mcunder1",
"mcunder2",
"mcunder3",
"mcunder4"
]
},
"composition": {
"main": {
"id": "granite"
},
"subs": [
{
"id": "cobblestone"
}
]
},
"wall": {
"id": "granite",
"full": true
},
"oreGroupName": "default",
"liquidInfo": {
"liquid": "water",
"maxAllowCount": 500
},
"distributions": {
"airWeight": 100,
"surfacePlaceables": [
{
"id": "pot",
"tag": 0,
"weight": 40
},
{
"id": "stalactite_stone",
"weight": 15
},
{
"id": "stalactite_small_stone",
"weight": 10
},
{
"id": "stalactite_granite",
"weight": 15
},
{
"id": "stalactite_small_granite",
"weight": 10
},
{
"id": "stone_pillar_normal",
"weight": 4
},
{
"id": "rock",
"weight": 4
},
{
"id": "stone_decos_normal",
"weight": 12
}
],
"hangingWeight": 100,
"hangingPlaceables": [
{
"id": "stalactite_hanging_stone",
"weight": 30
},
{
"id": "stalactite_hanging_small_stone",
"weight": 30
},
{
"id": "stalactite_hanging_granite",
"weight": 30
},
{
"id": "stalactite_hanging_small_granite",
"weight": 30
}
]
},
"pot": [
{
"itemId": "torch",
"min": 1,
"max": 5,
"weight": 15
},
{
"itemId": "potion_healing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_night_vision",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_strength",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_leaping",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_water_breathing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "wooden_arrow",
"min": 3,
"max": 10,
"weight": 12
},
{
"itemId": "lighting_arrow",
"min": 3,
"max": 10,
"weight": 5
},
{
"itemId": "coal",
"min": 1,
"max": 2,
"weight": 10
},
{
"itemId": "flint",
"min": 1,
"max": 4,
"weight": 10
},
{
"itemId": "grenade",
"min": 1,
"max": 1,
"weight": 4
},
{
"itemId": "bomb",
"min": 1,
"max": 1,
"weight": 2
}
],
"spawn": {
"mobSpeed": 300,
"maxMobSpawn": 6,
"mobs": [
{
"id": "zombie",
"weight": 20
},
{
"id": "boney_skeleton",
"weight": 12
},
{
"id": "black_skeleton",
"weight": 12
},
{
"id": "spider",
"weight": 8
},
{
"id": "bald_zombie",
"weight": 8
},
{
"id": "villager_zombie",
"weight": 6
},
{
"id": "bat",
"weight": 5
},
{
"id": "skeleton",
"weight": 2
},
{
"id": "creeper",
"weight": 2
},
{
"id": "flower_creeper",
"weight": 1
},
{
"id": "enderman",
"weight": 2
}
],
"animalSpeed": 600,
"maxAnimalSpawn": 5,
"animals": []
},
"buildingInfo": [
{
"buildingId": "mineshaft",
"density": 1.0
},
{
"buildingId": "fossils",
"density": 6.0
}
],
"environmentBlocks": {
"total": 100,
"blocks": [
{
"id": "granite",
"weight": 1
}
]
}
}
}
================================================
FILE: biomes/undergrounds/ice_cave.json
================================================
{
"ice_cave": {
"biomeType": "Underground",
"scale": 1.0,
"wallParallaxe": "ice_wall",
"musics": {
"underground": [
"mcunder1",
"mcunder2",
"mcunder3",
"mcunder4"
]
},
"composition": {
"main": {
"id": "ice_cobblestone"
},
"subs": [
{
"id": "snow"
},
{
"id": "ice"
},
{
"id": "ice_packed"
}
]
},
"wall": {
"id": "ice_cobblestone",
"full": false
},
"oreGroupName": "default",
"liquidInfo": {
"liquid": "water",
"maxAllowCount": 500
},
"distributions": {
"airWeight": 100,
"surfacePlaceables": [
{
"id": "pot",
"tag": 1,
"weight": 5
},
{
"id": "small_tree_snowy",
"weight": 30
},
{
"id": "stone_decos_ice",
"weight": 15
},
{
"id": "stone_pillar_ice",
"weight": 15
},
{
"id": "stalactite_ice",
"weight": 5
},
{
"id": "stalactite_small_ice",
"weight": 5
}
],
"hangingWeight": 100,
"hangingPlaceables": [
{
"id": "stalactite_hanging_ice",
"weight": 30
},
{
"id": "stalactite_hanging_small_ice",
"weight": 30
}
]
},
"pot": [
{
"itemId": "torch",
"min": 1,
"max": 5,
"weight": 15
},
{
"itemId": "potion_healing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_night_vision",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_strength",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_leaping",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_water_breathing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "wooden_arrow",
"min": 3,
"max": 10,
"weight": 12
},
{
"itemId": "lighting_arrow",
"min": 3,
"max": 10,
"weight": 5
},
{
"itemId": "coal",
"min": 1,
"max": 2,
"weight": 10
},
{
"itemId": "flint",
"min": 1,
"max": 4,
"weight": 10
},
{
"itemId": "grenade",
"min": 1,
"max": 1,
"weight": 4
},
{
"itemId": "bomb",
"min": 1,
"max": 1,
"weight": 2
}
],
"spawn": {
"mobSpeed": 300,
"maxMobSpawn": 6,
"mobs": [
{
"id": "ice_elf",
"weight": 10
},
{
"id": "zombie",
"weight": 8
},
{
"id": "large_ice_slime",
"weight": 6
},
{
"id": "skeleton",
"weight": 2
},
{
"id": "creeper",
"weight": 2
},
{
"id": "flower_creeper",
"weight": 1
},
{
"id": "boney_skeleton",
"weight": 1
},
{
"id": "enderman",
"weight": 1
}
],
"animalSpeed": 600,
"maxAnimalSpawn": 5,
"animals": [
{
"id": "squid",
"weight": 10
}
]
},
"buildingInfo": [
{
"buildingId": "fossils",
"density": 2.0
}
],
"environmentBlocks": {
"total": 100,
"blocks": [
{
"id": "ice_cobblestone",
"weight": 1
},
{
"id": "snow",
"weight": 1
}
]
}
}
}
================================================
FILE: biomes/undergrounds/jungle_cave.json
================================================
{
"jungle_cave": {
"biomeType": "Underground",
"scale": 1.0,
"wallParallaxe": "mud_wall",
"musics": {
"underground": [
"mcunder1",
"mcunder2",
"mcunder3",
"mcunder4"
]
},
"composition": {
"main": {
"id": "dirt"
},
"subs": [
{
"id": "coarse_dirt"
},
{
"id": "cobblestone"
},
{
"id": "gravel"
}
]
},
"wall": {
"id": "coarse_dirt",
"full": false
},
"oreGroupName": "default",
"liquidInfo": {
"liquid": "water",
"maxAllowCount": 500
},
"treeInfo": {
"styles": [
"log_acacia"
],
"density": 0.2
},
"mushroomInfo": {
"styles": [
"brown_mushroom_block",
"red_mushroom_block"
],
"density": 0.2
},
"distributions": {
"airWeight": 100,
"surfacePlaceables": [
{
"id": "pot",
"tag": 0,
"weight": 40
},
{
"id": "stalactite_stone",
"weight": 15
},
{
"id": "stalactite_small_stone",
"weight": 10
},
{
"id": "stone_pillar_normal",
"weight": 4
},
{
"id": "stone_decos_normal",
"weight": 15
},
{
"id": "stone_decos_mossy",
"weight": 15
},
{
"id": "rock",
"weight": 4
},
{
"id": "grass",
"weight": 30
},
{
"id": "large_brown_mushroom",
"weight": 4
},
{
"id": "large_red_mushroom",
"weight": 3
},
{
"id": "red_mushroom",
"weight": 8
},
{
"id": "brown_mushroom",
"weight": 8
},
{
"id": "fern",
"weight": 10
},
{
"id": "glowing_mushroom",
"weight": 10
},
{
"id": "watermelon",
"weight": 10
},
{
"id": "pumpkin",
"weight": 10
},
{
"id": "small_tree_normal",
"weight": 3
}
],
"hangingWeight": 100,
"hangingPlaceables": [
{
"id": "vine",
"weight": 88
},
{
"id": "stalactite_hanging_stone",
"weight": 30
},
{
"id": "stalactite_hanging_small_stone",
"weight": 30
}
]
},
"pot": [
{
"itemId": "torch",
"min": 1,
"max": 5,
"weight": 15
},
{
"itemId": "potion_healing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_night_vision",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_strength",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_leaping",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_water_breathing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "wooden_arrow",
"min": 3,
"max": 10,
"weight": 12
},
{
"itemId": "lighting_arrow",
"min": 3,
"max": 10,
"weight": 5
},
{
"itemId": "coal",
"min": 1,
"max": 2,
"weight": 10
},
{
"itemId": "flint",
"min": 1,
"max": 4,
"weight": 10
},
{
"itemId": "grenade",
"min": 1,
"max": 1,
"weight": 4
},
{
"itemId": "bomb",
"min": 1,
"max": 1,
"weight": 2
}
],
"spawn": {
"mobSpeed": 280,
"maxMobSpawn": 6,
"mobs": [
{
"id": "large_black_slime",
"weight": 10
},
{
"id": "man_eater",
"weight": 10
},
{
"id": "zombie",
"weight": 10
},
{
"id": "spider",
"weight": 8
},
{
"id": "bald_zombie",
"weight": 8
},
{
"id": "villager_zombie",
"weight": 6
},
{
"id": "jungle_bat",
"weight": 5
},
{
"id": "skeleton",
"weight": 2
},
{
"id": "creeper",
"weight": 2
},
{
"id": "flower_creeper",
"weight": 2
},
{
"id": "enderman",
"weight": 2
}
],
"animalSpeed": 600,
"maxAnimalSpawn": 5,
"animals": [
{
"id": "squid",
"weight": 10
}
]
},
"buildingInfo": [
{
"buildingId": "mineshaft",
"density": 1.0
},
{
"buildingId": "under_jungle_cabin",
"density": 3.0
},
{
"buildingId": "under_stone_cabin",
"density": 4.0
},
{
"buildingId": "fossils",
"density": 6.0
}
]
}
}
================================================
FILE: biomes/undergrounds/lava_cave.json
================================================
{
"lava_cave": {
"biomeType": "Underground",
"scale": 1.0,
"wallParallaxe": "lava_wall",
"musics": {
"underground": [
"mcunder1",
"mcunder2",
"mcunder3",
"mcunder4"
]
},
"composition": {
"main": {
"id": "cobblestone"
},
"subs": [
{
"id": "dirt"
},
{
"id": "magma_block"
}
]
},
"wall": {
"id": "cobblestone",
"full": false
},
"oreGroupName": "default",
"liquidInfo": {
"liquid": "water",
"maxAllowCount": 500
},
"distributions": {
"airWeight": 100,
"surfacePlaceables": [
{
"id": "pot",
"tag": 0,
"weight": 40
},
{
"id": "stalactite_stone",
"weight": 15
},
{
"id": "stalactite_small_stone",
"weight": 10
},
{
"id": "stone_pillar_normal",
"weight": 4
},
{
"id": "rock",
"weight": 4
}
],
"hangingWeight": 100,
"hangingPlaceables": [
{
"id": "stalactite_hanging_stone",
"weight": 30
},
{
"id": "stalactite_hanging_small_stone",
"weight": 30
}
]
},
"pot": [
{
"itemId": "torch",
"min": 1,
"max": 5,
"weight": 15
},
{
"itemId": "potion_healing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_night_vision",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_strength",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_leaping",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_water_breathing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "wooden_arrow",
"min": 3,
"max": 10,
"weight": 12
},
{
"itemId": "lighting_arrow",
"min": 3,
"max": 10,
"weight": 5
},
{
"itemId": "coal",
"min": 1,
"max": 2,
"weight": 10
},
{
"itemId": "flint",
"min": 1,
"max": 4,
"weight": 10
},
{
"itemId": "grenade",
"min": 1,
"max": 1,
"weight": 4
},
{
"itemId": "bomb",
"min": 1,
"max": 1,
"weight": 2
}
],
"spawn": {
"mobSpeed": 240,
"maxMobSpawn": 6,
"mobs": [
{
"id": "magma_elf",
"weight": 10
},
{
"id": "zombie",
"weight": 10
},
{
"id": "spider",
"weight": 8
},
{
"id": "angry_skeleton",
"weight": 8
},
{
"id": "black_skeleton",
"weight": 6
},
{
"id": "boney_skeleton",
"weight": 5
},
{
"id": "creeper",
"weight": 2
},
{
"id": "flower_creeper",
"weight": 1
},
{
"id": "enderman",
"weight": 1
}
],
"animalSpeed": 600,
"maxAnimalSpawn": 5,
"animals": [
{
"id": "squid",
"weight": 10
}
]
},
"buildingInfo": [
{
"buildingId": "under_dark_oak_cabin",
"density": 3.0
},
{
"buildingId": "under_jungle_cabin",
"density": 3.0
},
{
"buildingId": "fossils",
"density": 10.0
}
]
}
}
================================================
FILE: biomes/undergrounds/magma_cave.json
================================================
{
"magma_cave": {
"biomeType": "Underground",
"scale": 1.0,
"wallParallaxe": "lava_wall",
"musics": {
"underground": [
"mcunder1",
"mcunder2",
"mcunder3",
"mcunder4"
]
},
"composition": {
"main": {
"id": "volcano_burn_stone"
},
"subs": [
{
"id": "volcano_stone"
},
{
"id": "volcano_dirt"
},
{
"id": "magma_block"
}
]
},
"wall": {
"id": "volcano_dirt",
"full": false
},
"oreGroupName": "default",
"liquidInfo": {
"liquid": "lava",
"maxAllowCount": 500
},
"distributions": {
"airWeight": 100,
"surfacePlaceables": [
{
"id": "pot",
"tag": 4,
"weight": 40
},
{
"id": "stalactite_stone",
"weight": 15
},
{
"id": "stalactite_small_stone",
"weight": 10
},
{
"id": "stone_pillar_normal",
"weight": 4
},
{
"id": "rock",
"weight": 4
}
],
"hangingWeight": 100,
"hangingPlaceables": [
{
"id": "stalactite_hanging_stone",
"weight": 30
},
{
"id": "stalactite_hanging_small_stone",
"weight": 30
}
]
},
"pot": [
{
"itemId": "torch",
"min": 1,
"max": 5,
"weight": 15
},
{
"itemId": "potion_healing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_night_vision",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_strength",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_leaping",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_water_breathing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "wooden_arrow",
"min": 3,
"max": 10,
"weight": 12
},
{
"itemId": "lighting_arrow",
"min": 3,
"max": 10,
"weight": 5
},
{
"itemId": "coal",
"min": 1,
"max": 2,
"weight": 10
},
{
"itemId": "flint",
"min": 1,
"max": 4,
"weight": 10
},
{
"itemId": "grenade",
"min": 1,
"max": 1,
"weight": 4
},
{
"itemId": "bomb",
"min": 1,
"max": 1,
"weight": 2
}
],
"spawn": {
"mobSpeed": 240,
"maxMobSpawn": 6,
"mobs": [
{
"id": "magma_elf",
"weight": 10
},
{
"id": "magma_birdo",
"weight": 6
},
{
"id": "meteor",
"weight": 4
},
{
"id": "zombie",
"weight": 6
},
{
"id": "large_black_slime",
"weight": 5
},
{
"id": "skeleton",
"weight": 2
},
{
"id": "angry_skeleton",
"weight": 2
},
{
"id": "boney_skeleton",
"weight": 1
},
{
"id": "enderman",
"weight": 1
}
],
"animalSpeed": 600,
"maxAnimalSpawn": 5,
"animals": []
},
"buildingInfo": [
{
"buildingId": "fossils",
"density": 6.0
}
],
"environmentBlocks": {
"total": 100,
"blocks": [
{
"id": "volcano_dirt",
"weight": 1
},
{
"id": "volcano_stone",
"weight": 1
}
]
}
}
}
================================================
FILE: biomes/undergrounds/mud_cave.json
================================================
{
"mud_cave": {
"biomeType": "Underground",
"scale": 1.0,
"wallParallaxe": "mud_wall",
"musics": {
"underground": [
"mcunder1",
"mcunder2",
"mcunder3",
"mcunder4"
]
},
"composition": {
"main": {
"id": "cobblestone"
},
"subs": [
{
"id": "coarse_dirt"
},
{
"id": "dirt"
},
{
"id": "gravel"
}
]
},
"wall": {
"id": "dirt",
"full": false
},
"oreGroupName": "default",
"liquidInfo": {
"liquid": "water",
"maxAllowCount": 500
},
"distributions": {
"airWeight": 100,
"surfacePlaceables": [
{
"id": "pot",
"tag": 0,
"weight": 40
},
{
"id": "stalactite_stone",
"weight": 15
},
{
"id": "stalactite_small_stone",
"weight": 10
},
{
"id": "stone_pillar_normal",
"weight": 4
},
{
"id": "rock",
"weight": 4
},
{
"id": "grass",
"weight": 30
},
{
"id": "red_mushroom",
"weight": 8
},
{
"id": "brown_mushroom",
"weight": 8
}
],
"hangingWeight": 100,
"hangingPlaceables": [
{
"id": "vine",
"weight": 34
},
{
"id": "stalactite_hanging_stone",
"weight": 30
},
{
"id": "stalactite_hanging_small_stone",
"weight": 30
}
]
},
"pot": [
{
"itemId": "torch",
"min": 1,
"max": 5,
"weight": 15
},
{
"itemId": "potion_healing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_night_vision",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_strength",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_leaping",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_water_breathing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "wooden_arrow",
"min": 3,
"max": 10,
"weight": 12
},
{
"itemId": "coal",
"min": 1,
"max": 2,
"weight": 10
},
{
"itemId": "flint",
"min": 1,
"max": 4,
"weight": 10
},
{
"itemId": "grenade",
"min": 1,
"max": 1,
"weight": 4
},
{
"itemId": "bomb",
"min": 1,
"max": 1,
"weight": 2
}
],
"spawn": {
"mobSpeed": 300,
"maxMobSpawn": 6,
"mobs": [
{
"id": "large_black_slime",
"weight": 12
},
{
"id": "zombie",
"weight": 10
},
{
"id": "spider",
"weight": 8
},
{
"id": "bald_zombie",
"weight": 8
},
{
"id": "villager_zombie",
"weight": 6
},
{
"id": "bat",
"weight": 5
},
{
"id": "skeleton",
"weight": 2
},
{
"id": "creeper",
"weight": 2
},
{
"id": "flower_creeper",
"weight": 1
},
{
"id": "black_skeleton",
"weight": 12
},
{
"id": "enderman",
"weight": 2
}
],
"animalSpeed": 600,
"maxAnimalSpawn": 5,
"animals": [
{
"id": "squid",
"weight": 10
}
]
},
"buildingInfo": [
{
"buildingId": "mineshaft",
"density": 1.0
},
{
"buildingId": "under_spruce_cabin",
"density": 1.0
},
{
"buildingId": "under_oak_cabin",
"density": 2.0
},
{
"buildingId": "under_dark_oak_cabin",
"density": 3.0
},
{
"buildingId": "under_jungle_cabin",
"density": 3.0
},
{
"buildingId": "fossils",
"density": 6.0
}
]
}
}
================================================
FILE: biomes/undergrounds/mushroom_cave.json
================================================
{
"mushroom_cave": {
"biomeType": "Underground",
"scale": 1.0,
"wallParallaxe": "stone_wall",
"musics": {
"underground": [
"mcunder1",
"mcunder2",
"mcunder3",
"mcunder4"
]
},
"composition": {
"main": {
"id": "mycelium"
},
"subs": [
{
"id": "brown_mushroom_block"
},
{
"id": "red_mushroom_block"
},
{
"id": "mushroom_stem"
}
]
},
"wall": {
"id": "mycelium",
"full": false
},
"oreGroupName": "default",
"liquidInfo": {
"liquid": "water",
"maxAllowCount": 500
},
"mushroomInfo": {
"styles": [
"brown_mushroom_block",
"red_mushroom_block"
],
"density": 0.5
},
"distributions": {
"airWeight": 100,
"surfacePlaceables": [
{
"id": "pot",
"tag": 0,
"weight": 40
},
{
"id": "brown_mushroom",
"weight": 20
},
{
"id": "red_mushroom",
"weight": 20
},
{
"id": "large_brown_mushroom",
"weight": 5
},
{
"id": "large_red_mushroom",
"weight": 10
},
{
"id": "glowing_mushroom",
"weight": 4
}
],
"hangingWeight": 100,
"hangingPlaceables": []
},
"pot": [
{
"itemId": "torch",
"min": 1,
"max": 5,
"weight": 15
},
{
"itemId": "potion_healing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_night_vision",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_strength",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_leaping",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_water_breathing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "wooden_arrow",
"min": 3,
"max": 10,
"weight": 12
},
{
"itemId": "lighting_arrow",
"min": 3,
"max": 10,
"weight": 5
},
{
"itemId": "coal",
"min": 1,
"max": 2,
"weight": 10
},
{
"itemId": "flint",
"min": 1,
"max": 4,
"weight": 10
},
{
"itemId": "grenade",
"min": 1,
"max": 1,
"weight": 4
},
{
"itemId": "bomb",
"min": 1,
"max": 1,
"weight": 2
}
],
"spawn": {
"mobSpeed": 400,
"maxMobSpawn": 6,
"mobs": [],
"animalSpeed": 300,
"maxAnimalSpawn": 5,
"animals": [
{
"id": "squid",
"weight": 10
},
{
"id": "brown_mushroom_cow",
"weight": 10
},
{
"id": "red_mushroom_cow",
"weight": 10
}
]
},
"buildingInfo": [
{
"buildingId": "fossils",
"density": 6.0
}
],
"environmentBlocks": {
"total": 100,
"blocks": [
{
"id": "mycelium",
"weight": 1
}
]
}
}
}
================================================
FILE: biomes/undergrounds/normal_cave.json
================================================
{
"normal_cave": {
"biomeType": "Underground",
"scale": 1.0,
"wallParallaxe": "pile_cave_wall",
"musics": {
"underground": [
"mcunder1",
"mcunder2",
"mcunder3",
"mcunder4"
]
},
"composition": {
"main": {
"id": "cobblestone"
},
"subs": [
{
"id": "dirt"
},
{
"id": "gravel"
}
]
},
"wall": {
"id": "coarse_dirt",
"full": false
},
"oreGroupName": "default",
"liquidInfo": {
"liquid": "water",
"maxAllowCount": 500
},
"distributions": {
"airWeight": 100,
"surfacePlaceables": [
{
"id": "pot",
"tag": 0,
"weight": 40
},
{
"id": "stalactite_stone",
"weight": 15
},
{
"id": "stalactite_small_stone",
"weight": 10
},
{
"id": "stone_pillar_normal",
"weight": 4
},
{
"id": "rock",
"weight": 4
}
],
"hangingWeight": 100,
"hangingPlaceables": [
{
"id": "vine",
"weight": 18
},
{
"id": "stalactite_hanging_stone",
"weight": 30
},
{
"id": "stalactite_hanging_small_stone",
"weight": 30
}
]
},
"pot": [
{
"itemId": "torch",
"min": 1,
"max": 5,
"weight": 10
},
{
"itemId": "potion_healing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_night_vision",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_strength",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "wooden_arrow",
"min": 3,
"max": 10,
"weight": 8
},
{
"itemId": "coal",
"min": 1,
"max": 2,
"weight": 8
},
{
"itemId": "flint",
"min": 1,
"max": 4,
"weight": 8
},
{
"itemId": "grenade",
"min": 1,
"max": 3,
"weight": 5
},
{
"itemId": "bomb",
"min": 1,
"max": 1,
"weight": 4
}
],
"spawn": {
"mobSpeed": 300,
"maxMobSpawn": 6,
"mobs": [
{
"id": "large_green_slime",
"weight": 5
},
{
"id": "large_black_slime",
"weight": 8
},
{
"id": "zombie",
"weight": 10
},
{
"id": "spider",
"weight": 8
},
{
"id": "bald_zombie",
"weight": 8
},
{
"id": "villager_zombie",
"weight": 6
},
{
"id": "bat",
"weight": 5
},
{
"id": "skeleton",
"weight": 2
},
{
"id": "angry_skeleton",
"weight": 2
},
{
"id": "creeper",
"weight": 2
},
{
"id": "flower_creeper",
"weight": 1
},
{
"id": "enderman",
"weight": 1
}
],
"animalSpeed": 600,
"maxAnimalSpawn": 5,
"animals": [
{
"id": "squid",
"weight": 10
}
]
},
"buildingInfo": [
{
"buildingId": "mineshaft",
"density": 1.0
},
{
"buildingId": "under_spruce_cabin",
"density": 1.0
},
{
"buildingId": "under_oak_cabin",
"density": 2.0
},
{
"buildingId": "under_dark_oak_cabin",
"density": 3.0
},
{
"buildingId": "under_jungle_cabin",
"density": 3.0
},
{
"buildingId": "fossils",
"density": 6.0
}
]
}
}
================================================
FILE: biomes/undergrounds/stone_cave.json
================================================
{
"stone_cave": {
"biomeType": "Underground",
"scale": 1.0,
"wallParallaxe": "stone_wall",
"musics": {
"underground": [
"mcunder1",
"mcunder2",
"mcunder3",
"mcunder4"
]
},
"composition": {
"main": {
"id": "cobblestone"
},
"subs": [
{
"id": "dirt"
},
{
"id": "cobblestone"
}
]
},
"wall": {
"id": "cobblestone",
"full": false
},
"oreGroupName": "default",
"liquidInfo": {
"liquid": "water",
"maxAllowCount": 500
},
"distributions": {
"airWeight": 100,
"surfacePlaceables": [
{
"id": "pot",
"tag": 0,
"weight": 40
},
{
"id": "stalactite_stone",
"weight": 15
},
{
"id": "stalactite_small_stone",
"weight": 10
},
{
"id": "stone_pillar_normal",
"weight": 4
},
{
"id": "rock",
"weight": 4
},
{
"id": "stone_decos_normal",
"weight": 12
}
],
"hangingWeight": 100,
"hangingPlaceables": [
{
"id": "stalactite_hanging_stone",
"weight": 30
},
{
"id": "stalactite_hanging_small_stone",
"weight": 30
}
]
},
"pot": [
{
"itemId": "torch",
"min": 1,
"max": 5,
"weight": 15
},
{
"itemId": "potion_healing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_night_vision",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_strength",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_leaping",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_water_breathing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "wooden_arrow",
"min": 3,
"max": 10,
"weight": 12
},
{
"itemId": "coal",
"min": 1,
"max": 2,
"weight": 10
},
{
"itemId": "flint",
"min": 1,
"max": 4,
"weight": 10
},
{
"itemId": "grenade",
"min": 1,
"max": 1,
"weight": 4
},
{
"itemId": "bomb",
"min": 1,
"max": 1,
"weight": 2
}
],
"spawn": {
"mobSpeed": 250,
"maxMobSpawn": 6,
"mobs": [
{
"id": "large_black_slime",
"weight": 12
},
{
"id": "boney_skeleton",
"weight": 12
},
{
"id": "black_skeleton",
"weight": 12
},
{
"id": "zombie",
"weight": 10
},
{
"id": "spider",
"weight": 8
},
{
"id": "bald_zombie",
"weight": 8
},
{
"id": "villager_zombie",
"weight": 6
},
{
"id": "bat",
"weight": 5
},
{
"id": "skeleton",
"weight": 2
},
{
"id": "creeper",
"weight": 2
},
{
"id": "flower_creeper",
"weight": 1
},
{
"id": "enderman",
"weight": 2
}
],
"animalSpeed": 600,
"maxAnimalSpawn": 5,
"animals": [
{
"id": "squid",
"weight": 10
}
]
},
"buildingInfo": [
{
"buildingId": "mineshaft",
"density": 1.0
},
{
"buildingId": "under_spruce_cabin",
"density": 1.0
},
{
"buildingId": "under_oak_cabin",
"density": 2.0
},
{
"buildingId": "under_dark_oak_cabin",
"density": 3.0
},
{
"buildingId": "under_jungle_cabin",
"density": 3.0
},
{
"buildingId": "fossils",
"density": 8.0
}
]
}
}
================================================
FILE: biomes/undergrounds/tainted_cave.json
================================================
{
"tainted_cave": {
"biomeType": "Underground",
"scale": 1.0,
"wallParallaxe": "tainted_wall",
"musics": {
"underground": [
"mcunder1",
"mcunder2",
"mcunder3",
"mcunder4"
]
},
"composition": {
"main": {
"id": "tainted_stone"
},
"subs": [
{
"id": "tainted_dirt"
}
]
},
"wall": {
"id": "tainted_stone",
"full": false
},
"oreGroupName": "default",
"liquidInfo": {
"liquid": "water",
"maxAllowCount": 500
},
"distributions": {
"airWeight": 100,
"surfacePlaceables": [
{
"id": "pot",
"tag": 3,
"weight": 40
},
{
"id": "small_tree_tainted",
"weight": 10
},
{
"id": "large_poison_mushroom",
"weight": 10
},
{
"id": "poison_mushroom",
"weight": 10
},
{
"id": "tainted_grass",
"weight": 50
},
{
"id": "stone_decos_tainted",
"weight": 10
},
{
"id": "stone_pillar_tainted",
"weight": 10
},
{
"id": "stalactite_tainted",
"weight": 10
},
{
"id": "stalactite_small_tainted",
"weight": 10
},
{
"id": "stab_tainted",
"weight": 10
}
],
"hangingWeight": 100,
"hangingPlaceables": [
{
"id": "tainted_vine",
"weight": 40
},
{
"id": "stalactite_hanging_tainted",
"weight": 10
},
{
"id": "stalactite_hanging_small_tainted",
"weight": 10
},
{
"id": "stab_hanging_tainted",
"weight": 4
}
]
},
"pot": [
{
"itemId": "torch",
"min": 1,
"max": 5,
"weight": 15
},
{
"itemId": "potion_healing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_night_vision",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_strength",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_leaping",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_water_breathing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "wooden_arrow",
"min": 3,
"max": 10,
"weight": 12
},
{
"itemId": "lighting_arrow",
"min": 3,
"max": 10,
"weight": 5
},
{
"itemId": "coal",
"min": 1,
"max": 2,
"weight": 10
},
{
"itemId": "flint",
"min": 1,
"max": 4,
"weight": 10
},
{
"itemId": "grenade",
"min": 1,
"max": 1,
"weight": 4
},
{
"itemId": "bomb",
"min": 1,
"max": 1,
"weight": 2
}
],
"spawn": {
"mobSpeed": 220,
"maxMobSpawn": 6,
"mobs": [
{
"id": "large_tainted_slime",
"weight": 10
},
{
"id": "spider",
"weight": 8
},
{
"id": "enderman",
"weight": 15
},
{
"id": "evoker",
"weight": 6
},
{
"id": "phantom",
"weight": 5
},
{
"id": "tainted_skeleton",
"weight": 2
},
{
"id": "tainted_creeper",
"weight": 2
},
{
"id": "enderman",
"weight": 2
}
],
"animalSpeed": 600,
"maxAnimalSpawn": 5,
"animals": [
{
"id": "squid",
"weight": 10
}
]
},
"buildingInfo": [
{
"buildingId": "under_tainted_cabin",
"density": 3.0
},
{
"buildingId": "fossils",
"density": 4.0
}
],
"environmentBlocks": {
"total": 100,
"blocks": [
{
"id": "tainted_dirt",
"weight": 1
},
{
"id": "tainted_stone",
"weight": 1
}
]
}
}
}
================================================
FILE: biomes/undergrounds/waste_cave.json
================================================
{
"waste_cave": {
"biomeType": "Underground",
"scale": 1.0,
"wallParallaxe": "red_sand_wall",
"musics": {
"underground": [
"mcunder1",
"mcunder2",
"mcunder3",
"mcunder4"
]
},
"composition": {
"main": {
"id": "red_sand_stone"
},
"subs": [
{
"id": "red_sand"
},
{
"id": "cobblestone"
},
{
"id": "red_sand"
}
]
},
"wall": {
"id": "red_sand_stone",
"full": false
},
"oreGroupName": "default",
"liquidInfo": {
"liquid": "water",
"maxAllowCount": 500
},
"distributions": {
"airWeight": 100,
"surfacePlaceables": [
{
"id": "pot",
"tag": 0,
"weight": 5
},
{
"id": "stalactite_waste",
"weight": 5
},
{
"id": "stalactite_small_waste",
"weight": 5
},
{
"id": "rock_waste",
"weight": 20
}
],
"hangingWeight": 100,
"hangingPlaceables": [
{
"id": "stalactite_hanging_waste",
"weight": 30
},
{
"id": "stalactite_hanging_small_waste",
"weight": 30
}
]
},
"pot": [
{
"itemId": "torch",
"min": 1,
"max": 5,
"weight": 15
},
{
"itemId": "potion_healing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_night_vision",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_strength",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_leaping",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "potion_water_breathing",
"min": 1,
"max": 1,
"weight": 1
},
{
"itemId": "wooden_arrow",
"min": 3,
"max": 10,
"weight": 12
},
{
"itemId": "lighting_arrow",
"min": 3,
"max": 10,
"weight": 5
},
{
"itemId": "coal",
"min": 1,
"max": 2,
"weight": 10
},
{
"itemId": "flint",
"min": 1,
"max": 4,
"weight": 10
},
{
"itemId": "grenade",
"min": 1,
"max": 1,
"weight": 4
},
{
"itemId": "bomb",
"min": 1,
"max": 1,
"weight": 2
}
],
"spawn": {
"mobSpeed": 300,
"maxMobSpawn": 6,
"mobs": [
{
"id": "large_waste_slime",
"weight": 10
},
{
"id": "waste_block_slime",
"weight": 4
},
{
"id": "large_waste_block_slime",
"weight": 4
},
{
"id": "waste_mummy",
"weight": 10
},
{
"id": "zombie",
"weight": 10
},
{
"id": "spider",
"weight": 8
},
{
"id": "bald_zombie",
"weight": 8
},
{
"id": "villager_zombie",
"weight": 6
},
{
"id": "waste_ghost",
"weight": 5
},
{
"id": "skeleton",
"weight": 2
},
{
"id": "creeper",
"weight": 2
},
{
"id": "flower_creeper",
"weight": 1
},
{
"id": "enderman",
"weight": 3
}
],
"animalSpeed": 600,
"maxAnimalSpawn": 5,
"animals": [
{
"id": "squid",
"weight": 10
}
]
},
"buildingInfo": [
{
"buildingId": "mineshaft",
"density": 1.0
},
{
"buildingId": "fossils",
"density": 6.0
}
],
"environmentBlocks": {
"total": 100,
"blocks": [
{
"id": "red_sand",
"weight": 1
},
{
"id": "red_sand_stone",
"weight": 1
}
]
}
}
}
================================================
FILE: block_entity_ai/BrewingEntity.json
================================================
{
"BrewingEntity": {
"script": {
"path": "BrewingEntity.lua"
}
}
}
================================================
FILE: block_entity_ai/BrewingEntity.lua
================================================
---@class TC.BrewingEntity:ModBlockEntity
local BrewingEntity = class("BrewingEntity", ModBlockEntity)
function BrewingEntity:Init()
self.inventory = Inventory.new(4)
self.potionSlot = self.inventory:GetSlot(0)
self.sourceSlot = self.inventory:GetSlot(1)
self.outputSlot = self.inventory:GetSlot(2)
self.fuelSlot = self.inventory:GetSlot(3)
self.processedTime = 0
self.totalProcessTime = 0
self.currentRecipeID = 0
self.remainProcessTimes = 0
self.blockEntity.dataWatcher:AddInventory(self.inventory)
end
function BrewingEntity:OnKilled(parameterDestroy)
local cx, cy = MapUtils.GetFrontCenterXY(self.blockEntity.xi, self.blockEntity.yi)
---@param slot Slot
local function _TryDropItemAndClearSlot(slot)
if slot.hasStack then
ItemUtils.CreateDrop(slot:GetStack(), cx, cy,
Utils.RandSym(3), Utils.RandDoubleArea(-4, 1))
slot:ClearStack()
end
end
_TryDropItemAndClearSlot(self.sourceSlot)
_TryDropItemAndClearSlot(self.potionSlot)
_TryDropItemAndClearSlot(self.outputSlot)
_TryDropItemAndClearSlot(self.fuelSlot)
end
function BrewingEntity:Update()
if self.currentRecipeID > 0 then
self.processedTime = self.processedTime + 1
end
local nextLoop = false
local lastRecipeID = self.currentRecipeID
if self.currentRecipeID > 0 and self.processedTime >= self.totalProcessTime then
-- brewing finish
local recipe = RecipeUtils.GetRecipe(self.currentRecipeID)
local recipeSourceStackSize = recipe.inputs[1].stackSize
local recipePotionStackSize = recipe.inputs[2].stackSize
local recipeOutputStack = recipe.outputs[1]:GetStack()
local outputItem = recipeOutputStack:GetItem()
if not self.outputSlot.hasStack then
self.outputSlot:PushStack(recipeOutputStack:Clone())
else
local outputStack = self.outputSlot:GetStack()
assert(outputStack:IsItemStackEqual(recipeOutputStack, true), "Current output item is not same as the recipe item!")
outputStack:SetStackSize(outputStack.stackSize + recipeOutputStack.stackSize)
end
assert(self.sourceSlot.hasStack, "Current source item is not exist!")
assert(self.potionSlot.hasStack, "Current potion item is not exist!")
self.sourceSlot:DecrStackSize(recipeSourceStackSize)
self.potionSlot:DecrStackSize(recipePotionStackSize)
self.remainProcessTimes = self.remainProcessTimes - 1
local inputOk = self.sourceSlot.hasStack and self.sourceSlot:GetStack().stackSize >= recipeSourceStackSize
inputOk = inputOk and self.potionSlot.hasStack and self.potionSlot:GetStack().stackSize >= recipePotionStackSize
if inputOk then
if self.outputSlot:GetStack().stackSize + recipeOutputStack.stackSize <= outputItem.maxStackSize then
-- output can add for the next loop
nextLoop = true
end
end
self.currentRecipeID = 0
self.processedTime = 0
self.totalProcessTime = 0
end
if self.remainProcessTimes <= 0 then
if self.fuelSlot.hasStack then
if self.fuelSlot:GetStack():GetItem().id == Reg.ItemID("tc:blaze_powder") then
self.fuelSlot:DecrStackSize(1)
self.remainProcessTimes = 20
if nextLoop then
self.currentRecipeID = lastRecipeID
if self.currentRecipeID > 0 then
self.totalProcessTime = RecipeUtils.GetRecipe(self.currentRecipeID).exData.time
end
end
end
end
elseif nextLoop then
self.currentRecipeID = lastRecipeID
if self.currentRecipeID > 0 then
self.totalProcessTime = RecipeUtils.GetRecipe(self.currentRecipeID).exData.time
end
end
if self.currentRecipeID > 0 then
self.blockEntity:SetAnimation(1)
else
self.blockEntity:SetAnimation(0)
end
end
function BrewingEntity:FlushRecipeData()
if self.sourceSlot.hasStack and self.potionSlot.hasStack then
local recipeID = RecipeUtils.SearchRecipe(Reg.RecipeConfigID("Brew"), self.inventory, 0, 2)
if recipeID == 0 then
self.currentRecipeID = 0
self.processedTime = 0
self.totalProcessTime = 0
elseif recipeID > 0 and recipeID ~= self.currentRecipeID then
if self.outputSlot.hasStack then
local recipeOutputStack = RecipeUtils.GetRecipe(recipeID).outputs[1]:GetStack()
local outputStack = self.outputSlot:GetStack()
if outputStack:IsItemStackEqual(recipeOutputStack, true) then
if outputStack.stackSize + recipeOutputStack.stackSize >
recipeOutputStack:GetItem().maxStackSize then
recipeID = 0
end
else
recipeID = 0
end
end
self.currentRecipeID = recipeID
self.processedTime = 0
if recipeID == 0 then
self.totalProcessTime = 0
else
local recipe = RecipeUtils.GetRecipe(recipeID)
self.totalProcessTime = recipe.exData.time
end
end
else
self.currentRecipeID = 0
self.processedTime = 0
self.totalProcessTime = 0
end
if self.remainProcessTimes <= 0 and self.currentRecipeID > 0 and self.fuelSlot.hasStack and
self.fuelSlot:GetStack():GetItem().id == Reg.ItemID("tc:blaze_powder") then
self.fuelSlot:DecrStackSize(1)
self.remainProcessTimes = 20
end
if self.remainProcessTimes <= 0 and self.currentRecipeID > 0 then
self.currentRecipeID = 0
self.processedTime = 0
self.totalProcessTime = 0
end
end
function BrewingEntity:OnClicked(parameterClick)
local player = PlayerUtils.Get(parameterClick.playerEntityIndex)
if player then
local GuiID = require("ui.GuiID")
player:OpenGui(Mod.current, GuiID.Brewing, self.blockEntity.xi, self.blockEntity.yi)
end
end
function BrewingEntity:Save()
local res = {
processedTime = self.processedTime,
remainProcessTimes = self.remainProcessTimes,
}
if self.sourceSlot.hasStack then
res.sourceSlot = self.sourceSlot:GetStack():Serialization()
end
if self.potionSlot.hasStack then
res.potionSlot = self.potionSlot:GetStack():Serialization()
end
if self.outputSlot.hasStack then
res.outputSlot = self.outputSlot:GetStack():Serialization()
end
if self.fuelSlot.hasStack then
res.fuelSlot = self.fuelSlot:GetStack():Serialization()
end
return res
end
function BrewingEntity:Load(tagTable)
self.processedTime = tagTable.processedTime
self.remainProcessTimes = tagTable.remainProcessTimes
if tagTable.sourceSlot ~= nil then
self.sourceSlot:PushStack(ItemStack.Deserialization(tagTable.sourceSlot))
end
if tagTable.potionSlot ~= nil then
self.potionSlot:PushStack(ItemStack.Deserialization(tagTable.potionSlot))
end
if tagTable.outputSlot ~= nil then
self.outputSlot:PushStack(ItemStack.Deserialization(tagTable.outputSlot))
end
if tagTable.fuelSlot ~= nil then
self.fuelSlot:PushStack(ItemStack.Deserialization(tagTable.fuelSlot))
end
self.currentRecipeID = RecipeUtils.SearchRecipe(Reg.RecipeConfigID("Brew"), self.inventory, 0, 2)
end
return BrewingEntity
================================================
FILE: block_entity_ai/Chest30Entity.json
================================================
{
"Chest30Entity": {
"script": {
"path": "Chest30Entity.lua"
}
}
}
================================================
FILE: block_entity_ai/Chest30Entity.lua
================================================
---@class TC.Chest30Entity:TC.IChestEntity
local Chest30Entity = class("Chest30Entity", require("IChestEntity"))
function Chest30Entity:Init()
Chest30Entity.super.Init(self, 30)
end
function Chest30Entity:OnClicked(parameterClick)
self:InnerOnClicked(parameterClick, require("ui.GuiID").Chest30)
end
return Chest30Entity
================================================
FILE: block_entity_ai/IChestEntity.lua
================================================
---@class TC.IChestEntity:ModBlockEntity
local IChestEntity = class("IChestEntity", ModBlockEntity)
function IChestEntity:Init(slotCount)
slotCount = slotCount or 1
---@type Inventory
self.inventory = Inventory.new(slotCount)
self.inventorySize = slotCount
self.blockEntity.dataWatcher:AddInventory(self.inventory)
end
function IChestEntity:OnKilled(parameterDestroy)
local cx, cy = MapUtils.GetFrontCenterXY(self.blockEntity.xi, self.blockEntity.yi)
local cnt = self.inventory.slotCount
for i = 1, cnt do
local slot = self.inventory:GetSlot(i - 1)
if slot.hasStack then
ItemUtils.CreateDrop(slot:GetStack(), cx, cy,
Utils.RandSym(3), Utils.RandDoubleArea(-4, 1))
slot:ClearStack()
end
end
end
function IChestEntity:InnerOnClicked(parameterClick, guiID)
local player = PlayerUtils.Get(parameterClick.playerEntityIndex)
if player then
player:OpenGui(Mod.current, guiID, self.blockEntity.xi, self.blockEntity.yi)
end
end
function IChestEntity:Save()
local res = { inventory = self.inventory:Serialization() }
return res
end
function IChestEntity:Load(tagTable)
self.inventory:Deserialization(tagTable.inventory)
end
return IChestEntity
================================================
FILE: block_entity_ai/IShooterEntity.lua
================================================
---@class TC.IShooterEntity:TC.IChestEntity
local IShooterEntity = class("IShooterEntity", require("IChestEntity"))
function IShooterEntity:Init(slotCount)
IShooterEntity.super.Init(self, slotCount)
self.direction = 0 -- 0 left 1 right 2 up 3 down
self.wi = 2
self.hi = 2
self.active = false
-- TODO ANIMATION!!!!!!!!
end
function IShooterEntity:OnActivated(isActive)
if not isActive then
self.active = false
elseif not self.active then
self.active = true
local indices = {}
local size = self.inventorySize
for i = 0, size - 1 do
local slot = self.inventory:GetSlot(i)
if slot.hasStack then
indices[#indices + 1] = i
end
end
if #indices == 0 then
return
end
local pickIndex = indices[math.random(1, #indices)]
local slot = self.inventory:GetSlot(pickIndex)
if not slot.hasStack then
return
end
local shootX = self.blockEntity.xi - math.floor(self.wi / 2) * 16
local shootX2 = shootX + self.wi * 16
local shootY2 = self.blockEntity.yi * 16 + 16
local shootY = shootY2 - self.hi * 16
local centerX = (shootX + shootX2) / 2
local centerY = (shootY + shootY2) / 2
local dirX = 0
local dirY = 0
local shootWidth = 16
local shootHeight = 16
local stack = slot:GetStack()
local item = stack:GetItem()
if item.shootable and item.projectileID > 0 then
-- TODO: ProjectileNS::Data &dp = projectileData->GetData(di.projectileId);
shootWidth = 32
shootHeight = 32
shootWidth = math.max(shootWidth, shootHeight)
shootHeight = shootWidth
end
if self.direction == 0 then
shootX = shootX - shootWidth / 2
shootY = centerY
dirX = -1
dirY = 0
elseif self.direction == 1 then
shootX = shootX2 + shootWidth / 2
shootY = centerY
dirX = 1
dirY = 0
elseif self.direction == 2 then
shootX = centerX
shootY = shootY - shootHeight / 2
dirX = 0
dirY = -1
elseif self.direction == 3 then
shootX = centerX
shootY = shootY2 + shootHeight / 2
dirX = 0
dirY = 1
end
if item.shootable then
local speed = 15
-- TODO: Projectile Shoot!
--ProjectileUtils
else
local speed = 4
ItemUtils.CreateDrop(stack:Clone(1), shootX, shootY,
speed * dirX + Utils.RandSym(0.25), speed * dirY + Utils.RandSym(0.25))
slot:DecrStackSize(1)
end
SoundUtils.PlaySound(Reg.SoundID("bow"), self.blockEntity.xi, self.blockEntity.yi)
end
end
return IShooterEntity
================================================
FILE: block_entity_ai/Shooter9Entity.json
================================================
{
"Shooter9Entity": {
"script": {
"path": "Shooter9Entity.lua"
}
}
}
================================================
FILE: block_entity_ai/Shooter9Entity.lua
================================================
---@class TC.Shooter9Entity:TC.IShooterEntity
local Shooter9Entity = class("Shooter9Entity", require("IShooterEntity"))
function Shooter9Entity:Init()
Shooter9Entity.super.Init(self, 9)
end
function Shooter9Entity:OnClicked(parameterClick)
self:InnerOnClicked(parameterClick, require("ui.GuiID").Shooter9)
end
return Shooter9Entity
================================================
FILE: block_entity_ai/SmeltEntity.json
================================================
{
"SmeltEntity": {
"script": {
"path": "SmeltEntity.lua"
}
}
}
================================================
FILE: block_entity_ai/SmeltEntity.lua
================================================
---@class TC.SmeltEntity:ModBlockEntity
local SmeltEntity = class("SmeltEntity", ModBlockEntity)
function SmeltEntity:Init()
self.inventory = Inventory.new(4)
self.inputSlot = self.inventory:GetSlot(0)
self.fuelSlot = self.inventory:GetSlot(1)
self.outputSlot = self.inventory:GetSlot(2)
self.fuelBackSlot = self.inventory:GetSlot(3)
self.burnTime = 0 -- current burning remain time
self.burnTotalTime = 0
self.cookedTime = 0
self.totalCookTime = 0
self.currentRecipeID = 0
self.blockEntity.dataWatcher:AddInventory(self.inventory)
end
function SmeltEntity:OnPlaced()
end
function SmeltEntity:OnKilled(parameterDestroy)
local cx, cy = MapUtils.GetFrontCenterXY(self.blockEntity.xi, self.blockEntity.yi)
---@param slot Slot
local function _TryDropItemAndClearSlot(slot)
if slot.hasStack then
ItemUtils.CreateDrop(slot:GetStack(), cx, cy,
Utils.RandSym(3), Utils.RandDoubleArea(-4, 1))
slot:ClearStack()
end
end
_TryDropItemAndClearSlot(self.inputSlot)
_TryDropItemAndClearSlot(self.outputSlot)
_TryDropItemAndClearSlot(self.fuelSlot)
_TryDropItemAndClearSlot(self.fuelBackSlot)
end
function SmeltEntity:Update()
if self.currentRecipeID > 0 then
self.cookedTime = self.cookedTime + 1
end
if self.burnTime > 0 then
self.burnTime = self.burnTime - 1
end
local lastRecipeID = self.currentRecipeID
local nextCookLoop = false
if self.currentRecipeID > 0 and self.cookedTime >= self.totalCookTime then
-- current cooking is finished
local recipe = RecipeUtils.GetRecipe(self.currentRecipeID)
-- add the output
local recipeInputStackSize = recipe.inputs[1].stackSize
local recipeOutputStack = recipe.outputs[1]:GetStack()
local outputItem = recipeOutputStack:GetItem()
if not self.outputSlot.hasStack then
self.outputSlot:PushStack(recipeOutputStack:Clone())
else
local outputStack = self.outputSlot:GetStack()
assert(outputStack:IsItemStackEqual(recipeOutputStack, true), "Current output item is not same as the recipe item!")
outputStack:SetStackSize(outputStack.stackSize + recipeOutputStack.stackSize)
end
-- remove the input
assert(self.inputSlot.hasStack, "Current input item is not exist!")
self.inputSlot:DecrStackSize(recipeInputStackSize)
-- check the next loop
if self.inputSlot.hasStack and self.inputSlot:GetStack().stackSize >= recipeInputStackSize then
-- input item is exist and enough for the next loop
if self.outputSlot:GetStack().stackSize + recipeOutputStack.stackSize <= outputItem.maxStackSize then
-- output can add for the next loop
nextCookLoop = true
end
end
self.cookedTime = 0
self.totalCookTime = 0
self.currentRecipeID = 0
end
if self.burnTime <= 0 then
-- current fuel is burning over
self.burnTotalTime = 0
if self.currentRecipeID > 0 or nextCookLoop then
local hasFuel = false
if self.fuelSlot.hasStack then
local fuelItem = self.fuelSlot:GetStack():GetItem()
if fuelItem.fuelTime > 0 then
local canNextFuelLoop = true
local canReturnItem = false
if fuelItem.fuelReturnItemID > 0 then
if self.fuelBackSlot.hasStack then
local fuelStack = self.fuelBackSlot:GetStack()
if fuelStack:GetItem().id == fuelItem.fuelReturnItemID then
if fuelStack.stackSize < fuelStack:GetItem().maxStackSize then
canReturnItem = true
end
end
else
canReturnItem = true
end
canNextFuelLoop = canReturnItem
end
if canNextFuelLoop then
hasFuel = true
self.burnTotalTime = fuelItem.fuelTime
self.burnTime = self.burnTotalTime
self.fuelSlot:DecrStackSize(1)
if canReturnItem then
if self.fuelBackSlot.hasStack then
local fuelStack = self.fuelBackSlot:GetStack()
fuelStack:SetStackSize(fuelStack.stackSize + 1)
else
self.fuelBackSlot:PushStack(
ItemStack.new(ItemRegistry.GetItemByID(fuelItem.fuelReturnItemID)))
end
end
if nextCookLoop then
self.currentRecipeID = lastRecipeID
if self.currentRecipeID > 0 then
self.totalCookTime = RecipeUtils.GetRecipe(self.currentRecipeID).exData.time
end
end
end
end
end
if not hasFuel then
self.currentRecipeID = 0
self.cookedTime = 0
self.totalCookTime = 0
end
end
else
if nextCookLoop then
self.currentRecipeID = lastRecipeID
if self.currentRecipeID > 0 then
self.totalCookTime = RecipeUtils.GetRecipe(self.currentRecipeID).exData.time
end
end
end
if self.burnTime == 0 then
-- normal animation
self.blockEntity:SetAnimation(0)
else
-- burning animation
self.blockEntity:SetAnimation(1)
end
end
function SmeltEntity:FlushRecipeData()
if self.inputSlot.hasStack then
local lastRecipeID = self.currentRecipeID
local recipeID = RecipeUtils.SearchRecipe(Reg.RecipeConfigID("Smelt"), self.inventory, 0, 1)
if recipeID > 0 and recipeID ~= lastRecipeID then
-- recipe data changed
if self.outputSlot.hasStack then
local recipe = RecipeUtils.GetRecipe(recipeID)
local recipeOutputStack = recipe.outputs[1]:GetStack()
local outputStack = self.outputSlot:GetStack()
if not outputStack:IsItemStackEqual(recipeOutputStack, true) then
-- recipe is invalid because the recipe output is not same
recipeID = 0
else
local outputItem = outputStack:GetItem()
if outputStack.stackSize + recipeOutputStack.stackSize > outputItem.maxStackSize then
-- recipe is invalid because cannot add full recipe output items into output slot
recipeID = 0
end
end
end
end
if recipeID > 0 then
if self.burnTime == 0 then
if not self.fuelSlot.hasStack or self.fuelSlot:GetStack():GetItem().fuelTime == 0 then
-- fuel is invalid, so recipe is also invalid
recipeID = 0
end
end
end
if lastRecipeID ~= recipeID then
-- recipe is changed, reset the cooking data
self.currentRecipeID = recipeID
self.cookedTime = 0
self.totalCookTime = 0
if self.currentRecipeID > 0 then
self.totalCookTime = RecipeUtils.GetRecipe(self.currentRecipeID).exData.time
end
end
else
-- no input item exist, clear cooking data
self.currentRecipeID = 0
self.cookedTime = 0
self.totalCookTime = 0
end
end
function SmeltEntity:OnClicked(parameterClick)
local player = PlayerUtils.Get(parameterClick.playerEntityIndex)
if player then
local GuiID = require("ui.GuiID")
player:OpenGui(Mod.current, GuiID.Smelt, self.blockEntity.xi, self.blockEntity.yi)
end
end
function SmeltEntity:Save()
local res = {
burnTime = self.burnTime,
burnTotalTime = self.burnTotalTime,
cookedTime = self.cookedTime,
}
if self.inputSlot.hasStack then
res.inputSlot = self.inputSlot:GetStack():Serialization()
end
if self.fuelSlot.hasStack then
res.fuelSlot = self.fuelSlot:GetStack():Serialization()
end
if self.outputSlot.hasStack then
res.outputSlot = self.outputSlot:GetStack():Serialization()
end
if self.fuelBackSlot.hasStack then
res.fuelBackSlot = self.fuelBackSlot:GetStack():Serialization()
end
return res
end
function SmeltEntity:Load(tagTable)
if tagTable.burnTime ~= nil then
self.burnTime = tagTable.burnTime
end
if tagTable.burnTotalTime ~= nil then
self.burnTotalTime = tagTable.burnTotalTime
end
if tagTable.cookedTime ~= nil then
self.cookedTime = tagTable.cookedTime
end
if tagTable.inputSlot ~= nil then
self.inputSlot:PushStack(ItemStack.Deserialization(tagTable.inputSlot))
end
if tagTable.fuelSlot ~= nil then
self.fuelSlot:PushStack(ItemStack.Deserialization(tagTable.fuelSlot))
end
if tagTable.outputSlot ~= nil then
self.outputSlot:PushStack(ItemStack.Deserialization(tagTable.outputSlot))
end
if tagTable.fuelBackSlot ~= nil then
self.fuelBackSlot:PushStack(ItemStack.Deserialization(tagTable.fuelBackSlot))
end
self.currentRecipeID = RecipeUtils.SearchRecipe(Reg.RecipeConfigID("Smelt"), self.inventory, 0, 1)
end
return SmeltEntity
================================================
FILE: block_presets/Anvil.json
================================================
{
"Anvil": {
"script": {
"path": "Anvil.lua"
}
}
}
================================================
FILE: block_presets/Anvil.lua
================================================
---@class TC.Anvil:ModBlock
local Anvil = class("Anvil", ModBlock)
local GuiID = require("ui.GuiID")
function Anvil.OnClicked(xi, yi, parameterClick)
local player = PlayerUtils.Get(parameterClick.playerEntityIndex)
if player then
player:OpenGui(Mod.current, GuiID.Repair, xi, yi)
end
end
return Anvil
================================================
FILE: block_presets/Bed.json
================================================
{
"Bed": {
"pOnClicked": "ClickBed"
}
}
================================================
FILE: block_presets/Brewing.json
================================================
{
"Brewing": {
"entityId": "BrewingEntity"
}
}
================================================
FILE: block_presets/BurnerTower.json
================================================
{
"BurnerTower": {
"entityId": "Tower",
"pOnScreenUpdate": "UpdateBurnerTower",
"pOnPlaced": "TowerPlaced",
"pOnDestroy": "TowerDestroy",
"pOnClicked": "ClickTower"
}
}
================================================
FILE: block_presets/Button.json
================================================
{
"Button": {
"pOnClicked": "ClickSwitch",
"isTrigger": true
}
}
================================================
FILE: block_presets/Cake.json
================================================
{
"Cake": {
"pOnClicked": "ClickCake"
}
}
================================================
FILE: block_presets/Cobweb.json
================================================
{
"Cobweb": {
"script": {
"path": "Cobweb.lua"
},
"pOnDraw": "DrawCobweb"
}
}
================================================
FILE: block_presets/Cobweb.lua
================================================
---@class TC.Cobweb:ModBlock
local Cobweb = class("Cobweb", ModBlock)
function Cobweb.OnPlayerOverlap(xi, yi, player)
if player.speedX > 0.25 then
player:SetSpeedX(0.25)
elseif player.speedX < -0.25 then
player:SetSpeedX(0.25)
end
if player.speedY > 0.25 then
player:SetSpeedY(0.25)
elseif player.speedY < -0.25 then
player:SetSpeedY(0.25)
end
if Utils.RandTry(32) then
MapUtils.RemoveFrontAndDrop(xi, yi)
end
end
return Cobweb
================================================
FILE: block_presets/CraftingTable.json
================================================
{
"CraftingTable": {
"script": {
"path": "CraftingTable.lua"
}
}
}
================================================
FILE: block_presets/CraftingTable.lua
================================================
---@class TC.CraftingTable:ModBlock
local CraftingTable = class("CraftingTable", ModBlock)
local GuiID = require("ui.GuiID")
function CraftingTable.OnClicked(xi, yi, parameterClick)
local player = PlayerUtils.Get(parameterClick.playerEntityIndex)
if player then
player:OpenGui(Mod.current, GuiID.Craft3x, xi, yi)
end
end
return CraftingTable
================================================
FILE: block_presets/Crop.json
================================================
{
"Crop": {
"pOnDestroy": "CropDestroy",
"pOnRandomEvent": "RandomGrowCrop"
}
}
================================================
FILE: block_presets/CrystalTower.json
================================================
{
"CrystalTower": {
"pOnScreenUpdate": "UpdateCrystalTower",
"entityId": "Tower",
"pOnPlaced": "TowerPlaced",
"pOnDestroy": "TowerDestroy",
"pOnClicked": "ClickTower"
}
}
================================================
FILE: block_presets/DaylightTrigger.json
================================================
{
"DaylightTrigger": {
"isTrigger": true,
"pOnRandomEvent": "RandomDayLightTrigger"
}
}
================================================
FILE: block_presets/DoorClosed.json
================================================
{
"DoorClosed": {
"pOnDraw": "DrawDoorClosed",
"pOnClicked": "ClickOpenDoor",
"pOnActivated": "DoorActivated"
}
}
================================================
FILE: block_presets/DoorOpened.json
================================================
{
"DoorOpened": {
"pOnDraw": "DrawDoorOpened",
"pOnClicked": "ClickCloseDoor",
"pOnActivated": "DoorActivated"
}
}
================================================
FILE: block_presets/Enchantment.json
================================================
{
"Enchantment": {
"script": {
"path": "EnchantmentTable.lua"
}
}
}
================================================
FILE: block_presets/EnchantmentTable.lua
================================================
---@class TC.EnchantmentTable:ModBlock
local EnchantmentTable = class("EnchantmentTable", ModBlock)
local GuiID = require("ui.GuiID")
local ModTextures = require("mod_textures.ModTextures")
function EnchantmentTable.OnClicked(xi, yi, parameterClick)
local player = PlayerUtils.Get(parameterClick.playerEntityIndex)
if player then
player:OpenGui(Mod.current, GuiID.Enchantment, xi, yi)
end
end
function EnchantmentTable.UpdateScreen(xi, yi, tickTime)
local checkTime = xi + yi + tickTime
if checkTime % 32 == 0 then
local effect = EffectUtils.Create(Reg.EffectID("heal"), xi * 16 + Utils.RandInt(16), yi * 16 - 48 + Utils.RandInt(16),
Utils.RandSym(1), Utils.RandSym(1) - 0.5, Utils.RandSym(0.5), 1, 0.75)
effect.color = Color.new(70, 70, 255)
end
if checkTime % 16 == 0 then
local pickXi = Utils.RandIntArea(xi - 5, 12)
local pickYi = Utils.RandIntArea(yi - 6, 7)
local picked = false
local frontID = MapUtils.GetFrontID(pickXi, pickYi)
if frontID > 0 and (frontID == Reg.BlockID("book") or BlockUtils.GetSubGroupID(frontID) == Reg.BlockSubGroupID("BOOKCASE")) then
picked = true
end
if picked then
local effectX = pickXi * 16 + 8
local effectY = pickYi * 16 + 8
local cx = xi * 16 + 8
local cy = yi * 16 - 32
local effectAngle = Utils.GetAngle(effectX - cx, effectY - cy)
local effectSpeed = 1
local effectSpeedAngle = Utils.FixAngle(effectAngle + math.pi)
local spx = math.cos(effectSpeedAngle) * effectSpeed
local spy = math.sin(effectSpeedAngle) * effectSpeed
local effect = EffectUtils.Create(
Reg.EffectID("heal"),
effectX,
effectY,
spx,
spy,
Utils.RandSym(0.25),
Utils.RandDoubleArea(0.5, 0.7),
1,
Color.new(70, 70, 255)
)
effect:SetDisappearTime(240)
end
end
end
function EnchantmentTable.PostRenderFurniture(xi, yi, tickTime)
local sourceRect = Rect.new(0, 0, 32, 32)
local ex = SpriteExData.new()
ex.angle = Utils.CosValue(tickTime, 256, xi) * math.pi
ex.origin = Vector2.new(16, 16)
local drawX = (xi - 1) * 16 + 4 * Utils.SinValue(tickTime, 128, xi) + 24 - MiscUtils.screenX
local drawY = (yi - 1) * 16 + 6 * Utils.CosValue(tickTime, 128, xi) - 24 - MiscUtils.screenY
local pos = Vector2.new(drawX, drawY)
Sprite.draw(ModTextures.getInstance():getTexture("fly_book"), pos, sourceRect, Color.White, ex, 0)
end
return EnchantmentTable
================================================
FILE: block_presets/EndRod.json
================================================
{
"EndRod": {
"pOnDraw": "DrawTorch"
}
}
================================================
FILE: block_presets/EnderStorage.json
================================================
{
"EnderStorage": {
"script": {
"path": "EnderStorage.lua"
}
}
}
================================================
FILE: block_presets/EnderStorage.lua
================================================
---@class TC.EnderStorage:ModBlock
local EnderStorage = class("EnderStorage", ModBlock)
local GuiID = require("ui.GuiID")
function EnderStorage.OnClicked(xi, yi, parameterClick)
local player = PlayerUtils.Get(parameterClick.playerEntityIndex)
if player then
player:OpenGui(Mod.current, GuiID.EnderChest30, xi, yi)
end
end
return EnderStorage
================================================
FILE: block_presets/Facing.json
================================================
{
"Facing": {
"pOnPlaced": "DirectionPlaced",
"directionDraw": true
}
}
================================================
FILE: block_presets/Farmland.json
================================================
{
"Farmland": {
"pOnRandomEvent": "RandomFarmland"
}
}
================================================
FILE: block_presets/Furnace.json
================================================
{
"Furnace": {
"script": {
"path": "Furnace.lua"
},
"entityId": "SmeltEntity"
}
}
================================================
FILE: block_presets/Furnace.lua
================================================
---@class TC.Furnace:ModBlock
local Furnace = class("Furnace", ModBlock)
function Furnace.OnPlaced(xi, yi)
end
function Furnace.OnDestroy(xi, yi, parameterDestroy)
end
function Furnace.OnClicked(xi, yi, parameterClick)
end
return Furnace
================================================
FILE: block_presets/Grass.json
================================================
{
"Grass": {
"pOnDestroy": "GrassDestroy"
}
}
================================================
FILE: block_presets/GrowGrass.json
================================================
{
"GrowGrass": {
"pOnDrawCoverGroup": "SetDirtGrassCover",
"pOnRandomEvent": "RandomGrowGrass"
}
}
================================================
FILE: block_presets/HeartCrystal.json
================================================
{
"HeartCrystal": {
"script": {
"path": "HeartCrystal.lua"
}
}
}
================================================
FILE: block_presets/HeartCrystal.lua
================================================
---@class TC.HeartCrystal:ModBlock
local HeartCrystal = class("HeartCrystal", ModBlock)
local PlayerConstants = require("player.PlayerConstants")
function HeartCrystal.OnDestroy(xi, yi, parameterDestroy)
for i = 1, 32 do
local effectAngle = Utils.RandSym(math.pi)
local d = 240
local effectX = xi * 16 + 8 + math.cos(effectAngle) * d
local effectY = (yi - 1) * 16 + 8 + math.sin(effectAngle) * d
local effectSpeed = 4 - Utils.RandDouble(1.5)
local effectSpeedAngle = Utils.FixAngle(effectAngle + math.pi)
local spx = math.cos(effectSpeedAngle) * effectSpeed
local spy = math.sin(effectSpeedAngle) * effectSpeed
local colorChannel = Utils.RandIntArea(200, 50)
local effect = EffectUtils.SendFromServer(
Reg.EffectID("flash2"),
effectX,
effectY,
spx,
spy,
Utils.RandSym(0.5),
Utils.RandDoubleArea(1.0, 0.55),
1,
Color.new(colorChannel, colorChannel * 0.45, colorChannel * 0.45)
)
effect:SetDisappearTime(120)
end
SoundUtils.PlaySound(Reg.SoundID("travel"), xi, yi)
local players = PlayerUtils.SearchByCircle(xi * 16 + 8, yi * 16 + 8, 64 * 16)
---@param player Player
for _, player in each(players) do
player:AddExperience(35)
local addValue = 20
player.maxHealth = math.min(player.maxHealth + addValue, PlayerConstants.MaxHealthA)
player:Heal(addValue)
end
end
return HeartCrystal
================================================
FILE: block_presets/IceSmelt.json
================================================
{
"IceSmelt": {
"pOnRandomEvent": "RandomSmeltIce"
}
}
================================================
FILE: block_presets/InsideStorage.json
================================================
{
"InsideStorage": {
"insideDrop": true,
"entityId": "Storage",
"pOnPlaced": "ChestPlaced",
"pOnDestroy": "InsideChestDestroy",
"pOnDraw": "DrawChest",
"pOnClicked": "ClickStorage"
}
}
================================================
FILE: block_presets/Kelp.json
================================================
{
"Kelp": {
"pOnRandomEvent": "RandomGrowKelp"
}
}
================================================
FILE: block_presets/MagmaBlock.json
================================================
{
"MagmaBlock": {
"script": {
"path": "MagmaBlock.lua"
}
}
}
================================================
FILE: block_presets/MagmaBlock.lua
================================================
---@class TC.MagmaBlock:ModBlock
local MagmaBlock = class("MagmaBlock", ModBlock)
function MagmaBlock.OnPlayerCollide(xi, yi, player, collisionDirection)
player:AddBuff(Reg.BuffID("fire"), 120)
end
return MagmaBlock
================================================
FILE: block_presets/Melon.json
================================================
{
"Melon": {
"pOnDestroy": "MelonDestroy"
}
}
================================================
FILE: block_presets/MelonStem.json
================================================
{
"MelonStem": {
"pOnRandomEvent": "RandomGrowMelon"
}
}
================================================
FILE: block_presets/MoonlightTrigger.json
================================================
{
"MoonlightTrigger": {
"isTrigger": true,
"pOnRandomEvent": "RandomMoonLightTrigger"
}
}
================================================
FILE: block_presets/NetherAltar.json
================================================
{
"NetherAltar": {
"script": {
"path": "NetherAltar.lua"
}
}
}
================================================
FILE: block_presets/NetherAltar.lua
================================================
---@class TC.NetherAltar:ModBlock
local NetherAltar = class("NetherAltar", ModBlock)
function NetherAltar.OnDestroy(xi, yi, parameterDestroy)
NpcUtils.Create(Reg.NpcID("worm_head"), xi * 16 - 1000, yi * 16)
SoundUtils.PlaySound(Reg.SoundID("monster"), xi, yi)
end
return NetherAltar
================================================
FILE: block_presets/Painting.json
================================================
{
"Painting": {
"pOnPlaced": "PaintingPlaced"
}
}
================================================
FILE: block_presets/PortalDoor.json
================================================
{
"PortalDoor": {
"pOnClicked": "ClickPortalDoor",
"pOnScreenUpdate": "UpdatePortalDoor"
}
}
================================================
FILE: block_presets/Pot.json
================================================
{
"Pot": {
"pOnDraw": "DrawPot",
"pOnDestroy": "PotDestroy"
}
}
================================================
FILE: block_presets/Pumpkin.json
================================================
{
"Pumpkin": {
"pOnDestroy": "MelonDestroy"
}
}
================================================
FILE: block_presets/RandomDisplay.json
================================================
{
"RandomDisplay": {
"pOnDraw": "DrawGeneral"
}
}
================================================
FILE: block_presets/RedstoneLamp.json
================================================
{
"RedstoneLamp": {
"pOnActivated": "LampActivated",
"pOnScreenUpdate": "UpdateLamp"
}
}
================================================
FILE: block_presets/RedstonePlate.json
================================================
{
"RedstonePlate": {
"script": {
"path": "RedstonePlate.lua"
},
"isTrigger": true
}
}
================================================
FILE: block_presets/RedstonePlate.lua
================================================
---@class TC.RedstonePlate:ModBlock
local RedstonePlate = class("RedstonePlate", ModBlock)
function RedstonePlate.OnPlayerOverlap(xi, yi, player)
if player.stand and math.abs(player.bottomY - (yi + 1) * 16) < 4 then
MapUtils.TriggerSignal(xi, yi, true)
MapUtils.DelayTriggerSignal(xi, yi, false, 32)
end
end
return RedstonePlate
================================================
FILE: block_presets/RedstoneTorch.json
================================================
{
"RedstoneTorch": {
"pOnDraw": "DrawTorch",
"pOnScreenUpdate": "UpdateRedstoneTorch",
"isTrigger": true,
"pOnClicked": "ClickSwitch",
"noSmartAct": true
}
}
================================================
FILE: block_presets/Sapling.json
================================================
{
"Sapling": {
"pOnRandomEvent": "RandomGrowTree"
}
}
================================================
FILE: block_presets/Shooter.json
================================================
{
"Shooter": {
"entityId": "Shooter",
"pOnActivated": "ShooterActivated",
"pOnPlaced": "ShooterPlaced",
"pOnDestroy": "ShooterDestroy",
"pOnClicked": "ClickShooter"
}
}
================================================
FILE: block_presets/SnowQueenBall.json
================================================
{
"SnowQueenBall": {
"script": {
"path": "SnowQueenBall.lua"
}
}
}
================================================
FILE: block_presets/SnowQueenBall.lua
================================================
---@class TC.SnowQueenBall:ModBlock
local SnowQueenBall = class("SnowQueenBall", ModBlock)
local RecordData = require("record.RecordData")
function SnowQueenBall.OnClicked(xi, yi, parameterClick)
if RecordData.getInstance().hasSnowQueen then
return
end
local npc = NpcUtils.Create(Reg.NpcID("snow_queen"), xi * 16, yi * 16 - 160, 0, -8)
local modNpc = npc:GetModNpc()
if modNpc ~= nil then
modNpc.hookXi = xi
modNpc.hookYi = yi
end
SoundUtils.PlaySound(Reg.SoundID("monster"), xi, yi)
end
return SnowQueenBall
================================================
FILE: block_presets/SoulSand.json
================================================
{
"SoulSand": {
"script": {
"path": "SoulSand.lua"
}
}
}
================================================
FILE: block_presets/SoulSand.lua
================================================
---@class TC.SoulSand:ModBlock
local SoulSand = class("SoulSand", ModBlock)
function SoulSand.OnPlayerCollide(xi, yi, player, collisionDirection)
if player.speedRate > 0.5 then
player.speedRate = player.speedRate * 0.75
if player.speedRate < 0.5 then
player.speedRate = 0.5
end
end
end
return SoulSand
================================================
FILE: block_presets/Sponge.json
================================================
{
"Sponge": {
"pOnTouchLiquid": "SpongeTouchLiquid"
}
}
================================================
FILE: block_presets/Stalactite.json
================================================
{
"Stalactite": {
"pOnDraw": "DrawGeneral",
"pOnScreenUpdate": "UpdateStalactite"
}
}
================================================
FILE: block_presets/Storage.json
================================================
{
"Storage": {
"entityId": "Chest30Entity"
}
}
================================================
FILE: block_presets/Sugarcane.json
================================================
{
"Sugarcane": {
"pOnDraw": "DrawGeneral",
"pOnRandomEvent": "RandomGrowSugarCane"
}
}
================================================
FILE: block_presets/TNT.json
================================================
{
"TNT": {
"pOnActivated": "TNTActivated",
"pOnDestroy": "TNTDestroy"
}
}
================================================
FILE: block_presets/Torch.json
================================================
{
"Torch": {
"pOnDraw": "DrawTorch",
"noSmartAct": true
}
}
================================================
FILE: block_presets/TrapStorage.json
================================================
{
"TrapStorage": {
"entityId": "Storage",
"pOnPlaced": "ChestPlaced",
"pOnDestroy": "ChestDestroy",
"pOnDraw": "DrawChest",
"pOnClicked": "ClickTrappedStorage"
}
}
================================================
FILE: block_presets/Vine.json
================================================
{
"Vine": {
"pOnDraw": "DrawGeneral",
"pOnRandomEvent": "RandomGrowVine"
}
}
================================================
FILE: block_presets/WetSponge.json
================================================
{
"WetSponge": {
"pOnScreenUpdate": "UpdateWetSponge"
}
}
================================================
FILE: blocks/furnitures/beds/wooden_bed_black.json
================================================
{
"block": {
"wooden_bed_black": {
"textureData": "wooden_bed_black.png",
"color": [ 99, 99, 99 ],
"type": "FURNITURE",
"subGroup": "BED",
"width": 4,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 130,
"slipperiness": 1.0,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 0, 0, 0 ],
"preset": "Bed"
}
},
"item": {
"wooden_bed_black": {
"type": "BLOCKS",
"iconTextureData": "wooden_bed_black.png",
"group": "GROUP_WOODEN_BED",
"blockId": "wooden_bed_black",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/beds/wooden_bed_blue.json
================================================
{
"block": {
"wooden_bed_blue": {
"textureData": "wooden_bed_blue.png",
"color": [ 119, 129, 188 ],
"type": "FURNITURE",
"subGroup": "BED",
"width": 4,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 130,
"slipperiness": 1.0,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 0, 0, 120 ],
"preset": "Bed"
}
},
"item": {
"wooden_bed_blue": {
"type": "BLOCKS",
"iconTextureData": "wooden_bed_blue.png",
"group": "GROUP_WOODEN_BED",
"blockId": "wooden_bed_blue",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/beds/wooden_bed_brown.json
================================================
{
"block": {
"wooden_bed_brown": {
"textureData": "wooden_bed_brown.png",
"color": [ 167, 133, 108 ],
"type": "FURNITURE",
"subGroup": "BED",
"width": 4,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 130,
"slipperiness": 1.0,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 130, 100, 50 ],
"preset": "Bed"
}
},
"item": {
"wooden_bed_brown": {
"type": "BLOCKS",
"iconTextureData": "wooden_bed_brown.png",
"group": "GROUP_WOODEN_BED",
"blockId": "wooden_bed_brown",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/beds/wooden_bed_cyan.json
================================================
{
"block": {
"wooden_bed_cyan": {
"textureData": "wooden_bed_cyan.png",
"color": [ 88, 180, 180 ],
"type": "FURNITURE",
"subGroup": "BED",
"width": 4,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 130,
"slipperiness": 1.0,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 0, 120, 120 ],
"preset": "Bed"
}
},
"item": {
"wooden_bed_cyan": {
"type": "BLOCKS",
"iconTextureData": "wooden_bed_cyan.png",
"group": "GROUP_WOODEN_BED",
"blockId": "wooden_bed_cyan",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/beds/wooden_bed_gray.json
================================================
{
"block": {
"wooden_bed_gray": {
"textureData": "wooden_bed_gray.png",
"color": [ 125, 125, 128 ],
"type": "FURNITURE",
"subGroup": "BED",
"width": 4,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 130,
"slipperiness": 1.0,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 60, 60, 60 ],
"preset": "Bed"
}
},
"item": {
"wooden_bed_gray": {
"type": "BLOCKS",
"iconTextureData": "wooden_bed_gray.png",
"group": "GROUP_WOODEN_BED",
"blockId": "wooden_bed_gray",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/beds/wooden_bed_green.json
================================================
{
"block": {
"wooden_bed_green": {
"textureData": "wooden_bed_green.png",
"color": [ 144, 66, 92 ],
"type": "FURNITURE",
"subGroup": "BED",
"width": 4,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 130,
"slipperiness": 1.0,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 0, 120, 0 ],
"preset": "Bed"
}
},
"item": {
"wooden_bed_green": {
"type": "BLOCKS",
"iconTextureData": "wooden_bed_green.png",
"group": "GROUP_WOODEN_BED",
"blockId": "wooden_bed_green",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/beds/wooden_bed_light_blue.json
================================================
{
"block": {
"wooden_bed_light_blue": {
"textureData": "wooden_bed_light_blue.png",
"color": [ 130, 215, 240 ],
"type": "FURNITURE",
"subGroup": "BED",
"width": 4,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 130,
"slipperiness": 1.0,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 60, 90, 120 ],
"preset": "Bed"
}
},
"item": {
"wooden_bed_light_blue": {
"type": "BLOCKS",
"iconTextureData": "wooden_bed_light_blue.png",
"group": "GROUP_WOODEN_BED",
"blockId": "wooden_bed_light_blue",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/beds/wooden_bed_light_gray.json
================================================
{
"block": {
"wooden_bed_light_gray": {
"textureData": "wooden_bed_light_gray.png",
"color": [ 160, 166, 169 ],
"type": "FURNITURE",
"subGroup": "BED",
"width": 4,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 130,
"slipperiness": 1.0,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 120, 120, 100 ],
"preset": "Bed"
}
},
"item": {
"wooden_bed_light_gray": {
"type": "BLOCKS",
"iconTextureData": "wooden_bed_light_gray.png",
"group": "GROUP_WOODEN_BED",
"blockId": "wooden_bed_light_gray",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/beds/wooden_bed_lime.json
================================================
{
"block": {
"wooden_bed_lime": {
"textureData": "wooden_bed_lime.png",
"type": "FURNITURE",
"subGroup": "BED",
"width": 4,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 130,
"slipperiness": 1.0,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 50, 100, 0 ],
"preset": "Bed"
}
},
"item": {
"wooden_bed_lime": {
"type": "BLOCKS",
"iconTextureData": "wooden_bed_lime.png",
"group": "GROUP_WOODEN_BED",
"blockId": "wooden_bed_lime",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/beds/wooden_bed_magenta.json
================================================
{
"block": {
"wooden_bed_magenta": {
"textureData": "wooden_bed_magenta.png",
"color": [ 202, 109, 193 ],
"type": "FURNITURE",
"subGroup": "BED",
"width": 4,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 130,
"slipperiness": 1.0,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 120, 60, 120 ],
"preset": "Bed"
}
},
"item": {
"wooden_bed_magenta": {
"type": "BLOCKS",
"iconTextureData": "wooden_bed_magenta.png",
"group": "GROUP_WOODEN_BED",
"blockId": "wooden_bed_magenta",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/beds/wooden_bed_orange.json
================================================
{
"block": {
"wooden_bed_orange": {
"textureData": "wooden_bed_orange.png",
"color": [ 248, 116, 93 ],
"type": "FURNITURE",
"subGroup": "BED",
"width": 4,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 130,
"slipperiness": 1.0,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 140, 120, 100 ],
"preset": "Bed"
}
},
"item": {
"wooden_bed_orange": {
"type": "BLOCKS",
"iconTextureData": "wooden_bed_orange.png",
"group": "GROUP_WOODEN_BED",
"blockId": "wooden_bed_orange",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/beds/wooden_bed_pink.json
================================================
{
"block": {
"wooden_bed_pink": {
"textureData": "wooden_bed_pink.png",
"color": [ 212, 155, 188 ],
"type": "FURNITURE",
"subGroup": "BED",
"width": 4,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 130,
"slipperiness": 1.0,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 130, 100, 100 ],
"preset": "Bed"
}
},
"item": {
"wooden_bed_pink": {
"type": "BLOCKS",
"iconTextureData": "wooden_bed_pink.png",
"group": "GROUP_WOODEN_BED",
"blockId": "wooden_bed_pink",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/beds/wooden_bed_purple.json
================================================
{
"block": {
"wooden_bed_purple": {
"textureData": "wooden_bed_purple.png",
"color": [ 90, 114, 204 ],
"type": "FURNITURE",
"subGroup": "BED",
"width": 4,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 130,
"slipperiness": 1.0,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 60, 30, 120 ],
"preset": "Bed"
}
},
"item": {
"wooden_bed_purple": {
"type": "BLOCKS",
"iconTextureData": "wooden_bed_purple.png",
"group": "GROUP_WOODEN_BED",
"blockId": "wooden_bed_purple",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/beds/wooden_bed_red.json
================================================
{
"block": {
"wooden_bed_red": {
"textureData": "wooden_bed_red.png",
"color": [ 186, 100, 97 ],
"type": "FURNITURE",
"subGroup": "BED",
"width": 4,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 130,
"slipperiness": 1.0,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 120, 0, 0 ],
"preset": "Bed"
}
},
"item": {
"wooden_bed_red": {
"type": "BLOCKS",
"iconTextureData": "wooden_bed_red.png",
"group": "GROUP_WOODEN_BED",
"blockId": "wooden_bed_red",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/beds/wooden_bed_white.json
================================================
{
"block": {
"wooden_bed_white": {
"note": "各色床 89:0-15",
"textureData": "wooden_bed_white.png",
"color": [ 201, 208, 208 ],
"type": "FURNITURE",
"subGroup": "BED",
"width": 4,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 130,
"slipperiness": 1.0,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 200, 170, 150 ],
"preset": "Bed"
}
},
"item": {
"wooden_bed_white": {
"type": "BLOCKS",
"iconTextureData": "wooden_bed_white.png",
"group": "GROUP_WOODEN_BED",
"blockId": "wooden_bed_white",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/beds/wooden_bed_yellow.json
================================================
{
"block": {
"wooden_bed_yellow": {
"textureData": "wooden_bed_yellow.png",
"color": [ 252, 218, 96 ],
"type": "FURNITURE",
"subGroup": "BED",
"width": 4,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 130,
"slipperiness": 1.0,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 120, 120, 0 ],
"preset": "Bed"
}
},
"item": {
"wooden_bed_yellow": {
"type": "BLOCKS",
"iconTextureData": "wooden_bed_yellow.png",
"group": "GROUP_WOODEN_BED",
"blockId": "wooden_bed_yellow",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/benches/bench_acacia.json
================================================
{
"block": {
"bench_acacia": {
"textureData": "bench_acacia.png",
"color": [ 190, 125, 90 ],
"type": "FURNITURE",
"width": 3,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 80,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 180, 100, 60 ]
}
},
"item": {
"bench_acacia": {
"type": "BLOCKS",
"iconTextureData": "bench_acacia.png",
"group": "GROUP_BENCH",
"blockId": "bench_acacia",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/benches/bench_birch.json
================================================
{
"block": {
"bench_birch": {
"textureData": "bench_birch.png",
"color": [ 220, 210, 160 ],
"type": "FURNITURE",
"width": 3,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 80,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 200, 200, 130 ]
}
},
"item": {
"bench_birch": {
"type": "BLOCKS",
"iconTextureData": "bench_birch.png",
"group": "GROUP_BENCH",
"blockId": "bench_birch",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/benches/bench_dark_oak.json
================================================
{
"block": {
"bench_dark_oak": {
"textureData": "bench_dark_oak.png",
"color": [ 106, 86, 66 ],
"type": "FURNITURE",
"width": 3,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 80,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 60, 30, 10 ]
}
},
"item": {
"bench_dark_oak": {
"type": "BLOCKS",
"iconTextureData": "bench_dark_oak.png",
"group": "GROUP_BENCH",
"blockId": "bench_dark_oak",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/benches/bench_jungle.json
================================================
{
"block": {
"bench_jungle": {
"textureData": "bench_jungle.png",
"color": [ 137, 110, 92 ],
"type": "FURNITURE",
"width": 3,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 80,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 100, 70, 50 ]
}
},
"item": {
"bench_jungle": {
"type": "BLOCKS",
"iconTextureData": "bench_jungle.png",
"group": "GROUP_BENCH",
"blockId": "bench_jungle",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/benches/bench_nether.json
================================================
{
"block": {
"bench_nether": {
"textureData": "bench_nether.png",
"color": [ 76, 29, 34 ],
"type": "FURNITURE",
"width": 3,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 80,
"slipperiness": 1.0,
"isKilledByLava": false,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 76, 29, 34 ]
}
},
"item": {
"bench_nether": {
"type": "BLOCKS",
"iconTextureData": "bench_nether.png",
"group": "GROUP_BENCH",
"blockId": "bench_nether",
"antiLava": true
}
}
}
================================================
FILE: blocks/furnitures/benches/bench_oak.json
================================================
{
"block": {
"bench_oak": {
"textureData": "bench_oak.png",
"color": [ 167, 136, 79 ],
"type": "FURNITURE",
"width": 3,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 80,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 173, 137, 80 ]
}
},
"item": {
"bench_oak": {
"type": "BLOCKS",
"iconTextureData": "bench_oak.png",
"group": "GROUP_BENCH",
"blockId": "bench_oak",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/benches/bench_palm.json
================================================
{
"block": {
"bench_palm": {
"textureData": "bench_palm.png",
"color": [ 182, 141, 86 ],
"type": "FURNITURE",
"width": 3,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 80,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 182, 141, 86 ]
}
},
"item": {
"bench_palm": {
"type": "BLOCKS",
"iconTextureData": "bench_palm.png",
"group": "GROUP_BENCH",
"blockId": "bench_palm",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/benches/bench_spruce.json
================================================
{
"block": {
"bench_spruce": {
"textureData": "bench_spruce.png",
"color": [ 144, 119, 93 ],
"type": "FURNITURE",
"width": 3,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 80,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 120, 90, 60 ]
}
},
"item": {
"bench_spruce": {
"type": "BLOCKS",
"iconTextureData": "bench_spruce.png",
"group": "GROUP_BENCH",
"blockId": "bench_spruce",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/benches/bench_tainted.json
================================================
{
"block": {
"bench_tainted": {
"textureData": "bench_tainted.png",
"color": [ 89, 85, 107 ],
"type": "FURNITURE",
"width": 3,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 80,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 89, 85, 107 ]
}
},
"item": {
"bench_tainted": {
"type": "BLOCKS",
"iconTextureData": "bench_tainted.png",
"group": "GROUP_BENCH",
"blockId": "bench_tainted",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/benches/bench_volcano.json
================================================
{
"block": {
"bench_volcano": {
"textureData": "bench_volcano.png",
"color": [ 200, 60, 60 ],
"type": "FURNITURE",
"width": 3,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 80,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 200, 60, 60 ]
}
},
"item": {
"bench_volcano": {
"type": "BLOCKS",
"iconTextureData": "bench_volcano.png",
"group": "GROUP_BENCH",
"blockId": "bench_volcano",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/bookcases/bookcase_acacia.json
================================================
{
"block": {
"bookcase_acacia": {
"textureData": "bookcase_acacia.png",
"color": [ 190, 125, 90 ],
"type": "FURNITURE",
"subGroup": "BOOKCASE",
"width": 3,
"height": 4,
"collision": "PLATFORM",
"attach": "BOTTOM",
"attachable": "TOP",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 140,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"functionSoundId": "chest",
"functionSoundId2": "chestclosed",
"particleColor": [ 255, 180, 100, 60 ],
"preset": "Storage"
}
},
"item": {
"bookcase_acacia": {
"type": "BLOCKS",
"iconTextureData": "bookcase_acacia.png",
"group": "GROUP_BOOKCASE",
"blockId": "bookcase_acacia",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/bookcases/bookcase_birch.json
================================================
{
"block": {
"bookcase_birch": {
"textureData": "bookcase_birch.png",
"color": [ 220, 210, 160 ],
"type": "FURNITURE",
"subGroup": "BOOKCASE",
"width": 3,
"height": 4,
"collision": "PLATFORM",
"attach": "BOTTOM",
"attachable": "TOP",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 140,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"functionSoundId": "chest",
"functionSoundId2": "chestclosed",
"particleColor": [ 255, 200, 200, 130 ],
"preset": "Storage"
}
},
"item": {
"bookcase_birch": {
"type": "BLOCKS",
"iconTextureData": "bookcase_birch.png",
"group": "GROUP_BOOKCASE",
"blockId": "bookcase_birch",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/bookcases/bookcase_dark_oak.json
================================================
{
"block": {
"bookcase_dark_oak": {
"textureData": "bookcase_dark_oak.png",
"color": [ 106, 86, 66 ],
"type": "FURNITURE",
"subGroup": "BOOKCASE",
"width": 3,
"height": 4,
"collision": "PLATFORM",
"attach": "BOTTOM",
"attachable": "TOP",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 140,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"functionSoundId": "chest",
"functionSoundId2": "chestclosed",
"particleColor": [ 255, 60, 30, 10 ],
"preset": "Storage"
}
},
"item": {
"bookcase_dark_oak": {
"type": "BLOCKS",
"iconTextureData": "bookcase_dark_oak.png",
"group": "GROUP_BOOKCASE",
"blockId": "bookcase_dark_oak",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/bookcases/bookcase_jungle.json
================================================
{
"block": {
"bookcase_jungle": {
"textureData": "bookcase_jungle.png",
"color": [ 137, 110, 92 ],
"type": "FURNITURE",
"subGroup": "BOOKCASE",
"width": 3,
"height": 4,
"collision": "PLATFORM",
"attach": "BOTTOM",
"attachable": "TOP",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 140,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"functionSoundId": "chest",
"functionSoundId2": "chestclosed",
"particleColor": [ 255, 100, 70, 50 ],
"preset": "Storage"
}
},
"item": {
"bookcase_jungle": {
"type": "BLOCKS",
"iconTextureData": "bookcase_jungle.png",
"group": "GROUP_BOOKCASE",
"blockId": "bookcase_jungle",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/bookcases/bookcase_nether.json
================================================
{
"block": {
"bookcase_nether": {
"textureData": "bookcase_nether.png",
"color": [ 73, 29, 34 ],
"type": "FURNITURE",
"subGroup": "BOOKCASE",
"width": 3,
"height": 4,
"collision": "PLATFORM",
"attach": "BOTTOM",
"attachable": "TOP",
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 140,
"slipperiness": 1.0,
"isKilledByLava": false,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"functionSoundId": "chest",
"functionSoundId2": "chestclosed",
"particleColor": [ 255, 73, 29, 34 ],
"preset": "Storage"
}
},
"item": {
"bookcase_nether": {
"type": "BLOCKS",
"iconTextureData": "bookcase_nether.png",
"group": "GROUP_BOOKCASE",
"blockId": "bookcase_nether",
"antiLava": true
}
}
}
================================================
FILE: blocks/furnitures/bookcases/bookcase_oak.json
================================================
{
"block": {
"bookcase_oak": {
"textureData": "bookcase_oak.png",
"color": [ 167, 136, 79 ],
"type": "FURNITURE",
"subGroup": "BOOKCASE",
"width": 3,
"height": 4,
"collision": "PLATFORM",
"attach": "BOTTOM",
"attachable": "TOP",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 140,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"functionSoundId": "chest",
"functionSoundId2": "chestclosed",
"particleColor": [ 255, 173, 137, 80 ],
"preset": "Storage"
}
},
"item": {
"bookcase_oak": {
"type": "BLOCKS",
"iconTextureData": "bookcase_oak.png",
"group": "GROUP_BOOKCASE",
"blockId": "bookcase_oak",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/bookcases/bookcase_palm.json
================================================
{
"block": {
"bookcase_palm": {
"textureData": "bookcase_palm.png",
"color": [ 182, 141, 86 ],
"type": "FURNITURE",
"subGroup": "BOOKCASE",
"width": 3,
"height": 4,
"collision": "PLATFORM",
"attach": "BOTTOM",
"attachable": "TOP",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 140,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"functionSoundId": "chest",
"functionSoundId2": "chestclosed",
"particleColor": [ 255, 182, 141, 86 ],
"preset": "Storage"
}
},
"item": {
"bookcase_palm": {
"type": "BLOCKS",
"iconTextureData": "bookcase_palm.png",
"group": "GROUP_BOOKCASE",
"blockId": "bookcase_palm",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/bookcases/bookcase_spruce.json
================================================
{
"block": {
"bookcase_spruce": {
"textureData": "bookcase_spruce.png",
"color": [ 144, 119, 93 ],
"type": "FURNITURE",
"subGroup": "BOOKCASE",
"width": 3,
"height": 4,
"collision": "PLATFORM",
"attach": "BOTTOM",
"attachable": "TOP",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 140,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"functionSoundId": "chest",
"functionSoundId2": "chestclosed",
"particleColor": [ 255, 120, 90, 60 ],
"preset": "Storage"
}
},
"item": {
"bookcase_spruce": {
"type": "BLOCKS",
"iconTextureData": "bookcase_spruce.png",
"group": "GROUP_BOOKCASE",
"blockId": "bookcase_spruce",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/bookcases/bookcase_tainted.json
================================================
{
"block": {
"bookcase_tainted": {
"textureData": "bookcase_tainted.png",
"color": [ 89, 85, 107 ],
"type": "FURNITURE",
"subGroup": "BOOKCASE",
"width": 3,
"height": 4,
"collision": "PLATFORM",
"attach": "BOTTOM",
"attachable": "TOP",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 140,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"functionSoundId": "chest",
"functionSoundId2": "chestclosed",
"particleColor": [ 255, 89, 85, 107 ],
"preset": "Storage"
}
},
"item": {
"bookcase_tainted": {
"type": "BLOCKS",
"iconTextureData": "bookcase_tainted.png",
"group": "GROUP_BOOKCASE",
"blockId": "bookcase_tainted",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/bookcases/bookcase_volcano.json
================================================
{
"block": {
"bookcase_volcano": {
"textureData": "bookcase_volcano.png",
"color": [ 200, 60, 60 ],
"type": "FURNITURE",
"subGroup": "BOOKCASE",
"width": 3,
"height": 4,
"collision": "PLATFORM",
"attach": "BOTTOM",
"attachable": "TOP",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 140,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"functionSoundId": "chest",
"functionSoundId2": "chestclosed",
"particleColor": [ 255, 200, 60, 60 ],
"preset": "Storage"
}
},
"item": {
"bookcase_volcano": {
"type": "BLOCKS",
"iconTextureData": "bookcase_volcano.png",
"group": "GROUP_BOOKCASE",
"blockId": "bookcase_volcano",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/bosses/nether_altar.json
================================================
{
"block": {
"nether_altar": {
"textureData": "nether_altar.png",
"color": [ 166, 0, 0 ],
"type": "FURNITURE",
"width": 3,
"height": 3,
"collision": "NONE",
"attach": "NONE",
"attachable": "NONE",
"toolType": "PICKAXE",
"mineGrade": "DIAMOND",
"hardness": 1000,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 166, 0, 0 ],
"preset": "NetherAltar"
}
},
"item": {
"nether_altar": {
"type": "MATERIALS",
"iconTextureData": "nether_altar_icon.png",
"group": "GROUP_OTHERS_FURNITURE"
}
}
}
================================================
FILE: blocks/furnitures/bosses/snow_glass_ball.json
================================================
{
"block": {
"snow_glass_ball": {
"textureData": "snow_glass_ball.png",
"color": [ 200, 200, 255 ],
"type": "FURNITURE",
"width": 3,
"height": 3,
"collision": "NONE",
"attach": "NONE",
"attachable": "NONE",
"toolType": "PICKAXE",
"mineGrade": "DIAMOND",
"hardness": 1000000000,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 200, 200, 255 ],
"preset": "SnowQueenBall"
}
},
"item": {
"snow_glass_ball": {
"type": "MATERIALS",
"iconTextureData": "snow_glass_ball_icon.png",
"group": "GROUP_OTHERS_FURNITURE"
}
}
}
================================================
FILE: blocks/furnitures/cabinet/cabinet_acacia.json
================================================
{
"block": {
"cabinet_acacia": {
"textureData": "wooden_cabinet_acacia.png",
"color": [ 190, 125, 90 ],
"type": "FURNITURE",
"width": 3,
"height": 2,
"collision": "PLATFORM",
"attach": "BOTTOM",
"attachable": "TOP",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 140,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"functionSoundId": "chest",
"functionSoundId2": "chestclosed",
"particleColor": [ 255, 180, 100, 60 ],
"preset": "Storage"
}
},
"item": {
"cabinet_acacia": {
"type": "BLOCKS",
"iconTextureData": "wooden_cabinet_acacia.png",
"group": "GROUP_WOODEN_CABINET",
"blockId": "cabinet_acacia",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/cabinet/cabinet_birch.json
================================================
{
"block": {
"cabinet_birch": {
"textureData": "wooden_cabinet_birch.png",
"color": [ 220, 210, 160 ],
"type": "FURNITURE",
"width": 3,
"height": 2,
"collision": "PLATFORM",
"attach": "BOTTOM",
"attachable": "TOP",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 140,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"functionSoundId": "chest",
"functionSoundId2": "chestclosed",
"particleColor": [ 255, 200, 200, 130 ],
"preset": "Storage"
}
},
"item": {
"cabinet_birch": {
"type": "BLOCKS",
"iconTextureData": "wooden_cabinet_birch.png",
"group": "GROUP_WOODEN_CABINET",
"blockId": "cabinet_birch",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/cabinet/cabinet_dark_oak.json
================================================
{
"block": {
"cabinet_dark_oak": {
"textureData": "wooden_cabinet_dark_oak.png",
"color": [ 106, 86, 66 ],
"type": "FURNITURE",
"width": 3,
"height": 2,
"collision": "PLATFORM",
"attach": "BOTTOM",
"attachable": "TOP",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 140,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"functionSoundId": "chest",
"functionSoundId2": "chestclosed",
"particleColor": [ 255, 60, 30, 10 ],
"preset": "Storage"
}
},
"item": {
"cabinet_dark_oak": {
"type": "BLOCKS",
"iconTextureData": "wooden_cabinet_dark_oak.png",
"group": "GROUP_WOODEN_CABINET",
"blockId": "cabinet_dark_oak",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/cabinet/cabinet_jungle.json
================================================
{
"block": {
"cabinet_jungle": {
"textureData": "wooden_cabinet_jungle.png",
"color": [ 137, 110, 92 ],
"type": "FURNITURE",
"width": 3,
"height": 2,
"collision": "PLATFORM",
"attach": "BOTTOM",
"attachable": "TOP",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 140,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"functionSoundId": "chest",
"functionSoundId2": "chestclosed",
"particleColor": [ 255, 100, 70, 50 ],
"preset": "Storage"
}
},
"item": {
"cabinet_jungle": {
"type": "BLOCKS",
"iconTextureData": "wooden_cabinet_jungle.png",
"group": "GROUP_WOODEN_CABINET",
"blockId": "cabinet_jungle",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/cabinet/cabinet_nether.json
================================================
{
"block": {
"cabinet_nether": {
"textureData": "cabinet_nether.png",
"color": [ 73, 29, 34 ],
"type": "FURNITURE",
"width": 3,
"height": 2,
"collision": "PLATFORM",
"attach": "BOTTOM",
"attachable": "TOP",
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 140,
"slipperiness": 1.0,
"isKilledByLava": false,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"functionSoundId": "chest",
"functionSoundId2": "chestclosed",
"particleColor": [ 255, 73, 29, 34 ],
"preset": "Storage"
}
},
"item": {
"cabinet_nether": {
"type": "BLOCKS",
"iconTextureData": "cabinet_nether.png",
"group": "GROUP_WOODEN_CABINET",
"blockId": "cabinet_nether",
"antiLava": true
}
}
}
================================================
FILE: blocks/furnitures/cabinet/cabinet_oak.json
================================================
{
"block": {
"cabinet_oak": {
"textureData": "wooden_cabinet_oak.png",
"color": [ 167, 136, 79 ],
"type": "FURNITURE",
"width": 3,
"height": 2,
"collision": "PLATFORM",
"attach": "BOTTOM",
"attachable": "TOP",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 140,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"functionSoundId": "chest",
"functionSoundId2": "chestclosed",
"particleColor": [ 255, 173, 137, 80 ],
"preset": "Storage"
}
},
"item": {
"cabinet_oak": {
"type": "BLOCKS",
"iconTextureData": "wooden_cabinet_oak.png",
"group": "GROUP_WOODEN_CABINET",
"blockId": "cabinet_oak",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/cabinet/cabinet_palm.json
================================================
{
"block": {
"cabinet_palm": {
"textureData": "wooden_cabinet_palm.png",
"color": [ 182, 141, 86 ],
"type": "FURNITURE",
"width": 3,
"height": 2,
"collision": "PLATFORM",
"attach": "BOTTOM",
"attachable": "TOP",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 140,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"functionSoundId": "chest",
"functionSoundId2": "chestclosed",
"particleColor": [ 255, 182, 141, 86 ],
"preset": "Storage"
}
},
"item": {
"cabinet_palm": {
"type": "BLOCKS",
"iconTextureData": "wooden_cabinet_palm.png",
"group": "GROUP_WOODEN_CABINET",
"blockId": "cabinet_palm",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/cabinet/cabinet_spruce.json
================================================
{
"block": {
"cabinet_spruce": {
"textureData": "wooden_cabinet_spruce.png",
"color": [ 144, 119, 93 ],
"type": "FURNITURE",
"width": 3,
"height": 2,
"collision": "PLATFORM",
"attach": "BOTTOM",
"attachable": "TOP",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 140,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"functionSoundId": "chest",
"functionSoundId2": "chestclosed",
"particleColor": [ 255, 120, 90, 60 ],
"preset": "Storage"
}
},
"item": {
"cabinet_spruce": {
"type": "BLOCKS",
"iconTextureData": "wooden_cabinet_spruce.png",
"group": "GROUP_WOODEN_CABINET",
"blockId": "cabinet_spruce",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/cabinet/cabinet_tainted.json
================================================
{
"block": {
"cabinet_tainted": {
"textureData": "wooden_cabinet_tainted.png",
"color": [ 89, 85, 107 ],
"type": "FURNITURE",
"width": 3,
"height": 2,
"collision": "PLATFORM",
"attach": "BOTTOM",
"attachable": "TOP",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 140,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"functionSoundId": "chest",
"functionSoundId2": "chestclosed",
"particleColor": [ 255, 89, 85, 107 ],
"preset": "Storage"
}
},
"item": {
"cabinet_tainted": {
"type": "BLOCKS",
"iconTextureData": "wooden_cabinet_tainted.png",
"group": "GROUP_WOODEN_CABINET",
"blockId": "cabinet_tainted",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/cabinet/cabinet_volcano.json
================================================
{
"block": {
"cabinet_volcano": {
"textureData": "wooden_cabinet_volcano.png",
"color": [ 200, 60, 60 ],
"type": "FURNITURE",
"width": 3,
"height": 2,
"collision": "PLATFORM",
"attach": "BOTTOM",
"attachable": "TOP",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 140,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"functionSoundId": "chest",
"functionSoundId2": "chestclosed",
"particleColor": [ 255, 200, 60, 60 ],
"preset": "Storage"
}
},
"item": {
"cabinet_volcano": {
"type": "BLOCKS",
"iconTextureData": "wooden_cabinet_volcano.png",
"group": "GROUP_WOODEN_CABINET",
"blockId": "cabinet_volcano",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/chairs/chair_acacia.json
================================================
{
"block": {
"chair_acacia": {
"textureData": "wooden_chair_acacia.png",
"color": [ 190, 125, 90 ],
"type": "FURNITURE",
"width": 1,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 80,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 180, 100, 60 ],
"preset": "Facing"
}
},
"item": {
"chair_acacia": {
"type": "BLOCKS",
"iconTextureData": "wooden_chair_acacia_icon.png",
"group": "GROUP_WOODEN_CHAIR",
"blockId": "chair_acacia",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/chairs/chair_birch.json
================================================
{
"block": {
"chair_birch": {
"textureData": "wooden_chair_birch.png",
"color": [ 220, 210, 160 ],
"type": "FURNITURE",
"width": 1,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 80,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 200, 200, 130 ],
"preset": "Facing"
}
},
"item": {
"chair_birch": {
"type": "BLOCKS",
"iconTextureData": "wooden_chair_birch_icon.png",
"group": "GROUP_WOODEN_CHAIR",
"blockId": "chair_birch",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/chairs/chair_dark_oak.json
================================================
{
"block": {
"chair_dark_oak": {
"textureData": "wooden_chair_dark_oak.png",
"color": [ 106, 86, 66 ],
"type": "FURNITURE",
"width": 1,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 80,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 60, 30, 10 ],
"preset": "Facing"
}
},
"item": {
"chair_dark_oak": {
"type": "BLOCKS",
"iconTextureData": "wooden_chair_dark_oak_icon.png",
"group": "GROUP_WOODEN_CHAIR",
"blockId": "chair_dark_oak",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/chairs/chair_jungle.json
================================================
{
"block": {
"chair_jungle": {
"textureData": "wooden_chair_jungle.png",
"color": [ 137, 110, 92 ],
"type": "FURNITURE",
"width": 1,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 80,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 100, 70, 50 ],
"preset": "Facing"
}
},
"item": {
"chair_jungle": {
"type": "BLOCKS",
"iconTextureData": "wooden_chair_jungle_icon.png",
"group": "GROUP_WOODEN_CHAIR",
"blockId": "chair_jungle",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/chairs/chair_nether.json
================================================
{
"block": {
"chair_nether": {
"textureData": "chair_nether.png",
"color": [ 73, 29, 34 ],
"type": "FURNITURE",
"width": 1,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 80,
"slipperiness": 1.0,
"isKilledByLava": false,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 73, 29, 34 ],
"preset": "Facing"
}
},
"item": {
"chair_nether": {
"type": "BLOCKS",
"iconTextureData": "chair_nether_icon.png",
"group": "GROUP_WOODEN_CHAIR",
"blockId": "chair_nether",
"antiLava": true
}
}
}
================================================
FILE: blocks/furnitures/chairs/chair_oak.json
================================================
{
"block": {
"chair_oak": {
"textureData": "wooden_chair_oak.png",
"color": [ 167, 136, 79 ],
"type": "FURNITURE",
"width": 1,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 80,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 173, 137, 80 ],
"preset": "Facing"
}
},
"item": {
"chair_oak": {
"type": "BLOCKS",
"iconTextureData": "wooden_chair_oak_icon.png",
"group": "GROUP_WOODEN_CHAIR",
"blockId": "chair_oak",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/chairs/chair_palm.json
================================================
{
"block": {
"chair_palm": {
"textureData": "wooden_chair_palm.png",
"color": [ 182, 141, 86 ],
"type": "FURNITURE",
"width": 1,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 80,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 182, 141, 86 ],
"preset": "Facing"
}
},
"item": {
"chair_palm": {
"type": "BLOCKS",
"iconTextureData": "wooden_chair_palm_icon.png",
"group": "GROUP_WOODEN_CHAIR",
"blockId": "chair_palm",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/chairs/chair_spruce.json
================================================
{
"block": {
"chair_spruce": {
"textureData": "wooden_chair_spruce.png",
"color": [ 144, 119, 93 ],
"type": "FURNITURE",
"width": 1,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 80,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 120, 90, 60 ],
"preset": "Facing"
}
},
"item": {
"chair_spruce": {
"type": "BLOCKS",
"iconTextureData": "wooden_chair_spruce_icon.png",
"group": "GROUP_WOODEN_CHAIR",
"blockId": "chair_spruce",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/chairs/chair_tainted.json
================================================
{
"block": {
"chair_tainted": {
"textureData": "wooden_chair_tainted.png",
"color": [ 89, 85, 107 ],
"type": "FURNITURE",
"width": 1,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 80,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 89, 85, 107 ],
"preset": "Facing"
}
},
"item": {
"chair_tainted": {
"type": "BLOCKS",
"iconTextureData": "wooden_chair_tainted_icon.png",
"group": "GROUP_WOODEN_CHAIR",
"blockId": "chair_tainted",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/chairs/chair_volcano.json
================================================
{
"block": {
"chair_volcano": {
"textureData": "wooden_chair_volcano.png",
"color": [ 200, 60, 60 ],
"type": "FURNITURE",
"width": 1,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 80,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 200, 60, 60 ],
"preset": "Facing"
}
},
"item": {
"chair_volcano": {
"type": "BLOCKS",
"iconTextureData": "wooden_chair_volcano_icon.png",
"group": "GROUP_WOODEN_CHAIR",
"blockId": "chair_volcano",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/chests/barrel.json
================================================
{
"block": {
"barrel": {
"textureData": "barrel.png",
"color": [ 171, 121, 45 ],
"type": "FURNITURE",
"width": 2,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 100,
"slipperiness": 1.0,
"soundGroupId": "wood",
"functionSoundId": "barrel_open",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 160, 110, 40 ],
"preset": "Storage"
}
},
"item": {
"barrel": {
"type": "BLOCKS",
"iconTextureData": "barrel_icon.png",
"group": "GROUP_WOODEN_FURNITURE",
"blockId": "barrel",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/chests/chest.json
================================================
{
"block": {
"chest": {
"textureData": "chest.png",
"color": [ 171, 121, 45 ],
"type": "FURNITURE",
"width": 2,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 100,
"slipperiness": 1.0,
"soundGroupId": "wood",
"functionSoundId": "chest",
"functionSoundId2": "chestclosed",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 160, 110, 40 ],
"preset": "Storage",
"animation": [
{
"animationId": 0,
"frameStart": 0
},
{
"animationId": 1,
"frameStart": 3
}
]
}
},
"item": {
"chest": {
"type": "BLOCKS",
"iconTextureData": "chest_icon.png",
"group": "GROUP_WOODEN_FURNITURE",
"blockId": "chest",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/chests/ender_chest.json
================================================
{
"block": {
"ender_chest": {
"textureData": "ender_chest.png",
"color": [ 36, 55, 52 ],
"type": "FURNITURE",
"width": 2,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "PICKAXE",
"mineGrade": "IRON",
"hardness": 500,
"slipperiness": 1.0,
"soundGroupId": "stone",
"functionSoundId": "chest",
"functionSoundId2": "chestclosed",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 33, 33, 33 ],
"preset": "EnderStorage",
"animation": [
{
"animationId": 0,
"frameStart": 0
},
{
"animationId": 1,
"frameStart": 3
}
]
}
},
"item": {
"ender_chest": {
"type": "BLOCKS",
"iconTextureData": "ender_chest_icon.png",
"group": "GROUP_OTHERS_FURNITURE",
"blockId": "ender_chest"
}
}
}
================================================
FILE: blocks/furnitures/chests/nether_chest.json
================================================
{
"block": {
"nether_chest": {
"textureData": "nether_chest.png",
"color": [ 73, 29, 34 ],
"type": "FURNITURE",
"width": 2,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 130,
"slipperiness": 1.0,
"soundGroupId": "stone",
"functionSoundId": "chest",
"functionSoundId2": "chestclosed",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 73, 29, 34 ],
"preset": "Storage",
"animation": [
{
"animationId": 0,
"frameStart": 0
},
{
"animationId": 1,
"frameStart": 3
}
]
}
},
"item": {
"nether_chest": {
"type": "BLOCKS",
"iconTextureData": "nether_chest_icon.png",
"group": "GROUP_OTHERS_FURNITURE",
"blockId": "nether_chest"
}
}
}
================================================
FILE: blocks/furnitures/chests/shulker_box.json
================================================
{
"block": {
"shulker_box": {
"textureData": "shulker_box.png",
"color": [ 111, 111, 111 ],
"type": "FURNITURE",
"width": 2,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 130,
"slipperiness": 1.0,
"soundGroupId": "stone",
"functionSoundId": "shulker_box_open",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 100, 100, 100 ],
"preset": "InsideStorage",
"animation": [
{
"animationId": 0,
"frameStart": 0
},
{
"animationId": 1,
"frameStart": 3
}
]
}
},
"item": {
"shulker_box": {
"type": "CHESTS",
"iconTextureData": "shulker_box_icon.png",
"group": "GROUP_SHULKER_BOX",
"blockId": "shulker_box"
}
}
}
================================================
FILE: blocks/furnitures/chests/stone_chest.json
================================================
{
"block": {
"stone_chest": {
"textureData": "stone_chest.png",
"color": [ 111, 111, 111 ],
"type": "FURNITURE",
"width": 2,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 130,
"slipperiness": 1.0,
"soundGroupId": "stone",
"functionSoundId": "chest",
"functionSoundId2": "chestclosed",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 100, 100, 100 ],
"preset": "Storage",
"animation": [
{
"animationId": 0,
"frameStart": 0
},
{
"animationId": 1,
"frameStart": 3
}
]
}
},
"item": {
"stone_chest": {
"type": "BLOCKS",
"iconTextureData": "stone_chest_icon.png",
"group": "GROUP_STONE_FURNITURE",
"blockId": "stone_chest"
}
}
}
================================================
FILE: blocks/furnitures/chests/trapped_chest.json
================================================
{
"block": {
"trapped_chest": {
"textureData": "trapped_chest.png",
"color": [ 171, 121, 45 ],
"type": "FURNITURE",
"width": 2,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 100,
"slipperiness": 1.0,
"soundGroupId": "wood",
"functionSoundId": "chest",
"functionSoundId2": "chestclosed",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 160, 110, 40 ],
"preset": "TrapStorage"
}
},
"item": {
"trapped_chest": {
"type": "BLOCKS",
"iconTextureData": "trapped_chest_icon.png",
"group": "GROUP_WOODEN_FURNITURE",
"blockId": "trapped_chest",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/doors/door_nether.json
================================================
{
"block": {
"door_nether": {
"note": "地狱门 ",
"textureData": "door_nether.png",
"color": [ 73, 29, 34 ],
"type": "FURNITURE",
"subGroup": "CLOSED_DOOR",
"width": 1,
"height": 4,
"collision": "SOLID",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "PICKAXE",
"mineGrade": "STONE",
"hardness": 200,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 73, 29, 34 ],
"transformId": "door_nether_open",
"preset": "DoorClosed",
"isDoorClosed": true
}
},
"item": {
"door_nether": {
"type": "BLOCKS",
"iconTextureData": "door_nether_icon.png",
"group": "GROUP_DOOR",
"blockId": "door_nether",
"antiLava": true
}
}
}
================================================
FILE: blocks/furnitures/doors/door_nether_open.json
================================================
{
"block": {
"door_nether_open": {
"note": "地狱门 ",
"textureData": "door_nether.png",
"color": [ 73, 29, 34 ],
"type": "FURNITURE",
"subGroup": "OPENED_DOOR",
"width": 3,
"height": 4,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "PICKAXE",
"mineGrade": "STONE",
"hardness": 200,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 73, 29, 34 ],
"transformId": "door_nether",
"preset": "DoorOpened",
"isDoorOpened": true
}
}
}
================================================
FILE: blocks/furnitures/doors/iron_door.json
================================================
{
"block": {
"iron_door": {
"note": "铁门 ",
"textureData": "iron_door.png",
"color": [ 166, 166, 166 ],
"type": "FURNITURE",
"subGroup": "CLOSED_DOOR",
"width": 1,
"height": 4,
"collision": "SOLID",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "PICKAXE",
"mineGrade": "STONE",
"hardness": 200,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 180, 180, 180 ],
"transformId": "iron_door_open",
"preset": "DoorClosed",
"isDoorClosed": true
}
},
"item": {
"iron_door": {
"type": "BLOCKS",
"iconTextureData": "iron_door_icon.png",
"group": "GROUP_DOOR",
"blockId": "iron_door"
}
}
}
================================================
FILE: blocks/furnitures/doors/iron_door_open.json
================================================
{
"block": {
"iron_door_open": {
"note": "铁门 ",
"textureData": "iron_door.png",
"color": [ 166, 166, 166 ],
"type": "FURNITURE",
"subGroup": "OPENED_DOOR",
"width": 3,
"height": 4,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "PICKAXE",
"mineGrade": "STONE",
"hardness": 200,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 180, 180, 180 ],
"transformId": "iron_door",
"preset": "DoorOpened",
"isDoorOpened": true
}
}
}
================================================
FILE: blocks/furnitures/doors/wooden_door_acacia.json
================================================
{
"block": {
"wooden_door_acacia": {
"textureData": "wooden_door_acacia.png",
"color": [ 144, 74, 47 ],
"type": "FURNITURE",
"subGroup": "CLOSED_DOOR",
"width": 1,
"height": 4,
"collision": "SOLID",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 120,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 130, 70, 40 ],
"transformId": "wooden_door_acacia_open",
"preset": "DoorClosed",
"isDoorClosed": true
}
},
"item": {
"wooden_door_acacia": {
"type": "BLOCKS",
"iconTextureData": "wooden_door_acacia_icon.png",
"group": "GROUP_DOOR",
"blockId": "wooden_door_acacia",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/doors/wooden_door_acacia_open.json
================================================
{
"block": {
"wooden_door_acacia_open": {
"textureData": "wooden_door_acacia.png",
"color": [ 144, 74, 47 ],
"type": "FURNITURE",
"subGroup": "OPENED_DOOR",
"width": 3,
"height": 4,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 120,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 130, 70, 40 ],
"transformId": "wooden_door_acacia",
"preset": "DoorOpened",
"isDoorOpened": true
}
}
}
================================================
FILE: blocks/furnitures/doors/wooden_door_birch.json
================================================
{
"block": {
"wooden_door_birch": {
"textureData": "wooden_door_birch.png",
"color": [ 170, 160, 120 ],
"type": "FURNITURE",
"subGroup": "CLOSED_DOOR",
"width": 1,
"height": 4,
"collision": "SOLID",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 120,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 165, 155, 110 ],
"transformId": "wooden_door_birch_open",
"preset": "DoorClosed",
"isDoorClosed": true
}
},
"item": {
"wooden_door_birch": {
"type": "BLOCKS",
"iconTextureData": "wooden_door_birch_icon.png",
"group": "GROUP_DOOR",
"blockId": "wooden_door_birch",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/doors/wooden_door_birch_open.json
================================================
{
"block": {
"wooden_door_birch_open": {
"textureData": "wooden_door_birch.png",
"color": [ 170, 160, 120 ],
"type": "FURNITURE",
"subGroup": "OPENED_DOOR",
"width": 3,
"height": 4,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 120,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 165, 155, 110 ],
"transformId": "wooden_door_birch",
"preset": "DoorOpened",
"isDoorOpened": true
}
}
}
================================================
FILE: blocks/furnitures/doors/wooden_door_dark_oak.json
================================================
{
"block": {
"wooden_door_dark_oak": {
"textureData": "wooden_door_dark_oak.png",
"color": [ 44, 26, 16 ],
"type": "FURNITURE",
"subGroup": "CLOSED_DOOR",
"width": 1,
"height": 4,
"collision": "SOLID",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 120,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 46, 28, 18 ],
"transformId": "wooden_door_dark_oak_open",
"preset": "DoorClosed",
"isDoorClosed": true
}
},
"item": {
"wooden_door_dark_oak": {
"type": "BLOCKS",
"iconTextureData": "wooden_door_dark_oak_icon.png",
"group": "GROUP_DOOR",
"blockId": "wooden_door_dark_oak",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/doors/wooden_door_dark_oak_open.json
================================================
{
"block": {
"wooden_door_dark_oak_open": {
"textureData": "wooden_door_dark_oak.png",
"color": [ 44, 26, 16 ],
"type": "FURNITURE",
"subGroup": "OPENED_DOOR",
"width": 3,
"height": 4,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 120,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 46, 28, 18 ],
"transformId": "wooden_door_dark_oak",
"preset": "DoorOpened",
"isDoorOpened": true
}
}
}
================================================
FILE: blocks/furnitures/doors/wooden_door_jungle.json
================================================
{
"block": {
"wooden_door_jungle": {
"textureData": "wooden_door_jungle.png",
"color": [ 150, 108, 77 ],
"type": "FURNITURE",
"subGroup": "CLOSED_DOOR",
"width": 1,
"height": 4,
"collision": "SOLID",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 120,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 150, 100, 80 ],
"transformId": "wooden_door_jungle_open",
"preset": "DoorClosed",
"isDoorClosed": true
}
},
"item": {
"wooden_door_jungle": {
"type": "BLOCKS",
"iconTextureData": "wooden_door_jungle_icon.png",
"group": "GROUP_DOOR",
"blockId": "wooden_door_jungle",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/doors/wooden_door_jungle_open.json
================================================
{
"block": {
"wooden_door_jungle_open": {
"textureData": "wooden_door_jungle.png",
"color": [ 150, 108, 77 ],
"type": "FURNITURE",
"subGroup": "OPENED_DOOR",
"width": 3,
"height": 4,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 120,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 150, 100, 80 ],
"transformId": "wooden_door_jungle",
"preset": "DoorOpened",
"isDoorOpened": true
}
}
}
================================================
FILE: blocks/furnitures/doors/wooden_door_oak.json
================================================
{
"block": {
"wooden_door_oak": {
"textureData": "wooden_door_oak.png",
"color": [ 159, 132, 77 ],
"type": "FURNITURE",
"subGroup": "CLOSED_DOOR",
"width": 1,
"height": 4,
"collision": "SOLID",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 120,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 144, 122, 80 ],
"transformId": "wooden_door_oak_open",
"preset": "DoorClosed",
"isDoorClosed": true
}
},
"item": {
"wooden_door_oak": {
"type": "BLOCKS",
"iconTextureData": "wooden_door_oak_icon.png",
"group": "GROUP_DOOR",
"blockId": "wooden_door_oak",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/doors/wooden_door_oak_open.json
================================================
{
"block": {
"wooden_door_oak_open": {
"textureData": "wooden_door_oak.png",
"color": [ 159, 132, 77 ],
"type": "FURNITURE",
"subGroup": "OPENED_DOOR",
"width": 3,
"height": 4,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 120,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 144, 122, 80 ],
"transformId": "wooden_door_oak",
"preset": "DoorOpened",
"isDoorOpened": true
}
}
}
================================================
FILE: blocks/furnitures/doors/wooden_door_palm.json
================================================
{
"block": {
"wooden_door_palm": {
"textureData": "wooden_door_palm.png",
"color": [ 182, 141, 86 ],
"type": "FURNITURE",
"subGroup": "CLOSED_DOOR",
"width": 1,
"height": 4,
"collision": "SOLID",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 120,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 182, 141, 86 ],
"transformId": "wooden_door_palm_open",
"preset": "DoorClosed",
"isDoorClosed": true
}
},
"item": {
"wooden_door_palm": {
"type": "BLOCKS",
"iconTextureData": "wooden_door_palm_icon.png",
"group": "GROUP_DOOR",
"blockId": "wooden_door_palm",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/doors/wooden_door_palm_open.json
================================================
{
"block": {
"wooden_door_palm_open": {
"textureData": "wooden_door_palm.png",
"color": [ 182, 141, 86 ],
"type": "FURNITURE",
"subGroup": "OPENED_DOOR",
"width": 3,
"height": 4,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 120,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 182, 141, 86 ],
"transformId": "wooden_door_palm",
"preset": "DoorOpened",
"isDoorOpened": true
}
}
}
================================================
FILE: blocks/furnitures/doors/wooden_door_spruce.json
================================================
{
"block": {
"wooden_door_spruce": {
"textureData": "wooden_door_spruce.png",
"color": [ 77, 55, 30 ],
"type": "FURNITURE",
"subGroup": "CLOSED_DOOR",
"width": 1,
"height": 4,
"collision": "SOLID",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 120,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 100, 70, 40 ],
"transformId": "wooden_door_spruce_open",
"preset": "DoorClosed",
"isDoorClosed": true
}
},
"item": {
"wooden_door_spruce": {
"type": "BLOCKS",
"iconTextureData": "wooden_door_spruce_icon.png",
"group": "GROUP_DOOR",
"blockId": "wooden_door_spruce",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/doors/wooden_door_spruce_open.json
================================================
{
"block": {
"wooden_door_spruce_open": {
"textureData": "wooden_door_spruce.png",
"color": [ 77, 55, 30 ],
"type": "FURNITURE",
"subGroup": "OPENED_DOOR",
"width": 3,
"height": 4,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 120,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 100, 70, 40 ],
"transformId": "wooden_door_spruce",
"preset": "DoorOpened",
"isDoorOpened": true
}
}
}
================================================
FILE: blocks/furnitures/doors/wooden_door_tainted.json
================================================
{
"block": {
"wooden_door_tainted": {
"textureData": "wooden_door_tainted.png",
"color": [ 89, 85, 107 ],
"type": "FURNITURE",
"subGroup": "CLOSED_DOOR",
"width": 1,
"height": 4,
"collision": "SOLID",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 120,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 89, 85, 107 ],
"transformId": "wooden_door_tainted_open",
"preset": "DoorClosed",
"isDoorClosed": true
}
},
"item": {
"wooden_door_tainted": {
"type": "BLOCKS",
"iconTextureData": "wooden_door_tainted_icon.png",
"group": "GROUP_DOOR",
"blockId": "wooden_door_tainted",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/doors/wooden_door_tainted_open.json
================================================
{
"block": {
"wooden_door_tainted_open": {
"textureData": "wooden_door_tainted.png",
"color": [ 89, 85, 107 ],
"type": "FURNITURE",
"subGroup": "OPENED_DOOR",
"width": 3,
"height": 4,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 120,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 89, 85, 107 ],
"transformId": "wooden_door_tainted",
"preset": "DoorOpened",
"isDoorOpened": true
}
}
}
================================================
FILE: blocks/furnitures/doors/wooden_door_volcano.json
================================================
{
"block": {
"wooden_door_volcano": {
"textureData": "wooden_door_volcano.png",
"color": [ 200, 60, 60 ],
"type": "FURNITURE",
"subGroup": "CLOSED_DOOR",
"width": 1,
"height": 4,
"collision": "SOLID",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 120,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 200, 60, 60 ],
"transformId": "wooden_door_volcano_open",
"preset": "DoorClosed",
"isDoorClosed": true
}
},
"item": {
"wooden_door_volcano": {
"type": "BLOCKS",
"iconTextureData": "wooden_door_volcano_icon.png",
"group": "GROUP_DOOR",
"blockId": "wooden_door_volcano",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/doors/wooden_door_volcano_open.json
================================================
{
"block": {
"wooden_door_volcano_open": {
"textureData": "wooden_door_volcano.png",
"color": [ 200, 60, 60 ],
"type": "FURNITURE",
"subGroup": "OPENED_DOOR",
"width": 3,
"height": 4,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 120,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 200, 60, 60 ],
"transformId": "wooden_door_volcano",
"preset": "DoorOpened",
"isDoorOpened": true
}
}
}
================================================
FILE: blocks/furnitures/farms/carrot.json
================================================
{
"block": {
"carrot": {
"textureData": "carrot.png",
"color": [ 222, 177, 66 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_PLANT_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 10,
"slipperiness": 1.0,
"isKilledByLava": true,
"isFragile": true,
"isRipen": true,
"soundGroupId": "grass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 170, 140, 80 ],
"preset": "Crop",
"maxTag": 3,
"cropDrops": [
{
"itemId": "carrot",
"minCount": 2,
"maxCount": 4
}
],
"animation": [
{
"animationId": 0,
"tagUsage": "TAG_ADD_FRAME_INDEX_X",
"shake": true,
"shakeCenterX": 8,
"shakeCenterY": 16,
"shakePeriod": 128,
"shakeAngle": 0.2
}
]
}
}
}
================================================
FILE: blocks/furnitures/farms/melon_stem.json
================================================
{
"block": {
"melon_stem": {
"textureData": "melon_stem.png",
"color": [ 102, 88, 19 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_PLANT_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 60,
"slipperiness": 1.0,
"isKilledByLava": true,
"isFragile": true,
"soundGroupId": "grass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 155, 125, 28 ],
"transformId": "watermelon",
"preset": "MelonStem",
"maxTag": 3,
"animation": [
{
"animationId": 0,
"tagUsage": "TAG_ADD_FRAME_INDEX_X",
"shake": true,
"shakeCenterX": 8,
"shakeCenterY": 16,
"shakePeriod": 128,
"shakeAngle": 0.2
}
]
}
}
}
================================================
FILE: blocks/furnitures/farms/nether_wart.json
================================================
{
"block": {
"nether_wart": {
"textureData": "nether_wart.png",
"color": [ 92, 21, 26 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_PLANT_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 10,
"slipperiness": 1.0,
"isKilledByLava": true,
"isFragile": true,
"isLossyCollection": true,
"isRipen": true,
"soundGroupId": "grass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 166, 37, 48 ],
"preset": "Crop",
"maxTag": 3,
"cropDrops": [
{
"itemId": "nether_wart",
"minCount": 2,
"maxCount": 4
}
],
"animation": [
{
"animationId": 0,
"tagUsage": "TAG_ADD_FRAME_INDEX_X",
"shake": true,
"shakeCenterX": 8,
"shakeCenterY": 16,
"shakePeriod": 128,
"shakeAngle": 0.2
}
]
}
}
}
================================================
FILE: blocks/furnitures/farms/potato.json
================================================
{
"block": {
"potato": {
"textureData": "potato.png",
"color": [ 13, 132, 13 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_PLANT_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 10,
"slipperiness": 1.0,
"isKilledByLava": true,
"isFragile": true,
"isRipen": true,
"soundGroupId": "grass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 13, 133, 13 ],
"preset": "Crop",
"maxTag": 3,
"cropDrops": [
{
"itemId": "potato",
"minCount": 2,
"maxCount": 4
}
],
"animation": [
{
"animationId": 0,
"tagUsage": "TAG_ADD_FRAME_INDEX_X",
"shake": true,
"shakeCenterX": 8,
"shakeCenterY": 16,
"shakePeriod": 128,
"shakeAngle": 0.2
}
]
}
}
}
================================================
FILE: blocks/furnitures/farms/pumpkin.json
================================================
{
"block": {
"pumpkin": {
"textureData": "pumpkin.png",
"color": [ 205, 123, 12 ],
"type": "FURNITURE",
"width": 2,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_PLANT_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 10,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 200, 123, 13 ],
"isCarveable": true,
"transformId": "pumpkin_stem",
"transformId2": "pumpkin_carved",
"preset": "Pumpkin"
}
},
"item": {
"pumpkin": {
"type": "BLOCKS",
"iconTextureData": "pumpkin_icon.png",
"group": "GROUP_SAPLING",
"blockId": "pumpkin"
}
}
}
================================================
FILE: blocks/furnitures/farms/pumpkin_carved.json
================================================
{
"block": {
"pumpkin_carved": {
"textureData": "pumpkin_carved.png",
"color": [ 205, 123, 12 ],
"type": "FURNITURE",
"width": 2,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_PLANT_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 10,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 200, 123, 13 ]
}
},
"item": {
"pumpkin_carved": {
"type": "BLOCKS",
"iconTextureData": "pumpkin_carved_icon.png",
"group": "GROUP_SAPLING",
"blockId": "pumpkin_carved"
}
}
}
================================================
FILE: blocks/furnitures/farms/pumpkin_stem.json
================================================
{
"block": {
"pumpkin_stem": {
"textureData": "pumpkin_stem.png",
"color": [ 153, 125, 28 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_PLANT_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 10,
"slipperiness": 1.0,
"isKilledByLava": true,
"isFragile": true,
"soundGroupId": "grass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 13, 133, 13 ],
"transformId": "pumpkin",
"preset": "MelonStem",
"maxTag": 3,
"animation": [
{
"animationId": 0,
"tagUsage": "TAG_ADD_FRAME_INDEX_X",
"shake": true,
"shakeCenterX": 8,
"shakeCenterY": 16,
"shakePeriod": 128,
"shakeAngle": 0.2
}
]
}
}
}
================================================
FILE: blocks/furnitures/farms/sugar_cane.json
================================================
{
"block": {
"sugar_cane": {
"textureData": "sugar_cane.png",
"color": [ 133, 189, 59 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "TOP",
"placeCheck": "PLACE_PLANT_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 10,
"slipperiness": 1.0,
"isKilledByLava": true,
"isFragile": true,
"soundGroupId": "grass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 133, 188, 60 ],
"preset": "Sugarcane"
}
}
}
================================================
FILE: blocks/furnitures/farms/watermelon.json
================================================
{
"block": {
"watermelon": {
"textureData": "watermelon.png",
"color": [ 108, 121, 33 ],
"type": "FURNITURE",
"width": 2,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_PLANT_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"isChipCollection": true,
"lossyItemId": "melon_slice",
"chipCount": 6,
"hardness": 10,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 144, 144, 38 ],
"transformId": "melon_stem",
"preset": "Melon"
}
},
"item": {
"watermelon": {
"type": "BLOCKS",
"iconTextureData": "watermelon_icon.png",
"group": "GROUP_MELON",
"blockId": "watermelon"
}
}
}
================================================
FILE: blocks/furnitures/farms/wheat.json
================================================
{
"block": {
"wheat": {
"textureData": "wheat.png",
"color": [ 106, 118, 11 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_PLANT_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 10,
"slipperiness": 1.0,
"isKilledByLava": true,
"isFragile": true,
"isLossyCollection": true,
"isRipen": true,
"soundGroupId": "grass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 106, 118, 17 ],
"preset": "Crop",
"maxTag": 3,
"cropDrops": [
{
"itemId": "wheat",
"minCount": 2,
"maxCount": 4
},
{
"itemId": "seed",
"minCount": 1,
"maxCount": 2
}
],
"animation": [
{
"animationId": 0,
"tagUsage": "TAG_ADD_FRAME_INDEX_X",
"shake": true,
"shakeCenterX": 8,
"shakeCenterY": 16,
"shakePeriod": 128,
"shakeAngle": 0.2
}
]
}
}
}
================================================
FILE: blocks/furnitures/flowers/allium.json
================================================
{
"block": {
"allium": {
"textureData": "allium.png",
"color": [ 188, 110, 250 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_PLANT_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 10,
"slipperiness": 1.0,
"isKilledByLava": true,
"isFragile": true,
"isDestroyByWeapon": false,
"soundGroupId": "grass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 188, 109, 255 ],
"animation": [
{
"animationId": 0,
"shake": true,
"shakeCenterX": 8,
"shakeCenterY": 16,
"shakePeriod": 128,
"shakeAngle": 0.2
}
]
}
},
"item": {
"allium": {
"type": "BLOCKS",
"iconTextureData": "allium.png",
"group": "GROUP_FLOWER",
"blockId": "allium"
}
}
}
================================================
FILE: blocks/furnitures/flowers/azure_bluet.json
================================================
{
"block": {
"azure_bluet": {
"textureData": "azure_bluet.png",
"color": [ 225, 225, 225 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_PLANT_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 10,
"slipperiness": 1.0,
"isKilledByLava": true,
"isFragile": true,
"isDestroyByWeapon": false,
"soundGroupId": "grass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 188, 188, 188 ],
"animation": [
{
"animationId": 0,
"shake": true,
"shakeCenterX": 8,
"shakeCenterY": 16,
"shakePeriod": 128,
"shakeAngle": 0.2
}
]
}
},
"item": {
"azure_bluet": {
"type": "BLOCKS",
"iconTextureData": "azure_bluet.png",
"group": "GROUP_FLOWER",
"blockId": "azure_bluet"
}
}
}
================================================
FILE: blocks/furnitures/flowers/blue_orchid.json
================================================
{
"block": {
"blue_orchid": {
"textureData": "blue_orchid.png",
"color": [ 47, 177, 233 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_PLANT_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 10,
"slipperiness": 1.0,
"isKilledByLava": true,
"isFragile": true,
"isDestroyByWeapon": false,
"soundGroupId": "grass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 50, 180, 230 ],
"animation": [
{
"animationId": 0,
"shake": true,
"shakeCenterX": 8,
"shakeCenterY": 16,
"shakePeriod": 128,
"shakeAngle": 0.2
}
]
}
},
"item": {
"blue_orchid": {
"type": "BLOCKS",
"iconTextureData": "blue_orchid.png",
"group": "GROUP_FLOWER",
"blockId": "blue_orchid"
}
}
}
================================================
FILE: blocks/furnitures/flowers/dandelion.json
================================================
{
"block": {
"dandelion": {
"textureData": "dandelion.png",
"color": [ 240, 210, 17 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_PLANT_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 10,
"slipperiness": 1.0,
"isKilledByLava": true,
"isFragile": true,
"isDestroyByWeapon": false,
"soundId": "grass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 255, 233, 24 ],
"animation": [
{
"animationId": 0,
"shake": true,
"shakeCenterX": 8,
"shakeCenterY": 16,
"shakePeriod": 128,
"shakeAngle": 0.2
}
]
}
},
"item": {
"dandelion": {
"type": "BLOCKS",
"iconTextureData": "dandelion.png",
"group": "GROUP_FLOWER",
"blockId": "dandelion"
}
}
}
================================================
FILE: blocks/furnitures/flowers/fern.json
================================================
{
"block": {
"fern": {
"textureData": "fern.png",
"color": [ 60, 90, 50 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_PLANT_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 10,
"slipperiness": 1.0,
"isKilledByLava": true,
"isFragile": true,
"isDestroyByWeapon": false,
"soundGroupId": "grass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 66, 99, 55 ],
"animation": [
{
"animationId": 0,
"shake": true,
"shakeCenterX": 8,
"shakeCenterY": 16,
"shakePeriod": 128,
"shakeAngle": 0.2
}
]
}
},
"item": {
"fern": {
"type": "BLOCKS",
"iconTextureData": "fern.png",
"group": "GROUP_GRASS",
"blockId": "fern",
"fuelTime": 20
}
}
}
================================================
FILE: blocks/furnitures/flowers/lilac.json
================================================
{
"block": {
"lilac": {
"textureData": "lilac.png",
"color": [ 137, 93, 148 ],
"type": "FURNITURE",
"width": 2,
"height": 4,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_PLANT_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 80,
"slipperiness": 1.0,
"isKilledByLava": true,
"isFragile": true,
"soundGroupId": "grass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 140, 100, 140 ],
"animation": [
{
"animationId": 0,
"shake": true,
"shakeCenterX": 16,
"shakeCenterY": 64,
"shakePeriod": 128,
"shakeAngle": 0.05
}
]
}
},
"item": {
"lilac": {
"type": "BLOCKS",
"iconTextureData": "lilac.png",
"group": "GROUP_LARGE_FLOWER",
"blockId": "lilac"
}
}
}
================================================
FILE: blocks/furnitures/flowers/orange_tulip.json
================================================
{
"block": {
"orange_tulip": {
"textureData": "orange_tulip.png",
"color": [ 238, 144, 18 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_PLANT_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 10,
"slipperiness": 1.0,
"isDestroyByWeapon": false,
"isKilledByLava": true,
"isFragile": true,
"soundGroupId": "grass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 233, 144, 17 ],
"animation": [
{
"animationId": 0,
"shake": true,
"shakeCenterX": 8,
"shakeCenterY": 16,
"shakePeriod": 128,
"shakeAngle": 0.2
}
]
}
},
"item": {
"orange_tulip": {
"type": "BLOCKS",
"iconTextureData": "orange_tulip.png",
"group": "GROUP_FLOWER",
"blockId": "orange_tulip"
}
}
}
================================================
FILE: blocks/furnitures/flowers/peony.json
================================================
{
"block": {
"peony": {
"textureData": "peony.png",
"color": [ 227, 180, 255 ],
"type": "FURNITURE",
"width": 2,
"height": 4,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_PLANT_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 80,
"slipperiness": 1.0,
"isKilledByLava": true,
"isFragile": true,
"soundGroupId": "grass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 222, 180, 255 ],
"animation": [
{
"animationId": 0,
"shake": true,
"shakeCenterX": 16,
"shakeCenterY": 64,
"shakePeriod": 128,
"shakeAngle": 0.05
}
]
}
},
"item": {
"peony": {
"type": "BLOCKS",
"iconTextureData": "peony.png",
"group": "GROUP_LARGE_FLOWER",
"blockId": "peony"
}
}
}
================================================
FILE: blocks/furnitures/flowers/pink_tulip.json
================================================
{
"block": {
"pink_tulip": {
"textureData": "pink_tulip.png",
"color": [ 214, 171, 218 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_PLANT_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 10,
"slipperiness": 1.0,
"isKilledByLava": true,
"isFragile": true,
"isDestroyByWeapon": false,
"soundGroupId": "grass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 222, 190, 222 ],
"animation": [
{
"animationId": 0,
"shake": true,
"shakeCenterX": 8,
"shakeCenterY": 16,
"shakePeriod": 128,
"shakeAngle": 0.2
}
]
}
},
"item": {
"pink_tulip": {
"type": "BLOCKS",
"iconTextureData": "pink_tulip.png",
"group": "GROUP_FLOWER",
"blockId": "pink_tulip"
}
}
}
================================================
FILE: blocks/furnitures/flowers/poppy.json
================================================
{
"block": {
"poppy": {
"textureData": "poppy.png",
"color": [ 220, 6, 6 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_PLANT_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 10,
"slipperiness": 1.0,
"isKilledByLava": true,
"isFragile": true,
"isDestroyByWeapon": false,
"soundGroupId": "grass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 200, 1, 1 ],
"animation": [
{
"animationId": 0,
"shake": true,
"shakeCenterX": 8,
"shakeCenterY": 16,
"shakePeriod": 128,
"shakeAngle": 0.2
}
]
}
},
"item": {
"poppy": {
"type": "BLOCKS",
"iconTextureData": "poppy.png",
"group": "GROUP_FLOWER",
"blockId": "poppy"
}
}
}
================================================
FILE: blocks/furnitures/flowers/red_tulip.json
================================================
{
"block": {
"red_tulip": {
"textureData": "red_tulip.png",
"color": [ 210, 15, 13 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_PLANT_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 10,
"slipperiness": 1.0,
"isKilledByLava": true,
"isFragile": true,
"isDestroyByWeapon": false,
"soundGroupId": "grass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 120, 1, 1 ],
"animation": [
{
"animationId": 0,
"shake": true,
"shakeCenterX": 8,
"shakeCenterY": 16,
"shakePeriod": 128,
"shakeAngle": 0.2
}
]
}
},
"item": {
"red_tulip": {
"type": "BLOCKS",
"iconTextureData": "red_tulip.png",
"group": "GROUP_FLOWER",
"blockId": "red_tulip"
}
}
}
================================================
FILE: blocks/furnitures/flowers/rose_bush.json
================================================
{
"block": {
"rose_bush": {
"textureData": "rose_bush.png",
"color": [ 210, 10, 10 ],
"type": "FURNITURE",
"width": 2,
"height": 4,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_PLANT_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 80,
"slipperiness": 1.0,
"isKilledByLava": true,
"isFragile": true,
"soundGroupId": "grass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 222, 11, 11 ],
"animation": [
{
"animationId": 0,
"shake": true,
"shakeCenterX": 16,
"shakeCenterY": 64,
"shakePeriod": 128,
"shakeAngle": 0.05
}
]
}
},
"item": {
"rose_bush": {
"type": "BLOCKS",
"iconTextureData": "rose_bush.png",
"group": "GROUP_LARGE_FLOWER",
"blockId": "rose_bush"
}
}
}
================================================
FILE: blocks/furnitures/flowers/sunflower.json
================================================
{
"block": {
"sunflower": {
"textureData": "sunflower.png",
"color": [ 135, 226, 55 ],
"type": "FURNITURE",
"width": 2,
"height": 4,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_PLANT_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 80,
"slipperiness": 1.0,
"isKilledByLava": true,
"isFragile": true,
"soundGroupId": "grass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 233, 233, 55 ],
"animation": [
{
"animationId": 0,
"shake": true,
"shakeCenterX": 16,
"shakeCenterY": 64,
"shakePeriod": 128,
"shakeAngle": 0.05
}
]
}
},
"item": {
"sunflower": {
"type": "BLOCKS",
"iconTextureData": "sunflower.png",
"group": "GROUP_LARGE_FLOWER",
"blockId": "sunflower"
}
}
}
================================================
FILE: blocks/furnitures/flowers/white_tulip.json
================================================
{
"block": {
"white_tulip": {
"textureData": "white_tulip.png",
"color": [ 222, 222, 222 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_PLANT_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 10,
"slipperiness": 1.0,
"isKilledByLava": true,
"isFragile": true,
"isDestroyByWeapon": false,
"soundGroupId": "grass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 222, 222, 222 ],
"animation": [
{
"animationId": 0,
"shake": true,
"shakeCenterX": 8,
"shakeCenterY": 16,
"shakePeriod": 128,
"shakeAngle": 0.2
}
]
}
},
"item": {
"white_tulip": {
"type": "BLOCKS",
"iconTextureData": "white_tulip.png",
"group": "GROUP_FLOWER",
"blockId": "white_tulip"
}
}
}
================================================
FILE: blocks/furnitures/grasses/blood_grass.json
================================================
{
"block": {
"blood_grass": {
"textureData": "blood_grass.png",
"color": [ 80, 20, 20 ],
"type": "FURNITURE",
"width": 1,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_PLANT_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 10,
"slipperiness": 1.0,
"isKilledByLava": true,
"isFragile": true,
"isDestroyByWeapon": false,
"isLossyCollection": true,
"soundId": "grass",
"stepSoundId": "grass",
"particleColor": [ 255, 80, 20, 20 ],
"preset": "Grass",
"animation": [
{
"animationId": 0,
"frameRandom": true,
"frameStart": 0,
"frameCount": 6,
"shake": true,
"shakeCenterX": 8,
"shakeCenterY": 32,
"shakePeriod": 128,
"shakeAngle": 0.2
}
]
}
}
}
================================================
FILE: blocks/furnitures/grasses/eyeball_grass.json
================================================
{
"block": {
"eyeball_grass": {
"textureData": "eyeball_grass.png",
"color": [ 238, 178, 198 ],
"type": "FURNITURE",
"width": 2,
"height": 4,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_PLANT_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 80,
"slipperiness": 1.0,
"isKilledByLava": true,
"isFragile": true,
"soundGroupId": "grass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 238, 178, 198 ],
"animation": [
{
"animationId": 0,
"shake": true,
"shakeCenterX": 16,
"shakeCenterY": 64,
"shakePeriod": 128,
"shakeAngle": 0.05
}
]
}
}
}
================================================
FILE: blocks/furnitures/grasses/grass.json
================================================
{
"block": {
"grass": {
"textureData": "grass.png",
"color": [ 110, 162, 63 ],
"type": "FURNITURE",
"width": 1,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_PLANT_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 10,
"slipperiness": 1.0,
"isKilledByLava": true,
"isFragile": true,
"isDestroyByWeapon": false,
"isLossyCollection": true,
"soundId": "grass",
"stepSoundId": "grass",
"particleColor": [ 255, 100, 150, 60 ],
"preset": "Grass",
"animation": [
{
"animationId": 0,
"frameRandom": true,
"frameStart": 0,
"frameCount": 6,
"shake": true,
"shakeCenterX": 8,
"shakeCenterY": 32,
"shakePeriod": 128,
"shakeAngle": 0.2
}
]
}
},
"item": {
"grass": {
"type": "BLOCKS",
"iconTextureData": "grass_icon.png",
"group": "GROUP_GRASS",
"blockId": "grass",
"fuelTime": 20
}
}
}
================================================
FILE: blocks/furnitures/grasses/large_eyeball_grass.json
================================================
{
"block": {
"large_eyeball_grass": {
"textureData": "large_eyeball_grass.png",
"color": [ 238, 178, 198 ],
"type": "FURNITURE",
"width": 2,
"height": 4,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_PLANT_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 80,
"slipperiness": 1.0,
"isKilledByLava": true,
"isFragile": true,
"soundGroupId": "grass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 238, 178, 198 ],
"animation": [
{
"animationId": 0,
"shake": true,
"shakeCenterX": 16,
"shakeCenterY": 64,
"shakePeriod": 128,
"shakeAngle": 0.05
}
]
}
}
}
================================================
FILE: blocks/furnitures/grasses/tainted_grass.json
================================================
{
"block": {
"tainted_grass": {
"textureData": "tainted_grass.png",
"color": [ 120, 60, 190 ],
"type": "FURNITURE",
"width": 1,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_TAINTED_DECO_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 10,
"slipperiness": 1.0,
"isKilledByLava": true,
"isFragile": true,
"isDestroyByWeapon": false,
"isLossyCollection": true,
"soundId": "grass",
"stepSoundId": "grass",
"particleColor": [ 255, 120, 60, 190 ],
"preset": "Grass",
"animation": [
{
"animationId": 0,
"frameRandom": true,
"frameStart": 0,
"frameCount": 6,
"shake": true,
"shakeCenterX": 8,
"shakeCenterY": 32,
"shakePeriod": 128,
"shakeAngle": 0.2
}
]
}
}
}
================================================
FILE: blocks/furnitures/lightings/candle.json
================================================
{
"block": {
"candle": {
"textureData": "candle.png",
"color": [ 255, 166, 77 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 20,
"isKilledByLava": true,
"isFragile": true,
"isLighting": true,
"lightColor": [ 24, 2, 2, 0 ],
"lightX": 0,
"lightY": 0,
"lightWi": 1,
"lightHi": 1,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 255, 155, 40 ],
"covers": [
{
"modTextureId": "candle_fire",
"offsetX": 0,
"offsetY": -12
}
]
}
},
"item": {
"candle": {
"type": "BLOCKS",
"iconTextureData": "candle.png",
"group": "GROUP_OTHERS_FURNITURE",
"blockId": "candle"
}
}
}
================================================
FILE: blocks/furnitures/lightings/candle_holder.json
================================================
{
"block": {
"candle_holder": {
"textureData": "candle_holder.png",
"color": [ 255, 168, 77 ],
"type": "FURNITURE",
"width": 2,
"height": 3,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 20,
"isKilledByLava": true,
"isFragile": true,
"isLighting": true,
"lightColor": [ 26, 4, 4, 0 ],
"lightX": 0,
"lightY": 0,
"lightWi": 3,
"lightHi": 1,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 50, 70, 80 ],
"covers": [
{
"modTextureId": "candle_fire",
"offsetX": 8,
"offsetY": -10
},
{
"modTextureId": "candle_fire",
"offsetX": -4,
"offsetY": -2
},
{
"modTextureId": "candle_fire",
"offsetX": 20,
"offsetY": -2
}
]
}
},
"item": {
"candle_holder": {
"type": "BLOCKS",
"iconTextureData": "candle_holder.png",
"group": "GROUP_OTHERS_FURNITURE",
"blockId": "candle_holder"
}
}
}
================================================
FILE: blocks/furnitures/lightings/chandeliers.json
================================================
{
"block": {
"chandeliers": {
"textureData": "chandeliers.png",
"color": [ 141, 225, 203 ],
"type": "FURNITURE",
"width": 3,
"height": 3,
"collision": "NONE",
"attach": "TOP",
"attachable": "NONE",
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 20,
"isKilledByLava": true,
"isFragile": true,
"isLighting": true,
"lightColor": [ 28, 8, 8, 8 ],
"lightX": 0,
"lightY": 2,
"lightWi": 2,
"lightHi": 1,
"soundGroupId": "glass",
"stepSoundId": "step_cloth",
"particleColor": [ 255, 222, 22, 222 ],
"animation": [
{
"animationId": 0,
"shake": true,
"shakeCenterX": 24,
"shakeCenterY": 0,
"shakePeriod": 128,
"shakeAngle": 0.05
}
]
}
},
"item": {
"chandeliers": {
"type": "BLOCKS",
"iconTextureData": "chandeliers.png",
"group": "GROUP_OTHERS_FURNITURE",
"blockId": "chandeliers"
}
}
}
================================================
FILE: blocks/furnitures/lightings/fire_lamp.json
================================================
{
"block": {
"fire_lamp": {
"textureData": "fire_lamp.png",
"color": [ 128, 100, 60 ],
"type": "FURNITURE",
"width": 3,
"height": 3,
"collision": "NONE",
"attach": "TOP",
"attachable": "NONE",
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 20,
"isKilledByLava": true,
"isFragile": true,
"isLighting": true,
"lightColor": [ 28, 8, 8, 0 ],
"lightX": 0,
"lightY": 2,
"lightWi": 3,
"lightHi": 1,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 180, 150, 100 ],
"animation": [
{
"animationId": 0,
"frameSpeed": 8,
"frameStart": 0,
"frameCount": 4,
"shake": true,
"shakeCenterX": 24,
"shakeCenterY": 0,
"shakePeriod": 128,
"shakeAngle": 0.05
}
]
}
},
"item": {
"fire_lamp": {
"type": "BLOCKS",
"iconTextureData": "fire_lamp_icon.png",
"group": "GROUP_OTHERS_FURNITURE",
"blockId": "fire_lamp"
}
}
}
================================================
FILE: blocks/furnitures/lightings/jack_o_lantern.json
================================================
{
"block": {
"jack_o_lantern": {
"textureData": "jack_o_lantern.png",
"color": [ 205, 123, 12 ],
"type": "FURNITURE",
"width": 2,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_PLANT_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"lightOpacity": 3,
"isLighting": true,
"lightColor": [ 32, 0, 0, 0 ],
"lightX": 0,
"lightY": 0,
"lightWi": 2,
"lightHi": 2,
"hardness": 10,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 200, 123, 13 ]
}
},
"item": {
"jack_o_lantern": {
"type": "BLOCKS",
"iconTextureData": "jack_o_lantern.png",
"group": "GROUP_SAPLING",
"blockId": "jack_o_lantern"
}
}
}
================================================
FILE: blocks/furnitures/lightings/lantern.json
================================================
{
"block": {
"lantern": {
"textureData": "lantern.png",
"color": [ 225, 225, 160 ],
"type": "FURNITURE",
"width": 1,
"height": 2,
"collision": "NONE",
"attach": "TOP",
"attachable": "NONE",
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 20,
"isKilledByLava": true,
"isNoWater": false,
"isFragile": true,
"isLighting": true,
"lightColor": [ 32, 0, 0, 0 ],
"lightX": 0,
"lightY": 1,
"lightWi": 1,
"lightHi": 1,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 225, 225, 160 ],
"animation": [
{
"animationId": 0,
"shake": true,
"shakeCenterX": 8,
"shakeCenterY": 0,
"shakePeriod": 128,
"shakeAngle": 0.05
}
]
}
},
"item": {
"lantern": {
"type": "BLOCKS",
"iconTextureData": "lantern.png",
"group": "GROUP_OTHERS_FURNITURE",
"blockId": "lantern"
}
}
}
================================================
FILE: blocks/furnitures/lightings/nether_lamp.json
================================================
{
"block": {
"nether_lamp": {
"textureData": "nether_lamp.png",
"color": [ 73, 29, 34 ],
"type": "FURNITURE",
"width": 3,
"height": 3,
"collision": "NONE",
"attach": "TOP",
"attachable": "NONE",
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 20,
"isKilledByLava": true,
"isFragile": true,
"isLighting": true,
"lightColor": [ 28, 8, 8, 0 ],
"lightX": 0,
"lightY": 2,
"lightWi": 3,
"lightHi": 1,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 73, 29, 34 ],
"animation": [
{
"animationId": 0,
"frameSpeed": 8,
"frameStart": 0,
"frameCount": 4,
"shake": true,
"shakeCenterX": 24,
"shakeCenterY": 0,
"shakePeriod": 128,
"shakeAngle": 0.05
}
]
}
},
"item": {
"nether_lamp": {
"type": "BLOCKS",
"iconTextureData": "nether_lamp_icon.png",
"group": "GROUP_OTHERS_FURNITURE",
"blockId": "nether_lamp"
}
}
}
================================================
FILE: blocks/furnitures/misc/anvil.json
================================================
{
"block": {
"anvil": {
"textureData": "anvil.png",
"color": [ 55, 55, 55 ],
"type": "FURNITURE",
"width": 3,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "PICKAXE",
"mineGrade": "STONE",
"hardness": 200,
"slipperiness": 1.0,
"placeSoundId": "anvil_land",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 100, 100, 100 ],
"preset": "Anvil"
}
},
"item": {
"anvil": {
"type": "BLOCKS",
"iconTextureData": "anvil.png",
"group": "GROUP_OTHERS_FURNITURE",
"blockId": "anvil"
}
}
}
================================================
FILE: blocks/furnitures/misc/book.json
================================================
{
"block": {
"book": {
"textureData": "book.png",
"color": [ 177, 177, 55 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 40,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 140, 140, 50 ],
"animation": [
{
"animationId": 0,
"frameRandom": true,
"frameStart": 0,
"frameCount": 4
}
]
}
},
"item": {
"book_block": {
"type": "BLOCKS",
"iconTextureData": "book_icon.png",
"group": "GROUP_OTHERS_FURNITURE",
"blockId": "book",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/misc/brewing_stand.json
================================================
{
"block": {
"brewing_stand": {
"textureData": "brewing_stand.png",
"color": [ 44, 44, 44 ],
"type": "FURNITURE",
"width": 3,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 60,
"slipperiness": 1.0,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 90, 80, 40 ],
"preset": "Brewing"
}
},
"item": {
"brewing_stand": {
"type": "BLOCKS",
"iconTextureData": "brewing_stand.png",
"group": "GROUP_OTHERS_FURNITURE",
"blockId": "brewing_stand"
}
}
}
================================================
FILE: blocks/furnitures/misc/cake.json
================================================
{
"block": {
"cake": {
"textureData": "cake.png",
"color": [ 244, 244, 244 ],
"type": "FURNITURE",
"width": 2,
"height": 1,
"collision": "PLATFORM",
"attach": "BOTTOM",
"attachable": "TOP",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 30,
"slipperiness": 1.0,
"isKilledByLava": true,
"isFragile": true,
"isLossyCollection": true,
"soundGroupId": "cloth",
"stepSoundId": "step_cloth",
"particleColor": [ 255, 90, 50, 10 ],
"preset": "Cake",
"animation": [
{
"animationId": 0,
"tagUsage": "TAG_ADD_FRAME_INDEX_Y"
}
]
}
},
"item": {
"cake": {
"type": "BLOCKS",
"iconTextureData": "cake_icon.png",
"group": "GROUP_OTHERS_FURNITURE",
"blockId": "cake"
}
}
}
================================================
FILE: blocks/furnitures/misc/campfire.json
================================================
{
"block": {
"campfire": {
"textureData": "campfire.png",
"color": [ 249, 235, 170 ],
"type": "FURNITURE",
"width": 2,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 20,
"isKilledByLava": true,
"isNoWater": true,
"isFragile": true,
"isLighting": true,
"lightColor": [ 32, 8, 8, 0 ],
"lightX": 0,
"lightY": 0,
"lightWi": 2,
"lightHi": 2,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 249, 235, 170 ],
"exParticle": "campfire_particle",
"animation": [
{
"animationId": 0,
"frameSpeed": 8,
"frameStart": 0,
"frameCount": 4
}
]
}
},
"item": {
"campfire": {
"type": "BLOCKS",
"iconTextureData": "campfire_icon.png",
"group": "GROUP_WOODEN_FURNITURE",
"blockId": "campfire"
}
}
}
================================================
FILE: blocks/furnitures/misc/cauldron.json
================================================
{
"block": {
"cauldron": {
"textureData": "cauldron.png",
"color": [ 77, 77, 77 ],
"type": "FURNITURE",
"width": 2,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "PICKAXE",
"mineGrade": "STONE",
"hardness": 200,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 100, 100, 100 ]
}
},
"item": {
"cauldron": {
"type": "BLOCKS",
"iconTextureData": "cauldron.png",
"group": "GROUP_OTHERS_FURNITURE",
"blockId": "cauldron"
}
}
}
================================================
FILE: blocks/furnitures/misc/cobweb.json
================================================
{
"block": {
"cobweb": {
"textureData": "cobweb.png",
"color": [ 188, 188, 188 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "ALL",
"attachable": "ALL",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 30,
"isKilledByLava": true,
"isNoWater": true,
"isFragile": true,
"isDestroyByWeapon": true,
"slipperiness": 1.0,
"isActAsTile": true,
"soundId": "grass",
"stepSoundId": "grass",
"particleColor": [ 255, 222, 222, 222 ],
"preset": "Cobweb"
}
},
"item": {
"cobweb": {
"type": "BLOCKS",
"iconTextureData": "cobweb_icon.png",
"group": "GROUP_OTHERS_FURNITURE",
"blockId": "cobweb"
}
}
}
================================================
FILE: blocks/furnitures/misc/crafting_table.json
================================================
{
"block": {
"crafting_table": {
"textureData": "crafting_table.png",
"color": [ 159, 132, 77 ],
"type": "FURNITURE",
"width": 3,
"height": 2,
"collision": "PLATFORM",
"attach": "BOTTOM",
"attachable": "TOP",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 140,
"slipperiness": 1.0,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 160, 130, 80 ],
"preset": "CraftingTable"
}
},
"item": {
"crafting_table": {
"type": "BLOCKS",
"iconTextureData": "crafting_table.png",
"group": "GROUP_WOODEN_FURNITURE",
"blockId": "crafting_table",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/misc/enchantment_table.json
================================================
{
"block": {
"enchantment_table": {
"textureData": "enchantment_table.png",
"type": "FURNITURE",
"width": 3,
"height": 2,
"collision": "PLATFORM",
"attach": "BOTTOM",
"attachable": "TOP",
"toolType": "PICKAXE",
"mineGrade": "DIAMOND",
"hardness": 500,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 76, 76, 155 ],
"preset": "Enchantment"
}
},
"item": {
"enchantment_table": {
"type": "BLOCKS",
"iconTextureData": "enchantment_table.png",
"group": "GROUP_OTHERS_FURNITURE",
"blockId": "enchantment_table"
}
}
}
================================================
FILE: blocks/furnitures/misc/flower_pot.json
================================================
{
"block": {
"flower_pot": {
"textureData": "flower_pot.png",
"color": [ 121, 67, 50 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "PLATFORM",
"attach": "BOTTOM",
"attachable": "TOP",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 60,
"slipperiness": 1.0,
"isKilledByLava": true,
"isFragile": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 121, 67, 50 ]
}
},
"item": {
"flower_pot": {
"type": "BLOCKS",
"iconTextureData": "flower_pot.png",
"group": "GROUP_OTHERS_FURNITURE",
"blockId": "flower_pot"
}
}
}
================================================
FILE: blocks/furnitures/misc/flower_pot_large.json
================================================
{
"block": {
"flower_pot_large": {
"textureData": "flower_pot_large.png",
"color": [ 121, 67, 50 ],
"type": "FURNITURE",
"width": 2,
"height": 2,
"collision": "PLATFORM",
"attach": "BOTTOM",
"attachable": "TOP",
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 60,
"slipperiness": 1.0,
"isKilledByLava": true,
"isFragile": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 121, 67, 50 ]
}
},
"item": {
"flower_pot_large": {
"type": "BLOCKS",
"iconTextureData": "flower_pot_large.png",
"group": "GROUP_OTHERS_FURNITURE",
"blockId": "flower_pot_large"
}
}
}
================================================
FILE: blocks/furnitures/misc/furnace.json
================================================
{
"block": {
"furnace": {
"textureData": "furnace.png",
"color": [ 133, 133, 133 ],
"type": "FURNITURE",
"width": 3,
"height": 2,
"collision": "PLATFORM",
"attach": "BOTTOM",
"attachable": "TOP",
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 200,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 100, 100, 100 ],
"exParticle": "furnace_particle",
"preset": "Furnace",
"animation": [
{
"animationId": 0,
"frameStart": 0
},
{
"animationId": 1,
"frameStart": 1
}
]
}
},
"item": {
"furnace": {
"type": "BLOCKS",
"iconTextureData": "furnace_icon.png",
"group": "GROUP_STONE_FURNITURE",
"blockId": "furnace"
}
}
}
================================================
FILE: blocks/furnitures/misc/health_crystal.json
================================================
{
"block": {
"health_crystal": {
"textureData": "health_crystal.png",
"color": [ 166, 0, 0 ],
"type": "FURNITURE",
"width": 2,
"height": 2,
"collision": "NONE",
"attach": "NONE",
"attachable": "NONE",
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 200,
"slipperiness": 1.0,
"soundGroupId": "glass",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 166, 0, 0 ],
"preset": "HeartCrystal"
}
},
"item": {
"health_crystal": {
"type": "MATERIALS",
"iconTextureData": "health_crystal.png",
"group": "GROUP_OTHERS_FURNITURE"
}
}
}
================================================
FILE: blocks/furnitures/misc/jukebox.json
================================================
{
"block": {
"jukebox": {
"textureData": "jukebox.png",
"color": [ 222, 100, 62 ],
"type": "FURNITURE",
"width": 3,
"height": 3,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 120,
"slipperiness": 1.0,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 200, 100, 60 ]
}
},
"item": {
"jukebox": {
"type": "MATERIALS",
"iconTextureData": "jukebox.png",
"group": "GROUP_OTHERS_FURNITURE",
"onTest": true
}
}
}
================================================
FILE: blocks/furnitures/misc/pot.json
================================================
{
"block": {
"pot": {
"textureData": "pot.png",
"color": [ 119, 85, 75 ],
"type": "FURNITURE",
"width": 2,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 10,
"slipperiness": 1.0,
"isKilledByLava": true,
"isFragile": true,
"isLossyCollection": true,
"isDestroyByWeapon": true,
"soundGroupId": "shatter",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 150, 110, 100 ],
"preset": "Pot"
}
}
}
================================================
FILE: blocks/furnitures/misc/potion.json
================================================
{
"block": {
"potion": {
"textureData": "potion.png",
"color": [ 66, 66, 255 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 10,
"slipperiness": 1.0,
"isKilledByLava": true,
"isFragile": true,
"soundGroupId": "glass",
"particleColor": [ 255, 55, 55, 255 ]
}
}
}
================================================
FILE: blocks/furnitures/misc/sign.json
================================================
{
"block": {
"sign": {
"textureData": "sign.png",
"color": [ 170, 133, 78 ],
"type": "FURNITURE",
"width": 2,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 60,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 100, 100, 40 ]
}
},
"item": {
"sign": {
"type": "MATERIALS",
"iconTextureData": "sign_icon.png",
"group": "GROUP_WOODEN_FURNITURE",
"fuelTime": 60,
"onTest": true
}
}
}
================================================
FILE: blocks/furnitures/misc/skull.json
================================================
{
"block": {
"skull": {
"textureData": "skull.png",
"color": [ 125, 188, 66 ],
"type": "FURNITURE",
"width": 2,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 10,
"slipperiness": 1.0,
"isFragile": true,
"isLossyCollection": true,
"isDestroyByWeapon": true,
"soundGroupId": "glass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 244, 177, 144 ],
"preset": "RandomDisplay"
}
}
}
================================================
FILE: blocks/furnitures/misc/thorn.json
================================================
{
"block": {
"thorn": {
"textureData": "thorn.png",
"color": [ 111, 111, 111 ],
"renderMode": "RENDER_PIPE",
"type": "TILE",
"group": "THRON",
"collision": "SOLID",
"lightOpacity": 3,
"lightTransparent": true,
"toolType": "PICKAXE",
"mineGrade": "DIAMOND",
"hardness": 500000,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 111, 111, 111 ]
}
}
}
================================================
FILE: blocks/furnitures/mushrooms/brown_mushroom.json
================================================
{
"block": {
"brown_mushroom": {
"textureData": "brown_mushroom.png",
"color": [ 157, 120, 72 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_MUSHROOM_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 10,
"slipperiness": 1.0,
"isKilledByLava": true,
"isFragile": true,
"isDestroyByWeapon": false,
"soundGroupId": "grass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 170, 140, 80 ],
"animation": [
{
"animationId": 0,
"shake": true,
"shakeCenterX": 8,
"shakeCenterY": 16,
"shakePeriod": 128,
"shakeAngle": 0.2
}
]
}
},
"item": {
"brown_mushroom": {
"type": "BLOCKS",
"iconTextureData": "brown_mushroom.png",
"group": "GROUP_OTHERS_FURNITURE",
"blockId": "brown_mushroom"
}
}
}
================================================
FILE: blocks/furnitures/mushrooms/glowing_mushroom.json
================================================
{
"block": {
"glowing_mushroom": {
"textureData": "glowing_mushroom.png",
"color": [ 222, 222, 0 ],
"type": "FURNITURE",
"width": 1,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_MUSHROOM_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 20,
"slipperiness": 1.0,
"isKilledByLava": true,
"isLighting": true,
"lightColor": [ 12, 4, 4, 0 ],
"lightX": 0,
"lightY": 0,
"lightWi": 1,
"lightHi": 2,
"soundGroupId": "grass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 200, 200, 10 ],
"animation": [
{
"animationId": 0,
"shake": true,
"shakeCenterX": 8,
"shakeCenterY": 32,
"shakePeriod": 128,
"shakeAngle": 0.05
}
]
}
},
"item": {
"glowing_mushroom": {
"type": "BLOCKS",
"iconTextureData": "glowing_mushroom.png",
"group": "GROUP_OTHERS_FURNITURE",
"blockId": "glowing_mushroom"
}
}
}
================================================
FILE: blocks/furnitures/mushrooms/large_brown_mushroom.json
================================================
{
"block": {
"large_brown_mushroom": {
"textureData": "large_brown_mushroom.png",
"color": [ 159, 120, 72 ],
"type": "FURNITURE",
"width": 2,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_MUSHROOM_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 20,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "grass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 155, 120, 72 ],
"animation": [
{
"animationId": 0,
"shake": true,
"shakeCenterX": 16,
"shakeCenterY": 32,
"shakePeriod": 128,
"shakeAngle": 0.05
}
]
}
},
"item": {
"large_brown_mushroom": {
"type": "BLOCKS",
"iconTextureData": "large_brown_mushroom.png",
"group": "GROUP_OTHERS_FURNITURE",
"blockId": "large_brown_mushroom"
}
}
}
================================================
FILE: blocks/furnitures/mushrooms/large_poison_mushroom.json
================================================
{
"block": {
"large_poison_mushroom": {
"textureData": "large_poison_mushroom.png",
"color": [ 144, 96, 160 ],
"type": "FURNITURE",
"width": 2,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_MUSHROOM_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 20,
"slipperiness": 1.0,
"isKilledByLava": true,
"isLighting": true,
"lightColor": [ 10, 6, 0, 6 ],
"lightX": 0,
"lightY": 0,
"lightWi": 2,
"lightHi": 2,
"soundGroupId": "grass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 140, 100, 160 ],
"animation": [
{
"animationId": 0,
"shake": true,
"shakeCenterX": 16,
"shakeCenterY": 32,
"shakePeriod": 128,
"shakeAngle": 0.05
}
]
}
},
"item": {
"large_poison_mushroom": {
"type": "BLOCKS",
"iconTextureData": "large_poison_mushroom.png",
"group": "GROUP_OTHERS_FURNITURE",
"blockId": "large_poison_mushroom"
}
}
}
================================================
FILE: blocks/furnitures/mushrooms/large_red_mushroom.json
================================================
{
"block": {
"large_red_mushroom": {
"textureData": "large_red_mushroom.png",
"color": [ 166, 12, 12 ],
"type": "FURNITURE",
"width": 2,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_MUSHROOM_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 20,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "grass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 200, 10, 10 ],
"animation": [
{
"animationId": 0,
"shake": true,
"shakeCenterX": 16,
"shakeCenterY": 32,
"shakePeriod": 128,
"shakeAngle": 0.05
}
]
}
},
"item": {
"large_red_mushroom": {
"type": "BLOCKS",
"iconTextureData": "large_red_mushroom.png",
"group": "GROUP_OTHERS_FURNITURE",
"blockId": "large_red_mushroom"
}
}
}
================================================
FILE: blocks/furnitures/mushrooms/poison_mushroom.json
================================================
{
"block": {
"poison_mushroom": {
"textureData": "poison_mushroom.png",
"color": [ 144, 96, 160 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_MUSHROOM_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 20,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "grass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 140, 100, 160 ],
"animation": [
{
"animationId": 0,
"shake": true,
"shakeCenterX": 8,
"shakeCenterY": 16,
"shakePeriod": 128,
"shakeAngle": 0.2
}
]
}
},
"item": {
"poison_mushroom": {
"type": "BLOCKS",
"iconTextureData": "poison_mushroom.png",
"group": "GROUP_OTHERS_FURNITURE",
"blockId": "poison_mushroom"
}
}
}
================================================
FILE: blocks/furnitures/mushrooms/red_mushroom.json
================================================
{
"block": {
"red_mushroom": {
"textureData": "red_mushroom.png",
"color": [ 180, 12, 12 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_MUSHROOM_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 10,
"slipperiness": 1.0,
"isKilledByLava": true,
"isFragile": true,
"isDestroyByWeapon": false,
"soundGroupId": "grass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 170, 10, 10 ],
"animation": [
{
"animationId": 0,
"shake": true,
"shakeCenterX": 8,
"shakeCenterY": 16,
"shakePeriod": 128,
"shakeAngle": 0.2
}
]
}
},
"item": {
"red_mushroom": {
"type": "BLOCKS",
"iconTextureData": "red_mushroom.png",
"group": "GROUP_OTHERS_FURNITURE",
"blockId": "red_mushroom"
}
}
}
================================================
FILE: blocks/furnitures/paintings/painting.json
================================================
{
"block": {
"painting": {
"textureData": "painting.png",
"color": [ 159, 132, 77 ],
"type": "FURNITURE",
"width": 3,
"height": 2,
"collision": "NONE",
"attach": "WALL",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 60,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 180, 150, 100 ]
}
}
}
================================================
FILE: blocks/furnitures/paintings/painting_2x2.json
================================================
{
"block": {
"painting_2x2": {
"textureData": "painting_2x2.png",
"color": [ 255, 0, 255 ],
"type": "FURNITURE",
"width": 2,
"height": 2,
"collision": "NONE",
"attach": "WALL",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 20,
"isKilledByLava": true,
"isNoWater": true,
"isFragile": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 255, 0, 255 ],
"preset": "Painting",
"maxTag": 7,
"animation": [
{
"animationId": 0,
"tagUsage": "TAG_ADD_FRAME_INDEX_X"
}
]
}
},
"item": {
"painting_2x2": {
"type": "BLOCKS",
"iconTextureData": "painting_2x2_icon.png",
"group": "GROUP_PAINTING",
"blockId": "painting_2x2",
"fuelTime": 20
}
}
}
================================================
FILE: blocks/furnitures/paintings/painting_2x4.json
================================================
{
"block": {
"painting_2x4": {
"textureData": "painting_2x4.png",
"color": [ 255, 0, 255 ],
"type": "FURNITURE",
"width": 2,
"height": 4,
"collision": "NONE",
"attach": "WALL",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 20,
"isKilledByLava": true,
"isNoWater": true,
"isFragile": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 255, 0, 255 ],
"preset": "Painting",
"maxTag": 2,
"animation": [
{
"animationId": 0,
"tagUsage": "TAG_ADD_FRAME_INDEX_X"
}
]
}
},
"item": {
"painting_2x4": {
"type": "BLOCKS",
"iconTextureData": "painting_2x4_icon.png",
"group": "GROUP_PAINTING",
"blockId": "painting_2x4",
"fuelTime": 20
}
}
}
================================================
FILE: blocks/furnitures/paintings/painting_4x2.json
================================================
{
"block": {
"painting_4x2": {
"textureData": "painting_4x2.png",
"color": [ 255, 0, 255 ],
"type": "FURNITURE",
"width": 4,
"height": 2,
"collision": "NONE",
"attach": "WALL",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 20,
"isKilledByLava": true,
"isNoWater": true,
"isFragile": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 255, 0, 255 ],
"preset": "Painting",
"maxTag": 5,
"animation": [
{
"animationId": 0,
"tagUsage": "TAG_ADD_FRAME_INDEX_X"
}
]
}
},
"item": {
"painting_4x2": {
"type": "BLOCKS",
"iconTextureData": "painting_4x2_icon.png",
"group": "GROUP_PAINTING",
"blockId": "painting_4x2",
"fuelTime": 20
}
}
}
================================================
FILE: blocks/furnitures/paintings/painting_4x4.json
================================================
{
"block": {
"painting_4x4": {
"textureData": "painting_4x4.png",
"color": [ 255, 0, 255 ],
"type": "FURNITURE",
"width": 4,
"height": 4,
"collision": "NONE",
"attach": "WALL",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 20,
"isKilledByLava": true,
"isNoWater": true,
"isFragile": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 255, 0, 255 ],
"preset": "Painting",
"maxTag": 6,
"animation": [
{
"animationId": 0,
"tagUsage": "TAG_ADD_FRAME_INDEX_X"
}
]
}
},
"item": {
"painting_4x4": {
"type": "BLOCKS",
"iconTextureData": "painting_4x4_icon.png",
"group": "GROUP_PAINTING",
"blockId": "painting_4x4",
"fuelTime": 20
}
}
}
================================================
FILE: blocks/furnitures/paintings/painting_8x4.json
================================================
{
"block": {
"painting_8x4": {
"textureData": "painting_8x4.png",
"color": [ 255, 0, 255 ],
"type": "FURNITURE",
"width": 8,
"height": 4,
"collision": "NONE",
"attach": "WALL",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 20,
"isKilledByLava": true,
"isNoWater": true,
"isFragile": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 255, 0, 255 ],
"preset": "Painting",
"maxTag": 1,
"animation": [
{
"animationId": 0,
"tagUsage": "TAG_ADD_FRAME_INDEX_X"
}
]
}
},
"item": {
"painting_8x4": {
"type": "BLOCKS",
"iconTextureData": "painting_8x4_icon.png",
"group": "GROUP_PAINTING",
"blockId": "painting_8x4",
"fuelTime": 20
}
}
}
================================================
FILE: blocks/furnitures/paintings/painting_8x6.json
================================================
{
"block": {
"painting_8x6": {
"textureData": "painting_8x6.png",
"color": [ 255, 0, 255 ],
"type": "FURNITURE",
"width": 8,
"height": 6,
"collision": "NONE",
"attach": "WALL",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 20,
"isKilledByLava": true,
"isNoWater": true,
"isFragile": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 255, 0, 255 ],
"preset": "Painting",
"maxTag": 1,
"animation": [
{
"animationId": 0,
"tagUsage": "TAG_ADD_FRAME_INDEX_X"
}
]
}
},
"item": {
"painting_8x6": {
"type": "BLOCKS",
"iconTextureData": "painting_8x6_icon.png",
"group": "GROUP_PAINTING",
"blockId": "painting_8x6",
"fuelTime": 20
}
}
}
================================================
FILE: blocks/furnitures/paintings/painting_8x8.json
================================================
{
"block": {
"painting_8x8": {
"textureData": "painting_8x8.png",
"color": [ 255, 0, 255 ],
"type": "FURNITURE",
"width": 8,
"height": 8,
"collision": "NONE",
"attach": "WALL",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 20,
"isKilledByLava": true,
"isNoWater": true,
"isFragile": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 255, 0, 255 ],
"preset": "Painting",
"maxTag": 3,
"animation": [
{
"animationId": 0,
"tagUsage": "TAG_ADD_FRAME_INDEX_X"
}
]
}
},
"item": {
"painting_8x8": {
"type": "BLOCKS",
"iconTextureData": "painting_8x8_icon.png",
"group": "GROUP_PAINTING",
"blockId": "painting_8x8",
"fuelTime": 20
}
}
}
================================================
FILE: blocks/furnitures/plants/bush.json
================================================
{
"block": {
"bush": {
"textureData": "bush.png",
"color": [ 92, 178, 66 ],
"type": "FURNITURE",
"width": 3,
"height": 3,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 120,
"slipperiness": 1.0,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 60, 100, 50 ]
}
}
}
================================================
FILE: blocks/furnitures/redstones/daylight_sensor.json
================================================
{
"block": {
"daylight_sensor": {
"textureData": "daylight_sensor.png",
"color": [ 211, 211, 122 ],
"type": "FURNITURE",
"width": 2,
"height": 1,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"lightOpacity": 3,
"isLighting": true,
"lightColor": [ 6, 0, 0, 0 ],
"lightX": 0,
"lightY": 0,
"lightWi": 2,
"lightHi": 1,
"hardness": 72,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "glass",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 80, 70, 50 ],
"preset": "DaylightTrigger",
"animation": [
{
"animationId": 0,
"tagUsage": "TAG_ADD_FRAME_INDEX_X"
}
]
}
},
"item": {
"daylight_sensor": {
"type": "BLOCKS",
"iconTextureData": "daylight_sensor_icon.png",
"group": "GROUP_OTHERS_FURNITURE",
"blockId": "daylight_sensor"
}
}
}
================================================
FILE: blocks/furnitures/redstones/daylight_sensor_inverted.json
================================================
{
"block": {
"daylight_sensor_inverted": {
"textureData": "daylight_sensor_inverted.png",
"color": [ 200, 210, 220 ],
"type": "FURNITURE",
"width": 2,
"height": 1,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"lightOpacity": 3,
"isLighting": true,
"lightColor": [ 6, 0, 0, 0 ],
"lightX": 0,
"lightY": 0,
"lightWi": 2,
"lightHi": 1,
"hardness": 72,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "glass",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 80, 70, 50 ],
"preset": "MoonlightTrigger",
"animation": [
{
"animationId": 0,
"tagUsage": "TAG_ADD_FRAME_INDEX_X"
}
]
}
},
"item": {
"daylight_sensor_inverted": {
"type": "BLOCKS",
"iconTextureData": "daylight_sensor_inverted_icon.png",
"group": "GROUP_OTHERS_FURNITURE",
"blockId": "daylight_sensor_inverted"
}
}
}
================================================
FILE: blocks/furnitures/redstones/dispenser.json
================================================
{
"block": {
"dispenser": {
"textureData": "dispenser.png",
"color": [ 111, 111, 111 ],
"type": "FURNITURE",
"width": 2,
"height": 2,
"collision": "SOLID",
"attach": "ALL",
"attachable": "ALL",
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 170,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 100, 100, 100 ],
"preset": "Shooter",
"animation": [
{
"animationId": 0,
"frameStart": 0
},
{
"animationId": 1,
"frameStart": 1
},
{
"animationId": 2,
"frameStart": 2
},
{
"animationId": 3,
"frameStart": 3
}
]
}
},
"item": {
"dispenser": {
"type": "BLOCKS",
"iconTextureData": "dispenser_icon.png",
"group": "GROUP_OTHERS_FURNITURE",
"blockId": "dispenser"
}
}
}
================================================
FILE: blocks/furnitures/redstones/lever.json
================================================
{
"block": {
"lever": {
"textureData": "lever.png",
"color": [ 33, 166, 180 ],
"type": "FURNITURE",
"width": 2,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 72,
"slipperiness": 1.0,
"soundGroupId": "stone",
"functionSoundId": "button1",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 100, 100, 100 ],
"preset": "Button",
"animation": [
{
"animationId": 0,
"tagUsage": "TAG_ADD_FRAME_INDEX_X"
}
]
}
},
"item": {
"lever": {
"type": "BLOCKS",
"iconTextureData": "lever_icon.png",
"group": "GROUP_BUTTON",
"blockId": "lever"
}
}
}
================================================
FILE: blocks/furnitures/redstones/pressure_plates/pressure_plate_golden.json
================================================
{
"block": {
"pressure_plate_golden": {
"textureData": "golden_pressure_plate.png",
"color": [ 222, 190, 55 ],
"type": "FURNITURE",
"subGroup": "PRESSURE_PLATE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 30,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 120, 120, 0 ],
"preset": "RedstonePlate",
"animation": [
{
"animationId": 0,
"tagUsage": "TAG_ADD_FRAME_INDEX_X"
}
]
}
},
"item": {
"golden_pressure_plate": {
"type": "BLOCKS",
"iconTextureData": "golden_pressure_plate_icon.png",
"group": "GROUP_PRESSURE_PLATE",
"blockId": "pressure_plate_golden"
}
}
}
================================================
FILE: blocks/furnitures/redstones/pressure_plates/pressure_plate_iron.json
================================================
{
"block": {
"pressure_plate_iron": {
"textureData": "iron_pressure_plate.png",
"color": [ 194, 188, 196 ],
"type": "FURNITURE",
"subGroup": "PRESSURE_PLATE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 30,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 200, 200, 200 ],
"preset": "RedstonePlate",
"animation": [
{
"animationId": 0,
"tagUsage": "TAG_ADD_FRAME_INDEX_X"
}
]
}
},
"item": {
"iron_pressure_plate": {
"type": "BLOCKS",
"iconTextureData": "iron_pressure_plate_icon.png",
"group": "GROUP_PRESSURE_PLATE",
"blockId": "pressure_plate_iron"
}
}
}
================================================
FILE: blocks/furnitures/redstones/pressure_plates/pressure_plate_stone.json
================================================
{
"block": {
"pressure_plate_stone": {
"textureData": "stone_pressure_plate.png",
"color": [ 111, 111, 111 ],
"type": "FURNITURE",
"subGroup": "PRESSURE_PLATE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 30,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 100, 100, 100 ],
"preset": "RedstonePlate",
"animation": [
{
"animationId": 0,
"tagUsage": "TAG_ADD_FRAME_INDEX_X"
}
]
}
},
"item": {
"stone_pressure_plate": {
"type": "BLOCKS",
"iconTextureData": "stone_pressure_plate_icon.png",
"group": "GROUP_PRESSURE_PLATE",
"blockId": "pressure_plate_stone"
}
}
}
================================================
FILE: blocks/furnitures/redstones/pressure_plates/pressure_plate_wooden.json
================================================
{
"block": {
"pressure_plate_wooden": {
"textureData": "wooden_pressure_plate.png",
"color": [ 180, 144, 90 ],
"type": "FURNITURE",
"subGroup": "PRESSURE_PLATE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 30,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 152, 120, 80 ],
"preset": "RedstonePlate",
"animation": [
{
"animationId": 0,
"tagUsage": "TAG_ADD_FRAME_INDEX_X"
}
]
}
},
"item": {
"wooden_pressure_plate": {
"type": "BLOCKS",
"iconTextureData": "wooden_pressure_plate_icon.png",
"group": "GROUP_PRESSURE_PLATE",
"blockId": "pressure_plate_wooden",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/redstones/redstone_lamp.json
================================================
{
"block": {
"redstone_lamp": {
"textureData": "redstone_lamp.png",
"color": [ 166, 166, 0 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "SOLID",
"attach": "ALL",
"attachable": "ALL",
"toolType": "AXE",
"mineGrade": "GRASS",
"lightOpacity": 3,
"lightColor": [ 32, 0, 0, 0 ],
"lightX": 0,
"lightY": 0,
"lightWi": 1,
"lightHi": 1,
"hardness": 72,
"slipperiness": 1.0,
"soundGroupId": "glass",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 100, 60, 30 ],
"preset": "RedstoneLamp",
"animation": [
{
"animationId": 0,
"tagUsage": "TAG_ADD_FRAME_INDEX_X"
}
]
}
},
"item": {
"redstone_lamp": {
"type": "BLOCKS",
"iconTextureData": "redstone_lamp_icon.png",
"group": "GROUP_LIGHTING",
"blockId": "redstone_lamp"
}
}
}
================================================
FILE: blocks/furnitures/redstones/stone_button.json
================================================
{
"block": {
"stone_button": {
"textureData": "stone_button.png",
"color": [ 111, 111, 111 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "WALL",
"attachable": "NONE",
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 72,
"slipperiness": 1.0,
"soundGroupId": "stone",
"functionSoundId": "button1",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 100, 100, 100 ],
"preset": "Button",
"animation": [
{
"animationId": 0,
"tagUsage": "TAG_ADD_FRAME_INDEX_X"
}
]
}
},
"item": {
"stone_button": {
"type": "BLOCKS",
"iconTextureData": "stone_button_icon.png",
"group": "GROUP_BUTTON",
"blockId": "stone_button"
}
}
}
================================================
FILE: blocks/furnitures/redstones/wooden_button.json
================================================
{
"block": {
"wooden_button": {
"textureData": "wooden_button.png",
"color": [ 159, 132, 77 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "WALL",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 72,
"slipperiness": 1.0,
"soundGroupId": "wood",
"functionSoundId": "button1",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 160, 130, 80 ],
"preset": "Button",
"animation": [
{
"animationId": 0,
"tagUsage": "TAG_ADD_FRAME_INDEX_X"
}
]
}
},
"item": {
"wooden_button": {
"type": "BLOCKS",
"iconTextureData": "wooden_button_icon.png",
"group": "GROUP_BUTTON",
"blockId": "wooden_button",
"fuelTime": 20
}
}
}
================================================
FILE: blocks/furnitures/rocks/rock.json
================================================
{
"block": {
"rock": {
"textureData": "rock.png",
"color": [ 128, 128, 128 ],
"type": "FURNITURE",
"width": 2,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 100,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 128, 128, 128 ],
"preset": "RandomDisplay"
}
}
}
================================================
FILE: blocks/furnitures/rocks/rock_waste.json
================================================
{
"block": {
"rock_waste": {
"textureData": "rock_waste.png",
"color": [ 100, 50, 30 ],
"type": "FURNITURE",
"width": 2,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 100,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 100, 50, 30 ],
"preset": "RandomDisplay"
}
}
}
================================================
FILE: blocks/furnitures/saplings/sapling_acacia.json
================================================
{
"block": {
"sapling_acacia": {
"textureData": "sapling_acacia.png",
"color": [ 109, 122, 19 ],
"type": "FURNITURE",
"width": 2,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_PLANT_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 80,
"slipperiness": 1.0,
"isKilledByLava": true,
"isFragile": true,
"soundGroupId": "grass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 88, 98, 16 ],
"transformId": "log_acacia",
"preset": "Sapling",
"animation": [
{
"animationId": 0,
"shake": true,
"shakeCenterX": 16,
"shakeCenterY": 32,
"shakePeriod": 128,
"shakeAngle": 0.05
}
]
}
},
"item": {
"sapling_acacia": {
"type": "BLOCKS",
"iconTextureData": "sapling_acacia.png",
"group": "GROUP_SAPLING",
"blockId": "sapling_acacia",
"fuelTime": 20
}
}
}
================================================
FILE: blocks/furnitures/saplings/sapling_bare_oak.json
================================================
{
"block": {
"sapling_bare_oak": {
"textureData": "sapling_bare_oak.png",
"color": [ 120, 90, 55 ],
"type": "FURNITURE",
"width": 2,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_PLANT_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 80,
"slipperiness": 1.0,
"isKilledByLava": true,
"isFragile": true,
"soundGroupId": "grass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 120, 90, 55 ],
"transformId": "log_bare_oak",
"preset": "Sapling",
"animation": [
{
"animationId": 0,
"shake": true,
"shakeCenterX": 16,
"shakeCenterY": 32,
"shakePeriod": 128,
"shakeAngle": 0.05
}
]
}
},
"item": {
"sapling_bare_oak": {
"type": "BLOCKS",
"iconTextureData": "sapling_bare_oak.png",
"group": "GROUP_SAPLING",
"blockId": "sapling_bare_oak",
"fuelTime": 20
}
}
}
================================================
FILE: blocks/furnitures/saplings/sapling_birch.json
================================================
{
"block": {
"sapling_birch": {
"textureData": "sapling_birch.png",
"color": [ 204, 209, 144 ],
"type": "FURNITURE",
"width": 2,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_PLANT_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 80,
"slipperiness": 1.0,
"isKilledByLava": true,
"isFragile": true,
"soundGroupId": "grass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 211, 211, 244 ],
"transformId": "log_birch",
"preset": "Sapling",
"animation": [
{
"animationId": 0,
"shake": true,
"shakeCenterX": 16,
"shakeCenterY": 32,
"shakePeriod": 128,
"shakeAngle": 0.05
}
]
}
},
"item": {
"sapling_birch": {
"type": "BLOCKS",
"iconTextureData": "sapling_birch.png",
"group": "GROUP_SAPLING",
"blockId": "sapling_birch",
"fuelTime": 20
}
}
}
================================================
FILE: blocks/furnitures/saplings/sapling_cactus.json
================================================
{
"block": {
"sapling_cactus": {
"textureData": "sapling_cactus.png",
"color": [ 150, 120, 76 ],
"type": "FURNITURE",
"width": 2,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_PLANT_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 80,
"slipperiness": 1.0,
"isKilledByLava": true,
"isFragile": true,
"soundGroupId": "grass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 150, 120, 30 ],
"transformId": "log_cactus",
"preset": "Sapling",
"animation": [
{
"animationId": 0,
"shake": true,
"shakeCenterX": 16,
"shakeCenterY": 32,
"shakePeriod": 128,
"shakeAngle": 0.05
}
]
}
},
"item": {
"sapling_cactus": {
"type": "BLOCKS",
"iconTextureData": "sapling_cactus.png",
"group": "GROUP_SAPLING",
"blockId": "sapling_cactus"
}
}
}
================================================
FILE: blocks/furnitures/saplings/sapling_dark_oak.json
================================================
{
"block": {
"sapling_dark_oak": {
"textureData": "sapling_dark_oak.png",
"color": [ 80, 55, 33 ],
"type": "FURNITURE",
"width": 2,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_PLANT_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 80,
"slipperiness": 1.0,
"isKilledByLava": true,
"isFragile": true,
"soundGroupId": "grass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 88, 55, 33 ],
"transformId": "log_dark_oak",
"preset": "Sapling",
"animation": [
{
"animationId": 0,
"shake": true,
"shakeCenterX": 16,
"shakeCenterY": 32,
"shakePeriod": 128,
"shakeAngle": 0.05
}
]
}
},
"item": {
"sapling_dark_oak": {
"type": "BLOCKS",
"iconTextureData": "sapling_dark_oak.png",
"group": "GROUP_SAPLING",
"blockId": "sapling_dark_oak",
"fuelTime": 20
}
}
}
================================================
FILE: blocks/furnitures/saplings/sapling_jungle.json
================================================
{
"block": {
"sapling_jungle": {
"textureData": "sapling_jungle.png",
"color": [ 54, 123, 54 ],
"type": "FURNITURE",
"width": 2,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_PLANT_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 80,
"slipperiness": 1.0,
"isKilledByLava": true,
"isFragile": true,
"soundGroupId": "grass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 55, 123, 55 ],
"transformId": "log_jungle",
"preset": "Sapling",
"animation": [
{
"animationId": 0,
"shake": true,
"shakeCenterX": 16,
"shakeCenterY": 32,
"shakePeriod": 128,
"shakeAngle": 0.05
}
]
}
},
"item": {
"sapling_jungle": {
"type": "BLOCKS",
"iconTextureData": "sapling_jungle.png",
"group": "GROUP_SAPLING",
"blockId": "sapling_jungle",
"fuelTime": 20
}
}
}
================================================
FILE: blocks/furnitures/saplings/sapling_oak.json
================================================
{
"block": {
"sapling_oak": {
"textureData": "sapling_oak.png",
"color": [ 120, 90, 55 ],
"type": "FURNITURE",
"width": 2,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_PLANT_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 80,
"slipperiness": 1.0,
"isKilledByLava": true,
"isFragile": true,
"soundGroupId": "grass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 88, 66, 27 ],
"transformId": "log_oak",
"preset": "Sapling",
"animation": [
{
"animationId": 0,
"shake": true,
"shakeCenterX": 16,
"shakeCenterY": 32,
"shakePeriod": 128,
"shakeAngle": 0.05
}
]
}
},
"item": {
"sapling_oak": {
"type": "BLOCKS",
"iconTextureData": "sapling_oak.png",
"group": "GROUP_SAPLING",
"blockId": "sapling_oak",
"fuelTime": 20
}
}
}
================================================
FILE: blocks/furnitures/saplings/sapling_palm.json
================================================
{
"block": {
"sapling_palm": {
"textureData": "sapling_palm.png",
"color": [ 130, 114, 70 ],
"type": "FURNITURE",
"width": 2,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_PLANT_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 80,
"slipperiness": 1.0,
"isKilledByLava": true,
"isFragile": true,
"soundGroupId": "grass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 150, 130, 80 ],
"transformId": "log_palm",
"preset": "Sapling",
"animation": [
{
"animationId": 0,
"shake": true,
"shakeCenterX": 16,
"shakeCenterY": 32,
"shakePeriod": 128,
"shakeAngle": 0.05
}
]
}
},
"item": {
"sapling_palm": {
"type": "BLOCKS",
"iconTextureData": "sapling_palm.png",
"group": "GROUP_SAPLING",
"blockId": "sapling_palm",
"fuelTime": 20
}
}
}
================================================
FILE: blocks/furnitures/saplings/sapling_spruce.json
================================================
{
"block": {
"sapling_spruce": {
"textureData": "sapling_spruce.png",
"color": [ 77, 55, 33 ],
"type": "FURNITURE",
"width": 2,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_PLANT_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 80,
"slipperiness": 1.0,
"isKilledByLava": true,
"isFragile": true,
"soundGroupId": "grass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 55, 27, 27 ],
"transformId": "log_spruce",
"preset": "Sapling",
"animation": [
{
"animationId": 0,
"shake": true,
"shakeCenterX": 16,
"shakeCenterY": 32,
"shakePeriod": 128,
"shakeAngle": 0.05
}
]
}
},
"item": {
"sapling_spruce": {
"type": "BLOCKS",
"iconTextureData": "sapling_spruce.png",
"group": "GROUP_SAPLING",
"blockId": "sapling_spruce",
"fuelTime": 20
}
}
}
================================================
FILE: blocks/furnitures/saplings/sapling_tainted.json
================================================
{
"block": {
"sapling_tainted": {
"textureData": "sapling_tainted.png",
"color": [ 67, 39, 90 ],
"type": "FURNITURE",
"width": 2,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_PLANT_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 80,
"slipperiness": 1.0,
"isKilledByLava": true,
"isFragile": true,
"soundGroupId": "grass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 88, 44, 111 ],
"transformId": "log_tainted",
"preset": "Sapling",
"animation": [
{
"animationId": 0,
"shake": true,
"shakeCenterX": 16,
"shakeCenterY": 32,
"shakePeriod": 128,
"shakeAngle": 0.05
}
]
}
},
"item": {
"sapling_tainted": {
"type": "BLOCKS",
"iconTextureData": "sapling_tainted.png",
"group": "GROUP_SAPLING",
"blockId": "sapling_tainted",
"fuelTime": 20
}
}
}
================================================
FILE: blocks/furnitures/saplings/sapling_volcano.json
================================================
{
"block": {
"sapling_volcano": {
"textureData": "sapling_volcano.png",
"color": [ 200, 60, 60 ],
"type": "FURNITURE",
"width": 2,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_PLANT_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 80,
"slipperiness": 1.0,
"isKilledByLava": true,
"isFragile": true,
"soundGroupId": "grass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 200, 60, 60 ],
"transformId": "log_volcano_oak",
"preset": "Sapling",
"animation": [
{
"animationId": 0,
"shake": true,
"shakeCenterX": 16,
"shakeCenterY": 32,
"shakePeriod": 128,
"shakeAngle": 0.05
}
]
}
},
"item": {
"sapling_volcano": {
"type": "BLOCKS",
"iconTextureData": "sapling_volcano.png",
"group": "GROUP_SAPLING",
"blockId": "sapling_volcano",
"fuelTime": 20
}
}
}
================================================
FILE: blocks/furnitures/seas/coral.json
================================================
{
"block": {
"coral": {
"textureData": "coral.png",
"color": [ 255, 190, 220 ],
"type": "FURNITURE",
"width": 2,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 50,
"slipperiness": 1.0,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 222, 222, 222 ],
"preset": "RandomDisplay"
}
}
}
================================================
FILE: blocks/furnitures/seas/kelp.json
================================================
{
"block": {
"kelp": {
"textureData": "kelp.png",
"color": [ 88, 171, 48 ],
"type": "FURNITURE",
"width": 2,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "TOP",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 10,
"isChipCollection": true,
"lossyItemId": "kelp",
"chipCount": 4,
"slipperiness": 1.0,
"isKilledByLava": true,
"isFragile": true,
"isDestroyByWeapon": true,
"soundId": "grass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 88, 171, 48 ],
"preset": "Kelp",
"animation": [
{
"animationId": 0,
"frameSpeed": 8,
"frameStart": 0,
"frameCount": 4
}
]
}
}
}
================================================
FILE: blocks/furnitures/seas/sea_grass.json
================================================
{
"block": {
"sea_grass": {
"textureData": "sea_grass.png",
"color": [ 60, 160, 10 ],
"type": "FURNITURE",
"width": 2,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 50,
"slipperiness": 1.0,
"soundGroupId": "grass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 60, 160, 0 ],
"preset": "RandomDisplay"
}
}
}
================================================
FILE: blocks/furnitures/seas/sea_shell.json
================================================
{
"block": {
"sea_shell": {
"textureData": "sea_shell.png",
"color": [ 244, 133, 119 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 50,
"slipperiness": 1.0,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 222, 222, 222 ],
"preset": "RandomDisplay"
}
}
}
================================================
FILE: blocks/furnitures/small_trees/small_tree_desert.json
================================================
{
"block": {
"small_tree_desert": {
"textureData": "small_tree_desert.png",
"color": [ 197, 133, 19 ],
"type": "FURNITURE",
"width": 3,
"height": 3,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_SAND_DECO_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 200,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 200, 140, 120 ]
}
}
}
================================================
FILE: blocks/furnitures/small_trees/small_tree_normal.json
================================================
{
"block": {
"small_tree_normal": {
"textureData": "small_tree.png",
"color": [ 183, 165, 80 ],
"type": "FURNITURE",
"width": 3,
"height": 3,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_PLANT_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 200,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 110, 100, 50 ]
}
}
}
================================================
FILE: blocks/furnitures/small_trees/small_tree_snowy.json
================================================
{
"block": {
"small_tree_snowy": {
"textureData": "small_tree_snowy.png",
"color": [ 166, 188, 190 ],
"type": "FURNITURE",
"width": 3,
"height": 3,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_ICE_DECO_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 200,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 100, 60, 140 ]
}
}
}
================================================
FILE: blocks/furnitures/small_trees/small_tree_tainted.json
================================================
{
"block": {
"small_tree_tainted": {
"textureData": "small_tree_tainted.png",
"color": [ 83, 48, 122 ],
"type": "FURNITURE",
"width": 3,
"height": 3,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_TAINTED_DECO_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 200,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 100, 60, 140 ]
}
}
}
================================================
FILE: blocks/furnitures/small_trees/small_tree_waste.json
================================================
{
"block": {
"small_tree_waste": {
"textureData": "small_tree_waste.png",
"color": [ 100, 50, 30 ],
"type": "FURNITURE",
"width": 3,
"height": 4,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_SAND_DECO_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 200,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 100, 50, 30 ]
}
}
}
================================================
FILE: blocks/furnitures/stabs/stab_hanging_tainted.json
================================================
{
"block": {
"stab_hanging_tainted": {
"textureData": "tainted_stab_hanging.png",
"color": [ 108, 65, 156 ],
"type": "FURNITURE",
"width": 2,
"height": 3,
"collision": "NONE",
"attach": "TOP",
"attachable": "NONE",
"placeCheck": "PLACE_TAINTED_DECO_CHECK",
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 200,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 128, 128, 128 ],
"preset": "RandomDisplay"
}
}
}
================================================
FILE: blocks/furnitures/stabs/stab_tainted.json
================================================
{
"block": {
"stab_tainted": {
"textureData": "tainted_stab.png",
"color": [ 108, 65, 156 ],
"type": "FURNITURE",
"width": 2,
"height": 3,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_TAINTED_DECO_CHECK",
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 200,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 128, 128, 128 ],
"preset": "RandomDisplay"
}
}
}
================================================
FILE: blocks/furnitures/stalactites/stalactite_andesite.json
================================================
{
"block": {
"stalactite_andesite": {
"textureData": "andesite_stalactite.png",
"color": [ 111, 111, 135 ],
"type": "FURNITURE",
"width": 1,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_ANDESITE_DECO_CHECK",
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 200,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 111, 111, 135 ],
"preset": "RandomDisplay"
}
}
}
================================================
FILE: blocks/furnitures/stalactites/stalactite_desert.json
================================================
{
"block": {
"stalactite_desert": {
"textureData": "desert_stalactite.png",
"color": [ 176, 162, 123 ],
"type": "FURNITURE",
"width": 1,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_SAND_DECO_CHECK",
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 200,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 140, 130, 100 ],
"preset": "RandomDisplay"
}
}
}
================================================
FILE: blocks/furnitures/stalactites/stalactite_diorite.json
================================================
{
"block": {
"stalactite_diorite": {
"textureData": "diorite_stalactite.png",
"color": [ 118, 118, 118 ],
"type": "FURNITURE",
"width": 1,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_DIORITE_DECO_CHECK",
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 200,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 118, 118, 118 ],
"preset": "RandomDisplay"
}
}
}
================================================
FILE: blocks/furnitures/stalactites/stalactite_granite.json
================================================
{
"block": {
"stalactite_granite": {
"textureData": "granite_stalactite.png",
"color": [ 111, 81, 69 ],
"type": "FURNITURE",
"width": 1,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_GRANITE_DECO_CHECK",
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 200,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 111, 81, 69 ],
"preset": "RandomDisplay"
}
}
}
================================================
FILE: blocks/furnitures/stalactites/stalactite_hanging_andesite.json
================================================
{
"block": {
"stalactite_hanging_andesite": {
"textureData": "andesite_stalactite_hanging.png",
"color": [ 111, 111, 135 ],
"type": "FURNITURE",
"width": 1,
"height": 2,
"collision": "NONE",
"attach": "TOP",
"attachable": "NONE",
"placeCheck": "PLACE_ANDESITE_DECO_CHECK",
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 200,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 111, 111, 135 ],
"preset": "RandomDisplay"
}
}
}
================================================
FILE: blocks/furnitures/stalactites/stalactite_hanging_desert.json
================================================
{
"block": {
"stalactite_hanging_desert": {
"textureData": "desert_stalactite_hanging.png",
"color": [ 176, 162, 123 ],
"type": "FURNITURE",
"width": 1,
"height": 2,
"collision": "NONE",
"attach": "TOP",
"attachable": "NONE",
"placeCheck": "PLACE_SAND_DECO_CHECK",
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 200,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 200, 160, 140 ],
"preset": "Stalactite"
}
}
}
================================================
FILE: blocks/furnitures/stalactites/stalactite_hanging_diorite.json
================================================
{
"block": {
"stalactite_hanging_diorite": {
"textureData": "diorite_stalactite_hanging.png",
"color": [ 118, 118, 118 ],
"type": "FURNITURE",
"width": 1,
"height": 2,
"collision": "NONE",
"attach": "TOP",
"attachable": "NONE",
"placeCheck": "PLACE_DIORITE_DECO_CHECK",
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 200,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 118, 118, 118 ],
"preset": "RandomDisplay"
}
}
}
================================================
FILE: blocks/furnitures/stalactites/stalactite_hanging_granite.json
================================================
{
"block": {
"stalactite_hanging_granite": {
"textureData": "granite_stalactite_hanging.png",
"color": [ 111, 81, 69 ],
"type": "FURNITURE",
"width": 1,
"height": 2,
"collision": "NONE",
"attach": "TOP",
"attachable": "NONE",
"placeCheck": "PLACE_GRANITE_DECO_CHECK",
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 200,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 111, 81, 69 ],
"preset": "RandomDisplay"
}
}
}
================================================
FILE: blocks/furnitures/stalactites/stalactite_hanging_ice.json
================================================
{
"block": {
"stalactite_hanging_ice": {
"textureData": "ice_stalactite_hanging.png",
"color": [ 124, 202, 235 ],
"type": "FURNITURE",
"width": 1,
"height": 2,
"collision": "NONE",
"attach": "TOP",
"attachable": "NONE",
"placeCheck": "PLACE_ICE_DECO_CHECK",
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 200,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 140, 180, 220 ],
"preset": "Stalactite"
}
}
}
================================================
FILE: blocks/furnitures/stalactites/stalactite_hanging_small_andesite.json
================================================
{
"block": {
"stalactite_hanging_small_andesite": {
"textureData": "andesite_small_stalactite_hanging.png",
"color": [ 111, 111, 135 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "TOP",
"attachable": "NONE",
"placeCheck": "PLACE_ANDESITE_DECO_CHECK",
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 200,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 111, 111, 135 ],
"preset": "RandomDisplay"
}
}
}
================================================
FILE: blocks/furnitures/stalactites/stalactite_hanging_small_desert.json
================================================
{
"block": {
"stalactite_hanging_small_desert": {
"textureData": "desert_small_stalactite_hanging.png",
"color": [ 176, 162, 123 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "TOP",
"attachable": "NONE",
"placeCheck": "PLACE_SAND_DECO_CHECK",
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 200,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 200, 160, 140 ],
"preset": "Stalactite"
}
}
}
================================================
FILE: blocks/furnitures/stalactites/stalactite_hanging_small_diorite.json
================================================
{
"block": {
"stalactite_hanging_small_diorite": {
"textureData": "diorite_small_stalactite_hanging.png",
"color": [ 118, 118, 118 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "TOP",
"attachable": "NONE",
"placeCheck": "PLACE_DIORITE_DECO_CHECK",
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 200,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 118, 118, 118 ],
"preset": "RandomDisplay"
}
}
}
================================================
FILE: blocks/furnitures/stalactites/stalactite_hanging_small_granite.json
================================================
{
"block": {
"stalactite_hanging_small_granite": {
"textureData": "granite_small_stalactite_hanging.png",
"color": [ 111, 81, 69 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "TOP",
"attachable": "NONE",
"placeCheck": "PLACE_GRANITE_DECO_CHECK",
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 200,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 111, 81, 69 ],
"preset": "RandomDisplay"
}
}
}
================================================
FILE: blocks/furnitures/stalactites/stalactite_hanging_small_ice.json
================================================
{
"block": {
"stalactite_hanging_small_ice": {
"textureData": "ice_small_stalactite_hanging.png",
"color": [ 124, 202, 235 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "TOP",
"attachable": "NONE",
"placeCheck": "PLACE_ICE_DECO_CHECK",
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 200,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 140, 180, 220 ],
"preset": "Stalactite"
}
}
}
================================================
FILE: blocks/furnitures/stalactites/stalactite_hanging_small_stone.json
================================================
{
"block": {
"stalactite_hanging_small_stone": {
"textureData": "stone_small_stalactite_hanging.png",
"color": [ 128, 128, 128 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "TOP",
"attachable": "NONE",
"placeCheck": "PLACE_STONE_DECO_CHECK",
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 200,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 128, 128, 128 ],
"preset": "RandomDisplay"
}
}
}
================================================
FILE: blocks/furnitures/stalactites/stalactite_hanging_small_tainted.json
================================================
{
"block": {
"stalactite_hanging_small_tainted": {
"textureData": "tainted_small_stalactite_hanging.png",
"color": [ 108, 65, 156 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "TOP",
"attachable": "NONE",
"placeCheck": "PLACE_TAINTED_DECO_CHECK",
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 200,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 120, 100, 140 ],
"preset": "RandomDisplay"
}
}
}
================================================
FILE: blocks/furnitures/stalactites/stalactite_hanging_small_waste.json
================================================
{
"block": {
"stalactite_hanging_small_waste": {
"textureData": "waste_small_stalactite_hanging.png",
"color": [ 104, 46, 23 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "TOP",
"attachable": "NONE",
"placeCheck": "PLACE_WASTE_DECO_CHECK",
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 200,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 104, 46, 23 ],
"preset": "RandomDisplay"
}
}
}
================================================
FILE: blocks/furnitures/stalactites/stalactite_hanging_stone.json
================================================
{
"block": {
"stalactite_hanging_stone": {
"textureData": "stone_stalactite_hanging.png",
"color": [ 128, 128, 128 ],
"type": "FURNITURE",
"width": 1,
"height": 2,
"collision": "NONE",
"attach": "TOP",
"attachable": "NONE",
"placeCheck": "PLACE_STONE_DECO_CHECK",
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 200,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 128, 128, 128 ],
"preset": "RandomDisplay"
}
}
}
================================================
FILE: blocks/furnitures/stalactites/stalactite_hanging_tainted.json
================================================
{
"block": {
"stalactite_hanging_tainted": {
"textureData": "tainted_stalactite_hanging.png",
"color": [ 108, 65, 156 ],
"type": "FURNITURE",
"width": 1,
"height": 2,
"collision": "NONE",
"attach": "TOP",
"attachable": "NONE",
"placeCheck": "PLACE_TAINTED_DECO_CHECK",
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 200,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 120, 100, 140 ],
"preset": "RandomDisplay"
}
}
}
================================================
FILE: blocks/furnitures/stalactites/stalactite_hanging_waste.json
================================================
{
"block": {
"stalactite_hanging_waste": {
"textureData": "waste_stalactite_hanging.png",
"color": [ 104, 46, 23 ],
"type": "FURNITURE",
"width": 1,
"height": 2,
"collision": "NONE",
"attach": "TOP",
"attachable": "NONE",
"placeCheck": "PLACE_WASTE_DECO_CHECK",
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 200,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 104, 46, 23 ],
"preset": "RandomDisplay"
}
}
}
================================================
FILE: blocks/furnitures/stalactites/stalactite_ice.json
================================================
{
"block": {
"stalactite_ice": {
"textureData": "ice_stalactite.png",
"color": [ 124, 202, 235 ],
"type": "FURNITURE",
"width": 1,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_ICE_DECO_CHECK",
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 200,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 140, 180, 220 ],
"preset": "RandomDisplay"
}
}
}
================================================
FILE: blocks/furnitures/stalactites/stalactite_small_andesite.json
================================================
{
"block": {
"stalactite_small_andesite": {
"textureData": "andesite_small_stalactite.png",
"color": [ 111, 111, 135 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_ANDESITE_DECO_CHECK",
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 200,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 111, 111, 135 ],
"preset": "RandomDisplay"
}
}
}
================================================
FILE: blocks/furnitures/stalactites/stalactite_small_desert.json
================================================
{
"block": {
"stalactite_small_desert": {
"textureData": "desert_small_stalactite.png",
"color": [ 176, 162, 123 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_SAND_DECO_CHECK",
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 200,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 140, 130, 100 ],
"preset": "RandomDisplay"
}
}
}
================================================
FILE: blocks/furnitures/stalactites/stalactite_small_diorite.json
================================================
{
"block": {
"stalactite_small_diorite": {
"textureData": "diorite_small_stalactite.png",
"color": [ 118, 118, 118 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_DIORITE_DECO_CHECK",
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 200,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 118, 118, 118 ],
"preset": "RandomDisplay"
}
}
}
================================================
FILE: blocks/furnitures/stalactites/stalactite_small_granite.json
================================================
{
"block": {
"stalactite_small_granite": {
"textureData": "granite_small_stalactite.png",
"color": [ 111, 81, 69 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_GRANITE_DECO_CHECK",
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 200,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 111, 81, 69 ],
"preset": "RandomDisplay"
}
}
}
================================================
FILE: blocks/furnitures/stalactites/stalactite_small_ice.json
================================================
{
"block": {
"stalactite_small_ice": {
"textureData": "ice_small_stalactite.png",
"color": [ 124, 202, 235 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_ICE_DECO_CHECK",
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 200,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 140, 180, 220 ],
"preset": "RandomDisplay"
}
}
}
================================================
FILE: blocks/furnitures/stalactites/stalactite_small_stone.json
================================================
{
"block": {
"stalactite_small_stone": {
"textureData": "stone_small_stalactite.png",
"color": [ 128, 128, 128 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_STONE_DECO_CHECK",
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 200,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 128, 128, 128 ],
"preset": "RandomDisplay"
}
}
}
================================================
FILE: blocks/furnitures/stalactites/stalactite_small_tainted.json
================================================
{
"block": {
"stalactite_small_tainted": {
"textureData": "tainted_small_stalactite.png",
"color": [ 108, 65, 156 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_TAINTED_DECO_CHECK",
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 200,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 120, 100, 140 ],
"preset": "RandomDisplay"
}
}
}
================================================
FILE: blocks/furnitures/stalactites/stalactite_small_waste.json
================================================
{
"block": {
"stalactite_small_waste": {
"textureData": "waste_small_stalactite.png",
"color": [ 104, 46, 23 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_WASTE_DECO_CHECK",
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 200,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 104, 46, 23 ],
"preset": "RandomDisplay"
}
}
}
================================================
FILE: blocks/furnitures/stalactites/stalactite_stone.json
================================================
{
"block": {
"stalactite_stone": {
"textureData": "stone_stalactite.png",
"color": [ 128, 128, 128 ],
"type": "FURNITURE",
"width": 1,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_STONE_DECO_CHECK",
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 200,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 128, 128, 128 ],
"preset": "RandomDisplay"
}
}
}
================================================
FILE: blocks/furnitures/stalactites/stalactite_tainted.json
================================================
{
"block": {
"stalactite_tainted": {
"textureData": "tainted_stalactite.png",
"color": [ 108, 65, 156 ],
"type": "FURNITURE",
"width": 1,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_TAINTED_DECO_CHECK",
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 200,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 120, 100, 140 ],
"preset": "RandomDisplay"
}
}
}
================================================
FILE: blocks/furnitures/stalactites/stalactite_waste.json
================================================
{
"block": {
"stalactite_waste": {
"textureData": "waste_stalactite.png",
"color": [ 104, 46, 23 ],
"type": "FURNITURE",
"width": 1,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_WASTE_DECO_CHECK",
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 200,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 104, 46, 23 ],
"preset": "RandomDisplay"
}
}
}
================================================
FILE: blocks/furnitures/stone_decoses/stone_decos_ice.json
================================================
{
"block": {
"stone_decos_ice": {
"textureData": "stone_decos_ice.png",
"color": [ 124, 202, 235 ],
"type": "FURNITURE",
"width": 3,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_ICE_DECO_CHECK",
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 200,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 100, 170, 200 ],
"preset": "RandomDisplay"
}
}
}
================================================
FILE: blocks/furnitures/stone_decoses/stone_decos_mossy.json
================================================
{
"block": {
"stone_decos_mossy": {
"textureData": "stone_decos_mossy.png",
"color": [ 106, 66, 55 ],
"type": "FURNITURE",
"width": 3,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 200,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 100, 140, 110 ],
"preset": "RandomDisplay"
}
}
}
================================================
FILE: blocks/furnitures/stone_decoses/stone_decos_normal.json
================================================
{
"block": {
"stone_decos_normal": {
"textureData": "stone_decos.png",
"color": [ 128, 128, 128 ],
"type": "FURNITURE",
"width": 3,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 200,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 128, 128, 128 ],
"preset": "RandomDisplay"
}
}
}
================================================
FILE: blocks/furnitures/stone_decoses/stone_decos_tainted.json
================================================
{
"block": {
"stone_decos_tainted": {
"textureData": "stone_decos_tainted.png",
"color": [ 108, 65, 156 ],
"type": "FURNITURE",
"width": 3,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_TAINTED_DECO_CHECK",
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 200,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 100, 60, 140 ],
"preset": "RandomDisplay"
}
}
}
================================================
FILE: blocks/furnitures/stone_decoses/stone_decos_waste.json
================================================
{
"block": {
"stone_decos_waste": {
"textureData": "stone_decos_waste.png",
"color": [ 100, 50, 30 ],
"type": "FURNITURE",
"width": 3,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 200,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 100, 50, 30 ],
"preset": "RandomDisplay"
}
}
}
================================================
FILE: blocks/furnitures/stone_pillars/stone_pillar_desert.json
================================================
{
"block": {
"stone_pillar_desert": {
"textureData": "stone_pillar_desert.png",
"type": "FURNITURE",
"width": 2,
"height": 3,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_SAND_DECO_CHECK",
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 200,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 150, 160, 110 ],
"preset": "RandomDisplay"
}
}
}
================================================
FILE: blocks/furnitures/stone_pillars/stone_pillar_ice.json
================================================
{
"block": {
"stone_pillar_ice": {
"textureData": "stone_pillar_ice.png",
"color": [ 128, 128, 128 ],
"type": "FURNITURE",
"width": 2,
"height": 3,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_ICE_DECO_CHECK",
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 200,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 100, 200, 255 ],
"preset": "RandomDisplay"
}
}
}
================================================
FILE: blocks/furnitures/stone_pillars/stone_pillar_normal.json
================================================
{
"block": {
"stone_pillar_normal": {
"textureData": "stone_pillar.png",
"type": "FURNITURE",
"width": 2,
"height": 3,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_STONE_DECO_CHECK",
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 200,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 128, 128, 128 ],
"preset": "RandomDisplay"
}
}
}
================================================
FILE: blocks/furnitures/stone_pillars/stone_pillar_tainted.json
================================================
{
"block": {
"stone_pillar_tainted": {
"textureData": "stone_pillar_tainted.png",
"color": [ 108, 65, 156 ],
"type": "FURNITURE",
"width": 2,
"height": 3,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_TAINTED_DECO_CHECK",
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 200,
"slipperiness": 1.0,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 80, 50, 120 ],
"preset": "RandomDisplay"
}
}
}
================================================
FILE: blocks/furnitures/tables/table_acacia.json
================================================
{
"block": {
"table_acacia": {
"textureData": "wooden_table_acacia.png",
"color": [ 190, 125, 90 ],
"type": "FURNITURE",
"width": 3,
"height": 2,
"collision": "PLATFORM",
"attach": "BOTTOM",
"attachable": "TOP",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 140,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 180, 100, 60 ]
}
},
"item": {
"table_acacia": {
"type": "BLOCKS",
"iconTextureData": "wooden_table_acacia.png",
"group": "GROUP_WOODEN_TABLE",
"blockId": "table_acacia",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/tables/table_birch.json
================================================
{
"block": {
"table_birch": {
"textureData": "wooden_table_birch.png",
"color": [ 220, 210, 160 ],
"type": "FURNITURE",
"width": 3,
"height": 2,
"collision": "PLATFORM",
"attach": "BOTTOM",
"attachable": "TOP",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 140,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 200, 200, 130 ]
}
},
"item": {
"table_birch": {
"type": "BLOCKS",
"iconTextureData": "wooden_table_birch.png",
"group": "GROUP_WOODEN_TABLE",
"blockId": "table_birch",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/tables/table_dark_oak.json
================================================
{
"block": {
"table_dark_oak": {
"textureData": "wooden_table_dark_oak.png",
"color": [ 106, 86, 66 ],
"type": "FURNITURE",
"width": 3,
"height": 2,
"collision": "PLATFORM",
"attach": "BOTTOM",
"attachable": "TOP",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 140,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 60, 30, 10 ]
}
},
"item": {
"table_dark_oak": {
"type": "BLOCKS",
"iconTextureData": "wooden_table_dark_oak.png",
"group": "GROUP_WOODEN_TABLE",
"blockId": "table_dark_oak",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/tables/table_jungle.json
================================================
{
"block": {
"table_jungle": {
"textureData": "wooden_table_jungle.png",
"color": [ 137, 110, 92 ],
"type": "FURNITURE",
"width": 3,
"height": 2,
"collision": "PLATFORM",
"attach": "BOTTOM",
"attachable": "TOP",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 140,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 100, 70, 50 ]
}
},
"item": {
"table_jungle": {
"type": "BLOCKS",
"iconTextureData": "wooden_table_jungle.png",
"group": "GROUP_WOODEN_TABLE",
"blockId": "table_jungle",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/tables/table_nether.json
================================================
{
"block": {
"table_nether": {
"textureData": "table_nether.png",
"color": [ 72, 29, 34 ],
"type": "FURNITURE",
"width": 3,
"height": 2,
"collision": "PLATFORM",
"attach": "BOTTOM",
"attachable": "TOP",
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 140,
"slipperiness": 1.0,
"isKilledByLava": false,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 72, 29, 34 ]
}
},
"item": {
"table_nether": {
"type": "BLOCKS",
"iconTextureData": "table_nether.png",
"group": "GROUP_WOODEN_TABLE",
"blockId": "table_nether",
"antiLava": true
}
}
}
================================================
FILE: blocks/furnitures/tables/table_oak.json
================================================
{
"block": {
"table_oak": {
"textureData": "wooden_table_oak.png",
"color": [ 167, 136, 79 ],
"type": "FURNITURE",
"width": 3,
"height": 2,
"collision": "PLATFORM",
"attach": "BOTTOM",
"attachable": "TOP",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 140,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 173, 137, 80 ]
}
},
"item": {
"table_oak": {
"type": "BLOCKS",
"iconTextureData": "wooden_table_oak.png",
"group": "GROUP_WOODEN_TABLE",
"blockId": "table_oak",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/tables/table_palm.json
================================================
{
"block": {
"table_palm": {
"textureData": "wooden_table_palm.png",
"color": [ 182, 141, 86 ],
"type": "FURNITURE",
"width": 3,
"height": 2,
"collision": "PLATFORM",
"attach": "BOTTOM",
"attachable": "TOP",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 140,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 182, 141, 86 ]
}
},
"item": {
"table_palm": {
"type": "BLOCKS",
"iconTextureData": "wooden_table_palm.png",
"group": "GROUP_WOODEN_TABLE",
"blockId": "table_palm",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/tables/table_spruce.json
================================================
{
"block": {
"table_spruce": {
"textureData": "wooden_table_spruce.png",
"color": [ 144, 119, 93 ],
"type": "FURNITURE",
"width": 3,
"height": 2,
"collision": "PLATFORM",
"attach": "BOTTOM",
"attachable": "TOP",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 140,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 120, 90, 60 ]
}
},
"item": {
"table_spruce": {
"type": "BLOCKS",
"iconTextureData": "wooden_table_spruce.png",
"group": "GROUP_WOODEN_TABLE",
"blockId": "table_spruce",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/tables/table_tainted.json
================================================
{
"block": {
"table_tainted": {
"textureData": "wooden_table_tainted.png",
"color": [ 89, 85, 107 ],
"type": "FURNITURE",
"width": 3,
"height": 2,
"collision": "PLATFORM",
"attach": "BOTTOM",
"attachable": "TOP",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 140,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 89, 85, 107 ]
}
},
"item": {
"table_tainted": {
"type": "BLOCKS",
"iconTextureData": "wooden_table_tainted.png",
"group": "GROUP_WOODEN_TABLE",
"blockId": "table_tainted",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/tables/table_volcano.json
================================================
{
"block": {
"table_volcano": {
"textureData": "wooden_table_volcano.png",
"color": [ 200, 60, 60 ],
"type": "FURNITURE",
"width": 3,
"height": 2,
"collision": "PLATFORM",
"attach": "BOTTOM",
"attachable": "TOP",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 140,
"slipperiness": 1.0,
"isKilledByLava": true,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 200, 60, 60 ]
}
},
"item": {
"table_volcano": {
"type": "BLOCKS",
"iconTextureData": "wooden_table_volcano.png",
"group": "GROUP_WOODEN_TABLE",
"blockId": "table_volcano",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/furnitures/tentacles/flesh_tentacle.json
================================================
{
"block": {
"flesh_tentacle": {
"textureData": "flesh_tentacle.png",
"color": [ 131, 37, 34 ],
"type": "FURNITURE",
"width": 2,
"height": 8,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 300,
"slipperiness": 1.0,
"isKilledByLava": true,
"isFragile": false,
"isDestroyByWeapon": false,
"soundGroupId": "grass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 131, 37, 34 ],
"animation": [
{
"animationId": 0,
"frameRandom": true,
"frameStart": 0,
"frameCount": 4,
"shake": true,
"shakeCenterX": 16,
"shakeCenterY": 128,
"shakePeriod": 256,
"shakeAngle": 0.1
}
]
}
}
}
================================================
FILE: blocks/furnitures/tentacles/flesh_tentacle_hanging.json
================================================
{
"block": {
"flesh_tentacle_hanging": {
"textureData": "flesh_tentacle_hanging.png",
"color": [ 131, 37, 34 ],
"type": "FURNITURE",
"width": 2,
"height": 8,
"collision": "NONE",
"attach": "TOP",
"attachable": "NONE",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 300,
"slipperiness": 1.0,
"isKilledByLava": true,
"isFragile": false,
"isDestroyByWeapon": false,
"soundGroupId": "grass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 131, 37, 34 ],
"animation": [
{
"animationId": 0,
"frameRandom": true,
"frameStart": 0,
"frameCount": 4,
"shake": true,
"shakeCenterX": 16,
"shakeCenterY": 0,
"shakePeriod": 256,
"shakeAngle": 0.1
}
]
}
}
}
================================================
FILE: blocks/furnitures/torches/blue_torch.json
================================================
{
"block": {
"blue_torch": {
"textureData": "torch.png",
"color": [ 143, 115, 73 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "TORCH",
"attachable": "NONE",
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 20,
"isFragile": true,
"isKilledByLava": true,
"isNoWater": true,
"modTextureId": "TORCH_FIRE_BLUE",
"isLighting": true,
"lightColor": [ 20, 0, 0, 32 ],
"lightX": 0,
"lightY": 0,
"lightWi": 1,
"lightHi": 1,
"isFlash": true,
"flashTime": 128,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 100, 100, 40 ],
"exParticle": "torch_particle",
"preset": "Torch",
"covers": [
{
"modTextureId": "torch_fire_blue",
"offsetX": 0,
"offsetY": -14
}
]
}
},
"item": {
"blue_torch": {
"type": "BLOCKS",
"iconTextureData": "blue_torch_icon.png",
"textureData": "torch_entity.png",
"group": "GROUP_TORCH",
"blockId": "blue_torch",
"isHandLight": true,
"entityWidth": 8,
"entityHeight": 16,
"handX": 4,
"handY": 14,
"firePoints": [[4,0]]
}
}
}
================================================
FILE: blocks/furnitures/torches/end_rod.json
================================================
{
"block": {
"end_rod": {
"textureData": "end_rod.png",
"color": [ 205, 192, 177 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "TORCH",
"attachable": "NONE",
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 20,
"isFragile": true,
"isKilledByLava": true,
"isNoWater": false,
"isLighting": true,
"lightColor": [ 32, 0, 0, 0 ],
"lightX": 0,
"lightY": 0,
"lightWi": 1,
"lightHi": 1,
"isFlash": true,
"flashTime": 128,
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 205, 192, 177 ],
"exParticle": "end_rod_particle",
"preset": "EndRod"
}
},
"item": {
"end_rod": {
"type": "BLOCKS",
"iconTextureData": "end_rod_icon.png",
"group": "GROUP_LIGHTING",
"blockId": "end_rod"
}
}
}
================================================
FILE: blocks/furnitures/torches/green_torch.json
================================================
{
"block": {
"green_torch": {
"textureData": "torch.png",
"color": [ 143, 115, 73 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "TORCH",
"attachable": "NONE",
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 20,
"isFragile": true,
"isKilledByLava": true,
"isNoWater": true,
"modTextureId": "TORCH_FIRE_GREEN",
"isLighting": true,
"lightColor": [ 20, 0, 32, 0 ],
"lightX": 0,
"lightY": 0,
"lightWi": 1,
"lightHi": 1,
"isFlash": true,
"flashTime": 128,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 100, 100, 40 ],
"exParticle": "torch_particle",
"preset": "Torch",
"covers": [
{
"modTextureId": "torch_fire_green",
"offsetX": 0,
"offsetY": -14
}
]
}
},
"item": {
"green_torch": {
"type": "BLOCKS",
"iconTextureData": "green_torch_icon.png",
"textureData": "torch_entity.png",
"group": "GROUP_TORCH",
"blockId": "green_torch",
"isHandLight": true,
"entityWidth": 8,
"entityHeight": 16,
"handX": 4,
"handY": 14,
"firePoints": [[4,0]]
}
}
}
================================================
FILE: blocks/furnitures/torches/red_torch.json
================================================
{
"block": {
"red_torch": {
"textureData": "torch.png",
"color": [ 143, 115, 73 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "TORCH",
"attachable": "NONE",
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 20,
"isFragile": true,
"isKilledByLava": true,
"isNoWater": true,
"isLighting": true,
"lightColor": [ 24, 32, 0, 0 ],
"lightX": 0,
"lightY": 0,
"lightWi": 1,
"lightHi": 1,
"isFlash": true,
"flashTime": 128,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 100, 100, 40 ],
"exParticle": "torch_particle",
"preset": "Torch",
"covers": [
{
"modTextureId": "torch_fire_red",
"offsetX": 0,
"offsetY": -14
}
]
}
},
"item": {
"red_torch": {
"type": "BLOCKS",
"iconTextureData": "red_torch_icon.png",
"textureData": "torch_entity.png",
"group": "GROUP_TORCH",
"blockId": "red_torch",
"isHandLight": true,
"entityWidth": 8,
"entityHeight": 16,
"handX": 4,
"handY": 14,
"firePoints": [[4,0]]
}
}
}
================================================
FILE: blocks/furnitures/torches/redstone_torch.json
================================================
{
"block": {
"redstone_torch": {
"textureData": "torch.png",
"color": [ 143, 115, 73 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "TORCH",
"attachable": "NONE",
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 20,
"isFragile": true,
"isKilledByLava": true,
"isNoWater": true,
"modTextureId": "TORCH_REDSTONE",
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 100, 100, 40 ],
"exParticle": "torch_particle",
"preset": "RedstoneTorch",
"covers": [
{
"modTextureId": "torch_redstone",
"offsetX": 0,
"offsetY": -14
}
]
}
},
"item": {
"redstone_torch": {
"type": "BLOCKS",
"iconTextureData": "redstone_torch_icon.png",
"group": "GROUP_LIGHTING",
"blockId": "redstone_torch"
}
}
}
================================================
FILE: blocks/furnitures/torches/torch.json
================================================
{
"block": {
"torch": {
"textureData": "torch.png",
"color": [ 110, 90, 57 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "TORCH",
"attachable": "NONE",
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 20,
"isFragile": true,
"isKilledByLava": true,
"isNoWater": true,
"isLighting": true,
"lightColor": [ 30, 0, 0, 0 ],
"lightX": 0,
"lightY": 0,
"lightWi": 1,
"lightHi": 1,
"isFlash": true,
"flashTime": 128,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 100, 100, 40 ],
"exParticle": "torch_particle",
"preset": "Torch",
"covers": [
{
"modTextureId": "torch_fire",
"offsetX": 0,
"offsetY": -14
}
]
}
},
"item": {
"torch": {
"ai": "Torch",
"type": "BLOCKS",
"iconTextureData": "torch_icon.png",
"textureData": "torch_entity.png",
"group": "GROUP_TORCH",
"blockId": "torch",
"fuelTime": 30,
"isHandLight": true,
"entityWidth": 8,
"entityHeight": 16,
"handX": 4,
"handY": 14,
"firePoints": [[4,0]]
}
}
}
================================================
FILE: blocks/furnitures/torches/white_torch.json
================================================
{
"block": {
"white_torch": {
"textureData": "torch.png",
"color": [ 143, 115, 73 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "TORCH",
"attachable": "NONE",
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 20,
"isFragile": true,
"isKilledByLava": true,
"isNoWater": true,
"modTextureId": "TORCH_FIRE_WHITE",
"isLighting": true,
"lightColor": [ 32, 24, 24, 24 ],
"lightX": 0,
"lightY": 0,
"lightWi": 1,
"lightHi": 1,
"isFlash": true,
"flashTime": 128,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 100, 100, 40 ],
"exParticle": "torch_particle",
"preset": "Torch",
"covers": [
{
"modTextureId": "torch_fire_white",
"offsetX": 0,
"offsetY": -14
}
]
}
},
"item": {
"white_torch": {
"type": "BLOCKS",
"iconTextureData": "white_torch_icon.png",
"textureData": "torch_entity.png",
"group": "GROUP_TORCH",
"blockId": "white_torch",
"isHandLight": true,
"entityWidth": 8,
"entityHeight": 16,
"handX": 4,
"handY": 14,
"firePoints": [[4,0]]
}
}
}
================================================
FILE: blocks/furnitures/torches/yellow_torch.json
================================================
{
"block": {
"yellow_torch": {
"textureData": "torch.png",
"color": [ 143, 115, 73 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "TORCH",
"attachable": "NONE",
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 20,
"isFragile": true,
"isKilledByLava": true,
"isNoWater": true,
"isLighting": true,
"lightColor": [ 24, 32, 32, 0 ],
"lightX": 0,
"lightY": 0,
"lightWi": 1,
"lightHi": 1,
"isFlash": true,
"flashTime": 128,
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 100, 100, 40 ],
"exParticle": "torch_particle",
"preset": "Torch",
"covers": [
{
"modTextureId": "torch_fire_yellow",
"offsetX": 0,
"offsetY": -14
}
]
}
},
"item": {
"yellow_torch": {
"type": "BLOCKS",
"iconTextureData": "yellow_torch_icon.png",
"textureData": "torch_entity.png",
"group": "GROUP_TORCH",
"blockId": "yellow_torch",
"isHandLight": true,
"entityWidth": 8,
"entityHeight": 16,
"handX": 4,
"handY": 14,
"firePoints": [[4,0]]
}
}
}
================================================
FILE: blocks/furnitures/vines/eyeball_vine.json
================================================
{
"block": {
"eyeball_vine": {
"textureData": "eyeball_vine.png",
"color": [ 100, 55, 55 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "TOP",
"attachable": "BOTTOM",
"placeCheck": "PLACE_VINE_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 10,
"slipperiness": 1.0,
"isKilledByLava": true,
"isFragile": false,
"isDestroyByWeapon": false,
"soundId": "grass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 100, 55, 55 ],
"preset": "Vine"
}
}
}
================================================
FILE: blocks/furnitures/vines/tainted_vine.json
================================================
{
"block": {
"tainted_vine": {
"textureData": "tainted_vine.png",
"color": [ 80, 40, 120 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "TOP",
"attachable": "BOTTOM",
"placeCheck": "PLACE_VINE_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 10,
"slipperiness": 1.0,
"isKilledByLava": true,
"isFragile": true,
"isDestroyByWeapon": true,
"soundId": "grass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 80, 40, 120 ],
"preset": "Vine"
}
}
}
================================================
FILE: blocks/furnitures/vines/vine.json
================================================
{
"block": {
"vine": {
"textureData": "vine.png",
"color": [ 68, 110, 31 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "TOP",
"attachable": "BOTTOM",
"placeCheck": "PLACE_VINE_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 10,
"slipperiness": 1.0,
"isKilledByLava": true,
"isFragile": true,
"isDestroyByWeapon": true,
"soundId": "grass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 92, 125, 53 ],
"preset": "Vine"
}
}
}
================================================
FILE: blocks/tiles/andesites/andesite.json
================================================
{
"block": {
"andesite": {
"textureData": "andesite.png",
"color": [ 102, 102, 117 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 8,
"type": "TILE",
"group": "ANDESITE",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 140,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": true,
"isWallDark": true,
"wallCheck": "NATURE_GENERABLE_ONLY",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 120, 120, 120 ]
}
},
"item": {
"andesite": {
"type": "BLOCKS",
"iconTextureData": "andesite_icon.png",
"group": "GROUP_ANDESITE",
"blockId": "andesite"
}
}
}
================================================
FILE: blocks/tiles/andesites/andesite_polished.json
================================================
{
"block": {
"andesite_polished": {
"textureData": "andesite_polished.png",
"color": [ 133, 133, 156 ],
"renderMode": "RENDER_BORDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 130,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": true,
"isWallDark": true,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 120, 120, 120 ]
}
},
"item": {
"andesite_polished": {
"type": "BLOCKS",
"iconTextureData": "andesite_polished_icon.png",
"group": "GROUP_ANDESITE",
"blockId": "andesite_polished"
}
}
}
================================================
FILE: blocks/tiles/auroras/aurora_block.json
================================================
{
"block": {
"aurora_block": {
"textureData": "aurora_block.png",
"color": [ 100, 200, 200 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "COBBLESTONE",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "DIAMOND",
"hardness": 150,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": true,
"wallCheck": "NATURE_GENERABLE_ONLY",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 100, 200, 200 ],
"hasColorWave": true
}
}
}
================================================
FILE: blocks/tiles/auroras/aurora_pillar.json
================================================
{
"block": {
"aurora_pillar": {
"textureData": "aurora_pillar.png",
"color": [ 100, 200, 200 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 120,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NATURE_GENERABLE_ONLY",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 100, 200, 200 ],
"hasColorWave": true
}
}
}
================================================
FILE: blocks/tiles/diorites/diorite.json
================================================
{
"block": {
"diorite": {
"textureData": "diorite.png",
"color": [ 144, 144, 144 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 8,
"type": "TILE",
"group": "DIORITE",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 140,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": true,
"isWallDark": true,
"wallCheck": "NATURE_GENERABLE_ONLY",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 170, 170, 170 ]
}
},
"item": {
"diorite": {
"type": "BLOCKS",
"iconTextureData": "diorite_icon.png",
"group": "GROUP_DIORITE",
"blockId": "diorite"
}
}
}
================================================
FILE: blocks/tiles/diorites/diorite_polished.json
================================================
{
"block": {
"diorite_polished": {
"textureData": "diorite_polished.png",
"color": [ 210, 210, 210 ],
"renderMode": "RENDER_BORDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 140,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 170, 170, 170 ]
}
},
"item": {
"diorite_polished": {
"type": "BLOCKS",
"iconTextureData": "diorite_polished_icon.png",
"group": "GROUP_DIORITE",
"blockId": "diorite_polished"
}
}
}
================================================
FILE: blocks/tiles/ends/end_stone.json
================================================
{
"block": {
"end_stone": {
"textureData": "end_stone.png",
"color": [ 198, 198, 188 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 8,
"type": "TILE",
"group": "ENDSTONE",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "STONE",
"hardness": 240,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": true,
"isWallDark": true,
"wallCheck": "GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 180, 180, 150 ]
}
},
"item": {
"end_stone": {
"type": "BLOCKS",
"iconTextureData": "end_stone_icon.png",
"group": "GROUP_ENDSTONE",
"blockId": "end_stone",
"onTest": true
}
}
}
================================================
FILE: blocks/tiles/ends/end_stone_brick.json
================================================
{
"block": {
"end_stone_brick": {
"textureData": "end_stone_brick.png",
"color": [ 227, 227, 215 ],
"renderMode": "RENDER_BORDER_CUT",
"renderSortedInterval": 6,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 230,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NATURE_GENERABLE_ONLY",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 200, 200, 180 ]
}
},
"item": {
"end_stone_brick": {
"type": "BLOCKS",
"iconTextureData": "end_stone_brick_icon.png",
"group": "GROUP_ENDSTONE_BRICK",
"blockId": "end_stone_brick",
"onTest": true
}
}
}
================================================
FILE: blocks/tiles/fences/cobblestone_fence.json
================================================
{
"block": {
"cobblestone_fence": {
"textureData": "cobblestone_fence.png",
"color": [ 111, 111, 111 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 2,
"type": "TILE",
"group": "FENCE",
"collision": "SOLID",
"lightOpacity": 1,
"lightTransparent": true,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 120,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 100, 100, 100 ]
}
},
"item": {
"cobblestone_fence": {
"type": "BLOCKS",
"iconTextureData": "cobblestone_fence_icon.png",
"group": "GROUP_STONE_FENCE",
"blockId": "cobblestone_fence"
}
}
}
================================================
FILE: blocks/tiles/fences/fence_acacia.json
================================================
{
"block": {
"fence_acacia": {
"textureData": "fence_acacia.png",
"color": [ 160, 105, 74 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 2,
"type": "TILE",
"group": "FENCE",
"collision": "SOLID",
"lightOpacity": 1,
"lightTransparent": true,
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 180, 100, 60 ]
}
},
"item": {
"fence_acacia": {
"type": "BLOCKS",
"iconTextureData": "fence_acacia_icon.png",
"group": "GROUP_WOODEN_FENCE",
"blockId": "fence_acacia",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/tiles/fences/fence_birch.json
================================================
{
"block": {
"fence_birch": {
"textureData": "fence_birch.png",
"color": [ 218, 209, 155 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 2,
"type": "TILE",
"group": "FENCE",
"collision": "SOLID",
"lightOpacity": 1,
"lightTransparent": true,
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 200, 200, 130 ]
}
},
"item": {
"fence_birch": {
"type": "BLOCKS",
"iconTextureData": "fence_birch_icon.png",
"group": "GROUP_WOODEN_FENCE",
"blockId": "fence_birch",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/tiles/fences/fence_dark_oak.json
================================================
{
"block": {
"fence_dark_oak": {
"textureData": "fence_dark_oak.png",
"color": [ 100, 80, 60 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 2,
"type": "TILE",
"group": "FENCE",
"collision": "SOLID",
"lightOpacity": 1,
"lightTransparent": true,
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 60, 30, 10 ]
}
},
"item": {
"fence_dark_oak": {
"type": "BLOCKS",
"iconTextureData": "fence_dark_oak_icon.png",
"group": "GROUP_WOODEN_FENCE",
"blockId": "fence_dark_oak",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/tiles/fences/fence_jungle.json
================================================
{
"block": {
"fence_jungle": {
"textureData": "fence_jungle.png",
"color": [ 134, 107, 90 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 2,
"type": "TILE",
"group": "FENCE",
"collision": "SOLID",
"lightOpacity": 1,
"lightTransparent": true,
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 100, 70, 50 ]
}
},
"item": {
"fence_jungle": {
"type": "BLOCKS",
"iconTextureData": "fence_jungle_icon.png",
"group": "GROUP_WOODEN_FENCE",
"blockId": "fence_jungle",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/tiles/fences/fence_nether.json
================================================
{
"block": {
"fence_nether": {
"textureData": "fence_nether.png",
"color": [ 90, 60, 70 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 2,
"type": "TILE",
"group": "FENCE",
"collision": "SOLID",
"lightOpacity": 1,
"lightTransparent": true,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 90, 60, 70 ]
}
},
"item": {
"fence_nether": {
"type": "BLOCKS",
"iconTextureData": "fence_nether_icon.png",
"group": "GROUP_NETHER_FENCE",
"blockId": "fence_nether"
}
}
}
================================================
FILE: blocks/tiles/fences/fence_oak.json
================================================
{
"block": {
"fence_oak": {
"textureData": "fence_oak.png",
"color": [ 159, 132, 77 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 2,
"type": "TILE",
"group": "FENCE",
"collision": "SOLID",
"lightOpacity": 1,
"lightTransparent": true,
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 173, 137, 80 ]
}
},
"item": {
"fence_oak": {
"type": "BLOCKS",
"iconTextureData": "fence_oak_icon.png",
"group": "GROUP_WOODEN_FENCE",
"blockId": "fence_oak",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/tiles/fences/fence_palm.json
================================================
{
"block": {
"fence_palm": {
"textureData": "fence_palm.png",
"color": [ 182, 141, 86 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 2,
"type": "TILE",
"group": "FENCE",
"collision": "SOLID",
"lightOpacity": 1,
"lightTransparent": true,
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 182, 141, 86 ]
}
},
"item": {
"fence_palm": {
"type": "BLOCKS",
"iconTextureData": "fence_palm_icon.png",
"group": "GROUP_WOODEN_FENCE",
"blockId": "fence_palm",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/tiles/fences/fence_spruce.json
================================================
{
"block": {
"fence_spruce": {
"textureData": "fence_spruce.png",
"color": [ 144, 119, 93 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 2,
"type": "TILE",
"group": "FENCE",
"collision": "SOLID",
"lightOpacity": 1,
"lightTransparent": true,
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 120, 90, 60 ]
}
},
"item": {
"fence_spruce": {
"type": "BLOCKS",
"iconTextureData": "fence_spruce_icon.png",
"group": "GROUP_WOODEN_FENCE",
"blockId": "fence_spruce",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/tiles/fences/fence_tainted.json
================================================
{
"block": {
"fence_tainted": {
"textureData": "fence_tainted.png",
"color": [ 89, 85, 107 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 2,
"type": "TILE",
"group": "FENCE",
"collision": "SOLID",
"lightOpacity": 1,
"lightTransparent": true,
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 89, 85, 107 ]
}
},
"item": {
"fence_tainted": {
"type": "BLOCKS",
"iconTextureData": "fence_tainted_icon.png",
"group": "GROUP_WOODEN_FENCE",
"blockId": "fence_tainted",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/tiles/fences/fence_volcano.json
================================================
{
"block": {
"fence_volcano": {
"textureData": "fence_volcano.png",
"color": [ 200, 60, 60 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 2,
"type": "TILE",
"group": "FENCE",
"collision": "SOLID",
"lightOpacity": 1,
"lightTransparent": true,
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 200, 60, 60 ]
}
},
"item": {
"fence_volcano": {
"type": "BLOCKS",
"iconTextureData": "fence_volcano_icon.png",
"group": "GROUP_WOODEN_FENCE",
"blockId": "fence_volcano",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/tiles/fences/iron_bar.json
================================================
{
"block": {
"iron_bar": {
"textureData": "iron_bar.png",
"color": [ 100, 100, 100 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 2,
"type": "TILE",
"group": "BAR",
"collision": "SOLID",
"lightOpacity": 1,
"lightTransparent": true,
"toolType": "PICKAXE",
"mineGrade": "STONE",
"hardness": 200,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 100, 100, 100 ]
}
},
"item": {
"iron_bar": {
"type": "BLOCKS",
"iconTextureData": "iron_bar_icon.png",
"group": "GROUP_OTHERS_BLOCK",
"blockId": "iron_bar"
}
}
}
================================================
FILE: blocks/tiles/fences/mossy_cobblestone_fence.json
================================================
{
"block": {
"mossy_cobblestone_fence": {
"textureData": "mossy_cobblestone_fence.png",
"color": [ 73, 100, 77 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 2,
"type": "TILE",
"group": "FENCE",
"collision": "SOLID",
"lightOpacity": 1,
"lightTransparent": true,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 120,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 100, 100, 100 ]
}
},
"item": {
"mossy_cobblestone_fence": {
"type": "BLOCKS",
"iconTextureData": "mossy_cobblestone_fence_icon.png",
"group": "GROUP_STONE_FENCE",
"blockId": "mossy_cobblestone_fence"
}
}
}
================================================
FILE: blocks/tiles/fleshes/flesh_dirt.json
================================================
{
"block": {
"flesh_dirt": {
"textureData": "flesh_dirt.png",
"color": [ 120, 36, 40 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 8,
"type": "TILE",
"group": "FLESH_DIRT",
"collision": "SOLID",
"growGroup": "FLESH_GROUP",
"hangGrowGroup": "FLESH_GROUP",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 90,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": true,
"isWallDark": true,
"hasGrassCover": true,
"isRipen": true,
"wallCheck": "GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 120, 36, 40 ],
"preset": "GrowGrass",
"covers": [
{
"modTextureId": "flesh_grass",
"offsetX": -8,
"offsetY": -8
}
]
}
},
"item": {
"flesh_dirt": {
"type": "BLOCKS",
"iconTextureData": "flesh_dirt_icon.png",
"group": "GROUP_FLESH",
"blockId": "flesh_dirt"
}
}
}
================================================
FILE: blocks/tiles/fleshes/flesh_gut.json
================================================
{
"block": {
"flesh_gut": {
"textureData": "flesh_gut.png",
"color": [ 120, 36, 40 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 8,
"type": "TILE",
"group": "FLESH_GUT",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 90,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": true,
"isWallDark": true,
"wallCheck": "GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 120, 36, 40 ]
}
},
"item": {
"flesh_gut": {
"type": "BLOCKS",
"iconTextureData": "flesh_gut_icon.png",
"group": "GROUP_FLESH",
"blockId": "flesh_gut"
}
}
}
================================================
FILE: blocks/tiles/fleshes/flesh_stone.json
================================================
{
"block": {
"flesh_stone": {
"textureData": "flesh_stone.png",
"color": [ 103, 29, 25 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 8,
"type": "TILE",
"group": "FLESH_STONE",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "STONE",
"hardness": 180,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": true,
"isWallDark": true,
"wallCheck": "GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 103, 29, 25 ]
}
},
"item": {
"flesh_stone": {
"type": "BLOCKS",
"iconTextureData": "flesh_stone_icon.png",
"group": "GROUP_FLESH",
"blockId": "flesh_stone"
}
}
}
================================================
FILE: blocks/tiles/glasses/glass.json
================================================
{
"block": {
"glass": {
"textureData": "glass.png",
"color": [ 233, 233, 255 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 10,
"type": "TILE",
"group": "GLASS",
"collision": "SOLID",
"lightOpacity": 1,
"lightTransparent": true,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 50,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "glass",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 200, 200, 200 ]
}
},
"item": {
"glass": {
"type": "BLOCKS",
"iconTextureData": "glass_icon.png",
"group": "GROUP_GLASS",
"blockId": "glass",
"oreDictionary": [ "OD_GLASS" ]
}
}
}
================================================
FILE: blocks/tiles/glasses/stained_glass_black.json
================================================
{
"block": {
"stained_glass_black": {
"textureData": "stained_glass_black.png",
"color": [ 99, 99, 99 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "GLASS",
"collision": "SOLID",
"lightOpacity": 1,
"lightTransparent": true,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 50,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "glass",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 0, 0, 0 ]
}
},
"item": {
"stained_glass_black": {
"type": "BLOCKS",
"iconTextureData": "stained_glass_black_icon.png",
"group": "GROUP_GLASS",
"blockId": "stained_glass_black",
"oreDictionary": [ "OD_GLASS" ]
}
}
}
================================================
FILE: blocks/tiles/glasses/stained_glass_blue.json
================================================
{
"block": {
"stained_glass_blue": {
"textureData": "stained_glass_blue.png",
"color": [ 119, 129, 188 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "GLASS",
"collision": "SOLID",
"lightOpacity": 1,
"lightTransparent": true,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 50,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "glass",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 0, 0, 120 ]
}
},
"item": {
"stained_glass_blue": {
"type": "BLOCKS",
"iconTextureData": "stained_glass_blue_icon.png",
"group": "GROUP_GLASS",
"blockId": "stained_glass_blue",
"oreDictionary": [ "OD_GLASS" ]
}
}
}
================================================
FILE: blocks/tiles/glasses/stained_glass_brown.json
================================================
{
"block": {
"stained_glass_brown": {
"textureData": "stained_glass_brown.png",
"color": [ 167, 133, 108 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "GLASS",
"collision": "SOLID",
"lightOpacity": 1,
"lightTransparent": true,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 50,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "glass",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 130, 100, 50 ]
}
},
"item": {
"stained_glass_brown": {
"type": "BLOCKS",
"iconTextureData": "stained_glass_brown_icon.png",
"group": "GROUP_GLASS",
"blockId": "stained_glass_brown",
"oreDictionary": [ "OD_GLASS" ]
}
}
}
================================================
FILE: blocks/tiles/glasses/stained_glass_cyan.json
================================================
{
"block": {
"stained_glass_cyan": {
"textureData": "stained_glass_cyan.png",
"color": [ 88, 180, 180 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "GLASS",
"collision": "SOLID",
"lightOpacity": 1,
"lightTransparent": true,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 50,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "glass",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 0, 120, 120 ]
}
},
"item": {
"stained_glass_cyan": {
"type": "BLOCKS",
"iconTextureData": "stained_glass_cyan_icon.png",
"group": "GROUP_GLASS",
"blockId": "stained_glass_cyan",
"oreDictionary": [ "OD_GLASS" ]
}
}
}
================================================
FILE: blocks/tiles/glasses/stained_glass_gray.json
================================================
{
"block": {
"stained_glass_gray": {
"textureData": "stained_glass_gray.png",
"color": [ 125, 125, 128 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "GLASS",
"collision": "SOLID",
"lightOpacity": 1,
"lightTransparent": true,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 50,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "glass",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 60, 60, 60 ]
}
},
"item": {
"stained_glass_gray": {
"type": "BLOCKS",
"iconTextureData": "stained_glass_gray_icon.png",
"group": "GROUP_GLASS",
"blockId": "stained_glass_gray",
"oreDictionary": [ "OD_GLASS" ]
}
}
}
================================================
FILE: blocks/tiles/glasses/stained_glass_green.json
================================================
{
"block": {
"stained_glass_green": {
"textureData": "stained_glass_green.png",
"color": [ 144, 66, 92 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "GLASS",
"collision": "SOLID",
"lightOpacity": 1,
"lightTransparent": true,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 50,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "glass",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 0, 120, 0 ]
}
},
"item": {
"stained_glass_green": {
"type": "BLOCKS",
"iconTextureData": "stained_glass_green_icon.png",
"group": "GROUP_GLASS",
"blockId": "stained_glass_green",
"oreDictionary": [ "OD_GLASS" ]
}
}
}
================================================
FILE: blocks/tiles/glasses/stained_glass_light_blue.json
================================================
{
"block": {
"stained_glass_light_blue": {
"textureData": "stained_glass_light_blue.png",
"color": [ 130, 215, 240 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "GLASS",
"collision": "SOLID",
"lightOpacity": 1,
"lightTransparent": true,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 50,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "glass",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 60, 90, 120 ]
}
},
"item": {
"stained_glass_light_blue": {
"type": "BLOCKS",
"iconTextureData": "stained_glass_light_blue_icon.png",
"group": "GROUP_GLASS",
"blockId": "stained_glass_light_blue",
"oreDictionary": [ "OD_GLASS" ]
}
}
}
================================================
FILE: blocks/tiles/glasses/stained_glass_light_gray.json
================================================
{
"block": {
"stained_glass_light_gray": {
"textureData": "stained_glass_light_gray.png",
"color": [ 160, 166, 169 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "GLASS",
"collision": "SOLID",
"lightOpacity": 1,
"lightTransparent": true,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 50,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "glass",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 120, 120, 100 ]
}
},
"item": {
"stained_glass_light_gray": {
"type": "BLOCKS",
"iconTextureData": "stained_glass_light_gray_icon.png",
"group": "GROUP_GLASS",
"blockId": "stained_glass_light_gray",
"oreDictionary": [ "OD_GLASS" ]
}
}
}
================================================
FILE: blocks/tiles/glasses/stained_glass_lime.json
================================================
{
"block": {
"stained_glass_lime": {
"textureData": "stained_glass_lime.png",
"color": [ 171, 212, 151 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "GLASS",
"collision": "SOLID",
"lightOpacity": 1,
"lightTransparent": true,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 50,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "glass",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 50, 100, 0 ]
}
},
"item": {
"stained_glass_lime": {
"type": "BLOCKS",
"iconTextureData": "stained_glass_lime_icon.png",
"group": "GROUP_GLASS",
"blockId": "stained_glass_lime",
"oreDictionary": [ "OD_GLASS" ]
}
}
}
================================================
FILE: blocks/tiles/glasses/stained_glass_magenta.json
================================================
{
"block": {
"stained_glass_magenta": {
"textureData": "stained_glass_magenta.png",
"color": [ 202, 109, 193 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "GLASS",
"collision": "SOLID",
"lightOpacity": 1,
"lightTransparent": true,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 50,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "glass",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 120, 60, 120 ]
}
},
"item": {
"stained_glass_magenta": {
"type": "BLOCKS",
"iconTextureData": "stained_glass_magenta_icon.png",
"group": "GROUP_GLASS",
"blockId": "stained_glass_magenta",
"oreDictionary": [ "OD_GLASS" ]
}
}
}
================================================
FILE: blocks/tiles/glasses/stained_glass_orange.json
================================================
{
"block": {
"stained_glass_orange": {
"textureData": "stained_glass_orange.png",
"color": [ 248, 116, 93 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "GLASS",
"collision": "SOLID",
"lightOpacity": 1,
"lightTransparent": true,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 50,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "glass",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 140, 120, 100 ]
}
},
"item": {
"stained_glass_orange": {
"type": "BLOCKS",
"iconTextureData": "stained_glass_orange_icon.png",
"group": "GROUP_GLASS",
"blockId": "stained_glass_orange",
"oreDictionary": [ "OD_GLASS" ]
}
}
}
================================================
FILE: blocks/tiles/glasses/stained_glass_pink.json
================================================
{
"block": {
"stained_glass_pink": {
"textureData": "stained_glass_pink.png",
"color": [ 212, 155, 188 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "GLASS",
"collision": "SOLID",
"lightOpacity": 1,
"lightTransparent": true,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 50,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "glass",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 130, 100, 100 ]
}
},
"item": {
"stained_glass_pink": {
"type": "BLOCKS",
"iconTextureData": "stained_glass_pink_icon.png",
"group": "GROUP_GLASS",
"blockId": "stained_glass_pink",
"oreDictionary": [ "OD_GLASS" ]
}
}
}
================================================
FILE: blocks/tiles/glasses/stained_glass_purple.json
================================================
{
"block": {
"stained_glass_purple": {
"textureData": "stained_glass_purple.png",
"color": [ 90, 114, 204 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "GLASS",
"collision": "SOLID",
"lightOpacity": 1,
"lightTransparent": true,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 50,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "glass",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 60, 30, 120 ]
}
},
"item": {
"stained_glass_purple": {
"type": "BLOCKS",
"iconTextureData": "stained_glass_purple_icon.png",
"group": "GROUP_GLASS",
"blockId": "stained_glass_purple",
"oreDictionary": [ "OD_GLASS" ]
}
}
}
================================================
FILE: blocks/tiles/glasses/stained_glass_red.json
================================================
{
"block": {
"stained_glass_red": {
"textureData": "stained_glass_red.png",
"color": [ 186, 100, 97 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "GLASS",
"collision": "SOLID",
"lightOpacity": 1,
"lightTransparent": true,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 50,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "glass",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 120, 0, 0 ]
}
},
"item": {
"stained_glass_red": {
"type": "BLOCKS",
"iconTextureData": "stained_glass_red_icon.png",
"group": "GROUP_GLASS",
"blockId": "stained_glass_red",
"oreDictionary": [ "OD_GLASS" ]
}
}
}
================================================
FILE: blocks/tiles/glasses/stained_glass_white.json
================================================
{
"block": {
"stained_glass_white": {
"note": "各色玻璃 186:0-15",
"textureData": "stained_glass_white.png",
"color": [ 201, 208, 208 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "GLASS",
"collision": "SOLID",
"lightOpacity": 1,
"lightTransparent": true,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 50,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "glass",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 200, 170, 150 ]
}
},
"item": {
"stained_glass_white": {
"type": "BLOCKS",
"iconTextureData": "stained_glass_white_icon.png",
"group": "GROUP_GLASS",
"blockId": "stained_glass_white",
"oreDictionary": [ "OD_GLASS" ]
}
}
}
================================================
FILE: blocks/tiles/glasses/stained_glass_yellow.json
================================================
{
"block": {
"stained_glass_yellow": {
"textureData": "stained_glass_yellow.png",
"color": [ 252, 218, 96 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "GLASS",
"collision": "SOLID",
"lightOpacity": 1,
"lightTransparent": true,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 50,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "glass",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 120, 120, 0 ]
}
},
"item": {
"stained_glass_yellow": {
"type": "BLOCKS",
"iconTextureData": "stained_glass_yellow_icon.png",
"group": "GROUP_GLASS",
"blockId": "stained_glass_yellow",
"oreDictionary": [ "OD_GLASS" ]
}
}
}
================================================
FILE: blocks/tiles/granites/granite.json
================================================
{
"block": {
"granite": {
"textureData": "granite.png",
"color": [ 127, 92, 48 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 8,
"type": "TILE",
"group": "GRANITE",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "STONE",
"hardness": 180,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": true,
"isWallDark": true,
"wallCheck": "NATURE_GENERABLE_ONLY",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 175, 137, 122 ]
}
},
"item": {
"granite": {
"type": "BLOCKS",
"iconTextureData": "granite_icon.png",
"group": "GROUP_GRANITE",
"blockId": "granite"
}
}
}
================================================
FILE: blocks/tiles/granites/granite_polished.json
================================================
{
"block": {
"granite_polished": {
"textureData": "granite_polished.png",
"color": [ 145, 112, 85 ],
"renderMode": "RENDER_BORDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "STONE",
"hardness": 170,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NATURE_GENERABLE_ONLY",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 175, 137, 122 ]
}
},
"item": {
"granite_polished": {
"type": "BLOCKS",
"iconTextureData": "granite_polished_icon.png",
"group": "GROUP_GRANITE",
"blockId": "granite_polished"
}
}
}
================================================
FILE: blocks/tiles/ices/blue_ice.json
================================================
{
"block": {
"blue_ice": {
"textureData": "blue_ice.png",
"color": [ 114, 161, 247 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 8,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 2,
"isLighting": true,
"lightColor": [ 10, 0, 0, 0 ],
"lightX": 0,
"lightY": 0,
"lightWi": 1,
"lightHi": 1,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 60,
"slipperiness": 0.2,
"isLossyCollection": true,
"gravity": false,
"allowSlope": false,
"isWallDark": true,
"wallCheck": "NATURE_GENERABLE_ONLY",
"soundGroupId": "glass",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 114, 161, 247 ]
}
},
"item": {
"blue_ice": {
"type": "BLOCKS",
"iconTextureData": "blue_ice_icon.png",
"group": "GROUP_SNOW_BRICK",
"blockId": "blue_ice"
}
}
}
================================================
FILE: blocks/tiles/ices/ice.json
================================================
{
"block": {
"ice": {
"textureData": "ice.png",
"color": [ 207, 207, 255 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 8,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 2,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 60,
"slipperiness": 0.5,
"isLossyCollection": true,
"gravity": false,
"allowSlope": false,
"isWallDark": true,
"wallCheck": "NATURE_GENERABLE_ONLY",
"soundGroupId": "glass",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 170, 200, 255 ]
}
},
"item": {
"ice": {
"type": "BLOCKS",
"iconTextureData": "ice_icon.png",
"group": "GROUP_SNOW_BRICK",
"blockId": "ice"
}
}
}
================================================
FILE: blocks/tiles/ices/ice_brick.json
================================================
{
"block": {
"ice_brick": {
"textureData": "ice_brick.png",
"color": [ 80, 251, 251 ],
"renderMode": "RENDER_BORDER_CUT",
"renderSortedInterval": 6,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 140,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "glass",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 30, 255, 255 ]
}
},
"item": {
"ice_brick": {
"type": "BLOCKS",
"iconTextureData": "ice_brick_icon.png",
"group": "GROUP_ICE_BRICK",
"blockId": "ice_brick"
}
}
}
================================================
FILE: blocks/tiles/ices/ice_cobblestone.json
================================================
{
"block": {
"ice_cobblestone": {
"textureData": "ice_cobblestone.png",
"color": [ 12, 200, 200 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 8,
"type": "TILE",
"group": "ICECOBBLESTONE",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 220,
"slipperiness": 0.8,
"gravity": false,
"allowSlope": true,
"isWallDark": true,
"wallCheck": "NATURE_GENERABLE_ONLY",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 180, 220, 220 ]
}
},
"item": {
"ice_cobblestone": {
"type": "BLOCKS",
"iconTextureData": "ice_cobblestone_icon.png",
"group": "GROUP_ICE_COBBLESTONE",
"blockId": "ice_cobblestone"
}
}
}
================================================
FILE: blocks/tiles/ices/ice_packed.json
================================================
{
"block": {
"ice_packed": {
"textureData": "ice_packed.png",
"color": [ 190, 190, 255 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 8,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 2,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 60,
"slipperiness": 0.6,
"isLossyCollection": true,
"gravity": false,
"allowSlope": false,
"isWallDark": true,
"wallCheck": "NATURE_GENERABLE_ONLY",
"soundGroupId": "glass",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 200, 220, 240 ]
}
},
"item": {
"ice_packed": {
"type": "BLOCKS",
"iconTextureData": "ice_packed_icon.png",
"group": "GROUP_SNOW_BRICK",
"blockId": "ice_packed"
}
}
}
================================================
FILE: blocks/tiles/ices/ice_thin.json
================================================
{
"block": {
"ice_thin": {
"textureData": "ice_thin.png",
"color": [ 190, 190, 255 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 8,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 2,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 60,
"slipperiness": 0.6,
"isLossyCollection": true,
"gravity": false,
"allowSlope": false,
"isWallDark": true,
"wallCheck": "NATURE_GENERABLE_ONLY",
"soundGroupId": "glass",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 200, 220, 240 ],
"preset": "IceSmelt"
}
}
}
================================================
FILE: blocks/tiles/misc/bedrock.json
================================================
{
"block": {
"bedrock": {
"textureData": "bedrock.png",
"color": [ 77, 77, 77 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "DIAMOND",
"hardness": 1000000000,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 77, 77, 77 ]
}
}
}
================================================
FILE: blocks/tiles/misc/bone_block.json
================================================
{
"block": {
"bone_block": {
"textureData": "bone_block.png",
"color": [ 200, 200, 180 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "COBBLESTONE",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 150,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": true,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 200, 200, 170 ]
}
},
"item": {
"bone_block": {
"type": "BLOCKS",
"iconTextureData": "bone_block_icon.png",
"group": "GROUP_OTHERS_BLOCK",
"blockId": "bone_block"
}
}
}
================================================
FILE: blocks/tiles/misc/brick.json
================================================
{
"block": {
"brick": {
"textureData": "brick.png",
"color": [ 123, 51, 37 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 10,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 130,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 120, 50, 36 ]
}
},
"item": {
"brick": {
"type": "BLOCKS",
"iconTextureData": "brick_icon.png",
"group": "GROUP_OTHERS_BLOCK",
"blockId": "brick"
}
}
}
================================================
FILE: blocks/tiles/misc/clay.json
================================================
{
"block": {
"clay": {
"textureData": "clay.png",
"color": [ 133, 133, 146 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 8,
"type": "TILE",
"group": "CLAY",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 80,
"isChipCollection": true,
"lossyItemId": "clay",
"chipCount": 4,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": true,
"wallCheck": "GENERABLE",
"soundGroupId": "dirt",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 160, 160, 180 ]
}
},
"item": {
"clay_block": {
"type": "BLOCKS",
"iconTextureData": "clay_icon.png",
"group": "GROUP_OTHERS_BLOCK",
"blockId": "clay"
}
}
}
================================================
FILE: blocks/tiles/misc/coarse_dirt.json
================================================
{
"block": {
"coarse_dirt": {
"textureData": "coarse_dirt.png",
"color": [ 87, 63, 43 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 8,
"type": "TILE",
"group": "COARSE_DIRT",
"collision": "SOLID",
"growGroup": "NORMAL_GROUP",
"hangGrowGroup": "NORMAL_GROUP",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 60,
"isLossyCollection": true,
"lossyItemId": "dirt",
"slipperiness": 1.0,
"isKilledByLava": true,
"gravity": false,
"allowSlope": true,
"isWallDark": true,
"hasGrassCover": true,
"isRipen": true,
"wallCheck": "GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 91, 64, 44 ],
"preset": "GrowGrass",
"covers": [
{
"modTextureId": "grass",
"offsetX": -8,
"offsetY": -8
}
]
}
},
"item": {
"coarse_dirt": {
"type": "BLOCKS",
"iconTextureData": "coarse_dirt_icon.png",
"group": "GROUP_DIRT",
"blockId": "coarse_dirt"
}
}
}
================================================
FILE: blocks/tiles/misc/dirt.json
================================================
{
"block": {
"dirt": {
"textureData": "dirt.png",
"color": [ 90, 57, 43 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 8,
"type": "TILE",
"group": "DIRT",
"collision": "SOLID",
"growGroup": "NORMAL_GROUP",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 60,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": true,
"isWallDark": true,
"hasGrassCover": true,
"isRipen": true,
"wallCheck": "GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 91, 64, 44 ],
"preset": "GrowGrass",
"covers": [
{
"modTextureId": "grass",
"offsetX": -8,
"offsetY": -8
}
]
}
},
"item": {
"dirt": {
"type": "BLOCKS",
"iconTextureData": "dirt_icon.png",
"group": "GROUP_DIRT",
"blockId": "dirt"
}
}
}
================================================
FILE: blocks/tiles/misc/dried_kelp_block.json
================================================
{
"block": {
"dried_kelp_block": {
"textureData": "dried_kelp_block.png",
"color": [ 47, 59, 42 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 2,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 70,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "grass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 47, 59, 42 ]
}
},
"item": {
"dried_kelp_block": {
"type": "BLOCKS",
"iconTextureData": "dried_kelp_block_icon.png",
"group": "GROUP_OTHERS_BLOCK",
"blockId": "dried_kelp_block",
"fuelTime": 800
}
}
}
================================================
FILE: blocks/tiles/misc/farmland.json
================================================
{
"block": {
"farmland": {
"textureData": "farmland.png",
"color": [ 96, 68, 49 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "DIRT",
"farmGroup": "FARMLAND_GROUP",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 60,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": true,
"wallCheck": "NO_GENERABLE",
"isLossyCollection": true,
"lossyItemId": "dirt",
"soundGroupId": "stone",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 116, 80, 60 ],
"preset": "Farmland"
}
},
"item": {
"farmland": {
"type": "BLOCKS",
"iconTextureData": "farmland_icon.png",
"group": "GROUP_DIRT",
"blockId": "farmland"
}
}
}
================================================
FILE: blocks/tiles/misc/gravel.json
================================================
{
"block": {
"gravel": {
"textureData": "gravel.png",
"color": [ 150, 130, 130 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "GRAVEL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 60,
"slipperiness": 1.0,
"gravity": true,
"allowSlope": false,
"isWallDark": true,
"wallCheck": "GENERABLE",
"chanceItemId": "flint",
"chanceDrop": 0.4,
"soundGroupId": "dirt",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 100, 100, 100 ]
}
},
"item": {
"gravel": {
"type": "BLOCKS",
"iconTextureData": "gravel_icon.png",
"group": "GROUP_OTHERS_BLOCK",
"blockId": "gravel"
}
}
}
================================================
FILE: blocks/tiles/misc/hay_bale.json
================================================
{
"block": {
"hay_bale": {
"textureData": "hay_bale.png",
"color": [ 205, 171, 0 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 2,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 70,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "grass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 200, 160, 0 ]
}
},
"item": {
"hay_bale": {
"type": "BLOCKS",
"iconTextureData": "hay_bale_icon.png",
"group": "GROUP_OTHERS_BLOCK",
"blockId": "hay_bale"
}
}
}
================================================
FILE: blocks/tiles/misc/obsidian.json
================================================
{
"block": {
"obsidian": {
"textureData": "obsidian.png",
"color": [ 28, 28, 60 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "OBSIDIAN",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "DIAMOND",
"hardness": 1500,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": true,
"wallCheck": "NATURE_GENERABLE_ONLY",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 0, 0, 0 ]
}
},
"item": {
"obsidian": {
"type": "BLOCKS",
"iconTextureData": "obsidian_icon.png",
"group": "GROUP_OTHERS_BLOCK",
"blockId": "obsidian",
"antiLava": true
}
}
}
================================================
FILE: blocks/tiles/misc/slime_block.json
================================================
{
"block": {
"slime_block": {
"textureData": "slime_block.png",
"color": [ 180, 240, 160 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "SLIME_BLOCK",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 70,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "cloth",
"stepSoundId": "step_cloth",
"particleColor": [ 255, 100, 220, 160 ]
}
},
"item": {
"slime_block": {
"type": "BLOCKS",
"iconTextureData": "slime_block_icon.png",
"group": "GROUP_OTHERS_BLOCK",
"blockId": "slime_block"
}
}
}
================================================
FILE: blocks/tiles/misc/tnt.json
================================================
{
"block": {
"tnt": {
"textureData": "tnt.png",
"color": [ 148, 26, 22 ],
"renderMode": "RENDER_BLOCK",
"renderSortedInterval": 1,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 20,
"slipperiness": 1.0,
"isFragile": true,
"gravity": false,
"allowSlope": false,
"isWallDark": true,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "grass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 200, 44, 44 ],
"preset": "TNT"
}
},
"item": {
"tnt": {
"type": "BLOCKS",
"iconTextureData": "tnt_icon.png",
"group": "GROUP_OTHERS_BLOCK",
"blockId": "tnt"
}
}
}
================================================
FILE: blocks/tiles/mushrooms/brown_mushroom_block.json
================================================
{
"block": {
"brown_mushroom_block": {
"textureData": "brown_mushroom_block.png",
"color": [ 130, 100, 80 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 70,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": true,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "cloth",
"stepSoundId": "step_cloth",
"particleColor": [ 255, 130, 100, 80 ]
}
},
"item": {
"brown_mushroom_block": {
"type": "BLOCKS",
"iconTextureData": "brown_mushroom_block_icon.png",
"group": "GROUP_MUSHROOM_BLOCK",
"blockId": "brown_mushroom_block"
}
}
}
================================================
FILE: blocks/tiles/mushrooms/mushroom_stem.json
================================================
{
"block": {
"mushroom_stem": {
"textureData": "mushroom_stem.png",
"color": [ 203, 172, 122 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "MUSHROOM",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 70,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": true,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "cloth",
"stepSoundId": "step_cloth",
"particleColor": [ 255, 141, 141, 130 ]
}
},
"item": {
"mushroom_stem": {
"type": "BLOCKS",
"iconTextureData": "mushroom_stem_icon.png",
"group": "GROUP_MUSHROOM_BLOCK",
"blockId": "mushroom_stem"
}
}
}
================================================
FILE: blocks/tiles/mushrooms/mycelium.json
================================================
{
"block": {
"mycelium": {
"textureData": "mycelium.png",
"color": [ 123, 100, 100 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 8,
"type": "TILE",
"group": "DIRT",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 60,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": true,
"isWallDark": true,
"hasGrassCover": true,
"isRipen": true,
"wallCheck": "NATURE_GENERABLE_ONLY",
"soundGroupId": "stone",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 123, 100, 100 ],
"preset": "GrowGrass",
"covers": [
{
"modTextureId": "mycelium_grass",
"offsetX": -8,
"offsetY": -8
}
]
}
},
"item": {
"mycelium": {
"type": "BLOCKS",
"iconTextureData": "mycelium_icon.png",
"group": "GROUP_MUSHROOM_BLOCK",
"blockId": "mycelium"
}
}
}
================================================
FILE: blocks/tiles/mushrooms/red_mushroom_block.json
================================================
{
"block": {
"red_mushroom_block": {
"textureData": "red_mushroom_block.png",
"color": [ 178, 28, 28 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 70,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": true,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "cloth",
"stepSoundId": "step_cloth",
"particleColor": [ 255, 160, 20, 20 ]
}
},
"item": {
"red_mushroom_block": {
"type": "BLOCKS",
"iconTextureData": "red_mushroom_block_icon.png",
"group": "GROUP_MUSHROOM_BLOCK",
"blockId": "red_mushroom_block"
}
}
}
================================================
FILE: blocks/tiles/nethers/glowstone.json
================================================
{
"block": {
"glowstone": {
"textureData": "glowstone.png",
"color": [ 224, 200, 134 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "GLOWSTONE",
"collision": "SOLID",
"lightOpacity": 3,
"isLighting": true,
"lightColor": [ 26, 5, 5, 0 ],
"lightX": 0,
"lightY": 0,
"lightWi": 1,
"lightHi": 1,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 120,
"isChipCollection": true,
"lossyItemId": "glowstone_dust",
"chipCount": 3,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": true,
"wallCheck": "GENERABLE",
"soundGroupId": "glass",
"stepSoundId": "step_cloth",
"particleColor": [ 255, 255, 185, 87 ]
}
},
"item": {
"glowstone": {
"type": "BLOCKS",
"iconTextureData": "glowstone_icon.png",
"group": "GROUP_OTHERS_BLOCK",
"blockId": "glowstone"
}
}
}
================================================
FILE: blocks/tiles/nethers/nether_brick.json
================================================
{
"block": {
"nether_brick": {
"textureData": "nether_brick.png",
"color": [ 66, 24, 29 ],
"renderMode": "RENDER_BORDER_CUT",
"renderSortedInterval": 6,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NATURE_GENERABLE_ONLY",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 70, 40, 50 ]
}
},
"item": {
"nether_brick_block": {
"type": "BLOCKS",
"iconTextureData": "nether_brick_icon.png",
"group": "GROUP_NETHER_BRICK",
"blockId": "nether_brick"
}
}
}
================================================
FILE: blocks/tiles/nethers/netherrack.json
================================================
{
"block": {
"netherrack": {
"textureData": "netherrack.png",
"color": [ 38, 33, 30 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 8,
"type": "TILE",
"group": "NETHERRACK",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 90,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": true,
"isWallDark": true,
"wallCheck": "GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 57, 52, 46 ]
}
},
"item": {
"netherrack": {
"type": "BLOCKS",
"iconTextureData": "netherrack_icon.png",
"group": "GROUP_NETHER",
"blockId": "netherrack"
}
}
}
================================================
FILE: blocks/tiles/nethers/red_nether_brick.json
================================================
{
"block": {
"red_nether_brick": {
"textureData": "red_nether_brick.png",
"color": [ 80, 0, 0 ],
"renderMode": "RENDER_BORDER_CUT",
"renderSortedInterval": 6,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NATURE_GENERABLE_ONLY",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 100, 0, 0 ]
}
},
"item": {
"red_nether_brick": {
"type": "BLOCKS",
"iconTextureData": "red_nether_brick_icon.png",
"group": "GROUP_NETHER_BRICK",
"blockId": "red_nether_brick"
}
}
}
================================================
FILE: blocks/tiles/nethers/soul_sand.json
================================================
{
"block": {
"soul_sand": {
"textureData": "soul_sand.png",
"color": [ 66, 53, 45 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "SOUL_SAND",
"farmGroup": "SOULSAND_GROUP",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 80,
"slipperiness": 1.5,
"gravity": false,
"allowSlope": false,
"isWallDark": true,
"wallCheck": "GENERABLE",
"soundGroupId": "sand",
"stepSoundId": "step_sand",
"particleColor": [ 255, 44, 33, 22 ],
"preset": "SoulSand"
}
},
"item": {
"soul_sand": {
"type": "BLOCKS",
"iconTextureData": "soul_sand_icon.png",
"group": "GROUP_OTHERS_BLOCK",
"blockId": "soul_sand"
}
}
}
================================================
FILE: blocks/tiles/ore_blocks/block_coal.json
================================================
{
"block": {
"block_coal": {
"textureData": "block_coal.png",
"color": [ 55, 55, 55 ],
"renderMode": "RENDER_BLOCK",
"renderSortedInterval": 2,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 33, 33, 33 ]
}
},
"item": {
"block_coal": {
"type": "BLOCKS",
"iconTextureData": "block_coal_icon.png",
"group": "GROUP_ORE_BLOCK",
"blockId": "block_coal",
"fuelTime": 1600
}
}
}
================================================
FILE: blocks/tiles/ore_blocks/block_diamond.json
================================================
{
"block": {
"block_diamond": {
"textureData": "block_diamond.png",
"color": [ 186, 230, 234 ],
"renderMode": "RENDER_BLOCK",
"renderSortedInterval": 2,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "IRON",
"hardness": 240,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 188, 233, 233 ]
}
},
"item": {
"block_diamond": {
"type": "BLOCKS",
"iconTextureData": "block_diamond_icon.png",
"group": "GROUP_ORE_BLOCK",
"blockId": "block_diamond"
}
}
}
================================================
FILE: blocks/tiles/ore_blocks/block_emerald.json
================================================
{
"block": {
"block_emerald": {
"textureData": "block_emerald.png",
"color": [ 76, 223, 107 ],
"renderMode": "RENDER_BLOCK",
"renderSortedInterval": 2,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "IRON",
"hardness": 180,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 54, 200, 88 ]
}
},
"item": {
"block_emerald": {
"type": "BLOCKS",
"iconTextureData": "block_emerald_icon.png",
"group": "GROUP_ORE_BLOCK",
"blockId": "block_emerald"
}
}
}
================================================
FILE: blocks/tiles/ore_blocks/block_gold.json
================================================
{
"block": {
"block_gold": {
"textureData": "block_gold.png",
"color": [ 255, 255, 0 ],
"renderMode": "RENDER_BLOCK",
"renderSortedInterval": 2,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "IRON",
"hardness": 180,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 222, 222, 0 ]
}
},
"item": {
"block_gold": {
"type": "BLOCKS",
"iconTextureData": "block_gold_icon.png",
"group": "GROUP_ORE_BLOCK",
"blockId": "block_gold"
}
}
}
================================================
FILE: blocks/tiles/ore_blocks/block_iron.json
================================================
{
"block": {
"block_iron": {
"textureData": "block_iron.png",
"color": [ 233, 233, 233 ],
"renderMode": "RENDER_BLOCK",
"renderSortedInterval": 2,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 120,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 222, 222, 222 ]
}
},
"item": {
"block_iron": {
"type": "BLOCKS",
"iconTextureData": "block_iron_icon.png",
"group": "GROUP_ORE_BLOCK",
"blockId": "block_iron"
}
}
}
================================================
FILE: blocks/tiles/ore_blocks/block_lapis.json
================================================
{
"block": {
"block_lapis": {
"textureData": "block_lapis.png",
"color": [ 12, 18, 55 ],
"renderMode": "RENDER_BLOCK",
"renderSortedInterval": 2,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "STONE",
"hardness": 160,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 10, 20, 40 ]
}
},
"item": {
"block_lapis": {
"type": "BLOCKS",
"iconTextureData": "block_lapis_icon.png",
"group": "GROUP_ORE_BLOCK",
"blockId": "block_lapis"
}
}
}
================================================
FILE: blocks/tiles/ore_blocks/block_netherite.json
================================================
{
"block": {
"block_netherite": {
"textureData": "block_netherite.png",
"color": [ 58, 55, 58 ],
"renderMode": "RENDER_BLOCK",
"renderSortedInterval": 2,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "DIAMOND",
"hardness": 320,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 58, 55, 58 ]
}
},
"item": {
"block_netherite": {
"type": "BLOCKS",
"iconTextureData": "block_netherite_icon.png",
"group": "GROUP_ORE_BLOCK",
"blockId": "block_netherite",
"antiLava": true
}
}
}
================================================
FILE: blocks/tiles/ore_blocks/block_quartz.json
================================================
{
"block": {
"block_quartz": {
"textureData": "block_quartz.png",
"color": [ 218, 214, 202 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 120,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 218, 214, 202 ]
}
},
"item": {
"block_quartz": {
"type": "BLOCKS",
"iconTextureData": "block_quartz_icon.png",
"group": "GROUP_ORE_BLOCK",
"blockId": "block_quartz"
}
}
}
================================================
FILE: blocks/tiles/ore_blocks/block_redstone.json
================================================
{
"block": {
"block_redstone": {
"textureData": "block_redstone.png",
"color": [ 222, 2, 2 ],
"renderMode": "RENDER_BLOCK",
"renderSortedInterval": 2,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "IRON",
"hardness": 140,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 66, 0, 0 ]
}
},
"item": {
"block_redstone": {
"type": "BLOCKS",
"iconTextureData": "block_redstone_icon.png",
"group": "GROUP_ORE_BLOCK",
"blockId": "block_redstone"
}
}
}
================================================
FILE: blocks/tiles/ores/ore_ancient_debris.json
================================================
{
"block": {
"ore_ancient_debris": {
"textureData": "ore_ancient_debris.png",
"color": [ 81, 57, 51 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ORE_GOLD",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "DIAMOND",
"hardness": 320,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": true,
"wallCheck": "GENERABLE",
"soundGroupId": "tink",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 81, 57, 51 ],
"exParticle": "ore_particle"
}
},
"item": {
"ore_ancient_debris": {
"type": "BLOCKS",
"iconTextureData": "ore_ancient_debris_icon.png",
"group": "GROUP_ORE",
"blockId": "ore_ancient_debris",
"antiLava": true
}
}
}
================================================
FILE: blocks/tiles/ores/ore_coal.json
================================================
{
"block": {
"ore_coal": {
"textureData": "ore_coal.png",
"color": [ 40, 40, 40 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 8,
"type": "TILE",
"group": "ORE_COAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 100,
"isChipCollection": true,
"lossyItemId": "coal",
"chipCount": 1,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": true,
"wallCheck": "GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 40, 40, 40 ]
}
},
"item": {
"ore_coal": {
"type": "BLOCKS",
"iconTextureData": "ore_coal_icon.png",
"group": "GROUP_ORE",
"blockId": "ore_coal"
}
}
}
================================================
FILE: blocks/tiles/ores/ore_copper.json
================================================
{
"block": {
"ore_copper": {
"textureData": "ore_copper.png",
"color": [ 128, 70, 30 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ORE_GOLD",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "STONE",
"hardness": 180,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": true,
"wallCheck": "GENERABLE",
"soundGroupId": "tink",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 180, 100, 50 ],
"exParticle": "ore_particle"
}
},
"item": {
"ore_copper": {
"type": "BLOCKS",
"iconTextureData": "ore_copper_icon.png",
"group": "GROUP_ORE",
"blockId": "ore_copper"
}
}
}
================================================
FILE: blocks/tiles/ores/ore_diamond.json
================================================
{
"block": {
"ore_diamond": {
"textureData": "ore_diamond.png",
"color": [ 160, 180, 220 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ORE_DIAMOND",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "IRON",
"hardness": 240,
"isChipCollection": true,
"lossyItemId": "diamond",
"chipCount": 1,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": true,
"wallCheck": "GENERABLE",
"soundGroupId": "tink",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 130, 150, 250 ],
"exParticle": "ore_particle"
}
},
"item": {
"ore_diamond": {
"type": "BLOCKS",
"iconTextureData": "ore_diamond_icon.png",
"group": "GROUP_ORE",
"blockId": "ore_diamond"
}
}
}
================================================
FILE: blocks/tiles/ores/ore_emerald.json
================================================
{
"block": {
"ore_emerald": {
"textureData": "ore_emerald.png",
"color": [ 85, 149, 94 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ORE_EMERALD",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "IRON",
"hardness": 180,
"isChipCollection": true,
"lossyItemId": "emerald",
"chipCount": 1,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": true,
"wallCheck": "GENERABLE",
"soundGroupId": "tink",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 40, 220, 120 ],
"exParticle": "ore_particle"
}
},
"item": {
"ore_emerald": {
"type": "BLOCKS",
"iconTextureData": "ore_emerald_icon.png",
"group": "GROUP_ORE",
"blockId": "ore_emerald"
}
}
}
================================================
FILE: blocks/tiles/ores/ore_gold.json
================================================
{
"block": {
"ore_gold": {
"textureData": "ore_gold.png",
"color": [ 210, 210, 160 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ORE_GOLD",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "IRON",
"hardness": 180,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": true,
"wallCheck": "GENERABLE",
"soundGroupId": "tink",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 200, 200, 160 ],
"exParticle": "ore_particle"
}
},
"item": {
"ore_gold": {
"type": "BLOCKS",
"iconTextureData": "ore_gold_icon.png",
"group": "GROUP_ORE",
"blockId": "ore_gold"
}
}
}
================================================
FILE: blocks/tiles/ores/ore_iron.json
================================================
{
"block": {
"ore_iron": {
"textureData": "ore_iron.png",
"color": [ 165, 155, 105 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ORE_IRON",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "STONE",
"hardness": 120,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": true,
"wallCheck": "GENERABLE",
"soundGroupId": "tink",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 160, 140, 120 ],
"exParticle": "ore_particle"
}
},
"item": {
"ore_iron": {
"type": "BLOCKS",
"iconTextureData": "ore_iron_icon.png",
"group": "GROUP_ORE",
"blockId": "ore_iron"
}
}
}
================================================
FILE: blocks/tiles/ores/ore_lapis.json
================================================
{
"block": {
"ore_lapis": {
"textureData": "ore_lapis.png",
"color": [ 49, 106, 133 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 6,
"type": "TILE",
"group": "ORE_LAPIS",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "STONE",
"hardness": 160,
"isChipCollection": true,
"lossyItemId": "lapis_lazuli",
"chipCount": 3,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": true,
"wallCheck": "GENERABLE",
"soundGroupId": "tink",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 30, 70, 180 ],
"exParticle": "ore_particle"
}
},
"item": {
"ore_lapis": {
"type": "BLOCKS",
"iconTextureData": "ore_lapis_icon.png",
"group": "GROUP_ORE",
"blockId": "ore_lapis"
}
}
}
================================================
FILE: blocks/tiles/ores/ore_lead.json
================================================
{
"block": {
"ore_lead": {
"textureData": "ore_lead.png",
"color": [ 87, 103, 137 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ORE_GOLD",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "STONE",
"hardness": 180,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": true,
"wallCheck": "GENERABLE",
"soundGroupId": "tink",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 60, 80, 100 ],
"exParticle": "ore_particle"
}
},
"item": {
"ore_lead": {
"type": "BLOCKS",
"iconTextureData": "ore_lead_icon.png",
"group": "GROUP_ORE",
"blockId": "ore_lead"
}
}
}
================================================
FILE: blocks/tiles/ores/ore_nether_quartz.json
================================================
{
"block": {
"ore_nether_quartz": {
"textureData": "ore_nether_quartz.png",
"color": [ 235, 231, 228 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ORE_LAPIS",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 160,
"isChipCollection": true,
"lossyItemId": "quartz",
"chipCount": 6,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": true,
"wallCheck": "GENERABLE",
"soundGroupId": "tink",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 235, 231, 228 ],
"exParticle": "ore_particle"
}
},
"item": {
"ore_nether_quartz": {
"type": "BLOCKS",
"iconTextureData": "ore_nether_quartz_icon.png",
"group": "GROUP_ORE",
"blockId": "ore_nether_quartz"
}
}
}
================================================
FILE: blocks/tiles/ores/ore_redstone.json
================================================
{
"block": {
"ore_redstone": {
"textureData": "ore_redstone.png",
"color": [ 156, 121, 121 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ORE_REDSTONE",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "IRON",
"hardness": 140,
"isChipCollection": true,
"lossyItemId": "redstone",
"chipCount": 4,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": true,
"wallCheck": "GENERABLE",
"soundGroupId": "tink",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 250, 30, 30 ],
"exParticle": "ore_particle"
}
},
"item": {
"ore_redstone": {
"type": "BLOCKS",
"iconTextureData": "ore_redstone_icon.png",
"group": "GROUP_ORE",
"blockId": "ore_redstone"
}
}
}
================================================
FILE: blocks/tiles/ores/ore_silver.json
================================================
{
"block": {
"ore_silver": {
"textureData": "ore_silver.png",
"color": [ 172, 172, 200 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ORE_GOLD",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "IRON",
"hardness": 180,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": true,
"wallCheck": "GENERABLE",
"soundGroupId": "tink",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 160, 160, 200 ],
"exParticle": "ore_particle"
}
},
"item": {
"ore_silver": {
"type": "BLOCKS",
"iconTextureData": "ore_silver_icon.png",
"group": "GROUP_ORE",
"blockId": "ore_silver"
}
}
}
================================================
FILE: blocks/tiles/ores/ore_tin.json
================================================
{
"block": {
"ore_tin": {
"textureData": "ore_tin.png",
"color": [ 110, 140, 110 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ORE_GOLD",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "STONE",
"hardness": 180,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": true,
"wallCheck": "GENERABLE",
"soundGroupId": "tink",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 180, 222, 180 ],
"exParticle": "ore_particle"
}
},
"item": {
"ore_tin": {
"type": "BLOCKS",
"iconTextureData": "ore_tin_icon.png",
"group": "GROUP_ORE",
"blockId": "ore_tin"
}
}
}
================================================
FILE: blocks/tiles/planks/plank_acacia.json
================================================
{
"block": {
"plank_acacia": {
"textureData": "plank_acacia.png",
"color": [ 190, 125, 90 ],
"renderMode": "RENDER_BORDER_CUT",
"renderSortedInterval": 8,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 180, 100, 60 ]
}
},
"item": {
"acacia_plank": {
"type": "BLOCKS",
"iconTextureData": "plank_acacia_icon.png",
"group": "GROUP_WOODEN_PLANK",
"oreDictionary": [ "OD_WOODEN_PLANK" ],
"blockId": "plank_acacia",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/tiles/planks/plank_birch.json
================================================
{
"block": {
"plank_birch": {
"textureData": "plank_birch.png",
"color": [ 220, 210, 160 ],
"renderMode": "RENDER_BORDER_CUT",
"renderSortedInterval": 8,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 200, 200, 130 ]
}
},
"item": {
"birch_plank": {
"type": "BLOCKS",
"iconTextureData": "plank_birch_icon.png",
"group": "GROUP_WOODEN_PLANK",
"oreDictionary": [ "OD_WOODEN_PLANK" ],
"blockId": "plank_birch",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/tiles/planks/plank_dark_oak.json
================================================
{
"block": {
"plank_dark_oak": {
"textureData": "plank_dark_oak.png",
"color": [ 106, 86, 66 ],
"renderMode": "RENDER_BORDER_CUT",
"renderSortedInterval": 8,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 60, 30, 10 ]
}
},
"item": {
"dark_oak_plank": {
"type": "BLOCKS",
"iconTextureData": "plank_dark_oak_icon.png",
"group": "GROUP_WOODEN_PLANK",
"oreDictionary": [ "OD_WOODEN_PLANK" ],
"blockId": "plank_dark_oak",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/tiles/planks/plank_jungle.json
================================================
{
"block": {
"plank_jungle": {
"textureData": "plank_jungle.png",
"color": [ 137, 110, 92 ],
"renderMode": "RENDER_BORDER_CUT",
"renderSortedInterval": 8,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 100, 70, 50 ]
}
},
"item": {
"jungle_plank": {
"type": "BLOCKS",
"iconTextureData": "plank_jungle_icon.png",
"group": "GROUP_WOODEN_PLANK",
"oreDictionary": [ "OD_WOODEN_PLANK" ],
"blockId": "plank_jungle",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/tiles/planks/plank_oak.json
================================================
{
"block": {
"plank_oak": {
"textureData": "plank_oak.png",
"color": [ 167, 136, 79 ],
"renderMode": "RENDER_BORDER_CUT",
"renderSortedInterval": 8,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": true,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 173, 137, 80 ]
}
},
"item": {
"oak_plank": {
"type": "BLOCKS",
"iconTextureData": "plank_oak_icon.png",
"group": "GROUP_WOODEN_PLANK",
"oreDictionary": [ "OD_WOODEN_PLANK" ],
"blockId": "plank_oak",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/tiles/planks/plank_palm.json
================================================
{
"block": {
"plank_palm": {
"textureData": "plank_palm.png",
"color": [ 182, 141, 86 ],
"renderMode": "RENDER_BORDER_CUT",
"renderSortedInterval": 8,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 182, 141, 86 ]
}
},
"item": {
"palm_plank": {
"type": "BLOCKS",
"iconTextureData": "plank_palm_icon.png",
"group": "GROUP_WOODEN_PLANK",
"oreDictionary": [ "OD_WOODEN_PLANK" ],
"blockId": "plank_palm",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/tiles/planks/plank_spruce.json
================================================
{
"block": {
"plank_spruce": {
"textureData": "plank_spruce.png",
"color": [ 144, 119, 93 ],
"renderMode": "RENDER_BORDER_CUT",
"renderSortedInterval": 8,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 120, 90, 60 ]
}
},
"item": {
"spruce_plank": {
"type": "BLOCKS",
"iconTextureData": "plank_spruce_icon.png",
"group": "GROUP_WOODEN_PLANK",
"oreDictionary": [ "OD_WOODEN_PLANK" ],
"blockId": "plank_spruce",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/tiles/planks/plank_tainted.json
================================================
{
"block": {
"plank_tainted": {
"textureData": "plank_tainted.png",
"color": [ 89, 85, 107 ],
"renderMode": "RENDER_BORDER_CUT",
"renderSortedInterval": 8,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 89, 85, 107 ]
}
},
"item": {
"tainted_plank": {
"type": "BLOCKS",
"iconTextureData": "plank_tainted_icon.png",
"group": "GROUP_WOODEN_PLANK",
"oreDictionary": [ "OD_WOODEN_PLANK" ],
"blockId": "plank_tainted",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/tiles/planks/plank_volcano.json
================================================
{
"block": {
"plank_volcano": {
"textureData": "plank_volcano.png",
"color": [ 200, 60, 60 ],
"renderMode": "RENDER_BORDER_CUT",
"renderSortedInterval": 8,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 200, 60, 60 ]
}
},
"item": {
"volcano_plank": {
"type": "BLOCKS",
"iconTextureData": "plank_volcano_icon.png",
"group": "GROUP_WOODEN_PLANK",
"oreDictionary": [ "OD_WOODEN_PLANK" ],
"blockId": "plank_volcano",
"fuelTime": 60
}
}
}
================================================
FILE: blocks/tiles/platforms/platform_acacia.json
================================================
{
"block": {
"platform_acacia": {
"textureData": "platform_acacia.png",
"color": [ 190, 125, 90 ],
"renderMode": "RENDER_PLATEFORM",
"type": "TILE",
"group": "PLATFORM",
"collision": "PLATFORM",
"lightOpacity": 1,
"lightTransparent": true,
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 180, 100, 60 ],
"isBackground": true,
"isNoLinkVertical": true
}
},
"item": {
"platform_acacia": {
"type": "BLOCKS",
"iconTextureData": "platform_acacia_icon.png",
"group": "GROUP_WOODEN_PLATFORM",
"blockId": "platform_acacia",
"fuelTime": 60,
"oreDictionary": [ "OD_WOODEN_PLATFORM" ]
}
}
}
================================================
FILE: blocks/tiles/platforms/platform_birch.json
================================================
{
"block": {
"platform_birch": {
"textureData": "platform_birch.png",
"color": [ 208, 219, 156 ],
"renderMode": "RENDER_PLATEFORM",
"type": "TILE",
"group": "PLATFORM",
"collision": "PLATFORM",
"lightOpacity": 1,
"lightTransparent": true,
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 200, 200, 130 ],
"isBackground": true,
"isNoLinkVertical": true
}
},
"item": {
"platform_birch": {
"type": "BLOCKS",
"iconTextureData": "platform_birch_icon.png",
"group": "GROUP_WOODEN_PLATFORM",
"blockId": "platform_birch",
"fuelTime": 60,
"oreDictionary": [ "OD_WOODEN_PLATFORM" ]
}
}
}
================================================
FILE: blocks/tiles/platforms/platform_dark_oak.json
================================================
{
"block": {
"platform_dark_oak": {
"textureData": "platform_dark_oak.png",
"color": [ 100, 80, 60 ],
"renderMode": "RENDER_PLATEFORM",
"type": "TILE",
"group": "PLATFORM",
"collision": "PLATFORM",
"lightOpacity": 1,
"lightTransparent": true,
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 60, 30, 10 ],
"isBackground": true,
"isNoLinkVertical": true
}
},
"item": {
"platform_dark_oak": {
"type": "BLOCKS",
"iconTextureData": "platform_dark_oak_icon.png",
"group": "GROUP_WOODEN_PLATFORM",
"blockId": "platform_dark_oak",
"fuelTime": 60,
"oreDictionary": [ "OD_WOODEN_PLATFORM" ]
}
}
}
================================================
FILE: blocks/tiles/platforms/platform_end_stone.json
================================================
{
"block": {
"platform_end_stone": {
"textureData": "platform_end_stone.png",
"color": [ 223, 223, 209 ],
"renderMode": "RENDER_PLATEFORM",
"type": "TILE",
"group": "PLATFORM",
"collision": "PLATFORM",
"lightOpacity": 1,
"lightTransparent": true,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 223, 223, 209 ],
"isBackground": true,
"isNoLinkVertical": true
}
},
"item": {
"platform_end_stone": {
"type": "BLOCKS",
"iconTextureData": "platform_end_stone_icon.png",
"group": "GROUP_PLATFORM",
"blockId": "platform_end_stone"
}
}
}
================================================
FILE: blocks/tiles/platforms/platform_jungle.json
================================================
{
"block": {
"platform_jungle": {
"textureData": "platform_jungle.png",
"color": [ 132, 105, 88 ],
"renderMode": "RENDER_PLATEFORM",
"type": "TILE",
"group": "PLATFORM",
"collision": "PLATFORM",
"lightOpacity": 1,
"lightTransparent": true,
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 100, 70, 50 ],
"isBackground": true,
"isNoLinkVertical": true
}
},
"item": {
"platform_jungle": {
"type": "BLOCKS",
"iconTextureData": "platform_jungle_icon.png",
"group": "GROUP_WOODEN_PLATFORM",
"blockId": "platform_jungle",
"fuelTime": 60,
"oreDictionary": [ "OD_WOODEN_PLATFORM" ]
}
}
}
================================================
FILE: blocks/tiles/platforms/platform_nether_brick.json
================================================
{
"block": {
"platform_nether_brick": {
"textureData": "platform_nether_brick.png",
"color": [ 49, 17, 21 ],
"renderMode": "RENDER_PLATEFORM",
"type": "TILE",
"group": "PLATFORM",
"collision": "PLATFORM",
"lightOpacity": 1,
"lightTransparent": true,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 49, 17, 21 ],
"isBackground": true,
"isNoLinkVertical": true
}
},
"item": {
"platform_nether_brick": {
"type": "BLOCKS",
"iconTextureData": "platform_nether_brick_icon.png",
"group": "GROUP_PLATFORM",
"blockId": "platform_nether_brick"
}
}
}
================================================
FILE: blocks/tiles/platforms/platform_oak.json
================================================
{
"block": {
"platform_oak": {
"textureData": "platform_oak.png",
"color": [ 159, 132, 77 ],
"renderMode": "RENDER_PLATEFORM",
"type": "TILE",
"group": "PLATFORM",
"collision": "PLATFORM",
"lightOpacity": 1,
"lightTransparent": true,
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 173, 137, 80 ],
"isBackground": true,
"isNoLinkVertical": true
}
},
"item": {
"platform_oak": {
"type": "BLOCKS",
"iconTextureData": "platform_oak_icon.png",
"group": "GROUP_WOODEN_PLATFORM",
"blockId": "platform_oak",
"fuelTime": 60,
"oreDictionary": [ "OD_WOODEN_PLATFORM" ]
}
}
}
================================================
FILE: blocks/tiles/platforms/platform_palm.json
================================================
{
"block": {
"platform_palm": {
"textureData": "platform_palm.png",
"color": [ 182, 142, 86 ],
"renderMode": "RENDER_PLATEFORM",
"type": "TILE",
"group": "PLATFORM",
"collision": "PLATFORM",
"lightOpacity": 1,
"lightTransparent": true,
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 182, 142, 86 ],
"isBackground": true,
"isNoLinkVertical": true
}
},
"item": {
"platform_palm": {
"type": "BLOCKS",
"iconTextureData": "platform_palm_icon.png",
"group": "GROUP_WOODEN_PLATFORM",
"blockId": "platform_palm",
"fuelTime": 60,
"oreDictionary": [ "OD_WOODEN_PLATFORM" ]
}
}
}
================================================
FILE: blocks/tiles/platforms/platform_prismarine.json
================================================
{
"block": {
"platform_prismarine": {
"textureData": "platform_prismarine.png",
"color": [ 105, 176, 169 ],
"renderMode": "RENDER_PLATEFORM",
"type": "TILE",
"group": "PLATFORM",
"collision": "PLATFORM",
"lightOpacity": 1,
"lightTransparent": true,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 105, 176, 169 ],
"isBackground": true,
"isNoLinkVertical": true
}
},
"item": {
"platform_prismarine": {
"type": "BLOCKS",
"iconTextureData": "platform_prismarine_icon.png",
"group": "GROUP_PLATFORM",
"blockId": "platform_prismarine"
}
}
}
================================================
FILE: blocks/tiles/platforms/platform_prismarine_dark.json
================================================
{
"block": {
"platform_prismarine_dark": {
"textureData": "platform_prismarine_dark.png",
"color": [ 72, 112, 97 ],
"renderMode": "RENDER_PLATEFORM",
"type": "TILE",
"group": "PLATFORM",
"collision": "PLATFORM",
"lightOpacity": 1,
"lightTransparent": true,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 72, 112, 97 ],
"isBackground": true,
"isNoLinkVertical": true
}
},
"item": {
"platform_prismarine_dark": {
"type": "BLOCKS",
"iconTextureData": "platform_prismarine_dark_icon.png",
"group": "GROUP_PLATFORM",
"blockId": "platform_prismarine_dark"
}
}
}
================================================
FILE: blocks/tiles/platforms/platform_purpur.json
================================================
{
"block": {
"platform_purpur": {
"textureData": "platform_purpur.png",
"color": [ 188, 125, 188 ],
"renderMode": "RENDER_PLATEFORM",
"type": "TILE",
"group": "PLATFORM",
"collision": "PLATFORM",
"lightOpacity": 1,
"lightTransparent": true,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 188, 125, 188 ],
"isBackground": true,
"isNoLinkVertical": true
}
},
"item": {
"platform_purpur": {
"type": "BLOCKS",
"iconTextureData": "platform_purpur_icon.png",
"group": "GROUP_PLATFORM",
"blockId": "platform_purpur"
}
}
}
================================================
FILE: blocks/tiles/platforms/platform_quartz.json
================================================
{
"block": {
"platform_quartz": {
"textureData": "platform_quartz.png",
"color": [ 235, 231, 228 ],
"renderMode": "RENDER_PLATEFORM",
"type": "TILE",
"group": "PLATFORM",
"collision": "PLATFORM",
"lightOpacity": 1,
"lightTransparent": true,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 235, 231, 228 ],
"isBackground": true,
"isNoLinkVertical": true
}
},
"item": {
"platform_quartz": {
"type": "BLOCKS",
"iconTextureData": "platform_quartz_icon.png",
"group": "GROUP_PLATFORM",
"blockId": "platform_quartz"
}
}
}
================================================
FILE: blocks/tiles/platforms/platform_red_sand_stone.json
================================================
{
"block": {
"platform_red_sand_stone": {
"textureData": "platform_red_sand_stone.png",
"color": [ 200, 100, 100 ],
"renderMode": "RENDER_PLATEFORM",
"type": "TILE",
"group": "PLATFORM",
"collision": "PLATFORM",
"lightOpacity": 1,
"lightTransparent": true,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 200, 100, 100 ],
"isBackground": true,
"isNoLinkVertical": true
}
},
"item": {
"platform_red_sand_stone": {
"type": "BLOCKS",
"iconTextureData": "platform_red_sand_stone_icon.png",
"group": "GROUP_PLATFORM",
"blockId": "platform_red_sand_stone"
}
}
}
================================================
FILE: blocks/tiles/platforms/platform_sandstone.json
================================================
{
"block": {
"platform_sandstone": {
"textureData": "platform_sandstone.png",
"color": [ 223, 223, 160 ],
"renderMode": "RENDER_PLATEFORM",
"type": "TILE",
"group": "PLATFORM",
"collision": "PLATFORM",
"lightOpacity": 1,
"lightTransparent": true,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 223, 223, 160 ],
"isBackground": true,
"isNoLinkVertical": true
}
},
"item": {
"platform_sandstone": {
"type": "BLOCKS",
"iconTextureData": "platform_sandstone_icon.png",
"group": "GROUP_PLATFORM",
"blockId": "platform_sandstone"
}
}
}
================================================
FILE: blocks/tiles/platforms/platform_spruce.json
================================================
{
"block": {
"platform_spruce": {
"textureData": "platform_spruce.png",
"color": [ 144, 119, 93 ],
"renderMode": "RENDER_PLATEFORM",
"type": "TILE",
"group": "PLATFORM",
"collision": "PLATFORM",
"lightOpacity": 1,
"lightTransparent": true,
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 120, 90, 60 ],
"isBackground": true,
"isNoLinkVertical": true
}
},
"item": {
"platform_spruce": {
"type": "BLOCKS",
"iconTextureData": "platform_spruce_icon.png",
"group": "GROUP_WOODEN_PLATFORM",
"blockId": "platform_spruce",
"fuelTime": 60,
"oreDictionary": [ "OD_WOODEN_PLATFORM" ]
}
}
}
================================================
FILE: blocks/tiles/platforms/platform_stone_brick.json
================================================
{
"block": {
"platform_stone_brick": {
"textureData": "platform_stone_brick.png",
"color": [ 122, 122, 122 ],
"renderMode": "RENDER_PLATEFORM",
"type": "TILE",
"group": "PLATFORM",
"collision": "PLATFORM",
"lightOpacity": 1,
"lightTransparent": true,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 122, 122, 122 ],
"isBackground": true,
"isNoLinkVertical": true
}
},
"item": {
"platform_stone_brick": {
"type": "BLOCKS",
"iconTextureData": "platform_stone_brick_icon.png",
"group": "GROUP_PLATFORM",
"blockId": "platform_stone_brick"
}
}
}
================================================
FILE: blocks/tiles/platforms/platform_tainted.json
================================================
{
"block": {
"platform_tainted": {
"textureData": "platform_tainted.png",
"color": [ 89, 85, 107 ],
"renderMode": "RENDER_PLATEFORM",
"type": "TILE",
"group": "PLATFORM",
"collision": "PLATFORM",
"lightOpacity": 1,
"lightTransparent": true,
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 89, 85, 107 ],
"isBackground": true,
"isNoLinkVertical": true
}
},
"item": {
"platform_tainted": {
"type": "BLOCKS",
"iconTextureData": "platform_tainted_icon.png",
"group": "GROUP_WOODEN_PLATFORM",
"blockId": "platform_tainted",
"fuelTime": 60,
"oreDictionary": [ "OD_WOODEN_PLATFORM" ]
}
}
}
================================================
FILE: blocks/tiles/platforms/platform_volcano.json
================================================
{
"block": {
"platform_volcano": {
"textureData": "platform_volcano.png",
"color": [ 200, 60, 60 ],
"renderMode": "RENDER_PLATEFORM",
"type": "TILE",
"group": "PLATFORM",
"collision": "PLATFORM",
"lightOpacity": 1,
"lightTransparent": true,
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 200, 60, 60 ],
"isBackground": true,
"isNoLinkVertical": true
}
},
"item": {
"platform_volcano": {
"type": "BLOCKS",
"iconTextureData": "platform_volcano_icon.png",
"group": "GROUP_WOODEN_PLATFORM",
"blockId": "platform_volcano",
"fuelTime": 60,
"oreDictionary": [ "OD_WOODEN_PLATFORM" ]
}
}
}
================================================
FILE: blocks/tiles/prismarines/prismarine.json
================================================
{
"block": {
"prismarine": {
"textureData": "prismarine.png",
"color": [ 140, 150, 170 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 8,
"type": "TILE",
"group": "PRISMARINE",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "STONE",
"hardness": 200,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": true,
"isWallDark": true,
"wallCheck": "NATURE_GENERABLE_ONLY",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 140, 150, 170 ]
}
},
"item": {
"prismarine": {
"type": "BLOCKS",
"iconTextureData": "prismarine_icon.png",
"group": "GROUP_PRISMARINE",
"blockId": "prismarine"
}
}
}
================================================
FILE: blocks/tiles/prismarines/prismarine_brick.json
================================================
{
"block": {
"prismarine_brick": {
"textureData": "prismarine_brick.png",
"color": [ 133, 190, 180 ],
"renderMode": "RENDER_BORDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ANDESITE",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "STONE",
"hardness": 210,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": true,
"isWallDark": false,
"wallCheck": "NATURE_GENERABLE_ONLY",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 140, 188, 188 ]
}
},
"item": {
"prismarine_brick": {
"type": "BLOCKS",
"iconTextureData": "prismarine_brick_icon.png",
"group": "GROUP_PRISMARINE",
"blockId": "prismarine_brick"
}
}
}
================================================
FILE: blocks/tiles/prismarines/prismarine_dark.json
================================================
{
"block": {
"prismarine_dark": {
"textureData": "prismarine_dark.png",
"color": [ 70, 112, 97 ],
"renderMode": "RENDER_BORDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "STONE",
"hardness": 220,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": true,
"isWallDark": false,
"wallCheck": "NATURE_GENERABLE_ONLY",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 100, 144, 144 ]
}
},
"item": {
"prismarine_dark": {
"type": "BLOCKS",
"iconTextureData": "prismarine_dark_icon.png",
"group": "GROUP_PRISMARINE",
"blockId": "prismarine_dark"
}
}
}
================================================
FILE: blocks/tiles/prismarines/prismarine_mud.json
================================================
{
"block": {
"prismarine_mud": {
"textureData": "prismarine_mud.png",
"color": [ 81, 132, 126 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 8,
"type": "TILE",
"group": "PRISMARINE",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "STONE",
"hardness": 200,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": true,
"isWallDark": true,
"wallCheck": "NATURE_GENERABLE_ONLY",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 140, 188, 188 ]
}
},
"item": {
"prismarine_mud": {
"type": "BLOCKS",
"iconTextureData": "prismarine_mud_icon.png",
"group": "GROUP_PRISMARINE",
"blockId": "prismarine_mud"
}
}
}
================================================
FILE: blocks/tiles/prismarines/sea_lantern.json
================================================
{
"block": {
"sea_lantern": {
"textureData": "sea_lantern.png",
"color": [ 210, 220, 210 ],
"renderMode": "RENDER_BLOCK",
"renderSortedInterval": 2,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"isLighting": true,
"lightColor": [ 32, 0, 0, 0 ],
"lightX": 0,
"lightY": 0,
"lightWi": 1,
"lightHi": 1,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 120,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "glass",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 200, 200, 200 ]
}
},
"item": {
"sea_lantern": {
"type": "BLOCKS",
"iconTextureData": "sea_lantern_icon.png",
"group": "GROUP_OTHERS_BLOCK",
"blockId": "sea_lantern"
}
}
}
================================================
FILE: blocks/tiles/purpurs/purpur_block.json
================================================
{
"block": {
"purpur_block": {
"textureData": "purpur_block.png",
"color": [ 177, 105, 177 ],
"renderMode": "RENDER_BORDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 220,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NATURE_GENERABLE_ONLY",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 150, 100, 150 ]
}
},
"item": {
"purpur_block": {
"type": "BLOCKS",
"iconTextureData": "purpur_block_icon.png",
"group": "GROUP_OTHERS_BLOCK",
"blockId": "purpur_block"
}
}
}
================================================
FILE: blocks/tiles/red_sands/red_sand.json
================================================
{
"block": {
"red_sand": {
"textureData": "red_sand.png",
"color": [ 140, 62, 20 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 8,
"type": "TILE",
"group": "REDSAND",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 70,
"slipperiness": 1.0,
"gravity": true,
"allowSlope": false,
"isWallDark": true,
"wallCheck": "GENERABLE",
"soundGroupId": "sand",
"stepSoundId": "step_sand",
"particleColor": [ 255, 200, 120, 50 ]
}
},
"item": {
"red_sand": {
"type": "BLOCKS",
"iconTextureData": "red_sand_icon.png",
"group": "GROUP_RED_SAND",
"blockId": "red_sand"
}
}
}
================================================
FILE: blocks/tiles/red_sands/red_sand_carved.json
================================================
{
"block": {
"red_sand_carved": {
"textureData": "red_sand_carved.png",
"color": [ 206, 20, 20 ],
"renderMode": "RENDER_BLOCK",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 140,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NATURE_GENERABLE_ONLY",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 255, 40, 40 ]
}
},
"item": {
"red_sand_carved": {
"type": "BLOCKS",
"iconTextureData": "red_sand_carved_icon.png",
"group": "GROUP_RED_SAND",
"blockId": "red_sand_carved"
}
}
}
================================================
FILE: blocks/tiles/red_sands/red_sand_smooth.json
================================================
{
"block": {
"red_sand_smooth": {
"textureData": "red_sand_smooth.png",
"color": [ 206, 111, 111 ],
"renderMode": "RENDER_BORDER_CUT",
"renderSortedInterval": 6,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 140,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NATURE_GENERABLE_ONLY",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 255, 40, 40 ]
}
},
"item": {
"red_sand_smooth": {
"type": "BLOCKS",
"iconTextureData": "red_sand_smooth_icon.png",
"group": "GROUP_RED_SAND",
"blockId": "red_sand_smooth"
}
}
}
================================================
FILE: blocks/tiles/red_sands/red_sand_stone.json
================================================
{
"block": {
"red_sand_stone": {
"textureData": "red_sand_stone.png",
"color": [ 153, 73, 42 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 8,
"type": "TILE",
"group": "RED_SAND_STONE",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 120,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": true,
"isWallDark": true,
"wallCheck": "NATURE_GENERABLE_ONLY",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 160, 20, 20 ]
}
},
"item": {
"red_sand_stone": {
"type": "BLOCKS",
"iconTextureData": "red_sand_stone_icon.png",
"group": "GROUP_RED_SAND",
"blockId": "red_sand_stone"
}
}
}
================================================
FILE: blocks/tiles/sands/sand.json
================================================
{
"block": {
"sand": {
"textureData": "sand.png",
"color": [ 220, 210, 160 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 8,
"type": "TILE",
"group": "SAND",
"farmGroup": "SAND_GROUP",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 50,
"slipperiness": 1.0,
"gravity": true,
"allowSlope": false,
"isWallDark": true,
"wallCheck": "GENERABLE",
"soundGroupId": "sand",
"stepSoundId": "step_sand",
"particleColor": [ 255, 200, 200, 150 ]
}
},
"item": {
"sand": {
"type": "BLOCKS",
"iconTextureData": "sand_icon.png",
"group": "GROUP_SAND",
"blockId": "sand"
}
}
}
================================================
FILE: blocks/tiles/sands/sandstone.json
================================================
{
"block": {
"sandstone": {
"textureData": "sandstone.png",
"color": [ 167, 157, 114 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 8,
"type": "TILE",
"group": "SANDSTONE",
"farmGroup": "SAND_GROUP",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": true,
"isWallDark": true,
"wallCheck": "NATURE_GENERABLE_ONLY",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 210, 200, 150 ]
}
},
"item": {
"sandstone": {
"type": "BLOCKS",
"iconTextureData": "sandstone_icon.png",
"group": "GROUP_SAND",
"blockId": "sandstone"
}
}
}
================================================
FILE: blocks/tiles/sands/sandstone_carved.json
================================================
{
"block": {
"sandstone_carved": {
"textureData": "sandstone_carved.png",
"color": [ 216, 208, 155 ],
"renderMode": "RENDER_BLOCK",
"renderSortedInterval": 4,
"type": "TILE",
"group": "SANDSTONE_CARVED",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 140,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NATURE_GENERABLE_ONLY",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 220, 210, 160 ]
}
},
"item": {
"sandstone_carved": {
"type": "BLOCKS",
"iconTextureData": "sandstone_carved_icon.png",
"group": "GROUP_SAND",
"blockId": "sandstone_carved"
}
}
}
================================================
FILE: blocks/tiles/sands/sandstone_smooth.json
================================================
{
"block": {
"sandstone_smooth": {
"textureData": "sandstone_smooth.png",
"color": [ 229, 222, 176 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 6,
"type": "TILE",
"group": "SANDSTONE_SMOOTH",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 140,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NATURE_GENERABLE_ONLY",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 220, 210, 160 ]
}
},
"item": {
"sandstone_smooth": {
"type": "BLOCKS",
"iconTextureData": "sandstone_smooth_icon.png",
"group": "GROUP_SAND",
"blockId": "sandstone_smooth"
}
}
}
================================================
FILE: blocks/tiles/snows/snow.json
================================================
{
"block": {
"snow": {
"textureData": "snow.png",
"color": [ 128, 255, 255 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 8,
"type": "TILE",
"group": "SNOW",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 60,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": true,
"isWallDark": true,
"wallCheck": "GENERABLE",
"soundGroupId": "snow",
"stepSoundGroupId": "step_snow",
"particleColor": [ 255, 170, 255, 255 ]
}
},
"item": {
"snow": {
"type": "BLOCKS",
"iconTextureData": "snow_icon.png",
"group": "GROUP_SNOW",
"blockId": "snow"
}
}
}
================================================
FILE: blocks/tiles/snows/snow_brick.json
================================================
{
"block": {
"snow_brick": {
"textureData": "snow_brick.png",
"color": [ 210, 233, 233 ],
"renderMode": "RENDER_BORDER_CUT",
"renderSortedInterval": 6,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 150,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 111, 255, 255 ]
}
},
"item": {
"snow_brick": {
"type": "BLOCKS",
"iconTextureData": "snow_brick_icon.png",
"group": "GROUP_SNOW_BRICK",
"blockId": "snow_brick"
}
}
}
================================================
FILE: blocks/tiles/sponges/sponge.json
================================================
{
"block": {
"sponge": {
"textureData": "sponge.png",
"color": [ 207, 207, 148 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "SPONGE",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 50,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": true,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "cloth",
"stepSoundId": "step_cloth",
"particleColor": [ 255, 200, 200, 100 ],
"preset": "Sponge"
}
},
"item": {
"sponge": {
"type": "BLOCKS",
"iconTextureData": "sponge_icon.png",
"group": "GROUP_OTHERS_BLOCK",
"blockId": "sponge"
}
}
}
================================================
FILE: blocks/tiles/sponges/wet_sponge.json
================================================
{
"block": {
"wet_sponge": {
"textureData": "wet_sponge.png",
"color": [ 170, 177, 138 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "SPONGE",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 50,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": true,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "cloth",
"stepSoundId": "step_cloth",
"particleColor": [ 255, 200, 200, 100 ],
"preset": "WetSponge"
}
},
"item": {
"wet_sponge": {
"type": "BLOCKS",
"iconTextureData": "wet_sponge_icon.png",
"group": "GROUP_OTHERS_BLOCK",
"blockId": "wet_sponge"
}
}
}
================================================
FILE: blocks/tiles/stones/cobblestone.json
================================================
{
"block": {
"cobblestone": {
"textureData": "cobblestone.png",
"color": [ 114, 114, 114 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 8,
"type": "TILE",
"group": "COBBLESTONE",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 120,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": true,
"isWallDark": true,
"wallCheck": "NATURE_GENERABLE_ONLY",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 100, 100, 100 ]
}
},
"item": {
"cobblestone": {
"type": "BLOCKS",
"iconTextureData": "cobblestone_icon.png",
"group": "GROUP_COBBLESTONE",
"blockId": "cobblestone"
}
}
}
================================================
FILE: blocks/tiles/stones/cobblestone_mossy.json
================================================
{
"block": {
"cobblestone_mossy": {
"textureData": "cobblestone_mossy.png",
"color": [ 88, 103, 66 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 8,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 180,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": true,
"isWallDark": true,
"wallCheck": "NATURE_GENERABLE_ONLY",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 40, 72, 40 ]
}
},
"item": {
"cobblestone_mossy": {
"type": "BLOCKS",
"iconTextureData": "cobblestone_mossy_icon.png",
"group": "GROUP_COBBLESTONE",
"blockId": "cobblestone_mossy"
}
}
}
================================================
FILE: blocks/tiles/stones/stone.json
================================================
{
"block": {
"stone": {
"textureData": "stone.png",
"color": [ 110, 110, 110 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 8,
"type": "TILE",
"group": "STONE",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 120,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": true,
"wallCheck": "NATURE_GENERABLE_ONLY",
"isLossyCollection": true,
"lossyItemId": "cobblestone",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 100, 100, 100 ]
}
},
"item": {
"stone": {
"type": "BLOCKS",
"iconTextureData": "stone_icon.png",
"group": "GROUP_STONE",
"blockId": "stone"
}
}
}
================================================
FILE: blocks/tiles/stones/stone_brick.json
================================================
{
"block": {
"stone_brick": {
"textureData": "stone_brick.png",
"color": [ 118, 118, 118 ],
"renderMode": "RENDER_BORDER_CUT",
"renderSortedInterval": 6,
"hasThinWall": true,
"type": "TILE",
"group": "STONE_BRICK",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 200,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NATURE_GENERABLE_ONLY",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 100, 100, 100 ]
}
},
"item": {
"stone_brick": {
"type": "BLOCKS",
"iconTextureData": "stone_brick_icon.png",
"group": "GROUP_STONE_BRICK",
"blockId": "stone_brick"
}
}
}
================================================
FILE: blocks/tiles/stones/stone_brick_carved.json
================================================
{
"block": {
"stone_brick_carved": {
"textureData": "stone_brick_carved.png",
"color": [ 118, 118, 118 ],
"renderMode": "RENDER_BLOCK",
"renderSortedInterval": 4,
"type": "TILE",
"group": "STONE_BRICK",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 200,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NATURE_GENERABLE_ONLY",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 100, 100, 100 ]
}
},
"item": {
"stone_brick_carved": {
"type": "BLOCKS",
"iconTextureData": "stone_brick_carved_icon.png",
"group": "GROUP_STONE_BRICK",
"blockId": "stone_brick_carved"
}
}
}
================================================
FILE: blocks/tiles/stones/stone_brick_cracked.json
================================================
{
"block": {
"stone_brick_cracked": {
"textureData": "stone_brick_cracked.png",
"color": [ 118, 118, 118 ],
"renderMode": "RENDER_BORDER_CUT",
"renderSortedInterval": 6,
"hasThinWall": true,
"type": "TILE",
"group": "STONE_BRICK",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 200,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NATURE_GENERABLE_ONLY",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 100, 100, 100 ]
}
},
"item": {
"stone_brick_cracked": {
"type": "BLOCKS",
"iconTextureData": "stone_brick_cracked_icon.png",
"group": "GROUP_STONE_BRICK",
"blockId": "stone_brick_cracked"
}
}
}
================================================
FILE: blocks/tiles/stones/stone_brick_mossy.json
================================================
{
"block": {
"stone_brick_mossy": {
"textureData": "stone_brick_mossy.png",
"color": [ 110, 116, 97 ],
"renderMode": "RENDER_BORDER_CUT",
"renderSortedInterval": 6,
"hasThinWall": true,
"type": "TILE",
"group": "STONE_BRICK",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 200,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NATURE_GENERABLE_ONLY",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 100, 100, 100 ]
}
},
"item": {
"stone_brick_mossy": {
"type": "BLOCKS",
"iconTextureData": "stone_brick_mossy_icon.png",
"group": "GROUP_STONE_BRICK",
"blockId": "stone_brick_mossy"
}
}
}
================================================
FILE: blocks/tiles/tainted/tainted_dirt.json
================================================
{
"block": {
"tainted_dirt": {
"textureData": "tainted_dirt.png",
"color": [ 60, 30, 90 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 8,
"type": "TILE",
"group": "DIRT",
"growGroup": "TAINTED_GROUP",
"hangGrowGroup": "TAINTED_GROUP",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 60,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": true,
"isWallDark": true,
"hasGrassCover": true,
"isRipen": true,
"wallCheck": "GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 91, 64, 44 ],
"preset": "GrowGrass",
"covers": [
{
"modTextureId": "tainted_grass",
"offsetX": -8,
"offsetY": -8
}
]
}
},
"item": {
"tainted_dirt": {
"type": "BLOCKS",
"iconTextureData": "tainted_dirt_icon.png",
"group": "GROUP_TAINTED",
"blockId": "tainted_dirt"
}
}
}
================================================
FILE: blocks/tiles/tainted/tainted_stone.json
================================================
{
"block": {
"tainted_stone": {
"textureData": "tainted_stone.png",
"color": [ 75, 52, 108 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 8,
"type": "TILE",
"group": "TAINTED_STONE",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "STONE",
"hardness": 200,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": true,
"isWallDark": true,
"wallCheck": "GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 100, 100, 100 ]
}
},
"item": {
"tainted_stone": {
"type": "BLOCKS",
"iconTextureData": "tainted_stone_icon.png",
"group": "GROUP_TAINTED",
"blockId": "tainted_stone"
}
}
}
================================================
FILE: blocks/tiles/terracottas/terracotta_black.json
================================================
{
"block": {
"terracotta_black": {
"textureData": "terracotta_black.png",
"color": [ 80, 80, 80 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 160,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 0, 0, 0 ]
}
},
"item": {
"terracotta_black": {
"type": "BLOCKS",
"iconTextureData": "terracotta_black_icon.png",
"group": "GROUP_TERRACOTTA",
"blockId": "terracotta_black",
"oreDictionary": [ "OD_TERRACOTTA" ]
}
}
}
================================================
FILE: blocks/tiles/terracottas/terracotta_blue.json
================================================
{
"block": {
"terracotta_blue": {
"textureData": "terracotta_blue.png",
"color": [ 111, 111, 172 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 160,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 0, 0, 120 ]
}
},
"item": {
"terracotta_blue": {
"type": "BLOCKS",
"iconTextureData": "terracotta_blue_icon.png",
"group": "GROUP_TERRACOTTA",
"blockId": "terracotta_blue",
"oreDictionary": [ "OD_TERRACOTTA" ]
}
}
}
================================================
FILE: blocks/tiles/terracottas/terracotta_brown.json
================================================
{
"block": {
"terracotta_brown": {
"textureData": "terracotta_brown.png",
"color": [ 172, 157, 141 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 160,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 130, 100, 50 ]
}
},
"item": {
"terracotta_brown": {
"type": "BLOCKS",
"iconTextureData": "terracotta_brown_icon.png",
"group": "GROUP_TERRACOTTA",
"blockId": "terracotta_brown",
"oreDictionary": [ "OD_TERRACOTTA" ]
}
}
}
================================================
FILE: blocks/tiles/terracottas/terracotta_cyan.json
================================================
{
"block": {
"terracotta_cyan": {
"textureData": "terracotta_cyan.png",
"color": [ 101, 168, 168 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 160,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 0, 120, 120 ]
}
},
"item": {
"terracotta_cyan": {
"type": "BLOCKS",
"iconTextureData": "terracotta_cyan_icon.png",
"group": "GROUP_TERRACOTTA",
"blockId": "terracotta_cyan",
"oreDictionary": [ "OD_TERRACOTTA" ]
}
}
}
================================================
FILE: blocks/tiles/terracottas/terracotta_gray.json
================================================
{
"block": {
"terracotta_gray": {
"textureData": "terracotta_gray.png",
"color": [ 144, 144, 144 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 160,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 60, 60, 60 ]
}
},
"item": {
"terracotta_gray": {
"type": "BLOCKS",
"iconTextureData": "terracotta_gray_icon.png",
"group": "GROUP_TERRACOTTA",
"blockId": "terracotta_gray",
"oreDictionary": [ "OD_TERRACOTTA" ]
}
}
}
================================================
FILE: blocks/tiles/terracottas/terracotta_green.json
================================================
{
"block": {
"terracotta_green": {
"textureData": "terracotta_green.png",
"color": [ 110, 172, 110 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 160,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 0, 120, 0 ]
}
},
"item": {
"terracotta_green": {
"type": "BLOCKS",
"iconTextureData": "terracotta_green_icon.png",
"group": "GROUP_TERRACOTTA",
"blockId": "terracotta_green",
"oreDictionary": [ "OD_TERRACOTTA" ]
}
}
}
================================================
FILE: blocks/tiles/terracottas/terracotta_light_blue.json
================================================
{
"block": {
"terracotta_light_blue": {
"textureData": "terracotta_light_blue.png",
"color": [ 141, 157, 172 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 160,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 60, 90, 120 ]
}
},
"item": {
"terracotta_light_blue": {
"type": "BLOCKS",
"iconTextureData": "terracotta_light_blue_icon.png",
"group": "GROUP_TERRACOTTA",
"blockId": "terracotta_light_blue",
"oreDictionary": [ "OD_TERRACOTTA" ]
}
}
}
================================================
FILE: blocks/tiles/terracottas/terracotta_light_gray.json
================================================
{
"block": {
"terracotta_light_gray": {
"textureData": "terracotta_light_gray.png",
"color": [ 184, 172, 160 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 160,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 120, 120, 100 ]
}
},
"item": {
"terracotta_light_gray": {
"type": "BLOCKS",
"iconTextureData": "terracotta_light_gray_icon.png",
"group": "GROUP_TERRACOTTA",
"blockId": "terracotta_light_gray",
"oreDictionary": [ "OD_TERRACOTTA" ]
}
}
}
================================================
FILE: blocks/tiles/terracottas/terracotta_lime.json
================================================
{
"block": {
"terracotta_lime": {
"textureData": "terracotta_lime.png",
"color": [ 134, 168, 101 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 160,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 50, 100, 0 ]
}
},
"item": {
"terracotta_lime": {
"type": "BLOCKS",
"iconTextureData": "terracotta_lime_icon.png",
"group": "GROUP_TERRACOTTA",
"blockId": "terracotta_lime",
"oreDictionary": [ "OD_TERRACOTTA" ]
}
}
}
================================================
FILE: blocks/tiles/terracottas/terracotta_magenta.json
================================================
{
"block": {
"terracotta_magenta": {
"textureData": "terracotta_magenta.png",
"color": [ 168, 134, 168 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 160,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 120, 60, 120 ]
}
},
"item": {
"terracotta_magenta": {
"type": "BLOCKS",
"iconTextureData": "terracotta_magenta_icon.png",
"group": "GROUP_TERRACOTTA",
"blockId": "terracotta_magenta",
"oreDictionary": [ "OD_TERRACOTTA" ]
}
}
}
================================================
FILE: blocks/tiles/terracottas/terracotta_orange.json
================================================
{
"block": {
"terracotta_orange": {
"textureData": "terracotta_orange.png",
"color": [ 180, 167, 154 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 160,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 140, 120, 100 ]
}
},
"item": {
"terracotta_orange": {
"type": "BLOCKS",
"iconTextureData": "terracotta_orange_icon.png",
"group": "GROUP_TERRACOTTA",
"blockId": "terracotta_orange",
"oreDictionary": [ "OD_TERRACOTTA" ]
}
}
}
================================================
FILE: blocks/tiles/terracottas/terracotta_pink.json
================================================
{
"block": {
"terracotta_pink": {
"textureData": "terracotta_pink.png",
"color": [ 168, 150, 150 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 160,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 130, 100, 100 ]
}
},
"item": {
"terracotta_pink": {
"type": "BLOCKS",
"iconTextureData": "terracotta_pink_icon.png",
"group": "GROUP_TERRACOTTA",
"blockId": "terracotta_pink",
"oreDictionary": [ "OD_TERRACOTTA" ]
}
}
}
================================================
FILE: blocks/tiles/terracottas/terracotta_purple.json
================================================
{
"block": {
"terracotta_purple": {
"textureData": "terracotta_purple.png",
"color": [ 141, 125, 172 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 160,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 60, 30, 120 ]
}
},
"item": {
"terracotta_purple": {
"type": "BLOCKS",
"iconTextureData": "terracotta_purple_icon.png",
"group": "GROUP_TERRACOTTA",
"blockId": "terracotta_purple",
"oreDictionary": [ "OD_TERRACOTTA" ]
}
}
}
================================================
FILE: blocks/tiles/terracottas/terracotta_red.json
================================================
{
"block": {
"terracotta_red": {
"textureData": "terracotta_red.png",
"color": [ 172, 100, 100 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 160,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 120, 0, 0 ]
}
},
"item": {
"terracotta_red": {
"type": "BLOCKS",
"iconTextureData": "terracotta_red_icon.png",
"group": "GROUP_TERRACOTTA",
"blockId": "terracotta_red",
"oreDictionary": [ "OD_TERRACOTTA" ]
}
}
}
================================================
FILE: blocks/tiles/terracottas/terracotta_white.json
================================================
{
"block": {
"terracotta_white": {
"note": "各色陶瓦 67:0-15",
"textureData": "terracotta_white.png",
"color": [ 209, 177, 161 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 160,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 200, 170, 150 ]
}
},
"item": {
"terracotta_white": {
"type": "BLOCKS",
"iconTextureData": "terracotta_white_icon.png",
"group": "GROUP_TERRACOTTA",
"blockId": "terracotta_white",
"oreDictionary": [ "OD_TERRACOTTA" ]
}
}
}
================================================
FILE: blocks/tiles/terracottas/terracotta_yellow.json
================================================
{
"block": {
"terracotta_yellow": {
"textureData": "terracotta_yellow.png",
"color": [ 166, 166, 101 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 160,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 120, 120, 0 ]
}
},
"item": {
"terracotta_yellow": {
"type": "BLOCKS",
"iconTextureData": "terracotta_yellow_icon.png",
"group": "GROUP_TERRACOTTA",
"blockId": "terracotta_yellow",
"oreDictionary": [ "OD_TERRACOTTA" ]
}
}
}
================================================
FILE: blocks/tiles/test/blue_mushroom.json
================================================
{
"block": {
"blue_mushroom": {
"textureData": "blue_mushroom.png",
"color": [ 157, 120, 72 ],
"type": "FURNITURE",
"width": 1,
"height": 1,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_BLUE_MUSHROOM_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 10,
"slipperiness": 1.0,
"isKilledByLava": true,
"isLighting": true,
"lightColor": [ 12, 0, 0, 4 ],
"lightX": 0,
"lightY": 0,
"lightWi": 1,
"lightHi": 2,
"isFragile": true,
"isDestroyByWeapon": false,
"soundGroupId": "grass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 170, 140, 80 ],
"animation": [
{
"animationId": 0,
"shake": true,
"shakeCenterX": 8,
"shakeCenterY": 16,
"shakePeriod": 128,
"shakeAngle": 0.2
}
],
"preset": "RandomDisplay"
}
},
"item": {
"blue_mushroom": {
"type": "BLOCKS",
"iconTextureData": "blue_mushroom_icon.png",
"group": "GROUP_OTHERS_FURNITURE",
"blockId": "blue_mushroom"
}
}
}
================================================
FILE: blocks/tiles/test/blue_mushroom_dirt.json
================================================
{
"block": {
"blue_mushroom_dirt": {
"textureData": "blue_mushroom_dirt.png",
"color": [ 15, 33, 112 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 8,
"type": "TILE",
"group": "DIRT",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 60,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": true,
"isWallDark": true,
"hasGrassCover": true,
"isRipen": true,
"wallCheck": "NATURE_GENERABLE_ONLY",
"soundGroupId": "stone",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 123, 100, 100 ],
"preset": "GrowGrass",
"covers": [
{
"modTextureId": "tainted_grass",
"offsetX": -8,
"offsetY": -8
}
]
}
},
"item": {
"blue_mushroom_dirt": {
"type": "BLOCKS",
"iconTextureData": "blue_mushroom_dirt_icon.png",
"group": "GROUP_MUSHROOM_BLOCK",
"blockId": "blue_mushroom_dirt"
}
}
}
================================================
FILE: blocks/tiles/test/blue_mushroom_stem.json
================================================
{
"block": {
"blue_mushroom_stem": {
"textureData": "blue_mushroom_stem.png",
"color": [ 2, 7, 91 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 8,
"type": "TILE",
"group": "COBBLESTONE",
"collision": "SOLID",
"lightOpacity": 3,
"isLighting": true,
"lightColor": [ 10, 0, 0, 5 ],
"lightX": 0,
"lightY": 0,
"lightWi": 1,
"lightHi": 1,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 120,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": true,
"wallCheck": "NATURE_GENERABLE_ONLY",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 100, 100, 100 ]
}
},
"item": {
"blue_mushroom_stem": {
"type": "BLOCKS",
"iconTextureData": "blue_mushroom_stem_icon.png",
"group": "GROUP_COBBLESTONE",
"blockId": "blue_mushroom_stem"
}
}
}
================================================
FILE: blocks/tiles/test/ice_cobblestone_hard.json
================================================
{
"block": {
"ice_cobblestone_hard": {
"textureData": "ice_cobblestone_hard.png",
"color": [ 71, 96, 118 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 8,
"type": "TILE",
"group": "COBBLESTONE",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 120,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": true,
"isWallDark": true,
"wallCheck": "NATURE_GENERABLE_ONLY",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 100, 100, 100 ]
}
},
"item": {
"ice_cobblestone_hard": {
"type": "BLOCKS",
"iconTextureData": "ice_cobblestone_hard_icon.png",
"group": "GROUP_COBBLESTONE",
"blockId": "ice_cobblestone_hard"
}
}
}
================================================
FILE: blocks/tiles/test/large_blue_mushroom.json
================================================
{
"block": {
"large_blue_mushroom": {
"textureData": "large_blue_mushroom.png",
"color": [ 157, 120, 72 ],
"type": "FURNITURE",
"width": 2,
"height": 2,
"collision": "NONE",
"attach": "BOTTOM",
"attachable": "NONE",
"placeCheck": "PLACE_BLUE_MUSHROOM_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 10,
"slipperiness": 1.0,
"isKilledByLava": true,
"isLighting": true,
"lightColor": [ 12, 0, 0, 4 ],
"lightX": 0,
"lightY": 0,
"lightWi": 1,
"lightHi": 2,
"isFragile": true,
"isDestroyByWeapon": false,
"soundGroupId": "grass",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 170, 140, 80 ],
"animation": [
{
"animationId": 0,
"shake": true,
"shakeCenterX": 8,
"shakeCenterY": 16,
"shakePeriod": 128,
"shakeAngle": 0.2
}
],
"preset": "RandomDisplay"
}
},
"item": {
"large_blue_mushroom": {
"type": "BLOCKS",
"iconTextureData": "large_blue_mushroom_icon.png",
"group": "GROUP_OTHERS_FURNITURE",
"blockId": "large_blue_mushroom"
}
}
}
================================================
FILE: blocks/tiles/test/lava_block_pile.json
================================================
{
"block": {
"lava_block_pile": {
"textureData": "lava_block_pile.png",
"color": [ 40, 64, 122 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 8,
"type": "TILE",
"group": "COBBLESTONE",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 120,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": true,
"isWallDark": true,
"wallCheck": "NATURE_GENERABLE_ONLY",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 100, 100, 100 ]
}
},
"item": {
"lava_block_pile": {
"type": "BLOCKS",
"iconTextureData": "lava_block_pile_icon.png",
"group": "GROUP_COBBLESTONE",
"blockId": "lava_block_pile"
}
}
}
================================================
FILE: blocks/tiles/test/pile_cobblestone.json
================================================
{
"block": {
"pile_cobblestone": {
"textureData": "pile_cobblestone.png",
"color": [ 40, 64, 122 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 8,
"type": "TILE",
"group": "COBBLESTONE",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 120,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": true,
"isWallDark": true,
"wallCheck": "NATURE_GENERABLE_ONLY",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 100, 100, 100 ]
}
},
"item": {
"pile_cobblestone": {
"type": "BLOCKS",
"iconTextureData": "pile_cobblestone_icon.png",
"group": "GROUP_COBBLESTONE",
"blockId": "pile_cobblestone"
}
}
}
================================================
FILE: blocks/tiles/test/snow_soft.json
================================================
{
"block": {
"snow_soft": {
"textureData": "snow_soft.png",
"color": [ 128, 255, 255 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 8,
"type": "TILE",
"group": "SNOW",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 60,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": true,
"isWallDark": true,
"wallCheck": "GENERABLE",
"soundGroupId": "snow",
"stepSoundGroupId": "step_snow",
"particleColor": [ 255, 170, 255, 255 ]
}
},
"item": {
"snow_soft": {
"type": "BLOCKS",
"iconTextureData": "snow_soft_icon.png",
"group": "GROUP_SNOW",
"blockId": "snow_soft"
}
}
}
================================================
FILE: blocks/tiles/test/volcano_burn_stone.json
================================================
{
"block": {
"volcano_burn_stone": {
"textureData": "volcano_burn_stone.png",
"color": [ 132, 21, 1 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 8,
"type": "TILE",
"group": "COBBLESTONE",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 120,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": true,
"isWallDark": true,
"wallCheck": "NATURE_GENERABLE_ONLY",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 100, 100, 100 ]
}
},
"item": {
"volcano_burn_stone": {
"type": "BLOCKS",
"iconTextureData": "volcano_burn_stone_icon.png",
"group": "GROUP_COBBLESTONE",
"blockId": "volcano_burn_stone"
}
}
}
================================================
FILE: blocks/tiles/test/volcano_cobblestone.json
================================================
{
"block": {
"volcano_cobblestone": {
"textureData": "volcano_cobblestone.png",
"color": [ 40, 64, 122 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 8,
"type": "TILE",
"group": "COBBLESTONE",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 120,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": true,
"isWallDark": true,
"wallCheck": "NATURE_GENERABLE_ONLY",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 100, 100, 100 ]
}
},
"item": {
"volcano_cobblestone": {
"type": "BLOCKS",
"iconTextureData": "volcano_cobblestone_icon.png",
"group": "GROUP_COBBLESTONE",
"blockId": "volcano_cobblestone"
}
}
}
================================================
FILE: blocks/tiles/volcanos/magma_block.json
================================================
{
"block": {
"magma_block": {
"textureData": "magma_block.png",
"color": [ 122, 46, 30 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 8,
"type": "TILE",
"group": "MAGMA_BLOCK",
"collision": "SOLID",
"lightOpacity": 3,
"isLighting": true,
"lightColor": [ 26, 10, 0, 0 ],
"lightX": 0,
"lightY": 0,
"lightWi": 1,
"lightHi": 1,
"toolType": "PICKAXE",
"mineGrade": "STONE",
"hardness": 220,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": true,
"wallCheck": "GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 230, 140, 70 ],
"preset": "MagmaBlock"
}
},
"item": {
"magma_block": {
"type": "BLOCKS",
"iconTextureData": "magma_block_icon.png",
"group": "GROUP_OTHERS_BLOCK",
"blockId": "magma_block"
}
}
}
================================================
FILE: blocks/tiles/volcanos/volcano_dirt.json
================================================
{
"block": {
"volcano_dirt": {
"textureData": "volcano_dirt.png",
"color": [ 100, 34, 0 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 8,
"type": "TILE",
"group": "DIRT",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 60,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": true,
"isWallDark": true,
"hasGrassCover": false,
"wallCheck": "GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_grass",
"particleColor": [ 255, 100, 34, 0 ]
}
},
"item": {
"volcano_dirt": {
"type": "BLOCKS",
"iconTextureData": "volcano_dirt_icon.png",
"group": "GROUP_VOLCANO",
"blockId": "volcano_dirt"
}
}
}
================================================
FILE: blocks/tiles/volcanos/volcano_stone.json
================================================
{
"block": {
"volcano_stone": {
"textureData": "volcano_stone.png",
"color": [ 134, 51, 10 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 8,
"type": "TILE",
"group": "COBBLESTONE",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "WOOD",
"hardness": 120,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": true,
"isWallDark": true,
"wallCheck": "GENERABLE",
"soundGroupId": "stone",
"stepSoundGroupId": "step_stone",
"particleColor": [ 255, 134, 51, 10 ]
}
},
"item": {
"volcano_stone": {
"type": "BLOCKS",
"iconTextureData": "volcano_stone_icon.png",
"group": "GROUP_VOLCANO",
"blockId": "volcano_stone"
}
}
}
================================================
FILE: blocks/tiles/woods/wood_acacia.json
================================================
{
"block": {
"wood_acacia": {
"textureData": "wood_acacia.png",
"color": [ 77, 77, 77 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "WOOD_B",
"subGroup": "WOOD",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"transformId": "wood_stripped_acacia",
"wallCheck": "NO_GENERABLE",
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 180, 100, 60 ]
}
},
"item": {
"wood_acacia": {
"type": "BLOCKS",
"iconTextureData": "wood_acacia_icon.png",
"group": "GROUP_WOOD",
"blockId": "wood_acacia",
"fuelTime": 60,
"oreDictionary": [ "OD_WOOD" ]
}
}
}
================================================
FILE: blocks/tiles/woods/wood_birch.json
================================================
{
"block": {
"wood_birch": {
"textureData": "wood_birch.png",
"color": [ 211, 211, 211 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "WOOD_A",
"subGroup": "WOOD",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"transformId": "wood_stripped_birch",
"wallCheck": "NO_GENERABLE",
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 200, 200, 130 ]
}
},
"item": {
"wood_birch": {
"type": "BLOCKS",
"iconTextureData": "wood_birch_icon.png",
"group": "GROUP_WOOD",
"blockId": "wood_birch",
"fuelTime": 60,
"oreDictionary": [ "OD_WOOD" ]
}
}
}
================================================
FILE: blocks/tiles/woods/wood_dark_oak.json
================================================
{
"block": {
"wood_dark_oak": {
"textureData": "wood_dark_oak.png",
"color": [ 74, 66, 51 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "WOOD_B",
"subGroup": "WOOD",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"transformId": "wood_stripped_dark_oak",
"wallCheck": "NO_GENERABLE",
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 60, 30, 10 ]
}
},
"item": {
"wood_dark_oak": {
"type": "BLOCKS",
"iconTextureData": "wood_dark_oak_icon.png",
"group": "GROUP_WOOD",
"blockId": "wood_dark_oak",
"fuelTime": 60,
"oreDictionary": [ "OD_WOOD" ]
}
}
}
================================================
FILE: blocks/tiles/woods/wood_jungle.json
================================================
{
"block": {
"wood_jungle": {
"textureData": "wood_jungle.png",
"color": [ 82, 71, 61 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "WOOD_B",
"subGroup": "WOOD",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"transformId": "wood_stripped_jungle",
"wallCheck": "NO_GENERABLE",
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 100, 70, 50 ]
}
},
"item": {
"wood_jungle": {
"type": "BLOCKS",
"iconTextureData": "wood_jungle_icon.png",
"group": "GROUP_WOOD",
"blockId": "wood_jungle",
"fuelTime": 60,
"oreDictionary": [ "OD_WOOD" ]
}
}
}
================================================
FILE: blocks/tiles/woods/wood_oak.json
================================================
{
"block": {
"wood_oak": {
"textureData": "wood_oak.png",
"color": [ 81, 69, 47 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "WOOD_B",
"subGroup": "WOOD",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"transformId": "wood_stripped_oak",
"wallCheck": "NO_GENERABLE",
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 173, 137, 80 ]
}
},
"item": {
"wood_oak": {
"type": "BLOCKS",
"iconTextureData": "wood_oak_icon.png",
"group": "GROUP_WOOD",
"blockId": "wood_oak",
"fuelTime": 60,
"oreDictionary": [ "OD_WOOD" ]
}
}
}
================================================
FILE: blocks/tiles/woods/wood_palm.json
================================================
{
"block": {
"wood_palm": {
"textureData": "wood_palm.png",
"color": [ 182, 141, 86 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "WOOD_B",
"subGroup": "WOOD",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"transformId": "wood_stripped_palm",
"wallCheck": "NO_GENERABLE",
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 182, 141, 86 ]
}
},
"item": {
"wood_palm": {
"type": "BLOCKS",
"iconTextureData": "wood_palm_icon.png",
"group": "GROUP_WOOD",
"blockId": "wood_palm",
"fuelTime": 60,
"oreDictionary": [ "OD_WOOD" ]
}
}
}
================================================
FILE: blocks/tiles/woods/wood_spruce.json
================================================
{
"block": {
"wood_spruce": {
"textureData": "wood_spruce.png",
"color": [ 91, 80, 75 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "WOOD_B",
"subGroup": "WOOD",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"transformId": "wood_stripped_spruce",
"wallCheck": "NO_GENERABLE",
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 120, 90, 60 ]
}
},
"item": {
"wood_spruce": {
"type": "BLOCKS",
"iconTextureData": "wood_spruce_icon.png",
"group": "GROUP_WOOD",
"blockId": "wood_spruce",
"fuelTime": 60,
"oreDictionary": [ "OD_WOOD" ]
}
}
}
================================================
FILE: blocks/tiles/woods/wood_stripped_acacia.json
================================================
{
"block": {
"wood_stripped_acacia": {
"textureData": "wood_stripped_acacia.png",
"color": [ 208, 150, 130 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "WOOD_B",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 180, 100, 60 ]
}
},
"item": {
"wood_stripped_acacia": {
"type": "BLOCKS",
"iconTextureData": "wood_stripped_acacia_icon.png",
"group": "GROUP_WOOD_STRIPPED",
"blockId": "wood_stripped_acacia",
"fuelTime": 60,
"oreDictionary": ["OD_WOOD_STRIPPED"]
}
}
}
================================================
FILE: blocks/tiles/woods/wood_stripped_birch.json
================================================
{
"block": {
"wood_stripped_birch": {
"textureData": "wood_stripped_birch.png",
"color": [ 220, 206, 166 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "WOOD_A",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 200, 200, 130 ]
}
},
"item": {
"wood_stripped_birch": {
"type": "BLOCKS",
"iconTextureData": "wood_stripped_birch_icon.png",
"group": "GROUP_WOOD_STRIPPED",
"blockId": "wood_stripped_birch",
"fuelTime": 60,
"oreDictionary": ["OD_WOOD_STRIPPED"]
}
}
}
================================================
FILE: blocks/tiles/woods/wood_stripped_dark_oak.json
================================================
{
"block": {
"wood_stripped_dark_oak": {
"textureData": "wood_stripped_dark_oak.png",
"color": [ 155, 140, 120 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "WOOD_B",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 60, 30, 10 ]
}
},
"item": {
"wood_stripped_dark_oak": {
"type": "BLOCKS",
"iconTextureData": "wood_stripped_dark_oak_icon.png",
"group": "GROUP_WOOD_STRIPPED",
"blockId": "wood_stripped_dark_oak",
"fuelTime": 60,
"oreDictionary": ["OD_WOOD_STRIPPED"]
}
}
}
================================================
FILE: blocks/tiles/woods/wood_stripped_jungle.json
================================================
{
"block": {
"wood_stripped_jungle": {
"textureData": "wood_stripped_jungle.png",
"color": [ 210, 177, 144 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "WOOD_B",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 100, 70, 50 ]
}
},
"item": {
"wood_stripped_jungle": {
"type": "BLOCKS",
"iconTextureData": "wood_stripped_jungle_icon.png",
"group": "GROUP_WOOD_STRIPPED",
"blockId": "wood_stripped_jungle",
"fuelTime": 60,
"oreDictionary": ["OD_WOOD_STRIPPED"]
}
}
}
================================================
FILE: blocks/tiles/woods/wood_stripped_oak.json
================================================
{
"block": {
"wood_stripped_oak": {
"textureData": "wood_stripped_oak.png",
"color": [ 166, 152, 134 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "WOOD_B",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 173, 137, 80 ]
}
},
"item": {
"wood_stripped_oak": {
"type": "BLOCKS",
"iconTextureData": "wood_stripped_oak_icon.png",
"group": "GROUP_WOOD_STRIPPED",
"blockId": "wood_stripped_oak",
"fuelTime": 60,
"oreDictionary": ["OD_WOOD_STRIPPED"]
}
}
}
================================================
FILE: blocks/tiles/woods/wood_stripped_palm.json
================================================
{
"block": {
"wood_stripped_palm": {
"textureData": "wood_stripped_palm.png",
"color": [ 182, 141, 86 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "WOOD_B",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 182, 141, 86 ]
}
},
"item": {
"wood_stripped_palm": {
"type": "BLOCKS",
"iconTextureData": "wood_stripped_palm_icon.png",
"group": "GROUP_WOOD_STRIPPED",
"blockId": "wood_stripped_palm",
"fuelTime": 60,
"oreDictionary": ["OD_WOOD_STRIPPED"]
}
}
}
================================================
FILE: blocks/tiles/woods/wood_stripped_spruce.json
================================================
{
"block": {
"wood_stripped_spruce": {
"textureData": "wood_stripped_spruce.png",
"color": [ 179, 158, 134 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "WOOD_B",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 120, 90, 60 ]
}
},
"item": {
"wood_stripped_spruce": {
"type": "BLOCKS",
"iconTextureData": "wood_stripped_spruce_icon.png",
"group": "GROUP_WOOD_STRIPPED",
"blockId": "wood_stripped_spruce",
"fuelTime": 60,
"oreDictionary": ["OD_WOOD_STRIPPED"]
}
}
}
================================================
FILE: blocks/tiles/woods/wood_stripped_tainted.json
================================================
{
"block": {
"wood_stripped_tainted": {
"textureData": "wood_stripped_tainted.png",
"color": [ 89, 85, 107 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "WOOD_B",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 89, 85, 107 ]
}
},
"item": {
"wood_stripped_tainted": {
"type": "BLOCKS",
"iconTextureData": "wood_stripped_tainted_icon.png",
"group": "GROUP_WOOD_STRIPPED",
"blockId": "wood_stripped_tainted",
"fuelTime": 60,
"oreDictionary": ["OD_WOOD_STRIPPED"]
}
}
}
================================================
FILE: blocks/tiles/woods/wood_stripped_volcano.json
================================================
{
"block": {
"wood_stripped_volcano": {
"textureData": "wood_stripped_volcano.png",
"color": [ 200, 60, 60 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "WOOD_B",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 200, 60, 60 ]
}
},
"item": {
"wood_stripped_volcano": {
"type": "BLOCKS",
"iconTextureData": "wood_stripped_volcano_icon.png",
"group": "GROUP_WOOD_STRIPPED",
"blockId": "wood_stripped_volcano",
"fuelTime": 60,
"oreDictionary": ["OD_WOOD_STRIPPED"]
}
}
}
================================================
FILE: blocks/tiles/woods/wood_tainted.json
================================================
{
"block": {
"wood_tainted": {
"textureData": "wood_tainted.png",
"color": [ 89, 85, 107 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "WOOD_B",
"subGroup": "WOOD",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"transformId": "wood_stripped_tainted",
"wallCheck": "NO_GENERABLE",
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 89, 85, 107 ]
}
},
"item": {
"wood_tainted": {
"type": "BLOCKS",
"iconTextureData": "wood_tainted_icon.png",
"group": "GROUP_WOOD",
"blockId": "wood_tainted",
"fuelTime": 60,
"oreDictionary": [ "OD_WOOD" ]
}
}
}
================================================
FILE: blocks/tiles/woods/wood_volcano.json
================================================
{
"block": {
"wood_volcano": {
"textureData": "wood_volcano.png",
"color": [ 200, 60, 60 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "WOOD_B",
"subGroup": "WOOD",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 100,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"transformId": "wood_stripped_volcano",
"wallCheck": "NO_GENERABLE",
"soundGroupId": "wood",
"stepSoundGroupId": "step_wood",
"particleColor": [ 255, 200, 60, 60 ]
}
},
"item": {
"wood_volcano": {
"type": "BLOCKS",
"iconTextureData": "wood_volcano_icon.png",
"group": "GROUP_WOOD",
"blockId": "wood_volcano",
"fuelTime": 360,
"oreDictionary": [ "OD_WOOD" ]
}
}
}
================================================
FILE: blocks/tiles/wools/wool_black.json
================================================
{
"block": {
"wool_black": {
"textureData": "wool_black.png",
"color": [ 99, 99, 99 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 60,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "cloth",
"stepSoundId": "step_cloth",
"particleColor": [ 255, 0, 0, 0 ]
}
},
"item": {
"wool_black": {
"type": "BLOCKS",
"iconTextureData": "wool_black_icon.png",
"group": "GROUP_WOOL",
"blockId": "wool_black",
"fuelTime": 20,
"oreDictionary": ["OD_WOOL"]
}
}
}
================================================
FILE: blocks/tiles/wools/wool_blue.json
================================================
{
"block": {
"wool_blue": {
"textureData": "wool_blue.png",
"color": [ 119, 129, 188 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 60,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "cloth",
"stepSoundId": "step_cloth",
"particleColor": [ 255, 0, 0, 120 ]
}
},
"item": {
"wool_blue": {
"type": "BLOCKS",
"iconTextureData": "wool_blue_icon.png",
"group": "GROUP_WOOL",
"blockId": "wool_blue",
"fuelTime": 20,
"oreDictionary": ["OD_WOOL"]
}
}
}
================================================
FILE: blocks/tiles/wools/wool_brown.json
================================================
{
"block": {
"wool_brown": {
"textureData": "wool_brown.png",
"color": [ 167, 133, 108 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 60,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "cloth",
"stepSoundId": "step_cloth",
"particleColor": [ 255, 130, 100, 50 ]
}
},
"item": {
"wool_brown": {
"type": "BLOCKS",
"iconTextureData": "wool_brown_icon.png",
"group": "GROUP_WOOL",
"blockId": "wool_brown",
"fuelTime": 20,
"oreDictionary": ["OD_WOOL"]
}
}
}
================================================
FILE: blocks/tiles/wools/wool_cyan.json
================================================
{
"block": {
"wool_cyan": {
"textureData": "wool_cyan.png",
"color": [ 88, 180, 180 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 60,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "cloth",
"stepSoundId": "step_cloth",
"particleColor": [ 255, 0, 120, 120 ]
}
},
"item": {
"wool_cyan": {
"type": "BLOCKS",
"iconTextureData": "wool_cyan_icon.png",
"group": "GROUP_WOOL",
"blockId": "wool_cyan",
"fuelTime": 20,
"oreDictionary": ["OD_WOOL"]
}
}
}
================================================
FILE: blocks/tiles/wools/wool_gray.json
================================================
{
"block": {
"wool_gray": {
"textureData": "wool_gray.png",
"color": [ 125, 125, 128 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 60,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "cloth",
"stepSoundId": "step_cloth",
"particleColor": [ 255, 60, 60, 60 ]
}
},
"item": {
"wool_gray": {
"type": "BLOCKS",
"iconTextureData": "wool_gray_icon.png",
"group": "GROUP_WOOL",
"blockId": "wool_gray",
"fuelTime": 20,
"oreDictionary": ["OD_WOOL"]
}
}
}
================================================
FILE: blocks/tiles/wools/wool_green.json
================================================
{
"block": {
"wool_green": {
"textureData": "wool_green.png",
"color": [ 144, 66, 92 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 60,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "cloth",
"stepSoundId": "step_cloth",
"particleColor": [ 255, 0, 120, 0 ]
}
},
"item": {
"wool_green": {
"type": "BLOCKS",
"iconTextureData": "wool_green_icon.png",
"group": "GROUP_WOOL",
"blockId": "wool_green",
"fuelTime": 20,
"oreDictionary": ["OD_WOOL"]
}
}
}
================================================
FILE: blocks/tiles/wools/wool_light_blue.json
================================================
{
"block": {
"wool_light_blue": {
"textureData": "wool_light_blue.png",
"color": [ 130, 215, 240 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 60,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "cloth",
"stepSoundId": "step_cloth",
"particleColor": [ 255, 60, 90, 120 ]
}
},
"item": {
"wool_light_blue": {
"type": "BLOCKS",
"iconTextureData": "wool_light_blue_icon.png",
"group": "GROUP_WOOL",
"blockId": "wool_light_blue",
"fuelTime": 20,
"oreDictionary": ["OD_WOOL"]
}
}
}
================================================
FILE: blocks/tiles/wools/wool_light_gray.json
================================================
{
"block": {
"wool_light_gray": {
"textureData": "wool_light_gray.png",
"color": [ 160, 166, 169 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 60,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "cloth",
"stepSoundId": "step_cloth",
"particleColor": [ 255, 120, 120, 100 ]
}
},
"item": {
"wool_light_gray": {
"type": "BLOCKS",
"iconTextureData": "wool_light_gray_icon.png",
"group": "GROUP_WOOL",
"blockId": "wool_light_gray",
"fuelTime": 20,
"oreDictionary": ["OD_WOOL"]
}
}
}
================================================
FILE: blocks/tiles/wools/wool_lime.json
================================================
{
"block": {
"wool_lime": {
"textureData": "wool_lime.png",
"color": [ 171, 212, 151 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 60,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "cloth",
"stepSoundId": "step_cloth",
"particleColor": [ 255, 50, 100, 0 ]
}
},
"item": {
"wool_lime": {
"type": "BLOCKS",
"iconTextureData": "wool_lime_icon.png",
"group": "GROUP_WOOL",
"blockId": "wool_lime",
"fuelTime": 20,
"oreDictionary": ["OD_WOOL"]
}
}
}
================================================
FILE: blocks/tiles/wools/wool_magenta.json
================================================
{
"block": {
"wool_magenta": {
"textureData": "wool_magenta.png",
"color": [ 202, 109, 193 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 60,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "cloth",
"stepSoundId": "step_cloth",
"particleColor": [ 255, 120, 60, 120 ]
}
},
"item": {
"wool_magenta": {
"type": "BLOCKS",
"iconTextureData": "wool_magenta_icon.png",
"group": "GROUP_WOOL",
"blockId": "wool_magenta",
"fuelTime": 20,
"oreDictionary": ["OD_WOOL"]
}
}
}
================================================
FILE: blocks/tiles/wools/wool_orange.json
================================================
{
"block": {
"wool_orange": {
"textureData": "wool_orange.png",
"color": [ 248, 116, 93 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 60,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "cloth",
"stepSoundId": "step_cloth",
"particleColor": [ 255, 140, 120, 100 ]
}
},
"item": {
"wool_orange": {
"type": "BLOCKS",
"iconTextureData": "wool_orange_icon.png",
"group": "GROUP_WOOL",
"blockId": "wool_orange",
"fuelTime": 20,
"oreDictionary": ["OD_WOOL"]
}
}
}
================================================
FILE: blocks/tiles/wools/wool_pink.json
================================================
{
"block": {
"wool_pink": {
"textureData": "wool_pink.png",
"color": [ 212, 155, 188 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 60,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "cloth",
"stepSoundId": "step_cloth",
"particleColor": [ 255, 130, 100, 100 ]
}
},
"item": {
"wool_pink": {
"type": "BLOCKS",
"iconTextureData": "wool_pink_icon.png",
"group": "GROUP_WOOL",
"blockId": "wool_pink",
"fuelTime": 20,
"oreDictionary": ["OD_WOOL"]
}
}
}
================================================
FILE: blocks/tiles/wools/wool_purple.json
================================================
{
"block": {
"wool_purple": {
"textureData": "wool_purple.png",
"color": [ 90, 114, 204 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 60,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "cloth",
"stepSoundId": "step_cloth",
"particleColor": [ 255, 60, 30, 120 ]
}
},
"item": {
"wool_purple": {
"type": "BLOCKS",
"iconTextureData": "wool_purple_icon.png",
"group": "GROUP_WOOL",
"blockId": "wool_purple",
"fuelTime": 20,
"oreDictionary": ["OD_WOOL"]
}
}
}
================================================
FILE: blocks/tiles/wools/wool_red.json
================================================
{
"block": {
"wool_red": {
"textureData": "wool_red.png",
"color": [ 186, 100, 97 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 60,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "cloth",
"stepSoundId": "step_cloth",
"particleColor": [ 255, 120, 0, 0 ]
}
},
"item": {
"wool_red": {
"type": "BLOCKS",
"iconTextureData": "wool_red_icon.png",
"group": "GROUP_WOOL",
"blockId": "wool_red",
"fuelTime": 20,
"oreDictionary": ["OD_WOOL"]
}
}
}
================================================
FILE: blocks/tiles/wools/wool_white.json
================================================
{
"block": {
"wool_white": {
"note": "各色羊毛 138:0-15",
"textureData": "wool_white.png",
"color": [ 201, 208, 208 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 60,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "cloth",
"stepSoundId": "step_cloth",
"particleColor": [ 255, 200, 170, 150 ]
}
},
"item": {
"wool_white": {
"type": "BLOCKS",
"iconTextureData": "wool_white_icon.png",
"group": "GROUP_WOOL",
"blockId": "wool_white",
"fuelTime": 20,
"oreDictionary": ["OD_WOOL"]
}
}
}
================================================
FILE: blocks/tiles/wools/wool_yellow.json
================================================
{
"block": {
"wool_yellow": {
"textureData": "wool_yellow.png",
"color": [ 252, 218, 96 ],
"renderMode": "RENDER_CUT",
"renderSortedInterval": 4,
"type": "TILE",
"group": "ARTIFICAL",
"collision": "SOLID",
"lightOpacity": 3,
"toolType": "PICKAXE",
"mineGrade": "GRASS",
"hardness": 60,
"slipperiness": 1.0,
"gravity": false,
"allowSlope": false,
"isWallDark": false,
"wallCheck": "NO_GENERABLE",
"soundGroupId": "cloth",
"stepSoundId": "step_cloth",
"particleColor": [ 255, 120, 120, 0 ]
}
},
"item": {
"wool_yellow": {
"type": "BLOCKS",
"iconTextureData": "wool_yellow_icon.png",
"group": "GROUP_WOOL",
"blockId": "wool_yellow",
"fuelTime": 20,
"oreDictionary": ["OD_WOOL"]
}
}
}
================================================
FILE: bone2d/ItemJointHelper.lua
================================================
local ItemJointHelper = class("ItemJointHelper")
---checkItemChanged
---@param itemSlot Slot
---@param cacheTable table
function ItemJointHelper.checkItemChanged(itemSlot, cacheTable)
local checking = false
if cacheTable.itemID == nil then
checking = true
else
if itemSlot.hasStack then
if cacheTable.itemID ~= itemSlot:GetStack():GetItem().id then
checking = true
end
else
if cacheTable.itemID ~= 0 then
checking = true
end
end
end
return checking
end
---setItem
---@param itemJoint Joint2D
---@param itemStack ItemStack
function ItemJointHelper.setItem(itemJoint, itemStack)
local holdX, holdY = 16, 16
local jointWidth, jointHeight = 32, 32
local item = itemStack:GetItem()
local usingEntity = item.hasEntity
if usingEntity then
holdX, holdY = item.handX, item.handY
jointWidth, jointHeight = item.entityWidth, item.entityHeight
end
itemJoint.transform.origin = Vector2.new(holdX, holdY)
itemJoint.size = Size.new(jointWidth, jointHeight)
itemJoint.visible = true
if NetMode.current == NetMode.Client then
local texOffsetX, texOffsetY, texWidth, texHeight = 0, 0, 32, 32
local texture = usingEntity and item.entityTextureLocation or item.iconTextureLocation
local scale = 1.0
if texture.valid then
local cut = TextureManager.getSourceRect(texture)
texWidth, texHeight = cut.width, cut.height
local modItem = itemStack:GetModItem()
if modItem ~= nil and modItem.IsUseTex32 and modItem:IsUseTex32() then
texWidth, texHeight = 32, 32
end
if usingEntity then
texOffsetX, texOffsetY = item.entityOffsetX, item.entityOffsetY
texWidth, texHeight = jointWidth, jointHeight
else
local maxTexSize = math.max(1, math.max(texWidth, texHeight))
scale = 32 / maxTexSize
end
itemJoint:setTexture("item", texture,
Vector2.new(-texOffsetX, -texOffsetY),
Rect.new(0, 0, texWidth, texHeight))
else
itemJoint:setTexture("item", texture, Vector2.new(0, 0), Rect.new(0, 0, 32, 32))
end
itemJoint.transform.rotation = math.pi / 2
itemJoint.transform.scale = Vector2.new(scale, scale)
end
end
---checkItem
---@param itemJoint Joint2D
---@param itemSlot Slot
---@param cacheTable table
function ItemJointHelper.checkItem(itemJoint, itemSlot, cacheTable)
local checking = ItemJointHelper.checkItemChanged(itemSlot, cacheTable)
if not checking then
return
end
if itemSlot.hasStack then
local stack = itemSlot:GetStack()
cacheTable.itemID = stack:GetItem().id
ItemJointHelper.setItem(itemJoint, stack)
else
cacheTable.itemID = 0
ItemJointHelper.clearItem(itemJoint)
end
end
---@param itemJoint Joint2D
function ItemJointHelper.clearItem(itemJoint)
itemJoint.visible = false
end
return ItemJointHelper
================================================
FILE: bone2d/NpcHumanAnimator.lua
================================================
local NpcHumanAnimator = class("NpcHumanAnimator")
function NpcHumanAnimator.create()
local asm = {
parameters = {
"Float Speed 0.0",
"Bool OnGround False",
"Float AirSpeed 0.0",
"Bool Standard False",
"Trigger SwordAttacking False",
"Bool HoldingItem False",
"Trigger StopAction False"
},
layers = {
{
name = "Base Layer",
weight = 1.0,
blending = "Override",
mask = {
disabledJoints = {}
},
states = {
{
name = "StandardIdle",
isDefault = true,
clipName = "Standard",
transitions = {
{
nextState = "Stand", offset = 0, duration = 0.5,
conditions = { "Standard == false" }
}
}
},
{
name = "Stand",
blendTree = {
parameter = "Speed",
motions = {
{ clipName = "Idle", threshold = 0.0 },
{ clipName = "Walk", threshold = 1.0 },
}
},
transitions = {
{
nextState = "Jump", offset = 0.0, duration = 0.15,
conditions = { "OnGround == false" }
},
}
},
{
name = "Jump",
clipName = "Jump",
transitions = {
{
nextState = "Stand", offset = 0, duration = 0.25,
hasExitTime = false,
conditions = { "OnGround == true" }
},
}
},
}
},
{
name = "Body Action Layer",
weight = 1.0,
blending = "Override",
--mask = {
--disabledJoints = { "base.body.front_leg", "base.body.back_leg" }
--},
states = {
{
name = "StandardIdle",
isDefault = true,
clipName = "Standard",
transitions = {
{
nextState = "HoldingItem", offset = 0, duration = 0.2,
conditions = { "HoldingItem == true" }
},
{
nextState = "SwordAttacking", offset = 0, duration = 0,
conditions = { "SwordAttacking == true" }
}
}
},
{
name = "HoldingItem",
clipName = "HoldingItem",
transitions = {
{
nextState = "StandardIdle", offset = 0, duration = 0.2,
conditions = { "HoldingItem == false" }
},
}
},
{
name = "SwordAttacking",
clipName = "SwordAttacking",
transitions = {
{
nextState = "StandardIdle", offset = 0.99, duration = 0,
hasExitTime = false,
},
{
nextState = "StandardIdle", offset = 0, duration = 0,
conditions = { "StopAction == true" }
}
}
},
}
}
}
}
return AnimatorData2D.new(asm)
end
return NpcHumanAnimator
================================================
FILE: bone2d/NpcHumanBoneInfo.lua
================================================
---@class TC.NpcHumanBoneInfo
local NpcHumanBoneInfo = class("NpcHumanBoneInfo")
local NpcHumanJoints = require("NpcHumanJoints")
local NpcHumanJointsTall = require("NpcHumanJointsTall")
local NpcHumanClips = require("NpcHumanClips")
local NpcHumanAnimator = require("NpcHumanAnimator")
local ItemJointHelper = require("ItemJointHelper")
local s_instance
---@return TC.NpcHumanBoneInfo
function NpcHumanBoneInfo.getInstance()
if s_instance == nil then
s_instance = NpcHumanBoneInfo.new()
end
return s_instance
end
function NpcHumanBoneInfo:__init()
self._pool = {} ---@type JointBody2D[]
end
---load
---@param npcID int
---@param texture TextureLocation
---@param sizeIndex int
---@return JointBody2D
function NpcHumanBoneInfo:load(npcID, texture, sizeIndex)
if sizeIndex == nil then
sizeIndex = 0
end
local last = self._pool[npcID]
if last then
return last:clone()
end
local joints
if sizeIndex == 1 then
joints = NpcHumanJointsTall.create(texture)
else
joints = NpcHumanJoints.create(texture)
end
local reserve = JointBody2D.new(joints)
reserve:setAnimator(NpcHumanClips.create(reserve.joints), NpcHumanAnimator.create())
self._pool[npcID] = reserve
return reserve:clone()
end
---checkHandItem
---@param itemJoint Joint2D
---@param itemSlot Slot
---@param cacheTable table
function NpcHumanBoneInfo.checkHandItem(itemJoint, itemSlot, cacheTable)
ItemJointHelper.checkItem(itemJoint, itemSlot, cacheTable)
end
---@param jointBody JointBody2D
---@param isBackHand boolean
function NpcHumanBoneInfo.getItemJoint(jointBody, isBackHand)
return isBackHand and jointBody.joints:getJoint("base.body.back_arm.back_item")
or jointBody.joints:getJoint("base.body.front_arm.front_item")
end
return NpcHumanBoneInfo
================================================
FILE: bone2d/NpcHumanClips.lua
================================================
local NpcHumanClips = class("NpcHumanClips")
---getClips
---@param joints JointCollection2D
---@return ClipCollection2D
function NpcHumanClips.create(joints)
local clips = ClipCollection2D.new(joints)
clips:addClip({
name = "Idle",
time = 1.5,
loop = true,
jointClips = {
{
jointName = "base.body",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = 0.0 },
{ time = 0.25, value = 0.0584 },
{ time = 0.5, value = 0.0 },
{ time = 0.7, value = -0.0425 },
{ time = 0.9, value = 0.0 },
}
}
}
},
{
jointName = "base.body.head",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = 0.0 },
{ time = 0.25, value = -0.0584 },
{ time = 0.5, value = 0.0 },
{ time = 0.7, value = 0.0425 },
{ time = 0.9, value = 0.0 },
}
}
}
},
{
jointName = "base.body.back_leg",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = 0.0 },
{ time = 0.25, value = -0.0584 },
{ time = 0.5, value = 0.0 },
{ time = 0.7, value = 0.0425 },
{ time = 0.9, value = 0.0 },
}
}
}
},
{
jointName = "base.body.front_leg",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = 0.0 },
{ time = 0.25, value = -0.0584 },
{ time = 0.5, value = 0.0 },
{ time = 0.7, value = 0.0425 },
{ time = 0.9, value = 0.0 },
}
}
}
},
{
jointName = "base.body.back_arm",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = 0.0 },
{ time = 0.5, value = -0.15 },
{ time = 1.0, value = 0.0 },
}
}
}
},
{
jointName = "base.body.front_arm",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = 0.0 },
{ time = 0.5, value = 0.15 },
{ time = 1.0, value = 0.0 },
}
}
}
},
}
})
clips:addClip({
name = "Walk",
time = 0.6,
loop = true,
jointClips = {
{
jointName = "base.body.back_leg",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = -0.75 },
{ time = 0.5, value = 0.5 },
{ time = 1.0, value = -0.75 },
}
}
}
},
{
jointName = "base.body.front_leg",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = 0.5 },
{ time = 0.5, value = -0.85 },
{ time = 1.0, value = 0.5 },
}
}
}
},
{
jointName = "base.body.front_arm",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = -0.5 },
{ time = 0.5, value = 0.5 },
{ time = 1.0, value = -0.5 },
}
}
}
},
{
jointName = "base.body.back_arm",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = 0.25 },
{ time = 0.5, value = -0.5 },
{ time = 1.0, value = 0.25 },
}
}
}
},
{
jointName = "base.body.head",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = 0.015 },
{ time = 0.5, value = -0.015 },
{ time = 1.0, value = 0.015 },
}
}
}
},
{
jointName = "base.body",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = 0.0 },
{ time = 0.5, value = 0.05 },
{ time = 1.0, value = 0.0 },
}
}
}
},
}
})
clips:addClip({
name = "Jump",
time = 1.79,
loop = true,
jointClips = {
{
jointName = "base.body.back_leg",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = -0.75 },
{ time = 0.5, value = -0.65 },
{ time = 1.0, value = -0.75 },
}
}
}
},
{
jointName = "base.body.front_leg",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = 0.75 },
{ time = 0.5, value = 0.85 },
{ time = 1.0, value = 0.75 },
}
}
}
},
{
jointName = "base.body.back_arm",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = -1.0 },
{ time = 0.5, value = -0.9 },
{ time = 1.0, value = -1.0 },
}
}
}
},
{
jointName = "base.body.front_arm",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = 1.0 },
{ time = 0.5, value = 0.9 },
{ time = 1.0, value = 1.0 },
}
}
}
},
{
jointName = "base.body.head",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = -0.02 },
{ time = 0.5, value = -0.05 },
{ time = 1.0, value = -0.02 },
}
}
}
},
{
jointName = "base.body",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = -0.00 },
{ time = 0.5, value = -0.03 },
{ time = 1.0, value = -0.00 },
}
}
}
},
}
})
clips:addClip({
name = "HoldingItem",
time = 0.51,
loop = true,
jointClips = {
{
jointName = "base.body.back_arm",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = -1.0 },
{ time = 0.5, value = -1.02 },
{ time = 1.0, value = -1.0 },
}
}
}
},
{
jointName = "base.body.back_arm.back_item",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, value = math.pi / 2 },
}
}
}
},
}
})
clips:addClip({
name = "SwordAttacking",
time = 1.0,
loop = false,
jointClips = {
{
jointName = "base.body.back_arm",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = -3.2 },
{ time = 1.0, value = -0.3 },
}
}
}
},
{
jointName = "base.body.back_arm",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, value = 0.0 },
}
}
}
},
{
jointName = "base.body.back_arm.back_item",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, value = 2.4 },
}
}
}
},
{
jointName = "base.body.front_arm",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, value = 1.0 },
}
}
}
},
{
jointName = "base.body.front_arm",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, value = -0.5 },
}
}
}
},
}
})
clips:addClip({
name = "Standard",
time = 1.0,
loop = true,
jointClips = {
{
jointName = "base.body.back_arm.back_item",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, value = math.pi / 2 },
}
}
}
},
}
})
return clips
end
return NpcHumanClips
================================================
FILE: bone2d/NpcHumanJoints.lua
================================================
local NpcHumanJoints = class("NpcHumanJoints")
---setSkin
---@param joints JointCollection2D
---@param textureLocation TextureLocation
function NpcHumanJoints.setSkin(joints, textureLocation)
if not textureLocation then
return
end
local body = joints:getJoint("base.body")
body:setTexture("skin", textureLocation, Vector2.new(-16, -18),
Rect.new(48, 0, 48, 48))
local head = body:getChild("head")
head:setTexture("skin", textureLocation, Vector2.new(-14, -14),
Rect.new(0, 0, 48, 48))
local front_arm = body:getChild("front_arm")
front_arm:setTexture("skin", textureLocation, Vector2.new(-20, -12),
Rect.new(96, 0, 48, 48))
local back_arm = body:getChild("back_arm")
back_arm:setTexture("skin", textureLocation, Vector2.new(-20, -12),
Rect.new(96, 0, 48, 48))
local front_leg = body:getChild("front_leg")
front_leg:setTexture("skin", textureLocation, Vector2.new(-20, -20),
Rect.new(144, 0, 48, 48))
local back_leg = body:getChild("back_leg")
back_leg:setTexture("skin", textureLocation, Vector2.new(-20, -20),
Rect.new(144, 0, 48, 48))
end
function NpcHumanJoints.create(textureLocation)
local joints = JointCollection2D.new()
joints.root = Joint2D.new("base",
Vector2.new(8, 48),
Size.new(16, 48))
local body = Joint2D.new("body",
Vector2.new(6, 15),
Size.new(8, 26))
joints.root:addChild(Vector2.new(8, 29), body)
local back_arm = Joint2D.new("back_arm",
Vector2.new(4, 4),
Size.new(8, 26))
body:addChild(Vector2.new(12, 4), back_arm, false)
local back_item = Joint2D.new("back_item",
Vector2.new(0, 0),
Size.new(32, 8))
back_arm:addChild(Vector2.new(4, 20), back_item, true)
back_item.visible = false
local head = Joint2D.new("head",
Vector2.new(12, 19),
Size.new(24, 22))
body:addChild(Vector2.new(8, -3), head, false)
local back_leg = Joint2D.new("back_leg",
Vector2.new(3, -1),
Size.new(10, 18))
body:addChild(Vector2.new(8, 17), back_leg, false)
local front_leg = Joint2D.new("front_leg",
Vector2.new(3, -1),
Size.new(10, 18))
body:addChild(Vector2.new(1, 17), front_leg, false)
local front_arm = Joint2D.new("front_arm",
Vector2.new(4, 4),
Size.new(8, 26))
body:addChild(Vector2.new(1, 4), front_arm)
local front_item = Joint2D.new("front_item",
Vector2.new(0, 0),
Size.new(32, 8))
front_arm:addChild(Vector2.new(4, 20), front_item, false)
front_item.visible = false
NpcHumanJoints.setSkin(joints, textureLocation)
return joints
end
return NpcHumanJoints
================================================
FILE: bone2d/NpcHumanJointsTall.lua
================================================
local NpcHumanJointsTall = class("NpcHumanJointsTall")
---setSkin
---@param joints JointCollection2D
---@param textureLocation TextureLocation
function NpcHumanJointsTall.setSkin(joints, textureLocation)
if not textureLocation then
return
end
local body = joints:getJoint("base.body")
body:setTexture("skin", textureLocation, Vector2.new(-16, -18),
Rect.new(48, 0, 48, 48))
local head = body:getChild("head")
head:setTexture("skin", textureLocation, Vector2.new(-14, -14),
Rect.new(0, 0, 48, 48))
local front_arm = body:getChild("front_arm")
front_arm:setTexture("skin", textureLocation, Vector2.new(-20, -12),
Rect.new(96, 0, 48, 48))
local back_arm = body:getChild("back_arm")
back_arm:setTexture("skin", textureLocation, Vector2.new(-20, -12),
Rect.new(96, 0, 48, 48))
local front_leg = body:getChild("front_leg")
front_leg:setTexture("skin", textureLocation, Vector2.new(-20, -20),
Rect.new(144, 0, 48, 48))
local back_leg = body:getChild("back_leg")
back_leg:setTexture("skin", textureLocation, Vector2.new(-20, -20),
Rect.new(144, 0, 48, 48))
end
function NpcHumanJointsTall.create(textureLocation)
local joints = JointCollection2D.new()
joints.root = Joint2D.new("base",
Vector2.new(8, 48),
Size.new(16, 48))
local body = Joint2D.new("body",
Vector2.new(6, 15),
Size.new(16, 26))
joints.root:addChild(Vector2.new(8, 10), body)
local back_arm = Joint2D.new("back_arm",
Vector2.new(4, 4),
Size.new(8, 26))
body:addChild(Vector2.new(14, 4), back_arm, false)
local back_item = Joint2D.new("back_item",
Vector2.new(0, 0),
Size.new(32, 8))
back_arm:addChild(Vector2.new(4, 28), back_item, true)
back_item.visible = false
local head = Joint2D.new("head",
Vector2.new(12, 19),
Size.new(24, 22))
body:addChild(Vector2.new(8, -3), head, false)
local back_leg = Joint2D.new("back_leg",
Vector2.new(5, -1),
Size.new(10, 28))
body:addChild(Vector2.new(11, 24), back_leg, false)
local front_leg = Joint2D.new("front_leg",
Vector2.new(5, -1),
Size.new(10, 28))
body:addChild(Vector2.new(4, 24), front_leg, false)
local front_arm = Joint2D.new("front_arm",
Vector2.new(4, 4),
Size.new(8, 26))
body:addChild(Vector2.new(3, 4), front_arm)
local front_item = Joint2D.new("front_item",
Vector2.new(0, 0),
Size.new(32, 8))
front_arm:addChild(Vector2.new(4, 20), front_item, false)
front_item.visible = false
NpcHumanJointsTall.setSkin(joints, textureLocation)
return joints
end
return NpcHumanJointsTall
================================================
FILE: bone2d/PlayerAnimator.lua
================================================
local PlayerAnimator = class("PlayerAnimator")
function PlayerAnimator.create()
local asm = {
parameters = {
"Float Speed 0.0",
"Bool OnGround False",
"Float AirSpeed 0.0",
"Bool Death False",
"Bool Standard False",
"Trigger Placing False",
"Trigger Eating False",
"Trigger SwordAttacking False",
"Bool HoldingItem False",
"Trigger StopAction False"
},
layers = {
{
name = "Base Layer",
weight = 1.0,
blending = "Override",
mask = {
disabledJoints = {}
},
states = {
{
name = "StandardIdle",
isDefault = true,
clipName = "Standard",
transitions = {
{
nextState = "Stand", offset = 0, duration = 0.5,
conditions = { "Standard == false" }
}
}
},
{
name = "Idle",
clipName = "Idle",
transitions = {
{
nextState = "Walk", offset = 0, duration = 0.95,
hasExitTime = false,
conditions = { "Speed > 0.5" }
}
}
},
{
name = "Walk",
clipName = "Walk",
transitions = {
{
nextState = "Idle", offset = 0.0, duration = 0.95,
conditions = { "Speed < 0.5" }
}
}
},
{
name = "Stand",
blendTree = {
parameter = "Speed",
motions = {
{ clipName = "Idle", threshold = 0.0 },
{ clipName = "Walk", threshold = 0.5 },
{ clipName = "Run", threshold = 1.0 }
}
},
transitions = {
{
nextState = "JumpUp", offset = 0.0, duration = 0.15,
conditions = { "OnGround == false", "AirSpeed < 0.0" }
},
{
nextState = "JumpDown", offset = 0.0, duration = 0.15,
conditions = { "OnGround == false", "AirSpeed >= 0.0" }
},
{
nextState = "Death", offset = 0.0, duration = 0.55,
conditions = { "Death == true" }
}
}
},
{
name = "JumpUp",
clipName = "JumpUp",
transitions = {
{
nextState = "JumpDown", offset = 0, duration = 0.15,
hasExitTime = false,
conditions = { "AirSpeed >= 0.0" }
},
{
nextState = "JustOnGround", offset = 0, duration = 0.25,
hasExitTime = false,
conditions = { "OnGround == true" }
},
{
nextState = "Death", offset = 0.0, duration = 0.55,
conditions = { "Death == true" }
}
}
},
{
name = "JumpDown",
clipName = "JumpDown",
transitions = {
{
nextState = "JumpUp", offset = 0, duration = 0.15,
hasExitTime = false,
conditions = { "AirSpeed < 0.0" }
},
{
nextState = "JustOnGround", offset = 0, duration = 0.05,
hasExitTime = false,
conditions = { "OnGround == true" }
},
{
nextState = "Death", offset = 0.0, duration = 0.55,
conditions = { "Death == true" }
}
}
},
{
name = "JustOnGround",
clipName = "JustOnGround",
transitions = {
{
nextState = "Stand", offset = 0.0, duration = 0.15,
hasExitTime = false,
},
{
nextState = "Death", offset = 0.0, duration = 0.55,
conditions = { "Death == true" }
}
}
},
{
name = "Death",
clipName = "Death",
transitions = {
{
nextState = "Stand", offset = 0.0, duration = 0.15,
conditions = { "Death == false" }
}
}
},
--{
-- name = "Standard",
-- clipName = "Standard",
-- isDefault = true,
-- transitions = {
-- }
--},
}
},
{
name = "Body Action Layer",
weight = 1.0,
blending = "Override",
--mask = {
--disabledJoints = { "base.body.front_leg", "base.body.back_leg" }
--},
states = {
{
name = "StandardIdle",
isDefault = true,
clipName = "Standard",
transitions = {
{
nextState = "Placing", offset = 0, duration = 0,
conditions = { "Placing == true" }
},
{
nextState = "Eating", offset = 0, duration = 0,
conditions = { "Eating == true" }
},
{
nextState = "HoldingItem", offset = 0, duration = 0.2,
conditions = { "HoldingItem == true" }
},
{
nextState = "SwordAttacking", offset = 0, duration = 0,
conditions = { "SwordAttacking == true" }
}
}
},
{
name = "HoldingItem",
clipName = "HoldingItem",
transitions = {
{
nextState = "Placing", offset = 0, duration = 0,
conditions = { "Placing == true" }
},
{
nextState = "Eating", offset = 0, duration = 0,
conditions = { "Eating == true" }
},
{
nextState = "StandardIdle", offset = 0, duration = 0.2,
conditions = { "HoldingItem == false" }
},
}
},
{
name = "Placing",
clipName = "Placing",
transitions = {
{
nextState = "HoldingItem", offset = 0.2499, duration = 0,
conditions = { "HoldingItem == true" }
},
{
nextState = "StandardIdle", offset = 0.2499, duration = 0,
},
{
nextState = "StandardIdle", offset = 0, duration = 0,
conditions = { "StopAction == true" }
}
}
},
{
name = "Eating",
clipName = "Eating",
transitions = {
{
nextState = "HoldingItem", offset = 0.2499, duration = 0,
conditions = { "HoldingItem == true" }
},
{
nextState = "StandardIdle", offset = 0.2499, duration = 0,
},
{
nextState = "StandardIdle", offset = 0, duration = 0,
conditions = { "StopAction == true" }
}
}
},
{
name = "SwordAttacking",
clipName = "SwordAttacking",
transitions = {
{
nextState = "StandardIdle", offset = 0.99, duration = 0,
hasExitTime = false,
},
{
nextState = "StandardIdle", offset = 0, duration = 0,
conditions = { "StopAction == true" }
}
}
},
}
}
}
}
return AnimatorData2D.new(asm)
end
return PlayerAnimator
================================================
FILE: bone2d/PlayerBoneInfo.lua
================================================
---@class TC.PlayerBoneInfo
local PlayerBoneInfo = class("PlayerJointBody")
local PlayerJoints = require("PlayerJoints")
local PlayerClips = require("PlayerClips")
local PlayerAnimator = require("PlayerAnimator")
local ItemJointHelper = require("ItemJointHelper")
local s_instance
---@return TC.PlayerBoneInfo
function PlayerBoneInfo.getInstance()
if s_instance == nil then
s_instance = PlayerBoneInfo.new()
end
return s_instance
end
function PlayerBoneInfo:__init()
self.body = JointBody2D.new(PlayerJoints.create())
self.body:setAnimator(PlayerClips.create(self.body.joints), PlayerAnimator.create())
end
function PlayerBoneInfo:reload()
self.body = JointBody2D.new(PlayerJoints.create())
self.body:setAnimator(PlayerClips.create(self.body.joints), PlayerAnimator.create())
end
---create
---@param skinTable table
---@return JointBody2D
function PlayerBoneInfo.create(skinTable)
local body = PlayerBoneInfo.getInstance().body:clone()
PlayerBoneInfo.setSkin(body, skinTable)
return body
end
function PlayerBoneInfo.getSkinTableByID(skinID)
local skin = SkinUtils.GetSkin(skinID)
return {
head = skin.headTexture,
body = skin.bodyTexture,
leg = skin.legTexture,
cloth = skin.clothTexture,
hair = skin.hairTexture,
pant = skin.pantTexture,
}
end
function PlayerBoneInfo.createBySkinID(skinID)
return PlayerBoneInfo.create(PlayerBoneInfo.getSkinTableByID(skinID))
end
---setSkin
---@param jointBody JointBody2D
---@param skinTable table
function PlayerBoneInfo.setSkin(jointBody, skinTable)
PlayerJoints.setSkin(jointBody.joints, skinTable)
end
function PlayerBoneInfo.setSkinByID(jointBody, skinID)
PlayerBoneInfo.setSkin(jointBody, PlayerBoneInfo.getSkinTableByID(skinID))
end
---checkHandItem
---@param itemJoint Joint2D
---@param itemSlot Slot
---@param cacheTable table
function PlayerBoneInfo.checkHandItem(itemJoint, itemSlot, cacheTable)
ItemJointHelper.checkItem(itemJoint, itemSlot, cacheTable)
end
---@param jointBody JointBody2D
---@param isBackHand boolean
function PlayerBoneInfo.getItemJoint(jointBody, isBackHand)
return isBackHand and jointBody.joints:getJoint("base.body.back_arm.back_hand.back_item")
or jointBody.joints:getJoint("base.body.front_arm.front_hand.front_item")
end
return PlayerBoneInfo
================================================
FILE: bone2d/PlayerClips.lua
================================================
local PlayerClips = class("PlayerClips")
---getClips
---@param joints JointCollection2D
---@return ClipCollection2D
function PlayerClips.create(joints)
local clips = ClipCollection2D.new(joints)
clips:addClip({
name = "Idle",
time = 1.5,
loop = true,
jointClips = {
{
jointName = "base.body",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = 0.0 },
{ time = 0.25, value = 0.0584 },
{ time = 0.5, value = 0.0 },
{ time = 0.7, value = -0.0425 },
{ time = 0.9, value = 0.0 },
}
}
}
},
{
jointName = "base.body.head",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = 0.0 },
{ time = 0.25, value = -0.0584 },
{ time = 0.5, value = 0.0 },
{ time = 0.7, value = 0.0425 },
{ time = 0.9, value = 0.0 },
}
}
}
},
{
jointName = "base.body.back_leg",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = 0.0 },
{ time = 0.25, value = -0.0584 },
{ time = 0.5, value = 0.0 },
{ time = 0.7, value = 0.0425 },
{ time = 0.9, value = 0.0 },
}
}
}
},
{
jointName = "base.body.back_leg.back_feet",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = 0.0 },
}
}
}
},
{
jointName = "base.body.front_leg",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = 0.0 },
{ time = 0.25, value = -0.0584 },
{ time = 0.5, value = 0.0 },
{ time = 0.7, value = 0.0425 },
{ time = 0.9, value = 0.0 },
}
}
}
},
{
jointName = "base.body.front_leg.front_feet",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = 0.0 },
}
}
}
},
{
jointName = "base.body.back_arm",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = 0.0 },
{ time = 0.5, value = -0.15 },
{ time = 1.0, value = 0.0 },
}
}
}
},
{
jointName = "base.body.back_arm.back_hand",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = 0.0 },
}
}
}
},
{
jointName = "base.body.front_arm",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = 0.0 },
{ time = 0.5, value = 0.15 },
{ time = 1.0, value = 0.0 },
}
}
}
},
{
jointName = "base.body.front_arm.front_hand",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = 0.0 },
}
}
}
},
}
})
clips:addClip({
name = "Walk",
time = 0.6,
loop = true,
jointClips = {
{
jointName = "base.body.back_leg",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = -0.75 },
{ time = 0.5, value = 0.5 },
{ time = 1.0, value = -0.75 },
}
}
}
},
{
jointName = "base.body.back_leg.back_feet",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = 0.25 },
{ time = 0.5, value = 0.75 },
{ time = 1.0, value = 0.25 },
}
}
}
},
{
jointName = "base.body.front_leg",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = 0.5 },
{ time = 0.5, value = -0.85 },
{ time = 1.0, value = 0.5 },
}
}
}
},
{
jointName = "base.body.front_leg.front_feet",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = 0.75 },
{ time = 0.5, value = 0.25 },
{ time = 1.0, value = 0.75 },
}
}
}
},
{
jointName = "base.body.front_arm",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = -0.5 },
{ time = 0.5, value = 0.5 },
{ time = 1.0, value = -0.5 },
}
}
}
},
{
jointName = "base.body.front_arm.front_hand",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = -0.5 },
{ time = 0.5, value = 0.0 },
{ time = 1.0, value = -0.5 },
}
}
}
},
{
jointName = "base.body.back_arm",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = 0.25 },
{ time = 0.5, value = -0.5 },
{ time = 1.0, value = 0.25 },
}
}
}
},
{
jointName = "base.body.back_arm.back_hand",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = 0.0 },
{ time = 0.5, value = -0.5 },
{ time = 1.0, value = 0.0 },
}
}
}
},
{
jointName = "base.body.head",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = 0.015 },
{ time = 0.5, value = -0.015 },
{ time = 1.0, value = 0.015 },
}
}
}
},
{
jointName = "base.body",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = 0.0 },
{ time = 0.5, value = 0.05 },
{ time = 1.0, value = 0.0 },
}
}
}
},
}
})
clips:addClip({
name = "Run",
time = 0.69,
loop = true,
jointClips = {
{
jointName = "base.body.back_leg",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = -0.85 },
{ time = 0.5, value = 0.5 },
{ time = 1.0, value = -0.85 },
}
}
}
},
{
jointName = "base.body.back_leg.back_feet",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = 0.05 },
{ time = 0.5, value = 0.95 },
{ time = 1.0, value = 0.05 },
}
}
}
},
{
jointName = "base.body.front_leg",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = 0.5 },
{ time = 0.5, value = -0.85 },
{ time = 1.0, value = 0.5 },
}
}
}
},
{
jointName = "base.body.front_leg.front_feet",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = 0.95 },
{ time = 0.5, value = 0.05 },
{ time = 1.0, value = 0.95 },
}
}
}
},
{
jointName = "base.body.front_arm",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = -0.5 },
{ time = 0.5, value = 0.75 },
{ time = 1.0, value = -0.5 },
}
}
}
},
{
jointName = "base.body.front_arm.front_hand",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = -1.25 },
{ time = 0.5, value = -0.60 },
{ time = 1.0, value = -1.25 },
}
}
}
},
{
jointName = "base.body.back_arm",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = 0.25 },
{ time = 0.5, value = -0.95 },
{ time = 1.0, value = 0.25 },
}
}
}
},
{
jointName = "base.body.back_arm.back_hand",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = -0.4 },
{ time = 0.5, value = -1.0 },
{ time = 1.0, value = -0.4 },
}
}
}
},
{
jointName = "base.body.head",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = 0.015 },
{ time = 0.5, value = -0.015 },
{ time = 1.0, value = 0.015 },
}
}
}
},
{
jointName = "base.body",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = 0.0 },
{ time = 0.5, value = 0.1 },
{ time = 1.0, value = 0.0 },
}
}
}
},
}
})
clips:addClip({
name = "JumpUp",
time = 1.79,
loop = true,
jointClips = {
{
jointName = "base.body.back_leg",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = -0.75 },
{ time = 0.5, value = -0.65 },
{ time = 1.0, value = -0.75 },
}
}
}
},
{
jointName = "base.body.back_leg.back_feet",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = 0.5 },
{ time = 0.5, value = 0.6 },
{ time = 1.0, value = 0.5 },
}
}
}
},
{
jointName = "base.body.front_leg",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = 0.15 },
{ time = 0.5, value = 0.05 },
{ time = 1.0, value = 0.15 },
}
}
}
},
{
jointName = "base.body.front_leg.front_feet",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = 0.6 },
{ time = 0.5, value = 0.5 },
{ time = 1.0, value = 0.6 },
}
}
}
},
{
jointName = "base.body.back_arm",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = -1.2 },
{ time = 0.5, value = -1.1 },
{ time = 1.0, value = -1.2 },
}
}
}
},
{
jointName = "base.body.back_arm.back_hand",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = -0.7 },
{ time = 0.5, value = -0.8 },
{ time = 1.0, value = -0.7 },
}
}
}
},
{
jointName = "base.body.front_arm",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = 1.1 },
{ time = 0.5, value = 1.0 },
{ time = 1.0, value = 1.1 },
}
}
}
},
{
jointName = "base.body.front_arm.front_hand",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = -0.70 },
{ time = 0.5, value = -0.60 },
{ time = 1.0, value = -0.70 },
}
}
}
},
{
jointName = "base.body.head",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = -0.05 },
{ time = 0.5, value = -0.1 },
{ time = 1.0, value = -0.05 },
}
}
}
},
{
jointName = "base.body",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = -0.10 },
{ time = 0.5, value = -0.08 },
{ time = 1.0, value = -0.10 },
}
}
}
},
}
})
clips:addClip({
name = "JumpDown",
time = 1.79,
loop = true,
jointClips = {
{
jointName = "base.body.back_leg",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = -0.95 },
{ time = 0.5, value = -0.85 },
{ time = 1.0, value = -0.95 },
}
}
}
},
{
jointName = "base.body.back_leg.back_feet",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = 0.5 },
{ time = 0.5, value = 0.6 },
{ time = 1.0, value = 0.5 },
}
}
}
},
{
jointName = "base.body.front_leg",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = -0.15 },
{ time = 0.5, value = -0.05 },
{ time = 1.0, value = -0.15 },
}
}
}
},
{
jointName = "base.body.front_leg.front_feet",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = 0.16 },
{ time = 0.5, value = 0.15 },
{ time = 1.0, value = 0.16 },
}
}
}
},
{
jointName = "base.body.back_arm",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = -2.4 },
{ time = 0.5, value = -2.5 },
{ time = 1.0, value = -2.4 },
}
}
}
},
{
jointName = "base.body.back_arm.back_hand",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = -0.0 },
{ time = 0.5, value = -0.0 },
{ time = 1.0, value = -0.0 },
}
}
}
},
{
jointName = "base.body.front_arm",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = 1.2 },
{ time = 0.5, value = 1.1 },
{ time = 1.0, value = 1.2 },
}
}
}
},
{
jointName = "base.body.front_arm.front_hand",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = -0.50 },
{ time = 0.5, value = -0.40 },
{ time = 1.0, value = -0.50 },
}
}
}
},
{
jointName = "base.body.head",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = -0.05 },
{ time = 0.5, value = -0.1 },
{ time = 1.0, value = -0.05 },
}
}
}
},
{
jointName = "base.body",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = 0.10 },
{ time = 0.5, value = 0.08 },
{ time = 1.0, value = 0.10 },
}
}
}
},
}
})
clips:addClip({
name = "JustOnGround",
time = 0.5,
loop = false,
jointClips = {
{
jointName = "base.body",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = 0.0 },
{ time = 0.5, value = 0.284 },
{ time = 1.0, value = 0.0 },
}
}
}
},
{
jointName = "base.body.head",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = 0.0 },
{ time = 0.25, value = -0.0584 },
{ time = 0.5, value = 0.0 },
{ time = 0.7, value = 0.0425 },
{ time = 0.9, value = 0.0 },
}
}
}
},
{
jointName = "base.body.back_arm",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = -1.2 },
{ time = 0.5, value = -1.1 },
{ time = 1.0, value = -1.2 },
}
}
}
},
{
jointName = "base.body.back_arm.back_hand",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = -0.7 },
{ time = 0.5, value = -0.8 },
{ time = 1.0, value = -0.7 },
}
}
}
},
{
jointName = "base.body.front_arm",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = 1.1 },
{ time = 0.5, value = 1.0 },
{ time = 1.0, value = 1.1 },
}
}
}
},
{
jointName = "base.body.front_arm.front_hand",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = -0.70 },
{ time = 0.5, value = -0.60 },
{ time = 1.0, value = -0.70 },
}
}
}
},
{
jointName = "base.body.back_leg",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = 0.0 },
{ time = 0.5, value = -0.284 },
{ time = 1.0, value = 0.0 },
}
}
}
},
{
jointName = "base.body.front_leg",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = 0.0 },
{ time = 0.5, value = -0.284 },
{ time = 1.0, value = 0.0 },
}
}
}
},
}
})
clips:addClip({
name = "Death",
time = 0.5,
loop = false,
jointClips = {
{
jointName = "base.body",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineIn", value = 0.0 },
{ time = 0.9, value = -1.57 },
}
}
}
},
{
jointName = "base.body.head",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineIn", value = 0.0 },
{ time = 0.5, value = 0.5 },
{ time = 0.9, value = -0.2 },
{ time = 1.0, value = 0.0 },
}
}
}
},
{
jointName = "base.body.back_leg",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = 0.0 },
{ time = 0.5, value = -1.3284 },
{ time = 1.0, value = 0.0 },
}
}
}
},
{
jointName = "base.body.front_leg",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = 0.0 },
{ time = 0.5, value = -0.9284 },
{ time = 0.9, value = 0.0 },
}
}
}
},
{
jointName = "base.body.back_arm",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = 0.0 },
{ time = 0.5, interpolation = "SineIn", value = -1.9284 },
{ time = 1.0, value = 0.0 },
}
}
}
},
{
jointName = "base.body.front_arm",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = 0.0 },
{ time = 0.5, interpolation = "SineIn", value = -1.4284 },
{ time = 1.0, value = 0.0 },
}
}
}
},
}
})
clips:addClip({
name = "HoldingItem",
time = 0.51,
loop = true,
jointClips = {
{
jointName = "base.body.back_arm",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = -1.0 },
{ time = 0.5, value = -1.02 },
{ time = 1.0, value = -1.0 },
}
}
}
},
{
jointName = "base.body.back_arm.back_hand.back_item",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, value = math.pi / 2 },
}
}
}
},
}
})
clips:addClip({
name = "SwordAttacking",
time = 1.0,
loop = false,
jointClips = {
{
jointName = "base.body.back_arm",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = -3.2 },
{ time = 1.0, value = -0.3 },
}
}
}
},
{
jointName = "base.body.back_arm.back_hand",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, value = 0.0 },
}
}
}
},
{
jointName = "base.body.back_arm.back_hand.back_item",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, value = 2.4 },
}
}
}
},
{
jointName = "base.body.front_arm",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, value = 1.0 },
}
}
}
},
{
jointName = "base.body.front_arm.front_hand",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, value = -0.5 },
}
}
}
},
{
jointName = "base.body",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = 0.0 },
{ time = 1.0, value = 0.1 },
}
}
}
},
--{
-- jointName = "base.body.back_leg",
-- data = {
-- {
-- variable = "Angle",
-- samples = {
-- { time = 0.0, interpolation = "SineInOut", value = 0.0 },
-- { time = 0.5, value = -0.1 },
-- { time = 1.0, value = 0.0 },
-- }
-- }
-- }
--},
--{
-- jointName = "base.body.front_leg",
-- data = {
-- {
-- variable = "Angle",
-- samples = {
-- { time = 0.0, interpolation = "SineInOut", value = 0.0 },
-- { time = 0.5, value = 0.1 },
-- { time = 0.9, value = 0.0 },
-- }
-- }
-- }
--},
}
})
clips:addClip({
name = "Placing",
time = 0.25,
loop = false,
jointClips = {
{
jointName = "base.body.back_arm",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = -4.0 },
{ time = 1.0, value = -0.8 },
}
}
}
}
}
})
clips:addClip({
name = "Eating",
time = 0.25,
loop = false,
jointClips = {
{
jointName = "base.body.back_arm",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, interpolation = "SineInOut", value = -0.8 },
{ time = 1.0, value = -4.0 },
}
}
}
}
}
})
clips:addClip({
name = "Standard",
time = 1.0,
loop = true,
jointClips = {
{
jointName = "base.body.back_arm.back_hand.back_item",
data = {
{
variable = "Angle",
samples = {
{ time = 0.0, value = math.pi / 2 },
}
}
}
},
}
})
return clips
end
return PlayerClips
================================================
FILE: bone2d/PlayerJoints.lua
================================================
local PlayerJoints = class("PlayerJoints")
---setSkin
---@param joints JointCollection2D
---@param textureTable table
function PlayerJoints.setSkin(joints, textureTable)
if not textureTable then
return
end
local body = joints:getJoint("base.body")
local head = body:getChild("head")
local back_arm = body:getChild("back_arm")
local back_hand = back_arm:getChild("back_hand")
local front_arm = body:getChild("front_arm")
local front_hand = front_arm:getChild("front_hand")
local back_leg = body:getChild("back_leg")
local back_feet = back_leg:getChild("back_feet")
local front_leg = body:getChild("front_leg")
local front_feet = front_leg:getChild("front_feet")
head:clearTexture("skin")
head:clearTexture("hair")
head:clearTexture("hat")
if textureTable.head ~= nil then
head:setTexture("skin", textureTable.head, Vector2.new(-16, -14),
Rect.new(0, 0, 48, 48))
end
if textureTable.hair ~= nil then
head:setTexture("hair", textureTable.hair, Vector2.new(-16, -14),
Rect.new(0, 0, 48, 48))
end
if textureTable.hat ~= nil then
head:setTexture("hat", textureTable.hat, Vector2.new(-16, -14),
Rect.new(0, 0, 48, 48))
end
body:clearTexture("skin")
body:clearTexture("cloth")
if textureTable.body ~= nil then
body:setTexture("skin", textureTable.body, Vector2.new(-16, -14),
Rect.new(0, 0, 48, 48))
back_arm:setTexture("skin", textureTable.body, Vector2.new(-22, -14),
Rect.new(144, 0, 48, 48))
back_hand:setTexture("skin", textureTable.body, Vector2.new(-22, -22),
Rect.new(192, 0, 48, 48))
front_arm:setTexture("skin", textureTable.body, Vector2.new(-12, -16),
Rect.new(48, 0, 48, 48))
front_hand:setTexture("skin", textureTable.body, Vector2.new(-14, -24),
Rect.new(96, 0, 48, 48))
end
if textureTable.cloth ~= nil then
body:setTexture("cloth", textureTable.cloth, Vector2.new(-16, -14),
Rect.new(0, 0, 48, 48))
back_arm:setTexture("cloth", textureTable.cloth, Vector2.new(-22, -14),
Rect.new(144, 0, 48, 48))
back_hand:setTexture("cloth", textureTable.cloth, Vector2.new(-22, -22),
Rect.new(192, 0, 48, 48))
front_arm:setTexture("cloth", textureTable.cloth, Vector2.new(-12, -16),
Rect.new(48, 0, 48, 48))
front_hand:setTexture("cloth", textureTable.cloth, Vector2.new(-14, -24),
Rect.new(96, 0, 48, 48))
end
back_leg:clearTexture("skin")
back_leg:clearTexture("pant")
front_leg:clearTexture("skin")
front_leg:clearTexture("pant")
back_feet:clearTexture("skin")
back_feet:clearTexture("shoe")
front_feet:clearTexture("skin")
front_feet:clearTexture("shoe")
if textureTable.leg ~= nil then
back_leg:setTexture("skin", textureTable.leg, Vector2.new(-20, -16),
Rect.new(0, 0, 48, 48))
back_feet:setTexture("skin", textureTable.leg, Vector2.new(-20, -22),
Rect.new(48, 0, 48, 48))
front_leg:setTexture("skin", textureTable.leg, Vector2.new(-20, -16),
Rect.new(0, 0, 48, 48))
front_feet:setTexture("skin", textureTable.leg, Vector2.new(-20, -22),
Rect.new(48, 0, 48, 48))
end
if textureTable.pant ~= nil then
back_leg:setTexture("pant", textureTable.pant, Vector2.new(-20, -16),
Rect.new(0, 0, 48, 48))
back_feet:setTexture("shoe", textureTable.pant, Vector2.new(-20, -22),
Rect.new(48, 0, 48, 48))
front_leg:setTexture("pant", textureTable.pant, Vector2.new(-20, -16),
Rect.new(0, 0, 48, 48))
front_feet:setTexture("shoe", textureTable.pant, Vector2.new(-20, -22),
Rect.new(48, 0, 48, 48))
end
end
function PlayerJoints.create(textureTable)
local joints = JointCollection2D.new()
joints.root = Joint2D.new("base",
Vector2.new(8, 48),
Size.new(16, 48))
local body = Joint2D.new("body",
Vector2.new(6, 15),
Size.new(12, 16))
joints.root:addChild(Vector2.new(8, 29), body)
local backpack = Joint2D.new("backpack",
Vector2.new(8, 8),
Size.new(16, 16))
body:addChild(Vector2.new(0, 8), backpack, false)
local back_arm = Joint2D.new("back_arm",
Vector2.new(4, 4),
Size.new(8, 10))
body:addChild(Vector2.new(10, 6), back_arm, false)
local back_hand = Joint2D.new("back_hand",
Vector2.new(3, 1),
Size.new(8, 14))
back_arm:addChild(Vector2.new(3, 7), back_hand, false)
local back_item = Joint2D.new("back_item",
Vector2.new(8, 4),
Size.new(32, 8))
back_hand:addChild(Vector2.new(4, 10), back_item, true)
back_item.visible = false
local head = Joint2D.new("head",
Vector2.new(8, 13),
Size.new(16, 16))
body:addChild(Vector2.new(6, -3), head, false)
local back_leg = Joint2D.new("back_leg",
Vector2.new(3, -1),
Size.new(8, 8))
body:addChild(Vector2.new(7, 15), back_leg, false)
local back_feet = Joint2D.new("back_feet",
Vector2.new(7, 0),
Size.new(10, 12))
back_leg:addChild(Vector2.new(7, 6), back_feet)
local front_leg = Joint2D.new("front_leg",
Vector2.new(3, -1),
Size.new(8, 8))
body:addChild(Vector2.new(3, 15), front_leg, false)
local front_feet = Joint2D.new("front_feet",
Vector2.new(7, 0),
Size.new(10, 12))
front_leg:addChild(Vector2.new(7, 6), front_feet)
local front_arm = Joint2D.new("front_arm",
Vector2.new(5, 4),
Size.new(8, 10))
body:addChild(Vector2.new(1, 6), front_arm)
local front_hand = Joint2D.new("front_hand",
Vector2.new(3, 1),
Size.new(8, 14))
front_arm:addChild(Vector2.new(5, 7), front_hand, false)
local front_item = Joint2D.new("front_item",
Vector2.new(8, 4),
Size.new(32, 8))
front_hand:addChild(Vector2.new(4, 10), front_item, false)
front_item.visible = false
PlayerJoints.setSkin(joints, textureTable)
return joints
end
return PlayerJoints
================================================
FILE: buffs/BaseBuffProxy.lua
================================================
---@class TC.BaseBuffProxy
local BaseBuffProxy = class("BaseBuffProxy")
---OnUpdatePlayer
---@param player Player
---@param buffRemainTime int
function BaseBuffProxy.OnUpdatePlayer(player, buffRemainTime)
end
return BaseBuffProxy
================================================
FILE: buffs/BuffBlindness.lua
================================================
---@class TC.BuffBlindness:TC.BaseBuffProxy
local BuffBlindness = class("BuffBlindness", require("BaseBuffProxy"))
function BuffBlindness.OnUpdatePlayer(player, _)
-- Client effect only.
if NetMode.current == NetMode.Server then
return
end
if player.isCurrentClientPlayer then
LightingUtils.SetState(LightingUtils.LIGHTING_STATE_BLINDNESS)
end
end
return BuffBlindness
================================================
FILE: buffs/BuffFire.lua
================================================
---@class TC.BuffFire:TC.BaseBuffProxy
local BuffFire = class("BuffFire", require("BaseBuffProxy"))
function BuffFire.OnUpdatePlayer(player, _)
if not player:HasBuff(Reg.BuffID("fire_defense")) then
local fireDefense = player.baseDefense.flameDefense
local interval = 16 * (1 + fireDefense)
if interval > 0 then
if player.tickTime % interval == 0 then
player:Strike(DeathReason.BURN,
Attack.new(1, 0, 0),
0, false, false)
end
end
end
if NetMode.current == NetMode.Client then
if player.tickTime % 8 == 0 then
EffectUtils.Create(Reg.EffectID("flame_star"),
player.randX,
player.randY,
Utils.RandSym(1),
Utils.RandSym(1),
0,
Utils.RandDoubleArea(1, 1)
)
EffectUtils.Create(Reg.EffectID("fire_flame"),
player.randX,
player.randY,
Utils.RandSym(1),
-Utils.RandDouble(2),
0,
Utils.RandDoubleArea(0.5, 0.5)
)
end
end
end
return BuffFire
================================================
FILE: buffs/BuffGlowing.lua
================================================
---@class TC.BuffGlowing:TC.BaseBuffProxy
local BuffGlowing = class("BuffGlowing", require("BaseBuffProxy"))
function BuffGlowing.OnUpdatePlayer(player, _)
-- Client effect only.
if NetMode.current == NetMode.Server then
return
end
if player.tickTime % 16 == 0 then
EffectUtils.Create(Reg.EffectID("chip"),
player.randX,
player.randY,
Utils.RandSym(2),
Utils.RandDoubleArea(-4, 2),
0,
Utils.RandDoubleArea(1, 2),
1.0,
Color.Yellow
)
end
LightingUtils.AddDelay(player.centerXi, player.centerYi, 32, 28)
end
return BuffGlowing
================================================
FILE: buffs/BuffHappiness.lua
================================================
---@class TC.BuffHappiness:TC.BaseBuffProxy
local BuffHappiness = class("BuffHappiness", require("BaseBuffProxy"))
function BuffHappiness.OnUpdatePlayer(player, _)
if player.tickTime % 64 == 0 then
EffectUtils.Create(Reg.EffectID("heal"),
player.randX,
player.randY,
Utils.RandSym(1),
Utils.RandDoubleArea(-2, 2),
0.0, 1.0, 1.0, Color.Red
)
player:Heal(1, false)
end
end
return BuffHappiness
================================================
FILE: buffs/BuffHealthBoost.lua
================================================
---@class TC.BuffHealthBoost:TC.BaseBuffProxy
local BuffHealthBoost = class("BuffHealthBoost", require("BaseBuffProxy"))
function BuffHealthBoost.OnUpdatePlayer(player, _)
if player.tickTime % 4 == 0 then
EffectUtils.Create(Reg.EffectID("heal"),
player.randX,
player.randY,
Utils.RandSym(1),
Utils.RandDoubleArea(-2, 2),
0, 1.0, 1.0, Color.Red)
player:Heal(1, false)
end
end
return BuffHealthBoost
================================================
FILE: buffs/BuffHunger.lua
================================================
---@class TC.BuffHunger:TC.BaseBuffProxy
local BuffHunger = class("BuffHunger", require("BaseBuffProxy"))
function BuffHunger.OnUpdatePlayer(player, _)
if player.tickTime % 128 == 0 then
player:DecFood(1)
end
if player.tickTime % 64 == 0 then
EffectUtils.Create(Reg.EffectID("chip"),
player.randX,
player.y,
Utils.RandSym(1),
Utils.RandDoubleArea(-2, 2),
Utils.RandSym(0.1),
2,
0.6,
Color.new(32, 32, 32)
)
end
end
return BuffHunger
================================================
FILE: buffs/BuffHurt.lua
================================================
---@class TC.BuffHurt:TC.BaseBuffProxy
local BuffHurt = class("BuffHurt", require("BaseBuffProxy"))
function BuffHurt.OnUpdatePlayer(player, _)
if player.tickTime % 4 == 0 then
EffectUtils.Create(Reg.EffectID("chip"),
player.randX,
player.y,
Utils.RandSym(1),
Utils.RandDoubleArea(-2, 1),
0,
1,
0.5,
Color.new(32, 32, 32)
)
end
if player.tickTime % 16 == 0 then
player:Strike(DeathReason.BUFF, Attack.new(1, 0, 0), 0, false, false)
end
end
return BuffHurt
================================================
FILE: buffs/BuffInvisibility.lua
================================================
---@class TC.BuffInvisibility:TC.BaseBuffProxy
local BuffInvisibility = class("BuffInvisibility", require("BaseBuffProxy"))
function BuffInvisibility.OnUpdatePlayer(player, _)
player.isInvisibility = true
if player.tickTime % 16 == 0 then
EffectUtils.Create(Reg.EffectID("chip"),
player.randX,
player.randY,
Utils.RandSym(1),
Utils.RandDoubleArea(-3, 3),
Utils.RandSym(0.1),
2,
1.0,
Color.new(100, 100, 200)
)
end
end
return BuffInvisibility
================================================
FILE: buffs/BuffJumpBoost.lua
================================================
---@class TC.BuffJumpBoost:TC.BaseBuffProxy
local BuffJumpBoost = class("BuffJumpBoost", require("BaseBuffProxy"))
function BuffJumpBoost.OnUpdatePlayer(player, _)
player.jumpRate = player.jumpRate + 0.5
end
return BuffJumpBoost
================================================
FILE: buffs/BuffLevitation.lua
================================================
---@class TC.BuffLevitation:TC.BaseBuffProxy
local BuffLevitation = class("BuffLevitation", require("BaseBuffProxy"))
function BuffLevitation.OnUpdatePlayer(player, _)
if not player.stand then
if player.speedY > -1 then
player.speedY = player.speedY - 0.2
else
player.speedY = -1
end
end
if player.tickTime % 8 == 0 then
EffectUtils.Create(Reg.EffectID("smoke"),
player.randX,
player.bottomY,
Utils.RandSym(1),
Utils.RandDouble(2),
Utils.RandSym(0.1),
0.5)
end
end
return BuffLevitation
================================================
FILE: buffs/BuffMiningFatigue.lua
================================================
---@class TC.BuffMiningFatigue:TC.BaseBuffProxy
local BuffMiningFatigue = class("BuffMiningFatigue", require("BaseBuffProxy"))
function BuffMiningFatigue.OnUpdatePlayer(player, _)
player.digSpeedRate = player.digSpeedRate + 0.5
if player.tickTime % 32 == 0 then
EffectUtils.Create(Reg.EffectID("heal"),
player.randX,
player.randY,
Utils.RandSym(1),
Utils.RandDoubleArea(-2, 2),
0, 1.0, 1.0, Color.Yellow)
end
end
return BuffMiningFatigue
================================================
FILE: buffs/BuffPoison.lua
================================================
---@class TC.BuffPoison:TC.BaseBuffProxy
local BuffPoison = class("BuffPoison", require("BaseBuffProxy"))
function BuffPoison.OnUpdatePlayer(player, _)
if player.tickTime % 16 == 0 then
EffectUtils.Create(Reg.EffectID("poison"),
player.randX,
player.y,
Utils.RandSym(1),
Utils.RandDoubleArea(-2, 1),
0,
1,
0.5)
end
if player.tickTime % 16 == 0 then
player:Strike(DeathReason.POISON, Attack.new(1, 0, 0), 0, false, false)
end
end
return BuffPoison
================================================
FILE: buffs/BuffProxies.lua
================================================
---@class TC.BuffProxies
local BuffProxies = class("BuffProxies")
local s_instance
---@return TC.BuffProxies
function BuffProxies.getInstance()
if s_instance == nil then
s_instance = BuffProxies.new()
end
return s_instance
end
function BuffProxies:__init()
---@type TC.BaseBuffProxy[]
self._proxies = {}
end
---@param player Player
function BuffProxies:OnUpdatePlayer(player)
if not player:HasAnyBuff() then
return
end
local buffs = player:GetBuffList()
---@param buff Buff
for _, buff in each(buffs) do
if buff.time > 0 then
local proxy = self._proxies[buff.id]
if proxy then
proxy.OnUpdatePlayer(player, buff.time)
end
end
end
end
---@param npc Npc
function BuffProxies:OnUpdateNpc(npc)
end
function BuffProxies:Register(idName, proxy)
local id = Reg.BuffID(idName)
self._proxies[id] = proxy
end
function BuffProxies:RegisterAll()
self:Register("tc:fire", require("BuffFire"))
self:Register("tc:blindness", require("BuffBlindness"))
self:Register("tc:glowing", require("BuffGlowing"))
self:Register("tc:happiness", require("BuffHappiness"))
self:Register("tc:health_boost", require("BuffHealthBoost"))
self:Register("tc:hunger", require("BuffHunger"))
self:Register("tc:hurt", require("BuffHurt"))
self:Register("tc:invisibility", require("BuffInvisibility"))
self:Register("tc:jump_boost", require("BuffJumpBoost"))
self:Register("tc:levitation", require("BuffLevitation"))
self:Register("tc:mining_fatique", require("BuffMiningFatigue"))
self:Register("tc:poison", require("BuffPoison"))
self:Register("tc:regeneration", require("BuffRegeneration"))
self:Register("tc:resistance", require("BuffResistance"))
self:Register("tc:sadness", require("BuffSadness"))
self:Register("tc:slow_falling", require("BuffSlowFalling"))
self:Register("tc:slow_mining", require("BuffSlowMining"))
self:Register("tc:slowness", require("BuffSlowness"))
self:Register("tc:speed", require("BuffSpeed"))
self:Register("tc:strength", require("BuffStrength"))
self:Register("tc:weak", require("BuffWeak"))
self:Register("tc:wither", require("BuffWither"))
self:Register("tc:vision", require("BuffVision"))
end
return BuffProxies
================================================
FILE: buffs/BuffRegeneration.lua
================================================
---@class TC.BuffRegeneration:TC.BaseBuffProxy
local BuffRegeneration = class("BuffRegeneration", require("BaseBuffProxy"))
function BuffRegeneration.OnUpdatePlayer(player, _)
if player.tickTime % 8 == 0 then
EffectUtils.Create(Reg.EffectID("heal"),
player.randX,
player.randY,
Utils.RandSym(1),
Utils.RandDoubleArea(-2, 2),
0, 1, 1, Color.Red)
player:Heal(1, false)
end
end
return BuffRegeneration
================================================
FILE: buffs/BuffResistance.lua
================================================
---@class TC.BuffResistance:TC.BaseBuffProxy
local BuffResistance = class("BuffResistance", require("BaseBuffProxy"))
function BuffResistance.OnUpdatePlayer(player, _)
player.baseDefense.defense = player.baseDefense.defense + 4
end
return BuffResistance
================================================
FILE: buffs/BuffSadness.lua
================================================
---@class TC.BuffSadness:TC.BaseBuffProxy
local BuffSadness = class("BuffSadness", require("BaseBuffProxy"))
function BuffSadness.OnUpdatePlayer(player, _)
player.baseDefense.defense = math.max(player.baseDefense.defense - 2, 0)
end
return BuffSadness
================================================
FILE: buffs/BuffSlowFalling.lua
================================================
---@class TC.BuffSlowFalling:TC.BaseBuffProxy
local BuffSlowFalling = class("BuffSlowFalling", require("BaseBuffProxy"))
function BuffSlowFalling.OnUpdatePlayer(player, _)
player.fallSpeedRate = player.fallSpeedRate - 0.75
if player.speedY > 1 then
if player.tickTime % 8 == 0 then
EffectUtils.Create(Reg.EffectID("chip"),
player.randX,
player.bottomY,
Utils.RandSym(1),
Utils.RandDoubleArea(2, 2),
Utils.RandSym(0.1),
2,
0.6,
Color.new(200, 200, 200)
)
end
end
end
return BuffSlowFalling
================================================
FILE: buffs/BuffSlowMining.lua
================================================
---@class TC.BuffSlowMining:TC.BaseBuffProxy
local BuffSlowMining = class("BuffSlowMining", require("BaseBuffProxy"))
function BuffSlowMining.OnUpdatePlayer(player, _)
player.digSpeedRate = player.digSpeedRate - 0.5
if player.tickTime % 32 == 0 then
EffectUtils.Create(Reg.EffectID("heal"),
player.randX,
player.randY,
Utils.RandSym(1),
Utils.RandDoubleArea(-2, 2),
0, 1, 1, Color.new(32, 32, 32))
end
end
return BuffSlowMining
================================================
FILE: buffs/BuffSlowness.lua
================================================
---@class TC.BuffSlowness:TC.BaseBuffProxy
local BuffSlowness = class("BuffSlowness", require("BaseBuffProxy"))
function BuffSlowness.OnUpdatePlayer(player, _)
player.speedRate = player.speedRate - 0.4
end
return BuffSlowness
================================================
FILE: buffs/BuffSpeed.lua
================================================
---@class TC.BuffSpeed:TC.BaseBuffProxy
local BuffSpeed = class("BuffSpeed", require("BaseBuffProxy"))
function BuffSpeed.OnUpdatePlayer(player, _)
player.speedRate = player.speedRate + 0.6
if math.abs(player.speedX) > 2 then
if player.tickTime % 4 == 0 then
if player.stand then
EffectUtils.Create(Reg.EffectID("smoke"),
player.randX,
player.bottomY,
Utils.RandSym(0.25),
Utils.RandSym(0.25),
Utils.RandSym(0.1), 0.25)
else
EffectUtils.Create(Reg.EffectID("smoke"),
player.randX,
player.randY,
-player.speedX / 8 + Utils.RandSym(0.5),
-player.speedY / 8 + Utils.RandSym(0.5),
Utils.RandSym(0.1), 0.5)
end
end
end
end
return BuffSpeed
================================================
FILE: buffs/BuffStrength.lua
================================================
---@class TC.BuffStrength:TC.BaseBuffProxy
local BuffStrength = class("BuffStrength", require("BaseBuffProxy"))
function BuffStrength.OnUpdatePlayer(player, _)
player.baseAttack.attack = player.baseAttack.attack + 3
end
return BuffStrength
================================================
FILE: buffs/BuffVision.lua
================================================
---@class TC.BuffVision:TC.BaseBuffProxy
local BuffVision = class("BuffVision", require("BaseBuffProxy"))
function BuffVision.OnUpdatePlayer(player, _)
if player.isCurrentClientPlayer then
LightingUtils.SetState(LightingUtils.LIGHTING_STATE_NIGHT_VISION)
end
end
return BuffVision
================================================
FILE: buffs/BuffWeak.lua
================================================
---@class TC.BuffWeak:TC.BaseBuffProxy
local BuffWeak = class("BuffWeak", require("BaseBuffProxy"))
function BuffWeak.OnUpdatePlayer(player, _)
player.baseAttack.attack = math.max(player.baseAttack.attack - 8, 0)
end
return BuffWeak
================================================
FILE: buffs/BuffWither.lua
================================================
---@class TC.BuffWither:TC.BaseBuffProxy
local BuffWither = class("BuffWither", require("BaseBuffProxy"))
function BuffWither.OnUpdatePlayer(player, _)
if player.tickTime % 16 == 0 then
EffectUtils.Create(Reg.EffectID("chip"),
player.randX,
player.y,
Utils.RandSym(1),
Utils.RandDoubleArea(-2, 1),
0, 1, 0.5, Color.new(32, 32, 32))
player:Strike(DeathReason.BUFF, Attack.new(1, 0, 0), 0, false, false)
end
end
return BuffWither
================================================
FILE: buffs/absorption.json
================================================
{
"absorption": {
"textureData": "absorption.png"
}
}
================================================
FILE: buffs/blindness.json
================================================
{
"blindness": {
"textureData": "blindness.png"
}
}
================================================
FILE: buffs/fire.json
================================================
{
"fire": {
"textureData": "fire.png"
}
}
================================================
FILE: buffs/fire_defense.json
================================================
{
"fire_defense": {
"textureData": "fire_defense.png"
}
}
================================================
FILE: buffs/glowing.json
================================================
{
"glowing": {
"textureData": "glowing.png"
}
}
================================================
FILE: buffs/happiness.json
================================================
{
"happiness": {
"textureData": "happiness.png"
}
}
================================================
FILE: buffs/health_boost.json
================================================
{
"health_boost": {
"textureData": "health_boost.png"
}
}
================================================
FILE: buffs/health_cold.json
================================================
{
"health_cold": {
"textureData": "health_cold.png"
}
}
================================================
FILE: buffs/hunger.json
================================================
{
"hunger": {
"textureData": "hunger.png"
}
}
================================================
FILE: buffs/hurt.json
================================================
{
"hurt": {
"textureData": "hurt.png"
}
}
================================================
FILE: buffs/invisibility.json
================================================
{
"invisibility": {
"textureData": "invisibility.png"
}
}
================================================
FILE: buffs/jump_boost.json
================================================
{
"jump_boost": {
"textureData": "jump_boost.png"
}
}
================================================
FILE: buffs/levitation.json
================================================
{
"levitation": {
"textureData": "levitation.png"
}
}
================================================
FILE: buffs/luck.json
================================================
{
"luck": {
"textureData": "luck.png"
}
}
================================================
FILE: buffs/mining_fatique.json
================================================
{
"mining_fatique": {
"textureData": "mining_fatique.png"
}
}
================================================
FILE: buffs/nausea.json
================================================
{
"nausea": {
"textureData": "nausea.png"
}
}
================================================
FILE: buffs/poison.json
================================================
{
"poison": {
"textureData": "poison.png"
}
}
================================================
FILE: buffs/regeneration.json
================================================
{
"regeneration": {
"textureData": "regeneration.png"
}
}
================================================
FILE: buffs/resistance.json
================================================
{
"resistance": {
"textureData": "resistance.png"
}
}
================================================
FILE: buffs/sadness.json
================================================
{
"sadness": {
"textureData": "sadness.png"
}
}
================================================
FILE: buffs/slow_falling.json
================================================
{
"slow_falling": {
"textureData": "slow_falling.png",
"script": {
"path": "slow_falling.lua"
}
}
}
================================================
FILE: buffs/slow_mining.json
================================================
{
"slow_mining": {
"textureData": "slow_mining.png",
"script": {
"path": "slow_mining.lua"
}
}
}
================================================
FILE: buffs/slowness.json
================================================
{
"slowness": {
"textureData": "slowness.png",
"script": {
"path": "slowness.lua"
}
}
}
================================================
FILE: buffs/speed.json
================================================
{
"speed": {
"textureData": "speed.png",
"script": {
"path": "speed.lua"
}
}
}
================================================
FILE: buffs/strength.json
================================================
{
"strength": {
"textureData": "strength.png",
"script": {
"path": "strength.lua"
}
}
}
================================================
FILE: buffs/vision.json
================================================
{
"vision": {
"textureData": "vision.png",
"script": {
"path": "vision.lua"
}
}
}
================================================
FILE: buffs/water_breathing.json
================================================
{
"water_breathing": {
"textureData": "water_breathing.png"
}
}
================================================
FILE: buffs/weak.json
================================================
{
"weak": {
"textureData": "weak.png",
"script": {
"path": "weak.lua"
}
}
}
================================================
FILE: buffs/wither.json
================================================
{
"wither": {
"textureData": "wither.png",
"script": {
"path": "wither.lua"
}
}
}
================================================
FILE: buildings/aurora_palace/aurora_palace.json
================================================
{
"aurora_palace": {
"maxGenPartCount": 40,
"limitSize": 1000,
"mainRestraint": {
"checks": [
[ "IS_CENTER_Y_GREATER_OR_EQUAL_TO", 0 ]
]
},
"blockEntityFormat": {
"normal_reward": {
"formatId": "tc:common_rewards",
"data": {
"rareGenCount": 1,
"rares": [
{
"itemId": "rocket_boost",
"count": 1
},
{
"itemId": "strange_eye",
"count": 1
},
{
"itemId": "ender_mirror",
"count": 1
},
{
"itemId": "wooden_sword",
"count": 1
},
{
"itemId": "stone_sword",
"count": 1
},
{
"itemId": "wooden_axe",
"count": 1
},
{
"itemId": "stone_axe",
"count": 1
},
{
"itemId": "wooden_pickaxe",
"count": 1
},
{
"itemId": "stone_pickaxe",
"count": 1
},
{
"itemId": "wooden_bow",
"count": 1
},
{
"itemId": "wooden_boomerang",
"count": 1
},
{
"itemId": "torch",
"count": 24
},
{
"itemId": "glow_bomb",
"count": 2
},
{
"itemId": "glow_ball",
"count": 6
},
{
"itemId": "book",
"count": 3
},
{
"itemId": "grenade",
"count": 3
},
{
"itemId": "amethyst_staff",
"count": 1
},
{
"itemId": "water_staff",
"count": 1
}
],
"normals": [
{
"itemIds": [ "ender_pearl" ],
"rate": 0.3,
"min": 1,
"max": 2
},
{
"itemIds": [ "sand" ],
"rate": 0.5,
"min": 1,
"max": 4
},
{
"itemIds": [ "sugar_cane" ],
"rate": 0.5,
"min": 1,
"max": 3
},
{
"itemIds": [ "ice" ],
"rate": 0.4,
"min": 1,
"max": 2
},
{
"itemIds": [ "blue_ice" ],
"rate": 0.3,
"min": 1,
"max": 3
},
{
"itemIds": [ "stick" ],
"rate": 0.3,
"min": 1,
"max": 12
},
{
"itemIds": [ "glowstone_dust" ],
"rate": 0.3,
"min": 3,
"max": 12
},
{
"itemIds": [ "coal", "charcoal" ],
"rate": 0.26,
"min": 1,
"max": 12
},
{
"itemIds": [ "redstone" ],
"rate": 0.26,
"min": 1,
"max": 4
},
{
"itemIds": [ "iron_ingot", "copper_ingot", "tin_ingot", "lead_ingot" ],
"rate": 0.3,
"min": 1,
"max": 4
},
{
"itemIds": [ "gold_ingot", "silver_ingot", "bronze_ingot", "steel_ingot" ],
"rate": 0.1,
"min": 1,
"max": 4
},
{
"itemIds": [ "wooden_arrow" ],
"rate": 0.4,
"min": 2,
"max": 7
},
{
"itemIds": [ "ice_arrow" ],
"rate": 0.4,
"min": 2,
"max": 7
},
{
"itemIds": [ "ice_bow" ],
"rate": 0.3,
"min": 1,
"max": 1
}
]
}
}
},
"rewards": [
],
"restraints": [
],
"commandColors": [
{
"color": [ 255, 64, 64, 64 ],
"note": "无操作",
"command": [
[ "BC_NO_OP" ]
]
},
{
"color": [ 255, 192, 192, 192 ],
"note": "前景记号"
},
{
"color": [ 255, 0, 0, 0 ],
"note": "空气",
"command": [
[ "BC_CLEAR_LAKE" ],
[ "BC_CLEAR" ]
]
},
{
"color": [ 255, 0, 64, 255 ],
"pipe": true
},
{
"color": [ 255, 0, 255, 255 ],
"pipe": true
},
{
"color": [ 255, 0, 160, 255 ],
"note": "箱子",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "aurora_block" ],
[ "BC_PLACE_FURNITURE", "chest", 0, "normal_reward" ]
]
},
{
"color": [ 255, 244, 0, 0 ],
"note": "女王球",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "aurora_block" ],
[ "BC_PLACE_FURNITURE", "snow_glass_ball" ]
]
},
{
"color": [ 255, 168, 168, 168 ],
"note": "主方块前景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "aurora_block" ],
[ "BC_PLACE_TILE", "aurora_block" ]
]
},
{
"color": [ 255, 114, 114, 114 ],
"note": "主方块后景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "aurora_block" ]
]
},
{
"color": [ 255, 188, 188, 188 ],
"note": "柱前景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "aurora_pillar" ],
[ "BC_PLACE_TILE", "aurora_pillar" ]
]
},
{
"color": [ 255, 144, 144, 144 ],
"note": "柱后景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "aurora_pillar" ]
]
},
{
"color": [ 255, 188, 144, 144 ],
"note": "木板前景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "aurora_block" ],
[ "BC_PLACE_TILE", "plank_birch" ]
]
},
{
"color": [ 255, 0, 0, 222 ],
"note": "浮冰",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "aurora_block" ],
[ "BC_PLACE_TILE", "ice_packed" ]
]
},
{
"color": [ 255, 0, 0, 122 ],
"note": "冰",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "aurora_block" ],
[ "BC_PLACE_TILE", "ice" ]
]
}
],
"parts": [
{
"name": "entrance",
"image": [ "entrance", "entrance_o1" ],
"type": "PT_START",
"hotX": 60,
"hotY": 50,
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "r1",
"image": [ "r1", "r1_o1", "r1_o2", "r1_o3", "r1_o4", "r1_o5", "r1_o6" ],
"type": "PT_NORMAL",
"unlinkParts": [],
"weight": 10
},
{
"name": "r2",
"image": [ "r2", "r2_o1", "r2_o2", "r2_o3", "r2_o4", "r2_o5" ],
"type": "PT_NORMAL",
"unlinkParts": [],
"weight": 10
},
{
"name": "r3",
"image": [ "r3", "r3_o1", "r3_o2", "r3_o3", "r3_o4", "r3_o5" ],
"type": "PT_NORMAL",
"unlinkParts": [],
"weight": 10
},
{
"name": "r4",
"image": [ "r4", "r4_o1", "r4_o2", "r4_o3" ],
"type": "PT_NORMAL",
"unlinkParts": [],
"weight": 10
},
{
"name": "r5",
"image": [ "r5", "r5_o1", "r5_o2", "r5_o3" ],
"type": "PT_NORMAL",
"unlinkParts": [],
"weight": 10
},
{
"name": "r6",
"image": [ "r6", "r4_o1", "r4_o2", "r4_o3" ],
"type": "PT_NORMAL",
"unlinkParts": [],
"weight": 10
},
{
"name": "r7",
"image": [ "r7", "r5_o1", "r5_o2", "r5_o3" ],
"type": "PT_NORMAL",
"unlinkParts": [],
"weight": 10
},
{
"name": "r8",
"image": [ "r8" ],
"type": "PT_NORMAL",
"unlinkParts": [],
"weight": 10
},
{
"name": "r9",
"image": [ "r9" ],
"type": "PT_NORMAL",
"unlinkParts": [],
"weight": 10
},
{
"name": "e1",
"image": [ "e1", "e1_o1", "e1_o2" ],
"type": "PT_END",
"unlinkParts": [],
"weight": 10
},
{
"name": "e2",
"image": [ "e2", "e1_o1", "e1_o2" ],
"type": "PT_END",
"unlinkParts": [],
"weight": 10
}
]
}
}
================================================
FILE: buildings/by_house/by_house.json
================================================
{
"by_house": {
"maxGenPartCount": 50,
"limitSize": 300,
"rewards": [
{
"name": "normal_reward",
"rareGenCount": 1,
"rares": [
{
"itemId": "stone_sword",
"count": 1
},
{
"itemId": "stone_pickaxe",
"count": 1
},
{
"itemId": "wooden_bow",
"count": 1
},
{
"itemId": "cross_bow",
"count": 1
}
],
"normals": [
{
"itemIds": [ "wood_dark_oak" ],
"rate": 0.9,
"min": 3,
"max": 5
},
{
"itemIds": [ "iron_ingot", "copper_ingot", "tin_ingot", "lead_ingot" ],
"rate": 0.3,
"min": 3,
"max": 10
},
{
"itemIds": [ "potato" ],
"rate": 0.5,
"min": 3,
"max": 6
},
{
"itemIds": [ "wheat" ],
"rate": 0.7,
"min": 3,
"max": 6
},
{
"itemIds": [ "carrot" ],
"rate": 0.5,
"min": 3,
"max": 6
},
{
"itemIds": [ "string" ],
"rate": 0.4,
"min": 2,
"max": 7
},
{
"itemIds": [ "wooden_arrow" ],
"rate": 0.4,
"min": 2,
"max": 7
}
]
}
],
"commandColors": [
{
"color": [ 255, 64, 64, 64 ],
"note": "无操作",
"command": [
[ "BC_NO_OP" ]
]
},
{
"color": [ 255, 192, 192, 192 ],
"note": "前景记号"
},
{
"color": [ 255, 0, 0, 0 ],
"note": "空气",
"command": [
[ "BC_CLEAR_LAKE" ],
[ "BC_CLEAR" ]
]
},
{
"color": [ 255, 0, 64, 255 ],
"pipe": true
},
{
"color": [ 255, 0, 255, 255 ],
"note": "箱子",
"command": [
]
},
{
"color": [ 255, 102, 102, 204 ],
"note": "橡木门",
"command": [
[ "BC_PLACE_FURNITURE", "wooden_door_oak" ]
]
},
{
"color": [ 255, 255, 0, 255 ],
"note": "橡木平台",
"command": [
[ "BC_PLACE_TILE", "platform_oak" ]
]
},
{
"color": [ 255, 50, 50, 100 ],
"note": "有空气就放水",
"command": [
[ "BC_PLACE_LIQUID", "water" ]
]
},
{
"color": [ 255, 54, 40, 27 ],
"note": "有空气就放泥土",
"command": [
[ "BC_CLEAR_FURNITURE" ],
[ "BC_PLACE_TILE", "dirt" ]
]
},
{
"color": [ 255, 54, 100, 27 ],
"note": "有空气就放草泥土",
"command": [
[ "BC_CLEAR_FURNITURE" ],
[ "BC_PLACE_TILE", "dirt", 1 ]
]
},
{
"color": [ 255, 40, 30, 20 ],
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "wood_dark_oak" ],
[ "BC_PLACE_TILE", "wood_dark_oak" ]
]
},
{
"color": [ 255, 20, 15, 11 ],
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "wood_dark_oak" ]
]
},
{
"color": [ 255, 70, 50, 20 ],
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "plank_dark_oak" ],
[ "BC_PLACE_TILE", "plank_dark_oak" ]
]
},
{
"color": [ 255, 44, 32, 13 ],
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "plank_dark_oak" ]
]
},
{
"color": [ 255, 120, 98, 60 ],
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "wood_stripped_oak" ]
]
},
{
"color": [ 255, 130, 70, 50 ],
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "brick" ],
[ "BC_PLACE_TILE", "brick" ]
]
},
{
"color": [ 255, 88, 49, 37 ],
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "brick" ]
]
},
{
"color": [ 255, 222, 222, 244 ],
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "glass" ]
]
}
],
"parts": [
{
"name": "entrance",
"image": [ "entrance" ],
"type": "PT_START",
"hotX": 100,
"hotY": 94,
"unlinkParts": [ "entrance" ],
"weight": 10
}
]
}
}
================================================
FILE: buildings/desert_house/desert_house.json
================================================
{
"desert_house": {
"maxGenPartCount": 1,
"limitSize": 100,
"blockEntityFormat": {
"normal_reward": {
"formatId": "tc:common_rewards",
"data": {
"rareGenCount": 1,
"rares": [],
"normals": [
{
"itemIds": [ "water_staff", "amethyst_staff" ],
"rate": 0.54,
"min": 1,
"max": 1
},
{
"itemIds": [ "ender_pearl" ],
"rate": 0.3,
"min": 1,
"max": 2
},
{
"itemIds": [ "bread" ],
"rate": 0.40,
"min": 1,
"max": 4
},
{
"itemIds": [ "iron_ingot", "copper_ingot", "tin_ingot", "lead_ingot" ],
"rate": 0.2,
"min": 1,
"max": 3
},
{
"itemIds": [ "emerald" ],
"rate": 0.15,
"min": 1,
"max": 1
},
{
"itemIds": [ "iron_helmet" ],
"rate": 0.15,
"min": 1,
"max": 1
},
{
"itemIds": [ "iron_chestplate" ],
"rate": 0.15,
"min": 1,
"max": 1
},
{
"itemIds": [ "iron_leggings" ],
"rate": 0.15,
"min": 1,
"max": 1
},
{
"itemIds": [ "raw_porkchop" ],
"rate": 0.24,
"min": 1,
"max": 3
},
{
"itemIds": [ "raw_mutton" ],
"rate": 0.24,
"min": 1,
"max": 3
},
{
"itemIds": [ "raw_beef" ],
"rate": 0.24,
"min": 1,
"max": 3
},
{
"itemIds": [ "wheat" ],
"rate": 0.24,
"min": 1,
"max": 3
},
{
"itemIds": [ "coal", "charcoal" ],
"rate": 0.13,
"min": 1,
"max": 3
},
{
"itemIds": [ "paper", "book" ],
"rate": 0.3,
"min": 1,
"max": 5
},
{
"itemIds": [ "stick" ],
"rate": 0.3,
"min": 1,
"max": 2
},
{
"itemIds": [ "sapling_oak" ],
"rate": 0.2,
"min": 1,
"max": 2
},
{
"itemIds": [ "raw_salmon" ],
"rate": 0.2,
"min": 1,
"max": 3
},
{
"itemIds": [ "raw_cod" ],
"rate": 0.2,
"min": 1,
"max": 3
},
{
"itemIds": [ "bucket_water" ],
"rate": 0.2,
"min": 1,
"max": 3
},
{
"itemIds": [ "feather" ],
"rate": 0.25,
"min": 1,
"max": 3
},
{
"itemIds": [ "wooden_arrow" ],
"rate": 0.12,
"min": 1,
"max": 3
},
{
"itemIds": [ "dye_yellow" ],
"rate": 0.12,
"min": 1,
"max": 1
},
{
"itemIds": [ "dye_green" ],
"rate": 0.12,
"min": 1,
"max": 1
}
]
}
}
},
"commandColors": [
{
"color": [ 255, 64, 64, 64 ],
"note": "无操作",
"command": [
[ "BC_NO_OP" ]
]
},
{
"color": [ 255, 192, 192, 192 ],
"note": "前景记号"
},
{
"color": [ 255, 0, 0, 0 ],
"note": "空气",
"command": [
[ "BC_CLEAR_LAKE" ],
[ "BC_CLEAR" ]
]
},
{
"color": [ 255, 0, 64, 255 ],
"pipe": true
},
{
"color": [ 255, 255, 255, 0 ],
"note": "火把",
"command": [
[ "BC_PLACE_FURNITURE", "torch", 0 ]
]
},
{
"color": [ 255, 130, 0, 0 ],
"note": "桶",
"command": [
[ "BC_PLACE_FURNITURE", "barrel", 0, "normal_reward" ]
]
},
{
"color": [ 255, 0, 200, 0 ],
"note": "罐子",
"command": [
[ "BC_PLACE_FURNITURE", "pot", 2 ]
]
},
{
"color": [ 255, 0, 255, 255 ],
"note": "箱子",
"command": [
[ "BC_PLACE_FURNITURE", "chest", 0, "normal_reward" ]
]
},
{
"color": [ 255, 102, 102, 204 ],
"note": "橡木门",
"command": [
[ "BC_PLACE_FURNITURE", "wooden_door_birch" ]
]
},
{
"color": [ 255, 255, 0, 255 ],
"note": "平台",
"command": [
[ "BC_PLACE_TILE", "platform_sandstone" ]
]
},
{
"color": [ 255, 0, 255, 0 ],
"note": "吊灯",
"command": [
[ "BC_PLACE_FURNITURE", "fire_lamp" ]
]
},
{
"color": [ 255, 128, 64, 32 ],
"note": "熔炉",
"command": [
[ "BC_PLACE_FURNITURE", "furnace" ]
]
},
{
"color": [ 255, 255, 0, 0 ],
"note": "桌子",
"command": [
[ "BC_PLACE_FURNITURE", "table_birch" ]
]
},
{
"color": [ 255, 128, 0, 0 ],
"note": "椅子",
"command": [
[ "BC_PLACE_FURNITURE", "chair_birch", 1 ]
]
},
{
"color": [ 255, 160, 0, 0 ],
"note": "椅子",
"command": [
[ "BC_PLACE_FURNITURE", "chair_birch", 0 ]
]
},
{
"color": [ 255, 0, 128, 255 ],
"note": "床",
"command": [
[ "BC_PLACE_FURNITURE", "wooden_bed_red", 0 ]
]
},
{
"color": [ 255, 100, 100, 0 ],
"note": "书架",
"command": [
[ "BC_PLACE_FURNITURE", "bookcase_birch", 0, "normal_reward" ]
]
},
{
"color": [ 255, 200, 200, 0 ],
"note": "桌柜",
"command": [
[ "BC_PLACE_FURNITURE", "cabinet_birch", 0, "normal_reward" ]
]
},
{
"color": [ 255, 200, 200, 120 ],
"note": "蜡烛",
"command": [
[ "BC_PLACE_FURNITURE", "candle" ]
]
},
{
"color": [ 255, 0, 130, 0 ],
"note": "长凳",
"command": [
[ "BC_PLACE_FURNITURE", "bench_birch" ]
]
},
{
"color": [ 255, 50, 50, 100 ],
"note": "有空气就放水",
"command": [
[ "BC_PLACE_LIQUID", "water" ]
]
},
{
"color": [ 255, 54, 40, 27 ],
"note": "有空气就放沙石",
"command": [
[ "BC_CLEAR_FURNITURE" ],
[ "BC_PLACE_TILE", "sandstone" ]
]
},
{
"color": [ 255, 120, 30, 30 ],
"note": "主前景1",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "sandstone_smooth", 1 ],
[ "BC_PLACE_TILE", "sandstone_smooth" ]
]
},
{
"color": [ 255, 40, 0, 0 ],
"note": "主后景1",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "sandstone_smooth", 1 ]
]
},
{
"color": [ 255, 100, 100, 100 ],
"note": "木板前景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "plank_spruce", 1 ],
[ "BC_PLACE_TILE", "plank_spruce" ]
]
},
{
"color": [ 255, 10, 10, 10 ],
"note": "木板后景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "fence_spruce", 1 ]
]
},
{
"color": [ 255, 222, 222, 244 ],
"note": "玻璃后景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "glass", 1 ]
]
},
{
"color": [ 255, 128, 64, 64 ],
"note": "木头前景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "plank_dark_oak", 1 ],
[ "BC_PLACE_TILE", "plank_dark_oak" ]
]
}
],
"parts": [
{
"name": "entrance",
"image": [ "entrance", "entrance_o1" ],
"type": "PT_START",
"hotX": 50,
"hotY": 55,
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "entrance2",
"image": [ "entrance2", "entrance2_o1" ],
"type": "PT_START",
"hotX": 50,
"hotY": 55,
"unlinkParts": [ "entrance2" ],
"weight": 100
},
{
"name": "entrance3",
"image": [ "entrance3", "entrance3_o1" ],
"type": "PT_START",
"hotX": 50,
"hotY": 55,
"unlinkParts": [ "entrance3" ],
"weight": 10
},
{
"name": "entrance4",
"image": [ "entrance4", "entrance4_o1" ],
"type": "PT_START",
"hotX": 50,
"hotY": 55,
"unlinkParts": [ "entrance4" ],
"weight": 10
}
]
}
}
================================================
FILE: buildings/end_outpost/end_outpost.json
================================================
{
"end_outpost": {
"maxGenPartCount": 1,
"limitSize": 100,
"blockEntityFormat": {
"normal_reward": {
"formatId": "tc:common_rewards",
"data": {
"rareGenCount": 1,
"rares": [
{
"itemId": "iron_sword",
"count": 1
},
{
"itemId": "iron_axe",
"count": 1
},
{
"itemId": "iron_pickaxe",
"count": 1
}
],
"normals": [
{
"itemIds": [ "iron_ingot", "copper_ingot", "tin_ingot", "lead_ingot" ],
"rate": 0.4,
"min": 4,
"max": 8
},
{
"itemIds": [ "gold_ingot", "silver_ingot", "bronze_ingot", "steel_ingot" ],
"rate": 0.5,
"min": 2,
"max": 6
},
{
"itemIds": [ "ender_pearl" ],
"rate": 0.7,
"min": 1,
"max": 2
},
{
"itemIds": [ "diamond" ],
"rate": 0.2,
"min": 1,
"max": 2
},
{
"itemIds": [ "emerald" ],
"rate": 0.1,
"min": 2,
"max": 6
},
{
"itemIds": [ "iron_helmet", "iron_chestplate", "iron_leggings" ],
"rate": 0.1,
"min": 1,
"max": 1
}
]
}
}
},
"commandColors": [
{
"color": [ 255, 64, 64, 64 ],
"note": "无操作",
"command": [
[ "BC_NO_OP" ]
]
},
{
"color": [ 255, 192, 192, 192 ],
"note": "前景记号"
},
{
"color": [ 255, 0, 0, 0 ],
"note": "空气",
"command": [
[ "BC_CLEAR_LAKE" ],
[ "BC_CLEAR" ]
]
},
{
"color": [ 255, 0, 64, 255 ],
"pipe": true
},
{
"color": [ 255, 255, 255, 0 ],
"note": "火把",
"command": [
[ "BC_PLACE_FURNITURE", "end_rod", 0 ]
]
},
{
"color": [ 255, 0, 160, 255 ],
"note": "潜影盒",
"command": [
[ "BC_PLACE_FURNITURE", "shulker_box", 0, "normal_reward" ]
]
},
{
"color": [ 255, 255, 0, 255 ],
"note": "平台",
"command": [
[ "BC_PLACE_TILE", "platform_purpur" ]
]
},
{
"color": [ 255, 200, 200, 120 ],
"note": "蜡烛",
"command": [
[ "BC_PLACE_FURNITURE", "candle" ]
]
},
{
"color": [ 255, 50, 50, 100 ],
"note": "有空气就放水",
"command": [
[ "BC_PLACE_LIQUID", "water" ]
]
},
{
"color": [ 255, 54, 40, 27 ],
"note": "有空气就放腐化石",
"command": [
[ "BC_CLEAR_FURNITURE" ],
[ "BC_PLACE_TILE", "tainted_stone" ]
]
},
{
"color": [ 255, 120, 30, 30 ],
"note": "主前景1",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "purpur_block" ],
[ "BC_PLACE_TILE", "purpur_block" ]
]
},
{
"color": [ 255, 40, 0, 0 ],
"note": "主后景1",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "purpur_block" ]
]
},
{
"color": [ 255, 100, 100, 100 ],
"note": "末地砖前景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "end_stone_brick" ],
[ "BC_PLACE_TILE", "end_stone_brick" ]
]
},
{
"color": [ 255, 10, 10, 10 ],
"note": "末地砖后景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "end_stone_brick" ]
]
},
{
"color": [ 255, 222, 222, 244 ],
"note": "玻璃后景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "stained_glass_magenta" ]
]
}
],
"parts": [
{
"name": "entrance",
"image": [ "entrance", "entrance_o1" ],
"type": "PT_START",
"hotX": 50,
"hotY": 55,
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "entrance2",
"image": [ "entrance2", "entrance2_o1" ],
"type": "PT_START",
"hotX": 50,
"hotY": 55,
"unlinkParts": [ "entrance2" ],
"weight": 10
},
{
"name": "entrance3",
"image": [ "entrance3", "entrance3_o1" ],
"type": "PT_START",
"hotX": 50,
"hotY": 55,
"unlinkParts": [ "entrance3" ],
"weight": 10
},
{
"name": "entrance4",
"image": [ "entrance4", "entrance4_o1" ],
"type": "PT_START",
"hotX": 50,
"hotY": 55,
"unlinkParts": [ "entrance4" ],
"weight": 10
},
{
"name": "entrance5",
"image": [ "entrance5", "entrance5_o1" ],
"type": "PT_START",
"hotX": 50,
"hotY": 55,
"unlinkParts": [ "entrance5" ],
"weight": 10
}
]
}
}
================================================
FILE: buildings/forest_house/forest_house.json
================================================
{
"forest_house": {
"maxGenPartCount": 50,
"limitSize": 300,
"rewards": [
{
"name": "normal_reward",
"rareGenCount": 1,
"rares": [
{
"itemId": "stone_sword",
"count": 1
},
{
"itemId": "stone_pickaxe",
"count": 1
},
{
"itemId": "wooden_bow",
"count": 1
},
{
"itemId": "cross_bow",
"count": 1
}
],
"normals": [
{
"itemIds": [ "wood_dark_oak" ],
"rate": 0.9,
"min": 3,
"max": 5
},
{
"itemIds": [ "iron_ingot", "copper_ingot", "tin_ingot", "lead_ingot" ],
"rate": 0.3,
"min": 3,
"max": 10
},
{
"itemIds": [ "potato" ],
"rate": 0.5,
"min": 3,
"max": 6
},
{
"itemIds": [ "wheat" ],
"rate": 0.7,
"min": 3,
"max": 6
},
{
"itemIds": [ "carrot" ],
"rate": 0.5,
"min": 3,
"max": 6
},
{
"itemIds": [ "string" ],
"rate": 0.4,
"min": 2,
"max": 7
},
{
"itemIds": [ "wooden_arrow" ],
"rate": 0.4,
"min": 2,
"max": 7
}
]
}
],
"commandColors": [
{
"color": [ 255, 64, 64, 64 ],
"note": "无操作",
"command": [
[ "BC_NO_OP" ]
]
},
{
"color": [ 255, 192, 192, 192 ],
"note": "前景记号"
},
{
"color": [ 255, 0, 0, 0 ],
"note": "空气",
"command": [
[ "BC_CLEAR_LAKE" ],
[ "BC_CLEAR" ]
]
},
{
"color": [ 255, 0, 64, 255 ],
"pipe": true
},
{
"color": [ 255, 0, 255, 255 ],
"note": "箱子",
"command": [
]
},
{
"color": [ 255, 102, 102, 204 ],
"note": "橡木门",
"command": [
[ "BC_PLACE_FURNITURE", "wooden_door_oak" ]
]
},
{
"color": [ 255, 255, 0, 255 ],
"note": "橡木平台",
"command": [
[ "BC_PLACE_TILE", "platform_oak" ]
]
},
{
"color": [ 255, 50, 50, 100 ],
"note": "有空气就放水",
"command": [
[ "BC_PLACE_LIQUID", "water" ]
]
},
{
"color": [ 255, 54, 40, 27 ],
"note": "有空气就放泥土",
"command": [
[ "BC_CLEAR_FURNITURE" ],
[ "BC_PLACE_TILE", "dirt" ]
]
},
{
"color": [ 255, 54, 100, 27 ],
"note": "有空气就放草泥土",
"command": [
[ "BC_CLEAR_FURNITURE" ],
[ "BC_PLACE_TILE", "dirt", 1 ]
]
},
{
"color": [ 255, 120, 30, 30 ],
"note": "木板前景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "plank_oak" ],
[ "BC_PLACE_TILE", "plank_oak" ]
]
},
{
"color": [ 255, 40, 0, 0 ],
"note": "木板后景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "plank_oak" ]
]
},
{
"color": [ 255, 100, 100, 100 ],
"note": "石砖前景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "stone_brick" ],
[ "BC_PLACE_TILE", "stone_brick" ]
]
},
{
"color": [ 255, 100, 0, 0 ],
"note": "红砖前景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "brick" ],
[ "BC_PLACE_TILE", "brick" ]
]
},
{
"color": [ 255, 100, 66, 66 ],
"note": "木板前景石砖后景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "stone_brick" ],
[ "BC_PLACE_TILE", "plank_oak" ]
]
},
{
"color": [ 255, 10, 10, 10 ],
"note": "石砖后景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "stone_brick" ]
]
},
{
"color": [ 255, 222, 222, 244 ],
"note": "玻璃后景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "glass" ]
]
}
],
"parts": [
{
"name": "entrance",
"image": [ "entrance", "entrance_o1" ],
"type": "PT_START",
"hotX": 50,
"hotY": 43,
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "h1",
"image": "h1",
"type": "PT_NORMAL",
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "h2",
"image": "h2",
"type": "PT_NORMAL",
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "h3",
"image": "h3",
"type": "PT_NORMAL",
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "h4",
"image": "h4",
"type": "PT_NORMAL",
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "h5",
"image": "h5",
"type": "PT_NORMAL",
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "h6",
"image": "h6",
"type": "PT_NORMAL",
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "h7",
"image": "h7",
"type": "PT_NORMAL",
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "h8",
"image": "h8",
"type": "PT_NORMAL",
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "h9",
"image": "h9",
"type": "PT_NORMAL",
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "h10",
"image": "h10",
"type": "PT_NORMAL",
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "h11",
"image": "h11",
"type": "PT_NORMAL",
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "h12",
"image": "h12",
"type": "PT_END",
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "h13",
"image": "h13",
"type": "PT_END",
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "h14",
"image": "h14",
"type": "PT_END",
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "h15",
"image": "h15",
"type": "PT_END",
"unlinkParts": [ "entrance" ],
"weight": 10
}
]
}
}
================================================
FILE: buildings/fossils/fossils.json
================================================
{
"fossils": {
"maxGenPartCount": 1,
"limitSize": 15,
"rewards": [],
"commandColors": [
{
"color": [ 255, 64, 64, 64 ],
"note": "无操作",
"command": [
[ "BC_NO_OP" ]
]
},
{
"color": [ 255, 192, 192, 192 ],
"note": "前景记号"
},
{
"color": [ 255, 0, 0, 0 ],
"note": "空气",
"command": [
[ "BC_CLEAR_LAKE" ],
[ "BC_CLEAR" ]
]
},
{
"color": [ 255, 0, 64, 255 ],
"pipe": true
},
{
"color": [ 255, 150, 150, 150 ],
"note": "后景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "bone_block" ]
]
},
{
"color": [ 255, 200, 200, 200 ],
"note": "前景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_TILE", "bone_block" ]
]
}
],
"parts": [
{
"name": "entrance",
"image": [ "entrance" ],
"type": "PT_START",
"hotX": 7,
"hotY": 7,
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "entrance2",
"image": [ "entrance2" ],
"type": "PT_START",
"hotX": 7,
"hotY": 7,
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "entrance3",
"image": [ "entrance3" ],
"type": "PT_START",
"hotX": 7,
"hotY": 7,
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "entrance4",
"image": [ "entrance4" ],
"type": "PT_START",
"hotX": 7,
"hotY": 7,
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "entrance5",
"image": [ "entrance5" ],
"type": "PT_START",
"hotX": 7,
"hotY": 7,
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "entrance6",
"image": [ "entrance6" ],
"type": "PT_START",
"hotX": 7,
"hotY": 7,
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "entrance7",
"image": [ "entrance7" ],
"type": "PT_START",
"hotX": 7,
"hotY": 7,
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "entrance8",
"image": [ "entrance8" ],
"type": "PT_START",
"hotX": 7,
"hotY": 7,
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "entrance9",
"image": [ "entrance9" ],
"type": "PT_START",
"hotX": 7,
"hotY": 7,
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "entrance10",
"image": [ "entrance10" ],
"type": "PT_START",
"hotX": 7,
"hotY": 7,
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "entrance11",
"image": [ "entrance11" ],
"type": "PT_START",
"hotX": 7,
"hotY": 7,
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "entrance12",
"image": [ "entrance12" ],
"type": "PT_START",
"hotX": 7,
"hotY": 7,
"unlinkParts": [ "entrance" ],
"weight": 10
}
]
}
}
================================================
FILE: buildings/heart/heart.json
================================================
{
"heart": {
"maxGenPartCount": 1,
"limitSize": 15,
"rewards": [],
"commandColors": [
{
"color": [ 255, 64, 64, 64 ],
"note": "无操作",
"command": [
[ "BC_NO_OP" ]
]
},
{
"color": [ 255, 192, 192, 192 ],
"note": "前景记号"
},
{
"color": [ 255, 0, 0, 0 ],
"note": "空气",
"command": [
[ "BC_CLEAR_LAKE" ],
[ "BC_CLEAR_FRONT" ]
]
},
{
"color": [ 255, 0, 64, 255 ],
"pipe": true
},
{
"color": [ 255, 255, 255, 0 ],
"note": "",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_FURNITURE", "health_crystal", 0 ]
]
},
{
"color": [ 255, 120, 30, 30 ],
"note": "前景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "stone_brick_cracked" ],
[ "BC_PLACE_TILE", "stone_brick_cracked" ]
]
}
],
"parts": [
{
"name": "entrance",
"image": [ "entrance" ],
"type": "PT_START",
"hotX": 7,
"hotY": 12,
"unlinkParts": [ "entrance" ],
"weight": 10
}
]
}
}
================================================
FILE: buildings/jungle_temple/jungle_temple.json
================================================
{
"jungle_temple": {
"maxGenPartCount": 1,
"limitSize": 200,
"rewards": [
{
"name": "normal_reward",
"rareGenCount": 1,
"rares": [
{
"itemId": "stone_sword",
"count": 1
},
{
"itemId": "stone_axe",
"count": 1
},
{
"itemId": "stone_pickaxe",
"count": 1
},
{
"itemId": "wooden_bow",
"count": 1
},
{
"itemId": "book",
"count": 8
},
{
"itemId": "amethyst_staff",
"count": 1
},
{
"itemId": "water_staff",
"count": 1
}
],
"normals": [
{
"itemIds": [ "ender_pearl" ],
"rate": 0.3,
"min": 1,
"max": 2
},
{
"itemIds": [ "bone" ],
"rate": 0.6,
"min": 4,
"max": 6
},
{
"itemIds": [ "rotten_flesh" ],
"rate": 0.5,
"min": 3,
"max": 8
},
{
"itemIds": [ "iron_ingot", "copper_ingot", "tin_ingot", "lead_ingot" ],
"rate": 0.4,
"min": 1,
"max": 5
},
{
"itemIds": [ "gold_ingot", "silver_ingot", "bronze_ingot", "steel_ingot" ],
"rate": 0.5,
"min": 2,
"max": 7
},
{
"itemIds": [ "stick" ],
"rate": 0.5,
"min": 1,
"max": 3
},
{
"itemIds": [ "diamond" ],
"rate": 0.12,
"min": 1,
"max": 3
},
{
"itemIds": [ "emerald" ],
"rate": 0.1,
"min": 1,
"max": 3
}
]
},
{
"name": "trap",
"rareGenCount": 0,
"rares": [],
"normals": [
{
"itemIds": [ "wooden_arrow", "blood_arrow" ],
"rate": 1.0,
"min": 8,
"max": 16
}
]
}
],
"commandColors": [
{
"color": [ 255, 64, 64, 64 ],
"note": "无操作",
"command": [
[ "BC_NO_OP" ]
]
},
{
"color": [ 255, 192, 192, 192 ],
"note": "前景记号"
},
{
"color": [ 255, 0, 0, 0 ],
"note": "空气",
"command": [
[ "BC_CLEAR_LAKE" ],
[ "BC_CLEAR" ]
]
},
{
"color": [ 255, 0, 64, 255 ],
"pipe": true
},
{
"color": [ 255, 0, 160, 255 ],
"note": "陷阱箱(砍了)",
"command": [
[ "BC_PLACE_CHEST", "trapped_chest", "normal_reward" ],
[ "BC_PLACE_WIRE", 1, 0 ]
]
},
{
"color": [ 255, 255, 0, 0 ],
"note": "发射器左",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "cobblestone" ],
]
},
{
"color": [ 255, 255, 255, 0 ],
"note": "发射器右",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "cobblestone" ],
]
},
{
"color": [ 255, 0, 200, 0 ],
"note": "罐子",
"command": [
[ "BC_PLACE_FURNITURE", "pot", 0 ]
]
},
{
"color": [ 255, 255, 0, 255 ],
"note": "平台",
"command": [
[ "BC_PLACE_TILE", "platform_stone_brick" ]
]
},
{
"color": [ 255, 200, 200, 120 ],
"note": "蜡烛",
"command": [
[ "BC_PLACE_FURNITURE", "candle" ]
]
},
{
"color": [ 255, 0, 0, 168 ],
"note": "踏板",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "cobblestone" ],
[ "BC_PLACE_FURNITURE", "pressure_plate_stone" ]
]
},
{
"color": [ 255, 255, 50, 50 ],
"note": "红石线",
"command": [
[ "BC_PLACE_WIRE", 1, 0 ]
]
},
{
"color": [ 255, 50, 50, 100 ],
"note": "有空气就放水",
"command": [
[ "BC_PLACE_LIQUID", "water" ]
]
},
{
"color": [ 255, 54, 40, 27 ],
"note": "有空气就放泥",
"command": [
[ "BC_CLEAR_FURNITURE" ],
[ "BC_PLACE_TILE", "coarse_dirt" ]
]
},
{
"color": [ 255, 120, 30, 30 ],
"note": "主前景1",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "cobblestone" ],
[ "BC_PLACE_TILE", "cobblestone" ]
]
},
{
"color": [ 255, 40, 0, 0 ],
"note": "主后景1",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "cobblestone" ]
]
},
{
"color": [ 255, 100, 100, 100 ],
"note": "前景2",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "cobblestone_mossy" ],
[ "BC_PLACE_TILE", "cobblestone_mossy" ]
]
},
{
"color": [ 255, 10, 10, 10 ],
"note": "后景2",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "cobblestone_mossy" ]
]
},
{
"color": [ 255, 222, 222, 244 ],
"note": "玻璃后景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "stained_glass_magenta" ]
]
}
],
"parts": [
{
"name": "entrance",
"image": [ "entrance", "entrance_o1" ],
"type": "PT_START",
"hotX": 95,
"hotY": 45,
"unlinkParts": [ "entrance" ],
"weight": 10
}
]
}
}
================================================
FILE: buildings/mineshaft/mineshaft.json
================================================
{
"mineshaft": {
"maxGenPartCount": 2,
"limitSize": 350,
"mainRestraint": {
"checks": [
[ "IS_CENTER_Y_GREATER_OR_EQUAL_TO", 0 ]
]
},
"blockEntityFormat": {
"normal_reward": {
"formatId": "tc:common_rewards",
"data": {
"rareGenCount": 1,
"rares": [
{
"itemId": "stone_sword",
"count": 1
},
{
"itemId": "stone_pickaxe",
"count": 1
},
{
"itemId": "iron_pickaxe",
"count": 1
},
{
"itemId": "torch",
"count": 12
},
{
"itemId": "yellow_torch",
"count": 6
}
],
"normals": [
{
"itemIds": [ "bread" ],
"rate": 0.44,
"min": 1,
"max": 3
},
{
"itemIds": [ "coal", "charcoal" ],
"rate": 0.3,
"min": 3,
"max": 8
},
{
"itemIds": [ "pumpkin_seed" ],
"rate": 0.3,
"min": 2,
"max": 4
},
{
"itemIds": [ "melon_seed" ],
"rate": 0.3,
"min": 2,
"max": 4
},
{
"itemIds": [ "golden_apple" ],
"rate": 0.2,
"min": 1,
"max": 1
},
{
"itemIds": [ "iron_ingot", "copper_ingot", "tin_ingot", "lead_ingot" ],
"rate": 0.3,
"min": 1,
"max": 5
},
{
"itemIds": [ "gold_ingot", "silver_ingot", "bronze_ingot", "steel_ingot" ],
"rate": 0.1,
"min": 1,
"max": 3
},
{
"itemIds": [ "lapis_lazuli" ],
"rate": 0.2,
"min": 4,
"max": 9
},
{
"itemIds": [ "redstone" ],
"rate": 0.2,
"min": 4,
"max": 9
},
{
"itemIds": [ "diamond" ],
"rate": 0.1,
"min": 1,
"max": 2
}
]
}
},
"desk_reward": {
"formatId": "tc:common_rewards",
"data": {
"rareGenCount": 1,
"rares": [
{
"itemId": "rocket_boost",
"count": 1
},
{
"itemId": "stone_sword",
"count": 1
},
{
"itemId": "stone_pickaxe",
"count": 1
}
],
"normals": [
{
"itemIds": [ "iron_ingot", "copper_ingot", "tin_ingot", "lead_ingot" ],
"rate": 0.3,
"min": 3,
"max": 10
},
{
"itemIds": [ "book" ],
"rate": 0.5,
"min": 3,
"max": 10
},
{
"itemIds": [ "paper" ],
"rate": 0.75,
"min": 12,
"max": 18
}
]
}
}
},
"restraints": [
],
"commandColors": [
{
"color": [ 255, 64, 64, 64 ],
"note": "无操作",
"command": [
[ "BC_NO_OP" ]
]
},
{
"color": [ 255, 192, 192, 192 ],
"note": "前景记号"
},
{
"color": [ 255, 0, 0, 0 ],
"note": "空气",
"command": [
[ "BC_CLEAR_LAKE" ],
[ "BC_CLEAR" ]
]
},
{
"color": [ 255, 0, 64, 255 ],
"pipe": true
},
{
"color": [ 255, 0, 255, 255 ],
"pipe": true
},
{
"color": [ 255, 0, 160, 255 ],
"note": "箱子",
"command": [
[ "BC_PLACE_FURNITURE", "chest", 0, "normal_reward" ]
]
},
{
"color": [ 255, 130, 0, 0 ],
"note": "桶",
"command": [
[ "BC_PLACE_FURNITURE", "barrel", 0, "normal_reward" ]
]
},
{
"color": [ 255, 0, 200, 0 ],
"note": "罐子",
"command": [
[ "BC_PLACE_FURNITURE", "pot", 0 ]
]
},
{
"color": [ 255, 255, 255, 0 ],
"note": "火把",
"command": [
[ "BC_PLACE_FURNITURE", "torch", 0 ]
]
},
{
"color": [ 255, 102, 102, 204 ],
"note": "门",
"command": [
[ "BC_PLACE_FURNITURE", "wooden_door_dark_oak" ]
]
},
{
"color": [ 255, 255, 0, 255 ],
"note": "平台",
"command": [
[ "BC_PLACE_TILE", "platform_dark_oak" ]
]
},
{
"color": [ 255, 0, 255, 0 ],
"note": "吊灯",
"command": [
[ "BC_PLACE_FURNITURE", "fire_lamp" ]
]
},
{
"color": [ 255, 0, 0, 130 ],
"note": "合成台",
"command": [
[ "BC_PLACE_FURNITURE", "crafting_table" ]
]
},
{
"color": [ 255, 128, 64, 32 ],
"note": "熔炉",
"command": [
[ "BC_PLACE_FURNITURE", "furnace" ]
]
},
{
"color": [ 255, 255, 0, 0 ],
"note": "桌子",
"command": [
[ "BC_PLACE_FURNITURE", "table_dark_oak" ]
]
},
{
"color": [ 255, 128, 0, 0 ],
"note": "椅子",
"command": [
[ "BC_PLACE_FURNITURE", "chair_dark_oak", 1 ]
]
},
{
"color": [ 255, 160, 0, 0 ],
"note": "椅子",
"command": [
[ "BC_PLACE_FURNITURE", "chair_dark_oak", 0 ]
]
},
{
"color": [ 255, 0, 130, 0 ],
"note": "长凳",
"command": [
[ "BC_PLACE_FURNITURE", "bench_dark_oak" ]
]
},
{
"color": [ 255, 0, 128, 255 ],
"note": "床",
"command": [
[ "BC_PLACE_FURNITURE", "wooden_bed_red", 0 ]
]
},
{
"color": [ 255, 100, 100, 0 ],
"note": "书架",
"command": [
[ "BC_PLACE_FURNITURE", "bookcase_dark_oak", 0, "desk_reward" ]
]
},
{
"color": [ 255, 200, 200, 0 ],
"note": "桌柜",
"command": [
[ "BC_PLACE_FURNITURE", "cabinet_dark_oak", 0, "desk_reward" ]
]
},
{
"color": [ 255, 200, 200, 120 ],
"note": "蜡烛",
"command": [
[ "BC_PLACE_FURNITURE", "candle" ]
]
},
{
"color": [ 255, 0, 130, 130 ],
"note": "蜡烛台",
"command": [
[ "BC_PLACE_FURNITURE", "candle_holder" ]
]
},
{
"color": [ 255, 130, 0, 130 ],
"note": "花盆",
"command": [
[ "BC_PLACE_FURNITURE", "flower_pot" ]
]
},
{
"color": [ 255, 150, 0, 0 ],
"note": "缸",
"command": [
[ "BC_PLACE_FURNITURE", "cauldron" ]
]
},
{
"color": [ 255, 150, 150, 0 ],
"note": "水晶灯",
"command": [
[ "BC_PLACE_FURNITURE", "chandeliers" ]
]
},
{
"color": [ 255, 150, 150, 150 ],
"note": "蜘蛛网",
"command": [
[ "BC_PLACE_FURNITURE", "cobweb" ]
]
},
{
"color": [ 255, 150, 0, 150 ],
"note": "藤蔓",
"command": [
[ "BC_PLACE_FURNITURE", "vine" ]
]
},
{
"color": [ 255, 150, 255, 0 ],
"note": "树苗",
"command": [
[ "BC_PLACE_FURNITURE", "sapling_dark_oak" ]
]
},
{
"color": [ 255, 168, 168, 168 ],
"note": "主方块前景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "plank_dark_oak" ],
[ "BC_PLACE_TILE", "plank_dark_oak" ]
]
},
{
"color": [ 255, 114, 114, 114 ],
"note": "主方块后景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "plank_dark_oak" ]
]
},
{
"color": [ 255, 83, 83, 83 ],
"note": "主方块后景2",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "fence_dark_oak" ]
]
}
],
"parts": [
{
"name": "entrance",
"image": [ "entrance", "entrance_o1", "entrance_o2" ],
"type": "PT_START",
"hotX": 25,
"hotY": 25,
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "entrance2",
"image": [ "entrance2", "entrance2_o1", "entrance2_o2" ],
"type": "PT_START",
"hotX": 25,
"hotY": 25,
"unlinkParts": [ "entrance2" ],
"weight": 10
},
{
"name": "r1",
"image": [ "r1", "r1_o1", "r1_o2" ],
"type": "PT_NORMAL",
"unlinkParts": [],
"weight": 10
},
{
"name": "r2",
"image": [ "r2", "r2_o1", "r2_o2" ],
"type": "PT_NORMAL",
"unlinkParts": [],
"weight": 10
},
{
"name": "r3",
"image": [ "r3" ],
"type": "PT_NORMAL",
"unlinkParts": [],
"weight": 10
},
{
"name": "r4",
"image": [ "r4" ],
"type": "PT_NORMAL",
"unlinkParts": [],
"weight": 10
},
{
"name": "r5",
"image": [ "r5", "r5_o1", "r5_o2" ],
"type": "PT_NORMAL",
"unlinkParts": [],
"weight": 10
},
{
"name": "e1",
"image": [ "e1", "e1_o1", "e1_o2" ],
"type": "PT_END",
"unlinkParts": [],
"weight": 10
},
{
"name": "e2",
"image": [ "e2", "e2_o1", "e2_o2" ],
"type": "PT_END",
"unlinkParts": [],
"weight": 10
}
]
}
}
================================================
FILE: buildings/mini_house/mini_house.json
================================================
{
"mini_house": {
"maxGenPartCount": 1,
"limitSize": 100,
"blockEntityFormat": {
"furnaceData": {
"formatId": "tc:empty_furnace",
"data": {}
},
"normal_reward": {
"formatId": "tc:common_rewards",
"data": {
"rareGenCount": 2,
"rares": [
{
"itemId": "stone_sword",
"count": 1
},
{
"itemId": "stone_pickaxe",
"count": 1
},
{
"itemId": "stone_axe",
"count": 1
},
{
"itemId": "wooden_bow",
"count": 1
},
{
"itemId": "cross_bow",
"count": 1
}
],
"normals": [
{
"itemIds": [ "ender_pearl" ],
"rate": 0.5,
"min": 1,
"max": 2
},
{
"itemIds": [ "wood_dark_oak" ],
"rate": 0.9,
"min": 3,
"max": 5
},
{
"itemIds": [ "iron_ingot", "copper_ingot", "tin_ingot", "lead_ingot" ],
"rate": 0.3,
"min": 3,
"max": 10
},
{
"itemIds": [ "potato" ],
"rate": 0.5,
"min": 3,
"max": 6
},
{
"itemIds": [ "wheat" ],
"rate": 0.7,
"min": 3,
"max": 6
},
{
"itemIds": [ "carrot" ],
"rate": 0.5,
"min": 3,
"max": 6
},
{
"itemIds": [ "string" ],
"rate": 0.4,
"min": 2,
"max": 7
},
{
"itemIds": [ "bread" ],
"rate": 0.4,
"min": 7,
"max": 12
},
{
"itemIds": [ "wooden_arrow" ],
"rate": 0.4,
"min": 2,
"max": 7
}
]
}
}
},
"commandColors": [
{
"color": [ 255, 64, 64, 64 ],
"note": "无操作",
"command": [
[ "BC_NO_OP" ]
]
},
{
"color": [ 255, 192, 192, 192 ],
"note": "前景记号"
},
{
"color": [ 255, 0, 0, 0 ],
"note": "空气",
"command": [
[ "BC_CLEAR_LAKE" ],
[ "BC_CLEAR" ]
]
},
{
"color": [ 255, 0, 64, 255 ],
"pipe": true
},
{
"color": [ 255, 255, 255, 0 ],
"note": "火把",
"command": [
[ "BC_PLACE_FURNITURE", "torch", 0 ]
]
},
{
"color": [ 255, 0, 255, 255 ],
"note": "箱子",
"command": [
[ "BC_PLACE_FURNITURE", "chest", 0, "normal_reward" ]
]
},
{
"color": [ 255, 102, 102, 204 ],
"note": "橡木门",
"command": [
[ "BC_PLACE_FURNITURE", "wooden_door_oak" ]
]
},
{
"color": [ 255, 255, 0, 255 ],
"note": "橡木平台",
"command": [
[ "BC_PLACE_TILE", "platform_oak" ]
]
},
{
"color": [ 255, 0, 255, 0 ],
"note": "吊灯",
"command": [
[ "BC_PLACE_FURNITURE", "fire_lamp" ]
]
},
{
"color": [ 255, 128, 64, 32 ],
"note": "熔炉",
"command": [
[ "BC_PLACE_FURNITURE", "furnace", 0, "furnaceData" ]
]
},
{
"color": [ 255, 255, 0, 0 ],
"note": "桌子",
"command": [
[ "BC_PLACE_FURNITURE", "table_oak" ]
]
},
{
"color": [ 255, 128, 0, 0 ],
"note": "椅子",
"command": [
[ "BC_PLACE_FURNITURE", "chair_oak", 1 ]
]
},
{
"color": [ 255, 160, 0, 0 ],
"note": "椅子",
"command": [
[ "BC_PLACE_FURNITURE", "chair_oak", 0 ]
]
},
{
"color": [ 255, 0, 128, 255 ],
"note": "床",
"command": [
[ "BC_PLACE_FURNITURE", "wooden_bed_red", 0 ]
]
},
{
"color": [ 255, 100, 100, 0 ],
"note": "书架",
"command": [
[ "BC_PLACE_FURNITURE", "bookcase_oak", 0, "normal_reward" ]
]
},
{
"color": [ 255, 200, 200, 0 ],
"note": "桌柜",
"command": [
[ "BC_PLACE_FURNITURE", "cabinet_oak", 0, "normal_reward" ]
]
},
{
"color": [ 255, 200, 200, 120 ],
"note": "蜡烛",
"command": [
[ "BC_PLACE_FURNITURE", "candle" ]
]
},
{
"color": [ 255, 50, 50, 100 ],
"note": "有空气就放水",
"command": [
[ "BC_PLACE_LIQUID", "water" ]
]
},
{
"color": [ 255, 54, 40, 27 ],
"note": "有空气就放泥土",
"command": [
[ "BC_CLEAR_FURNITURE" ],
[ "BC_PLACE_TILE", "dirt" ]
]
},
{
"color": [ 255, 54, 100, 27 ],
"note": "有空气就放草泥土",
"command": [
[ "BC_CLEAR_FURNITURE" ],
[ "BC_PLACE_TILE", "dirt", 1 ]
]
},
{
"color": [ 255, 120, 30, 30 ],
"note": "橡木木板前景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "plank_oak", 1 ],
[ "BC_PLACE_TILE", "plank_oak" ]
]
},
{
"color": [ 255, 40, 0, 0 ],
"note": "橡木木板后景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "plank_oak", 1 ]
]
},
{
"color": [ 255, 100, 100, 100 ],
"note": "石砖前景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "stone_brick", 1 ],
[ "BC_PLACE_TILE", "stone_brick" ]
]
},
{
"color": [ 255, 100, 66, 66 ],
"note": "橡木木板前景石砖后景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "stone_brick", 1 ],
[ "BC_PLACE_TILE", "plank_oak" ]
]
},
{
"color": [ 255, 10, 10, 10 ],
"note": "石砖后景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "stone_brick", 1 ]
]
},
{
"color": [ 255, 222, 222, 244 ],
"note": "玻璃后景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "glass", 1 ]
]
},
{
"color": [ 255, 128, 64, 64 ],
"note": "木头前景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "hay_bale", 1 ],
[ "BC_PLACE_TILE", "hay_bale" ]
]
}
],
"parts": [
{
"name": "entrance",
"image": [ "entrance", "entrance_o1" ],
"type": "PT_START",
"hotX": 50,
"hotY": 55,
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "entrance2",
"image": [ "entrance2", "entrance2_o1" ],
"type": "PT_START",
"hotX": 50,
"hotY": 55,
"unlinkParts": [ "entrance2" ],
"weight": 10
},
{
"name": "entrance3",
"image": [ "entrance3", "entrance3_o1" ],
"type": "PT_START",
"hotX": 50,
"hotY": 55,
"unlinkParts": [ "entrance3" ],
"weight": 10
},
{
"name": "entrance4",
"image": [ "entrance4", "entrance4_o1" ],
"type": "PT_START",
"hotX": 50,
"hotY": 55,
"unlinkParts": [ "entrance4" ],
"weight": 10
}
]
}
}
================================================
FILE: buildings/monument_ocean/monument_ocean.json
================================================
{
"monument_ocean": {
"noGenSubBiome": true,
"maxGenPartCount": 16,
"limitSize": 500,
"mainRestraint": {
"checks": [
[ "IS_CENTER_Y_GREATER_OR_EQUAL_TO", 2000 ]
]
},
"restraints": [
],
"commandColors": [
{
"color": [ 255, 64, 64, 64 ],
"note": "无操作",
"command": [
[ "BC_NO_OP" ]
]
},
{
"color": [ 255, 192, 192, 192 ],
"note": "前景记号"
},
{
"color": [ 255, 0, 0, 0 ],
"note": "水",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_LIQUID", "water" ]
]
},
{
"color": [ 255, 0, 64, 255 ],
"pipe": true
},
{
"color": [ 255, 0, 255, 255 ],
"pipe": true
},
{
"color": [ 255, 0, 255, 255 ],
"note": "箱子",
"command": [
]
},
{
"color": [ 255, 204, 153, 0 ],
"note": "水草",
"command": [
[ "BC_PLACE_FURNITURE", "kelp" ]
]
},
{
"color": [ 255, 0, 200, 0 ],
"note": "罐子",
"command": [
[ "BC_PLACE_FURNITURE", "pot", 0 ]
]
},
{
"color": [ 255, 168, 168, 168 ],
"note": "海晶石前景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "prismarine" ],
[ "BC_PLACE_TILE", "prismarine" ]
]
},
{
"color": [ 255, 114, 114, 114 ],
"note": "海晶石后景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "prismarine" ],
[ "BC_PLACE_LIQUID", "water" ]
]
},
{
"color": [ 255, 128, 0, 0 ],
"note": "海晶石砖前景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "prismarine_brick" ],
[ "BC_PLACE_TILE", "prismarine_brick" ]
]
},
{
"color": [ 255, 66, 0, 0 ],
"note": "海晶石砖后景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "prismarine_brick" ],
[ "BC_PLACE_LIQUID", "water" ]
]
},
{
"color": [ 255, 255, 0, 255 ],
"note": "暗海晶石前景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "prismarine_dark" ],
[ "BC_PLACE_TILE", "prismarine_dark" ]
]
},
{
"color": [ 255, 100, 0, 100 ],
"note": "暗海晶石后景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "prismarine_dark" ],
[ "BC_PLACE_LIQUID", "water" ]
]
},
{
"color": [ 255, 255, 255, 0 ],
"note": "海晶灯",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_TILE", "sea_lantern" ]
]
},
{
"color": [ 255, 0, 255, 0 ],
"note": "湿海绵",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "prismarine_dark" ],
[ "BC_PLACE_TILE", "wet_sponge" ]
]
},
{
"color": [ 255, 255, 204, 0 ],
"note": "金块",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "prismarine_dark" ],
[ "BC_PLACE_TILE", "block_gold" ]
]
},
{
"color": [ 255, 100, 66, 66 ],
"note": "木板前景石砖后景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "stone_brick" ],
[ "BC_PLACE_TILE", "plank_oak" ]
]
},
{
"color": [ 255, 10, 10, 10 ],
"note": "石砖后景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "stone_brick" ],
[ "BC_PLACE_LIQUID", "water" ]
]
},
{
"color": [ 255, 222, 222, 244 ],
"note": "玻璃后景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "glass" ],
[ "BC_PLACE_LIQUID", "water" ]
]
}
],
"parts": [
{
"name": "entrance",
"image": [ "entrance", "entrance_o1" ],
"type": "PT_START",
"hotX": 50,
"hotY": 43,
"unlinkParts": [ "entrance" ],
"weight": 10
}
]
}
}
================================================
FILE: buildings/nether_fortress/nether_fortress.json
================================================
{
"nether_fortress": {
"maxGenPartCount": 16,
"limitSize": 500,
"mainRestraint": {
"checks": [
[ "IS_CENTER_Y_GREATER_OR_EQUAL_TO", 2000 ]
]
},
"blockEntityFormat": {
"desk_reward": {
"formatId": "tc:common_rewards",
"data": {
"rareGenCount": 1,
"rares": [],
"normals": [
{
"itemIds": [ "ender_pearl" ],
"rate": 0.1,
"min": 1,
"max": 1
},
{
"itemIds": [ "book" ],
"rate": 0.5,
"min": 3,
"max": 10
},
{
"itemIds": [ "paper" ],
"rate": 0.5,
"min": 3,
"max": 10
},
{
"itemIds": [ "obsidian" ],
"rate": 0.35,
"min": 2,
"max": 4
},
{
"itemIds": [ "iron_ingot", "copper_ingot", "tin_ingot", "lead_ingot" ],
"rate": 0.5,
"min": 1,
"max": 3
}
]
}
},
"normal_reward": {
"formatId": "tc:common_rewards",
"data": {
"rareGenCount": 1,
"rares": [
{
"itemId": "strange_eye",
"count": 1
},
{
"itemId": "golden_sword",
"count": 1
},
{
"itemId": "golden_axe",
"count": 1
},
{
"itemId": "iron_axe",
"count": 1
},
{
"itemId": "iron_pickaxe",
"count": 1
},
{
"itemId": "iron_chestplate",
"count": 1
},
{
"itemId": "handgun",
"count": 1
},
{
"itemId": "shotgun",
"count": 1
},
{
"itemId": "ghost_sword",
"count": 1
},
{
"itemId": "air_sword",
"count": 1
}
],
"normals": [
{
"itemIds": [ "rifle", "rocket_launcher" ],
"rate": 0.05,
"min": 1,
"max": 1
},
{
"itemIds": [ "iron_ingot", "copper_ingot", "tin_ingot", "lead_ingot" ],
"rate": 0.75,
"min": 3,
"max": 10
},
{
"itemIds": [ "gold_ingot", "silver_ingot", "bronze_ingot", "steel_ingot" ],
"rate": 0.6,
"min": 1,
"max": 4
},
{
"itemIds": [ "diamond" ],
"rate": 0.4,
"min": 1,
"max": 2
},
{
"itemIds": [ "obsidian" ],
"rate": 0.45,
"min": 2,
"max": 4
}
]
}
}
},
"rewards": [
],
"restraints": [
],
"commandColors": [
{
"color": [ 255, 64, 64, 64 ],
"note": "无操作",
"command": [
[ "BC_NO_OP" ]
]
},
{
"color": [ 255, 192, 192, 192 ],
"note": "前景记号"
},
{
"color": [ 255, 0, 0, 0 ],
"note": "空气",
"command": [
[ "BC_CLEAR_LAKE" ],
[ "BC_CLEAR" ]
]
},
{
"color": [ 255, 0, 64, 255 ],
"pipe": true
},
{
"color": [ 255, 0, 255, 255 ],
"pipe": true
},
{
"color": [ 255, 144, 144, 0 ],
"note": "传送门",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_FURNITURE", "portal:nether_portal_door", 0 ]
]
},
{
"color": [ 255, 0, 160, 255 ],
"note": "箱子",
"command": [
[ "BC_PLACE_FURNITURE", "nether_chest", 0, "normal_reward" ]
]
},
{
"color": [ 255, 150, 0, 0 ],
"note": "祭坛",
"command": [
[ "BC_PLACE_FURNITURE", "nether_altar" ]
]
},
{
"color": [ 255, 0, 200, 0 ],
"note": "罐子",
"command": [
[ "BC_PLACE_FURNITURE", "pot", 5 ]
]
},
{
"color": [ 255, 255, 255, 0 ],
"note": "火把",
"command": [
[ "BC_PLACE_FURNITURE", "torch", 0 ]
]
},
{
"color": [ 255, 102, 102, 204 ],
"note": "门",
"command": [
[ "BC_PLACE_FURNITURE", "door_nether" ]
]
},
{
"color": [ 255, 255, 0, 255 ],
"note": "平台",
"command": [
[ "BC_PLACE_TILE", "platform_nether_brick" ]
]
},
{
"color": [ 255, 0, 255, 0 ],
"note": "吊灯",
"command": [
[ "BC_PLACE_FURNITURE", "nether_lamp" ]
]
},
{
"color": [ 255, 255, 0, 0 ],
"note": "桌子",
"command": [
[ "BC_PLACE_FURNITURE", "table_nether" ]
]
},
{
"color": [ 255, 128, 0, 0 ],
"note": "椅子",
"command": [
[ "BC_PLACE_FURNITURE", "chair_nether", 1 ]
]
},
{
"color": [ 255, 160, 0, 0 ],
"note": "椅子",
"command": [
[ "BC_PLACE_FURNITURE", "chair_nether", 0 ]
]
},
{
"color": [ 255, 0, 130, 0 ],
"note": "长凳",
"command": [
[ "BC_PLACE_FURNITURE", "bench_nether" ]
]
},
{
"color": [ 255, 100, 100, 0 ],
"note": "书架",
"command": [
[ "BC_PLACE_FURNITURE", "bookcase_nether", 0, "desk_reward" ]
]
},
{
"color": [ 255, 200, 200, 0 ],
"note": "桌柜",
"command": [
[ "BC_PLACE_FURNITURE", "cabinet_nether", 0, "desk_reward" ]
]
},
{
"color": [ 255, 200, 200, 120 ],
"note": "蜡烛",
"command": [
[ "BC_PLACE_FURNITURE", "candle" ]
]
},
{
"color": [ 255, 0, 130, 130 ],
"note": "蜡烛台",
"command": [
[ "BC_PLACE_FURNITURE", "candle_holder" ]
]
},
{
"color": [ 255, 255, 255, 55 ],
"note": "地狱疣",
"command": [
[ "BC_PLACE_FURNITURE", "nether_wart", 2 ]
]
},
{
"color": [ 255, 168, 168, 168 ],
"note": "地狱砖前景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "nether_brick" ],
[ "BC_PLACE_TILE", "nether_brick" ]
]
},
{
"color": [ 255, 114, 114, 114 ],
"note": "地狱砖后景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "nether_brick" ]
]
},
{
"color": [ 255, 133, 0, 0 ],
"note": "灵魂沙前景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "soul_sand" ],
[ "BC_PLACE_TILE", "soul_sand" ]
]
},
{
"color": [ 255, 255, 0, 200 ],
"note": "黑曜石前景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "obsidian" ],
[ "BC_PLACE_TILE", "obsidian" ]
]
},
{
"color": [ 255, 100, 0, 100 ],
"note": "黑曜石后景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "obsidian" ]
]
}
],
"parts": [
{
"name": "entrance",
"image": [ "entrance", "entrance_o1", "entrance_o2" ],
"type": "PT_START",
"hotX": 50,
"hotY": 43,
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "r1",
"image": [ "r1", "r1_o1", "r1_o2" ],
"type": "PT_NORMAL",
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "r2",
"image": [ "r2", "r2_o1", "r2_o2", "r2_o3", "r2_o4", "r2_o5", "r2_o6" ],
"type": "PT_NORMAL",
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "r3",
"image": [ "r3", "r3_o1", "r3_o2", "r3_o3", "r3_o4", "r3_o5", "r3_o6" ],
"type": "PT_NORMAL",
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "r4",
"image": [ "r4", "r4_o1", "r4_o2", "r4_o3", "r4_o4", "r4_o5", "r4_o6" ],
"type": "PT_NORMAL",
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "r5",
"image": [ "r5", "r5_o1", "r5_o2", "r5_o3", "r5_o4", "r5_o5", "r5_o6" ],
"type": "PT_NORMAL",
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "r6",
"image": [ "r6", "r6_o1", "r6_o2", "r6_o3", "r6_o4", "r6_o5", "r6_o6" ],
"type": "PT_NORMAL",
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "r7",
"image": [ "r7", "r7_o1", "r7_o2", "r7_o3", "r7_o4", "r7_o5", "r7_o6" ],
"type": "PT_NORMAL",
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "r8",
"image": [ "r8", "r8_o1", "r8_o2", "r8_o3", "r8_o4", "r8_o5", "r8_o6" ],
"type": "PT_NORMAL",
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "r9",
"image": [ "r9", "r9_o1", "r9_o2" ],
"type": "PT_NORMAL",
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "r10",
"image": [ "r10", "r10_o1", "r10_o2" ],
"type": "PT_NORMAL",
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "r11",
"image": [ "r11", "r11_o1", "r11_o2", "r11_o3", "r11_o4", "r11_o5", "r11_o6" ],
"type": "PT_NORMAL",
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "r12",
"image": [ "r12", "r12_o1", "r12_o2", "r12_o3", "r12_o4", "r12_o5", "r12_o6" ],
"type": "PT_NORMAL",
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "r13",
"image": [ "r13", "r13_o1", "r13_o2", "r13_o3", "r13_o4", "r13_o5", "r13_o6" ],
"type": "PT_NORMAL",
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "r14",
"image": [ "r14", "r14_o1", "r14_o2", "r14_o3", "r14_o4", "r14_o5", "r14_o6" ],
"type": "PT_NORMAL",
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "r15",
"image": [ "r15", "r15_o1", "r15_o2" ],
"type": "PT_NORMAL",
"unlinkParts": [ "entrance", "r15" ],
"weight": 10
},
{
"name": "r16",
"image": [ "r16" ],
"type": "PT_NORMAL",
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "r17",
"image": [ "r17" ],
"type": "PT_NORMAL",
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "e1",
"image": [ "e1", "e1_o1", "e1_o2", "e1_o3", "e1_o4", "e1_o5", "e1_o6" ],
"type": "PT_END",
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "e2",
"image": [ "e2", "e2_o1", "e2_o2", "e2_o3", "e2_o4", "e2_o5", "e2_o6" ],
"type": "PT_END",
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "e3",
"image": [ "e3", "e3_o1", "e3_o2", "e3_o3", "e3_o4", "e3_o5", "e3_o6" ],
"type": "PT_END",
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "e4",
"image": [ "e4", "e4_o1", "e4_o2", "e4_o3" ],
"type": "PT_END",
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "e5",
"image": [ "e5", "e5_o1", "e5_o2", "e5_o3", "e5_o4" ],
"type": "PT_END",
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "e6",
"image": [ "e6", "e6_o1", "e6_o2", "e6_o3", "e6_o4" ],
"type": "PT_END",
"unlinkParts": [ "entrance" ],
"weight": 10
}
]
}
}
================================================
FILE: buildings/pyramid/pyramid.json
================================================
{
"pyramid": {
"maxGenPartCount": 1,
"limitSize": 200,
"mainRestraint": {
"checks": [
[ "IS_CENTER_Y_GREATER_OR_EQUAL_TO", 0 ]
]
},
"blockEntityFormat": {
"normal_reward": {
"formatId": "tc:common_rewards",
"data": {
"rareGenCount": 1,
"rares": [],
"normals": [
{
"itemIds": [ "bone" ],
"rate": 0.7,
"min": 4,
"max": 6
},
{
"itemIds": [ "rotten_flesh" ],
"rate": 0.7,
"min": 1,
"max": 8
},
{
"itemIds": [ "gunpowder" ],
"rate": 0.6,
"min": 1,
"max": 8
},
{
"itemIds": [ "sand" ],
"rate": 0.6,
"min": 1,
"max": 8
},
{
"itemIds": [ "string" ],
"rate": 0.6,
"min": 1,
"max": 8
},
{
"itemIds": [ "spider_eye" ],
"rate": 0.3,
"min": 1,
"max": 3
},
{
"itemIds": [ "book" ],
"rate": 0.3,
"min": 1,
"max": 3
},
{
"itemIds": [ "golden_apple" ],
"rate": 0.23,
"min": 1,
"max": 1
},
{
"itemIds": [ "iron_ingot", "copper_ingot", "tin_ingot", "lead_ingot" ],
"rate": 0.18,
"min": 1,
"max": 5
},
{
"itemIds": [ "gold_ingot", "silver_ingot", "bronze_ingot", "steel_ingot" ],
"rate": 0.18,
"min": 2,
"max": 5
},
{
"itemIds": [ "emerald" ],
"rate": 0.18,
"min": 1,
"max": 3
},
{
"itemIds": [ "diamond" ],
"rate": 0.18,
"min": 1,
"max": 3
}
]
}
}
},
"restraints": [
],
"commandColors": [
{
"color": [ 255, 64, 64, 64 ],
"note": "无操作",
"command": [
[ "BC_NO_OP" ]
]
},
{
"color": [ 255, 192, 192, 192 ],
"note": "前景记号"
},
{
"color": [ 255, 0, 0, 0 ],
"note": "空气",
"command": [
[ "BC_CLEAR_LAKE" ],
[ "BC_CLEAR" ]
]
},
{
"color": [ 255, 0, 64, 255 ],
"pipe": true
},
{
"color": [ 255, 0, 255, 255 ],
"pipe": true
},
{
"color": [ 255, 0, 160, 255 ],
"note": "箱子",
"command": [
[ "BC_PLACE_FURNITURE", "chest", 0, "normal_reward" ]
]
},
{
"color": [ 255, 130, 0, 0 ],
"note": "桶",
"command": [
[ "BC_PLACE_FURNITURE", "barrel", 0, "normal_reward" ]
]
},
{
"color": [ 255, 0, 200, 0 ],
"note": "罐子",
"command": [
[ "BC_PLACE_FURNITURE", "pot", 2 ]
]
},
{
"color": [ 255, 255, 255, 0 ],
"note": "火把",
"command": [
[ "BC_PLACE_FURNITURE", "torch", 0 ]
]
},
{
"color": [ 255, 102, 102, 204 ],
"note": "门",
"command": [
[ "BC_PLACE_FURNITURE", "wooden_door_dark_oak" ]
]
},
{
"color": [ 255, 255, 0, 255 ],
"note": "平台",
"command": [
[ "BC_PLACE_TILE", "platform_sandstone" ]
]
},
{
"color": [ 255, 0, 255, 0 ],
"note": "吊灯",
"command": [
[ "BC_PLACE_FURNITURE", "fire_lamp" ]
]
},
{
"color": [ 255, 0, 0, 130 ],
"note": "合成台",
"command": [
[ "BC_PLACE_FURNITURE", "crafting_table" ]
]
},
{
"color": [ 255, 128, 64, 32 ],
"note": "熔炉",
"command": [
[ "BC_PLACE_FURNITURE", "furnace" ]
]
},
{
"color": [ 255, 255, 0, 0 ],
"note": "桌子",
"command": [
[ "BC_PLACE_FURNITURE", "table_dark_oak" ]
]
},
{
"color": [ 255, 128, 0, 0 ],
"note": "椅子",
"command": [
[ "BC_PLACE_FURNITURE", "chair_dark_oak", 1 ]
]
},
{
"color": [ 255, 160, 0, 0 ],
"note": "椅子",
"command": [
[ "BC_PLACE_FURNITURE", "chair_dark_oak", 0 ]
]
},
{
"color": [ 255, 0, 130, 0 ],
"note": "长凳",
"command": [
[ "BC_PLACE_FURNITURE", "bench_dark_oak" ]
]
},
{
"color": [ 255, 0, 128, 255 ],
"note": "床",
"command": [
[ "BC_PLACE_FURNITURE", "wooden_bed_red", 0 ]
]
},
{
"color": [ 255, 100, 100, 0 ],
"note": "书架",
"command": [
[ "BC_PLACE_FURNITURE", "bookcase_dark_oak", 0, "normal_reward" ]
]
},
{
"color": [ 255, 200, 200, 0 ],
"note": "桌柜",
"command": [
[ "BC_PLACE_FURNITURE", "cabinet_dark_oak", 0, "normal_reward" ]
]
},
{
"color": [ 255, 200, 200, 120 ],
"note": "蜡烛",
"command": [
[ "BC_PLACE_FURNITURE", "candle" ]
]
},
{
"color": [ 255, 0, 130, 130 ],
"note": "蜡烛台",
"command": [
[ "BC_PLACE_FURNITURE", "candle_holder" ]
]
},
{
"color": [ 255, 130, 0, 130 ],
"note": "花盆",
"command": [
[ "BC_PLACE_FURNITURE", "flower_pot" ]
]
},
{
"color": [ 255, 130, 0, 180 ],
"note": "花盆",
"command": [
[ "BC_PLACE_FURNITURE", "flower_pot_large" ]
]
},
{
"color": [ 255, 150, 0, 0 ],
"note": "缸",
"command": [
[ "BC_PLACE_FURNITURE", "cauldron" ]
]
},
{
"color": [ 255, 150, 150, 0 ],
"note": "水晶灯",
"command": [
[ "BC_PLACE_FURNITURE", "chandeliers" ]
]
},
{
"color": [ 255, 150, 150, 150 ],
"note": "蜘蛛网",
"command": [
[ "BC_PLACE_FURNITURE", "cobweb" ]
]
},
{
"color": [ 255, 150, 0, 150 ],
"note": "藤蔓",
"command": [
[ "BC_PLACE_FURNITURE", "vine" ]
]
},
{
"color": [ 255, 150, 255, 0 ],
"note": "树苗",
"command": [
[ "BC_PLACE_FURNITURE", "sapling_cactus" ]
]
},
{
"color": [ 255, 0, 0, 168 ],
"note": "踏板",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "sandstone_smooth" ],
[ "BC_PLACE_FURNITURE", "pressure_plate_stone" ]
]
},
{
"color": [ 255, 255, 50, 50 ],
"note": "红石线",
"command": [
[ "BC_PLACE_WIRE", 1, 0 ]
]
},
{
"color": [ 255, 168, 168, 168 ],
"note": "主方块前景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "sandstone_smooth" ],
[ "BC_PLACE_TILE", "sandstone_smooth" ]
]
},
{
"color": [ 255, 202, 202, 202 ],
"note": "主方块前景2",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "sandstone_carved" ],
[ "BC_PLACE_TILE", "sandstone_carved" ]
]
},
{
"color": [ 255, 130, 70, 40 ],
"note": "主方块前景3",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "terracotta_orange" ],
[ "BC_PLACE_TILE", "terracotta_orange" ]
]
},
{
"color": [ 255, 0, 0, 240 ],
"note": "主方块前景4",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "terracotta_blue" ],
[ "BC_PLACE_TILE", "terracotta_blue" ]
]
},
{
"color": [ 255, 250, 0, 0 ],
"note": "TNT",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "sandstone_smooth" ],
[ "BC_PLACE_TILE", "tnt" ]
]
},
{
"color": [ 255, 114, 114, 114 ],
"note": "主方块后景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "sandstone_smooth" ]
]
},
{
"color": [ 255, 133, 133, 133 ],
"note": "主方块后景2",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "sandstone_carved" ]
]
},
{
"color": [ 255, 100, 100, 240 ],
"note": "主方块后景3",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "terracotta_blue" ]
]
}
],
"parts": [
{
"name": "entrance",
"image": [ "entrance", "entrance_o1" ],
"type": "PT_START",
"hotX": 100,
"hotY": 72,
"unlinkParts": [ "entrance" ],
"weight": 10
}
]
}
}
================================================
FILE: buildings/under_dark_oak_cabin/under_dark_oak_cabin.json
================================================
{
"under_dark_oak_cabin": {
"maxGenPartCount": 2,
"limitSize": 50,
"mainRestraint": {
"checks": [
[ "IS_CENTER_Y_GREATER_OR_EQUAL_TO", 0 ]
]
},
"blockEntityFormat": {
"normal_reward": {
"formatId": "tc:common_rewards",
"data": {
"rareGenCount": 1,
"rares": [
{
"itemId": "rocket_boost",
"count": 1
},
{
"itemId": "red_crystal",
"count": 2
},
{
"itemId": "blue_crystal",
"count": 2
},
{
"itemId": "white_crystal",
"count": 2
},
{
"itemId": "yellow_crystal",
"count": 2
},
{
"itemId": "strange_eye",
"count": 1
},
{
"itemId": "ender_mirror",
"count": 1
},
{
"itemId": "wooden_sword",
"count": 1
},
{
"itemId": "stone_sword",
"count": 1
},
{
"itemId": "wooden_axe",
"count": 1
},
{
"itemId": "stone_axe",
"count": 1
},
{
"itemId": "wooden_pickaxe",
"count": 1
},
{
"itemId": "stone_pickaxe",
"count": 1
},
{
"itemId": "wooden_bow",
"count": 1
},
{
"itemId": "wooden_boomerang",
"count": 1
},
{
"itemId": "torch",
"count": 24
},
{
"itemId": "glow_bomb",
"count": 2
},
{
"itemId": "glow_ball",
"count": 6
},
{
"itemId": "book",
"count": 3
},
{
"itemId": "grenade",
"count": 3
},
{
"itemId": "amethyst_staff",
"count": 1
},
{
"itemId": "water_staff",
"count": 1
}
],
"normals": [
{
"itemIds": [ "ender_pearl" ],
"rate": 0.3,
"min": 1,
"max": 2
},
{
"itemIds": [ "bone" ],
"rate": 0.5,
"min": 1,
"max": 8
},
{
"itemIds": [ "gunpowder" ],
"rate": 0.5,
"min": 1,
"max": 8
},
{
"itemIds": [ "rotten_flesh" ],
"rate": 0.5,
"min": 1,
"max": 8
},
{
"itemIds": [ "string" ],
"rate": 0.5,
"min": 1,
"max": 8
},
{
"itemIds": [ "wheat" ],
"rate": 0.34,
"min": 1,
"max": 4
},
{
"itemIds": [ "coal", "charcoal" ],
"rate": 0.26,
"min": 1,
"max": 4
},
{
"itemIds": [ "redstone" ],
"rate": 0.26,
"min": 1,
"max": 4
},
{
"itemIds": [ "golden_apple" ],
"rate": 0.20,
"min": 1,
"max": 1
},
{
"itemIds": [ "pumpkin_seed" ],
"rate": 0.18,
"min": 2,
"max": 4
},
{
"itemIds": [ "melon_seed" ],
"rate": 0.18,
"min": 2,
"max": 4
},
{
"itemIds": [ "iron_ingot", "copper_ingot", "tin_ingot", "lead_ingot" ],
"rate": 0.3,
"min": 1,
"max": 4
},
{
"itemIds": [ "gold_ingot", "silver_ingot", "bronze_ingot", "steel_ingot" ],
"rate": 0.1,
"min": 1,
"max": 4
},
{
"itemIds": [ "bucket_empty" ],
"rate": 0.18,
"min": 1,
"max": 1
},
{
"itemIds": [ "wooden_arrow" ],
"rate": 0.4,
"min": 2,
"max": 7
},
{
"itemIds": [ "lighting_arrow" ],
"rate": 0.4,
"min": 2,
"max": 7
}
]
}
}
},
"restraints": [
],
"commandColors": [
{
"color": [ 255, 64, 64, 64 ],
"note": "无操作",
"command": [
[ "BC_NO_OP" ]
]
},
{
"color": [ 255, 192, 192, 192 ],
"note": "前景记号"
},
{
"color": [ 255, 0, 0, 0 ],
"note": "空气",
"command": [
[ "BC_CLEAR_LAKE" ],
[ "BC_CLEAR" ]
]
},
{
"color": [ 255, 0, 64, 255 ],
"pipe": true
},
{
"color": [ 255, 0, 255, 255 ],
"pipe": true
},
{
"color": [ 255, 0, 160, 255 ],
"note": "箱子",
"command": [
[ "BC_PLACE_FURNITURE", "chest", 0, "normal_reward" ]
]
},
{
"color": [ 255, 130, 0, 0 ],
"note": "桶",
"command": [
[ "BC_PLACE_FURNITURE", "barrel", 0, "normal_reward" ]
]
},
{
"color": [ 255, 0, 200, 0 ],
"note": "罐子",
"command": [
[ "BC_PLACE_FURNITURE", "pot", 0 ]
]
},
{
"color": [ 255, 255, 255, 0 ],
"note": "火把",
"command": [
[ "BC_PLACE_FURNITURE", "torch", 0 ]
]
},
{
"color": [ 255, 102, 102, 204 ],
"note": "门",
"command": [
[ "BC_PLACE_FURNITURE", "wooden_door_dark_oak" ]
]
},
{
"color": [ 255, 255, 0, 255 ],
"note": "平台",
"command": [
[ "BC_PLACE_TILE", "platform_dark_oak" ]
]
},
{
"color": [ 255, 0, 255, 0 ],
"note": "吊灯",
"command": [
[ "BC_PLACE_FURNITURE", "fire_lamp" ]
]
},
{
"color": [ 255, 0, 0, 130 ],
"note": "合成台",
"command": [
[ "BC_PLACE_FURNITURE", "crafting_table" ]
]
},
{
"color": [ 255, 128, 64, 32 ],
"note": "熔炉",
"command": [
[ "BC_PLACE_FURNITURE", "furnace" ]
]
},
{
"color": [ 255, 255, 0, 0 ],
"note": "桌子",
"command": [
[ "BC_PLACE_FURNITURE", "table_dark_oak" ]
]
},
{
"color": [ 255, 128, 0, 0 ],
"note": "椅子",
"command": [
[ "BC_PLACE_FURNITURE", "chair_dark_oak", 1 ]
]
},
{
"color": [ 255, 160, 0, 0 ],
"note": "椅子",
"command": [
[ "BC_PLACE_FURNITURE", "chair_dark_oak", 0 ]
]
},
{
"color": [ 255, 0, 130, 0 ],
"note": "长凳",
"command": [
[ "BC_PLACE_FURNITURE", "bench_dark_oak" ]
]
},
{
"color": [ 255, 0, 128, 255 ],
"note": "床",
"command": [
[ "BC_PLACE_FURNITURE", "wooden_bed_red", 0 ]
]
},
{
"color": [ 255, 100, 100, 0 ],
"note": "书架",
"command": [
[ "BC_PLACE_FURNITURE", "bookcase_dark_oak", 0, "normal_reward" ]
]
},
{
"color": [ 255, 200, 200, 0 ],
"note": "桌柜",
"command": [
[ "BC_PLACE_FURNITURE", "cabinet_dark_oak", 0, "normal_reward" ]
]
},
{
"color": [ 255, 200, 200, 120 ],
"note": "蜡烛",
"command": [
[ "BC_PLACE_FURNITURE", "candle" ]
]
},
{
"color": [ 255, 0, 130, 130 ],
"note": "蜡烛台",
"command": [
[ "BC_PLACE_FURNITURE", "candle_holder" ]
]
},
{
"color": [ 255, 130, 0, 130 ],
"note": "花盆",
"command": [
[ "BC_PLACE_FURNITURE", "flower_pot" ]
]
},
{
"color": [ 255, 150, 0, 0 ],
"note": "缸",
"command": [
[ "BC_PLACE_FURNITURE", "cauldron" ]
]
},
{
"color": [ 255, 150, 150, 0 ],
"note": "水晶灯",
"command": [
[ "BC_PLACE_FURNITURE", "chandeliers" ]
]
},
{
"color": [ 255, 150, 150, 150 ],
"note": "蜘蛛网",
"command": [
[ "BC_PLACE_FURNITURE", "cobweb" ]
]
},
{
"color": [ 255, 150, 0, 150 ],
"note": "藤蔓",
"command": [
[ "BC_PLACE_FURNITURE", "vine" ]
]
},
{
"color": [ 255, 150, 255, 0 ],
"note": "树苗",
"command": [
[ "BC_PLACE_FURNITURE", "sapling_dark_oak" ]
]
},
{
"color": [ 255, 168, 168, 168 ],
"note": "主方块前景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "plank_dark_oak" ],
[ "BC_PLACE_TILE", "plank_dark_oak" ]
]
},
{
"color": [ 255, 114, 114, 114 ],
"note": "主方块后景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "plank_dark_oak" ]
]
}
],
"parts": [
{
"name": "entrance",
"image": [ "entrance", "entrance_o1", "entrance_o2" ],
"type": "PT_START",
"hotX": 25,
"hotY": 25,
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "entrance2",
"image": [ "entrance2", "entrance2_o1" ],
"type": "PT_START",
"hotX": 25,
"hotY": 25,
"unlinkParts": [ "entrance2" ],
"weight": 10
},
{
"name": "entrance3",
"image": [ "entrance3", "entrance3_o1" ],
"type": "PT_START",
"hotX": 25,
"hotY": 25,
"unlinkParts": [ "entrance3" ],
"weight": 10
},
{
"name": "entrance4",
"image": [ "entrance4", "entrance4_o1" ],
"type": "PT_START",
"hotX": 25,
"hotY": 25,
"unlinkParts": [ "entrance4" ],
"weight": 10
},
{
"name": "r1",
"image": [ "r1", "r1_o1", "r1_o2" ],
"type": "PT_NORMAL",
"unlinkParts": [],
"weight": 10
},
{
"name": "r2",
"image": [ "r2", "r2_o1", "r2_o2" ],
"type": "PT_NORMAL",
"unlinkParts": [],
"weight": 10
},
{
"name": "r3",
"image": [ "r3", "r3_o1", "r3_o2" ],
"type": "PT_NORMAL",
"unlinkParts": [],
"weight": 10
},
{
"name": "r4",
"image": [ "r4", "r4_o1" ],
"type": "PT_NORMAL",
"unlinkParts": [],
"weight": 10
},
{
"name": "e1",
"image": [ "e1", "e1_o1", "e1_o2" ],
"type": "PT_END",
"unlinkParts": [],
"weight": 10
},
{
"name": "e2",
"image": [ "e2", "e2_o1", "e2_o2" ],
"type": "PT_END",
"unlinkParts": [],
"weight": 10
},
{
"name": "e3",
"image": [ "e3", "e3_o1" ],
"type": "PT_END",
"unlinkParts": [],
"weight": 10
},
{
"name": "e4",
"image": [ "e4", "e4_o1" ],
"type": "PT_END",
"unlinkParts": [],
"weight": 10
}
]
}
}
================================================
FILE: buildings/under_desert_cabin/under_desert_cabin.json
================================================
{
"under_desert_cabin": {
"maxGenPartCount": 2,
"limitSize": 50,
"mainRestraint": {
"checks": [
[ "IS_CENTER_Y_GREATER_OR_EQUAL_TO", 0 ]
]
},
"blockEntityFormat": {
"normal_reward": {
"formatId": "tc:common_rewards",
"data": {
"rareGenCount": 1,
"rares": [],
"normals": [
{
"itemIds": [ "bone" ],
"rate": 0.7,
"min": 4,
"max": 6
},
{
"itemIds": [ "rotten_flesh" ],
"rate": 0.7,
"min": 1,
"max": 8
},
{
"itemIds": [ "gunpowder" ],
"rate": 0.6,
"min": 1,
"max": 8
},
{
"itemIds": [ "sand" ],
"rate": 0.6,
"min": 1,
"max": 8
},
{
"itemIds": [ "string" ],
"rate": 0.6,
"min": 1,
"max": 8
},
{
"itemIds": [ "spider_eye" ],
"rate": 0.3,
"min": 1,
"max": 3
},
{
"itemIds": [ "book" ],
"rate": 0.3,
"min": 1,
"max": 3
},
{
"itemIds": [ "golden_apple" ],
"rate": 0.23,
"min": 1,
"max": 1
},
{
"itemIds": [ "iron_ingot", "copper_ingot", "tin_ingot", "lead_ingot" ],
"rate": 0.18,
"min": 1,
"max": 5
},
{
"itemIds": [ "gold_ingot", "silver_ingot", "bronze_ingot", "steel_ingot" ],
"rate": 0.18,
"min": 2,
"max": 5
},
{
"itemIds": [ "emerald" ],
"rate": 0.18,
"min": 1,
"max": 3
},
{
"itemIds": [ "diamond" ],
"rate": 0.18,
"min": 1,
"max": 3
}
]
}
}
},
"restraints": [
],
"commandColors": [
{
"color": [ 255, 64, 64, 64 ],
"note": "无操作",
"command": [
[ "BC_NO_OP" ]
]
},
{
"color": [ 255, 192, 192, 192 ],
"note": "前景记号"
},
{
"color": [ 255, 0, 0, 0 ],
"note": "空气",
"command": [
[ "BC_CLEAR_LAKE" ],
[ "BC_CLEAR" ]
]
},
{
"color": [ 255, 0, 64, 255 ],
"pipe": true
},
{
"color": [ 255, 0, 255, 255 ],
"pipe": true
},
{
"color": [ 255, 0, 160, 255 ],
"note": "箱子",
"command": [
[ "BC_PLACE_FURNITURE", "stone_chest", 0, "normal_reward" ]
]
},
{
"color": [ 255, 130, 0, 0 ],
"note": "桶",
"command": [
[ "BC_PLACE_FURNITURE", "barrel", 0, "normal_reward" ]
]
},
{
"color": [ 255, 0, 200, 0 ],
"note": "罐子",
"command": [
[ "BC_PLACE_FURNITURE", "pot", 0 ]
]
},
{
"color": [ 255, 255, 255, 0 ],
"note": "火把",
"command": [
[ "BC_PLACE_FURNITURE", "torch", 0 ]
]
},
{
"color": [ 255, 102, 102, 204 ],
"note": "门",
"command": [
[ "BC_PLACE_FURNITURE", "wooden_door_birch" ]
]
},
{
"color": [ 255, 255, 0, 255 ],
"note": "平台",
"command": [
[ "BC_PLACE_TILE", "platform_birch" ]
]
},
{
"color": [ 255, 0, 255, 0 ],
"note": "吊灯",
"command": [
[ "BC_PLACE_FURNITURE", "fire_lamp" ]
]
},
{
"color": [ 255, 0, 0, 130 ],
"note": "合成台",
"command": [
[ "BC_PLACE_FURNITURE", "crafting_table" ]
]
},
{
"color": [ 255, 128, 64, 32 ],
"note": "熔炉",
"command": [
[ "BC_PLACE_FURNITURE", "furnace" ]
]
},
{
"color": [ 255, 255, 0, 0 ],
"note": "桌子",
"command": [
[ "BC_PLACE_FURNITURE", "table_birch" ]
]
},
{
"color": [ 255, 128, 0, 0 ],
"note": "椅子",
"command": [
[ "BC_PLACE_FURNITURE", "chair_birch", 1 ]
]
},
{
"color": [ 255, 160, 0, 0 ],
"note": "椅子",
"command": [
[ "BC_PLACE_FURNITURE", "chair_birch", 0 ]
]
},
{
"color": [ 255, 0, 130, 0 ],
"note": "长凳",
"command": [
[ "BC_PLACE_FURNITURE", "bench_birch" ]
]
},
{
"color": [ 255, 0, 128, 255 ],
"note": "床",
"command": [
[ "BC_PLACE_FURNITURE", "wooden_bed_red", 0 ]
]
},
{
"color": [ 255, 100, 100, 0 ],
"note": "书架",
"command": [
[ "BC_PLACE_FURNITURE", "bookcase_birch", 0, "normal_reward" ]
]
},
{
"color": [ 255, 200, 200, 0 ],
"note": "桌柜",
"command": [
[ "BC_PLACE_FURNITURE", "cabinet_birch", 0, "normal_reward" ]
]
},
{
"color": [ 255, 200, 200, 120 ],
"note": "蜡烛",
"command": [
[ "BC_PLACE_FURNITURE", "candle" ]
]
},
{
"color": [ 255, 0, 130, 130 ],
"note": "蜡烛台",
"command": [
[ "BC_PLACE_FURNITURE", "candle_holder" ]
]
},
{
"color": [ 255, 130, 0, 130 ],
"note": "花盆",
"command": [
[ "BC_PLACE_FURNITURE", "flower_pot" ]
]
},
{
"color": [ 255, 130, 0, 180 ],
"note": "花盆",
"command": [
[ "BC_PLACE_FURNITURE", "flower_pot_large" ]
]
},
{
"color": [ 255, 150, 0, 0 ],
"note": "缸",
"command": [
[ "BC_PLACE_FURNITURE", "cauldron" ]
]
},
{
"color": [ 255, 150, 150, 0 ],
"note": "水晶灯",
"command": [
[ "BC_PLACE_FURNITURE", "chandeliers" ]
]
},
{
"color": [ 255, 150, 150, 150 ],
"note": "蜘蛛网",
"command": [
[ "BC_PLACE_FURNITURE", "cobweb" ]
]
},
{
"color": [ 255, 150, 255, 0 ],
"note": "树苗",
"command": [
[ "BC_PLACE_FURNITURE", "sapling_cactus" ]
]
},
{
"color": [ 255, 168, 168, 168 ],
"note": "主方块前景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "terracotta_yellow" ],
[ "BC_PLACE_TILE", "terracotta_yellow" ]
]
},
{
"color": [ 255, 114, 114, 114 ],
"note": "主方块后景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "terracotta_yellow" ]
]
},
{
"color": [ 255, 97, 97, 97 ],
"note": "主方块后景2",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "sandstone" ]
]
}
],
"parts": [
{
"name": "entrance",
"image": [ "entrance", "entrance_o1", "entrance_o2" ],
"type": "PT_START",
"hotX": 25,
"hotY": 25,
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "entrance2",
"image": [ "entrance2", "entrance2_o1" ],
"type": "PT_START",
"hotX": 25,
"hotY": 25,
"unlinkParts": [ "entrance2" ],
"weight": 10
},
{
"name": "entrance3",
"image": [ "entrance3", "entrance3_o1" ],
"type": "PT_START",
"hotX": 25,
"hotY": 25,
"unlinkParts": [ "entrance3" ],
"weight": 10
},
{
"name": "entrance4",
"image": [ "entrance4", "entrance4_o1" ],
"type": "PT_START",
"hotX": 25,
"hotY": 25,
"unlinkParts": [ "entrance4" ],
"weight": 10
}
]
}
}
================================================
FILE: buildings/under_jungle_cabin/under_jungle_cabin.json
================================================
{
"under_jungle_cabin": {
"maxGenPartCount": 2,
"limitSize": 50,
"mainRestraint": {
"checks": [
[ "IS_CENTER_Y_GREATER_OR_EQUAL_TO", 0 ]
]
},
"blockEntityFormat": {
"normal_reward": {
"formatId": "tc:common_rewards",
"data": {
"rareGenCount": 1,
"rares": [
{
"itemId": "rocket_boost",
"count": 1
},
{
"itemId": "red_crystal",
"count": 2
},
{
"itemId": "blue_crystal",
"count": 2
},
{
"itemId": "white_crystal",
"count": 2
},
{
"itemId": "yellow_crystal",
"count": 2
},
{
"itemId": "ender_mirror",
"count": 1
},
{
"itemId": "wooden_sword",
"count": 1
},
{
"itemId": "stone_sword",
"count": 1
},
{
"itemId": "wooden_axe",
"count": 1
},
{
"itemId": "stone_axe",
"count": 1
},
{
"itemId": "wooden_pickaxe",
"count": 1
},
{
"itemId": "stone_pickaxe",
"count": 1
},
{
"itemId": "wooden_bow",
"count": 1
},
{
"itemId": "wooden_boomerang",
"count": 1
},
{
"itemId": "torch",
"count": 24
},
{
"itemId": "glow_bomb",
"count": 2
},
{
"itemId": "glow_ball",
"count": 6
},
{
"itemId": "book",
"count": 3
},
{
"itemId": "grenade",
"count": 3
},
{
"itemId": "amethyst_staff",
"count": 1
},
{
"itemId": "water_staff",
"count": 1
}
],
"normals": [
{
"itemIds": [ "ender_pearl" ],
"rate": 0.3,
"min": 1,
"max": 2
},
{
"itemIds": [ "bone" ],
"rate": 0.5,
"min": 1,
"max": 8
},
{
"itemIds": [ "gunpowder" ],
"rate": 0.5,
"min": 1,
"max": 8
},
{
"itemIds": [ "rotten_flesh" ],
"rate": 0.5,
"min": 1,
"max": 8
},
{
"itemIds": [ "string" ],
"rate": 0.5,
"min": 1,
"max": 8
},
{
"itemIds": [ "wheat" ],
"rate": 0.34,
"min": 1,
"max": 4
},
{
"itemIds": [ "coal", "charcoal" ],
"rate": 0.26,
"min": 1,
"max": 4
},
{
"itemIds": [ "redstone" ],
"rate": 0.26,
"min": 1,
"max": 4
},
{
"itemIds": [ "golden_apple" ],
"rate": 0.20,
"min": 1,
"max": 1
},
{
"itemIds": [ "pumpkin_seed" ],
"rate": 0.18,
"min": 2,
"max": 4
},
{
"itemIds": [ "melon_seed" ],
"rate": 0.18,
"min": 2,
"max": 4
},
{
"itemIds": [ "iron_ingot", "copper_ingot", "tin_ingot", "lead_ingot" ],
"rate": 0.3,
"min": 1,
"max": 4
},
{
"itemIds": [ "gold_ingot", "silver_ingot", "bronze_ingot", "steel_ingot" ],
"rate": 0.1,
"min": 1,
"max": 4
},
{
"itemIds": [ "bucket_empty" ],
"rate": 0.18,
"min": 1,
"max": 1
},
{
"itemIds": [ "wooden_arrow" ],
"rate": 0.4,
"min": 2,
"max": 7
},
{
"itemIds": [ "lighting_arrow" ],
"rate": 0.4,
"min": 2,
"max": 7
}
]
}
}
},
"restraints": [
],
"commandColors": [
{
"color": [ 255, 64, 64, 64 ],
"note": "无操作",
"command": [
[ "BC_NO_OP" ]
]
},
{
"color": [ 255, 192, 192, 192 ],
"note": "前景记号"
},
{
"color": [ 255, 0, 0, 0 ],
"note": "空气",
"command": [
[ "BC_CLEAR_LAKE" ],
[ "BC_CLEAR" ]
]
},
{
"color": [ 255, 0, 64, 255 ],
"pipe": true
},
{
"color": [ 255, 0, 255, 255 ],
"pipe": true
},
{
"color": [ 255, 0, 160, 255 ],
"note": "箱子",
"command": [
[ "BC_PLACE_FURNITURE", "chest", 0, "normal_reward" ]
]
},
{
"color": [ 255, 130, 0, 0 ],
"note": "桶",
"command": [
[ "BC_PLACE_FURNITURE", "barrel", 0, "normal_reward" ]
]
},
{
"color": [ 255, 0, 200, 0 ],
"note": "罐子",
"command": [
[ "BC_PLACE_FURNITURE", "pot", 0 ]
]
},
{
"color": [ 255, 255, 255, 0 ],
"note": "火把",
"command": [
[ "BC_PLACE_FURNITURE", "torch", 0 ]
]
},
{
"color": [ 255, 102, 102, 204 ],
"note": "门",
"command": [
[ "BC_PLACE_FURNITURE", "wooden_door_jungle" ]
]
},
{
"color": [ 255, 255, 0, 255 ],
"note": "平台",
"command": [
[ "BC_PLACE_TILE", "platform_jungle" ]
]
},
{
"color": [ 255, 0, 255, 0 ],
"note": "吊灯",
"command": [
[ "BC_PLACE_FURNITURE", "fire_lamp" ]
]
},
{
"color": [ 255, 0, 0, 130 ],
"note": "合成台",
"command": [
[ "BC_PLACE_FURNITURE", "crafting_table" ]
]
},
{
"color": [ 255, 128, 64, 32 ],
"note": "熔炉",
"command": [
[ "BC_PLACE_FURNITURE", "furnace" ]
]
},
{
"color": [ 255, 255, 0, 0 ],
"note": "桌子",
"command": [
[ "BC_PLACE_FURNITURE", "table_jungle" ]
]
},
{
"color": [ 255, 128, 0, 0 ],
"note": "椅子",
"command": [
[ "BC_PLACE_FURNITURE", "chair_jungle", 1 ]
]
},
{
"color": [ 255, 160, 0, 0 ],
"note": "椅子",
"command": [
[ "BC_PLACE_FURNITURE", "chair_jungle", 0 ]
]
},
{
"color": [ 255, 0, 130, 0 ],
"note": "长凳",
"command": [
[ "BC_PLACE_FURNITURE", "bench_jungle" ]
]
},
{
"color": [ 255, 0, 128, 255 ],
"note": "床",
"command": [
[ "BC_PLACE_FURNITURE", "wooden_bed_red", 0 ]
]
},
{
"color": [ 255, 100, 100, 0 ],
"note": "书架",
"command": [
[ "BC_PLACE_FURNITURE", "bookcase_jungle", 0, "normal_reward" ]
]
},
{
"color": [ 255, 200, 200, 0 ],
"note": "桌柜",
"command": [
[ "BC_PLACE_FURNITURE", "cabinet_jungle", 0, "normal_reward" ]
]
},
{
"color": [ 255, 200, 200, 120 ],
"note": "蜡烛",
"command": [
[ "BC_PLACE_FURNITURE", "candle" ]
]
},
{
"color": [ 255, 0, 130, 130 ],
"note": "蜡烛台",
"command": [
[ "BC_PLACE_FURNITURE", "candle_holder" ]
]
},
{
"color": [ 255, 130, 0, 130 ],
"note": "花盆",
"command": [
[ "BC_PLACE_FURNITURE", "flower_pot" ]
]
},
{
"color": [ 255, 130, 0, 180 ],
"note": "花盆",
"command": [
[ "BC_PLACE_FURNITURE", "flower_pot_large" ]
]
},
{
"color": [ 255, 150, 0, 0 ],
"note": "缸",
"command": [
[ "BC_PLACE_FURNITURE", "cauldron" ]
]
},
{
"color": [ 255, 150, 150, 0 ],
"note": "水晶灯",
"command": [
[ "BC_PLACE_FURNITURE", "chandeliers" ]
]
},
{
"color": [ 255, 150, 150, 150 ],
"note": "蜘蛛网",
"command": [
[ "BC_PLACE_FURNITURE", "cobweb" ]
]
},
{
"color": [ 255, 150, 0, 150 ],
"note": "藤蔓",
"command": [
[ "BC_PLACE_FURNITURE", "vine" ]
]
},
{
"color": [ 255, 150, 255, 0 ],
"note": "树苗",
"command": [
[ "BC_PLACE_FURNITURE", "sapling_jungle" ]
]
},
{
"color": [ 255, 168, 168, 168 ],
"note": "主方块前景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "plank_jungle" ],
[ "BC_PLACE_TILE", "plank_jungle" ]
]
},
{
"color": [ 255, 114, 114, 114 ],
"note": "主方块后景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "plank_jungle" ]
]
}
],
"parts": [
{
"name": "entrance",
"image": [ "entrance", "entrance_o1", "entrance_o2" ],
"type": "PT_START",
"hotX": 25,
"hotY": 25,
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "entrance2",
"image": [ "entrance2", "entrance2_o1" ],
"type": "PT_START",
"hotX": 25,
"hotY": 25,
"unlinkParts": [ "entrance2" ],
"weight": 10
},
{
"name": "entrance3",
"image": [ "entrance3", "entrance3_o1" ],
"type": "PT_START",
"hotX": 25,
"hotY": 25,
"unlinkParts": [ "entrance3" ],
"weight": 10
},
{
"name": "entrance4",
"image": [ "entrance4", "entrance4_o1" ],
"type": "PT_START",
"hotX": 25,
"hotY": 25,
"unlinkParts": [ "entrance4" ],
"weight": 10
},
{
"name": "r1",
"image": [ "r1", "r1_o1", "r1_o2" ],
"type": "PT_NORMAL",
"unlinkParts": [],
"weight": 10
},
{
"name": "r2",
"image": [ "r2", "r2_o1", "r2_o2" ],
"type": "PT_NORMAL",
"unlinkParts": [],
"weight": 10
},
{
"name": "r3",
"image": [ "r3", "r3_o1", "r3_o2" ],
"type": "PT_NORMAL",
"unlinkParts": [],
"weight": 10
},
{
"name": "r4",
"image": [ "r4", "r4_o1" ],
"type": "PT_NORMAL",
"unlinkParts": [],
"weight": 10
},
{
"name": "e1",
"image": [ "e1", "e1_o1", "e1_o2" ],
"type": "PT_END",
"unlinkParts": [],
"weight": 10
},
{
"name": "e2",
"image": [ "e2", "e2_o1", "e2_o2" ],
"type": "PT_END",
"unlinkParts": [],
"weight": 10
},
{
"name": "e3",
"image": [ "e3", "e3_o1" ],
"type": "PT_END",
"unlinkParts": [],
"weight": 10
},
{
"name": "e4",
"image": [ "e4", "e4_o1" ],
"type": "PT_END",
"unlinkParts": [],
"weight": 10
}
]
}
}
================================================
FILE: buildings/under_oak_cabin/under_oak_cabin.json
================================================
{
"under_oak_cabin": {
"maxGenPartCount": 2,
"limitSize": 34,
"mainRestraint": {
"checks": [
[ "IS_CENTER_Y_GREATER_OR_EQUAL_TO", 0 ]
]
},
"blockEntityFormat": {
"normal_reward": {
"formatId": "tc:common_rewards",
"data": {
"name": "normal_reward",
"rareGenCount": 1,
"rares": [
{
"itemId": "rocket_boost",
"count": 1
},
{
"itemId": "strange_eye",
"count": 1
},
{
"itemId": "ender_mirror",
"count": 1
},
{
"itemId": "wooden_sword",
"count": 1
},
{
"itemId": "stone_sword",
"count": 1
},
{
"itemId": "wooden_axe",
"count": 1
},
{
"itemId": "stone_axe",
"count": 1
},
{
"itemId": "wooden_pickaxe",
"count": 1
},
{
"itemId": "stone_pickaxe",
"count": 1
},
{
"itemId": "wooden_bow",
"count": 1
},
{
"itemId": "wooden_boomerang",
"count": 1
},
{
"itemId": "torch",
"count": 24
},
{
"itemId": "glow_bomb",
"count": 2
},
{
"itemId": "glow_ball",
"count": 6
},
{
"itemId": "book",
"count": 3
},
{
"itemId": "grenade",
"count": 3
},
{
"itemId": "amethyst_staff",
"count": 1
},
{
"itemId": "water_staff",
"count": 1
}
],
"normals": [
{
"itemIds": [ "ender_pearl" ],
"rate": 0.3,
"min": 1,
"max": 2
},
{
"itemIds": [ "bone" ],
"rate": 0.5,
"min": 1,
"max": 8
},
{
"itemIds": [ "gunpowder" ],
"rate": 0.5,
"min": 1,
"max": 8
},
{
"itemIds": [ "rotten_flesh" ],
"rate": 0.5,
"min": 1,
"max": 8
},
{
"itemIds": [ "string" ],
"rate": 0.5,
"min": 1,
"max": 8
},
{
"itemIds": [ "wheat" ],
"rate": 0.34,
"min": 1,
"max": 4
},
{
"itemIds": [ "coal", "charcoal" ],
"rate": 0.26,
"min": 1,
"max": 4
},
{
"itemIds": [ "redstone" ],
"rate": 0.26,
"min": 1,
"max": 4
},
{
"itemIds": [ "golden_apple" ],
"rate": 0.20,
"min": 1,
"max": 1
},
{
"itemIds": [ "pumpkin_seed" ],
"rate": 0.18,
"min": 2,
"max": 4
},
{
"itemIds": [ "melon_seed" ],
"rate": 0.18,
"min": 2,
"max": 4
},
{
"itemIds": [ "iron_ingot", "copper_ingot", "tin_ingot", "lead_ingot" ],
"rate": 0.3,
"min": 1,
"max": 4
},
{
"itemIds": [ "gold_ingot", "silver_ingot", "bronze_ingot", "steel_ingot" ],
"rate": 0.1,
"min": 1,
"max": 4
},
{
"itemIds": [ "bucket_empty" ],
"rate": 0.18,
"min": 1,
"max": 1
},
{
"itemIds": [ "wooden_arrow" ],
"rate": 0.4,
"min": 2,
"max": 7
},
{
"itemIds": [ "lighting_arrow" ],
"rate": 0.4,
"min": 2,
"max": 7
}
]
}
}
},
"restraints": [
],
"commandColors": [
{
"color": [ 255, 64, 64, 64 ],
"note": "无操作",
"command": [
[ "BC_NO_OP" ]
]
},
{
"color": [ 255, 192, 192, 192 ],
"note": "前景记号"
},
{
"color": [ 255, 0, 0, 0 ],
"note": "空气",
"command": [
[ "BC_CLEAR_LAKE" ],
[ "BC_CLEAR" ]
]
},
{
"color": [ 255, 0, 64, 255 ],
"pipe": true
},
{
"color": [ 255, 0, 255, 255 ],
"pipe": true
},
{
"color": [ 255, 0, 160, 255 ],
"note": "箱子",
"command": [
[ "BC_PLACE_FURNITURE", "chest", 0, "normal_reward" ]
]
},
{
"color": [ 255, 130, 0, 0 ],
"note": "桶",
"command": [
[ "BC_PLACE_FURNITURE", "barrel", 0, "normal_reward" ]
]
},
{
"color": [ 255, 0, 200, 0 ],
"note": "罐子",
"command": [
[ "BC_PLACE_FURNITURE", "pot", 0 ]
]
},
{
"color": [ 255, 255, 255, 0 ],
"note": "火把",
"command": [
[ "BC_PLACE_FURNITURE", "torch", 0 ]
]
},
{
"color": [ 255, 102, 102, 204 ],
"note": "门",
"command": [
[ "BC_PLACE_FURNITURE", "wooden_door_oak" ]
]
},
{
"color": [ 255, 255, 0, 255 ],
"note": "平台",
"command": [
[ "BC_PLACE_TILE", "platform_oak" ]
]
},
{
"color": [ 255, 0, 255, 0 ],
"note": "吊灯",
"command": [
[ "BC_PLACE_FURNITURE", "fire_lamp" ]
]
},
{
"color": [ 255, 0, 0, 130 ],
"note": "合成台",
"command": [
[ "BC_PLACE_FURNITURE", "crafting_table" ]
]
},
{
"color": [ 255, 128, 64, 32 ],
"note": "熔炉",
"command": [
[ "BC_PLACE_FURNITURE", "furnace" ]
]
},
{
"color": [ 255, 255, 0, 0 ],
"note": "桌子",
"command": [
[ "BC_PLACE_FURNITURE", "table_oak" ]
]
},
{
"color": [ 255, 128, 0, 0 ],
"note": "椅子",
"command": [
[ "BC_PLACE_FURNITURE", "chair_oak", 1 ]
]
},
{
"color": [ 255, 160, 0, 0 ],
"note": "椅子",
"command": [
[ "BC_PLACE_FURNITURE", "chair_oak", 0 ]
]
},
{
"color": [ 255, 0, 130, 0 ],
"note": "长凳",
"command": [
[ "BC_PLACE_FURNITURE", "bench_oak" ]
]
},
{
"color": [ 255, 0, 128, 255 ],
"note": "床",
"command": [
[ "BC_PLACE_FURNITURE", "wooden_bed_red", 0 ]
]
},
{
"color": [ 255, 100, 100, 0 ],
"note": "书架",
"command": [
[ "BC_PLACE_FURNITURE", "bookcase_oak", 0, "normal_reward" ]
]
},
{
"color": [ 255, 200, 200, 0 ],
"note": "桌柜",
"command": [
[ "BC_PLACE_FURNITURE", "cabinet_oak", 0, "normal_reward" ]
]
},
{
"color": [ 255, 200, 200, 120 ],
"note": "蜡烛",
"command": [
[ "BC_PLACE_FURNITURE", "candle" ]
]
},
{
"color": [ 255, 0, 130, 130 ],
"note": "蜡烛台",
"command": [
[ "BC_PLACE_FURNITURE", "candle_holder" ]
]
},
{
"color": [ 255, 130, 0, 130 ],
"note": "花盆",
"command": [
[ "BC_PLACE_FURNITURE", "flower_pot" ]
]
},
{
"color": [ 255, 150, 0, 0 ],
"note": "缸",
"command": [
[ "BC_PLACE_FURNITURE", "cauldron" ]
]
},
{
"color": [ 255, 150, 150, 0 ],
"note": "水晶灯",
"command": [
[ "BC_PLACE_FURNITURE", "chandeliers" ]
]
},
{
"color": [ 255, 150, 150, 150 ],
"note": "蜘蛛网",
"command": [
[ "BC_PLACE_FURNITURE", "cobweb" ]
]
},
{
"color": [ 255, 150, 0, 150 ],
"note": "藤蔓",
"command": [
[ "BC_PLACE_FURNITURE", "vine" ]
]
},
{
"color": [ 255, 150, 255, 0 ],
"note": "树苗",
"command": [
[ "BC_PLACE_FURNITURE", "sapling_oak" ]
]
},
{
"color": [ 255, 168, 168, 168 ],
"note": "主方块前景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "plank_oak" ],
[ "BC_PLACE_TILE", "plank_oak" ]
]
},
{
"color": [ 255, 114, 114, 114 ],
"note": "主方块后景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "plank_oak" ]
]
}
],
"parts": [
{
"name": "entrance",
"image": [ "entrance", "entrance_o1", "entrance_o2" ],
"type": "PT_START",
"hotX": 25,
"hotY": 25,
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "entrance2",
"image": [ "entrance2", "entrance2_o1" ],
"type": "PT_START",
"hotX": 25,
"hotY": 25,
"unlinkParts": [ "entrance2" ],
"weight": 10
},
{
"name": "entrance3",
"image": [ "entrance3", "entrance3_o1" ],
"type": "PT_START",
"hotX": 25,
"hotY": 25,
"unlinkParts": [ "entrance3" ],
"weight": 10
},
{
"name": "entrance4",
"image": [ "entrance4", "entrance4_o1" ],
"type": "PT_START",
"hotX": 25,
"hotY": 25,
"unlinkParts": [ "entrance4" ],
"weight": 10
},
{
"name": "r1",
"image": [ "r1", "r1_o1", "r1_o2" ],
"type": "PT_NORMAL",
"unlinkParts": [],
"weight": 10
},
{
"name": "r2",
"image": [ "r2", "r2_o1", "r2_o2" ],
"type": "PT_NORMAL",
"unlinkParts": [],
"weight": 10
},
{
"name": "r3",
"image": [ "r3", "r3_o1", "r3_o2" ],
"type": "PT_NORMAL",
"unlinkParts": [],
"weight": 10
},
{
"name": "r4",
"image": [ "r4", "r4_o1" ],
"type": "PT_NORMAL",
"unlinkParts": [],
"weight": 10
},
{
"name": "e1",
"image": [ "e1", "e1_o1", "e1_o2" ],
"type": "PT_END",
"unlinkParts": [],
"weight": 10
},
{
"name": "e2",
"image": [ "e2", "e2_o1", "e2_o2" ],
"type": "PT_END",
"unlinkParts": [],
"weight": 10
},
{
"name": "e3",
"image": [ "e3", "e3_o1" ],
"type": "PT_END",
"unlinkParts": [],
"weight": 10
},
{
"name": "e4",
"image": [ "e4", "e4_o1" ],
"type": "PT_END",
"unlinkParts": [],
"weight": 10
}
]
}
}
================================================
FILE: buildings/under_spruce_cabin/under_spruce_cabin.json
================================================
{
"under_spruce_cabin": {
"maxGenPartCount": 2,
"limitSize": 50,
"mainRestraint": {
"checks": [
[ "IS_CENTER_Y_GREATER_OR_EQUAL_TO", 0 ]
]
},
"blockEntityFormat": {
"normal_reward": {
"formatId": "tc:common_rewards",
"data": {
"rareGenCount": 1,
"rares": [
{
"itemId": "rocket_boost",
"count": 1
},
{
"itemId": "red_crystal",
"count": 2
},
{
"itemId": "blue_crystal",
"count": 2
},
{
"itemId": "white_crystal",
"count": 2
},
{
"itemId": "yellow_crystal",
"count": 2
},
{
"itemId": "iron_sword",
"count": 1
},
{
"itemId": "lead_sword",
"count": 1
},
{
"itemId": "copper_axe",
"count": 1
},
{
"itemId": "silver_pickaxe",
"count": 1
},
{
"itemId": "tin_pickaxe",
"count": 1
},
{
"itemId": "torch",
"count": 36
},
{
"itemId": "glow_bomb",
"count": 8
},
{
"itemId": "glow_ball",
"count": 12
},
{
"itemId": "book",
"count": 8
},
{
"itemId": "grenade",
"count": 6
},
{
"itemId": "ghost_sword",
"count": 1
}
],
"normals": [
{
"itemIds": [ "ender_pearl" ],
"rate": 0.3,
"min": 1,
"max": 2
},
{
"itemIds": [ "bone" ],
"rate": 0.5,
"min": 1,
"max": 8
},
{
"itemIds": [ "gunpowder" ],
"rate": 0.5,
"min": 1,
"max": 8
},
{
"itemIds": [ "rotten_flesh" ],
"rate": 0.5,
"min": 1,
"max": 8
},
{
"itemIds": [ "string" ],
"rate": 0.5,
"min": 1,
"max": 8
},
{
"itemIds": [ "wheat" ],
"rate": 0.34,
"min": 1,
"max": 4
},
{
"itemIds": [ "coal", "charcoal" ],
"rate": 0.26,
"min": 1,
"max": 4
},
{
"itemIds": [ "redstone" ],
"rate": 0.26,
"min": 1,
"max": 4
},
{
"itemIds": [ "golden_apple" ],
"rate": 0.20,
"min": 1,
"max": 1
},
{
"itemIds": [ "pumpkin_seed" ],
"rate": 0.18,
"min": 2,
"max": 4
},
{
"itemIds": [ "melon_seed" ],
"rate": 0.18,
"min": 2,
"max": 4
},
{
"itemIds": [ "iron_ingot", "copper_ingot", "tin_ingot", "lead_ingot" ],
"rate": 0.3,
"min": 1,
"max": 4
},
{
"itemIds": [ "gold_ingot", "silver_ingot", "bronze_ingot", "steel_ingot" ],
"rate": 0.1,
"min": 1,
"max": 4
},
{
"itemIds": [ "bucket_empty" ],
"rate": 0.18,
"min": 1,
"max": 1
},
{
"itemIds": [ "wooden_arrow" ],
"rate": 0.4,
"min": 2,
"max": 7
},
{
"itemIds": [ "lighting_arrow" ],
"rate": 0.4,
"min": 2,
"max": 7
}
]
}
}
},
"restraints": [
],
"commandColors": [
{
"color": [ 255, 64, 64, 64 ],
"note": "无操作",
"command": [
[ "BC_NO_OP" ]
]
},
{
"color": [ 255, 192, 192, 192 ],
"note": "前景记号"
},
{
"color": [ 255, 0, 0, 0 ],
"note": "空气",
"command": [
[ "BC_CLEAR_LAKE" ],
[ "BC_CLEAR" ]
]
},
{
"color": [ 255, 0, 64, 255 ],
"pipe": true
},
{
"color": [ 255, 0, 255, 255 ],
"pipe": true
},
{
"color": [ 255, 0, 160, 255 ],
"note": "箱子",
"command": [
[ "BC_PLACE_FURNITURE", "chest", 0, "normal_reward" ]
]
},
{
"color": [ 255, 130, 0, 0 ],
"note": "桶",
"command": [
[ "BC_PLACE_FURNITURE", "barrel", 0, "normal_reward" ]
]
},
{
"color": [ 255, 0, 200, 0 ],
"note": "罐子",
"command": [
[ "BC_PLACE_FURNITURE", "pot", 0 ]
]
},
{
"color": [ 255, 255, 255, 0 ],
"note": "火把",
"command": [
[ "BC_PLACE_FURNITURE", "torch", 0 ]
]
},
{
"color": [ 255, 102, 102, 204 ],
"note": "门",
"command": [
[ "BC_PLACE_FURNITURE", "wooden_door_spruce" ]
]
},
{
"color": [ 255, 255, 0, 255 ],
"note": "平台",
"command": [
[ "BC_PLACE_TILE", "platform_spruce" ]
]
},
{
"color": [ 255, 0, 255, 0 ],
"note": "吊灯",
"command": [
[ "BC_PLACE_FURNITURE", "fire_lamp" ]
]
},
{
"color": [ 255, 0, 0, 130 ],
"note": "合成台",
"command": [
[ "BC_PLACE_FURNITURE", "crafting_table" ]
]
},
{
"color": [ 255, 128, 64, 32 ],
"note": "熔炉",
"command": [
[ "BC_PLACE_FURNITURE", "furnace" ]
]
},
{
"color": [ 255, 255, 0, 0 ],
"note": "桌子",
"command": [
[ "BC_PLACE_FURNITURE", "table_spruce" ]
]
},
{
"color": [ 255, 128, 0, 0 ],
"note": "椅子",
"command": [
[ "BC_PLACE_FURNITURE", "chair_spruce", 1 ]
]
},
{
"color": [ 255, 160, 0, 0 ],
"note": "椅子",
"command": [
[ "BC_PLACE_FURNITURE", "chair_spruce", 0 ]
]
},
{
"color": [ 255, 0, 130, 0 ],
"note": "长凳",
"command": [
[ "BC_PLACE_FURNITURE", "bench_spruce" ]
]
},
{
"color": [ 255, 0, 128, 255 ],
"note": "床",
"command": [
[ "BC_PLACE_FURNITURE", "wooden_bed_red", 0 ]
]
},
{
"color": [ 255, 100, 100, 0 ],
"note": "书架",
"command": [
[ "BC_PLACE_FURNITURE", "bookcase_spruce", 0, "normal_reward" ]
]
},
{
"color": [ 255, 200, 200, 0 ],
"note": "桌柜",
"command": [
[ "BC_PLACE_FURNITURE", "cabinet_spruce", 0, "normal_reward" ]
]
},
{
"color": [ 255, 200, 200, 120 ],
"note": "蜡烛",
"command": [
[ "BC_PLACE_FURNITURE", "candle" ]
]
},
{
"color": [ 255, 0, 130, 130 ],
"note": "蜡烛台",
"command": [
[ "BC_PLACE_FURNITURE", "candle_holder" ]
]
},
{
"color": [ 255, 130, 0, 130 ],
"note": "花盆",
"command": [
[ "BC_PLACE_FURNITURE", "flower_pot" ]
]
},
{
"color": [ 255, 130, 0, 180 ],
"note": "花盆",
"command": [
[ "BC_PLACE_FURNITURE", "flower_pot_large" ]
]
},
{
"color": [ 255, 150, 0, 0 ],
"note": "缸",
"command": [
[ "BC_PLACE_FURNITURE", "cauldron" ]
]
},
{
"color": [ 255, 150, 150, 0 ],
"note": "水晶灯",
"command": [
[ "BC_PLACE_FURNITURE", "chandeliers" ]
]
},
{
"color": [ 255, 150, 150, 150 ],
"note": "蜘蛛网",
"command": [
[ "BC_PLACE_FURNITURE", "cobweb" ]
]
},
{
"color": [ 255, 150, 0, 150 ],
"note": "藤蔓",
"command": [
[ "BC_PLACE_FURNITURE", "vine" ]
]
},
{
"color": [ 255, 150, 255, 0 ],
"note": "树苗",
"command": [
[ "BC_PLACE_FURNITURE", "sapling_spruce" ]
]
},
{
"color": [ 255, 168, 168, 168 ],
"note": "主方块前景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "plank_spruce" ],
[ "BC_PLACE_TILE", "plank_spruce" ]
]
},
{
"color": [ 255, 114, 114, 114 ],
"note": "主方块后景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "plank_spruce" ]
]
}
],
"parts": [
{
"name": "entrance",
"image": [ "entrance", "entrance_o1", "entrance_o2" ],
"type": "PT_START",
"hotX": 25,
"hotY": 25,
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "entrance2",
"image": [ "entrance2", "entrance2_o1", "entrance2_o2" ],
"type": "PT_START",
"hotX": 25,
"hotY": 25,
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "entrance3",
"image": [ "entrance3", "entrance3_o1", "entrance3_o2" ],
"type": "PT_START",
"hotX": 25,
"hotY": 25,
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "e1",
"image": [ "e1", "e1_o1", "e1_o2" ],
"type": "PT_END",
"unlinkParts": [],
"weight": 10
},
{
"name": "e2",
"image": [ "e2", "e2_o1", "e2_o2" ],
"type": "PT_END",
"unlinkParts": [],
"weight": 10
},
{
"name": "e3",
"image": [ "e3", "e3_o1" ],
"type": "PT_END",
"unlinkParts": [],
"weight": 10
},
{
"name": "e4",
"image": [ "e4", "e4_o1" ],
"type": "PT_END",
"unlinkParts": [],
"weight": 10
}
]
}
}
================================================
FILE: buildings/under_stone_cabin/under_stone_cabin.json
================================================
{
"under_stone_cabin": {
"maxGenPartCount": 2,
"limitSize": 50,
"mainRestraint": {
"checks": [
[ "IS_CENTER_Y_GREATER_OR_EQUAL_TO", 0 ]
]
},
"blockEntityFormat": {
"normal_reward": {
"formatId": "tc:common_rewards",
"data": {
"name": "normal_reward",
"rareGenCount": 1,
"rares": [
{
"itemId": "rocket_boost",
"count": 1
},
{
"itemId": "red_crystal",
"count": 2
},
{
"itemId": "blue_crystal",
"count": 2
},
{
"itemId": "white_crystal",
"count": 2
},
{
"itemId": "yellow_crystal",
"count": 2
},
{
"itemId": "strange_eye",
"count": 1
},
{
"itemId": "ender_mirror",
"count": 1
},
{
"itemId": "iron_sword",
"count": 1
},
{
"itemId": "stone_sword",
"count": 1
},
{
"itemId": "iron_axe",
"count": 1
},
{
"itemId": "stone_axe",
"count": 1
},
{
"itemId": "stone_pickaxe",
"count": 1
},
{
"itemId": "torch",
"count": 8
},
{
"itemId": "glow_bomb",
"count": 2
},
{
"itemId": "bomb",
"count": 2
},
{
"itemId": "grenade",
"count": 3
},
{
"itemId": "ghost_sword",
"count": 1
},
{
"itemId": "amethyst_staff",
"count": 1
},
{
"itemId": "water_staff",
"count": 1
}
],
"normals": [
{
"itemIds": [ "ender_pearl" ],
"rate": 0.5,
"min": 1,
"max": 2
},
{
"itemIds": [ "apple" ],
"rate": 0.5,
"min": 1,
"max": 3
},
{
"itemIds": [ "bread" ],
"rate": 0.5,
"min": 1,
"max": 3
},
{
"itemIds": [ "coal", "charcoal" ],
"rate": 0.34,
"min": 3,
"max": 8
},
{
"itemIds": [ "redstone" ],
"rate": 0.26,
"min": 4,
"max": 9
},
{
"itemIds": [ "iron_ingot", "copper_ingot", "tin_ingot", "lead_ingot" ],
"rate": 0.3,
"min": 1,
"max": 4
},
{
"itemIds": [ "gold_ingot", "silver_ingot", "bronze_ingot", "steel_ingot" ],
"rate": 0.1,
"min": 1,
"max": 3
}
]
}
}
},
"restraints": [
],
"commandColors": [
{
"color": [ 255, 64, 64, 64 ],
"note": "无操作",
"command": [
[ "BC_NO_OP" ]
]
},
{
"color": [ 255, 192, 192, 192 ],
"note": "前景记号"
},
{
"color": [ 255, 0, 0, 0 ],
"note": "空气",
"command": [
[ "BC_CLEAR_LAKE" ],
[ "BC_CLEAR" ]
]
},
{
"color": [ 255, 0, 64, 255 ],
"pipe": true
},
{
"color": [ 255, 0, 255, 255 ],
"pipe": true
},
{
"color": [ 255, 0, 160, 255 ],
"note": "箱子",
"command": [
[ "BC_PLACE_FURNITURE", "stone_chest", 0, "normal_reward" ]
]
},
{
"color": [ 255, 130, 0, 0 ],
"note": "桶",
"command": [
[ "BC_PLACE_FURNITURE", "barrel", 0, "normal_reward" ]
]
},
{
"color": [ 255, 0, 200, 0 ],
"note": "罐子",
"command": [
[ "BC_PLACE_FURNITURE", "pot", 0 ]
]
},
{
"color": [ 255, 255, 255, 0 ],
"note": "火把",
"command": [
[ "BC_PLACE_FURNITURE", "torch", 0 ]
]
},
{
"color": [ 255, 102, 102, 204 ],
"note": "门",
"command": [
[ "BC_PLACE_FURNITURE", "wooden_door_jungle" ]
]
},
{
"color": [ 255, 255, 0, 255 ],
"note": "平台",
"command": [
[ "BC_PLACE_TILE", "platform_jungle" ]
]
},
{
"color": [ 255, 0, 255, 0 ],
"note": "吊灯",
"command": [
[ "BC_PLACE_FURNITURE", "fire_lamp" ]
]
},
{
"color": [ 255, 0, 0, 130 ],
"note": "合成台",
"command": [
[ "BC_PLACE_FURNITURE", "crafting_table" ]
]
},
{
"color": [ 255, 128, 64, 32 ],
"note": "熔炉",
"command": [
[ "BC_PLACE_FURNITURE", "furnace" ]
]
},
{
"color": [ 255, 255, 0, 0 ],
"note": "桌子",
"command": [
[ "BC_PLACE_FURNITURE", "table_jungle" ]
]
},
{
"color": [ 255, 128, 0, 0 ],
"note": "椅子",
"command": [
[ "BC_PLACE_FURNITURE", "chair_jungle", 1 ]
]
},
{
"color": [ 255, 160, 0, 0 ],
"note": "椅子",
"command": [
[ "BC_PLACE_FURNITURE", "chair_jungle", 0 ]
]
},
{
"color": [ 255, 0, 130, 0 ],
"note": "长凳",
"command": [
[ "BC_PLACE_FURNITURE", "bench_jungle" ]
]
},
{
"color": [ 255, 0, 128, 255 ],
"note": "床",
"command": [
[ "BC_PLACE_FURNITURE", "wooden_bed_red", 0 ]
]
},
{
"color": [ 255, 100, 100, 0 ],
"note": "书架",
"command": [
[ "BC_PLACE_FURNITURE", "bookcase_jungle", 0, "normal_reward" ]
]
},
{
"color": [ 255, 200, 200, 0 ],
"note": "桌柜",
"command": [
[ "BC_PLACE_FURNITURE", "cabinet_jungle", 0, "normal_reward" ]
]
},
{
"color": [ 255, 200, 200, 120 ],
"note": "蜡烛",
"command": [
[ "BC_PLACE_FURNITURE", "candle" ]
]
},
{
"color": [ 255, 0, 130, 130 ],
"note": "蜡烛台",
"command": [
[ "BC_PLACE_FURNITURE", "candle_holder" ]
]
},
{
"color": [ 255, 130, 0, 130 ],
"note": "花盆",
"command": [
[ "BC_PLACE_FURNITURE", "flower_pot" ]
]
},
{
"color": [ 255, 130, 0, 180 ],
"note": "花盆",
"command": [
[ "BC_PLACE_FURNITURE", "flower_pot_large" ]
]
},
{
"color": [ 255, 150, 0, 0 ],
"note": "缸",
"command": [
[ "BC_PLACE_FURNITURE", "cauldron" ]
]
},
{
"color": [ 255, 150, 150, 0 ],
"note": "水晶灯",
"command": [
[ "BC_PLACE_FURNITURE", "chandeliers" ]
]
},
{
"color": [ 255, 150, 150, 150 ],
"note": "蜘蛛网",
"command": [
[ "BC_PLACE_FURNITURE", "cobweb" ]
]
},
{
"color": [ 255, 150, 0, 150 ],
"note": "藤蔓",
"command": [
[ "BC_PLACE_FURNITURE", "vine" ]
]
},
{
"color": [ 255, 150, 255, 0 ],
"note": "树苗",
"command": [
[ "BC_PLACE_FURNITURE", "sapling_jungle" ]
]
},
{
"color": [ 255, 168, 168, 168 ],
"note": "主方块前景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "stone_brick" ],
[ "BC_PLACE_TILE", "stone_brick" ]
]
},
{
"color": [ 255, 114, 114, 114 ],
"note": "主方块后景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "stone_brick" ]
]
},
{
"color": [ 255, 97, 97, 97 ],
"note": "主方块后景2",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "cobblestone" ]
]
}
],
"parts": [
{
"name": "entrance",
"image": [ "entrance", "entrance_o1", "entrance_o2" ],
"type": "PT_START",
"hotX": 25,
"hotY": 25,
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "entrance2",
"image": [ "entrance2", "entrance2_o1" ],
"type": "PT_START",
"hotX": 25,
"hotY": 25,
"unlinkParts": [ "entrance2" ],
"weight": 10
},
{
"name": "entrance3",
"image": [ "entrance3", "entrance3_o1" ],
"type": "PT_START",
"hotX": 25,
"hotY": 25,
"unlinkParts": [ "entrance3" ],
"weight": 10
},
{
"name": "entrance4",
"image": [ "entrance4", "entrance4_o1" ],
"type": "PT_START",
"hotX": 25,
"hotY": 25,
"unlinkParts": [ "entrance4" ],
"weight": 10
}
]
}
}
================================================
FILE: buildings/under_tainted_cabin/under_tainted_cabin.json
================================================
{
"under_tainted_cabin": {
"maxGenPartCount": 2,
"limitSize": 50,
"mainRestraint": {
"checks": [
[ "IS_CENTER_Y_GREATER_OR_EQUAL_TO", 0 ]
]
},
"blockEntityFormat": {
"normal_reward": {
"formatId": "tc:common_rewards",
"data": {
"name": "normal_reward",
"rareGenCount": 1,
"rares": [
{
"itemId": "rocket_boost",
"count": 1
},
{
"itemId": "red_crystal",
"count": 2
},
{
"itemId": "blue_crystal",
"count": 2
},
{
"itemId": "white_crystal",
"count": 2
},
{
"itemId": "yellow_crystal",
"count": 2
},
{
"itemId": "red_crystal",
"count": 2
},
{
"itemId": "blue_crystal",
"count": 2
},
{
"itemId": "white_crystal",
"count": 2
},
{
"itemId": "yellow_crystal",
"count": 2
},
{
"itemId": "ender_mirror",
"count": 1
},
{
"itemId": "iron_sword",
"count": 1
},
{
"itemId": "iron_axe",
"count": 1
},
{
"itemId": "iron_pickaxe",
"count": 1
},
{
"itemId": "iron_helmet",
"count": 1
},
{
"itemId": "iron_chestplate",
"count": 1
},
{
"itemId": "iron_leggings",
"count": 1
},
{
"itemId": "iron_helmet",
"count": 1
},
{
"itemId": "copper_chestplate",
"count": 1
},
{
"itemId": "tin_leggings",
"count": 1
},
{
"itemId": "tin_chestplate",
"count": 1
},
{
"itemId": "tin_leggings",
"count": 1
},
{
"itemId": "ghost_sword",
"count": 1
}
],
"normals": [
{
"itemIds": [ "ender_pearl" ],
"rate": 0.3,
"min": 1,
"max": 2
},
{
"itemIds": [ "apple" ],
"rate": 0.3,
"min": 1,
"max": 3
},
{
"itemIds": [ "redstone" ],
"rate": 0.23,
"min": 4,
"max": 9
},
{
"itemIds": [ "golden_apple" ],
"rate": 0.20,
"min": 1,
"max": 1
},
{
"itemIds": [ "pumpkin_seed" ],
"rate": 0.18,
"min": 2,
"max": 4
},
{
"itemIds": [ "melon_seed" ],
"rate": 0.18,
"min": 2,
"max": 4
},
{
"itemIds": [ "iron_ingot", "copper_ingot", "tin_ingot", "lead_ingot" ],
"rate": 0.3,
"min": 1,
"max": 4
},
{
"itemIds": [ "gold_ingot", "silver_ingot", "bronze_ingot", "steel_ingot" ],
"rate": 0.1,
"min": 1,
"max": 3
},
{
"itemIds": [ "diamond" ],
"rate": 0.1,
"min": 1,
"max": 2
},
{
"itemIds": [ "emerald" ],
"rate": 0.1,
"min": 1,
"max": 3
}
]
}
}
},
"restraints": [
],
"commandColors": [
{
"color": [ 255, 64, 64, 64 ],
"note": "无操作",
"command": [
[ "BC_NO_OP" ]
]
},
{
"color": [ 255, 192, 192, 192 ],
"note": "前景记号"
},
{
"color": [ 255, 0, 0, 0 ],
"note": "空气",
"command": [
[ "BC_CLEAR_LAKE" ],
[ "BC_CLEAR" ]
]
},
{
"color": [ 255, 0, 64, 255 ],
"pipe": true
},
{
"color": [ 255, 0, 255, 255 ],
"pipe": true
},
{
"color": [ 255, 0, 160, 255 ],
"note": "箱子",
"command": [
[ "BC_PLACE_FURNITURE", "chest", 0, "normal_reward" ]
]
},
{
"color": [ 255, 130, 0, 0 ],
"note": "桶",
"command": [
[ "BC_PLACE_FURNITURE", "barrel", 0, "normal_reward" ]
]
},
{
"color": [ 255, 0, 200, 0 ],
"note": "罐子",
"command": [
[ "BC_PLACE_FURNITURE", "pot", 3 ]
]
},
{
"color": [ 255, 255, 255, 0 ],
"note": "火把",
"command": [
[ "BC_PLACE_FURNITURE", "torch", 0 ]
]
},
{
"color": [ 255, 102, 102, 204 ],
"note": "门",
"command": [
[ "BC_PLACE_FURNITURE", "wooden_door_tainted" ]
]
},
{
"color": [ 255, 255, 0, 255 ],
"note": "平台",
"command": [
[ "BC_PLACE_TILE", "platform_tainted" ]
]
},
{
"color": [ 255, 128, 64, 32 ],
"note": "熔炉",
"command": [
[ "BC_PLACE_FURNITURE", "furnace" ]
]
},
{
"color": [ 255, 255, 0, 0 ],
"note": "桌子",
"command": [
[ "BC_PLACE_FURNITURE", "table_tainted" ]
]
},
{
"color": [ 255, 128, 0, 0 ],
"note": "椅子",
"command": [
[ "BC_PLACE_FURNITURE", "chair_tainted", 1 ]
]
},
{
"color": [ 255, 160, 0, 0 ],
"note": "椅子",
"command": [
[ "BC_PLACE_FURNITURE", "chair_tainted", 0 ]
]
},
{
"color": [ 255, 0, 130, 0 ],
"note": "长凳",
"command": [
[ "BC_PLACE_FURNITURE", "bench_tainted" ]
]
},
{
"color": [ 255, 0, 128, 255 ],
"note": "床",
"command": [
[ "BC_PLACE_FURNITURE", "wooden_bed_red", 0 ]
]
},
{
"color": [ 255, 100, 100, 0 ],
"note": "书架",
"command": [
[ "BC_PLACE_FURNITURE", "bookcase_tainted", 0, "normal_reward" ]
]
},
{
"color": [ 255, 200, 200, 0 ],
"note": "桌柜",
"command": [
[ "BC_PLACE_FURNITURE", "cabinet_tainted", 0, "normal_reward" ]
]
},
{
"color": [ 255, 200, 200, 120 ],
"note": "蜡烛",
"command": [
[ "BC_PLACE_FURNITURE", "candle" ]
]
},
{
"color": [ 255, 0, 130, 130 ],
"note": "蜡烛台",
"command": [
[ "BC_PLACE_FURNITURE", "candle_holder" ]
]
},
{
"color": [ 255, 150, 0, 0 ],
"note": "缸",
"command": [
[ "BC_PLACE_FURNITURE", "cauldron" ]
]
},
{
"color": [ 255, 150, 150, 0 ],
"note": "水晶灯",
"command": [
[ "BC_PLACE_FURNITURE", "chandeliers" ]
]
},
{
"color": [ 255, 150, 150, 150 ],
"note": "蜘蛛网",
"command": [
[ "BC_PLACE_FURNITURE", "cobweb" ]
]
},
{
"color": [ 255, 150, 0, 150 ],
"note": "藤蔓",
"command": [
[ "BC_PLACE_FURNITURE", "tainted_vine" ]
]
},
{
"color": [ 255, 150, 255, 0 ],
"note": "树苗",
"command": [
[ "BC_PLACE_FURNITURE", "sapling_tainted" ]
]
},
{
"color": [ 255, 168, 168, 168 ],
"note": "主方块前景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "plank_tainted" ],
[ "BC_PLACE_TILE", "plank_tainted" ]
]
},
{
"color": [ 255, 114, 114, 114 ],
"note": "主方块后景",
"command": [
[ "BC_CLEAR" ],
[ "BC_PLACE_BACK", "wood_tainted" ]
]
}
],
"parts": [
{
"name": "entrance",
"image": [ "entrance", "entrance_o1", "entrance_o2" ],
"type": "PT_START",
"hotX": 25,
"hotY": 25,
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "entrance2",
"image": [ "entrance2", "entrance2_o1", "entrance2_o2" ],
"type": "PT_START",
"hotX": 25,
"hotY": 25,
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "entrance3",
"image": [ "entrance3", "entrance3_o1", "entrance3_o2" ],
"type": "PT_START",
"hotX": 25,
"hotY": 25,
"unlinkParts": [ "entrance" ],
"weight": 10
},
{
"name": "e1",
"image": [ "e1", "e1_o1", "e1_o2" ],
"type": "PT_END",
"unlinkParts": [],
"weight": 10
},
{
"name": "e2",
"image": [ "e2", "e2_o1", "e2_o2" ],
"type": "PT_END",
"unlinkParts": [],
"weight": 10
},
{
"name": "e3",
"image": [ "e3", "e3_o1" ],
"type": "PT_END",
"unlinkParts": [],
"weight": 10
},
{
"name": "e4",
"image": [ "e4", "e4_o1" ],
"type": "PT_END",
"unlinkParts": [],
"weight": 10
}
]
}
}
================================================
FILE: client/CameraInGame.lua
================================================
---@class TC.CameraInGame
local CameraInGame = class("CameraInGame")
local s_instance
---@return TC.CameraInGame
function CameraInGame.getInstance()
if s_instance == nil then
s_instance = CameraInGame.new()
end
return s_instance
end
function CameraInGame:__init()
---@type CameraComponentWrapper
self.camera = nil
end
function CameraInGame:setCamera(camera)
self.camera = camera
end
return CameraInGame
================================================
FILE: client/ControlAimMode.lua
================================================
local ControlAimMode = {
PressOnly = 0,
LookDirectionOrShoot = 1,
LookPositionOrUse = 2
}
return ControlAimMode
================================================
FILE: client/InputControl.lua
================================================
local ControlAimMode = require("client.ControlAimMode")
---@class TC.InputControl
local InputControl = class("InputControl")
local SettingsData = require("settings.SettingsData")
local s_instance
---@return TC.InputControl
function InputControl.getInstance()
if s_instance == nil then
s_instance = InputControl.new()
end
return s_instance
end
function InputControl:__init()
self.keyMap = {
left = Keys.A,
right = Keys.D,
up = Keys.W,
down = Keys.S,
jump = Keys.Space,
Drop = Keys.Q,
Backpack = Keys.E,
Task = Keys.F,
Nei = Keys.R,
Esc = Keys.Escape,
Ctrl = Keys.LeftControl,
Shift = Keys.LeftShift,
}
self.joystickKeyStates = {
left = false,
right = false,
up = false,
down = false,
jump = false,
}
self.operatingWall = false
self.isSmart = false
self.usingVirtualJoystick = false
---@type UIJoystick
self.virtualJoystickLeftNode = nil
---@type UIJoystick
self.virtualJoystickRightNode = nil
---@type UIJoystick
self.virtualJoystickCenterNode = nil
self.aimMode = ControlAimMode.PressOnly
self.aimAngle = 0
self.aimDistance = 0
self.aimInstanceClicked = false
self.aimPressing = false
self.aimTriggerUsing = false
self.isMapClicking = false
self.touchMapPosition = Vector2.new()
self._lastRightJoystickPressed = false
self._lastCenterJoystickPressed = false
self._lastWriteVirtualJoystickLeft = false
self._lastWriteVirtualJoystickRight = false
self.isPcMouseAtMap = false
self.pcMouseAtMapX = 0
self.pcMouseAtMapY = 0
self.pcMouseAtMapXi = 0
self.pcMouseAtMapYi = 0
self.pcMouseScrollDeltaY = 0
self.isPcMouseLeftInstantDown = false
self.isPcMouseLeftInstantDownAtMap = false
self.isPcMouseLeftPressing = false
self.isPcMouseLeftPressingAtMap = false
self.isPcMouseLeftInstantUp = false
self.isPcMouseLeftInstantUpAtMap = false
self.isPcMouseRightInstantDown = false
self.isPcMouseRightInstantDownAtMap = false
self.isPcMouseRightPressing = false
self.isPcMouseRightPressingAtMap = false
self.isPcMouseRightInstantUp = false
self.isPcMouseRightInstantUpAtMap = false
self._pressingKeys = {}
self._instantPressedKeys = {}
for k, _ in pairs(self.keyMap) do
self._pressingKeys[k] = false
self._instantPressedKeys[k] = false
end
Input.mouse:addScrollListener({ InputControl._onMouseScroll, self })
end
function InputControl:_onMouseScroll(_, deltaY)
if deltaY == 0 then
return
end
self.pcMouseScrollDeltaY = deltaY
end
function InputControl.isPressing(keyName)
local instance = InputControl.getInstance()
local key = instance.keyMap[keyName]
if key ~= nil then
if Input.keyboard:isKeyPressed(key) then
return true
end
end
local joystickState = instance.joystickKeyStates[keyName]
if joystickState ~= nil then
return joystickState
end
return false
end
function InputControl.isInstantPressing(keyName)
local instance = InputControl.getInstance()
return instance._instantPressedKeys[keyName] == true
end
function InputControl.isNumKeyPressing(num)
return Input.keyboard:isKeyPressed(Keys.D0 + num)
end
function InputControl.getCurrentPressingKeyNum()
for i = 0, 9 do
if InputControl.isNumKeyPressing(i) then
return i
end
end
return -1
end
function InputControl:updateMovementByAxis(x, y)
self.joystickKeyStates.left = x < -0.3
self.joystickKeyStates.right = x > 0.3
self.joystickKeyStates.up = y < -0.3
self.joystickKeyStates.down = y > 0.3
self.joystickKeyStates.jump = self.joystickKeyStates.up
end
function InputControl:update()
self.joystickKeyStates.left = false
self.joystickKeyStates.right = false
self.joystickKeyStates.up = false
self.joystickKeyStates.down = false
self.joystickKeyStates.jump = false
self.aimPressing = false
self.aimInstanceClicked = false
self.aimTriggerUsing = false
self.isPcMouseLeftInstantUp = false
self.isPcMouseLeftInstantDown = false
self.isPcMouseLeftInstantDownAtMap = false
self.isPcMouseRightInstantUp = false
self.isPcMouseRightInstantDown = false
self.isPcMouseRightInstantDownAtMap = false
self.pcMouseAtMapX = 0
self.pcMouseAtMapY = 0
self.pcMouseAtMapXi = 0
self.pcMouseAtMapYi = 0
local checkMovingByVirtualJoystick = false
local checkAimingByVirtualJoystick = false
for k, v in pairs(self.keyMap) do
self._instantPressedKeys[k] = false
local pressed = Input.keyboard:isKeyPressed(v)
if pressed and not self._pressingKeys[k] then
self._pressingKeys[k] = true
self._instantPressedKeys[k] = true
elseif not pressed and self._pressingKeys[k] then
self._pressingKeys[k] = false
end
end
if SettingsData.isMobileOperation then
self.usingVirtualJoystick = (self.virtualJoystickCenterNode ~= nil)
if self.usingVirtualJoystick then
self.virtualJoystickCenterNode.visible = self.aimMode == ControlAimMode.LookPositionOrUse
-- movement
if self.virtualJoystickLeftNode.isTouching then
local u, d, l, r = self.virtualJoystickLeftNode:getControlledFourDirection()
if u or d or l or r then
self.joystickKeyStates.left = l
self.joystickKeyStates.right = r
self.joystickKeyStates.up = u
self.joystickKeyStates.down = d
self.joystickKeyStates.jump = u
checkMovingByVirtualJoystick = true
end
end
-- aim
if self.virtualJoystickRightNode.isTouching then
local angle = self.virtualJoystickRightNode.controlledAngle
local distance = self.virtualJoystickRightNode.controlledDistanceRate
self.aimAngle = angle
self.aimDistance = distance
if not self._lastRightJoystickPressed then
self.aimInstanceClicked = true
end
self.aimPressing = true
if self.aimMode == ControlAimMode.LookDirectionOrShoot then
if self.aimDistance > 0.5 then
self.aimTriggerUsing = true
end
else
self.aimTriggerUsing = true
end
checkAimingByVirtualJoystick = true
end
if self.aimMode == ControlAimMode.LookPositionOrUse then
if self.virtualJoystickCenterNode.isTouching then
local angle = self.virtualJoystickCenterNode.controlledAngle
local distance = self.virtualJoystickCenterNode.controlledDistanceRate
self.aimAngle = angle
self.aimDistance = distance
if not self._lastCenterJoystickPressed then
self.aimInstanceClicked = true
end
self.aimPressing = true
checkAimingByVirtualJoystick = true
end
self._lastCenterJoystickPressed = self.virtualJoystickCenterNode.isTouching
else
self._lastCenterJoystickPressed = false
end
end
else
self.usingVirtualJoystick = false
-- PC Mouse + Keyboard.
self.operatingWall = InputControl.isPressing("Shift")
local nPos = Input.mouse.position
nPos.x = nPos.x / GameWindow.displayResolution.width
nPos.y = nPos.y / GameWindow.displayResolution.height
self.pcMouseAtMapX = MiscUtils.screenX + MiscUtils.screenWidth * nPos.x
self.pcMouseAtMapY = MiscUtils.screenY + MiscUtils.screenHeight * nPos.y
self.pcMouseAtMapXi = Utils.Cell(self.pcMouseAtMapX)
self.pcMouseAtMapYi = Utils.Cell(self.pcMouseAtMapY)
local lp = Input.mouse.isLeftButtonPressed
if self.isPcMouseLeftPressing and not lp then
self.isPcMouseLeftInstantUp = true
elseif not self.isPcMouseLeftPressing and lp then
self.isPcMouseLeftInstantDown = true
if self.isPcMouseAtMap then
self.isPcMouseLeftInstantDownAtMap = true
self.isPcMouseLeftPressingAtMap = true
end
end
self.isPcMouseLeftPressing = lp
if not lp then
self.isPcMouseLeftPressingAtMap = false
end
local rp = Input.mouse.isRightButtonPressed
if self.isPcMouseRightPressing and not rp then
self.isPcMouseRightInstantUp = true
elseif not self.isPcMouseRightPressing and rp then
self.isPcMouseRightInstantDown = true
if self.isPcMouseAtMap then
self.isPcMouseRightInstantDownAtMap = true
self.isPcMouseRightPressingAtMap = true
end
end
self.isPcMouseRightPressing = rp
if not rp then
self.isPcMouseRightPressingAtMap = false
end
end
if Input.joystick[1].isConnected then
local leftPress = false
local rightPress = false
if not checkMovingByVirtualJoystick then
local x, y = Input.joystick[1]:getAxis(0), Input.joystick[1]:getAxis(1)
if not (math.abs(x) < 0.001 and math.abs(y) < 0.001) then
leftPress = true
self:updateMovementByAxis(x, y)
if self.usingVirtualJoystick then
self.virtualJoystickLeftNode:setControl(x, y)
if not self._lastWriteVirtualJoystickLeft then
self.virtualJoystickLeftNode.controlledCenter = Vector2.new(
self.virtualJoystickLeftNode.width / 2 + math.random(-20, 30),
self.virtualJoystickLeftNode.height / 2 + math.random(-30, 30))
end
end
else
if self.usingVirtualJoystick then
self.virtualJoystickLeftNode:setControl(0, 0)
end
end
end
if not checkAimingByVirtualJoystick then
local x, y = Input.joystick[1]:getAxis(2), Input.joystick[1]:getAxis(3)
if not (math.abs(x) < 0.001 and math.abs(y) < 0.001) then
rightPress = true
local tempVec = Vector2.new(x, y)
self.aimAngle = tempVec.angle
self.aimDistance = tempVec.length
if not self._lastRightJoystickPressed then
self.aimInstanceClicked = true
end
self.aimPressing = true
self.aimTriggerUsing = true
if self.usingVirtualJoystick then
self.virtualJoystickRightNode:setControl(x, y)
if not self._lastWriteVirtualJoystickRight then
self.virtualJoystickRightNode.controlledCenter = Vector2.new(
self.virtualJoystickRightNode.width / 2 + math.random(-20, 30),
self.virtualJoystickRightNode.height / 2 + math.random(-30, 30))
end
end
else
if self.usingVirtualJoystick then
self.virtualJoystickRightNode:setControl(0, 0)
end
end
end
self._lastWriteVirtualJoystickLeft = leftPress
self._lastWriteVirtualJoystickRight = rightPress
end
self._lastRightJoystickPressed = self.aimPressing
end
return InputControl
================================================
FILE: client/MenuJoinInfo.lua
================================================
---@class TC.MenuJoinInfo
local MenuJoinInfo = class("MenuJoinData")
local s_instance
---@return TC.MenuJoinInfo
function MenuJoinInfo.getInstance()
if s_instance == nil then
s_instance = MenuJoinInfo.new()
end
return s_instance
end
function MenuJoinInfo:__init()
self.playerInfo = {
name = ""
}
self.worldInfo = {
name = ""
}
self.serverInfo = {
address = "",
port = 0,
isMultiplayer = false
}
end
function MenuJoinInfo:getData()
local joinData = JoinData.new()
joinData.playerName = self.playerInfo.name
joinData.worldName = self.worldInfo.name
joinData.multiplayer = self.serverInfo.isMultiplayer
joinData.address = self.serverInfo.address
joinData.port = self.serverInfo.port
return joinData
end
return MenuJoinInfo
================================================
FILE: client/ModClient.lua
================================================
local ModClient = class("ModClient")
local MusicPool = require("MusicPool")
local MusicSystem = require("MusicSystem")
local UIManager = require("ui.UIManager")
local InputControl = require("InputControl")
local CameraInGame = require("CameraInGame")
local ModTextures = require("mod_textures.ModTextures")
local RecordData = require("record.RecordData")
--- the constructor of this class
function ModClient:__init()
self._cameraGameObject = nil
-- the menu background element renderer
self._hudUI = nil
self._pendingUI = nil
self._lastState = nil
self._stateBeginProxies = {
[ClientState.InMenu] = self.beginInMenu,
[ClientState.Joining] = self.beginJoining,
[ClientState.Gaming] = self.beginGaming,
[ClientState.SavingWorld] = self.beginSavingWorld,
[ClientState.LosingConnection] = self.beginSavingWorld,
}
self._stateEndProxies = {
[ClientState.LoadingWorld] = self.endLoadingWorld,
[ClientState.Gaming] = self.endGaming,
[ClientState.SavingWorld] = self.endSavingWorld,
[ClientState.LosingConnection] = self.endSavingWorld,
}
self._stateUpdateProxies = {
[ClientState.InMenu] = self.updateInMenu,
[ClientState.Joining] = self.updateJoining,
[ClientState.Gaming] = self.updateGaming,
}
self._stateRenderProxies = {
[ClientState.InMenu] = self.renderInMenu,
[ClientState.Gaming] = self.renderGaming,
}
self._testTime = 0
end
function ModClient:init()
FontManager.load(Path.join(Mod.current.assetRootPath, "font/msyhbd.ttf"), "msyhbd")
require("languages.LocaleHelper").reload(require("languages.Locale"))
require("settings.Settings").loadData()
-- create the main camera
self._cameraGameObject = GameObject.instantiate()
self._cameraGameObject.camera:init()
CameraInGame.getInstance():setCamera(self._cameraGameObject.camera)
MusicPool.getInstance():initModMusicResources(Mod.GetByID("tc_music"), "music")
MusicSystem.getInstance():registerFromProxy()
ModTextures.getInstance()
UIManager.getInstance():init()
UIManager.getInstance():initUISpriteResources(Mod.current, "ui_res")
UIManager.getInstance():initUISpriteResources(Mod.current, "ui_res_large")
UIManager.getInstance():postInit()
end
function ModClient:start()
end
function ModClient:beginInMenu()
require("ui.StartUI").new()
MusicSystem.getInstance():switchToScene("tc:menu")
end
function ModClient:preUpdate()
InputControl.getInstance():update()
self._cameraGameObject.transform.position = Vector3.new(MiscUtils.screenX, MiscUtils.screenY, 0)
end
function ModClient:update()
-- check end
if self._lastState ~= nil and self._lastState ~= ClientState.current then
print("end game state:", self._lastState, " -> ", ClientState.current)
local proxy = self._stateEndProxies[self._lastState]
if proxy then
proxy(self)
end
end
-- check begin
if self._lastState ~= ClientState.current then
self._lastState = ClientState.current
print("begin game state:", self._lastState)
local proxy = self._stateBeginProxies[ClientState.current]
if proxy then
proxy(self)
end
end
-- check update
local proxy = self._stateUpdateProxies[ClientState.current]
if proxy then
proxy(self)
end
UIManager.getInstance():update()
MusicSystem.getInstance():update()
end
function ModClient:render()
local proxy = self._stateRenderProxies[ClientState.current]
if proxy then
proxy(self)
end
UIManager.getInstance():render()
end
function ModClient:exit()
end
function ModClient:updateInMenu()
end
function ModClient:renderInMenu()
end
function ModClient:beginGaming()
local HudUI = require("ui.hud.HudUI")
self._hudUI = HudUI.new()
end
function ModClient:endGaming()
self._hudUI:closeWindow()
self._hudUI = nil
end
function ModClient:updateGaming()
self._hudUI:update()
MusicSystem.getInstance():updateGaming()
RecordData.getInstance():update()
end
function ModClient:renderGaming()
end
function ModClient:beginJoining()
local PendingUI = require("ui.PendingUI")
self._pendingUI = PendingUI.new()
end
function ModClient:updateJoining()
end
function ModClient:endLoadingWorld()
self._pendingUI:closeWindow()
self._pendingUI = nil
end
function ModClient:beginSavingWorld()
local PendingUI = require("ui.PendingUI")
self._pendingUI = PendingUI.new()
end
function ModClient:endSavingWorld()
self._pendingUI:closeWindow()
self._pendingUI = nil
end
return ModClient
================================================
FILE: client/ModMusicSceneProxy.lua
================================================
---@class TC.ModMusicSceneProxy
local ModMusicSceneProxy = class("ModMusicSceneProxy")
---@type TC.ModMusicSceneProxy[]
local s_proxy = {}
---__init
---@param proxy TC.MusicSceneProxy
function ModMusicSceneProxy:__init(proxy)
self._proxy = proxy
end
function ModMusicSceneProxy.getProxy()
return s_proxy
end
function ModMusicSceneProxy.register(modProxyClass)
table.insert(s_proxy, modProxyClass)
end
function ModMusicSceneProxy:onRegisterAllScenes()
end
return ModMusicSceneProxy
================================================
FILE: client/MusicCopyright.lua
================================================
local MusicCopyright = {}
MusicCopyright["tc:menu1"] = {
title = "menu1",
author = "author1",
}
MusicCopyright["tc:menu2"] = {
title = "menu2",
author = "author2",
}
MusicCopyright["tc:unfinished"] = {
title = "unfinished",
author = "author3",
}
return MusicCopyright
================================================
FILE: client/MusicPool.lua
================================================
---@class TC.MusicPool
local MusicPool = class("MusicPool")
---@class TC.MusicPoolElement
local MusicPoolElement = class("MusicPoolElement")
function MusicPoolElement:__init(musicAssetPath)
self.musicID = 0
self.musicAssetPath = musicAssetPath
end
local s_instance
---@return TC.MusicPool
function MusicPool.getInstance()
if s_instance == nil then
s_instance = MusicPool.new()
end
return s_instance
end
function MusicPool:__init()
self._elements = {}
end
---initModMusicResources
---@param mod Mod
---@param dirPathInMod string
function MusicPool:initModMusicResources(mod, dirPathInMod)
local searchPath = Path.join(mod.assetRootPath, dirPathInMod)
local musicNameMP3s = AssetManager.getAllFiles(searchPath, ".mp3",
true, false, true)
local musicNameOGGs = AssetManager.getAllFiles(searchPath, ".ogg",
true, false, true)
for _, musicName in ipairs(musicNameMP3s) do
local name = mod.modId .. ":" .. musicName
--print(name)
self._elements[name] = MusicPoolElement.new(Path.join(searchPath, musicName .. ".mp3"))
end
for _, musicName in ipairs(musicNameOGGs) do
local name = mod.modId .. ":" .. musicName
--print(name)
self._elements[name] = MusicPoolElement.new(Path.join(searchPath, musicName .. ".ogg"))
end
end
function MusicPool:getIDAndActivateMusic(musicName)
local element = self._elements[musicName]
if element == nil then
print("MusicPool:getIDAndActivateMusic failed:", musicName)
assert(false)
end
if element.musicID == 0 then
local bytes = AssetManager.readAsBytes(element.musicAssetPath)
element.musicID = Audio.loadMusicEffectFromMemory(bytes, 0, bytes.count)
end
return element.musicID
end
function MusicPool:recycleAndEnsureMusicMemory(ensureMusicNames)
local ensureNameDict = {}
for _, name in ipairs(ensureMusicNames) do
ensureNameDict[name] = true
end
-- unload all music if not ensured
---@param element TC.MusicPoolElement
for name, element in pairs(self._elements) do
if ensureNameDict[name] == nil then
if element.musicID ~= 0 then
Audio.unloadMusicEffectByID(element.musicID)
element.musicID = 0
end
end
end
-- load all music if ensured
for name, _ in pairs(ensureNameDict) do
---@type TC.MusicPoolElement
local element = self._elements[name]
if element.musicID == 0 then
local bytes = AssetManager.readAsBytes(element.musicAssetPath)
element.musicID = Audio.loadMusicEffectFromMemory(bytes, 0, bytes.count)
end
end
end
return MusicPool
================================================
FILE: client/MusicScene.lua
================================================
---@class TC.MusicScene
local MusicScene = class("MusicScene")
local Algorithm = require("util.Algorithm")
---__init
---@param musicList
---@param fadeInTime int
---@param fadeOutTime int
---@param interval int
---@param intervalRandOffset int
function MusicScene:__init(musicList, fadeInTime, fadeOutTime, interval, intervalRandOffset)
self.musicList = musicList
self.fadeInTime = fadeInTime
self.fadeOutTime = fadeOutTime
self.interval = interval
self.intervalRandOffset = intervalRandOffset
end
function MusicScene:doRandomList()
Algorithm.Shuffle(self.musicList)
end
return MusicScene
================================================
FILE: client/MusicSceneProxy.lua
================================================
---@class TC.MusicSceneProxy
local MusicSceneProxy = class("MusicSceneProxy")
local ModMusicSceneProxy = require("ModMusicSceneProxy")
local s_instance
---@return TC.MusicSceneProxy
function MusicSceneProxy.getInstance()
if s_instance == nil then
s_instance = MusicSceneProxy.new()
end
return s_instance
end
function MusicSceneProxy:__init()
self.proxy = {}
self.biomeProxy = {}
self.bossProxy = {}
end
function MusicSceneProxy:register(name, data)
self.proxy[name] = data
end
function MusicSceneProxy:registerAll()
self:register("tc:menu", {
musicList = {
"tc_music:unfinished",
"tc_music:menu1",
"tc_music:menu2",
},
fadeInTime = 5000,
fadeOutTime = 1000,
interval = 2000,
intervalRandOffset = 100,
})
self:register("tc:forest", {
musicList = {
"tc_music:overworld",
"tc_music:day2",
"tc_music:day3",
"tc_music:day4",
"tc_music:mc_aria_math",
"tc_music:mc_blind_spots",
"tc_music:mc_haunt_muskie",
"tc_music:mc_chris",
},
fadeInTime = 5000,
fadeOutTime = 3000,
interval = 2000,
intervalRandOffset = 100,
})
self:register("tc:night", {
musicList = {
"tc_music:night1",
"tc_music:night2",
"tc_music:night3",
"tc_music:night4",
},
fadeInTime = 5000,
fadeOutTime = 3000,
interval = 12000,
intervalRandOffset = 10000,
})
self:register("tc:snow", {
musicList = {
"tc_music:mc_snow",
},
fadeInTime = 5000,
fadeOutTime = 3000,
interval = 2000,
intervalRandOffset = 100,
})
self:register("tc:tainted", {
musicList = {
"tc_music:cr_deep_freeze",
},
fadeInTime = 5000,
fadeOutTime = 3000,
interval = 2000,
intervalRandOffset = 100,
})
self:register("tc:flesh", {
musicList = {
"tc_music:cr_dark_drifting",
},
fadeInTime = 5000,
fadeOutTime = 3000,
interval = 2000,
intervalRandOffset = 100,
})
self:register("tc:jungle", {
musicList = {
"tc_music:mc_aria_math",
"tc_music:mc_blind_spots",
"tc_music:mc_haunt_muskie",
"tc_music:mc_chris",
},
fadeInTime = 5000,
fadeOutTime = 3000,
interval = 32000,
intervalRandOffset = 16000,
})
self:register("tc:cave", {
musicList = {
"tc_music:mcunder1",
"tc_music:mcunder2",
"tc_music:mcunder3",
"tc_music:mcunder4",
},
fadeInTime = 5000,
fadeOutTime = 3000,
interval = 8000,
intervalRandOffset = 100,
})
self:register("tc:mushroom_cave", {
musicList = {
"tc_music:cr_star_trails",
},
fadeInTime = 3000,
fadeOutTime = 3000,
interval = 1000,
intervalRandOffset = 100,
})
self:register("tc:lava", {
musicList = {
"tc_music:cr_calamity_of_dread",
},
fadeInTime = 5000,
fadeOutTime = 3000,
interval = 8000,
intervalRandOffset = 100,
})
self:register("tc:ice_cave", {
musicList = {
"tc_music:cr_snow_delta",
},
fadeInTime = 5000,
fadeOutTime = 3000,
interval = 8000,
intervalRandOffset = 100,
})
self:register("tc:nether", {
musicList = {
"tc_music:mcnether1",
},
fadeInTime = 5000,
fadeOutTime = 3000,
interval = 2000,
intervalRandOffset = 100,
})
self:register("tc:boss", {
musicList = {
"tc_music:boss",
},
fadeInTime = 100,
fadeOutTime = 1000,
interval = 100,
intervalRandOffset = 100,
})
self:registerBiomeScene("tc:Surface", "tc:forest", "day", "tc:forest")
self:registerBiomeScene("tc:Surface", "tc:forest", "night", "tc:night")
self:registerBiomeScene("tc:Surface", "tc:soft_snow_land", "day", "tc:snow")
self:registerBiomeScene("tc:Surface", "tc:soft_snow_land", "night", "tc:night")
self:registerBiomeScene("tc:Surface", "tc:snow_land", "day", "tc:snow")
self:registerBiomeScene("tc:Surface", "tc:snow_land", "night", "tc:night")
self:registerBiomeScene("tc:Surface", "tc:tainted_land", "day", "tc:tainted")
self:registerBiomeScene("tc:Surface", "tc:tainted_land", "night", "tc:tainted")
self:registerBiomeScene("tc:Surface", "tc:flesh", "day", "tc:flesh")
self:registerBiomeScene("tc:Surface", "tc:flesh", "night", "tc:flesh")
self:registerBiomeScene("tc:Surface", "tc:jungle", "day", "tc:jungle")
self:registerBiomeScene("tc:Surface", "tc:super_volcano", "day", "tc:lava")
self:registerBiomeScene("tc:Surface", "tc:super_volcano", "night", "tc:lava")
self:registerBiomeScene("tc:Underground", "tc:deep_ice_cave", "default", "tc:ice_cave")
self:registerBiomeScene("tc:Underground", "tc:blue_mushroom_cave", "default", "tc:mushroom_cave")
self:registerBiomeScene("tc:Underground", "tc:flesh_cave", "default", "tc:flesh")
self:registerBiomeScene("tc:Underground", "tc:tainted_cave", "default", "tc:tainted")
self:registerBiomeScene("tc:Nether", "tc:nether", "default", "tc:nether")
self:registerBossScene("tc:snow_queen", "tc:boss")
self:registerBossScene("tc:worm_head", "tc:boss")
self:registerBossScene("tc:crison_eye", "tc:boss")
self:registerBossScene("tc:dungeon_eater_head", "tc:boss")
---@type TC.ModMusicSceneProxy[]
local modProxies = {}
for _, c in ipairs(ModMusicSceneProxy.getProxy()) do
table.insert(modProxies, c.new(self))
end
for _, p in ipairs(modProxies) do
p:onRegisterAllScenes()
end
end
function MusicSceneProxy:registerBossScene(bossIDName, musicSceneName)
local bossID = Reg.NpcID(bossIDName)
self.bossProxy[bossID] = musicSceneName
end
function MusicSceneProxy:tryGetBossSceneName(bossID)
return self.bossProxy[bossID]
end
---registerBiomeScene
---@param biomeTypeName string
---@param biomeIDName string
---@param style string
---@param musicSceneName string
function MusicSceneProxy:registerBiomeScene(biomeTypeName, biomeIDName, style, musicSceneName)
local biomeType = Reg.BiomeTypeID(biomeTypeName)
local biomeID = Reg.BiomeID(biomeIDName)
if self.biomeProxy[biomeType] == nil then
self.biomeProxy[biomeType] = {}
end
if self.biomeProxy[biomeType][biomeID] == nil then
self.biomeProxy[biomeType][biomeID] = {}
end
self.biomeProxy[biomeType][biomeID][style] = musicSceneName
end
---tryGetBiomeSceneName
---@param biomeType int
---@param biomeID int
---@param style string
function MusicSceneProxy:tryGetBiomeSceneName(biomeType, biomeID, style)
local biomeTypeProxy = self.biomeProxy[biomeType]
if biomeTypeProxy == nil then
return nil
end
local biomeIDProxy = biomeTypeProxy[biomeID]
if biomeIDProxy == nil then
return nil
end
return biomeIDProxy[style]
end
return MusicSceneProxy
================================================
FILE: client/MusicSystem.lua
================================================
---@class TC.MusicSystem
local MusicSystem = class("MusicSystem")
local MusicScene = require("MusicScene")
local MusicPool = require("MusicPool")
local MusicSceneProxy = require("MusicSceneProxy")
local SettingsData = require("settings.SettingsData")
local RecordData = require("record.RecordData")
local BIOME_TYPE_SURFACE = Reg.BiomeTypeID("tc:Surface")
local BIOME_TYPE_UNDERGROUND = Reg.BiomeTypeID("tc:Underground")
local BIOME_TYPE_NETHER = Reg.BiomeTypeID("tc:Nether")
local s_instance
local COPYRIGHT_DISPLAY_SECONDS = 4
---@return TC.MusicSystem
function MusicSystem.getInstance()
if s_instance == nil then
s_instance = MusicSystem.new()
end
return s_instance
end
function MusicSystem:__init()
self.musicScenes = {}
self.currentMusicScene = nil ---@type TC.MusicScene
self.currentMusicSceneName = nil
self.nextMusicSceneName = nil
self.lastMusicSceneNameForContinue = nil
self.lastMusicIndexForContinue = 1
self.lastMusicTimeForContinue = 0
self.usingLastMusicScene = false
self.usingLastMusicIndex = 1
self.usingLastMusicTime = 0
self.nextMusicPendingTime = 0
self.isNextMusicPending = false
self.musicIndexInList = 1
self.test = 0
self.lastBossID = -1
self.lastBiomeType = -1
self.lastBiomeID = -1
self.lastIsNight = false
self.playingTime = 0
self._lastSoundVolumePercent = 100
self._lastMusicVolumePercent = 100
self.musicCopyright = nil
self.musicCopyrightTick = 0
Audio.addMusicFinishedListener({ MusicSystem._onMusicFinished, self })
end
function MusicSystem:_onMusicFinished()
self.playingTime = 0
if self.nextMusicSceneName ~= nil then
self.currentMusicScene = self.musicScenes[self.nextMusicSceneName]
self.currentMusicSceneName = self.nextMusicSceneName
self.nextMusicSceneName = nil
local offsetTime = 0
if self.usingLastMusicScene ~= nil then
self.musicIndexInList = self.usingLastMusicIndex
offsetTime = self.usingLastMusicTime
else
self.musicIndexInList = 1
self.currentMusicScene:doRandomList()
end
self:_playCurrentMusic(offsetTime)
else
self.isNextMusicPending = true
self.nextMusicPendingTime = self.currentMusicScene.interval + math.random(self.currentMusicScene.intervalRandOffset)
end
end
function MusicSystem:update()
if self._lastMusicVolumePercent ~= SettingsData.musicVolume then
self._lastMusicVolumePercent = SettingsData.musicVolume
Audio.setMusicVolume(self._lastMusicVolumePercent / 100.0)
end
if self._lastSoundVolumePercent ~= SettingsData.soundVolume then
self._lastSoundVolumePercent = SettingsData.soundVolume
Audio.setAllSoundEffectVolume(self._lastSoundVolumePercent / 100.0)
end
if self.isNextMusicPending then
if self.nextMusicPendingTime > 0 then
self.nextMusicPendingTime = self.nextMusicPendingTime - Time.deltaTime * 1000
end
if self.nextMusicPendingTime <= 0 then
self.isNextMusicPending = false
self.nextMusicPendingTime = 0
self.musicIndexInList = self.musicIndexInList + 1
if self.musicIndexInList > #self.currentMusicScene.musicList then
self.musicIndexInList = 1
end
self:_playCurrentMusic()
end
end
self.test = self.test + 1
if self.test == 60 * 10 then
--self:switchToScene("tc:forest")
end
if Audio.isMusicPlaying() then
self.playingTime = self.playingTime + Time.deltaTime
else
self.playingTime = 0
end
if self.musicCopyrightTick > 0 then
self.musicCopyrightTick = self.musicCopyrightTick - 1
if self.musicCopyrightTick == 0 then
self.musicCopyright = nil
end
end
end
function MusicSystem:updateGaming()
local player = PlayerUtils.GetCurrentClientPlayer()
if player == nil then
return
end
local biomeType = player.biomeType
local biomeID = player.biomeID
local isNight = MiscUtils.isNight
local bossID = RecordData.getInstance().curBossID
local playingBossMusic = false
if self.lastBossID ~= bossID then
self.lastBossID = bossID
if bossID > 0 then
local name = MusicSceneProxy.getInstance():tryGetBossSceneName(bossID)
if name ~= nil then
self:switchToScene(name)
end
end
end
if self.lastBossID > 0 then
playingBossMusic = true
self.lastBiomeType = -1
self.lastBiomeID = -1
end
if not playingBossMusic then
if self.lastBiomeType ~= biomeType or self.lastBiomeID ~= biomeID or self.lastIsNight ~= isNight then
self.lastBiomeType = biomeType
self.lastBiomeID = biomeID
self.lastIsNight = isNight
if biomeType == BIOME_TYPE_SURFACE then
if not isNight then
local name = MusicSceneProxy.getInstance():tryGetBiomeSceneName(biomeType, biomeID, "day")
if name ~= nil then
self:switchToScene(name)
else
name = MusicSceneProxy.getInstance():tryGetBiomeSceneName(biomeType, Reg.BiomeID("tc:forest"), "day")
self:switchToScene(name)
end
else
local name = MusicSceneProxy.getInstance():tryGetBiomeSceneName(biomeType, biomeID, "night")
if name ~= nil then
self:switchToScene(name)
else
name = MusicSceneProxy.getInstance():tryGetBiomeSceneName(biomeType, Reg.BiomeID("tc:forest"), "night")
self:switchToScene(name)
end
end
elseif biomeType == BIOME_TYPE_UNDERGROUND then
local name = MusicSceneProxy.getInstance():tryGetBiomeSceneName(biomeType, biomeID, "default")
if name ~= nil then
self:switchToScene(name)
else
self:switchToScene("tc:cave")
end
elseif biomeType == BIOME_TYPE_NETHER then
local name = MusicSceneProxy.getInstance():tryGetBiomeSceneName(biomeType, biomeID, "default")
if name ~= nil then
self:switchToScene(name)
else
self:switchToScene("tc:nether")
end
end
end
end
end
function MusicSystem:_playCurrentMusic(offsetTime)
if offsetTime == nil then
offsetTime = 0
end
if #self.currentMusicScene.musicList > 0 then
local name = self.currentMusicScene.musicList[self.musicIndexInList]
local musicID = MusicPool.getInstance():getIDAndActivateMusic(name)
Audio.playMusic(musicID, 1, self.currentMusicScene.fadeInTime, offsetTime * 1000)
local MusicCopyright = require("MusicCopyright")
if MusicCopyright[name] ~= nil then
self.musicCopyright = MusicCopyright[name]
self.musicCopyrightTick = 60 * COPYRIGHT_DISPLAY_SECONDS
else
self.musicCopyright = MusicCopyright['tc:unfinished']
self.musicCopyrightTick = 60 * COPYRIGHT_DISPLAY_SECONDS
end
end
end
function MusicSystem:switchToScene(sceneName)
local scene = self.musicScenes[sceneName] ---@type TC.MusicScene
if scene == nil then
return
end
print("Play Music Scene:", sceneName)
if self.currentMusicSceneName == nil then
self.currentMusicSceneName = sceneName
self.currentMusicScene = scene
self.musicIndexInList = 1
self.currentMusicScene:doRandomList()
self:_playCurrentMusic()
else
if sceneName == self.currentMusicSceneName then
return
end
if self.lastMusicSceneNameForContinue ~= nil and sceneName == self.lastMusicSceneNameForContinue then
self.usingLastMusicScene = self.lastMusicSceneNameForContinue
self.usingLastMusicIndex = self.lastMusicIndexForContinue
self.usingLastMusicTime = self.lastMusicTimeForContinue
else
self.usingLastMusicScene = nil
self.usingLastMusicIndex = 1
self.usingLastMusicTime = 0
scene:doRandomList()
end
self.lastMusicSceneNameForContinue = self.currentMusicSceneName
self.lastMusicIndexForContinue = self.musicIndexInList
self.lastMusicTimeForContinue = self.playingTime
self.nextMusicSceneName = sceneName
Audio.stopMusic(self.currentMusicScene.fadeOutTime)
end
end
function MusicSystem:playCurrentMusicSceneImmediately()
if self.currentMusicScene == nil then
return
end
end
function MusicSystem:registerFromProxy()
local Proxy = require("MusicSceneProxy")
for name, data in pairs(Proxy.getInstance().proxy) do
local musicList = {}
local fadeInTime = 0
local fadeOutTime = 0
local interval = 0
local intervalRandOffset = 0
if data.musicList ~= nil then
musicList = data.musicList
end
if data.fadeInTime ~= nil then
fadeInTime = data.fadeInTime
end
if data.fadeOutTime ~= nil then
fadeOutTime = data.fadeOutTime
end
if data.interval ~= nil then
interval = data.interval
end
if data.intervalRandOffset ~= nil then
intervalRandOffset = data.intervalRandOffset
end
self.musicScenes[name] = MusicScene.new(
musicList,
fadeInTime,
fadeOutTime,
interval,
intervalRandOffset
)
end
end
return MusicSystem
================================================
FILE: constants/Constants.lua
================================================
local Constants = {
PLAYER_MAX_MAX_HEALTH = 400,
PLAYER_MAX_MAX_MANA = 1000,
}
return Constants
================================================
FILE: contents/IGNORE_THIS_FOLDER.txt
================================================
================================================
FILE: contents/commands/admin.json
================================================
{
"admin": {
"isClient": false,
"fromPlayer": false,
"gameMode": "creative",
"op": "master",
"parameters": [
{
"type": "CP_PLAYER"
}
],
"script": {
"path": "admin.lua"
}
}
}
================================================
FILE: contents/commands/admin.lua
================================================
function RunCommand(sourceCmd, player)
player:SetOP(OP_ADMIN)
player:SetGameMode(GAME_MODE_CREATIVE)
sourceCmd:ResponseUTF8(string.format(LangUtils.ModText("admin_ok"), player.name))
end
================================================
FILE: contents/commands/autosave-off.json
================================================
{
"autosave-off": {
"isClient": false,
"fromPlayer": false,
"gameMode": "creative",
"op": "admin",
"parameters": [],
"script": {
"path": "autosaveoff.lua"
}
}
}
================================================
FILE: contents/commands/autosave-on.json
================================================
{
"autosave-on": {
"isClient": false,
"fromPlayer": false,
"gameMode": "creative",
"op": "admin",
"parameters": [],
"script": {
"path": "autosaveon.lua"
}
}
}
================================================
FILE: contents/commands/autosaveoff.lua
================================================
function RunCommand(sourceCmd)
MiscUtils.SetAutoSaveEnabled(false)
sourceCmd:ResponseUTF8(string.format(LangUtils.ModText("autosave_off_ok")))
end
================================================
FILE: contents/commands/autosaveon.lua
================================================
function RunCommand(sourceCmd)
MiscUtils.SetAutoSaveEnabled(true)
sourceCmd:ResponseUTF8(string.format(LangUtils.ModText("autosave_on_ok")))
end
================================================
FILE: contents/commands/banip.json
================================================
{
"banip": {
"isClient": false,
"fromPlayer": false,
"gameMode": "creative",
"op": "admin",
"parameters": [
{
"type": "CP_STRING"
}
],
"script": {
"path": "banip.lua"
}
}
}
================================================
FILE: contents/commands/banip.lua
================================================
function RunCommand(sourceCmd, ip)
MiscUtils.Ban(ip)
sourceCmd:ResponseUTF8(string.format(LangUtils.ModText("banip_ok"), ip))
end
================================================
FILE: contents/commands/blacklist.json
================================================
{
"blacklist": {
"isClient": false,
"fromPlayer": false,
"gameMode": "creative",
"op": "admin",
"parameters": [],
"script": {
"path": "blacklist.lua"
}
}
}
================================================
FILE: contents/commands/blacklist.lua
================================================
function RunCommand(sourceCmd)
local blackList = MiscUtils.GetBlackList()
local count = blackList.length
for i = 1, count do
sourceCmd:ResponseUTF8(string.format(LangUtils.ModText("blacklist_info"), i, blackList[i]))
end
sourceCmd:ResponseUTF8(string.format(LangUtils.ModText("blacklist_ok"), count))
end
================================================
FILE: contents/commands/blueyoshiiscool.json
================================================
{
"blueyoshiiscool": {
"isClient": false,
"fromPlayer": false,
"gameMode": "creative",
"op": "master",
"parameters": [],
"script": {
"path": "byiscool.lua"
}
}
}
================================================
FILE: contents/commands/buff.json
================================================
{
"buff": {
"isClient": false,
"fromPlayer": true,
"gameMode": "creative",
"op": "any",
"parameters": [
{
"type": "CP_BUFF"
},
{
"type": "CP_INTEGER",
"min": 1,
"max": 216000
}
],
"script": {
"path": "buff.lua"
}
}
}
================================================
FILE: contents/commands/buff.lua
================================================
function InnerRunCommand(player, buffID, buffTime)
player:AddBuff(buffID, buffTime)
end
function RunCommandFromPlayer(myPlayer, buffID, buffTime)
InnerRunCommand(myPlayer, buffID, buffTime)
MiscUtils.UnicastUTF8(myPlayer, string.format(LangUtils.ModText("buff_ok"), myPlayer.name,
LangUtils.BuffName(buffID), math.floor(buffTime / 60)))
end
function RunCommand(sourceCmd, player, buffID, buffTime)
InnerRunCommand(player, buffID, buffTime)
sourceCmd:ResponseUTF8(string.format(LangUtils.ModText("buff_ok"), player.name, LangUtils.BuffName(buffID),
math.floor(buffTime / 60)))
end
================================================
FILE: contents/commands/buffp.json
================================================
{
"buffp": {
"isClient": false,
"fromPlayer": false,
"gameMode": "creative",
"op": "admin",
"parameters": [
{
"type": "CP_PLAYER"
},
{
"type": "CP_BUFF"
},
{
"type": "CP_INTEGER",
"min": 1,
"max": 216000
}
],
"script": {
"path": "buff.lua"
}
}
}
================================================
FILE: contents/commands/byiscool.lua
================================================
function RunCommand(sourceCmd)
local msg = string.format(LangUtils.ModText("blueyoshiiscool_ok"))
MiscUtils.BroadcastUTF8(msg)
end
================================================
FILE: contents/commands/clear.json
================================================
{
"clear": {
"isClient": false,
"fromPlayer": true,
"gameMode": "creative",
"op": "any",
"parameters": [],
"script": {
"path": "clear.lua"
}
}
}
================================================
FILE: contents/commands/clear.lua
================================================
function RunCommandFromPlayer(myPlayer)
myPlayer:ClearBackpack()
MiscUtils.UnicastUTF8(myPlayer, string.format(LangUtils.ModText("clear_ok"), myPlayer.name))
end
function RunCommand(sourceCmd, player)
player:ClearBackpack()
sourceCmd:ResponseUTF8(string.format(LangUtils.ModText("clear_ok"), player.name))
end
================================================
FILE: contents/commands/clearp.json
================================================
{
"clearp": {
"isClient": false,
"fromPlayer": false,
"gameMode": "creative",
"op": "admin",
"parameters": [
{
"type": "CP_PLAYER"
}
],
"script": {
"path": "clear.lua"
}
}
}
================================================
FILE: contents/commands/day.json
================================================
{
"day": {
"isClient": false,
"fromPlayer": false,
"gameMode": "creative",
"op": "any",
"parameters": [
{
"type": "CP_INTEGER",
"min": 0,
"max": 86400
}
],
"script": {
"path": "day.lua"
}
}
}
================================================
FILE: contents/commands/day.lua
================================================
function RunCommand(sourceCmd, dayTime)
MiscUtils.SetDayTime(dayTime)
local h, m, s = MiscUtils.GetDayTimeFormat()
sourceCmd:ResponseUTF8(string.format(LangUtils.ModText("day_ok"), h, m, s))
end
================================================
FILE: contents/commands/dayf.json
================================================
{
"dayf": {
"isClient": false,
"fromPlayer": false,
"gameMode": "creative",
"op": "any",
"parameters": [
{
"type": "CP_INTEGER",
"min": 0,
"max": 23
},
{
"type": "CP_INTEGER",
"min": 0,
"max": 59,
"default": 0
},
{
"type": "CP_INTEGER",
"min": 0,
"max": 59,
"default": 0
}
],
"script": {
"path": "dayf.lua"
}
}
}
================================================
FILE: contents/commands/dayf.lua
================================================
function RunCommand(sourceCmd, h, m, s)
MiscUtils.SetDayTimeFormat(h, m, s)
h, m, s = MiscUtils.GetDayTimeFormat()
sourceCmd:ResponseUTF8(string.format(LangUtils.ModText("day_ok"), h, m, s))
end
================================================
FILE: contents/commands/daylock.json
================================================
{
"daylock": {
"isClient": false,
"fromPlayer": false,
"gameMode": "creative",
"op": "any",
"parameters": [],
"script": {
"path": "daylock.lua"
}
}
}
================================================
FILE: contents/commands/daylock.lua
================================================
function RunCommand(sourceCmd)
MiscUtils.SetDaySpeed(0)
daySpeed = MiscUtils.GetDaySpeed()
sourceCmd:ResponseUTF8(string.format(LangUtils.ModText("dayspeed_ok"), daySpeed))
end
================================================
FILE: contents/commands/dayspeed.json
================================================
{
"dayspeed": {
"isClient": false,
"fromPlayer": false,
"gameMode": "creative",
"op": "any",
"parameters": [
{
"type": "CP_DOUBLE",
"min": 0,
"max": 1000
}
],
"script": {
"path": "dayspeed.lua"
}
}
}
================================================
FILE: contents/commands/dayspeed.lua
================================================
function RunCommand(sourceCmd, daySpeed)
MiscUtils.SetDaySpeed(daySpeed)
daySpeed = MiscUtils.GetDaySpeed()
sourceCmd:ResponseUTF8(string.format(LangUtils.ModText("dayspeed_ok"), daySpeed))
end
================================================
FILE: contents/commands/dayunlock.json
================================================
{
"dayunlock": {
"isClient": false,
"fromPlayer": false,
"gameMode": "creative",
"op": "any",
"parameters": [],
"script": {
"path": "dayunlock.lua"
}
}
}
================================================
FILE: contents/commands/dayunlock.lua
================================================
function RunCommand(sourceCmd)
MiscUtils.SetDaySpeed(1.0)
daySpeed = MiscUtils.GetDaySpeed()
sourceCmd:ResponseUTF8(string.format(LangUtils.ModText("dayspeed_ok"), daySpeed))
end
================================================
FILE: contents/commands/effect.json
================================================
{
"effect": {
"isClient": false,
"fromPlayer": false,
"gameMode": "creative",
"op": "any",
"parameters": [
{
"type": "CP_EFFECT"
},
{
"type": "CP_POSITION_CELL_X",
"default": "~8"
},
{
"type": "CP_POSITION_CELL_Y",
"default": "~-8"
}
],
"script": {
"path": "effect.lua"
}
}
}
================================================
FILE: contents/commands/effect.lua
================================================
function RunCommand(sourceCmd, effectID, x, y)
EffectUtils.SendFromServer(effectID, x * 16, y * 16)
end
================================================
FILE: contents/commands/enchant.json
================================================
{
"enchant": {
"isClient": false,
"fromPlayer": true,
"gameMode": "creative",
"op": "any",
"parameters": [
{
"type": "CP_ENCHANTMENT"
},
{
"type": "CP_INTEGER",
"min": 1,
"max": 8
}
],
"script": {
"path": "enchant.lua"
}
}
}
================================================
FILE: contents/commands/enchant.lua
================================================
function RunCommand(myPlayer, enchantmentID, enchantmentLevel)
local heldItemSlot = myPlayer:GetHeldItemSlot()
local ok = false
if heldItemSlot.hasItem then
ok = heldItemSlot:AddEnchantment(enchantmentID, enchantmentLevel)
end
if ok then
MiscUtils.UnicastUTF8(myPlayer,
string.format(LangUtils.ModText("em_ok"), myPlayer.name, LangUtils.ItemName(heldItemSlot.id),
LangUtils.EnchantmentName(enchantmentID), enchantmentLevel))
else
MiscUtils.UnicastUTF8(myPlayer, string.format(LangUtils.ModText("em_fail")))
end
end
================================================
FILE: contents/commands/ex.json
================================================
{
"ex": {
"isClient": false,
"fromPlayer": true,
"gameMode": "creative",
"op": "any",
"parameters": [
{
"type": "CP_INTEGER",
"min": 1,
"max": 10000000
}
],
"script": {
"path": "ex.lua"
}
}
}
================================================
FILE: contents/commands/ex.lua
================================================
function InnerRunCommand(player, exValue)
player:AddExperience(exValue)
end
function RunCommandFromPlayer(myPlayer, exValue)
InnerRunCommand(myPlayer, exValue)
MiscUtils.UnicastUTF8(myPlayer, string.format(LangUtils.ModText("ex_ok"), myPlayer.name, exValue))
end
function RunCommand(sourceCmd, player, exValue)
InnerRunCommand(player, exValue)
sourceCmd:ResponseUTF8(string.format(LangUtils.ModText("ex_ok"), player.name, exValue))
end
================================================
FILE: contents/commands/exp.json
================================================
{
"exp": {
"isClient": false,
"fromPlayer": false,
"gameMode": "creative",
"op": "admin",
"parameters": [
{
"type": "CP_PLAYER"
},
{
"type": "CP_INTEGER",
"min": 1,
"max": 10000000
}
],
"script": {
"path": "ex.lua"
}
}
}
================================================
FILE: contents/commands/gamemode.json
================================================
{
"gamemode": {
"isClient": false,
"fromPlayer": true,
"gameMode": "creative",
"op": "any",
"parameters": [
{
"type": "CP_GAME_MODE"
}
],
"script": {
"path": "gamemodep.lua"
}
}
}
================================================
FILE: contents/commands/gamemodep.json
================================================
{
"gamemodep": {
"isClient": false,
"fromPlayer": false,
"gameMode": "creative",
"op": "admin",
"parameters": [
{
"type": "CP_PLAYER"
},
{
"type": "CP_GAME_MODE"
}
],
"script": {
"path": "gamemodep.lua"
}
}
}
================================================
FILE: contents/commands/gamemodep.lua
================================================
function InnerRunCommand(player, gameMode, changeFromSelf)
player:SetGameMode(gameMode, changeFromSelf)
local msg = ""
if gameMode == GAME_MODE_SURVIVAL then
msg = string.format(LangUtils.ModText("gamemodep_s_ok"), player.name)
elseif gameMode == GAME_MODE_CREATIVE then
msg = string.format(LangUtils.ModText("gamemodep_c_ok"), player.name)
elseif gameMode == GAME_MODE_ADVENTURE then
msg = string.format(LangUtils.ModText("gamemodep_a_ok"), player.name)
end
return msg
end
function RunCommandFromPlayer(myPlayer, gameMode)
local msg = InnerRunCommand(myPlayer, gameMode, true)
MiscUtils.UnicastUTF8(myPlayer, msg)
end
function RunCommand(sourceCmd, player, gameMode)
local msg = InnerRunCommand(player, gameMode, false)
MiscUtils.UnicastUTF8(player, msg)
sourceCmd:ResponseUTF8(msg)
end
================================================
FILE: contents/commands/gamemodew.json
================================================
{
"gamemodew": {
"isClient": false,
"fromPlayer": false,
"gameMode": "creative",
"op": "admin",
"parameters": [
{
"type": "CP_GAME_MODE"
}
],
"script": {
"path": "gamemodew.lua"
}
}
}
================================================
FILE: contents/commands/gamemodew.lua
================================================
function RunCommand(sourceCmd, gameMode)
MiscUtils.SetGameMode(gameMode)
local msg = ""
if gameMode == GAME_MODE_SURVIVAL then
msg = string.format(LangUtils.ModText("gamemodew_s_ok"))
elseif gameMode == GAME_MODE_CREATIVE then
msg = string.format(LangUtils.ModText("gamemodew_c_ok"))
elseif gameMode == GAME_MODE_ADVENTURE then
msg = string.format(LangUtils.ModText("gamemodew_a_ok"))
end
sourceCmd:ResponseUTF8(msg)
end
================================================
FILE: contents/commands/give.json
================================================
{
"give": {
"isClient": false,
"fromPlayer": true,
"gameMode": "creative",
"op": "any",
"parameters": [
{
"type": "CP_ITEM"
},
{
"type": "CP_INTEGER",
"min": 1,
"max": 9999,
"default": 9999
}
],
"script": {
"path": "give.lua"
}
}
}
================================================
FILE: contents/commands/give.lua
================================================
function InnerRunCommand(player, itemID, itemCount)
local imax = ItemUtils.GetMaxCount(itemID)
if itemCount > imax then
itemCount = imax
end
player:AddBackpack(itemID, itemCount)
return itemCount
end
function RunCommandFromPlayer(myPlayer, itemID, itemCount)
itemCount = InnerRunCommand(myPlayer, itemID, itemCount)
MiscUtils.UnicastUTF8(myPlayer, string.format(LangUtils.ModText("give_ok"), myPlayer.name,
LangUtils.ItemName(itemID), itemCount))
end
function RunCommand(sourceCmd, player, itemID, itemCount)
itemCount = InnerRunCommand(player, itemID, itemCount)
sourceCmd:ResponseUTF8(string.format(LangUtils.ModText("give_ok"), player.name, LangUtils.ItemName(itemID),
itemCount))
end
================================================
FILE: contents/commands/givep.json
================================================
{
"givep": {
"isClient": false,
"fromPlayer": false,
"gameMode": "creative",
"op": "admin",
"parameters": [
{
"type": "CP_PLAYER"
},
{
"type": "CP_ITEM"
},
{
"type": "CP_INTEGER",
"min": 1,
"max": 9999,
"default": 9999
}
],
"script": {
"path": "give.lua"
}
}
}
================================================
FILE: contents/commands/home.json
================================================
{
"home": {
"isClient": false,
"fromPlayer": true,
"gameMode": "creative",
"op": "any",
"parameters": [],
"script": {
"path": "home.lua"
}
}
}
================================================
FILE: contents/commands/home.lua
================================================
function RunCommandFromPlayer(myPlayer)
local ok = myPlayer:GoHome()
if ok then
MiscUtils.UnicastUTF8(myPlayer, string.format(LangUtils.ModText("home_ok"), myPlayer.name))
else
MiscUtils.UnicastUTF8(myPlayer, string.format(LangUtils.ModText("home_fail"), myPlayer.name))
end
end
================================================
FILE: contents/commands/kick.json
================================================
{
"kick": {
"isClient": false,
"fromPlayer": false,
"gameMode": "creative",
"op": "admin",
"parameters": [
{
"type": "CP_PLAYER"
}
],
"script": {
"path": "kick.lua"
}
}
}
================================================
FILE: contents/commands/kick.lua
================================================
function RunCommand(sourceCmd, player)
local name = player.name
MiscUtils.KickPlayer(name)
sourceCmd:ResponseUTF8(string.format(LangUtils.ModText("kick_ok"), name))
end
================================================
FILE: contents/commands/kickall.json
================================================
{
"kickall": {
"isClient": false,
"fromPlayer": false,
"gameMode": "creative",
"op": "admin",
"parameters": [],
"script": {
"path": "kickall.lua"
}
}
}
================================================
FILE: contents/commands/kickall.lua
================================================
function RunCommand(sourceCmd)
MiscUtils.KickAllPlayers()
end
================================================
FILE: contents/commands/kill.json
================================================
{
"kill": {
"isClient": false,
"fromPlayer": true,
"gameMode": "survival",
"op": "any",
"parameters": [],
"script": {
"path": "kill.lua"
}
}
}
================================================
FILE: contents/commands/kill.lua
================================================
function RunCommandFromPlayer(myPlayer)
myPlayer:Strike(DEATH_REASON_SUICIDE, Attack.new(114514, 0, 0))
end
function RunCommand(sourceCmd, player)
player:Strike(DEATH_REASON_UNKNOWN, Attack.new(114514, 0, 0))
end
================================================
FILE: contents/commands/killp.json
================================================
{
"killp": {
"isClient": false,
"fromPlayer": false,
"gameMode": "creative",
"op": "admin",
"parameters": [
{
"type": "CP_PLAYER"
}
],
"script": {
"path": "kill.lua"
}
}
}
================================================
FILE: contents/commands/master.json
================================================
{
"master": {
"isClient": false,
"fromPlayer": false,
"gameMode": "creative",
"op": "developer",
"parameters": [
{
"type": "CP_PLAYER"
}
],
"script": {
"path": "master.lua"
}
}
}
================================================
FILE: contents/commands/master.lua
================================================
function RunCommand(sourceCmd, player)
player:SetOP(OP_MASTER)
player:SetGameMode(GAME_MODE_CREATIVE)
sourceCmd:ResponseUTF8(string.format(LangUtils.ModText("master_ok"), player.name))
end
================================================
FILE: contents/commands/me.json
================================================
{
"me": {
"isClient": false,
"fromPlayer": true,
"gameMode": "survival",
"op": "any",
"parameters": [
{
"type": "CP_STRING"
}
],
"script": {
"path": "me.lua"
}
}
}
================================================
FILE: contents/commands/me.lua
================================================
function RunCommandFromPlayer(myPlayer, message)
local msg = string.format("#H* %s %s", myPlayer.name, message)
MiscUtils.BroadcastUTF8(msg)
end
================================================
FILE: contents/commands/msg.json
================================================
{
"msg": {
"isClient": false,
"fromPlayer": true,
"gameMode": "survival",
"op": "any",
"parameters": [
{
"type": "CP_PLAYER"
},
{
"type": "CP_STRING"
}
],
"script": {
"path": "msg.lua"
}
}
}
================================================
FILE: contents/commands/msg.lua
================================================
function RunCommandFromPlayer(myPlayer, toPlayer, message)
MiscUtils.UnicastUTF8(myPlayer, string.format(LangUtils.ModText("msg_to_content"), toPlayer.name, message))
MiscUtils.UnicastUTF8(toPlayer, string.format(LangUtils.ModText("msg_content"), myPlayer.name, message))
end
function RunCommand(sourceCmd, toPlayer, message)
sourceCmd:ResponseUTF8(string.format(LangUtils.ModText("msg_to_server_content"), toPlayer.name, message))
MiscUtils.UnicastUTF8(toPlayer, string.format(LangUtils.ModText("msg_server_content"), message))
end
================================================
FILE: contents/commands/noadmin.json
================================================
{
"noadmin": {
"isClient": false,
"fromPlayer": false,
"gameMode": "creative",
"op": "master",
"parameters": [
{
"type": "CP_PLAYER"
}
],
"script": {
"path": "noadmin.lua"
}
}
}
================================================
FILE: contents/commands/noadmin.lua
================================================
function RunCommand(sourceCmd, player)
player:SetOP(OP_ANY)
local gameMode = MiscUtils.GetGameMode()
player:SetGameMode(gameMode)
sourceCmd:ResponseUTF8(string.format(LangUtils.ModText("noadmin_ok"), player.name))
end
================================================
FILE: contents/commands/nobanip.json
================================================
{
"nobanip": {
"isClient": false,
"fromPlayer": false,
"gameMode": "creative",
"op": "admin",
"parameters": [
{
"type": "CP_STRING"
}
],
"script": {
"path": "nobanip.lua"
}
}
}
================================================
FILE: contents/commands/nobanip.lua
================================================
function RunCommand(sourceCmd, ip)
local ok = MiscUtils.RemoveBan(ip)
if ok then
sourceCmd:ResponseUTF8(string.format(LangUtils.ModText("nobanip_ok"), ip))
else
sourceCmd:ResponseUTF8(string.format(LangUtils.ModText("nobanip_fail"), ip))
end
end
================================================
FILE: contents/commands/nomaster.json
================================================
{
"nomaster": {
"isClient": false,
"fromPlayer": false,
"gameMode": "creative",
"op": "developer",
"parameters": [
{
"type": "CP_PLAYER"
}
],
"script": {
"path": "nomaster.lua"
}
}
}
================================================
FILE: contents/commands/nomaster.lua
================================================
function RunCommand(sourceCmd, player)
player:SetOP(OP_ANY)
local gameMode = MiscUtils.GetGameMode()
player:SetGameMode(gameMode)
sourceCmd:ResponseUTF8(string.format(LangUtils.ModText("nomaster_ok"), player.name))
end
================================================
FILE: contents/commands/npc.json
================================================
{
"npc": {
"isClient": false,
"fromPlayer": false,
"gameMode": "creative",
"op": "any",
"parameters": [
{
"type": "CP_NPC"
},
{
"type": "CP_POSITION_CELL_X",
"default": "~8"
},
{
"type": "CP_POSITION_CELL_Y",
"default": "~-8"
}
],
"script": {
"path": "npc.lua"
}
}
}
================================================
FILE: contents/commands/npc.lua
================================================
function RunCommand(sourceCmd, npcID, x, y)
NpcUtils.Create(npcID, x * 16, y * 16)
sourceCmd:ResponseUTF8(string.format(LangUtils.ModText("npc_ok"),
LangUtils.NpcName(npcID), x, y))
end
================================================
FILE: contents/commands/players.json
================================================
{
"players": {
"isClient": false,
"fromPlayer": false,
"gameMode": "creative",
"op": "admin",
"parameters": [],
"script": {
"path": "players.lua"
}
}
}
================================================
FILE: contents/commands/players.lua
================================================
function RunCommand(sourceCmd)
local onlinePlayers = MiscUtils.GetOnlinePlayerList()
local count = onlinePlayers.length
for i = 1, count do
local player = onlinePlayers[i]
local info = string.format(LangUtils.ModText("player_info"), i, player.name, player.ip, player.portNumber)
sourceCmd:ResponseUTF8(info)
end
sourceCmd:ResponseUTF8(string.format(LangUtils.ModText("players_ok"), count))
end
================================================
FILE: contents/commands/port.json
================================================
{
"port": {
"isClient": false,
"fromPlayer": false,
"gameMode": "creative",
"op": "admin",
"parameters": [],
"script": {
"path": "port.lua"
}
}
}
================================================
FILE: contents/commands/port.lua
================================================
function RunCommand(sourceCmd)
local port = MiscUtils.GetPortNumber()
sourceCmd:ResponseUTF8(string.format(LangUtils.ModText("port_ok"), port))
end
================================================
FILE: contents/commands/pvp-off.json
================================================
{
"pvp-off": {
"isClient": false,
"fromPlayer": false,
"gameMode": "creative",
"op": "admin",
"parameters": [],
"script": {
"path": "pvpoff.lua"
}
}
}
================================================
FILE: contents/commands/pvp-on.json
================================================
{
"pvp-on": {
"isClient": false,
"fromPlayer": false,
"gameMode": "creative",
"op": "admin",
"parameters": [],
"script": {
"path": "pvpon.lua"
}
}
}
================================================
FILE: contents/commands/pvpoff.lua
================================================
function RunCommand(sourceCmd)
MiscUtils.SetPVP(false)
sourceCmd:ResponseUTF8(string.format(LangUtils.ModText("pvp_off_ok")))
end
================================================
FILE: contents/commands/pvpon.lua
================================================
function RunCommand(sourceCmd)
MiscUtils.SetPVP(true)
sourceCmd:ResponseUTF8(string.format(LangUtils.ModText("pvp_on_ok")))
end
================================================
FILE: contents/commands/safeblow-off.json
================================================
{
"safeblow-off": {
"isClient": false,
"fromPlayer": false,
"gameMode": "creative",
"op": "admin",
"parameters": [],
"script": {
"path": "safeblowoff.lua"
}
}
}
================================================
FILE: contents/commands/safeblow-on.json
================================================
{
"safeblow-on": {
"isClient": false,
"fromPlayer": false,
"gameMode": "creative",
"op": "admin",
"parameters": [],
"script": {
"path": "safeblowon.lua"
}
}
}
================================================
FILE: contents/commands/safeblowoff.lua
================================================
function RunCommand(sourceCmd)
MiscUtils.SetSafeBlow(false)
sourceCmd:ResponseUTF8(string.format(LangUtils.ModText("safeblow_off_ok")))
end
================================================
FILE: contents/commands/safeblowon.lua
================================================
function RunCommand(sourceCmd)
MiscUtils.SetSafeBlow(true)
sourceCmd:ResponseUTF8(string.format(LangUtils.ModText("safeblow_on_ok")))
end
================================================
FILE: contents/commands/save.json
================================================
{
"save": {
"isClient": false,
"fromPlayer": false,
"gameMode": "creative",
"op": "admin",
"parameters": [],
"script": {
"path": "save.lua"
}
}
}
================================================
FILE: contents/commands/save.lua
================================================
function RunCommand(sourceCmd)
MiscUtils.SaveAll()
sourceCmd:ResponseUTF8(string.format(LangUtils.ModText("save_ok")))
end
================================================
FILE: contents/commands/say.json
================================================
{
"say": {
"isClient": false,
"fromPlayer": false,
"gameMode": "creative",
"op": "any",
"parameters": [
{
"type": "CP_STRING"
}
],
"script": {
"path": "say.lua"
}
}
}
================================================
FILE: contents/commands/say.lua
================================================
function RunCommand(sourceCmd, message)
MiscUtils.BroadcastUTF8(string.format(LangUtils.ModText("say"), message))
end
================================================
FILE: contents/commands/spawn.json
================================================
{
"spawn": {
"isClient": false,
"fromPlayer": true,
"gameMode": "creative",
"op": "any",
"parameters": [],
"script": {
"path": "spawn.lua"
}
}
}
================================================
FILE: contents/commands/spawn.lua
================================================
function RunCommandFromPlayer(myPlayer)
myPlayer:TeleportToSpawn()
MiscUtils.UnicastUTF8(myPlayer, string.format(LangUtils.ModText("spawn_ok"), myPlayer.name))
end
================================================
FILE: contents/commands/state.json
================================================
{
"state": {
"isClient": false,
"fromPlayer": true,
"gameMode": "creative",
"op": "admin",
"parameters": []
}
}
================================================
FILE: contents/commands/stopwea.json
================================================
{
"stopwea": {
"isClient": false,
"fromPlayer": false,
"gameMode": "creative",
"op": "any",
"parameters": [],
"script": {
"path": "stopwea.lua"
}
}
}
================================================
FILE: contents/commands/stopwea.lua
================================================
function RunCommand(sourceCmd)
MiscUtils.SetWeatherTime(216000 * 100)
sourceCmd:ResponseUTF8(string.format(LangUtils.ModText("wea_ok"), 100))
end
================================================
FILE: contents/commands/tp.json
================================================
{
"tp": {
"isClient": false,
"fromPlayer": true,
"gameMode": "creative",
"op": "any",
"parameters": [
{
"type": "CP_POSITION_CELL_X"
},
{
"type": "CP_POSITION_CELL_Y"
}
],
"script": {
"path": "tp.lua"
}
}
}
================================================
FILE: contents/commands/tp.lua
================================================
function InnerRunCommand(player, x, y)
player:Teleport(x * 16, y * 16)
end
function RunCommandFromPlayer(myPlayer, x, y)
InnerRunCommand(myPlayer, x, y)
MiscUtils.UnicastUTF8(myPlayer, string.format(LangUtils.ModText("tp_ok"), myPlayer.name, x, y))
end
function RunCommand(sourceCmd, player, x, y)
InnerRunCommand(player, x, y)
sourceCmd:ResponseUTF8(string.format(LangUtils.ModText("tp_ok"), player.name, x, y))
end
================================================
FILE: contents/commands/tpp.json
================================================
{
"tpp": {
"isClient": false,
"fromPlayer": false,
"gameMode": "creative",
"op": "admin",
"parameters": [
{
"type": "CP_PLAYER"
},
{
"type": "CP_POSITION_CELL_X"
},
{
"type": "CP_POSITION_CELL_Y"
}
],
"script": {
"path": "tp.lua"
}
}
}
================================================
FILE: contents/commands/wea.json
================================================
{
"wea": {
"isClient": false,
"fromPlayer": false,
"gameMode": "creative",
"op": "any",
"parameters": [
{
"type": "CP_INTEGER",
"min": 1,
"max": 216000
}
],
"script": {
"path": "wea.lua"
}
}
}
================================================
FILE: contents/commands/wea.lua
================================================
function RunCommand(sourceCmd, weaTime)
MiscUtils.SetWeatherTime(weaTime)
local progress = math.floor(weaTime / 86400 * 100)
sourceCmd:ResponseUTF8(string.format(LangUtils.ModText("wea_ok"), progress))
end
================================================
FILE: data/backgrounds.json
================================================
{
"sun": "backgrounds/sky/elements/sun.png",
"moon": "backgrounds/sky/elements/moon.png",
"smallClouds": [
"backgrounds/sky/clouds/small.png",
"backgrounds/sky/clouds/small2.png",
"backgrounds/sky/clouds/small3.png",
"backgrounds/sky/clouds/small4.png",
"backgrounds/sky/clouds/small5.png"
],
"largeClouds": [
"backgrounds/sky/clouds/large.png",
"backgrounds/sky/clouds/large2.png"
],
"stars": [
"backgrounds/sky/stars/star.png",
"backgrounds/sky/stars/star2.png",
"backgrounds/sky/stars/star3.png",
"backgrounds/sky/stars/star4.png",
"backgrounds/sky/stars/star5.png"
],
"walls": [
{
"stone_wall": "backgrounds/walls/stone_wall.png"
},
{
"stone_wall_link": "backgrounds/walls/stone_wall_link.png"
},
{
"dirt_wall": "backgrounds/walls/dirt_wall.png"
},
{
"dirt_wall_link": "backgrounds/walls/dirt_wall_link.png"
},
{
"tainted_wall": "backgrounds/walls/tainted_wall.png"
},
{
"tainted_wall_link": "backgrounds/walls/tainted_wall_link.png"
},
{
"sand_wall": "backgrounds/walls/sand_wall.png"
},
{
"sand_wall_link": "backgrounds/walls/sand_wall_link.png"
},
{
"ice_wall": "backgrounds/walls/ice_wall.png"
},
{
"ice_wall_link": "backgrounds/walls/ice_wall_link.png"
},
{
"lava_wall": "backgrounds/walls/lava_wall.png"
},
{
"lava_wall_link": "backgrounds/walls/lava_wall_link.png"
},
{
"mud_wall": "backgrounds/walls/mud_wall.png"
},
{
"mud_wall_link": "backgrounds/walls/mud_wall_link.png"
},
{
"red_sand_wall": "backgrounds/walls/red_sand_wall.png"
},
{
"red_sand_wall_link": "backgrounds/walls/red_sand_wall_link.png"
},
{
"flesh_wall": "backgrounds/walls/flesh_wall.png"
},
{
"flesh_wall_link": "backgrounds/walls/flesh_wall_link.png"
},
{
"pile_cave_wall": "backgrounds/walls/pile_cave_wall.png"
},
{
"long_lava_wall": "backgrounds/walls/long_lava_wall.png"
},
{
"pile_ice_wall": "backgrounds/walls/pile_ice_wall.png"
},
{
"mushroom_wall": "backgrounds/walls/mushroom_wall.png"
}
],
"backgrounds": [
{
"large_tree_leaf": "backgrounds/layers/large_tree_leaf.png"
},
{
"large_tree_leaf2": "backgrounds/layers/large_tree_leaf2.png"
},
{
"large_tree_stem": "backgrounds/layers/large_tree_stem.png"
},
{
"snowy_hill": "backgrounds/layers/snowy_hill.png"
},
{
"dirty_hill": "backgrounds/layers/dirty_hill.png"
},
{
"stone_hill": "backgrounds/layers/stone_hill.png"
},
{
"large_grass": "backgrounds/layers/large_grass.png"
},
{
"large_grass_tree": "backgrounds/layers/large_grass_tree.png"
},
{
"large_grass_medium_tree": "backgrounds/layers/large_grass_medium_tree.png"
},
{
"large_grass_small_tree": "backgrounds/layers/large_grass_small_tree.png"
},
{
"large_bush": "backgrounds/layers/large_bush.png"
},
{
"desert_back": "backgrounds/layers/desert_back.png"
},
{
"desert_hill": "backgrounds/layers/desert_hill.png"
},
{
"desert_hill_new": "backgrounds/layers/desert_hill_new.png"
},
{
"desert_hill_new_2": "backgrounds/layers/desert_hill_new_2.png"
},
{
"desert_back_hill": "backgrounds/layers/desert_back_hill.png"
},
{
"desert": "backgrounds/layers/desert.png"
},
{
"desert_2": "backgrounds/layers/desert_2.png"
},
{
"desert_back_hill2": "backgrounds/layers/desert_back_hill2.png"
},
{
"desert_back_hill3": "backgrounds/layers/desert_back_hill3.png"
},
{
"desert_front": "backgrounds/layers/desert_front.png"
},
{
"desert_rock": "backgrounds/layers/desert_rock.png"
},
{
"snow_back": "backgrounds/layers/snow_back.png"
},
{
"snow_hill": "backgrounds/layers/snow_hill.png"
},
{
"snow_trees": "backgrounds/layers/snow_trees.png"
},
{
"snow_trees2": "backgrounds/layers/snow_trees2.png"
},
{
"snow_trees3": "backgrounds/layers/snow_trees3.png"
},
{
"snow_dune": "backgrounds/layers/snow_dune.png"
},
{
"jungle_bush": "backgrounds/layers/jungle_bush.png"
},
{
"tainted_hill": "backgrounds/layers/tainted_hill.png"
},
{
"tainted_hill2": "backgrounds/layers/tainted_hill2.png"
},
{
"tainted_bush": "backgrounds/layers/tainted_bush.png"
},
{
"tainted_bush_strick": "backgrounds/layers/tainted_bush_strick.png"
},
{
"tainted_rock": "backgrounds/layers/tainted_rock.png"
},
{
"lava_lake": "backgrounds/layers/lava_lake.png"
},
{
"lava_layer": "backgrounds/layers/lava_layer.png"
},
{
"lava_rock": "backgrounds/layers/lava_rock.png"
},
{
"lava_pile": "backgrounds/layers/lava_pile.png"
},
{
"lava_layer_hanging": "backgrounds/layers/lava_layer_hanging.png"
},
{
"lava_rock_hanging": "backgrounds/layers/lava_rock_hanging.png"
},
{
"lava_pile_hanging": "backgrounds/layers/lava_pile_hanging.png"
},
{
"fossil": "backgrounds/layers/fossil.png"
},
{
"waste_back": "backgrounds/layers/waste_back.png"
},
{
"waste_back2": "backgrounds/layers/waste_back2.png"
},
{
"waste_hill": "backgrounds/layers/waste_hill.png"
},
{
"waste_hill2": "backgrounds/layers/waste_hill2.png"
},
{
"flesh_fossil": "backgrounds/layers/flesh_fossil.png"
},
{
"flesh_fossil2": "backgrounds/layers/flesh_fossil2.png"
},
{
"flesh_back": "backgrounds/layers/flesh_back.png"
},
{
"flesh_back2": "backgrounds/layers/flesh_back2.png"
},
{
"flesh_hill": "backgrounds/layers/flesh_hill.png"
},
{
"flesh_hill2": "backgrounds/layers/flesh_hill2.png"
},
{
"flesh_bush": "backgrounds/layers/flesh_bush.png"
},
{
"mushroom_grass": "backgrounds/layers/mushroom_grass.png"
},
{
"large_mushrooms": "backgrounds/layers/large_mushrooms.png"
},
{
"large_mushrooms2": "backgrounds/layers/large_mushrooms2.png"
},
{
"volcano_back": "backgrounds/layers/volcano_back.png"
},
{
"volcano_back2": "backgrounds/layers/volcano_back2.png"
},
{
"volcano_back3": "backgrounds/layers/volcano_back3.png"
},
{
"snowy_hill2": "backgrounds/layers/snowy_hill2.png"
},
{
"tainted_hill3": "backgrounds/layers/tainted_hill3.png"
},
{
"flesh_hill3": "backgrounds/layers/flesh_hill3.png"
},
{
"waste_hill3": "backgrounds/layers/waste_hill3.png"
},
{
"volcano_hill": "backgrounds/layers/volcano_hill.png"
},
{
"snow_mountain": "backgrounds/layers/snow_mountain.png"
},
{
"snow_trees_new": "backgrounds/layers/snow_trees_new.png"
},
{
"snow_trees_new2": "backgrounds/layers/snow_trees_new2.png"
}
]
}
================================================
FILE: data/block_config.json
================================================
{
"exParticles": [
{
"torch_particle": [
{
"condition": {
"checkInterval": true,
"intervalTime": 24
},
"action": {
"effectId": "fire_smoke",
"offsetX": [ 6, 10 ],
"offsetY": [ -4, 0 ],
"speedX": [ -0.25, 0.25 ],
"speedY": [ -0.5 ],
"rotateSpeed": [ -0.05, 0.05 ],
"scale": [ 0.95, 1.45 ],
"alpha": [ 0.8 ],
"color": [ 255, 255, 255, 255 ]
}
},
{
"condition": {
"checkRandom": true,
"randomTimes": 256
},
"action": {
"effectId": "liquid_paticular",
"offsetX": [ 6, 10 ],
"offsetY": [ -4, 0 ],
"speedX": [ -0.25, 0.25 ],
"speedY": [ -2.0 ],
"rotateSpeed": [ -0.05, 0.05 ],
"scale": [ 0.5 ],
"alpha": [ 1.0 ],
"color": [ 255, 255, 255, 0 ]
}
}
]
},
{
"campfire_particle": [
{
"condition": {
"checkInterval": true,
"intervalTime": 32
},
"action": {
"effectId": "fire_smoke",
"offsetX": [ 10, 22 ],
"offsetY": [ 4, 12 ],
"speedX": [ -0.25, 0.25 ],
"speedY": [ -2.0 ],
"rotateSpeed": [ -0.05, 0.05 ],
"scale": [ 1.8, 2.2 ],
"alpha": [ 0.8 ],
"color": [ 255, 255, 255, 255 ]
}
},
{
"condition": {
"checkRandom": true,
"randomTimes": 256
},
"action": {
"effectId": "liquid_paticular",
"offsetX": [ 10, 22 ],
"offsetY": [ 4, 12 ],
"speedX": [ -1.25, 1.25 ],
"speedY": [ -2.0 ],
"rotateSpeed": [ -0.05, 0.05 ],
"scale": [ 0.5 ],
"alpha": [ 1.0 ],
"color": [ 255, 255, 255, 0 ]
}
}
]
},
{
"end_rod_particle": [
{
"condition": {
"checkRandom": true,
"randomTimes": 256
},
"action": {
"effectId": "liquid_paticular",
"offsetX": [ 6, 10 ],
"offsetY": [ 6, 10 ],
"speedX": [ -1.25, 1.25 ],
"speedY": [ -2.0, 0.0 ],
"rotateSpeed": [ -0.05, 0.05 ],
"scale": [ 0.85, 1.0 ],
"alpha": [ 1.0 ],
"color": [ 255, 255, 255, 255 ]
}
}
]
},
{
"ore_particle": [
{
"condition": {
"checkRandom": true,
"randomTimes": 512,
"checkLighting": true,
"lightingArea": [ 18, 32 ]
},
"action": {
"effectId": "flash",
"offsetX": [ 0, 16 ],
"offsetY": [ 0, 16 ],
"speedX": [ 0.0 ],
"speedY": [ 0.0 ],
"rotateSpeed": [ 0.0 ],
"scale": [ 2.0 ],
"alpha": [ 1.0 ],
"color": [ 255, 255, 255, 255 ]
}
}
]
},
{
"furnace_particle": [
{
"condition": {
"checkInterval": true,
"intervalTime": 16,
"checkAnimation": true,
"animationIndex": 1
},
"action": {
"effectId": "fire",
"offsetX": [ 18, 30 ],
"offsetY": [ 20, 28 ],
"speedX": [ 0.0 ],
"speedY": [ 0.0 ],
"rotateSpeed": [ 0.0 ],
"scale": [ 0.8, 1.2 ],
"alpha": [ 1.0 ],
"color": [ 255, 255, 255, 255 ]
}
},
{
"condition": {
"checkInterval": true,
"intervalTime": 32,
"checkAnimation": true,
"animationIndex": 1
},
"action": {
"effectId": "fire_smoke",
"offsetX": [ 22, 26 ],
"offsetY": [ 20, 28 ],
"speedX": [ -0.25, 0.25 ],
"speedY": [ -0.5 ],
"rotateSpeed": [ -0.05, 0.05 ],
"scale": [ 0.9, 1.5 ],
"alpha": [ 1.0 ],
"color": [ 255, 255, 255, 255 ]
}
}
]
}
],
"growGroups": [
{
"NORMAL_GROUP": [
[ "grass", 100 ],
[ "grass", 100 ],
[ "dandelion", 10 ],
[ "allium", 10 ],
[ "sunflower", 5 ],
[ "brown_mushroom", 20 ],
[ "red_mushroom", 20 ],
[ "large_brown_mushroom", 5 ],
[ "large_red_mushroom", 5 ],
[ "lilac", 5 ],
[ "red_tulip", 8 ],
[ "white_tulip", 8 ],
[ "orange_tulip", 8 ],
[ "pink_tulip", 8 ],
[ "azure_bluet", 8 ],
[ "blue_orchid", 8 ],
[ "fern", 6 ],
[ "peony", 5 ],
[ "rose_bush", 5 ],
[ "poppy", 8 ]
]
},
{
"TAINTED_GROUP": [
[ "tainted_grass", 10 ]
]
},
{
"FLESH_GROUP": [
[ "blood_grass", 10 ]
]
}
],
"hangGrowGroups": [
{
"NORMAL_GROUP": [
[ "vine", 10 ]
]
},
{
"TAINTED_GROUP": [
[ "tainted_vine", 10 ]
]
},
{
"FLESH_GROUP": [
[ "eyeball_vine", 10 ]
]
}
],
"farmGroups": [
{
"FARMLAND_GROUP": [
"melon_seed",
"pumpkin_seed",
"seed",
"sugar_cane",
"carrot",
"potato"
]
},
{
"SAND_GROUP": [
"sugar_cane"
]
},
{
"SOULSAND_GROUP": [
"nether_wart"
]
}
],
"placeChecks": [
{
"PLACE_TREE_CHECK": {
"bottomBlocks": [],
"topBlocks": []
}
},
{
"PLACE_PLANT_CHECK": {
"bottomBlocks": [],
"topBlocks": []
}
},
{
"PLACE_VINE_CHECK": {
"bottomBlocks": [],
"topBlocks": [
"dirt",
"coarse_dirt",
"tainted_dirt",
"tainted_stone",
"flesh_dirt"
]
}
},
{
"PLACE_STONE_DECO_CHECK": {
"bottomBlocks": [
"cobblestone",
"stone"
],
"topBlocks": [
"cobblestone",
"stone"
]
}
},
{
"PLACE_ICE_DECO_CHECK": {
"bottomBlocks": [
"snow",
"snow_soft",
"ice_cobblestone",
"ice_cobblestone_hard"
],
"topBlocks": [
"snow",
"snow_soft",
"ice_cobblestone",
"ice_cobblestone_hard"
]
}
},
{
"PLACE_JUNGLE_DECO_CHECK": {
"bottomBlocks": [
"dirt",
"coarse_dirt"
],
"topBlocks": [
"dirt",
"coarse_dirt"
]
}
},
{
"PLACE_SAND_DECO_CHECK": {
"bottomBlocks": [
"sandstone",
"red_sand_stone"
],
"topBlocks": [
"sandstone",
"red_sand_stone"
]
}
},
{
"PLACE_TAINTED_DECO_CHECK": {
"bottomBlocks": [
"tainted_dirt",
"tainted_stone"
],
"topBlocks": [
"tainted_dirt",
"tainted_stone"
]
}
},
{
"PLACE_WASTE_DECO_CHECK": {
"bottomBlocks": [
"red_sand_stone"
],
"topBlocks": [
"red_sand_stone"
]
}
},
{
"PLACE_UNDERWATER_CHECK": {
"bottomBlocks": [
"sandstone"
],
"topBlocks": []
}
},
{
"PLACE_ANDESITE_DECO_CHECK": {
"bottomBlocks": [
"andesite"
],
"topBlocks": [
"andesite"
]
}
},
{
"PLACE_DIORITE_DECO_CHECK": {
"bottomBlocks": [
"diorite"
],
"topBlocks": [
"diorite"
]
}
},
{
"PLACE_GRANITE_DECO_CHECK": {
"bottomBlocks": [
"granite"
],
"topBlocks": [
"granite"
]
}
},
{
"PLACE_OBSIDIAN_DECO_CHECK": {
"bottomBlocks": [
"obsidian"
],
"topBlocks": [
"obsidian"
]
}
},
{
"PLACE_MUSHROOM_CHECK": {
"bottomBlocks": [
"brown_mushroom_block",
"red_mushroom_block",
"mycelium"
],
"topBlocks": []
}
},
{
"PLACE_BLUE_MUSHROOM_CHECK": {
"bottomBlocks": [
"blue_mushroom_dirt",
"blue_mushroom_stem"
],
"topBlocks": []
}
}
],
"ores": {
"none": [],
"default": [
{
"oreId": "ore_iron",
"density": 625,
"radius": 4,
"startYi": 400,
"endYi": 2560
},
{
"oreId": "ore_gold",
"density": 312,
"radius": 5,
"startYi": 1000,
"endYi": 2560
},
{
"oreId": "ore_coal",
"density": 500,
"radius": 5,
"startYi": 400,
"endYi": 2560
},
{
"oreId": "ore_diamond",
"density": 230,
"radius": 2,
"startYi": 1400,
"endYi": 2560
},
{
"oreId": "ore_emerald",
"density": 190,
"radius": 2,
"startYi": 1000,
"endYi": 2560
},
{
"oreId": "ore_lapis",
"density": 320,
"radius": 3,
"startYi": 1200,
"endYi": 2560
},
{
"oreId": "ore_redstone",
"density": 850,
"radius": 4,
"startYi": 1800,
"endYi": 2560
},
{
"oreId": "ore_copper",
"density": 700,
"radius": 4,
"startYi": 300,
"endYi": 2560
},
{
"oreId": "ore_tin",
"density": 650,
"radius": 4,
"startYi": 300,
"endYi": 2560
},
{
"oreId": "ore_lead",
"density": 550,
"radius": 4,
"startYi": 600,
"endYi": 2560
},
{
"oreId": "ore_silver",
"density": 800,
"radius": 4,
"startYi": 1200,
"endYi": 2560
},
{
"oreId": "ore_ancient_debris",
"density": 180,
"radius": 3,
"startYi": 2560,
"endYi": 3072
},
{
"oreId": "ore_nether_quartz",
"density": 600,
"radius": 4,
"startYi": 2560,
"endYi": 3072
}
]
},
"groups": [
"ORE_GOLD",
"ORE_DIAMOND",
"ORE_REDSTONE",
"ORE_IRON",
"ORE_EMERALD",
"ORE_LAPIS",
"ORE_COAL",
"MUSHROOM",
"DIRT",
"COARSE_DIRT",
"TAINTED_DIRT",
"COBBLESTONE",
"TAINTED_STONE",
"STONE",
"OBSIDIAN",
"PRISMARINE",
"DIORITE",
"GRANITE",
"ANDESITE",
"GRAVEL",
"CLAY",
"SNOW",
"ICE",
"SAND",
"REDSAND",
"FLESH_DIRT",
"FLESH_STONE",
"FLESH_GUT",
"MYCELIUM",
"GLOWSTONE",
"SOUL_SAND",
"NETHERRACK",
"MAGMA_BLOCK",
"ENDSTONE",
"ICECOBBLESTONE",
"SANDSTONE",
"RED_SAND_STONE",
"SPONGE",
"SLIME_BLOCK",
"THRON",
"STONE_BRICK",
"SANDSTONE_CARVED",
"SANDSTONE_SMOOTH",
"WOOD_A",
"WOOD_B",
"ARTIFICAL",
"PLATFORM",
"FENCE",
"BAR",
"GLASS",
"FURNITURE_ALL",
"TREE_ALL"
],
"subGroups": [
"BED",
"CLOSED_DOOR",
"OPENED_DOOR",
"BOOKCASE",
"PRESSURE_PLATE",
"WOOD",
"LOG"
]
}
================================================
FILE: data/item_config.json
================================================
{
"ammos": [
"arrow",
"bullet",
"rocket"
],
"toolGrade": [
["NONE", 0],
["GRASS", 100],
["WOOD", 200],
["STONE", 300],
["IRON", 400],
["GOLD", 500],
["DIAMOND", 600]
],
"oreDictionary": [
"OD_IRON_INGOT",
"OD_COPPER_INGOT",
"OD_TERRACOTTA",
"OD_WOODEN_PLATFORM",
"OD_WOODEN_PLANK",
"OD_WOOD",
"OD_WOOD_STRIPPED",
"OD_WOOL",
"OD_GLASS",
"OD_BOOKCASE",
"OD_STAFF",
"OD_SWORD",
"OD_HOE"
],
"sub_groups": [
"SUB_GROUP_DIAMOND",
"SUB_GROUP_NETHERITE"
],
"groups": [
{
"name": "ALL",
"list": []
},
{
"name": "NATURE",
"itemIconId": "dirt",
"list": [
"GROUP_DIRT",
"GROUP_STONE",
"GROUP_COBBLESTONE",
"GROUP_ANDESITE",
"GROUP_DIORITE",
"GROUP_GRANITE",
"GROUP_PRISMARINE",
"GROUP_SAND",
"GROUP_RED_SAND",
"GROUP_ENDSTONE",
"GROUP_NETHER",
"GROUP_SNOW",
"GROUP_ICE",
"GROUP_ICE_COBBLESTONE",
"GROUP_MUSHROOM_BLOCK",
"GROUP_FLESH",
"GROUP_TAINTED",
"GROUP_VOLCANO",
"GROUP_LOG",
"GROUP_ORE",
"GROUP_OTHERS_BLOCK"
]
},
{
"name": "MANMADE",
"itemIconId": "stone_brick",
"list": [
"GROUP_STONE_BRICK",
"GROUP_ENDSTONE_BRICK",
"GROUP_NETHER_BRICK",
"GROUP_SNOW_BRICK",
"GROUP_ICE_BRICK",
"GROUP_GLASS",
"GROUP_WOODEN_PLANK",
"GROUP_WOODEN_PLATFORM",
"GROUP_PLATFORM",
"GROUP_WOOD",
"GROUP_WOOD_STRIPPED",
"GROUP_TERRACOTTA",
"GROUP_WOOL",
"GROUP_ORE_BLOCK"
]
},
{
"name": "PLANT",
"itemIconId": "orange_tulip",
"list": [
"GROUP_GRASS",
"GROUP_FLOWER",
"GROUP_LARGE_FLOWER",
"GROUP_SAPLING",
"GROUP_PUMPKIN",
"GROUP_MELON"
]
},
{
"name": "FURNITURE",
"itemIconId": "crafting_table",
"list": [
"GROUP_WOODEN_FENCE",
"GROUP_STONE_FENCE",
"GROUP_NETHER_FENCE",
"GROUP_PAINTING",
"GROUP_WOODEN_FURNITURE",
"GROUP_WOODEN_BED",
"GROUP_WOODEN_TABLE",
"GROUP_WOODEN_CABINET",
"GROUP_WOODEN_CHAIR",
"GROUP_BOOKCASE",
"GROUP_BENCH",
"GROUP_STONE_FURNITURE",
"GROUP_OTHERS_FURNITURE",
"GROUP_SHULKER_BOX",
"GROUP_PRESSURE_PLATE",
"GROUP_DOOR",
"GROUP_TORCH",
"GROUP_LIGHTING",
"GROUP_BUTTON",
"GROUP_TOWER"
]
},
{
"name": "REDSTONE",
"itemIconId": "redstone",
"list": [
"GROUP_REDSTONE_WIRE",
"GROUP_WIRE_CUTTER"
]
},
{
"name": "FOOD",
"itemIconId": "apple",
"list": [
"GROUP_FOOD"
]
},
{
"name": "TOOL",
"itemIconId": "wooden_pickaxe",
"list": [
"GROUP_BUCKET",
"GROUP_AXE",
"GROUP_PICKAXE",
"GROUP_HOE",
"GROUP_FISHINGROD",
"GROUP_SHEARS",
"GROUP_LIGHTER",
"GROUP_DRILL",
"GROUP_SAW",
"GROUP_MAP",
"GROUP_DROPABLE",
"GROUP_BOOK",
"GROUP_TOWER_CORE"
]
},
{
"name": "WEAPON",
"itemIconId": "stone_sword",
"list": [
"GROUP_HELMET",
"GROUP_CHESTPLATE",
"GROUP_LEGGINGS",
"GROUP_SWORD",
"GROUP_BOW",
"GROUP_CROSS_BOW",
"GROUP_GUN",
"GROUP_LAUNCHER",
"GROUP_ARROW",
"GROUP_BULLET",
"GROUP_ROCKET",
"GROUP_BOMB",
"GROUP_STAFF",
"GROUP_BOOMERANG",
"GROUP_LOOT"
]
},
{
"name": "POTION",
"itemIconId": "potion_awkward",
"list": [
"GROUP_POTION"
]
},
{
"name": "MATERIAL",
"itemIconId": "stick",
"list": [
"GROUP_STICK",
"GROUP_MATERIAL",
"GROUP_DYE",
"GROUP_SEED",
"GROUP_MANA",
"GROUP_BOSS"
]
},
{
"name": "GOODS",
"itemIconId": "iron_ingot",
"list": [
"GROUP_DIAMOND",
"GROUP_EMERALD",
"GROUP_LAPIS",
"GROUP_QUARTZ",
"GROUP_REDSTONE",
"GROUP_NUGGET",
"GROUP_INGOT"
]
}
]
}
================================================
FILE: data/sound_config.json
================================================
{
"soundGroup": [
{ "step_grass": [ "step_snow1", "step_snow2", "step_snow3", "step_snow4" ] },
{ "step_stone": [ "step_stone1", "step_stone2", "step_stone3", "step_stone4", "step_stone5", "step_stone6" ] },
{ "step_wood": [ "step_wood1", "step_wood2", "step_wood3", "step_wood4", "step_wood5", "step_wood6" ] },
{ "step_snow": [ "step_snow1", "step_snow2", "step_snow3", "step_snow4" ] },
{ "dirt": [ "dirt1", "dirt2", "dirt3" ] },
{ "sand": [ "sand1", "sand2", "sand3" ] },
{ "stone": [ "stone1", "stone2", "stone3" ] },
{ "wood": [ "wood1", "wood2", "wood3" ] },
{ "snow": [ "snow1", "snow2", "snow3" ] },
{ "grass": [ "grass1", "grass2", "grass3" ] },
{ "shatter": [ "shatter1", "shatter2", "shatter3" ] },
{ "glass": [ "glass1", "glass2", "glass3" ] },
{ "cloth": [ "cloth1", "cloth2", "cloth3" ] },
{ "tink": [ "tink1", "tink2", "tink3" ] },
{ "swim": [ "swim1", "swim2", "swim3", "swim4" ] },
{ "farm": [ "sand1", "sand2", "sand3" ] },
{ "strip": [ "strip1", "strip2", "strip3", "strip4" ] },
{ "door": [ "door1", "door2" ] },
{ "explode": [ "explode1", "explode2", "explode3", "explode4" ] },
{ "portal": [ "portal", "portal2" ] },
{ "hit": [ "hit1", "hit2", "hit3" ] },
{ "eat": [ "eat1", "eat2", "eat3" ] },
{ "thunder": [ "thunder1", "thunder2", "thunder3" ] },
{ "rain": [ "rain1", "rain2", "rain3", "rain4" ] },
{ "wand": [ "wand1", "wand2", "wand3" ] },
{ "thorns_hit": [ "thorns_hit1", "thorns_hit2", "thorns_hit3", "thorns_hit4" ] },
{ "enchant": [ "enchant1", "enchant2", "enchant3" ] }
]
}
================================================
FILE: data/sounds.json
================================================
[
{
"sys3": {
"path": "sounds/sys3.ogg"
}
},
{
"cannon": {
"path": "sounds/cannon.ogg"
}
},
{
"pop": {
"path": "sounds/pop.ogg"
}
},
{
"stone1": {
"path": "sounds/stone1.ogg"
}
},
{
"stone2": {
"path": "sounds/stone2.ogg"
}
},
{
"stone3": {
"path": "sounds/stone3.ogg"
}
},
{
"dirt1": {
"path": "sounds/dirt1.ogg"
}
},
{
"dirt2": {
"path": "sounds/dirt2.ogg"
}
},
{
"dirt3": {
"path": "sounds/dirt3.ogg"
}
},
{
"wood1": {
"path": "sounds/wood1.ogg"
}
},
{
"wood2": {
"path": "sounds/wood2.ogg"
}
},
{
"wood3": {
"path": "sounds/wood3.ogg"
}
},
{
"grass1": {
"path": "sounds/grass1.ogg"
}
},
{
"grass2": {
"path": "sounds/grass2.ogg"
}
},
{
"grass3": {
"path": "sounds/grass3.ogg"
}
},
{
"cloth1": {
"path": "sounds/cloth1.ogg"
}
},
{
"cloth2": {
"path": "sounds/cloth2.ogg"
}
},
{
"cloth3": {
"path": "sounds/cloth3.ogg"
}
},
{
"sand1": {
"path": "sounds/sand1.ogg"
}
},
{
"sand2": {
"path": "sounds/sand2.ogg"
}
},
{
"sand3": {
"path": "sounds/sand3.ogg"
}
},
{
"step_cloth": {
"path": "sounds/step_cloth.ogg"
}
},
{
"step_grass1": {
"path": "sounds/step_grass1.ogg"
}
},
{
"step_grass2": {
"path": "sounds/step_grass2.ogg"
}
},
{
"step_grass3": {
"path": "sounds/step_grass3.ogg"
}
},
{
"step_grass4": {
"path": "sounds/step_grass4.ogg"
}
},
{
"step_grass5": {
"path": "sounds/step_grass5.ogg"
}
},
{
"step_grass6": {
"path": "sounds/step_grass6.ogg"
}
},
{
"step_ladder": {
"path": "sounds/step_ladder.ogg"
}
},
{
"step_sand": {
"path": "sounds/step_sand.ogg"
}
},
{
"step_snow1": {
"path": "sounds/step_snow1.ogg"
}
},
{
"step_snow2": {
"path": "sounds/step_snow2.ogg"
}
},
{
"step_snow3": {
"path": "sounds/step_snow3.ogg"
}
},
{
"step_snow4": {
"path": "sounds/step_snow4.ogg"
}
},
{
"step_stone1": {
"path": "sounds/step_stone1.ogg"
}
},
{
"step_stone2": {
"path": "sounds/step_stone2.ogg"
}
},
{
"step_stone3": {
"path": "sounds/step_stone3.ogg"
}
},
{
"step_stone4": {
"path": "sounds/step_stone4.ogg"
}
},
{
"step_stone5": {
"path": "sounds/step_stone5.ogg"
}
},
{
"step_stone6": {
"path": "sounds/step_stone6.ogg"
}
},
{
"step_wood1": {
"path": "sounds/step_wood1.ogg"
}
},
{
"step_wood2": {
"path": "sounds/step_wood2.ogg"
}
},
{
"step_wood3": {
"path": "sounds/step_wood3.ogg"
}
},
{
"step_wood4": {
"path": "sounds/step_wood4.ogg"
}
},
{
"step_wood5": {
"path": "sounds/step_wood5.ogg"
}
},
{
"step_wood6": {
"path": "sounds/step_wood6.ogg"
}
},
{
"bowhit": {
"path": "sounds/bowhit.ogg"
}
},
{
"bow": {
"path": "sounds/bow.ogg"
}
},
{
"explode1": {
"path": "sounds/explode1.ogg"
}
},
{
"explode2": {
"path": "sounds/explode2.ogg"
}
},
{
"explode3": {
"path": "sounds/explode3.ogg"
}
},
{
"explode4": {
"path": "sounds/explode4.ogg"
}
},
{
"launch": {
"path": "sounds/launch.ogg"
}
},
{
"broken": {
"path": "sounds/broken.ogg"
}
},
{
"chest": {
"path": "sounds/chest.ogg"
}
},
{
"chestclosed": {
"path": "sounds/chestclosed.ogg"
}
},
{
"glass1": {
"path": "sounds/glass1.ogg"
}
},
{
"glass2": {
"path": "sounds/glass2.ogg"
}
},
{
"glass3": {
"path": "sounds/glass3.ogg"
}
},
{
"button1": {
"path": "sounds/button1.ogg"
}
},
{
"door1": {
"path": "sounds/door1.ogg"
}
},
{
"door2": {
"path": "sounds/door2.ogg"
}
},
{
"hit1": {
"path": "sounds/hit1.ogg"
}
},
{
"hit2": {
"path": "sounds/hit2.ogg"
}
},
{
"hit3": {
"path": "sounds/hit3.ogg"
}
},
{
"creeper1": {
"path": "sounds/creeper1.ogg"
}
},
{
"creeper2": {
"path": "sounds/creeper2.ogg"
}
},
{
"creeper3": {
"path": "sounds/creeper3.ogg"
}
},
{
"creeper_death": {
"path": "sounds/creeper_death.ogg"
}
},
{
"slime_attack1": {
"path": "sounds/slime_attack1.ogg"
}
},
{
"slime_attack2": {
"path": "sounds/slime_attack2.ogg"
}
},
{
"splash": {
"path": "sounds/splash.ogg"
}
},
{
"lavapop": {
"path": "sounds/lavapop.ogg"
}
},
{
"pig_death": {
"path": "sounds/pig_death.ogg"
}
},
{
"pig_say1": {
"path": "sounds/pig_say1.ogg"
}
},
{
"pig_say2": {
"path": "sounds/pig_say2.ogg"
}
},
{
"pig_say3": {
"path": "sounds/pig_say3.ogg"
}
},
{
"zombie_death": {
"path": "sounds/zombie_death.ogg"
}
},
{
"zombie_say1": {
"path": "sounds/zombie_say1.ogg"
}
},
{
"zombie_say2": {
"path": "sounds/zombie_say2.ogg"
}
},
{
"zombie_say3": {
"path": "sounds/zombie_say3.ogg"
}
},
{
"zombie_hurt1": {
"path": "sounds/zombie_hurt1.ogg"
}
},
{
"zombie_hurt2": {
"path": "sounds/zombie_hurt2.ogg"
}
},
{
"skeleton_death": {
"path": "sounds/skeleton_death.ogg"
}
},
{
"skeleton1": {
"path": "sounds/skeleton1.ogg"
}
},
{
"skeleton2": {
"path": "sounds/skeleton2.ogg"
}
},
{
"skeleton3": {
"path": "sounds/skeleton3.ogg"
}
},
{
"spider_death": {
"path": "sounds/spider_death.ogg"
}
},
{
"spider_say1": {
"path": "sounds/spider_say1.ogg"
}
},
{
"spider_say2": {
"path": "sounds/spider_say2.ogg"
}
},
{
"spider_say3": {
"path": "sounds/spider_say3.ogg"
}
},
{
"bat_death": {
"path": "sounds/bat_death.ogg"
}
},
{
"bat_hurt1": {
"path": "sounds/bat_hurt1.ogg"
}
},
{
"bat_hurt2": {
"path": "sounds/bat_hurt2.ogg"
}
},
{
"bat_hurt3": {
"path": "sounds/bat_hurt3.ogg"
}
},
{
"chicken_say1": {
"path": "sounds/chicken_say1.ogg"
}
},
{
"chicken_say2": {
"path": "sounds/chicken_say2.ogg"
}
},
{
"chicken_say3": {
"path": "sounds/chicken_say3.ogg"
}
},
{
"chicken_hurt1": {
"path": "sounds/chicken_hurt1.ogg"
}
},
{
"chicken_hurt2": {
"path": "sounds/chicken_hurt2.ogg"
}
},
{
"sheep_say1": {
"path": "sounds/sheep_say1.ogg"
}
},
{
"sheep_say2": {
"path": "sounds/sheep_say2.ogg"
}
},
{
"sheep_say3": {
"path": "sounds/sheep_say3.ogg"
}
},
{
"cow_say1": {
"path": "sounds/cow_say1.ogg"
}
},
{
"cow_say2": {
"path": "sounds/cow_say2.ogg"
}
},
{
"cow_say3": {
"path": "sounds/cow_say3.ogg"
}
},
{
"cow_hurt1": {
"path": "sounds/cow_hurt1.ogg"
}
},
{
"cow_hurt2": {
"path": "sounds/cow_hurt2.ogg"
}
},
{
"cow_hurt3": {
"path": "sounds/cow_hurt3.ogg"
}
},
{
"cat_meow1": {
"path": "sounds/cat_meow1.ogg"
}
},
{
"cat_meow2": {
"path": "sounds/cat_meow2.ogg"
}
},
{
"cat_meow3": {
"path": "sounds/cat_meow3.ogg"
}
},
{
"cat_hit1": {
"path": "sounds/cat_hit1.ogg"
}
},
{
"cat_hit2": {
"path": "sounds/cat_hit2.ogg"
}
},
{
"cat_hit3": {
"path": "sounds/cat_hit3.ogg"
}
},
{
"rabbit_hurt1": {
"path": "sounds/rabbit_hurt1.ogg"
}
},
{
"rabbit_hurt2": {
"path": "sounds/rabbit_hurt2.ogg"
}
},
{
"rabbit_hurt3": {
"path": "sounds/rabbit_hurt3.ogg"
}
},
{
"turtle_hurt1": {
"path": "sounds/turtle_hurt1.ogg"
}
},
{
"turtle_hurt2": {
"path": "sounds/turtle_hurt2.ogg"
}
},
{
"turtle_hurt3": {
"path": "sounds/turtle_hurt3.ogg"
}
},
{
"turtle_death": {
"path": "sounds/turtle_death.ogg"
}
},
{
"villager_say1": {
"path": "sounds/villager_say1.ogg"
}
},
{
"villager_say2": {
"path": "sounds/villager_say2.ogg"
}
},
{
"villager_say3": {
"path": "sounds/villager_say3.ogg"
}
},
{
"villager_hit1": {
"path": "sounds/villager_hit1.ogg"
}
},
{
"villager_hit2": {
"path": "sounds/villager_hit2.ogg"
}
},
{
"villager_hit3": {
"path": "sounds/villager_hit3.ogg"
}
},
{
"villager_death": {
"path": "sounds/villager_death.ogg"
}
},
{
"fuse": {
"path": "sounds/fuse.ogg"
}
},
{
"pufferfish_hurt1": {
"path": "sounds/pufferfish_hurt1.ogg"
}
},
{
"pufferfish_hurt2": {
"path": "sounds/pufferfish_hurt2.ogg"
}
},
{
"dolphin_hurt1": {
"path": "sounds/dolphin_hurt1.ogg"
}
},
{
"dolphin_hurt2": {
"path": "sounds/dolphin_hurt2.ogg"
}
},
{
"dolphin_hurt3": {
"path": "sounds/dolphin_hurt3.ogg"
}
},
{
"wolf_hurt1": {
"path": "sounds/wolf_hurt1.ogg"
}
},
{
"wolf_hurt2": {
"path": "sounds/wolf_hurt2.ogg"
}
},
{
"wolf_hurt3": {
"path": "sounds/wolf_hurt3.ogg"
}
},
{
"wolf_bark1": {
"path": "sounds/wolf_bark1.ogg"
}
},
{
"wolf_bark2": {
"path": "sounds/wolf_bark2.ogg"
}
},
{
"wolf_bark3": {
"path": "sounds/wolf_bark3.ogg"
}
},
{
"wolf_death": {
"path": "sounds/wolf_death.ogg"
}
},
{
"enderman_death": {
"path": "sounds/enderman_death.ogg"
}
},
{
"enderman_hit1": {
"path": "sounds/enderman_hit1.ogg"
}
},
{
"enderman_hit2": {
"path": "sounds/enderman_hit2.ogg"
}
},
{
"enderman_hit3": {
"path": "sounds/enderman_hit3.ogg"
}
},
{
"enderman_idle1": {
"path": "sounds/enderman_idle1.ogg"
}
},
{
"enderman_idle2": {
"path": "sounds/enderman_idle2.ogg"
}
},
{
"enderman_idle3": {
"path": "sounds/enderman_idle3.ogg"
}
},
{
"portal": {
"path": "sounds/portal.ogg"
}
},
{
"portal2": {
"path": "sounds/portal2.ogg"
}
},
{
"zpig1": {
"path": "sounds/zpig1.ogg"
}
},
{
"zpig2": {
"path": "sounds/zpig2.ogg"
}
},
{
"zpig3": {
"path": "sounds/zpig3.ogg"
}
},
{
"zpighurt1": {
"path": "sounds/zpighurt1.ogg"
}
},
{
"zpighurt2": {
"path": "sounds/zpighurt2.ogg"
}
},
{
"zpigdeath": {
"path": "sounds/zpigdeath.ogg"
}
},
{
"blaze_death": {
"path": "sounds/blaze_death.ogg"
}
},
{
"blaze_hit1": {
"path": "sounds/blaze_hit1.ogg"
}
},
{
"blaze_hit2": {
"path": "sounds/blaze_hit2.ogg"
}
},
{
"blaze_hit3": {
"path": "sounds/blaze_hit3.ogg"
}
},
{
"fireball": {
"path": "sounds/fireball.ogg"
}
},
{
"affectionate_scream": {
"path": "sounds/affectionate_scream.ogg"
}
},
{
"ghast_charge": {
"path": "sounds/ghast_charge.ogg"
}
},
{
"ghast_death": {
"path": "sounds/ghast_death.ogg"
}
},
{
"ghast_moan1": {
"path": "sounds/ghast_moan1.ogg"
}
},
{
"ghast_moan2": {
"path": "sounds/ghast_moan2.ogg"
}
},
{
"ghast_moan3": {
"path": "sounds/ghast_moan3.ogg"
}
},
{
"phantom_death": {
"path": "sounds/phantom_death.ogg"
}
},
{
"phantom_hurt1": {
"path": "sounds/phantom_hurt1.ogg"
}
},
{
"phantom_hurt2": {
"path": "sounds/phantom_hurt2.ogg"
}
},
{
"phantom_hurt3": {
"path": "sounds/phantom_hurt3.ogg"
}
},
{
"shulker_open": {
"path": "sounds/shulker_open.ogg"
}
},
{
"shulker_close": {
"path": "sounds/shulker_close.ogg"
}
},
{
"shulker_hit1": {
"path": "sounds/shulker_hit1.ogg"
}
},
{
"orb": {
"path": "sounds/orb.ogg"
}
},
{
"levelup": {
"path": "sounds/levelup.ogg"
}
},
{
"drink": {
"path": "sounds/drink.ogg"
}
},
{
"eat1": {
"path": "sounds/eat1.ogg"
}
},
{
"eat2": {
"path": "sounds/eat2.ogg"
}
},
{
"eat3": {
"path": "sounds/eat3.ogg"
}
},
{
"system1": {
"path": "sounds/system1.ogg"
}
},
{
"anvil_use": {
"path": "sounds/anvil_use.ogg"
}
},
{
"shear": {
"path": "sounds/shear.ogg"
}
},
{
"swim1": {
"path": "sounds/swim1.ogg"
}
},
{
"swim2": {
"path": "sounds/swim2.ogg"
}
},
{
"swim3": {
"path": "sounds/swim3.ogg"
}
},
{
"swim4": {
"path": "sounds/swim4.ogg"
}
},
{
"system2": {
"path": "sounds/system2.ogg"
}
},
{
"shotgun_fire": {
"path": "sounds/shotgun_fire.ogg"
}
},
{
"click": {
"path": "sounds/click.ogg"
}
},
{
"female_hit1": {
"path": "sounds/female_hit1.ogg"
}
},
{
"female_hit2": {
"path": "sounds/female_hit2.ogg"
}
},
{
"female_hit3": {
"path": "sounds/female_hit3.ogg"
}
},
{
"shatter1": {
"path": "sounds/shatter1.ogg"
}
},
{
"tink1": {
"path": "sounds/tink1.ogg"
}
},
{
"tink2": {
"path": "sounds/tink2.ogg"
}
},
{
"tink3": {
"path": "sounds/tink3.ogg"
}
},
{
"rain1": {
"path": "sounds/rain1.ogg"
}
},
{
"rain2": {
"path": "sounds/rain2.ogg"
}
},
{
"rain3": {
"path": "sounds/rain3.ogg"
}
},
{
"rain4": {
"path": "sounds/rain4.ogg"
}
},
{
"thunder1": {
"path": "sounds/thunder1.ogg"
}
},
{
"thunder2": {
"path": "sounds/thunder2.ogg"
}
},
{
"thunder3": {
"path": "sounds/thunder3.ogg"
}
},
{
"grass": {
"path": "sounds/grass.ogg"
}
},
{
"weapon": {
"path": "sounds/weapon.ogg"
}
},
{
"anvil_land": {
"path": "sounds/anvil_land.ogg"
}
},
{
"bazooka_fire": {
"path": "sounds/bazooka_fire.ogg"
}
},
{
"chain_gun_fire": {
"path": "sounds/chain_gun_fire.ogg"
}
},
{
"grenade_fire": {
"path": "sounds/grenade_fire.ogg"
}
},
{
"pistol_fire": {
"path": "sounds/pistol_fire.ogg"
}
},
{
"rifle_fire": {
"path": "sounds/rifle_fire.ogg"
}
},
{
"snow1": {
"path": "sounds/snow1.ogg"
}
},
{
"snow2": {
"path": "sounds/snow2.ogg"
}
},
{
"snow3": {
"path": "sounds/snow3.ogg"
}
},
{
"shatter2": {
"path": "sounds/shatter2.ogg"
}
},
{
"shatter3": {
"path": "sounds/shatter3.ogg"
}
},
{
"strip1": {
"path": "sounds/strip1.ogg"
}
},
{
"strip2": {
"path": "sounds/strip2.ogg"
}
},
{
"strip3": {
"path": "sounds/strip3.ogg"
}
},
{
"strip4": {
"path": "sounds/strip4.ogg"
}
},
{
"barrel_open": {
"path": "sounds/barrel_open.ogg"
}
},
{
"shulker_box_open": {
"path": "sounds/shulker_box_open.ogg"
}
},
{
"monster": {
"path": "sounds/monster.ogg"
}
},
{
"attack1": {
"path": "sounds/attack1.ogg"
}
},
{
"attack2": {
"path": "sounds/attack2.ogg"
}
},
{
"fireball2": {
"path": "sounds/fireball2.ogg"
}
},
{
"laser": {
"path": "sounds/laser.ogg"
}
},
{
"wand1": {
"path": "sounds/wand1.ogg"
}
},
{
"wand2": {
"path": "sounds/wand2.ogg"
}
},
{
"wand3": {
"path": "sounds/wand3.ogg"
}
},
{
"gore1": {
"path": "sounds/gore1.ogg"
}
},
{
"gore2": {
"path": "sounds/gore2.ogg"
}
},
{
"gore3": {
"path": "sounds/gore3.ogg"
}
},
{
"thorns_hit1": {
"path": "sounds/thorns_hit1.ogg"
}
},
{
"thorns_hit2": {
"path": "sounds/thorns_hit2.ogg"
}
},
{
"thorns_hit3": {
"path": "sounds/thorns_hit3.ogg"
}
},
{
"thorns_hit4": {
"path": "sounds/thorns_hit4.ogg"
}
},
{
"enchant1": {
"path": "sounds/enchant1.ogg"
}
},
{
"enchant2": {
"path": "sounds/enchant2.ogg"
}
},
{
"enchant3": {
"path": "sounds/enchant3.ogg"
}
},
{
"travel": {
"path": "sounds/travel.ogg"
}
},
{
"trigger": {
"path": "sounds/trigger.ogg"
}
}
]
================================================
FILE: effect_ai/Explosion.json
================================================
{
"Explosion": {
"pAI": "Explosion_AI"
}
}
================================================
FILE: effect_ai/GlowingFlow.json
================================================
{
"GlowingFlow": {
"ai": "GlowingFlow"
}
}
================================================
FILE: effect_ai/Gore.json
================================================
{
"Gore": {
"pAI": "Gore_AI"
}
}
================================================
FILE: effect_ai/Smoke.json
================================================
{
"Smoke": {}
}
================================================
FILE: effects/arrow_paticular.json
================================================
{
"arrow_paticular": {
"ai": "Smoke",
"textureData": "chip.png",
"width": 6,
"height": 6,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"gfxWidth": 6,
"gfxHeight": 6,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 72,
"isForeground": false,
"gravity": false,
"collisionWithBlocks": false,
"fixByBlocks": false,
"fadeScale": true,
"fadeAlpha": true,
"slowSpeed": true,
"slowRotateSpeed": true
}
}
================================================
FILE: effects/chasting_word.json
================================================
{
"chasting_word": {
"ai": "Smoke",
"textureData": "heal.png",
"width": 12,
"height": 12,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"gfxWidth": 12,
"gfxHeight": 12,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 72,
"isForeground": true,
"gravity": false,
"collisionWithBlocks": false,
"fixByBlocks": false,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/chip.json
================================================
{
"chip": {
"ai": "Smoke",
"textureData": "chip.png",
"width": 6,
"height": 6,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"gfxWidth": 6,
"gfxHeight": 6,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 160,
"isForeground": true,
"gravity": true,
"collisionWithBlocks": false,
"fixByBlocks": false,
"fadeScale": true,
"fadeAlpha": true,
"slowSpeed": true,
"slowRotateSpeed": true,
"isLighting": true
}
}
================================================
FILE: effects/chip_fast.json
================================================
{
"chip_fast": {
"ai": "Smoke",
"textureData": "chip.png",
"width": 6,
"height": 6,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"gfxWidth": 6,
"gfxHeight": 6,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 64,
"isForeground": true,
"gravity": true,
"collisionWithBlocks": false,
"fixByBlocks": false,
"fadeScale": true,
"fadeAlpha": true,
"slowSpeed": true,
"slowRotateSpeed": true,
"isLighting": true
}
}
================================================
FILE: effects/circle.json
================================================
{
"circle": {
"ai": "Smoke",
"textureData": "circle.png",
"width": 32,
"height": 32,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"gfxWidth": 32,
"gfxHeight": 32,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 48,
"isForeground": true,
"gravity": false,
"collisionWithBlocks": false,
"fixByBlocks": false,
"fadeScale": true,
"fadeAlpha": true,
"isLighting": true,
"slowSpeed": true,
"slowRotateSpeed": true,
"lightColor": [ 26, 0, 0, 0 ]
}
}
================================================
FILE: effects/ender_flash.json
================================================
{
"ender_flash": {
"ai": "Smoke",
"textureData": "ender_flash.png",
"width": 6,
"height": 6,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"gfxWidth": 6,
"gfxHeight": 6,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 72,
"isForeground": true,
"gravity": false,
"collisionWithBlocks": false,
"fixByBlocks": false,
"fadeScale": true,
"fadeAlpha": true,
"slowSpeed": true,
"slowRotateSpeed": true,
"isLighting": true,
"lightColor": [ 24, 0, 0, 8 ]
}
}
================================================
FILE: effects/exp_paticular.json
================================================
{
"exp_paticular": {
"ai": "Smoke",
"textureData": "liquid_paticular.png",
"width": 6,
"height": 6,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"gfxWidth": 6,
"gfxHeight": 6,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 160,
"isForeground": true,
"gravity": false,
"collisionWithBlocks": false,
"fixByBlocks": false,
"fadeScale": true,
"fadeAlpha": true,
"slowSpeed": true,
"slowRotateSpeed": true
}
}
================================================
FILE: effects/explosion.json
================================================
{
"explosion": {
"ai": "Explosion",
"textureData": "explosion.png",
"width": 64,
"height": 64,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"gfxWidth": 64,
"gfxHeight": 64,
"frameStyle": 0,
"frameStyles": 1,
"frames": 16,
"frameSpeed": 2,
"disappearTime": 32,
"isForeground": true,
"gravity": false,
"collisionWithBlocks": false,
"fixByBlocks": false,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/fallen_flame_star.json
================================================
{
"fallen_flame_star": {
"ai": "Smoke",
"textureData": "flame_star.png",
"width": 6,
"height": 6,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"gfxWidth": 6,
"gfxHeight": 6,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 72,
"isForeground": true,
"gravity": true,
"collisionWithBlocks": false,
"fixByBlocks": false,
"fadeScale": true,
"fadeAlpha": true,
"isLighting": true,
"slowSpeed": true,
"slowRotateSpeed": true,
"lightColor": [ 20, 0, 0, 0 ]
}
}
================================================
FILE: effects/fire.json
================================================
{
"fire": {
"ai": "Smoke",
"textureData": "fire.png",
"width": 16,
"height": 16,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"gfxWidth": 16,
"gfxHeight": 16,
"frameStyle": 0,
"frameStyles": 1,
"frames": 4,
"frameSpeed": 8,
"disappearTime": 120,
"isForeground": true,
"gravity": false,
"collisionWithBlocks": false,
"fixByBlocks": false,
"fadeScale": true,
"fadeAlpha": true,
"isLighting": true,
"slowSpeed": true,
"slowRotateSpeed": true,
"lightColor": [ 20, 6, 6, 0 ]
}
}
================================================
FILE: effects/fire_flame.json
================================================
{
"fire_flame": {
"ai": "Smoke",
"textureData": "fire_flame.png",
"width": 16,
"height": 16,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"gfxWidth": 16,
"gfxHeight": 16,
"frameStyle": 0,
"frameStyles": 3,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 80,
"isForeground": true,
"gravity": false,
"collisionWithBlocks": false,
"fixByBlocks": false,
"fadeScale": true,
"fadeAlpha": false,
"slowSpeed": true,
"slowRotateSpeed": true,
"isLighting": true,
"lightColor": [ 28, 12, 8, 0 ]
}
}
================================================
FILE: effects/fire_flame_long.json
================================================
{
"fire_flame_long": {
"ai": "Smoke",
"textureData": "fire_flame.png",
"width": 16,
"height": 16,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"gfxWidth": 16,
"gfxHeight": 16,
"frameStyle": 0,
"frameStyles": 3,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 300,
"isForeground": true,
"gravity": false,
"collisionWithBlocks": false,
"fixByBlocks": false,
"fadeScale": true,
"fadeAlpha": false,
"slowSpeed": true,
"slowRotateSpeed": true,
"isLighting": true,
"lightColor": [ 28, 12, 8, 0 ]
}
}
================================================
FILE: effects/fire_smoke.json
================================================
{
"fire_smoke": {
"ai": "Smoke",
"textureData": "fire_smoke.png",
"width": 16,
"height": 16,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"gfxWidth": 16,
"gfxHeight": 16,
"frameStyle": 0,
"frameStyles": 3,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 80,
"isForeground": true,
"gravity": false,
"collisionWithBlocks": false,
"fixByBlocks": false,
"fadeScale": true,
"fadeAlpha": true,
"slowSpeed": false,
"slowRotateSpeed": true,
"isLighting": true
}
}
================================================
FILE: effects/flame_star.json
================================================
{
"flame_star": {
"ai": "Smoke",
"textureData": "flame_star.png",
"width": 6,
"height": 6,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"gfxWidth": 6,
"gfxHeight": 6,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 72,
"isForeground": true,
"gravity": false,
"collisionWithBlocks": false,
"fixByBlocks": false,
"fadeScale": true,
"fadeAlpha": true,
"isLighting": true,
"slowSpeed": true,
"slowRotateSpeed": true,
"lightColor": [ 20, 0, 0, 0 ]
}
}
================================================
FILE: effects/flash.json
================================================
{
"flash": {
"ai": "Smoke",
"textureData": "flash.png",
"width": 6,
"height": 6,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"gfxWidth": 6,
"gfxHeight": 6,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 32,
"isForeground": true,
"gravity": false,
"collisionWithBlocks": false,
"fixByBlocks": false,
"fadeScale": true,
"fadeAlpha": true,
"isLighting": true,
"slowSpeed": true,
"slowRotateSpeed": true,
"lightColor": [ 24, 0, 0, 0 ]
}
}
================================================
FILE: effects/flash2.json
================================================
{
"flash2": {
"ai": "Smoke",
"textureData": "flash2.png",
"width": 14,
"height": 14,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"gfxWidth": 14,
"gfxHeight": 14,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 32,
"isForeground": true,
"gravity": false,
"collisionWithBlocks": false,
"fixByBlocks": false,
"fadeScale": true,
"fadeAlpha": true,
"isLighting": true,
"slowSpeed": true,
"slowRotateSpeed": true,
"lightColor": [ 24, 0, 0, 0 ]
}
}
================================================
FILE: effects/flow_particular.json
================================================
{
"flow_particular": {
"ai": "GlowingFlow",
"textureData": "flow_particular.png",
"width": 8,
"height": 8,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"gfxWidth": 8,
"gfxHeight": 8,
"frameStyle": 0,
"frameStyles": 1,
"frames": 4,
"frameSpeed": 8,
"disappearTime": 180,
"isForeground": true,
"gravity": false,
"collisionWithBlocks": false,
"fixByBlocks": false,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false,
"isLighting": true,
"lightColor": [ 28, 0, 0, 0 ]
}
}
================================================
FILE: effects/gores/gore_angry_skeleton.json
================================================
{
"gore_angry_skeleton": {
"ai": "Gore",
"textureData": "angry_skeleton.png",
"width": 20,
"height": 20,
"gfxOffsetX": -2,
"gfxOffsetY": 0,
"gfxWidth": 24,
"gfxHeight": 20,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 600,
"isForeground": false,
"gravity": true,
"collisionWithBlocks": true,
"fixByBlocks": true,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/gores/gore_arrow_zombie.json
================================================
{
"gore_arrow_zombie": {
"ai": "Gore",
"textureData": "arrow_zombie.png",
"width": 24,
"height": 24,
"gfxOffsetX": -12,
"gfxOffsetY": -1,
"gfxWidth": 48,
"gfxHeight": 26,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 600,
"isForeground": false,
"gravity": true,
"collisionWithBlocks": true,
"fixByBlocks": true,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/gores/gore_bald_zombie.json
================================================
{
"gore_bald_zombie": {
"ai": "Gore",
"textureData": "bald_zombie.png",
"width": 20,
"height": 20,
"gfxOffsetX": -1,
"gfxOffsetY": -2,
"gfxWidth": 22,
"gfxHeight": 24,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 600,
"isForeground": false,
"gravity": true,
"collisionWithBlocks": true,
"fixByBlocks": true,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/gores/gore_bat.json
================================================
{
"gore_bat": {
"ai": "Gore",
"textureData": "bat.png",
"width": 20,
"height": 20,
"gfxOffsetX": -3,
"gfxOffsetY": -2,
"gfxWidth": 26,
"gfxHeight": 24,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 600,
"isForeground": false,
"gravity": true,
"collisionWithBlocks": true,
"fixByBlocks": true,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/gores/gore_black_rabbit.json
================================================
{
"gore_black_rabbit": {
"ai": "Gore",
"textureData": "black_rabbit.png",
"width": 16,
"height": 16,
"gfxOffsetX": 0,
"gfxOffsetY": -1,
"gfxWidth": 16,
"gfxHeight": 18,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 600,
"isForeground": false,
"gravity": true,
"collisionWithBlocks": true,
"fixByBlocks": true,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/gores/gore_black_skeleton.json
================================================
{
"gore_black_skeleton": {
"ai": "Gore",
"textureData": "black_skeleton.png",
"width": 20,
"height": 20,
"gfxOffsetX": -2,
"gfxOffsetY": 0,
"gfxWidth": 24,
"gfxHeight": 20,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 600,
"isForeground": false,
"gravity": true,
"collisionWithBlocks": true,
"fixByBlocks": true,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/gores/gore_blood_bat.json
================================================
{
"gore_blood_bat": {
"ai": "Gore",
"textureData": "blood_bat.png",
"width": 20,
"height": 20,
"gfxOffsetX": -1,
"gfxOffsetY": -1,
"gfxWidth": 22,
"gfxHeight": 22,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 600,
"isForeground": false,
"gravity": true,
"collisionWithBlocks": true,
"fixByBlocks": true,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/gores/gore_blood_eye.json
================================================
{
"gore_blood_eye": {
"ai": "Gore",
"textureData": "blood_eye.png",
"width": 20,
"height": 20,
"gfxOffsetX": -10,
"gfxOffsetY": -10,
"gfxWidth": 40,
"gfxHeight": 40,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 600,
"isForeground": false,
"gravity": true,
"collisionWithBlocks": true,
"fixByBlocks": true,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/gores/gore_blood_skeleton.json
================================================
{
"gore_blood_skeleton": {
"ai": "Gore",
"textureData": "blood_skeleton.png",
"width": 20,
"height": 20,
"gfxOffsetX": -2,
"gfxOffsetY": 0,
"gfxWidth": 24,
"gfxHeight": 20,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 600,
"isForeground": false,
"gravity": true,
"collisionWithBlocks": true,
"fixByBlocks": true,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/gores/gore_bone_lee.json
================================================
{
"gore_bone_lee": {
"ai": "Gore",
"textureData" : "bone_lee.png",
"width" : 20,
"height" : 20,
"gfxOffsetX" : -4,
"gfxOffsetY" : 0,
"gfxWidth" : 28,
"gfxHeight" : 20,
"frameStyle" : 0,
"frameStyles" : 1,
"frames" : 1,
"frameSpeed" : 8,
"disappearTime" : 600,
"isForeground" : false,
"gravity" : true,
"collisionWithBlocks" : true,
"fixByBlocks" : true,
"fadeScale" : false,
"fadeAlpha" : false,
"slowSpeed" : false,
"slowRotateSpeed" : false
}
}
================================================
FILE: effects/gores/gore_bone_officer.json
================================================
{
"gore_bone_officer": {
"ai": "Gore",
"textureData" : "bone_officer.png",
"width" : 20,
"height" : 20,
"gfxOffsetX" : -6,
"gfxOffsetY" : -3,
"gfxWidth" : 32,
"gfxHeight" : 26,
"frameStyle" : 0,
"frameStyles" : 1,
"frames" : 1,
"frameSpeed" : 8,
"disappearTime" : 600,
"isForeground" : false,
"gravity" : true,
"collisionWithBlocks" : true,
"fixByBlocks" : true,
"fadeScale" : false,
"fadeAlpha" : false,
"slowSpeed" : false,
"slowRotateSpeed" : false
}
}
================================================
FILE: effects/gores/gore_bone_sniper.json
================================================
{
"gore_bone_sniper": {
"ai": "Gore",
"textureData" : "bone_sniper.png",
"width" : 20,
"height" : 20,
"gfxOffsetX" : -5,
"gfxOffsetY" : -3,
"gfxWidth" : 30,
"gfxHeight" : 26,
"frameStyle" : 0,
"frameStyles" : 1,
"frames" : 1,
"frameSpeed" : 8,
"disappearTime" : 600,
"isForeground" : false,
"gravity" : true,
"collisionWithBlocks" : true,
"fixByBlocks" : true,
"fadeScale" : false,
"fadeAlpha" : false,
"slowSpeed" : false,
"slowRotateSpeed" : false
}
}
================================================
FILE: effects/gores/gore_boney_skeleton.json
================================================
{
"gore_boney_skeleton": {
"ai": "Gore",
"textureData": "boney_skeleton.png",
"width": 20,
"height": 20,
"gfxOffsetX": -8,
"gfxOffsetY": -4,
"gfxWidth": 36,
"gfxHeight": 28,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 600,
"isForeground": false,
"gravity": true,
"collisionWithBlocks": true,
"fixByBlocks": true,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/gores/gore_brown_mushroom_cow.json
================================================
{
"gore_brown_mushroom_cow": {
"ai": "Gore",
"textureData": "brown_mushroom_cow.png",
"width": 32,
"height": 32,
"gfxOffsetX": -4,
"gfxOffsetY": -4,
"gfxWidth": 40,
"gfxHeight": 40,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 600,
"isForeground": false,
"gravity": true,
"collisionWithBlocks": true,
"fixByBlocks": true,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/gores/gore_brown_rabbit.json
================================================
{
"gore_brown_rabbit": {
"ai": "Gore",
"textureData": "brown_rabbit.png",
"width": 16,
"height": 16,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"gfxWidth": 16,
"gfxHeight": 16,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 600,
"isForeground": false,
"gravity": true,
"collisionWithBlocks": true,
"fixByBlocks": true,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/gores/gore_chicken.json
================================================
{
"gore_chicken": {
"ai": "Gore",
"textureData": "chicken.png",
"width": 14,
"height": 14,
"gfxOffsetX": -2,
"gfxOffsetY": 0,
"gfxWidth": 18,
"gfxHeight": 14,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 600,
"isForeground": false,
"gravity": true,
"collisionWithBlocks": true,
"fixByBlocks": true,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/gores/gore_cow.json
================================================
{
"gore_cow": {
"ai": "Gore",
"textureData": "cow.png",
"width": 24,
"height": 24,
"gfxOffsetX": -8,
"gfxOffsetY": -3,
"gfxWidth": 40,
"gfxHeight": 30,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 600,
"isForeground": false,
"gravity": true,
"collisionWithBlocks": true,
"fixByBlocks": true,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/gores/gore_creeper.json
================================================
{
"gore_creeper": {
"ai": "Gore",
"textureData": "creeper.png",
"width": 20,
"height": 20,
"gfxOffsetX": -2,
"gfxOffsetY": 0,
"gfxWidth": 24,
"gfxHeight": 20,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 600,
"isForeground": false,
"gravity": true,
"collisionWithBlocks": true,
"fixByBlocks": true,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/gores/gore_cursed_skull.json
================================================
{
"gore_cursed_skull": {
"ai": "Gore",
"textureData" : "cursed_skull.png",
"width" : 20,
"height" : 20,
"gfxOffsetX" : -3,
"gfxOffsetY" : -2,
"gfxWidth" : 26,
"gfxHeight" : 24,
"frameStyle" : 0,
"frameStyles" : 1,
"frames" : 1,
"frameSpeed" : 8,
"disappearTime" : 600,
"isForeground" : false,
"gravity" : true,
"collisionWithBlocks" : true,
"fixByBlocks" : true,
"fadeScale" : false,
"fadeAlpha" : false,
"slowSpeed" : false,
"slowRotateSpeed" : false
}
}
================================================
FILE: effects/gores/gore_dark_mage.json
================================================
{
"gore_dark_mage": {
"ai": "Gore",
"textureData" : "dark_mage.png",
"width" : 20,
"height" : 20,
"gfxOffsetX" : -2,
"gfxOffsetY" : -1,
"gfxWidth" : 24,
"gfxHeight" : 22,
"frameStyle" : 0,
"frameStyles" : 1,
"frames" : 1,
"frameSpeed" : 8,
"disappearTime" : 600,
"isForeground" : false,
"gravity" : true,
"collisionWithBlocks" : true,
"fixByBlocks" : true,
"fadeScale" : false,
"fadeAlpha" : false,
"slowSpeed" : false,
"slowRotateSpeed" : false
}
}
================================================
FILE: effects/gores/gore_dead_mage.json
================================================
{
"gore_dead_mage": {
"ai": "Gore",
"textureData" : "dead_mage.png",
"width" : 20,
"height" : 20,
"gfxOffsetX" : -6,
"gfxOffsetY" : -7,
"gfxWidth" : 32,
"gfxHeight" : 34,
"frameStyle" : 0,
"frameStyles" : 1,
"frames" : 1,
"frameSpeed" : 8,
"disappearTime" : 600,
"isForeground" : false,
"gravity" : true,
"collisionWithBlocks" : true,
"fixByBlocks" : true,
"fadeScale" : false,
"fadeAlpha" : false,
"slowSpeed" : false,
"slowRotateSpeed" : false
}
}
================================================
FILE: effects/gores/gore_doge_zombie.json
================================================
{
"gore_doge_zombie": {
"ai": "Gore",
"textureData": "doge_zombie.png",
"width": 20,
"height": 20,
"gfxOffsetX": -4,
"gfxOffsetY": -1,
"gfxWidth": 28,
"gfxHeight": 22,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 600,
"isForeground": false,
"gravity": true,
"collisionWithBlocks": true,
"fixByBlocks": true,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/gores/gore_dolphin.json
================================================
{
"gore_dolphin": {
"ai": "Gore",
"textureData": "dolphin.png",
"width": 32,
"height": 32,
"gfxOffsetX": -8,
"gfxOffsetY": -3,
"gfxWidth": 48,
"gfxHeight": 38,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 600,
"isForeground": false,
"gravity": true,
"collisionWithBlocks": true,
"fixByBlocks": true,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/gores/gore_drowned.json
================================================
{
"gore_drowned": {
"ai": "Gore",
"textureData": "drowned.png",
"width": 20,
"height": 20,
"gfxOffsetX": -4,
"gfxOffsetY": -3,
"gfxWidth": 28,
"gfxHeight": 26,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 600,
"isForeground": false,
"gravity": true,
"collisionWithBlocks": true,
"fixByBlocks": true,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/gores/gore_dungeon_creeper.json
================================================
{
"gore_dungeon_creeper": {
"ai": "Gore",
"textureData" : "dungeon_creeper.png",
"width" : 20,
"height" : 20,
"gfxOffsetX" : -6,
"gfxOffsetY" : -12,
"gfxWidth" : 32,
"gfxHeight" : 44,
"frameStyle" : 0,
"frameStyles" : 1,
"frames" : 1,
"frameSpeed" : 8,
"disappearTime" : 600,
"isForeground" : false,
"gravity" : true,
"collisionWithBlocks" : true,
"fixByBlocks" : true,
"fadeScale" : false,
"fadeAlpha" : false,
"slowSpeed" : false,
"slowRotateSpeed" : false
}
}
================================================
FILE: effects/gores/gore_dungeon_knight.json
================================================
{
"gore_dungeon_knight": {
"ai": "Gore",
"textureData" : "dungeon_knight.png",
"width" : 20,
"height" : 20,
"gfxOffsetX" : -6,
"gfxOffsetY" : -6,
"gfxWidth" : 32,
"gfxHeight" : 32,
"frameStyle" : 0,
"frameStyles" : 1,
"frames" : 1,
"frameSpeed" : 8,
"disappearTime" : 600,
"isForeground" : false,
"gravity" : true,
"collisionWithBlocks" : true,
"fixByBlocks" : true,
"fadeScale" : false,
"fadeAlpha" : false,
"slowSpeed" : false,
"slowRotateSpeed" : false
}
}
================================================
FILE: effects/gores/gore_eagle.json
================================================
{
"gore_eagle": {
"ai": "Gore",
"textureData": "eagle.png",
"width": 16,
"height": 16,
"gfxOffsetX": -4,
"gfxOffsetY": -3,
"gfxWidth": 24,
"gfxHeight": 22,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 600,
"isForeground": false,
"gravity": true,
"collisionWithBlocks": true,
"fixByBlocks": true,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/gores/gore_enderman.json
================================================
{
"gore_enderman": {
"ai": "Gore",
"textureData": "enderman.png",
"width": 20,
"height": 20,
"gfxOffsetX": -3,
"gfxOffsetY": -4,
"gfxWidth": 26,
"gfxHeight": 28,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 600,
"isForeground": false,
"gravity": true,
"collisionWithBlocks": true,
"fixByBlocks": true,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/gores/gore_evil.json
================================================
{
"gore_evil": {
"ai": "Gore",
"textureData" : "evil.png",
"width" : 20,
"height" : 20,
"gfxOffsetX" : 0,
"gfxOffsetY" : -1,
"gfxWidth" : 20,
"gfxHeight" : 22,
"frameStyle" : 0,
"frameStyles" : 1,
"frames" : 1,
"frameSpeed" : 8,
"disappearTime" : 600,
"isForeground" : false,
"gravity" : true,
"collisionWithBlocks" : true,
"fixByBlocks" : true,
"fadeScale" : false,
"fadeAlpha" : false,
"slowSpeed" : false,
"slowRotateSpeed" : false
}
}
================================================
FILE: effects/gores/gore_evoker.json
================================================
{
"gore_evoker": {
"ai": "Gore",
"textureData": "evoker.png",
"width": 30,
"height": 30,
"gfxOffsetX": -1,
"gfxOffsetY": 0,
"gfxWidth": 32,
"gfxHeight": 30,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 600,
"isForeground": false,
"gravity": true,
"collisionWithBlocks": true,
"fixByBlocks": true,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/gores/gore_eye_guard.json
================================================
{
"gore_eye_guard": {
"ai": "Gore",
"textureData" : "eye_guard.png",
"width" : 20,
"height" : 20,
"gfxOffsetX" : -14,
"gfxOffsetY" : -38,
"gfxWidth" : 48,
"gfxHeight" : 96,
"frameStyle" : 0,
"frameStyles" : 1,
"frames" : 1,
"frameSpeed" : 8,
"disappearTime" : 600,
"isForeground" : false,
"gravity" : true,
"collisionWithBlocks" : true,
"fixByBlocks" : true,
"fadeScale" : false,
"fadeAlpha" : false,
"slowSpeed" : false,
"slowRotateSpeed" : false
}
}
================================================
FILE: effects/gores/gore_eye_guard_laser.json
================================================
{
"gore_eye_guard_laser": {
"ai": "Gore",
"textureData" : "eye_guard_laser.png",
"width" : 20,
"height" : 20,
"gfxOffsetX" : -14,
"gfxOffsetY" : -38,
"gfxWidth" : 48,
"gfxHeight" : 96,
"frameStyle" : 0,
"frameStyles" : 1,
"frames" : 1,
"frameSpeed" : 8,
"disappearTime" : 600,
"isForeground" : false,
"gravity" : true,
"collisionWithBlocks" : true,
"fixByBlocks" : true,
"fadeScale" : false,
"fadeAlpha" : false,
"slowSpeed" : false,
"slowRotateSpeed" : false
}
}
================================================
FILE: effects/gores/gore_flower_creeper.json
================================================
{
"gore_flower_creeper": {
"ai": "Gore",
"textureData": "flower_creeper.png",
"width": 8,
"height": 8,
"gfxOffsetX": -10,
"gfxOffsetY": -5,
"gfxWidth": 28,
"gfxHeight": 18,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 600,
"isForeground": false,
"gravity": true,
"collisionWithBlocks": true,
"fixByBlocks": true,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/gores/gore_fly_eye.json
================================================
{
"gore_fly_eye": {
"ai": "Gore",
"textureData" : "fly_eye.png",
"width" : 20,
"height" : 20,
"gfxOffsetX" : -2,
"gfxOffsetY" : -4,
"gfxWidth" : 24,
"gfxHeight" : 28,
"frameStyle" : 0,
"frameStyles" : 1,
"frames" : 1,
"frameSpeed" : 8,
"disappearTime" : 600,
"isForeground" : false,
"gravity" : true,
"collisionWithBlocks" : true,
"fixByBlocks" : true,
"fadeScale" : false,
"fadeAlpha" : false,
"slowSpeed" : false,
"slowRotateSpeed" : false
}
}
================================================
FILE: effects/gores/gore_fly_mouth.json
================================================
{
"gore_fly_mouth": {
"ai": "Gore",
"textureData" : "fly_mouth.png",
"width" : 20,
"height" : 20,
"gfxOffsetX" : -2,
"gfxOffsetY" : -4,
"gfxWidth" : 24,
"gfxHeight" : 28,
"frameStyle" : 0,
"frameStyles" : 1,
"frames" : 1,
"frameSpeed" : 8,
"disappearTime" : 600,
"isForeground" : false,
"gravity" : true,
"collisionWithBlocks" : true,
"fixByBlocks" : true,
"fadeScale" : false,
"fadeAlpha" : false,
"slowSpeed" : false,
"slowRotateSpeed" : false
}
}
================================================
FILE: effects/gores/gore_fly_skeleton.json
================================================
{
"gore_fly_skeleton": {
"ai": "Gore",
"textureData" : "fly_skeleton.png",
"width" : 20,
"height" : 20,
"gfxOffsetX" : -6,
"gfxOffsetY" : -7,
"gfxWidth" : 32,
"gfxHeight" : 34,
"frameStyle" : 0,
"frameStyles" : 1,
"frames" : 1,
"frameSpeed" : 8,
"disappearTime" : 600,
"isForeground" : false,
"gravity" : true,
"collisionWithBlocks" : true,
"fixByBlocks" : true,
"fadeScale" : false,
"fadeAlpha" : false,
"slowSpeed" : false,
"slowRotateSpeed" : false
}
}
================================================
FILE: effects/gores/gore_giant_cursed_skull.json
================================================
{
"gore_giant_cursed_skull": {
"ai": "Gore",
"textureData" : "giant_cursed_skull.png",
"width" : 20,
"height" : 20,
"gfxOffsetX" : -12,
"gfxOffsetY" : -14,
"gfxWidth" : 44,
"gfxHeight" : 48,
"frameStyle" : 0,
"frameStyles" : 1,
"frames" : 1,
"frameSpeed" : 8,
"disappearTime" : 600,
"isForeground" : false,
"gravity" : true,
"collisionWithBlocks" : true,
"fixByBlocks" : true,
"fadeScale" : false,
"fadeAlpha" : false,
"slowSpeed" : false,
"slowRotateSpeed" : false
}
}
================================================
FILE: effects/gores/gore_grass_walker.json
================================================
{
"gore_grass_walker": {
"ai": "Gore",
"textureData" : "grass_walker.png",
"width" : 20,
"height" : 20,
"gfxOffsetX" : -5,
"gfxOffsetY" : -6,
"gfxWidth" : 30,
"gfxHeight" : 32,
"frameStyle" : 0,
"frameStyles" : 1,
"frames" : 1,
"frameSpeed" : 8,
"disappearTime" : 600,
"isForeground" : false,
"gravity" : true,
"collisionWithBlocks" : true,
"fixByBlocks" : true,
"fadeScale" : false,
"fadeAlpha" : false,
"slowSpeed" : false,
"slowRotateSpeed" : false
}
}
================================================
FILE: effects/gores/gore_grim_reaper.json
================================================
{
"gore_grim_reaper": {
"ai": "Gore",
"textureData" : "grim_reaper.png",
"width" : 20,
"height" : 20,
"gfxOffsetX" : -2,
"gfxOffsetY" : -1,
"gfxWidth" : 24,
"gfxHeight" : 22,
"frameStyle" : 0,
"frameStyles" : 1,
"frames" : 1,
"frameSpeed" : 8,
"disappearTime" : 600,
"isForeground" : false,
"gravity" : true,
"collisionWithBlocks" : true,
"fixByBlocks" : true,
"fadeScale" : false,
"fadeAlpha" : false,
"slowSpeed" : false,
"slowRotateSpeed" : false
}
}
================================================
FILE: effects/gores/gore_husk.json
================================================
{
"gore_husk": {
"ai": "Gore",
"textureData": "husk.png",
"width": 20,
"height": 20,
"gfxOffsetX": -4,
"gfxOffsetY": -3,
"gfxWidth": 28,
"gfxHeight": 26,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 600,
"isForeground": false,
"gravity": true,
"collisionWithBlocks": true,
"fixByBlocks": true,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/gores/gore_ice_sprite_girl.json
================================================
{
"gore_ice_sprite_girl": {
"ai": "Gore",
"textureData" : "ice_sprite_girl.png",
"width" : 20,
"height" : 20,
"gfxOffsetX" : -6,
"gfxOffsetY" : -5,
"gfxWidth" : 32,
"gfxHeight" : 30,
"frameStyle" : 0,
"frameStyles" : 1,
"frames" : 1,
"frameSpeed" : 8,
"disappearTime" : 600,
"isForeground" : false,
"gravity" : true,
"collisionWithBlocks" : true,
"fixByBlocks" : true,
"fadeScale" : false,
"fadeAlpha" : false,
"slowSpeed" : false,
"slowRotateSpeed" : false
}
}
================================================
FILE: effects/gores/gore_iron_zombie.json
================================================
{
"gore_iron_zombie": {
"ai": "Gore",
"textureData": "iron_zombie.png",
"width": 20,
"height": 20,
"gfxOffsetX": -3,
"gfxOffsetY": -1,
"gfxWidth": 26,
"gfxHeight": 22,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 600,
"isForeground": false,
"gravity": true,
"collisionWithBlocks": true,
"fixByBlocks": true,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/gores/gore_jungle_bat.json
================================================
{
"gore_jungle_bat": {
"ai": "Gore",
"textureData": "jungle_bat.png",
"width": 20,
"height": 20,
"gfxOffsetX": -1,
"gfxOffsetY": -1,
"gfxWidth": 22,
"gfxHeight": 22,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 600,
"isForeground": false,
"gravity": true,
"collisionWithBlocks": true,
"fixByBlocks": true,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/gores/gore_large_bat.json
================================================
{
"gore_large_bat": {
"ai": "Gore",
"textureData" : "large_bat.png",
"width" : 20,
"height" : 20,
"gfxOffsetX" : -5,
"gfxOffsetY" : -5,
"gfxWidth" : 30,
"gfxHeight" : 30,
"frameStyle" : 0,
"frameStyles" : 1,
"frames" : 1,
"frameSpeed" : 8,
"disappearTime" : 600,
"isForeground" : false,
"gravity" : true,
"collisionWithBlocks" : true,
"fixByBlocks" : true,
"fadeScale" : false,
"fadeAlpha" : false,
"slowSpeed" : false,
"slowRotateSpeed" : false
}
}
================================================
FILE: effects/gores/gore_large_jungle_bat.json
================================================
{
"gore_large_jungle_bat": {
"ai": "Gore",
"textureData": "large_jungle_bat.png",
"width": 20,
"height": 20,
"gfxOffsetX": -4,
"gfxOffsetY": -6,
"gfxWidth": 28,
"gfxHeight": 32,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 600,
"isForeground": false,
"gravity": true,
"collisionWithBlocks": true,
"fixByBlocks": true,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/gores/gore_large_spider.json
================================================
{
"gore_large_spider": {
"ai": "Gore",
"textureData" : "large_spider.png",
"width" : 20,
"height" : 20,
"gfxOffsetX" : -2,
"gfxOffsetY" : 0,
"gfxWidth" : 24,
"gfxHeight" : 20,
"frameStyle" : 0,
"frameStyles" : 1,
"frames" : 1,
"frameSpeed" : 8,
"disappearTime" : 600,
"isForeground" : false,
"gravity" : true,
"collisionWithBlocks" : true,
"fixByBlocks" : true,
"fadeScale" : false,
"fadeAlpha" : false,
"slowSpeed" : false,
"slowRotateSpeed" : false
}
}
================================================
FILE: effects/gores/gore_lava_snake_body.json
================================================
{
"gore_lava_snake_body": {
"ai": "Gore",
"textureData" : "lava_snake_body.png",
"width" : 20,
"height" : 20,
"gfxOffsetX" : -12,
"gfxOffsetY" : -8,
"gfxWidth" : 44,
"gfxHeight" : 36,
"frameStyle" : 0,
"frameStyles" : 1,
"frames" : 1,
"frameSpeed" : 8,
"disappearTime" : 600,
"isForeground" : false,
"gravity" : true,
"collisionWithBlocks" : true,
"fixByBlocks" : true,
"fadeScale" : false,
"fadeAlpha" : false,
"slowSpeed" : false,
"slowRotateSpeed" : false
}
}
================================================
FILE: effects/gores/gore_lava_snake_head.json
================================================
{
"gore_lava_snake_head": {
"ai": "Gore",
"textureData" : "lava_snake_head.png",
"width" : 20,
"height" : 20,
"gfxOffsetX" : -15,
"gfxOffsetY" : -10,
"gfxWidth" : 50,
"gfxHeight" : 40,
"frameStyle" : 0,
"frameStyles" : 1,
"frames" : 1,
"frameSpeed" : 8,
"disappearTime" : 600,
"isForeground" : false,
"gravity" : true,
"collisionWithBlocks" : true,
"fixByBlocks" : true,
"fadeScale" : false,
"fadeAlpha" : false,
"slowSpeed" : false,
"slowRotateSpeed" : false
}
}
================================================
FILE: effects/gores/gore_lava_snake_tail.json
================================================
{
"gore_lava_snake_tail": {
"ai": "Gore",
"textureData" : "lava_snake_tail.png",
"width" : 20,
"height" : 20,
"gfxOffsetX" : -17,
"gfxOffsetY" : -10,
"gfxWidth" : 54,
"gfxHeight" : 40,
"frameStyle" : 0,
"frameStyles" : 1,
"frames" : 1,
"frameSpeed" : 8,
"disappearTime" : 600,
"isForeground" : false,
"gravity" : true,
"collisionWithBlocks" : true,
"fixByBlocks" : true,
"fadeScale" : false,
"fadeAlpha" : false,
"slowSpeed" : false,
"slowRotateSpeed" : false
}
}
================================================
FILE: effects/gores/gore_mad_skeleton.json
================================================
{
"gore_mad_skeleton": {
"ai": "Gore",
"textureData" : "mad_skeleton.png",
"width" : 20,
"height" : 20,
"gfxOffsetX" : -2,
"gfxOffsetY" : 0,
"gfxWidth" : 24,
"gfxHeight" : 20,
"frameStyle" : 0,
"frameStyles" : 1,
"frames" : 1,
"frameSpeed" : 8,
"disappearTime" : 600,
"isForeground" : false,
"gravity" : true,
"collisionWithBlocks" : true,
"fixByBlocks" : true,
"fadeScale" : false,
"fadeAlpha" : false,
"slowSpeed" : false,
"slowRotateSpeed" : false
}
}
================================================
FILE: effects/gores/gore_mad_skeleton_armed.json
================================================
{
"gore_mad_skeleton_armed": {
"ai": "Gore",
"textureData" : "mad_skeleton_armed.png",
"width" : 20,
"height" : 20,
"gfxOffsetX" : -3,
"gfxOffsetY" : -2,
"gfxWidth" : 26,
"gfxHeight" : 24,
"frameStyle" : 0,
"frameStyles" : 1,
"frames" : 1,
"frameSpeed" : 8,
"disappearTime" : 600,
"isForeground" : false,
"gravity" : true,
"collisionWithBlocks" : true,
"fixByBlocks" : true,
"fadeScale" : false,
"fadeAlpha" : false,
"slowSpeed" : false,
"slowRotateSpeed" : false
}
}
================================================
FILE: effects/gores/gore_mad_skeleton_tall.json
================================================
{
"gore_mad_skeleton_tall": {
"ai": "Gore",
"textureData" : "mad_skeleton_tall.png",
"width" : 20,
"height" : 20,
"gfxOffsetX" : -4,
"gfxOffsetY" : -2,
"gfxWidth" : 28,
"gfxHeight" : 24,
"frameStyle" : 0,
"frameStyles" : 1,
"frames" : 1,
"frameSpeed" : 8,
"disappearTime" : 600,
"isForeground" : false,
"gravity" : true,
"collisionWithBlocks" : true,
"fixByBlocks" : true,
"fadeScale" : false,
"fadeAlpha" : false,
"slowSpeed" : false,
"slowRotateSpeed" : false
}
}
================================================
FILE: effects/gores/gore_mad_skeleton_tall_armed.json
================================================
{
"gore_mad_skeleton_tall_armed": {
"ai": "Gore",
"textureData" : "mad_skeleton_tall_armed.png",
"width" : 20,
"height" : 20,
"gfxOffsetX" : -3,
"gfxOffsetY" : -2,
"gfxWidth" : 26,
"gfxHeight" : 24,
"frameStyle" : 0,
"frameStyles" : 1,
"frames" : 1,
"frameSpeed" : 8,
"disappearTime" : 600,
"isForeground" : false,
"gravity" : true,
"collisionWithBlocks" : true,
"fixByBlocks" : true,
"fadeScale" : false,
"fadeAlpha" : false,
"slowSpeed" : false,
"slowRotateSpeed" : false
}
}
================================================
FILE: effects/gores/gore_mad_skeleton_tall_helmet_armed.json
================================================
{
"gore_mad_skeleton_tall_helmet_armed": {
"ai": "Gore",
"textureData" : "mad_skeleton_tall_helmet_armed.png",
"width" : 20,
"height" : 20,
"gfxOffsetX" : -4,
"gfxOffsetY" : -7,
"gfxWidth" : 28,
"gfxHeight" : 34,
"frameStyle" : 0,
"frameStyles" : 1,
"frames" : 1,
"frameSpeed" : 8,
"disappearTime" : 600,
"isForeground" : false,
"gravity" : true,
"collisionWithBlocks" : true,
"fixByBlocks" : true,
"fadeScale" : false,
"fadeAlpha" : false,
"slowSpeed" : false,
"slowRotateSpeed" : false
}
}
================================================
FILE: effects/gores/gore_magma_birdo.json
================================================
{
"gore_magma_birdo": {
"ai": "Gore",
"textureData": "magma_birdo.png",
"width": 20,
"height": 20,
"gfxOffsetX": -5,
"gfxOffsetY": -3,
"gfxWidth": 30,
"gfxHeight": 26,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 600,
"isForeground": false,
"gravity": true,
"collisionWithBlocks": true,
"fixByBlocks": true,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/gores/gore_man_eater.json
================================================
{
"gore_man_eater": {
"ai": "Gore",
"textureData": "man_eater.png",
"width": 20,
"height": 20,
"gfxOffsetX": -6,
"gfxOffsetY": -16,
"gfxWidth": 32,
"gfxHeight": 52,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 600,
"isForeground": false,
"gravity": true,
"collisionWithBlocks": true,
"fixByBlocks": true,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/gores/gore_mummy.json
================================================
{
"gore_mummy": {
"ai": "Gore",
"textureData": "mummy.png",
"width": 20,
"height": 20,
"gfxOffsetX": -1,
"gfxOffsetY": -2,
"gfxWidth": 22,
"gfxHeight": 24,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 600,
"isForeground": false,
"gravity": true,
"collisionWithBlocks": true,
"fixByBlocks": true,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/gores/gore_paimon.json
================================================
{
"gore_paimon": {
"ai": "Gore",
"textureData" : "paimon.png",
"width" : 20,
"height" : 20,
"gfxOffsetX" : -9,
"gfxOffsetY" : -4,
"gfxWidth" : 38,
"gfxHeight" : 28,
"frameStyle" : 0,
"frameStyles" : 1,
"frames" : 1,
"frameSpeed" : 8,
"disappearTime" : 600,
"isForeground" : false,
"gravity" : true,
"collisionWithBlocks" : true,
"fixByBlocks" : true,
"fadeScale" : false,
"fadeAlpha" : false,
"slowSpeed" : false,
"slowRotateSpeed" : false
}
}
================================================
FILE: effects/gores/gore_phantom.json
================================================
{
"gore_phantom": {
"ai": "Gore",
"textureData": "phantom.png",
"width": 20,
"height": 20,
"gfxOffsetX": -6,
"gfxOffsetY": -4,
"gfxWidth": 32,
"gfxHeight": 28,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 600,
"isForeground": false,
"gravity": true,
"collisionWithBlocks": true,
"fixByBlocks": true,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/gores/gore_pig.json
================================================
{
"gore_pig": {
"ai": "Gore",
"textureData": "pig.png",
"width": 32,
"height": 32,
"gfxOffsetX": -4,
"gfxOffsetY": -3,
"gfxWidth": 40,
"gfxHeight": 38,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 600,
"isForeground": false,
"gravity": true,
"collisionWithBlocks": true,
"fixByBlocks": true,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/gores/gore_ragged_mage.json
================================================
{
"gore_ragged_mage": {
"ai": "Gore",
"textureData" : "ragged_mage.png",
"width" : 20,
"height" : 20,
"gfxOffsetX" : -2,
"gfxOffsetY" : 0,
"gfxWidth" : 24,
"gfxHeight" : 20,
"frameStyle" : 0,
"frameStyles" : 1,
"frames" : 1,
"frameSpeed" : 8,
"disappearTime" : 600,
"isForeground" : false,
"gravity" : true,
"collisionWithBlocks" : true,
"fixByBlocks" : true,
"fadeScale" : false,
"fadeAlpha" : false,
"slowSpeed" : false,
"slowRotateSpeed" : false
}
}
================================================
FILE: effects/gores/gore_red_mage.json
================================================
{
"gore_red_mage": {
"ai": "Gore",
"textureData" : "red_mage.png",
"width" : 20,
"height" : 20,
"gfxOffsetX" : -6,
"gfxOffsetY" : -5,
"gfxWidth" : 32,
"gfxHeight" : 30,
"frameStyle" : 0,
"frameStyles" : 1,
"frames" : 1,
"frameSpeed" : 8,
"disappearTime" : 600,
"isForeground" : false,
"gravity" : true,
"collisionWithBlocks" : true,
"fixByBlocks" : true,
"fadeScale" : false,
"fadeAlpha" : false,
"slowSpeed" : false,
"slowRotateSpeed" : false
}
}
================================================
FILE: effects/gores/gore_red_mushroom_cow.json
================================================
{
"gore_red_mushroom_cow": {
"ai": "Gore",
"textureData": "red_mushroom_cow.png",
"width": 32,
"height": 32,
"gfxOffsetX": -4,
"gfxOffsetY": -4,
"gfxWidth": 40,
"gfxHeight": 40,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 600,
"isForeground": false,
"gravity": true,
"collisionWithBlocks": true,
"fixByBlocks": true,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/gores/gore_red_phantom.json
================================================
{
"gore_red_phantom": {
"ai": "Gore",
"textureData" : "red_phantom.png",
"width" : 20,
"height" : 20,
"gfxOffsetX" : 1,
"gfxOffsetY" : 2,
"gfxWidth" : 18,
"gfxHeight" : 16,
"frameStyle" : 0,
"frameStyles" : 1,
"frames" : 1,
"frameSpeed" : 8,
"disappearTime" : 600,
"isForeground" : false,
"gravity" : true,
"collisionWithBlocks" : true,
"fixByBlocks" : true,
"fadeScale" : false,
"fadeAlpha" : false,
"slowSpeed" : false,
"slowRotateSpeed" : false
}
}
================================================
FILE: effects/gores/gore_rock_man.json
================================================
{
"gore_rock_man": {
"ai": "Gore",
"textureData" : "rock_man.png",
"width" : 20,
"height" : 20,
"gfxOffsetX" : -3,
"gfxOffsetY" : -1,
"gfxWidth" : 26,
"gfxHeight" : 22,
"frameStyle" : 0,
"frameStyles" : 1,
"frames" : 1,
"frameSpeed" : 8,
"disappearTime" : 600,
"isForeground" : false,
"gravity" : true,
"collisionWithBlocks" : true,
"fixByBlocks" : true,
"fadeScale" : false,
"fadeAlpha" : false,
"slowSpeed" : false,
"slowRotateSpeed" : false
}
}
================================================
FILE: effects/gores/gore_sheep.json
================================================
{
"gore_sheep": {
"ai": "Gore",
"textureData": "sheep.png",
"width": 20,
"height": 20,
"gfxOffsetX": -7,
"gfxOffsetY": -6,
"gfxWidth": 34,
"gfxHeight": 32,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 600,
"isForeground": false,
"gravity": true,
"collisionWithBlocks": true,
"fixByBlocks": true,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/gores/gore_shulker.json
================================================
{
"gore_shulker": {
"ai": "Gore",
"textureData": "shulker.png",
"width": 16,
"height": 16,
"gfxOffsetX": -8,
"gfxOffsetY": -1,
"gfxWidth": 32,
"gfxHeight": 18,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 600,
"isForeground": false,
"gravity": true,
"collisionWithBlocks": true,
"fixByBlocks": true,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/gores/gore_skeleton_assaulter.json
================================================
{
"gore_skeleton_assaulter": {
"ai": "Gore",
"textureData" : "skeleton_assaulter.png",
"width" : 20,
"height" : 20,
"gfxOffsetX" : -2,
"gfxOffsetY" : 0,
"gfxWidth" : 24,
"gfxHeight" : 20,
"frameStyle" : 0,
"frameStyles" : 1,
"frames" : 1,
"frameSpeed" : 8,
"disappearTime" : 600,
"isForeground" : false,
"gravity" : true,
"collisionWithBlocks" : true,
"fixByBlocks" : true,
"fadeScale" : false,
"fadeAlpha" : false,
"slowSpeed" : false,
"slowRotateSpeed" : false
}
}
================================================
FILE: effects/gores/gore_skeleton_blue_armed.json
================================================
{
"gore_skeleton_blue_armed": {
"ai": "Gore",
"textureData" : "skeleton_blue_armed.png",
"width" : 20,
"height" : 20,
"gfxOffsetX" : -7,
"gfxOffsetY" : -4,
"gfxWidth" : 34,
"gfxHeight" : 28,
"frameStyle" : 0,
"frameStyles" : 1,
"frames" : 1,
"frameSpeed" : 8,
"disappearTime" : 600,
"isForeground" : false,
"gravity" : true,
"collisionWithBlocks" : true,
"fixByBlocks" : true,
"fadeScale" : false,
"fadeAlpha" : false,
"slowSpeed" : false,
"slowRotateSpeed" : false
}
}
================================================
FILE: effects/gores/gore_skeleton_blue_armed_masked.json
================================================
{
"gore_skeleton_blue_armed_masked": {
"ai": "Gore",
"textureData" : "skeleton_blue_armed_masked.png",
"width" : 20,
"height" : 20,
"gfxOffsetX" : -7,
"gfxOffsetY" : -4,
"gfxWidth" : 34,
"gfxHeight" : 28,
"frameStyle" : 0,
"frameStyles" : 1,
"frames" : 1,
"frameSpeed" : 8,
"disappearTime" : 600,
"isForeground" : false,
"gravity" : true,
"collisionWithBlocks" : true,
"fixByBlocks" : true,
"fadeScale" : false,
"fadeAlpha" : false,
"slowSpeed" : false,
"slowRotateSpeed" : false
}
}
================================================
FILE: effects/gores/gore_skeleton_blue_knight.json
================================================
{
"gore_skeleton_blue_knight": {
"ai": "Gore",
"textureData" : "skeleton_blue_knight.png",
"width" : 20,
"height" : 20,
"gfxOffsetX" : -6,
"gfxOffsetY" : -5,
"gfxWidth" : 32,
"gfxHeight" : 30,
"frameStyle" : 0,
"frameStyles" : 1,
"frames" : 1,
"frameSpeed" : 8,
"disappearTime" : 600,
"isForeground" : false,
"gravity" : true,
"collisionWithBlocks" : true,
"fixByBlocks" : true,
"fadeScale" : false,
"fadeAlpha" : false,
"slowSpeed" : false,
"slowRotateSpeed" : false
}
}
================================================
FILE: effects/gores/gore_skeleton_fire_armed.json
================================================
{
"gore_skeleton_fire_armed": {
"ai": "Gore",
"textureData" : "skeleton_fire_armed.png",
"width" : 20,
"height" : 20,
"gfxOffsetX" : -7,
"gfxOffsetY" : -4,
"gfxWidth" : 34,
"gfxHeight" : 28,
"frameStyle" : 0,
"frameStyles" : 1,
"frames" : 1,
"frameSpeed" : 8,
"disappearTime" : 600,
"isForeground" : false,
"gravity" : true,
"collisionWithBlocks" : true,
"fixByBlocks" : true,
"fadeScale" : false,
"fadeAlpha" : false,
"slowSpeed" : false,
"slowRotateSpeed" : false
}
}
================================================
FILE: effects/gores/gore_skeleton_fire_armed_swordsman.json
================================================
{
"gore_skeleton_fire_armed_swordsman": {
"ai": "Gore",
"textureData" : "skeleton_fire_armed_swordsman.png",
"width" : 20,
"height" : 20,
"gfxOffsetX" : -3,
"gfxOffsetY" : -4,
"gfxWidth" : 26,
"gfxHeight" : 28,
"frameStyle" : 0,
"frameStyles" : 1,
"frames" : 1,
"frameSpeed" : 8,
"disappearTime" : 600,
"isForeground" : false,
"gravity" : true,
"collisionWithBlocks" : true,
"fixByBlocks" : true,
"fadeScale" : false,
"fadeAlpha" : false,
"slowSpeed" : false,
"slowRotateSpeed" : false
}
}
================================================
FILE: effects/gores/gore_skeleton_guard.json
================================================
{
"gore_skeleton_guard": {
"ai": "Gore",
"textureData" : "skeleton_guard.png",
"width" : 20,
"height" : 20,
"gfxOffsetX" : -6,
"gfxOffsetY" : -3,
"gfxWidth" : 32,
"gfxHeight" : 26,
"frameStyle" : 0,
"frameStyles" : 1,
"frames" : 1,
"frameSpeed" : 8,
"disappearTime" : 600,
"isForeground" : false,
"gravity" : true,
"collisionWithBlocks" : true,
"fixByBlocks" : true,
"fadeScale" : false,
"fadeAlpha" : false,
"slowSpeed" : false,
"slowRotateSpeed" : false
}
}
================================================
FILE: effects/gores/gore_skeleton_kid.json
================================================
{
"gore_skeleton_kid": {
"ai": "Gore",
"textureData" : "skeleton_kid.png",
"width" : 20,
"height" : 20,
"gfxOffsetX" : -3,
"gfxOffsetY" : 1,
"gfxWidth" : 26,
"gfxHeight" : 18,
"frameStyle" : 0,
"frameStyles" : 1,
"frames" : 1,
"frameSpeed" : 8,
"disappearTime" : 600,
"isForeground" : false,
"gravity" : true,
"collisionWithBlocks" : true,
"fixByBlocks" : true,
"fadeScale" : false,
"fadeAlpha" : false,
"slowSpeed" : false,
"slowRotateSpeed" : false
}
}
================================================
FILE: effects/gores/gore_skull.json
================================================
{
"gore_skull": {
"ai": "Gore",
"textureData": "skull.png",
"width": 20,
"height": 20,
"gfxOffsetX": -2,
"gfxOffsetY": 0,
"gfxWidth": 24,
"gfxHeight": 20,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 600,
"isForeground": false,
"gravity": true,
"collisionWithBlocks": true,
"fixByBlocks": true,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/gores/gore_small_hell_eater.json
================================================
{
"gore_small_hell_eater": {
"ai": "Gore",
"textureData": "small_hell_eater.png",
"width": 16,
"height": 16,
"gfxOffsetX": -8,
"gfxOffsetY": -8,
"gfxWidth": 32,
"gfxHeight": 32,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 600,
"isForeground": false,
"gravity": true,
"collisionWithBlocks": true,
"fixByBlocks": true,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/gores/gore_snow_guner.json
================================================
{
"gore_snow_guner": {
"ai": "Gore",
"textureData" : "snow_guner.png",
"width" : 20,
"height" : 20,
"gfxOffsetX" : -4,
"gfxOffsetY" : -4,
"gfxWidth" : 28,
"gfxHeight" : 28,
"frameStyle" : 0,
"frameStyles" : 1,
"frames" : 1,
"frameSpeed" : 8,
"disappearTime" : 600,
"isForeground" : false,
"gravity" : true,
"collisionWithBlocks" : true,
"fixByBlocks" : true,
"fadeScale" : false,
"fadeAlpha" : false,
"slowSpeed" : false,
"slowRotateSpeed" : false
}
}
================================================
FILE: effects/gores/gore_spider.json
================================================
{
"gore_spider": {
"ai": "Gore",
"textureData": "spider.png",
"width": 20,
"height": 20,
"gfxOffsetX": -3,
"gfxOffsetY": 0,
"gfxWidth": 26,
"gfxHeight": 20,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 600,
"isForeground": false,
"gravity": true,
"collisionWithBlocks": true,
"fixByBlocks": true,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/gores/gore_squid.json
================================================
{
"gore_squid": {
"ai": "Gore",
"textureData": "squid.png",
"width": 20,
"height": 20,
"gfxOffsetX": -1,
"gfxOffsetY": -1,
"gfxWidth": 22,
"gfxHeight": 22,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 600,
"isForeground": false,
"gravity": true,
"collisionWithBlocks": true,
"fixByBlocks": true,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/gores/gore_tainted_creeper.json
================================================
{
"gore_tainted_creeper": {
"ai": "Gore",
"textureData": "tainted_creeper.png",
"width": 20,
"height": 20,
"gfxOffsetX": -6,
"gfxOffsetY": -6,
"gfxWidth": 32,
"gfxHeight": 32,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 600,
"isForeground": false,
"gravity": true,
"collisionWithBlocks": true,
"fixByBlocks": true,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/gores/gore_tainted_skeleton.json
================================================
{
"gore_tainted_skeleton": {
"ai": "Gore",
"textureData": "tainted_skeleton.png",
"width": 20,
"height": 20,
"gfxOffsetX": -2,
"gfxOffsetY": 0,
"gfxWidth": 24,
"gfxHeight": 20,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 600,
"isForeground": false,
"gravity": true,
"collisionWithBlocks": true,
"fixByBlocks": true,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/gores/gore_turtle.json
================================================
{
"gore_turtle": {
"ai": "Gore",
"textureData": "turtle.png",
"width": 16,
"height": 16,
"gfxOffsetX": -9,
"gfxOffsetY": -5,
"gfxWidth": 34,
"gfxHeight": 26,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 600,
"isForeground": false,
"gravity": true,
"collisionWithBlocks": true,
"fixByBlocks": true,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/gores/gore_undead_miner.json
================================================
{
"gore_undead_miner": {
"ai": "Gore",
"textureData" : "undead_miner.png",
"width" : 20,
"height" : 20,
"gfxOffsetX" : -3,
"gfxOffsetY" : -1,
"gfxWidth" : 26,
"gfxHeight" : 22,
"frameStyle" : 0,
"frameStyles" : 1,
"frames" : 1,
"frameSpeed" : 8,
"disappearTime" : 600,
"isForeground" : false,
"gravity" : true,
"collisionWithBlocks" : true,
"fixByBlocks" : true,
"fadeScale" : false,
"fadeAlpha" : false,
"slowSpeed" : false,
"slowRotateSpeed" : false
}
}
================================================
FILE: effects/gores/gore_vampire_miner.json
================================================
{
"gore_vampire_miner": {
"ai": "Gore",
"textureData" : "vampire_miner.png",
"width" : 20,
"height" : 20,
"gfxOffsetX" : -4,
"gfxOffsetY" : -3,
"gfxWidth" : 28,
"gfxHeight" : 26,
"frameStyle" : 0,
"frameStyles" : 1,
"frames" : 1,
"frameSpeed" : 8,
"disappearTime" : 600,
"isForeground" : false,
"gravity" : true,
"collisionWithBlocks" : true,
"fixByBlocks" : true,
"fadeScale" : false,
"fadeAlpha" : false,
"slowSpeed" : false,
"slowRotateSpeed" : false
}
}
================================================
FILE: effects/gores/gore_villager_zombie.json
================================================
{
"gore_villager_zombie": {
"ai": "Gore",
"textureData": "villager_zombie.png",
"width": 20,
"height": 20,
"gfxOffsetX": -3,
"gfxOffsetY": -3,
"gfxWidth": 26,
"gfxHeight": 26,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 600,
"isForeground": false,
"gravity": true,
"collisionWithBlocks": true,
"fixByBlocks": true,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/gores/gore_waste_mummy.json
================================================
{
"gore_waste_mummy": {
"ai": "Gore",
"textureData": "waste_mummy.png",
"width": 20,
"height": 20,
"gfxOffsetX": -7,
"gfxOffsetY": -5,
"gfxWidth": 34,
"gfxHeight": 30,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 600,
"isForeground": false,
"gravity": true,
"collisionWithBlocks": true,
"fixByBlocks": true,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/gores/gore_white_rabbit.json
================================================
{
"gore_white_rabbit": {
"ai": "Gore",
"textureData": "white_rabbit.png",
"width": 16,
"height": 16,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"gfxWidth": 16,
"gfxHeight": 16,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 600,
"isForeground": false,
"gravity": true,
"collisionWithBlocks": true,
"fixByBlocks": true,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/gores/gore_wither_skeleton.json
================================================
{
"gore_wither_skeleton": {
"ai": "Gore",
"textureData": "wither_skeleton.png",
"width": 20,
"height": 20,
"gfxOffsetX": -4,
"gfxOffsetY": -2,
"gfxWidth": 28,
"gfxHeight": 24,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 600,
"isForeground": false,
"gravity": true,
"collisionWithBlocks": true,
"fixByBlocks": true,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/gores/gore_worm_body.json
================================================
{
"gore_worm_body": {
"ai": "Gore",
"textureData": "worm_body.png",
"width": 30,
"height": 30,
"gfxOffsetX": -8,
"gfxOffsetY": -11,
"gfxWidth": 46,
"gfxHeight": 52,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 300,
"isForeground": false,
"gravity": true,
"collisionWithBlocks": true,
"fixByBlocks": true,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/gores/gore_worm_head.json
================================================
{
"gore_worm_head": {
"ai": "Gore",
"textureData": "worm_head.png",
"width": 30,
"height": 30,
"gfxOffsetX": -24,
"gfxOffsetY": -11,
"gfxWidth": 78,
"gfxHeight": 52,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 300,
"isForeground": false,
"gravity": true,
"collisionWithBlocks": true,
"fixByBlocks": true,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/gores/gore_worm_tail.json
================================================
{
"gore_worm_tail": {
"ai": "Gore",
"textureData": "worm_tail.png",
"width": 30,
"height": 30,
"gfxOffsetX": -15,
"gfxOffsetY": -17,
"gfxWidth": 60,
"gfxHeight": 64,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 300,
"isForeground": false,
"gravity": true,
"collisionWithBlocks": true,
"fixByBlocks": true,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/gores/gore_yellow_rabbit.json
================================================
{
"gore_yellow_rabbit": {
"ai": "Gore",
"textureData": "yellow_rabbit.png",
"width": 16,
"height": 16,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"gfxWidth": 16,
"gfxHeight": 16,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 600,
"isForeground": false,
"gravity": true,
"collisionWithBlocks": true,
"fixByBlocks": true,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/gores/gore_zombie.json
================================================
{
"gore_zombie": {
"ai": "Gore",
"textureData": "zombie.png",
"width": 20,
"height": 20,
"gfxOffsetX": -6,
"gfxOffsetY": -3,
"gfxWidth": 32,
"gfxHeight": 26,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 600,
"isForeground": false,
"gravity": true,
"collisionWithBlocks": true,
"fixByBlocks": true,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/gores/gore_zombie_pigman.json
================================================
{
"gore_zombie_pigman": {
"ai": "Gore",
"textureData": "zombie_pigman.png",
"width": 20,
"height": 20,
"gfxOffsetX": -4,
"gfxOffsetY": -3,
"gfxWidth": 28,
"gfxHeight": 26,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 600,
"isForeground": false,
"gravity": true,
"collisionWithBlocks": true,
"fixByBlocks": true,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/heal.json
================================================
{
"heal": {
"ai": "Smoke",
"textureData": "heal.png",
"width": 12,
"height": 12,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"gfxWidth": 12,
"gfxHeight": 12,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 72,
"isForeground": true,
"gravity": false,
"collisionWithBlocks": false,
"fixByBlocks": false,
"fadeScale": true,
"fadeAlpha": false,
"slowSpeed": true,
"slowRotateSpeed": true
}
}
================================================
FILE: effects/laser_flash.json
================================================
{
"laser_flash": {
"ai": "Smoke",
"textureData": "laser_flash.png",
"width": 8,
"height": 8,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"gfxWidth": 8,
"gfxHeight": 8,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 72,
"isForeground": true,
"gravity": false,
"collisionWithBlocks": false,
"fixByBlocks": false,
"fadeScale": true,
"fadeAlpha": true,
"slowSpeed": true,
"slowRotateSpeed": true,
"isLighting": true,
"lightColor": [ 16, 0, 0, 0 ]
}
}
================================================
FILE: effects/liquid_paticular.json
================================================
{
"liquid_paticular": {
"ai": "Smoke",
"textureData": "liquid_paticular.png",
"width": 8,
"height": 8,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"gfxWidth": 8,
"gfxHeight": 8,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 160,
"isForeground": true,
"gravity": true,
"collisionWithBlocks": false,
"fixByBlocks": false,
"fadeScale": true,
"fadeAlpha": true,
"slowSpeed": true,
"slowRotateSpeed": true
}
}
================================================
FILE: effects/poison.json
================================================
{
"poison": {
"ai": "Smoke",
"textureData": "poison.png",
"width": 20,
"height": 20,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"gfxWidth": 20,
"gfxHeight": 20,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 72,
"isForeground": true,
"gravity": false,
"collisionWithBlocks": false,
"fixByBlocks": false,
"fadeScale": true,
"fadeAlpha": true,
"slowSpeed": true,
"slowRotateSpeed": true
}
}
================================================
FILE: effects/pot_break.json
================================================
{
"pot_break": {
"ai": "Gore",
"textureData": "pot_break.png",
"width": 16,
"height": 16,
"gfxOffsetX": -8,
"gfxOffsetY": -8,
"gfxWidth": 32,
"gfxHeight": 32,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 1000,
"isForeground": false,
"gravity": true,
"collisionWithBlocks": true,
"fixByBlocks": true,
"fadeScale": false,
"fadeAlpha": false,
"slowSpeed": false,
"slowRotateSpeed": false
}
}
================================================
FILE: effects/redstone_smoke.json
================================================
{
"redstone_smoke": {
"ai": "Smoke",
"textureData": "redstone_smoke.png",
"width": 16,
"height": 16,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"gfxWidth": 16,
"gfxHeight": 16,
"frameStyle": 0,
"frameStyles": 3,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 80,
"isForeground": true,
"gravity": false,
"collisionWithBlocks": false,
"fixByBlocks": false,
"fadeScale": true,
"fadeAlpha": true,
"slowSpeed": true,
"slowRotateSpeed": true
}
}
================================================
FILE: effects/smoke.json
================================================
{
"smoke": {
"ai": "Smoke",
"textureData": "smoke.png",
"width": 32,
"height": 32,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"gfxWidth": 32,
"gfxHeight": 32,
"frameStyle": 0,
"frameStyles": 3,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 120,
"isForeground": true,
"gravity": false,
"collisionWithBlocks": false,
"fixByBlocks": false,
"fadeScale": true,
"fadeAlpha": true,
"slowSpeed": true,
"slowRotateSpeed": true
}
}
================================================
FILE: effects/star.json
================================================
{
"star": {
"ai": "Smoke",
"textureData": "star.png",
"width": 16,
"height": 16,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"gfxWidth": 16,
"gfxHeight": 16,
"frameStyle": 0,
"frameStyles": 1,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 72,
"isForeground": true,
"gravity": false,
"collisionWithBlocks": false,
"fixByBlocks": false,
"fadeScale": true,
"fadeAlpha": false,
"isLighting": true,
"slowSpeed": true,
"slowRotateSpeed": true,
"lightColor": [ 24, 0, 0, 0 ]
}
}
================================================
FILE: effects/white_smoke.json
================================================
{
"white_smoke": {
"ai": "Smoke",
"textureData": "white_smoke.png",
"width": 32,
"height": 32,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"gfxWidth": 32,
"gfxHeight": 32,
"frameStyle": 0,
"frameStyles": 3,
"frames": 1,
"frameSpeed": 8,
"disappearTime": 60,
"isForeground": true,
"gravity": false,
"collisionWithBlocks": false,
"fixByBlocks": false,
"fadeScale": true,
"fadeAlpha": true,
"slowSpeed": true,
"slowRotateSpeed": true
}
}
================================================
FILE: enchantments/BaseEnchantmentProxy.lua
================================================
---@class TC.BaseEnchantmentProxy
local BaseEnchantmentProxy = class("BaseEnchantmentProxy")
---OnHeld
---@param level int
---@param player Player
---@param itemStack ItemStack
function BaseEnchantmentProxy.OnHeld(level, player, itemStack)
end
---OnUpdateSecond
---@param level int
---@param player Player
---@param itemStack ItemStack
function BaseEnchantmentProxy.OnUpdateSecond(level, player, itemStack)
end
---OnEquipped
---@param equipmentIndex int
---@param level int
---@param player Player
---@param itemStack ItemStack
function BaseEnchantmentProxy.OnEquipped(equipmentIndex, level, player, itemStack)
end
---OnEquippedHitByNpc
---@param equipmentIndex int
---@param level int
---@param player Player
---@param itemStack ItemStack
---@param npc Npc
function BaseEnchantmentProxy.OnEquippedHitByNpc(equipmentIndex, level, player, itemStack, npc)
end
---OnEquippedHitByProjectile
---@param equipmentIndex int
---@param level int
---@param player Player
---@param itemStack ItemStack
---@param projectile Projectile
function BaseEnchantmentProxy.OnEquippedHitByProjectile(equipmentIndex, level, player, itemStack, projectile)
end
return BaseEnchantmentProxy
================================================
FILE: enchantments/EnchantmentAquaAffinity.lua
================================================
---@class TC.EnchantmentAquaAffinity:TC.BaseEnchantmentProxy
local EnchantmentAquaAffinity = class("EnchantmentAquaAffinity")
function EnchantmentAquaAffinity.OnEquipped(equipmentIndex, level, player, _)
if player.inLiquid then
player.digSpeedRate = player.digSpeedRate + level * 0.1
end
end
return EnchantmentAquaAffinity
================================================
FILE: enchantments/EnchantmentBlastProtection.lua
================================================
---@class TC.EnchantmentBlastProtection:TC.BaseEnchantmentProxy
local EnchantmentBlastProtection = class("EnchantmentBlastProtection")
function EnchantmentBlastProtection.OnEquipped(equipmentIndex, level, player, _)
player.baseDefense.blastDefense = player.baseDefense.blastDefense + level
end
return EnchantmentBlastProtection
================================================
FILE: enchantments/EnchantmentDepthStrider.lua
================================================
---@class TC.EnchantmentDepthStrider:TC.BaseEnchantmentProxy
local EnchantmentDepthStrider = class("EnchantmentDepthStrider")
function EnchantmentDepthStrider.OnEquipped(equipmentIndex, level, player, _)
if player.inLiquid then
player.speedRate = player.speedRate + level * 0.2
end
end
return EnchantmentDepthStrider
================================================
FILE: enchantments/EnchantmentFeatherFalling.lua
================================================
---@class TC.EnchantmentFeatherFalling:TC.BaseEnchantmentProxy
local EnchantmentFeatherFalling = class("EnchantmentFeatherFalling")
function EnchantmentFeatherFalling.OnEquipped(equipmentIndex, level, player, _)
player.baseDefense.fallDefense = player.baseDefense.fallDefense + level
end
return EnchantmentFeatherFalling
================================================
FILE: enchantments/EnchantmentFireProtection.lua
================================================
---@class TC.EnchantmentFireProtection:TC.BaseEnchantmentProxy
local EnchantmentFireProtection = class("EnchantmentFireProtection")
function EnchantmentFireProtection.OnEquipped(equipmentIndex, level, player, _)
player.baseDefense.flameDefense = player.baseDefense.flameDefense + level
end
return EnchantmentFireProtection
================================================
FILE: enchantments/EnchantmentFrostWalker.lua
================================================
---@class TC.EnchantmentFrostWalker:TC.BaseEnchantmentProxy
local EnchantmentFrostWalker = class("EnchantmentFrostWalker")
function EnchantmentFrostWalker.OnHeld(level, player, _)
local waterID = Reg.LiquidID("water")
local xi1 = Utils.Cell(player.x) - 2
local xi2 = Utils.Cell(player.rightX) + 2
local yi1 = Utils.Cell(player.bottomY)
local yi2 = yi1 + 1
if MapUtils.IsAreaValid(xi1, yi1 - 1, xi2 - xi1, yi2 - yi1 + 1) then
for xi = xi1, xi2 do
for yi = yi1, yi2 do
if not MapUtils.HasFront(xi, yi) then
local liquidID, amount = MapUtils.GetLiquidIDAmount(xi, yi)
if liquidID == waterID then
if not MapUtils.IsSolid(xi, yi - 1) then
MapUtils.RemoveFront(xi, yi)
MapUtils.SetFront(xi, yi, Reg.BlockID("ice_thin"))
MapUtils.SetFrontTag(xi, yi, amount)
for i = 1, 4 do
EffectUtils.SendFromServer(Reg.EffectID("heal"), xi * 16 + 8, yi * 16 + 8,
Utils.RandSym(1.0), Utils.RandSym(1.0),
Utils.RandSym(0.25))
end
end
end
end
end
end
end
end
return EnchantmentFrostWalker
================================================
FILE: enchantments/EnchantmentKnockBack.lua
================================================
---@class TC.EnchantmentKnockBack:TC.BaseEnchantmentProxy
local EnchantmentKnockBack = class("EnchantmentKnockBack")
function EnchantmentKnockBack.OnHeld(level, player, _)
player.baseAttack.knockBack = player.baseAttack.knockBack + level
end
return EnchantmentKnockBack
================================================
FILE: enchantments/EnchantmentPhyton.lua
================================================
---@class TC.EnchantmentPhyton:TC.BaseEnchantmentProxy
local EnchantmentPhyton = class("EnchantmentProtection")
function EnchantmentPhyton.OnUpdateSecond(level, player, itemStack)
itemStack:AddDurable(level * 2)
end
return EnchantmentPhyton
================================================
FILE: enchantments/EnchantmentProjectileProtection.lua
================================================
---@class TC.EnchantmentProjectileProtection:TC.BaseEnchantmentProxy
local EnchantmentProjectileProtection = class("EnchantmentProjectileProtection")
function EnchantmentProjectileProtection.OnEquipped(equipmentIndex, level, player, _)
player.baseDefense.projectileDefense = player.baseDefense.projectileDefense + level
end
return EnchantmentProjectileProtection
================================================
FILE: enchantments/EnchantmentProtection.lua
================================================
---@class TC.EnchantmentProtection:TC.BaseEnchantmentProxy
local EnchantmentProtection = class("EnchantmentProtection")
function EnchantmentProtection.OnEquipped(equipmentIndex, level, player, _)
player.baseDefense.defense = player.baseDefense.defense + level
end
return EnchantmentProtection
================================================
FILE: enchantments/EnchantmentProxies.lua
================================================
---@class TC.EnchantmentProxies
local EnchantmentProxies = class("EnchantmentProxies")
local s_instance
---@return TC.EnchantmentProxies
function EnchantmentProxies.getInstance()
if s_instance == nil then
s_instance = EnchantmentProxies.new()
end
return s_instance
end
function EnchantmentProxies:__init()
---@type TC.BaseEnchantmentProxy[]
self._proxies = {}
end
---OnHeld
---@param itemStack ItemStack
---@param player Player
function EnchantmentProxies:OnHeld(itemStack, player)
if not itemStack:HasEnchantment() then
return
end
for index = 0, itemStack.enchantmentCount - 1 do
local enchantment = itemStack:GetEnchantmentByIndex(index)
local proxy = self._proxies[enchantment.id]
if proxy and proxy.OnHeld ~= nil then
proxy.OnHeld(enchantment.level, player, itemStack)
end
end
end
---OnUpdateSecond
---@param itemStack ItemStack
---@param player Player
function EnchantmentProxies:OnUpdateSecond(itemStack, player)
if not itemStack:HasEnchantment() then
return
end
for index = 0, itemStack.enchantmentCount - 1 do
local enchantment = itemStack:GetEnchantmentByIndex(index)
local proxy = self._proxies[enchantment.id]
if proxy and proxy.OnUpdateSecond ~= nil then
proxy.OnUpdateSecond(enchantment.level, player, itemStack)
end
end
end
---@param equipmentIndex int
---@param itemStack ItemStack
---@param player Player
function EnchantmentProxies:OnEquipped(equipmentIndex, itemStack, player)
if not itemStack:HasEnchantment() then
return
end
for index = 0, itemStack.enchantmentCount - 1 do
local enchantment = itemStack:GetEnchantmentByIndex(index)
local proxy = self._proxies[enchantment.id]
if proxy and proxy.OnEquipped ~= nil then
proxy.OnEquipped(equipmentIndex, enchantment.level, player, itemStack)
end
end
end
---@param equipmentIndex int
---@param itemStack ItemStack
---@param player Player
---@param npc Npc
function EnchantmentProxies:OnEquippedHitByNpc(equipmentIndex, itemStack, player, npc)
if not itemStack:HasEnchantment() then
return
end
for index = 0, itemStack.enchantmentCount - 1 do
local enchantment = itemStack:GetEnchantmentByIndex(index)
local proxy = self._proxies[enchantment.id]
if proxy and proxy.OnEquippedHitByNpc ~= nil then
proxy.OnEquippedHitByNpc(equipmentIndex, enchantment.level, player, itemStack, npc)
end
end
end
---@param equipmentIndex int
---@param itemStack ItemStack
---@param player Player
---@param projectile Projectile
function EnchantmentProxies:OnEquippedHitByProjectile(equipmentIndex, itemStack, player, projectile)
if not itemStack:HasEnchantment() then
return
end
for index = 0, itemStack.enchantmentCount - 1 do
local enchantment = itemStack:GetEnchantmentByIndex(index)
local proxy = self._proxies[enchantment.id]
if proxy and proxy.OnEquippedHitByProjectile ~= nil then
proxy.OnEquippedHitByProjectile(equipmentIndex, enchantment.level, player, itemStack, projectile)
end
end
end
function EnchantmentProxies:Register(idName, proxy)
local id = Reg.EnchantmentID(idName)
self._proxies[id] = proxy
end
function EnchantmentProxies:RegisterAll()
self:Register("tc:knockback", require("EnchantmentKnockBack"))
self:Register("tc:sharpness", require("EnchantmentSharpness"))
self:Register("tc:blast_protection", require("EnchantmentBlastProtection"))
self:Register("tc:aqua_affinity", require("EnchantmentAquaAffinity"))
self:Register("tc:depth_strider", require("EnchantmentDepthStrider"))
self:Register("tc:feather_falling", require("EnchantmentFeatherFalling"))
self:Register("tc:fire_protection", require("EnchantmentFireProtection"))
self:Register("tc:projectile_protection", require("EnchantmentProjectileProtection"))
self:Register("tc:protection", require("EnchantmentProtection"))
self:Register("tc:respiration", require("EnchantmentRespiration"))
self:Register("tc:frost_walker", require("EnchantmentFrostWalker"))
self:Register("tc:thorns", require("EnchantmentThorns"))
self:Register("tc:phyton", require("EnchantmentPhyton"))
end
return EnchantmentProxies
================================================
FILE: enchantments/EnchantmentRespiration.lua
================================================
---@class TC.EnchantmentRespiration:TC.BaseEnchantmentProxy
local EnchantmentRespiration = class("EnchantmentRespiration")
function EnchantmentRespiration.OnEquipped(equipmentIndex, level, player, _)
player.baseDefense.breathDefense = player.baseDefense.breathDefense + level
end
return EnchantmentRespiration
================================================
FILE: enchantments/EnchantmentSharpness.lua
================================================
---@class TC.EnchantmentSharpness:TC.BaseEnchantmentProxy
local EnchantmentSharpness = class("EnchantmentSharpness")
function EnchantmentSharpness.OnHeld(level, player, _)
player.baseAttack.attack = player.baseAttack.attack + level
end
return EnchantmentSharpness
================================================
FILE: enchantments/EnchantmentThorns.lua
================================================
---@class TC.EnchantmentThorns:TC.BaseEnchantmentProxy
local EnchantmentThorns = class("EnchantmentThorns")
function EnchantmentThorns.OnEquippedHitByNpc(equipmentIndex, level, player, itemStack, npc)
local hitAngle = player:GetAngleTo(npc.centerX, npc.centerY)
npc:Strike(Attack.new(1 + level, 1 + level, 0), hitAngle)
SoundUtils.PlaySoundGroup(Reg.SoundGroupID("thorns_hit"), player.centerXi, player.centerYi)
local initAngle = Utils.RandDouble(math.pi)
local times = Utils.RandIntArea(4, 4)
for i = 0, times do
local angle = initAngle + i * math.pi * 2 / times
EffectUtils.SendFromServer(Reg.EffectID("heal"),
player.centerX,
player.centerY,
math.cos(angle) * 3,
math.sin(angle) * 3,
Utils.RandSym(0.1),
Utils.RandDoubleArea(1, 0.5),
1.0,
Color.Red
)
end
end
return EnchantmentThorns
================================================
FILE: enchantments/aqua_affinity.json
================================================
{
"aqua_affinity": {
"noCreating": false,
"minCreatingLevel": 3,
"allowMaxLevel": 8,
"tool": [
"HELMET"
]
}
}
================================================
FILE: enchantments/bane_of_arthropods.json
================================================
{
"bane_of_arthropods": {
"noCreating": false,
"minCreatingLevel": 5,
"allowMaxLevel": 8,
"tool": [
"SWORD"
],
"conflict": [
"smite",
"sharpness"
]
}
}
================================================
FILE: enchantments/blast_protection.json
================================================
{
"blast_protection": {
"noCreating": false,
"minCreatingLevel": 3,
"allowMaxLevel": 8,
"tool": [
"HELMET",
"CHESTPLATE",
"LEGGINGS"
],
"conflict": [
"protection",
"fire_protection",
"projectile_protection"
]
}
}
================================================
FILE: enchantments/curse_of_binding.json
================================================
{
"curse_of_binding": {
"noCreating": true,
"minCreatingLevel": 1000,
"allowMaxLevel": 8,
"tool": [
"HELMET",
"CHESTPLATE",
"LEGGINGS"
]
}
}
================================================
FILE: enchantments/curse_of_vanishing.json
================================================
{
"curse_of_vanishing": {
"noCreating": true,
"minCreatingLevel": 1000,
"allowMaxLevel": 8,
"tool": [
"AXE",
"PICKAXE",
"SWORD",
"BOW",
"FISHING_ROD",
"HELMET",
"CHESTPLATE",
"LEGGINGS"
]
}
}
================================================
FILE: enchantments/depth_strider.json
================================================
{
"depth_strider": {
"noCreating": false,
"minCreatingLevel": 29,
"allowMaxLevel": 8,
"tool": [
"LEGGINGS"
],
"conflict": [
"frost_walker"
]
}
}
================================================
FILE: enchantments/efficiency.json
================================================
{
"efficiency": {
"noCreating": false,
"minCreatingLevel": 1,
"allowMaxLevel": 8,
"tool": [
"AXE",
"PICKAXE"
]
}
}
================================================
FILE: enchantments/feather_falling.json
================================================
{
"feather_falling": {
"noCreating": false,
"minCreatingLevel": 10,
"allowMaxLevel": 8,
"tool": [
"LEGGINGS"
]
}
}
================================================
FILE: enchantments/fire_aspect.json
================================================
{
"fire_aspect": {
"noCreating": false,
"minCreatingLevel": 15,
"allowMaxLevel": 8,
"tool": [
"SWORD"
]
}
}
================================================
FILE: enchantments/fire_protection.json
================================================
{
"fire_protection": {
"noCreating": false,
"minCreatingLevel": 8,
"allowMaxLevel": 6,
"tool": [
"HELMET",
"CHESTPLATE",
"LEGGINGS"
],
"conflict": [
"blast_protection",
"protection",
"projectile_protection"
]
}
}
================================================
FILE: enchantments/flame.json
================================================
{
"flame": {
"noCreating": false,
"minCreatingLevel": 29,
"allowMaxLevel": 8,
"tool": [
"BOW"
]
}
}
================================================
FILE: enchantments/fortune.json
================================================
{
"fortune": {
"noCreating": false,
"minCreatingLevel": 29,
"allowMaxLevel": 8,
"tool": [
"AXE",
"PICKAXE"
],
"conflict": [
"silk_touch"
]
}
}
================================================
FILE: enchantments/frost_walker.json
================================================
{
"frost_walker": {
"noCreating": false,
"minCreatingLevel": 29,
"allowMaxLevel": 8,
"tool": [
"LEGGINGS"
],
"conflict": [
"depth_strider"
]
}
}
================================================
FILE: enchantments/infinity.json
================================================
{
"infinity": {
"noCreating": false,
"minCreatingLevel": 29,
"allowMaxLevel": 8,
"tool": [
"BOW"
]
}
}
================================================
FILE: enchantments/knockback.json
================================================
{
"knockback": {
"noCreating": false,
"minCreatingLevel": 15,
"allowMaxLevel": 8,
"tool": [
"SWORD"
]
}
}
================================================
FILE: enchantments/looting.json
================================================
{
"looting": {
"noCreating": false,
"minCreatingLevel": 29,
"allowMaxLevel": 8,
"tool": [
"SWORD"
]
}
}
================================================
FILE: enchantments/luck_of_the_sea.json
================================================
{
"luck_of_the_sea": {
"noCreating": false,
"minCreatingLevel": 29,
"allowMaxLevel": 8,
"tool": [
"FISHING_ROD"
]
}
}
================================================
FILE: enchantments/lure.json
================================================
{
"lure": {
"noCreating": false,
"minCreatingLevel": 29,
"allowMaxLevel": 8,
"tool": [
"FISHING_ROD"
]
}
}
================================================
FILE: enchantments/multishot.json
================================================
{
"multishot": {
"noCreating": false,
"minCreatingLevel": 29,
"allowMaxLevel": 8,
"tool": [
"CROSS_BOW"
],
"conflict": [
"piercing"
]
}
}
================================================
FILE: enchantments/phyton.json
================================================
{
"phyton": {
"noCreating": true,
"minCreatingLevel": 1000,
"allowMaxLevel": 8,
"tool": [
"AXE",
"PICKAXE",
"SWORD",
"BOW",
"FISHING_ROD",
"HELMET",
"CHESTPLATE",
"LEGGINGS"
]
}
}
================================================
FILE: enchantments/piercing.json
================================================
{
"piercing": {
"noCreating": false,
"minCreatingLevel": 18,
"allowMaxLevel": 8,
"tool": [
"CROSS_BOW"
],
"conflict": [
"multishot"
]
}
}
================================================
FILE: enchantments/power.json
================================================
{
"power": {
"noCreating": false,
"minCreatingLevel": 7,
"allowMaxLevel": 8,
"tool": [
"BOW"
]
}
}
================================================
FILE: enchantments/projectile_protection.json
================================================
{
"projectile_protection": {
"noCreating": false,
"minCreatingLevel": 1,
"allowMaxLevel": 8,
"tool": [
"HELMET",
"CHESTPLATE",
"LEGGINGS"
],
"conflict": [
"blast_protection",
"fire_protection",
"protection"
]
}
}
================================================
FILE: enchantments/protection.json
================================================
{
"protection": {
"noCreating": false,
"minCreatingLevel": 1,
"allowMaxLevel": 8,
"tool": [
"HELMET",
"CHESTPLATE",
"LEGGINGS"
],
"conflict": [
"blast_protection",
"fire_protection",
"projectile_protection"
]
}
}
================================================
FILE: enchantments/punch.json
================================================
{
"punch": {
"noCreating": false,
"minCreatingLevel": 5,
"allowMaxLevel": 8,
"tool": [
"BOW"
]
}
}
================================================
FILE: enchantments/quick_charge.json
================================================
{
"quick_charge": {
"noCreating": false,
"minCreatingLevel": 29,
"allowMaxLevel": 8,
"tool": [
"CROSS_BOW"
]
}
}
================================================
FILE: enchantments/respiration.json
================================================
{
"respiration": {
"noCreating": false,
"minCreatingLevel": 29,
"allowMaxLevel": 8,
"tool": [
"HELMET"
]
}
}
================================================
FILE: enchantments/sharpness.json
================================================
{
"sharpness": {
"noCreating": false,
"minCreatingLevel": 3,
"allowMaxLevel": 8,
"tool": [
"SWORD"
],
"conflict": [
"bane_of_arthropods",
"smite"
]
}
}
================================================
FILE: enchantments/silk_touch.json
================================================
{
"silk_touch": {
"noCreating": false,
"minCreatingLevel": 29,
"allowMaxLevel": 2,
"tool": [
"AXE",
"PICKAXE"
],
"conflict": [
"fortune"
]
}
}
================================================
FILE: enchantments/smite.json
================================================
{
"smite": {
"noCreating": false,
"minCreatingLevel": 6,
"allowMaxLevel": 8,
"tool": [
"SWORD"
],
"conflict": [
"bane_of_arthropods",
"sharpness"
]
}
}
================================================
FILE: enchantments/thorns.json
================================================
{
"thorns": {
"noCreating": false,
"minCreatingLevel": 29,
"allowMaxLevel": 8,
"tool": [
"CHESTPLATE"
]
}
}
================================================
FILE: enchantments/unbreaking.json
================================================
{
"unbreaking": {
"noCreating": false,
"minCreatingLevel": 1,
"allowMaxLevel": 8,
"tool": [
"AXE",
"PICKAXE",
"SWORD",
"BOW",
"FISHING_ROD",
"HELMET",
"CHESTPLATE",
"LEGGINGS"
]
}
}
================================================
FILE: game_debug.json
================================================
{
"captureLoadedChunk": false,
"hideCmd": true,
"maxFps": false,
"singlePlayerPort": 0,
"stopNpcSpawn": false,
"isSpawnNpcQuick": false,
"ignoreHeartbeatPacket": true
}
================================================
FILE: init.lua
================================================
local ModTerraCraft = class("ModTerraCraft")
local RecordData = require("record.RecordData")
function ModTerraCraft:__init()
self.m_client = nil
self.m_server = nil
self.m_gcTick = 0
if NetMode.current == NetMode.Client then
self.m_client = require("client.ModClient").new()
end
end
function ModTerraCraft:registerProxy()
math.randomseed(os.time())
local guiLoader = require("ui.GuiLoader").new()
if NetMode.current == NetMode.Client then
Mod.current:RegisterClientGuiLoaderCallback({ guiLoader.GetClientGuiElement, guiLoader })
else
Mod.current:RegisterServerGuiLoaderCallback({ guiLoader.GetServerGuiElement, guiLoader })
local TCModWorldData = require("world.TCModWorldData")
local wdIns = TCModWorldData.getInstance()
Mod.current:RegisterWorldServerSaver({ TCModWorldData.Save, wdIns })
Mod.current:RegisterWorldServerLoader({ TCModWorldData.Load, wdIns })
end
local networkProxyHandler = require("network.TCNetworkProxyHandler")
networkProxyHandler.new()
local EnchantmentProxies = require("enchantments.EnchantmentProxies")
EnchantmentProxies.getInstance():RegisterAll()
local BuffProxies = require("buffs.BuffProxies")
BuffProxies.getInstance():RegisterAll()
local AdvancementTriggers = require("advancements.AdvancementTriggers")
AdvancementTriggers.getInstance():RegisterAll()
if NetMode.current == NetMode.Client then
local MusicSceneProxy = require("client.MusicSceneProxy")
MusicSceneProxy.getInstance():registerAll()
end
collectgarbage()
end
function ModTerraCraft:init()
self:registerProxy()
if Mod.GetByID("mod_edit") then
print("has mod_edit!")
end
if NetMode.current == NetMode.Server then
else
self.m_client:init()
end
end
function ModTerraCraft:start()
if NetMode.current == NetMode.Server then
else
self.m_client:start()
end
end
function ModTerraCraft:preUpdate()
if NetMode.current == NetMode.Server then
else
self.m_client:preUpdate()
end
end
function ModTerraCraft:update()
if NetMode.current == NetMode.Server then
RecordData.getInstance():update()
else
self.m_client:update()
end
self.m_gcTick = self.m_gcTick + 1
if self.m_gcTick >= 60 then
-- do gc every 1 seconds
self.m_gcTick = 0
collectgarbage()
end
end
function ModTerraCraft:render()
if NetMode.current == NetMode.Client then
self.m_client:render()
end
end
function ModTerraCraft:exit()
if NetMode.current == NetMode.Server then
else
self.m_client:exit()
end
end
return ModTerraCraft
================================================
FILE: item_ai/Axe.json
================================================
{
"Axe": {
"script": {
"path": "Axe.lua"
},
"destroyFragileBlocks": true,
"crossTiles": false,
"consumeItems": false,
"consumeMana": false,
"directHitPlayer": true,
"directHitNpc": true,
"hitDecreaseDurable": 0.2,
"shootDecreaseDurable": 0.0
}
}
================================================
FILE: item_ai/Axe.lua
================================================
---@class TC.Axe:TC.BaseTool
local Axe = class("Staff", require("BaseTool"))
function Axe:DrawIcon(position, color, spriteExData)
self:_DrawIconRotated(position, color, spriteExData)
end
return Axe
================================================
FILE: item_ai/BaseAccessory.lua
================================================
---@class TC.BaseAccessory:ModItem
local BaseAccessory = class("BaseAccessory", ModItem)
---
---@param player Player
function BaseAccessory:OnAccessoryUpdate(player)
end
return BaseAccessory
================================================
FILE: item_ai/BaseRangedWeapon.lua
================================================
---@class TC.BaseRangedWeapon:TC.BaseTool
local BaseRangedWeapon = class("BaseRangedWeapon", require("BaseTool"))
local GPlayer = require("player.GPlayer")
function BaseRangedWeapon:OnUsedByNpc(npc)
local item = self.itemStack:GetItem()
local modNpc = npc:GetModNpc()
if modNpc.GetHeldItemJoint ~= nil then
local itemJoint = modNpc:GetHeldItemJoint()
local projectileID = item.shootProjectileID
local realShootAngle = npc.watchAngle
local shootPoint = self:GetShootPoint(itemJoint)
local speed = item.speed
local proj = ProjectileUtils.CreateFromNpc(npc, projectileID,
shootPoint.x, shootPoint.y,
math.cos(realShootAngle) * speed,
math.sin(realShootAngle) * speed,
npc.baseAttack)
proj.isCheckPlayer = true
end
end
function BaseRangedWeapon:OnHeld(player)
local item = self.itemStack:GetItem()
local globalPlayer = GPlayer.GetInstance(player)
local lookAngle = globalPlayer:GetLookAngleInFacingDirection() - math.pi / 2
local body = globalPlayer.bone.joints:getJoint("base.body")
local head = body:getChild("head")
local backArm = body:getChild("back_arm")
local backHand = backArm:getChild("back_hand")
local frontArm = body:getChild("front_arm")
backArm.angle = lookAngle
backHand.angle = 0
local bodyAngle = lookAngle + math.pi / 2
head.angle = bodyAngle / 4
if item.twoHands then
frontArm.angle = lookAngle
end
globalPlayer.bone:update(false)
end
function BaseRangedWeapon:OnUsed(player)
local item = self.itemStack:GetItem()
local globalPlayer = GPlayer.GetInstance(player)
if globalPlayer.currentActionMaxTicks <= 0 then
-- avoid divide by zero
return
end
if item.consumeMana > 0 and player.mana < item.consumeMana then
return
end
if item.maxDurable > 0 and self.itemStack.durable <= 0 then
return
end
local lookAngle = globalPlayer:GetLookAngleInFacingDirection() - math.pi / 2
local itemJoint = globalPlayer:GetHeldItemJoint()
---@type Joint2D
local body = globalPlayer.bone.joints:getJoint("base.body")
local head = body:getChild("head")
local backArm = body:getChild("back_arm")
local backHand = backArm:getChild("back_hand")
local frontArm = body:getChild("front_arm")
backArm.angle = lookAngle
backHand.angle = 0
local bodyAngle = lookAngle + math.pi / 2
head.angle = bodyAngle / 4
local realShootAngle = player.lookAngle
if item.twoHands then
if item.usePosture == 1 then
local rate = globalPlayer.currentActionTick * 1.0 / globalPlayer.currentActionMaxTicks
if rate < 0.5 then
frontArm.angle = lookAngle - math.sin(rate * math.pi / 0.5)
else
frontArm.angle = lookAngle
end
else
frontArm.angle = lookAngle
end
end
self:OnSolveUsingAnimation(player)
-- Let's shoot the projectile from current bow!
local triggerShooting = globalPlayer.currentActionTick == 0
if triggerShooting then
local needConsume = true
local ammoIndex = -1
local projectileID = 0
local checkConsume = self:IsCheckingConsume(player)
local isMorePower = false
if checkConsume then
if item.ammoID > 0 then
local searchBest = item.ammoLevel == 0
ammoIndex = globalPlayer:GetAmmoIndexInBackpack(item.ammoID, item.ammoLevel, searchBest)
if ammoIndex >= 0 then
local slot = player.backpackInventory:GetSlot(ammoIndex)
if slot.hasStack then
local ammoItem = slot:GetStack():GetItem()
if item.ammoLevel > 0 and ammoItem.ammoLevel == 0 then
projectileID = item.shootProjectileID
else
projectileID = ammoItem.projectileID
end
if item.ammoLevel > 0 and item.ammoLevel == ammoItem.ammoLevel then
isMorePower = true
end
end
end
end
else
needConsume = false
projectileID = item.shootProjectileID
end
if checkConsume and ammoIndex < 0 then
return
end
projectileID = self:GetActualProjectileID(player, projectileID)
if projectileID > 0 then
local collided = MapUtils.WeaponCollideWithMap(itemJoint:getWorldObb(), false)
-- TODO: FIX THIS
local ignoreOverlapWithSolid = true
if not collided or (collided and ignoreOverlapWithSolid) then
local killAmmo = false
local attachItemID = -1
if NetMode.current == NetMode.Server then
if needConsume and ammoIndex >= 0 and player.backpackInventory:GetSlot(ammoIndex).hasStack then
if Utils.RandDouble(1) >= item.noConsumeChance then
killAmmo = true
if self:NeedAttachItemToProjectile(player) then
attachItemID = player.backpackInventory:GetSlot(ammoIndex):GetStack():GetItem().id
end
end
end
end
local shootPoint = self:GetShootPoint(itemJoint)
local speed = self:GetShootSpeed(player, projectileID, nil)
local attack = self:GetAttackValue(player, projectileID, nil)
realShootAngle = self:GetRealShootAngle(realShootAngle, player, projectileID, nil)
attack = attack or Attack.new(0, 0, 0)
if isMorePower then
attack.attack = math.floor(attack.attack * 1.3)
attack.knockBack = math.floor(attack.knockBack * 1.3)
end
local angleDt = self:GetMultiProjectileDeltaAngle(player, projectileID)
local angleTotalDt = 0
local shootTimes = math.max(1, item.shootTimes)
for i = 0, shootTimes - 1 do
local angle = realShootAngle + angleTotalDt
angleTotalDt = -angleTotalDt
if i % 2 == 0 then
angleTotalDt = angleTotalDt + angleDt
end
local realAttack = self:GetRealAttackValue(shootTimes, attack)
local proj = ProjectileUtils.CreateFromPlayer(player, projectileID,
shootPoint.x, shootPoint.y,
math.cos(angle) * speed,
math.sin(angle) * speed,
realAttack)
proj.isCheckNpc = true
if attachItemID > 0 and NetMode.current == NetMode.Server then
local mp = proj:GetModProjectile()
if mp then
mp.attachItemID = attachItemID
attachItemID = -1
end
end
end
if item.consumeMana > 0 then
player.mana = math.max(player.mana - item.consumeMana, 0)
end
local ammoStack = nil
if needConsume and ammoIndex >= 0 and player.backpackInventory:GetSlot(ammoIndex).hasStack then
ammoStack = player.backpackInventory:GetSlot(ammoIndex):GetStack()
end
self:OnAfterShoot(player, projectileID, ammoStack, itemJoint, realShootAngle)
if killAmmo then
player.backpackInventory:GetSlot(ammoIndex):DecrStackSize(1)
end
if item.maxDurable > 0 then
self.itemStack:LoseDurable(1)
end
end
end
end
-- test
--if NetMode.current == NetMode.Client then
-- local tp = itemJoint.transform.worldMatrix:transformVector2(self.itemStack:GetItem():GetFirePoint(0))
-- local spx, spy = math.cos(realShootAngle) * 8, math.sin(realShootAngle) * 8
-- EffectUtils.Create(Reg.EffectID("circle"), tp.x, tp.y,
-- spx, spy,
-- 0, 0.2, 0.2)
--
--end
end
---OnSolveUsingAnimation
---@param player Player
function BaseRangedWeapon:OnSolveUsingAnimation(player)
end
---IsCheckingConsume
---@param player Player
---@return boolean
function BaseRangedWeapon:IsCheckingConsume(player)
return false
end
function BaseRangedWeapon:NeedAttachItemToProjectile(player)
return false
end
---GetActualProjectileID
---@param player Player
---@param rawProjectileID int
---@return int
function BaseRangedWeapon:GetActualProjectileID(player, rawProjectileID)
return rawProjectileID
end
---GetMultiProjectileDeltaAngle
---@param player Player
---@param projectileID int
---@return double
function BaseRangedWeapon:GetMultiProjectileDeltaAngle(player, projectileID)
return 0.1
end
---GetAttackValue
---@param player Player
---@param projectileID int
---@param ammoStack ItemStack|nil
---@return Attack
function BaseRangedWeapon:GetAttackValue(player, projectileID, ammoStack)
local item = self.itemStack:GetItem()
local attack = player.baseAttack.attack + item.baseAttack.attack
local knockBack = player.baseAttack.knockBack + item.baseAttack.knockBack
local crit = player.baseAttack.crit + item.baseAttack.crit
return Attack.new(attack, knockBack, crit)
end
function BaseRangedWeapon:GetRealAttackValue(shootTimes, baseAttack)
local attack = baseAttack.attack
local knockBack = baseAttack.knockBack
local crit = baseAttack.crit
for i = 2, shootTimes do
attack = attack * 0.8
knockBack = knockBack * 0.8
crit = crit * 0.8
end
return Attack.new(attack, knockBack, crit)
end
---GetShootSpeed
---@param player Player
---@param projectileID int
---@param ammoStack ItemStack|nil
---@return double
function BaseRangedWeapon:GetShootSpeed(player, projectileID, ammoStack)
local item = self.itemStack:GetItem()
return item.speed
end
---GetRealShootAngle
---@param baseAngle double
---@param player Player
---@param projectileID int
---@param ammoStack ItemStack|nil
---@return double
function BaseRangedWeapon:GetRealShootAngle(baseAngle, player, projectileID, ammoStack)
local item = self.itemStack:GetItem()
return Utils.FixAngle(baseAngle + Utils.RandSym(item.deviation))
end
---@param player Player
---@param projectileID int
---@param ammoStack ItemStack|nil
---@param itemJoint Joint2D
---@param realShootAngle double
function BaseRangedWeapon:OnAfterShoot(player, projectileID, ammoStack, itemJoint, realShootAngle)
local item = self.itemStack:GetItem()
local soundID = item.useSoundID
if soundID > 0 then
SoundUtils.PlaySound(soundID, player.centerXi, player.centerYi)
end
local soundGroupID = item.useSoundGroupID
if soundGroupID > 0 then
SoundUtils.PlaySoundGroup(soundGroupID, player.centerXi, player.centerYi)
end
local force = 0
local backForceX = -force * math.cos(realShootAngle)
local backForceY = -force * math.sin(realShootAngle)
player.speedX = player.speedX + backForceX
player.speedY = player.speedY + backForceY
end
---GetShootPoint
---@param itemJoint Joint2D
---@return Vector2
function BaseRangedWeapon:GetShootPoint(itemJoint)
return itemJoint.transform.worldMatrix:transformVector2(self.itemStack:GetItem():GetFirePoint(0))
end
return BaseRangedWeapon
================================================
FILE: item_ai/BaseTool.lua
================================================
---@class TC.BaseTool:ModItem
local BaseTool = class("BaseTool", ModItem)
function BaseTool:_DrawIconRotated(position, color, spriteExData, rotateAngle)
if rotateAngle == nil then
rotateAngle = math.pi / 4
end
local item = self.itemStack:GetItem()
local texture = item.iconTextureLocation
local rectSource = TextureManager.getSourceRect(texture)
spriteExData.angle = spriteExData.angle + rotateAngle
spriteExData.originX = rectSource.width / 2
spriteExData.originY = rectSource.height / 2
local adaptWidth = rectSource.width > 32
local adaptHeight = rectSource.height > 32
if adaptWidth or adaptHeight then
local maxRate = 1.0
if adaptWidth then
maxRate = math.max(maxRate, rectSource.width / 32.0)
end
if adaptHeight then
maxRate = math.max(maxRate, rectSource.height / 32.0)
end
spriteExData.scaleRateX = spriteExData.scaleRateX / maxRate * 1.25
spriteExData.scaleRateY = spriteExData.scaleRateY / maxRate * 1.25
end
Sprite.draw(texture, position, rectSource, color, spriteExData, 0)
end
return BaseTool
================================================
FILE: item_ai/BlueTalisman.json
================================================
{
"BlueTalisman": {
"script": {
"path": "BlueTalisman.lua"
}
}
}
================================================
FILE: item_ai/BlueTalisman.lua
================================================
---@class TC.BlueTalisman:TC.BaseAccessory
local BlueTalisman = class("BlueTalisman", require("BaseAccessory"))
---OnAccessory
---@param player Player
function BlueTalisman:OnAccessoryUpdate(player)
if player.tickTime % 64 == 0 then
player:AddMagic(1, false)
end
end
return BlueTalisman
================================================
FILE: item_ai/BossCaller.json
================================================
{
"BossCaller": {
"script": {
"path": "BossCaller.lua"
}
}
}
================================================
FILE: item_ai/BossCaller.lua
================================================
---@class TC.BossCaller:ModItem
local BossCaller = class("BossCaller", ModItem)
function BossCaller:Init()
self.isBossCaller = true
end
function BossCaller:CanUse(player)
return true
end
function BossCaller:OnUsed(player)
self:GenBoss(player)
SoundUtils.PlaySound(Reg.SoundID("monster"), player.centerXi, player.centerYi)
end
function BossCaller:GenBoss(player)
end
function BossCaller:IsKilledAfterUsed()
return true
end
return BossCaller
================================================
FILE: item_ai/Bow.json
================================================
{
"Bow": {
"script": {
"path": "Bow.lua"
},
"destroyFragileBlocks": false,
"crossTiles": false,
"consumeItems": true,
"consumeMana": false,
"directHitPlayer": false,
"directHitNpc": false,
"hitDecreaseDurable": 0.0,
"shootDecreaseDurable": 1.0
}
}
================================================
FILE: item_ai/Bow.lua
================================================
---@class Bow:TC.BaseRangedWeapon
local Bow = class("Bow", require("BaseRangedWeapon"))
function Bow:IsCheckingConsume(player)
return true
end
function Bow:NeedAttachItemToProjectile(player)
return true
end
--function Bow:CheckShoot(itemSlot, hitbox, consumeItemID, projectileID, fireX, fireY, shootSpeed, shootAngle, baseAttack)
-- -- check enchantments
-- baseAttack.attack = baseAttack.attack + itemSlot:GetEnchantmentLevel(Reg.EnchantmentID("power"))
-- baseAttack.knockBack = baseAttack.knockBack + itemSlot:GetEnchantmentLevel(Reg.EnchantmentID("punch"))
-- return true
--end
--
--function Bow:OnShootFromPlayer(itemSlot, player, hitbox, consumeItemID, projectileID, fireX, fireY, shootSpeed, shootAngle,
-- baseAttack)
-- local flameLevel = itemSlot:GetEnchantmentLevel(Reg.EnchantmentID("flame"))
-- local shootTimes = itemSlot.shootTimes
-- for i = 1, shootTimes do
-- local angle = shootAngle + Utils.RandSym(itemSlot.deviation)
-- local speed = shootSpeed
-- local proj = ProjectileUtils.CreateFromPlayer(player, projectileID, fireX, fireY, math.cos(angle) * speed,
-- math.sin(angle) * speed, baseAttack)
-- proj.isCheckPlayer = true
-- proj.isCheckNpc = true
-- if proj.modData:DataOf("Arrow") then
-- if i == 1 and consumeItemID > 0 then
-- proj.modData.attachItemID = consumeItemID
-- end
-- proj.modData.flameLevel = flameLevel
-- end
-- end
-- return true
--end
--
--function Bow:OnShootFromNpc(itemSlot, npc, hitbox, consumeItemID, projectileID, fireX, fireY, shootSpeed, shootAngle,
-- baseAttack)
-- local flameLevel = itemSlot:GetEnchantmentLevel(Reg.EnchantmentID("flame"))
-- local shootTimes = itemSlot.shootTimes
-- for i = 1, shootTimes do
-- local angle = shootAngle + Utils.RandSym(itemSlot.deviation)
-- local speed = shootSpeed
-- local proj = ProjectileUtils.CreateFromNpc(npc, projectileID, fireX, fireY, math.cos(angle) * speed,
-- math.sin(angle) * speed, baseAttack)
-- proj.isCheckPlayer = true
-- proj.isCheckNpc = false
-- if proj.modData:DataOf("Arrow") then
-- if i == 1 and consumeItemID > 0 then
-- proj.modData.attachItemID = consumeItemID
-- end
-- proj.modData.flameLevel = flameLevel
-- end
-- end
-- return true
--end
--
--function Bow:CheckConsumeItem(itemSlot, player, projectileID)
-- local infinityLevel = itemSlot:GetEnchantmentLevel(Reg.EnchantmentID("infinity"))
-- -- Has unlimited enchantments, so no items are consumed
-- if infinityLevel > 0 then
-- return false
-- end
-- return true
--end
return Bow
================================================
FILE: item_ai/CrisonEye.json
================================================
{
"CrisonEye": {
"script": {
"path": "CrisonEye.lua"
}
}
}
================================================
FILE: item_ai/CrisonEye.lua
================================================
---@class TC.CrisonEyeItem:TC.BossCaller
local CrisonEye = class("CrisonEye", require("BossCaller"))
local RecordData = require("record.RecordData")
function CrisonEye:CanUse(player)
if MiscUtils.isNight then
if not RecordData.getInstance().hasCrisonEye then
return true
end
end
return false
end
---@param player Player
function CrisonEye:GenBoss(player)
NpcUtils.Create(Reg.NpcID("crison_eye"), player.centerX - 700, player.centerY - 400)
end
return CrisonEye
================================================
FILE: item_ai/DungeonEater.json
================================================
{
"DungeonEater": {
"script": {
"path": "DungeonEater.lua"
}
}
}
================================================
FILE: item_ai/DungeonEater.lua
================================================
---@class TC.DungeonEaterItem:TC.BossCaller
local DungeonEater = class("DungeonEater", require("BossCaller"))
local RecordData = require("record.RecordData")
function DungeonEater:CanUse(player)
if not RecordData.getInstance().hasDungeonEater then
if player.biomeID == Reg.BiomeID("more_dungeons:tr_dungeon") then
return true
end
end
return false
end
---@param player Player
function DungeonEater:GenBoss(player)
NpcUtils.Create(Reg.NpcID("dungeon_eater_head"), player.centerX - 700, player.centerY + 300)
end
return DungeonEater
================================================
FILE: item_ai/EnderMirror.json
================================================
{
"EnderMirror": {
"script": {
"path": "EnderMirror.lua"
}
}
}
================================================
FILE: item_ai/EnderMirror.lua
================================================
---@class TC.EnderMirror:ModItem
local EnderMirror = class("EnderMirror", ModItem)
function EnderMirror:Init()
end
function EnderMirror:CanUse(player)
return true
end
function EnderMirror:OnHeld(player)
end
function EnderMirror:OnUsed(player)
local ok = player:GoHome()
if not ok then
player:TeleportToSpawn()
end
player:FinishAdvancement(Reg.AdvancementID("mirror"))
SoundUtils.PlaySound(Reg.SoundID("travel"), player.centerXi, player.centerYi)
end
function EnderMirror:GenBoss(player)
end
function EnderMirror:IsKilledAfterUsed()
return false
end
return EnderMirror
================================================
FILE: item_ai/Food.json
================================================
{
"Food": {
"script": {
"path": "Food.lua"
}
}
}
================================================
FILE: item_ai/Food.lua
================================================
---@class TC.Food:ModItem
local Food = class("Food", ModItem)
local Constants = require("constants.Constants")
function Food:CanUse(player)
local stack = self.itemStack
local healthCodeID = Reg.BuffID("health_cold")
local item = stack:GetItem()
local buffs = item.buffs
if player:HasBuff(healthCodeID) then
for _, buff in ipairs(buffs) do
if buff.id == healthCodeID then
return false
end
end
end
if #buffs > 0 then
return true
end
if item.addHealth > 0 or (item.addMagic > 0 and item.addMaxMagic == 0) then
return true
end
if item.addMaxMagic > 0 then
if player.maxMana < Constants.PLAYER_MAX_MAX_MANA then
return true
end
return false
end
if item.food > 0 and player.foodLevel < 100 then
return true
end
return false
end
function Food:OnUsed(player)
local item = self.itemStack:GetItem()
if item.addHealth ~= 0 then
local v = math.abs(item.addHealth)
if item.addHealth < 0 then
player:Strike(DeathReason.BUFF, Attack.new(v, 0, 0), 0, false, false)
else
player:Heal(v)
end
end
if item.addMaxMagic ~= 0 then
local PlayerConstants = require("player.PlayerConstants")
player.maxMana = math.min(PlayerConstants.MaxManaA, player.maxMana + item.addMaxMagic)
end
if item.addMagic ~= 0 then
local v = math.abs(item.addMagic)
player:AddMagic(v)
end
local buffs = item.buffs
for _, buff in ipairs(buffs) do
player:AddBuff(buff.id, buff.time)
end
if item.food > 0 and player.foodLevel < 100 then
player:AddFood(item.food, item.foodSaturation)
end
self:PlayEatSound(player)
end
function Food:PlayEatSound(player)
SoundUtils.PlaySoundGroup(Reg.SoundGroupID("eat"), player.centerXi, player.centerYi)
end
function Food:IsKilledAfterUsed()
return true
end
return Food
================================================
FILE: item_ai/Gun.json
================================================
{
"Gun": {
"script": {
"path": "Gun.lua"
},
"destroyFragileBlocks": false,
"crossTiles": false,
"consumeItems": true,
"consumeMana": false,
"directHitPlayer": false,
"directHitNpc": false,
"hitDecreaseDurable": 0.0,
"shootDecreaseDurable": 1.0
}
}
================================================
FILE: item_ai/Gun.lua
================================================
---@class TC.Gun:TC.BaseRangedWeapon
local Gun = class("Gun", require("BaseRangedWeapon"))
function Gun:IsCheckingConsume(player)
return true
end
function Gun:NeedAttachItemToProjectile(player)
return true
end
--local e_fire_smoke = Reg.EffectID("fire_smoke")
--local e_liquid_paticular = Reg.EffectID("liquid_paticular")
--
--function Gun:CheckShoot(itemSlot, hitbox, consumeItemID, projectileID, fireX, fireY, shootSpeed, shootAngle, baseAttack)
-- -- Add some gunpowder effect.
--
-- local special = itemSlot.special
-- if special == 1 then -- Shoot from a normal gun.
-- local effect = EffectUtils.Create(e_fire_smoke, fireX, fireY, math.cos(shootAngle) * 0.5 + Utils.RandSym(0.25),
-- math.cos(shootAngle) * 0.5 + Utils.RandSym(0.25), Utils.RandSym(0.1),
-- Utils.RandDoubleArea(1.5, 0.5), 0.5)
-- effect.color = Color.new(200,200,200)
-- for i = 1, 3 do
-- local effect2 = EffectUtils.Create(e_liquid_paticular, fireX, fireY,
-- math.cos(shootAngle) * 1.0 + Utils.RandSym(0.25),
-- math.cos(shootAngle) * 1.0 - Utils.RandDouble(0.5), Utils.RandSym(0.1), 0.5)
-- effect2.color = Color.Yellow
-- end
-- elseif special == 2 then -- Shoot from a fire gun.
-- local effect = EffectUtils.Create(e_liquid_paticular, fireX, fireY,
-- math.cos(shootAngle) * 0.2 + Utils.RandSym(0.25), -Utils.RandDouble(0.75),
-- Utils.RandSym(0.1), Utils.RandDoubleArea(0.5, 1.0), 0.5)
-- effect.color = Color.new(255,180,0)
-- elseif special == 3 then -- Shoot from a laser gun.
-- for i = 1, 3 do
-- EffectUtils.Create(e_liquid_paticular, fireX, fireY, math.cos(shootAngle) * 0.2 + Utils.RandSym(0.25),
-- -Utils.RandDouble(0.75), Utils.RandSym(0.1), Utils.RandDoubleArea(0.5, 1.0), 0.5)
-- end
-- end
--
-- return true
--end
return Gun
================================================
FILE: item_ai/InfBow.json
================================================
{
"InfBow": {
"script": {
"path": "InfBow.lua"
},
"destroyFragileBlocks": false,
"crossTiles": false,
"consumeItems": true,
"consumeMana": false,
"directHitPlayer": false,
"directHitNpc": false,
"hitDecreaseDurable": 0.0,
"shootDecreaseDurable": 1.0
}
}
================================================
FILE: item_ai/InfBow.lua
================================================
---@class InfBow:TC.BaseRangedWeapon
local InfBow = class("InfBow", require("BaseRangedWeapon"))
function InfBow:IsCheckingConsume(player)
return false
end
function InfBow:NeedAttachItemToProjectile(player)
return false
end
return InfBow
================================================
FILE: item_ai/Ingot.json
================================================
{
"Ingot": {
"script": {
"path": "Ingot.lua"
}
}
}
================================================
FILE: item_ai/Ingot.lua
================================================
---@class TC.Ingot:ModItem
local Ingot = class("Ingot", ModItem)
function Ingot:IsUseTex32()
return true
end
function Ingot:DrawIcon(position, color, spriteExData)
local item = self.itemStack:GetItem()
local texture = item.iconTextureLocation
local rectSource = TextureManager.getSourceRect(texture)
local width = rectSource.width
local height = rectSource.height / 2
spriteExData.originX = width / 2
spriteExData.originY = height / 2
local rectBase = Rect.new(0, 0, width, height)
Sprite.draw(texture, position, rectBase, item.iconColor * color, spriteExData, 0)
if item.iconColor2.alpha ~= 0 then
local rectHighlight = Rect.new(0, height, width, height)
Sprite.draw(texture, position, rectHighlight, item.iconColor2 * color, spriteExData, 0)
end
end
return Ingot
================================================
FILE: item_ai/LavaNecklace.json
================================================
{
"LavaNecklace": {
"script": {
"path": "LavaNecklace.lua"
}
}
}
================================================
FILE: item_ai/LavaNecklace.lua
================================================
---@class TC.LavaNecklace:TC.BaseAccessory
local LavaNecklace = class("LavaNecklace", require("BaseAccessory"))
---OnAccessory
---@param player Player
function LavaNecklace:OnAccessoryUpdate(player)
if NetMode.current == NetMode.Client then
local cnt = 3
for i = 1, cnt do
local angle = player.tickTime / 10 + math.pi * 2 / cnt * i
local d = 45
local x = player.centerX + math.cos(angle) * d
local y = player.centerY + math.sin(angle) * d
local effect = EffectUtils.Create(
Reg.EffectID("circle"),
x,
y,
Utils.RandSym(0.5),
Utils.RandSym(0.5),
0,
Utils.RandDoubleArea(0.25, 0.15),
Utils.RandDoubleArea(0.25, 0.15),
Color.new(255, 255, 0)
)
effect:SetDisappearTime(6)
local effect = EffectUtils.Create(
Reg.EffectID("chip"),
x,
y,
Utils.RandSym(1.5),
Utils.RandSym(1.5),
0,
Utils.RandDoubleArea(0.75, 0.5),
Utils.RandDoubleArea(0.5, 0.5),
Color.new(255, 255, 0)
)
effect:SetDisappearTime(12)
end
--if player.tickTime % 8 == 0 then
-- local effect = EffectUtils.Create(Reg.EffectID("heal"),
-- player.randX, player.randY,
-- Utils.RandSym(1), Utils.RandDoubleArea(-2, 2)
-- )
-- effect:SetDisappearTime(10)
--
--end
else
if player.tickTime % 64 == 0 then
player:AddBuff(Reg.BuffID("fire_defense"), 100)
end
end
end
return LavaNecklace
================================================
FILE: item_ai/LavaSword.json
================================================
{
"LavaSword": {
"script": {
"path": "LavaSword.lua"
}
}
}
================================================
FILE: item_ai/LavaSword.lua
================================================
---@class TC.LavaSword:TC.Sword
local LavaSword = class("LavaSword", require("Sword"))
function LavaSword:ModifyHitNpc(npc, baseAttack)
npc:AddBuff(Reg.BuffID("fire"), 128)
return true
end
return LavaSword
================================================
FILE: item_ai/LightingTalisman.json
================================================
{
"LightingTalisman": {
"script": {
"path": "LightingTalisman.lua"
}
}
}
================================================
FILE: item_ai/LightingTalisman.lua
================================================
---@class TC.LightingTalisman:TC.BaseAccessory
local LightingTalisman = class("LightingTalisman", require("BaseAccessory"))
---OnAccessory
---@param player Player
function LightingTalisman:OnAccessoryUpdate(player)
LightingUtils.Add(player.centerXi, player.centerYi, 32)
end
return LightingTalisman
================================================
FILE: item_ai/Pickaxe.json
================================================
{
"Pickaxe": {
"script": {
"path": "Pickaxe.lua"
},
"destroyFragileBlocks": true,
"crossTiles": false,
"consumeItems": false,
"consumeMana": false,
"directHitPlayer": true,
"directHitNpc": true,
"hitDecreaseDurable": 0.2,
"shootDecreaseDurable": 0.0
}
}
================================================
FILE: item_ai/Pickaxe.lua
================================================
---@class TC.Pickaxe:TC.BaseTool
local Pickaxe = class("Staff", require("BaseTool"))
function Pickaxe:DrawIcon(position, color, spriteExData)
self:_DrawIconRotated(position, color, spriteExData)
end
return Pickaxe
================================================
FILE: item_ai/Potion.json
================================================
{
"Potion": {
"script": {
"path": "Potion.lua"
}
}
}
================================================
FILE: item_ai/Potion.lua
================================================
---@class TC.Potion:TC.Food
local Potion = class("Potion", require("Food"))
function Potion:IsUseTex32()
return true
end
function Potion:DrawIcon(position, color, spriteExData)
local item = self.itemStack:GetItem()
local texture = item.iconTextureLocation
local rectSource = TextureManager.getSourceRect(texture)
local width = rectSource.width
local height = rectSource.height / 2
spriteExData.originX = width / 2
spriteExData.originY = height / 2
local rectBase = Rect.new(0, 0, width, height)
local rectLiquid = Rect.new(0, height, width, height)
if item.iconColor2.alpha ~= 0 then
Sprite.draw(texture, position, rectLiquid, item.iconColor2 * color, spriteExData, 0)
end
Sprite.draw(texture, position, rectBase, color, spriteExData, 0)
end
function Potion:PlayEatSound(player)
SoundUtils.PlaySound(Reg.SoundID("drink"), player.centerXi, player.centerYi)
end
return Potion
================================================
FILE: item_ai/RedTalisman.json
================================================
{
"RedTalisman": {
"script": {
"path": "RedTalisman.lua"
}
}
}
================================================
FILE: item_ai/RedTalisman.lua
================================================
---@class TC.RedTalisman:TC.BaseAccessory
local RedTalisman = class("RedTalisman", require("BaseAccessory"))
---OnAccessory
---@param player Player
function RedTalisman:OnAccessoryUpdate(player)
if player.tickTime % 64 == 0 then
player:Heal(1, false)
end
end
return RedTalisman
================================================
FILE: item_ai/RocketBoost.json
================================================
{
"RocketBoost": {
"script": {
"path": "RocketBoost.lua"
}
}
}
================================================
FILE: item_ai/RocketBoost.lua
================================================
---@class TC.RocketBoost:TC.BaseAccessory
local RocketBoost = class("RocketBoost", require("BaseAccessory"))
local GPlayer = require("player.GPlayer")
local PlayerConstants = require("player.PlayerConstants")
function RocketBoost:Init()
self.flying = false
self.flyingTime = 0
self.flyingTimeMax = 128
end
---OnAccessory
---@param player Player
function RocketBoost:OnAccessoryUpdate(player)
if NetMode.current == NetMode.Client then
local gPlayer = GPlayer.GetInstance(player)
self.flyingTimeMax = 128
self:FlyMove(player)
if self.flying then
local fts = {
gPlayer.bone.joints:getJoint("base.body.front_leg.front_feet"),
gPlayer.bone.joints:getJoint("base.body.back_leg.back_feet")
}
for i = 1, 2 do
local c = fts[i].transform.worldMatrix:transformVector2(Vector2.new(4, 16))
local effect = EffectUtils.Create(
Reg.EffectID("fire_smoke"),
c.x,
c.y,
Utils.RandSym(0.5),
1 + Utils.RandSym(0.5),
Utils.RandSym(0.5),
Utils.RandDoubleArea(0.55, 0.15),
1.0,
Color.new(255, 255, 255)
)
effect:SetDisappearTime(50)
if player.tickTime % 4 == 0 then
EffectUtils.Create(
Reg.EffectID("fire_flame"),
c.x,
c.y,
Utils.RandSym(0.5),
0.5 + Utils.RandSym(0.5),
Utils.RandSym(0.5),
Utils.RandDoubleArea(0.55, 0.15),
1.0,
Color.new(255, 255, 255)
)
end
end
end
end
end
function RocketBoost:FlyMove(player)
local gPlayer = GPlayer.GetInstance(player)
if not gPlayer.jump then
self.flying = false
end
if player.stand then
self.flying = false
self.flyingTime = 0
return
end
if player.speedY > 0.5 then
if gPlayer.jump then
self.flying = true
end
end
if self.flying then
self.flyingTime = self.flyingTime + 1
if self.flyingTime > self.flyingTimeMax then
self.flying = false
return
end
player.speedY = player.speedY - 0.8
if player.speedY < -PlayerConstants.MAX_SPEED_UP / 2 then
player.speedY = -PlayerConstants.MAX_SPEED_UP / 2
end
end
end
return RocketBoost
================================================
FILE: item_ai/Staff.json
================================================
{
"Staff": {
"script": {
"path": "Staff.lua"
},
"destroyFragileBlocks": false,
"crossTiles": false,
"consumeItems": false,
"consumeMana": true,
"directHitPlayer": false,
"directHitNpc": false,
"hitDecreaseDurable": 0.0,
"shootDecreaseDurable": 0.0
}
}
================================================
FILE: item_ai/Staff.lua
================================================
---@class TC.Staff:TC.BaseRangedWeapon
local Staff = class("Staff", require("BaseRangedWeapon"))
local GPlayer = require("player.GPlayer")
local BoneAction = {
StaffShooting = 5,
}
function Staff:OnHeld(player)
local globalPlayer = GPlayer.GetInstance(player)
if globalPlayer.currentAction == BoneAction.StaffShooting or
globalPlayer.lastTickAction == BoneAction.StaffShooting then
return
end
local body = globalPlayer.bone.joints:getJoint("base.body")
local backArm = body:getChild("back_arm")
local backHand = backArm:getChild("back_hand")
backArm.angle = -math.pi * 0.4
backHand.angle = 0
globalPlayer.bone:update(false)
end
function Staff:OnSolveUsingAnimation(player)
local globalPlayer = GPlayer.GetInstance(player)
local itemJoint = globalPlayer:GetHeldItemJoint()
itemJoint.angle = math.pi
end
function Staff:DrawIcon(position, color, spriteExData)
self:_DrawIconRotated(position, color, spriteExData)
end
return Staff
================================================
FILE: item_ai/Sword.json
================================================
{
"Sword": {
"script": {
"path": "Sword.lua"
}
}
}
================================================
FILE: item_ai/Sword.lua
================================================
---@class TC.Sword:TC.BaseTool
local Sword = class("Sword", require("BaseTool"))
local GPlayer = require("player.GPlayer")
local USE_DECREASE_DURABLE = 0.5
function Sword:Init()
self.wasSwingAtCenter = false
end
function Sword:OnHeld(player)
end
function Sword:IsKilledAfterUsed()
return self.itemStack.durable <= 0
end
function Sword:OnKilledAfterUsed(player)
SoundUtils.PlaySound(Reg.SoundID("broken"), player.centerXi, player.centerYi)
end
function Sword:OnUsedByNpc(npc)
local modNpc = npc:GetModNpc()
if modNpc == nil or modNpc.GetHeldItemJoint == nil then
return
end
local itemJoint = modNpc:GetHeldItemJoint()
local attack = npc.baseAttack
local resPlayerIndex = EntityIndex.new()
local isHitPlayer = PlayerUtils.WeaponCollide(self.itemStack, 0, itemJoint:getWorldObb(), attack, resPlayerIndex)
if isHitPlayer then
local player = PlayerUtils.Get(resPlayerIndex)
local hitAngle = 0.0
if not npc.direction then
hitAngle = math.pi
end
player:StrikeFromNpc(npc, attack, hitAngle, true)
end
end
function Sword:OnUsed(player)
local item = self.itemStack:GetItem()
local globalPlayer = GPlayer.GetInstance(player)
local itemJoint = globalPlayer:GetHeldItemJoint()
if globalPlayer.currentActionTick == 0 then
self.wasSwingAtCenter = false
SoundUtils.PlaySound(Reg.SoundID("weapon"), player.centerXi, player.centerYi)
elseif globalPlayer.currentActionTick > 0.05 then
-- destroy the map block
local hitSolid, hasBlockDestroyed = MapUtils.WeaponCollideWithMap(itemJoint:getWorldObb(), true)
if not hitSolid then
local attack = player.baseAttack
local resNpcIndex = EntityIndex.new()
local hitNpc = NpcUtils.WeaponCollide(self.itemStack, 0,
itemJoint:getWorldObb(), attack, resNpcIndex)
if hitNpc then
local npc = NpcUtils.Get(resNpcIndex)
local hitAngle = 0.0
if not player.direction then
hitAngle = math.pi
end
local looting = self.itemStack:GetEnchantmentLevel(Reg.EnchantmentID("looting"))
npc:StrikeFromPlayer(player, attack, hitAngle, true, true, looting)
if NetMode.current == NetMode.Server then
-- TODO 耐久在创造模式不减
if USE_DECREASE_DURABLE > 0 then
self.itemStack:LoseDurable(USE_DECREASE_DURABLE)
end
end
end
if not self.wasSwingAtCenter and globalPlayer.currentActionTick > 0.5 then
self.wasSwingAtCenter = true
if item.consumeMana > 0 and item.shootProjectileID > 0 then
if player.mana >= item.consumeMana then
player.mana = math.max(0, player.mana - item.consumeMana)
local cx, cy = player.centerX, player.centerY
local realShootAngle = not player.direction and math.pi or 0
local proj = ProjectileUtils.CreateFromPlayer(player, item.shootProjectileID,
cx, cy,
math.cos(realShootAngle) * item.speed,
math.sin(realShootAngle) * item.speed,
attack)
proj.isCheckNpc = true
end
end
end
end
-- test
if false and NetMode.current == NetMode.Client then
local tp = itemJoint.transform.worldMatrix:transformVector2(self.itemStack:GetItem():GetFirePoint(0))
local effect = EffectUtils.Create(Reg.EffectID("circle"), tp.x, tp.y,
0, 0,
0, 0.2)
end
end
end
function Sword:DrawIcon(position, color, spriteExData)
self:_DrawIconRotated(position, color, spriteExData)
end
--function Sword:Save()
-- return {
-- test = 123,
-- word = "hello world"
-- }
--end
--
--function Sword:Load(tagTable)
-- --print(tagTable.test, tagTable.word)
--end
return Sword
================================================
FILE: item_ai/Torch.json
================================================
{
"Torch": {
"script": {
"path": "Torch.lua"
}
}
}
================================================
FILE: item_ai/Torch.lua
================================================
---@class TC.Torch:ModItem
local Torch = class("Sword", ModItem)
local GPlayer = require("player.GPlayer")
local modTextureID = Reg.ModTextureID("torch_fire")
local modTexture = ModTextureUtils.GetData(modTextureID)
local modTextureLocation = modTexture.textureLocation
function Torch:GetFirePoint(player)
local globalPlayer = GPlayer.GetInstance(player)
local itemJoint = globalPlayer:GetHeldItemJoint()
return itemJoint.transform.worldMatrix:transformVector2(self.itemStack:GetItem():GetFirePoint(0))
end
function Torch:OnHeld(player)
local tp = self:GetFirePoint(player)
local xi = Utils.Cell(tp.x)
local yi = Utils.Cell(tp.y)
local lightingAlpha, r, g, b = self:GetLightingValue()
LightingUtils.AddDelay(xi, yi, 20, lightingAlpha, r, g, b)
if player.tickTime % 16 == 0 then
EffectUtils.Create(Reg.EffectID("fire_smoke"), tp.x, tp.y,
Utils.RandSym(0.25), -0.85, Utils.RandSym(0.05),
Utils.RandDoubleArea(0.95, 0.5), 0.8
)
end
end
function Torch:OnHeldRender(player)
local tp = self:GetFirePoint(player)
local style = math.floor(player.tickTime / 8) % 4
local cutRect = Rect.new(style * 16, 0, 16, 16)
local drawX = tp.x - 8 - MiscUtils.screenX
local drawY = tp.y - 12 - MiscUtils.screenY
Sprite.draw(modTextureLocation, Vector2.new(drawX, drawY), cutRect, Color.White)
end
function Torch:GetLightingValue()
return 30, 0, 0, 0
end
return Torch
================================================
FILE: item_ai/cross_bow.json
================================================
{
"cross_bow": {
"script": {
"path": "cross_bow.lua"
},
"destroyFragileBlocks": false,
"crossTiles": false,
"consumeItems": true,
"consumeMana": false,
"directHitPlayer": false,
"directHitNpc": false,
"hitDecreaseDurable": 0.0,
"shootDecreaseDurable": 1.0
}
}
================================================
FILE: item_ai/cross_bow.lua
================================================
local CrossBow = class("CrossBow", ModItem)
--function CrossBow:OnShootFromPlayer(itemSlot, player, hitbox, consumeItemID, projectileID, fireX, fireY, shootSpeed, shootAngle,
-- baseAttack)
-- local shootTimes = itemSlot.shootTimes
-- if shootTimes == 1 then
-- local multishotLevel = itemSlot:GetEnchantmentLevel(Reg.EnchantmentID("multishot"))
-- shootTimes = shootTimes + multishotLevel
-- end
-- if shootTimes > 1 then
-- baseAttack.attack = math.ceil(baseAttack.attack * 0.75)
-- end
-- local piercingLevel = itemSlot:GetEnchantmentLevel(Reg.EnchantmentID("piercing"))
-- for i = 1, shootTimes do
-- local angle = shootAngle + Utils.RandSym(itemSlot.deviation)
-- local speed = shootSpeed
-- local proj = ProjectileUtils.CreateFromPlayer(player, projectileID, fireX, fireY, math.cos(angle) * speed,
-- math.sin(angle) * speed, baseAttack)
-- proj.isCheckPlayer = true
-- proj.isCheckNpc = true
-- if proj.modData:DataOf("Arrow") then
-- if i == 1 and consumeItemID > 0 then
-- proj.modData.attachItemID = consumeItemID
-- end
-- proj.modData.piercingCount = math.floor(piercingLevel * 0.5)
-- end
-- end
-- return true
--end
--
--function CrossBow:OnShootFromNpc(itemSlot, npc, hitbox, consumeItemID, projectileID, fireX, fireY, shootSpeed, shootAngle,
-- baseAttack)
-- local shootTimes = itemSlot.shootTimes
-- if shootTimes == 1 then
-- local multishotLevel = itemSlot:GetEnchantmentLevel(Reg.EnchantmentID("multishot"))
-- shootTimes = shootTimes + multishotLevel
-- end
-- local piercingLevel = itemSlot:GetEnchantmentLevel(Reg.EnchantmentID("piercing"))
-- for i = 1, shootTimes do
-- local angle = shootAngle + Utils.RandSym(itemSlot.deviation)
-- local speed = shootSpeed
-- local proj = ProjectileUtils.CreateFromNpc(npc, projectileID, fireX, fireY, math.cos(angle) * speed,
-- math.sin(angle) * speed, baseAttack)
-- proj.isCheckPlayer = true
-- proj.isCheckNpc = false
-- if proj.modData:DataOf("Arrow") then
-- if i == 1 and consumeItemID > 0 then
-- proj.modData.attachItemID = consumeItemID
-- end
-- proj.modData.piercingCount = math.floor(piercingLevel * 0.5)
-- end
-- end
-- return true
--end
return CrossBow
================================================
FILE: item_ai/dirt.json
================================================
{
"dirt": {
"script": {
"path": "dirt.lua"
}
}
}
================================================
FILE: item_ai/dirt.lua
================================================
---@class TC.Dirt:ModItem
local Dirt = class("Dirt", ModItem)
function Dirt:Init()
--print("hello dirt! you have", self.itemStack.stackSize)
end
function Dirt:DrawIcon(position, color, spriteExData)
local item = self.itemStack:GetItem()
local texture = item.iconTextureLocation
local rectSource = TextureManager.getSourceRect(texture)
spriteExData.originX = rectSource.width / 2
spriteExData.originY = rectSource.height / 2
Sprite.draw(texture, position, rectSource, color, spriteExData, 0)
end
function Dirt:OnHeld(player)
--print("hhhhh", player.name)
end
return Dirt
================================================
FILE: item_ai/drill.json
================================================
{
"drill": {
"script": {
"path": "drill.lua"
},
"destroyFragileBlocks": true,
"crossTiles": false,
"consumeItems": false,
"consumeMana": false,
"directHitPlayer": true,
"directHitNpc": true,
"hitDecreaseDurable": 0.5,
"shootDecreaseDurable": 0.0
}
}
================================================
FILE: item_ai/drill.lua
================================================
local Drill = class("Drill", ModItem)
--local e_fire_smoke = Reg.EffectID("fire_smoke")
--
--function Drill:OnUseFromPlayer(itemSlot, player, hitbox, fireX, fireY)
-- if player.tickTime % 4 == 0 then
-- EffectUtils.Create(e_fire_smoke, fireX, fireY, Utils.RandSym(1), Utils.RandSym(1), Utils.RandSym(0.05),
-- Utils.RandDoubleArea(0.5, 0.5))
-- end
--end
--
--function Drill:OnUseFromNpc(itemSlot, npc, hitbox, fireX, fireY)
-- if npc.tickTime % 4 == 0 then
-- EffectUtils.Create(e_fire_smoke, fireX, fireY, Utils.RandSym(1), Utils.RandSym(1), Utils.RandSym(0.05),
-- Utils.RandDoubleArea(0.5, 0.5))
-- end
--end
return Drill
================================================
FILE: item_ai/fire_gun.json
================================================
{
"fire_gun": {
"script": {
"path": "Gun.lua"
},
"destroyFragileBlocks": false,
"crossTiles": false,
"consumeItems": false,
"consumeMana": false,
"directHitPlayer": false,
"directHitNpc": false,
"hitDecreaseDurable": 0.0,
"shootDecreaseDurable": 1.0
}
}
================================================
FILE: item_ai/fishing_rod.json
================================================
{
"fishing_rod": {
"script": {
"path": "fishing_rod.lua"
},
"destroyFragileBlocks": false,
"crossTiles": false,
"consumeItems": true,
"consumeMana": false,
"directHitPlayer": false,
"directHitNpc": false,
"hitDecreaseDurable": 0.0,
"shootDecreaseDurable": 0.0
}
}
================================================
FILE: item_ai/fishing_rod.lua
================================================
local FishingRod = class("FishingRod", ModItem)
-- TODO
-- So when will blueyoshi write the code for the fishing rod?
return FishingRod
================================================
FILE: item_ai/laser_gun.json
================================================
{
"laser_gun": {
"script": {
"path": "Gun.lua"
},
"destroyFragileBlocks": false,
"crossTiles": false,
"consumeItems": false,
"consumeMana": false,
"directHitPlayer": false,
"directHitNpc": false,
"hitDecreaseDurable": 0.0,
"shootDecreaseDurable": 1.0
}
}
================================================
FILE: item_ai/magic_sword.json
================================================
{
"magic_sword": {
"script": {
"path": "Sword.lua"
},
"destroyFragileBlocks": true,
"crossTiles": false,
"consumeItems": false,
"consumeMana": true,
"directHitPlayer": true,
"directHitNpc": true,
"hitDecreaseDurable": 0.5,
"shootDecreaseDurable": 0.0
}
}
================================================
FILE: item_ai/rocket_launcher.json
================================================
{
"rocket_launcher": {
"script": {
"path": "Gun.lua"
},
"destroyFragileBlocks": false,
"crossTiles": false,
"consumeItems": true,
"consumeMana": false,
"directHitPlayer": false,
"directHitNpc": false,
"hitDecreaseDurable": 0.0,
"shootDecreaseDurable": 1.0
}
}
================================================
FILE: item_ai/saw.json
================================================
{
"saw": {
"script": {
"path": "drill.lua"
},
"destroyFragileBlocks": true,
"crossTiles": false,
"consumeItems": false,
"consumeMana": false,
"directHitPlayer": true,
"directHitNpc": true,
"hitDecreaseDurable": 0.5,
"shootDecreaseDurable": 0.0
}
}
================================================
FILE: item_ai/swordA.json
================================================
{
"sword": {
"script": {
"path": "swordA.lua"
},
"destroyFragileBlocks": true,
"crossTiles": false,
"consumeItems": false,
"consumeMana": false,
"directHitPlayer": true,
"directHitNpc": true,
"hitDecreaseDurable": 0.5,
"shootDecreaseDurable": 0.0
}
}
================================================
FILE: item_ai/swordA.lua
================================================
local Sword = class("Sword", ModItem)
--function Sword:CheckHitNpc(itemSlot, npcTarget, hitbox, fireX, fireY, hitAngle, baseAttack)
-- -- check enchantments
-- local arthropodsLevel = itemSlot:GetEnchantmentLevel(Reg.EnchantmentID("bane_of_arthropods"))
-- local fireAspectLevel = itemSlot:GetEnchantmentLevel(Reg.EnchantmentID("fire_aspect"))
-- local smiteLevel = itemSlot:GetEnchantmentLevel(Reg.EnchantmentID("smite"))
--
-- if fireAspectLevel > 0 then
-- npcTarget:AddBuff(Reg.BuffID("fire"), fireAspectLevel * 60)
-- end
-- if arthropodsLevel > 0 and npcTarget.type == NPC_TYPE_ARTHROPODS then
-- baseAttack.attack = baseAttack.attack + arthropodsLevel * 2
-- end
-- if smiteLevel > 0 and npcTarget.type == NPC_TYPE_SMITE then
-- baseAttack.attack = baseAttack.attack + smiteLevel * 2
-- end
--
-- return true
--end
--
--function Sword:CheckHitPlayer(itemSlot, playerTarget, hitbox, fireX, fireY, hitAngle, baseAttack)
-- -- check enchantments
-- local fireAspectLevel = itemSlot:GetEnchantmentLevel(Reg.EnchantmentID("fire_aspect"))
-- if fireAspectLevel > 0 then
-- playerTarget:AddBuff(Reg.BuffID("fire"), fireAspectLevel * 60)
-- end
-- return true
--end
return Sword
================================================
FILE: items/accessory/blue_talisman.json
================================================
{
"blue_talisman": {
"type": "MATERIALS",
"ai": "BlueTalisman",
"iconTextureData": "blue_talisman.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/accessory/gold_talisman.json
================================================
{
"gold_talisman": {
"type": "MATERIALS",
"iconTextureData": "gold_talisman.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/accessory/heart_talisman.json
================================================
{
"heart_talisman": {
"type": "MATERIALS",
"ai": "RedTalisman",
"iconTextureData": "heart_talisman.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/accessory/lava_necklace.json
================================================
{
"lava_necklace": {
"type": "MATERIALS",
"iconTextureData": "lava_necklace.png",
"ai": "LavaNecklace",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/accessory/lighting_talisman.json
================================================
{
"lighting_talisman": {
"type": "MATERIALS",
"ai": "LightingTalisman",
"iconTextureData": "lighting_talisman.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/accessory/rocket_boost.json
================================================
{
"rocket_boost": {
"type": "MATERIALS",
"ai": "RocketBoost",
"iconTextureData": "rocket_boost.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/armors/ancient/ancient_chestplate.json
================================================
{
"ancient_chestplate": {
"type": "TOOLS",
"iconTextureData": "chestplate14.png",
"textureData": "body14.png",
"group": "GROUP_CHESTPLATE",
"toolType": "CHESTPLATE",
"isArmor": true,
"defense": 8,
"durable": 3160
}
}
================================================
FILE: items/armors/ancient/ancient_helmet.json
================================================
{
"ancient_helmet": {
"type": "TOOLS",
"iconTextureData": "ihat14.png",
"textureData": "hat14.png",
"group": "GROUP_HELMET",
"toolType": "HELMET",
"isArmor": true,
"defense": 6,
"durable": 3160
}
}
================================================
FILE: items/armors/ancient/ancient_leggings.json
================================================
{
"ancient_leggings": {
"type": "TOOLS",
"iconTextureData": "leggings14.png",
"textureData": "leg14.png",
"group": "GROUP_LEGGINGS",
"toolType": "LEGGINGS",
"isArmor": true,
"defense": 7,
"durable": 3160
}
}
================================================
FILE: items/armors/bronze/bronze_chestplate.json
================================================
{
"bronze_chestplate": {
"type": "TOOLS",
"iconTextureData": "bronze_chestplate_icon.png",
"textureData": "body.png",
"group": "GROUP_CHESTPLATE",
"toolType": "CHESTPLATE",
"isArmor": true,
"defense": 5,
"durable": 624
}
}
================================================
FILE: items/armors/bronze/bronze_helmet.json
================================================
{
"bronze_helmet": {
"type": "TOOLS",
"iconTextureData": "bronze_helmet_icon.png",
"textureData": "hat.png",
"group": "GROUP_HELMET",
"toolType": "HELMET",
"isArmor": true,
"defense": 3,
"durable": 624
}
}
================================================
FILE: items/armors/bronze/bronze_leggings.json
================================================
{
"bronze_leggings": {
"type": "TOOLS",
"iconTextureData": "bronze_leggings_icon.png",
"textureData": "leg.png",
"group": "GROUP_LEGGINGS",
"toolType": "LEGGINGS",
"isArmor": true,
"defense": 4,
"durable": 624
}
}
================================================
FILE: items/armors/copper/copper_chestplate.json
================================================
{
"copper_chestplate": {
"type": "TOOLS",
"iconTextureData": "copper_chestplate_icon.png",
"textureData": "body.png",
"group": "GROUP_CHESTPLATE",
"toolType": "CHESTPLATE",
"isArmor": true,
"defense": 3,
"durable": 412
}
}
================================================
FILE: items/armors/copper/copper_helmet.json
================================================
{
"copper_helmet": {
"type": "TOOLS",
"iconTextureData": "copper_helmet_icon.png",
"textureData": "hat.png",
"group": "GROUP_HELMET",
"toolType": "HELMET",
"isArmor": true,
"defense": 2,
"durable": 412
}
}
================================================
FILE: items/armors/copper/copper_leggings.json
================================================
{
"copper_leggings": {
"type": "TOOLS",
"iconTextureData": "copper_leggings_icon.png",
"textureData": "leg.png",
"group": "GROUP_LEGGINGS",
"toolType": "LEGGINGS",
"isArmor": true,
"defense": 2,
"durable": 412
}
}
================================================
FILE: items/armors/diamond/diamond_chestplate.json
================================================
{
"diamond_chestplate": {
"type": "TOOLS",
"iconTextureData": "diamond_chestplate_icon.png",
"textureData": "body.png",
"group": "GROUP_CHESTPLATE",
"subGroup": "SUB_GROUP_DIAMOND",
"toolType": "CHESTPLATE",
"isArmor": true,
"defense": 7,
"durable": 1552
}
}
================================================
FILE: items/armors/diamond/diamond_helmet.json
================================================
{
"diamond_helmet": {
"type": "TOOLS",
"iconTextureData": "diamond_helmet_icon.png",
"textureData": "hat.png",
"group": "GROUP_HELMET",
"subGroup": "SUB_GROUP_DIAMOND",
"toolType": "HELMET",
"isArmor": true,
"defense": 5,
"durable": 1552
}
}
================================================
FILE: items/armors/diamond/diamond_leggings.json
================================================
{
"diamond_leggings": {
"type": "TOOLS",
"iconTextureData": "diamond_leggings_icon.png",
"textureData": "leg.png",
"group": "GROUP_LEGGINGS",
"subGroup": "SUB_GROUP_DIAMOND",
"toolType": "LEGGINGS",
"isArmor": true,
"defense": 6,
"durable": 1552
}
}
================================================
FILE: items/armors/fine_tin/fine_tin_chestplate.json
================================================
{
"fine_tin_chestplate": {
"type": "TOOLS",
"iconTextureData": "chestplate4.png",
"textureData": "body4.png",
"group": "GROUP_CHESTPLATE",
"toolType": "CHESTPLATE",
"isArmor": true,
"defense": 5,
"durable": 788
}
}
================================================
FILE: items/armors/fine_tin/fine_tin_helmet.json
================================================
{
"fine_tin_helmet": {
"type": "TOOLS",
"iconTextureData": "ihat4.png",
"textureData": "hat4.png",
"group": "GROUP_HELMET",
"toolType": "HELMET",
"isArmor": true,
"defense": 3,
"durable": 788
}
}
================================================
FILE: items/armors/fine_tin/fine_tin_leggings.json
================================================
{
"fine_tin_leggings": {
"type": "TOOLS",
"iconTextureData": "leggings4.png",
"textureData": "leg4.png",
"group": "GROUP_LEGGINGS",
"toolType": "LEGGINGS",
"isArmor": true,
"defense": 4,
"durable": 788
}
}
================================================
FILE: items/armors/flesh/flesh_chestplate.json
================================================
{
"flesh_chestplate": {
"type": "TOOLS",
"iconTextureData": "chestplate7.png",
"textureData": "body7.png",
"group": "GROUP_CHESTPLATE",
"toolType": "CHESTPLATE",
"isArmor": true,
"defense": 6,
"durable": 1560
}
}
================================================
FILE: items/armors/flesh/flesh_helmet.json
================================================
{
"flesh_helmet": {
"type": "TOOLS",
"iconTextureData": "ihat7.png",
"textureData": "hat7.png",
"group": "GROUP_HELMET",
"toolType": "HELMET",
"isArmor": true,
"defense": 4,
"durable": 1560
}
}
================================================
FILE: items/armors/flesh/flesh_leggings.json
================================================
{
"flesh_leggings": {
"type": "TOOLS",
"iconTextureData": "leggings7.png",
"textureData": "leg7.png",
"group": "GROUP_LEGGINGS",
"toolType": "LEGGINGS",
"isArmor": true,
"defense": 5,
"durable": 1560
}
}
================================================
FILE: items/armors/gold/golden_chestplate.json
================================================
{
"golden_chestplate": {
"type": "TOOLS",
"iconTextureData": "golden_chestplate_icon.png",
"textureData": "body.png",
"group": "GROUP_CHESTPLATE",
"toolType": "CHESTPLATE",
"isArmor": true,
"defense": 6,
"durable": 788
}
}
================================================
FILE: items/armors/gold/golden_helmet.json
================================================
{
"golden_helmet": {
"type": "TOOLS",
"iconTextureData": "golden_helmet_icon.png",
"textureData": "hat.png",
"group": "GROUP_HELMET",
"toolType": "HELMET",
"isArmor": true,
"defense": 4,
"durable": 788
}
}
================================================
FILE: items/armors/gold/golden_leggings.json
================================================
{
"golden_leggings": {
"type": "TOOLS",
"iconTextureData": "golden_leggings_icon.png",
"textureData": "leg.png",
"group": "GROUP_LEGGINGS",
"toolType": "LEGGINGS",
"isArmor": true,
"defense": 5,
"durable": 788
}
}
================================================
FILE: items/armors/iron/iron_chestplate.json
================================================
{
"iron_chestplate": {
"type": "TOOLS",
"iconTextureData": "iron_chestplate_icon.png",
"textureData": "body.png",
"group": "GROUP_CHESTPLATE",
"toolType": "CHESTPLATE",
"isArmor": true,
"defense": 4,
"durable": 500
}
}
================================================
FILE: items/armors/iron/iron_helmet.json
================================================
{
"iron_helmet": {
"type": "TOOLS",
"iconTextureData": "iron_helmet_icon.png",
"textureData": "hat.png",
"group": "GROUP_HELMET",
"toolType": "HELMET",
"isArmor": true,
"defense": 2,
"durable": 500
}
}
================================================
FILE: items/armors/iron/iron_leggings.json
================================================
{
"iron_leggings": {
"type": "TOOLS",
"iconTextureData": "iron_leggings_icon.png",
"textureData": "leg.png",
"group": "GROUP_LEGGINGS",
"toolType": "LEGGINGS",
"isArmor": true,
"defense": 3,
"durable": 500
}
}
================================================
FILE: items/armors/knight/knight_chestplate.json
================================================
{
"knight_chestplate": {
"type": "TOOLS",
"iconTextureData": "chestplate5.png",
"textureData": "body5.png",
"group": "GROUP_CHESTPLATE",
"toolType": "CHESTPLATE",
"isArmor": true,
"defense": 6,
"durable": 1552
}
}
================================================
FILE: items/armors/knight/knight_helmet.json
================================================
{
"knight_helmet": {
"type": "TOOLS",
"iconTextureData": "ihat5.png",
"textureData": "hat5.png",
"group": "GROUP_HELMET",
"toolType": "HELMET",
"isArmor": true,
"defense": 4,
"durable": 1552
}
}
================================================
FILE: items/armors/knight/knight_leggings.json
================================================
{
"knight_leggings": {
"type": "TOOLS",
"iconTextureData": "leggings5.png",
"textureData": "leg5.png",
"group": "GROUP_LEGGINGS",
"toolType": "LEGGINGS",
"isArmor": true,
"defense": 5,
"durable": 1552
}
}
================================================
FILE: items/armors/lava/lava_chestplate.json
================================================
{
"lava_chestplate": {
"type": "TOOLS",
"iconTextureData": "chestplate8.png",
"textureData": "body8.png",
"group": "GROUP_CHESTPLATE",
"toolType": "CHESTPLATE",
"isArmor": true,
"defense": 6,
"durable": 1552
}
}
================================================
FILE: items/armors/lava/lava_helmet.json
================================================
{
"lava_helmet": {
"type": "TOOLS",
"iconTextureData": "ihat8.png",
"textureData": "hat8.png",
"group": "GROUP_HELMET",
"toolType": "HELMET",
"isArmor": true,
"defense": 4,
"durable": 1552
}
}
================================================
FILE: items/armors/lava/lava_leggings.json
================================================
{
"lava_leggings": {
"type": "TOOLS",
"iconTextureData": "leggings8.png",
"textureData": "leg8.png",
"group": "GROUP_LEGGINGS",
"toolType": "LEGGINGS",
"isArmor": true,
"defense": 5,
"durable": 1552
}
}
================================================
FILE: items/armors/lead/lead_chestplate.json
================================================
{
"lead_chestplate": {
"type": "TOOLS",
"iconTextureData": "lead_chestplate_icon.png",
"textureData": "body.png",
"group": "GROUP_CHESTPLATE",
"toolType": "CHESTPLATE",
"isArmor": true,
"defense": 4,
"durable": 500
}
}
================================================
FILE: items/armors/lead/lead_helmet.json
================================================
{
"lead_helmet": {
"type": "TOOLS",
"iconTextureData": "lead_helmet_icon.png",
"textureData": "hat.png",
"group": "GROUP_HELMET",
"toolType": "HELMET",
"isArmor": true,
"defense": 3,
"durable": 500
}
}
================================================
FILE: items/armors/lead/lead_leggings.json
================================================
{
"lead_leggings": {
"type": "TOOLS",
"iconTextureData": "lead_leggings_icon.png",
"textureData": "leg.png",
"group": "GROUP_LEGGINGS",
"toolType": "LEGGINGS",
"isArmor": true,
"defense": 3,
"durable": 500
}
}
================================================
FILE: items/armors/leather/leather_chestplate.json
================================================
{
"leather_chestplate": {
"type": "TOOLS",
"iconTextureData": "leather_chestplate_icon.png",
"textureData": "body.png",
"group": "GROUP_CHESTPLATE",
"toolType": "CHESTPLATE",
"isArmor": true,
"defense": 2,
"durable": 64
}
}
================================================
FILE: items/armors/leather/leather_helmet.json
================================================
{
"leather_helmet": {
"type": "TOOLS",
"iconTextureData": "leather_helmet_icon.png",
"textureData": "hat.png",
"showHair": true,
"group": "GROUP_HELMET",
"toolType": "HELMET",
"isArmor": true,
"defense": 1,
"durable": 64
}
}
================================================
FILE: items/armors/leather/leather_leggings.json
================================================
{
"leather_leggings": {
"type": "TOOLS",
"iconTextureData": "leather_leggings_icon.png",
"textureData": "leg.png",
"group": "GROUP_LEGGINGS",
"toolType": "LEGGINGS",
"isArmor": true,
"defense": 1,
"durable": 64
}
}
================================================
FILE: items/armors/magic_gold/magic_gold_chestplate.json
================================================
{
"magic_gold_chestplate": {
"type": "TOOLS",
"iconTextureData": "chestplate2.png",
"textureData": "body2.png",
"group": "GROUP_CHESTPLATE",
"toolType": "CHESTPLATE",
"isArmor": true,
"defense": 6,
"durable": 1440
}
}
================================================
FILE: items/armors/magic_gold/magic_gold_helmet.json
================================================
{
"magic_gold_helmet": {
"type": "TOOLS",
"iconTextureData": "ihat2.png",
"textureData": "hat2.png",
"group": "GROUP_HELMET",
"toolType": "HELMET",
"isArmor": true,
"defense": 4,
"durable": 1440
}
}
================================================
FILE: items/armors/magic_gold/magic_gold_leggings.json
================================================
{
"magic_gold_leggings": {
"type": "TOOLS",
"iconTextureData": "leggings2.png",
"textureData": "leg2.png",
"group": "GROUP_LEGGINGS",
"toolType": "LEGGINGS",
"isArmor": true,
"defense": 5,
"durable": 1440
}
}
================================================
FILE: items/armors/magic_shadow/magic_shadow_chestplate.json
================================================
{
"magic_shadow_chestplate": {
"type": "TOOLS",
"iconTextureData": "chestplate11.png",
"textureData": "body11.png",
"group": "GROUP_CHESTPLATE",
"toolType": "CHESTPLATE",
"isArmor": true,
"defense": 6,
"durable": 2022
}
}
================================================
FILE: items/armors/magic_shadow/magic_shadow_helmet.json
================================================
{
"magic_shadow_helmet": {
"type": "TOOLS",
"iconTextureData": "ihat11.png",
"textureData": "hat11.png",
"group": "GROUP_HELMET",
"toolType": "HELMET",
"isArmor": true,
"defense": 4,
"durable": 2022
}
}
================================================
FILE: items/armors/magic_shadow/magic_shadow_leggings.json
================================================
{
"magic_shadow_leggings": {
"type": "TOOLS",
"iconTextureData": "leggings11.png",
"textureData": "leg11.png",
"group": "GROUP_LEGGINGS",
"toolType": "LEGGINGS",
"isArmor": true,
"defense": 5,
"durable": 2022
}
}
================================================
FILE: items/armors/magic_silver/magic_silver_chestplate.json
================================================
{
"magic_silver_chestplate": {
"type": "TOOLS",
"iconTextureData": "chestplate1.png",
"textureData": "body1.png",
"group": "GROUP_CHESTPLATE",
"toolType": "CHESTPLATE",
"isArmor": true,
"defense": 6,
"durable": 1440
}
}
================================================
FILE: items/armors/magic_silver/magic_silver_helmet.json
================================================
{
"magic_silver_helmet": {
"type": "TOOLS",
"iconTextureData": "ihat1.png",
"textureData": "hat1.png",
"group": "GROUP_HELMET",
"toolType": "HELMET",
"isArmor": true,
"defense": 4,
"durable": 1440
}
}
================================================
FILE: items/armors/magic_silver/magic_silver_leggings.json
================================================
{
"magic_silver_leggings": {
"type": "TOOLS",
"iconTextureData": "leggings1.png",
"textureData": "leg1.png",
"group": "GROUP_LEGGINGS",
"toolType": "LEGGINGS",
"isArmor": true,
"defense": 5,
"durable": 1440
}
}
================================================
FILE: items/armors/nether/nether_chestplate.json
================================================
{
"nether_chestplate": {
"type": "TOOLS",
"iconTextureData": "nether_chestplate_icon.png",
"textureData": "body.png",
"group": "GROUP_CHESTPLATE",
"subGroup": "SUB_GROUP_NETHERITE",
"toolType": "CHESTPLATE",
"isArmor": true,
"defense": 7,
"durable": 2020,
"antiLava": true
}
}
================================================
FILE: items/armors/nether/nether_helmet.json
================================================
{
"nether_helmet": {
"type": "TOOLS",
"iconTextureData": "nether_helmet_icon.png",
"textureData": "hat.png",
"group": "GROUP_HELMET",
"subGroup": "SUB_GROUP_NETHERITE",
"toolType": "HELMET",
"isArmor": true,
"defense": 5,
"durable": 2020,
"antiLava": true
}
}
================================================
FILE: items/armors/nether/nether_leggings.json
================================================
{
"nether_leggings": {
"type": "TOOLS",
"iconTextureData": "nether_leggings_icon.png",
"textureData": "leg.png",
"group": "GROUP_LEGGINGS",
"subGroup": "SUB_GROUP_NETHERITE",
"toolType": "LEGGINGS",
"isArmor": true,
"defense": 6,
"durable": 2020,
"antiLava": true
}
}
================================================
FILE: items/armors/pumpkin/pumpkin_helmet.json
================================================
{
"pumpkin_helmet": {
"type": "TOOLS",
"iconTextureData": "pumpkin_helmet_icon.png",
"textureData": "hat.png",
"group": "GROUP_HELMET",
"toolType": "HELMET",
"isArmor": true,
"defense": 1,
"durable": 64
}
}
================================================
FILE: items/armors/shadow/shadow_chestplate.json
================================================
{
"shadow_chestplate": {
"type": "TOOLS",
"iconTextureData": "chestplate3.png",
"textureData": "body3.png",
"group": "GROUP_CHESTPLATE",
"toolType": "CHESTPLATE",
"isArmor": true,
"defense": 6,
"durable": 788
}
}
================================================
FILE: items/armors/shadow/shadow_helmet.json
================================================
{
"shadow_helmet": {
"type": "TOOLS",
"iconTextureData": "ihat3.png",
"textureData": "hat3.png",
"group": "GROUP_HELMET",
"toolType": "HELMET",
"isArmor": true,
"defense": 4,
"durable": 788
}
}
================================================
FILE: items/armors/shadow/shadow_leggings.json
================================================
{
"shadow_leggings": {
"type": "TOOLS",
"iconTextureData": "leggings3.png",
"textureData": "leg3.png",
"group": "GROUP_LEGGINGS",
"toolType": "LEGGINGS",
"isArmor": true,
"defense": 5,
"durable": 788
}
}
================================================
FILE: items/armors/silver/silver_chestplate.json
================================================
{
"silver_chestplate": {
"type": "TOOLS",
"iconTextureData": "silver_chestplate_icon.png",
"textureData": "body.png",
"group": "GROUP_CHESTPLATE",
"toolType": "CHESTPLATE",
"isArmor": true,
"defense": 6,
"durable": 788
}
}
================================================
FILE: items/armors/silver/silver_helmet.json
================================================
{
"silver_helmet": {
"type": "TOOLS",
"iconTextureData": "silver_helmet_icon.png",
"textureData": "hat.png",
"group": "GROUP_HELMET",
"toolType": "HELMET",
"isArmor": true,
"defense": 4,
"durable": 788
}
}
================================================
FILE: items/armors/silver/silver_leggings.json
================================================
{
"silver_leggings": {
"type": "TOOLS",
"iconTextureData": "silver_leggings_icon.png",
"textureData": "leg.png",
"group": "GROUP_LEGGINGS",
"toolType": "LEGGINGS",
"isArmor": true,
"defense": 5,
"durable": 788
}
}
================================================
FILE: items/armors/star/star_chestplate.json
================================================
{
"star_chestplate": {
"type": "TOOLS",
"iconTextureData": "chestplate6.png",
"textureData": "body6.png",
"group": "GROUP_CHESTPLATE",
"toolType": "CHESTPLATE",
"isArmor": true,
"defense": 6,
"durable": 3160
}
}
================================================
FILE: items/armors/star/star_helmet.json
================================================
{
"star_helmet": {
"type": "TOOLS",
"iconTextureData": "ihat6.png",
"textureData": "hat6.png",
"group": "GROUP_HELMET",
"toolType": "HELMET",
"isArmor": true,
"defense": 4,
"durable": 3160
}
}
================================================
FILE: items/armors/star/star_leggings.json
================================================
{
"star_leggings": {
"type": "TOOLS",
"iconTextureData": "leggings6.png",
"textureData": "leg6.png",
"group": "GROUP_LEGGINGS",
"toolType": "LEGGINGS",
"isArmor": true,
"defense": 5,
"durable": 3160
}
}
================================================
FILE: items/armors/steel/steel_chestplate.json
================================================
{
"steel_chestplate": {
"type": "TOOLS",
"iconTextureData": "steel_chestplate_icon.png",
"textureData": "body.png",
"group": "GROUP_CHESTPLATE",
"toolType": "CHESTPLATE",
"isArmor": true,
"defense": 5,
"durable": 624
}
}
================================================
FILE: items/armors/steel/steel_helmet.json
================================================
{
"steel_helmet": {
"type": "TOOLS",
"iconTextureData": "steel_helmet_icon.png",
"textureData": "hat.png",
"group": "GROUP_HELMET",
"toolType": "HELMET",
"isArmor": true,
"defense": 3,
"durable": 624
}
}
================================================
FILE: items/armors/steel/steel_leggings.json
================================================
{
"steel_leggings": {
"type": "TOOLS",
"iconTextureData": "steel_leggings_icon.png",
"textureData": "leg.png",
"group": "GROUP_LEGGINGS",
"toolType": "LEGGINGS",
"isArmor": true,
"defense": 4,
"durable": 624
}
}
================================================
FILE: items/armors/super_diamond/super_diamond_chestplate.json
================================================
{
"super_diamond_chestplate": {
"type": "TOOLS",
"iconTextureData": "chestplate10.png",
"textureData": "body10.png",
"group": "GROUP_CHESTPLATE",
"toolType": "CHESTPLATE",
"isArmor": true,
"defense": 7,
"durable": 1552
}
}
================================================
FILE: items/armors/super_diamond/super_diamond_helmet.json
================================================
{
"super_diamond_helmet": {
"type": "TOOLS",
"iconTextureData": "ihat10.png",
"textureData": "hat10.png",
"group": "GROUP_HELMET",
"toolType": "HELMET",
"isArmor": true,
"defense": 5,
"durable": 1552
}
}
================================================
FILE: items/armors/super_diamond/super_diamond_leggings.json
================================================
{
"super_diamond_leggings": {
"type": "TOOLS",
"iconTextureData": "leggings10.png",
"textureData": "leg10.png",
"group": "GROUP_LEGGINGS",
"toolType": "LEGGINGS",
"isArmor": true,
"defense": 6,
"durable": 1552
}
}
================================================
FILE: items/armors/tin/tin_chestplate.json
================================================
{
"tin_chestplate": {
"type": "TOOLS",
"iconTextureData": "tin_chestplate_icon.png",
"textureData": "body.png",
"group": "GROUP_CHESTPLATE",
"toolType": "CHESTPLATE",
"isArmor": true,
"defense": 3,
"durable": 412
}
}
================================================
FILE: items/armors/tin/tin_helmet.json
================================================
{
"tin_helmet": {
"type": "TOOLS",
"iconTextureData": "tin_helmet_icon.png",
"textureData": "hat.png",
"group": "GROUP_HELMET",
"toolType": "HELMET",
"isArmor": true,
"defense": 2,
"durable": 412
}
}
================================================
FILE: items/armors/tin/tin_leggings.json
================================================
{
"tin_leggings": {
"type": "TOOLS",
"iconTextureData": "tin_leggings_icon.png",
"textureData": "leg.png",
"group": "GROUP_LEGGINGS",
"toolType": "LEGGINGS",
"isArmor": true,
"defense": 2,
"durable": 412
}
}
================================================
FILE: items/arrows/blood_arrow.json
================================================
{
"blood_arrow": {
"type": "PROJECTILES",
"iconTextureData": "blood_arrow_icon.png",
"group": "GROUP_ARROW",
"ammo": "arrow",
"ammoLevel": 3,
"projectileId": "blood_arrow",
"speed": 1.0,
"shootable": true,
"damage": 1,
"knockBack": 1
}
}
================================================
FILE: items/arrows/blue_arrow.json
================================================
{
"blue_arrow": {
"type": "PROJECTILES",
"iconTextureData": "blue_arrow.png",
"group": "GROUP_ARROW",
"ammo": "arrow",
"ammoLevel": 6,
"projectileId": "blue_arrow",
"speed": 2.0,
"shootable": true,
"damage": 3,
"knockBack": 1
}
}
================================================
FILE: items/arrows/ice_arrow.json
================================================
{
"ice_arrow": {
"type": "PROJECTILES",
"iconTextureData": "ice_arrow_icon.png",
"group": "GROUP_ARROW",
"ammo": "arrow",
"ammoLevel": 4,
"projectileId": "ice_arrow",
"speed": 2.0,
"shootable": true,
"damage": 1,
"knockBack": 1
}
}
================================================
FILE: items/arrows/lighting_arrow.json
================================================
{
"lighting_arrow": {
"type": "PROJECTILES",
"iconTextureData": "lighting_arrow_icon.png",
"group": "GROUP_ARROW",
"ammo": "arrow",
"ammoLevel": 1,
"projectileId": "lighting_arrow",
"speed": 1.0,
"shootable": true,
"damage": 2,
"knockBack": 1
}
}
================================================
FILE: items/arrows/star_arrow.json
================================================
{
"star_arrow": {
"type": "PROJECTILES",
"iconTextureData": "star_arrow_icon.png",
"group": "GROUP_ARROW",
"ammo": "arrow",
"ammoLevel": 2,
"projectileId": "star_arrow",
"speed": 1.0,
"shootable": true,
"damage": 2,
"knockBack": 1
}
}
================================================
FILE: items/arrows/sword_arrow.json
================================================
{
"sword_arrow": {
"type": "PROJECTILES",
"iconTextureData": "sword_arrow_icon.png",
"group": "GROUP_ARROW",
"ammo": "arrow",
"ammoLevel": 5,
"projectileId": "sword_arrow",
"speed": 0.0,
"shootable": true,
"damage": 1,
"knockBack": 1
}
}
================================================
FILE: items/arrows/wooden_arrow.json
================================================
{
"wooden_arrow": {
"type": "PROJECTILES",
"iconTextureData": "wooden_arrow_icon.png",
"group": "GROUP_ARROW",
"ammo": "arrow",
"ammoLevel": 0,
"projectileId": "wooden_arrow",
"speed": 0.0,
"shootable": true,
"damage": 2,
"knockBack": 1
}
}
================================================
FILE: items/axes/bronze_axe.json
================================================
{
"bronze_axe": {
"type": "TOOLS",
"iconTextureData": "bronze_axe_entity.png",
"textureData": "bronze_axe_entity.png",
"group": "GROUP_AXE",
"toolType": "AXE",
"toolGrade": "GOLD",
"efficiency": 3.5,
"ai": "Axe",
"coldTime": 18,
"entityWidth": 22,
"entityHeight": 40,
"handX": 8,
"handY": 32,
"holdType": "NORMAL",
"durable": 1248,
"damage": 4,
"knockBack": 1,
"crit": 0
}
}
================================================
FILE: items/axes/copper_axe.json
================================================
{
"copper_axe": {
"type": "TOOLS",
"iconTextureData": "copper_axe_entity.png",
"textureData": "copper_axe_entity.png",
"group": "GROUP_AXE",
"toolType": "AXE",
"toolGrade": "IRON",
"efficiency": 2.5,
"ai": "Axe",
"coldTime": 18,
"entityWidth": 22,
"entityHeight": 40,
"handX": 8,
"handY": 32,
"holdType": "NORMAL",
"durable": 824,
"damage": 4,
"knockBack": 1,
"crit": 0
}
}
================================================
FILE: items/axes/diamond_axe.json
================================================
{
"diamond_axe": {
"type": "TOOLS",
"iconTextureData": "diamond_axe_entity.png",
"textureData": "diamond_axe_entity.png",
"group": "GROUP_AXE",
"toolType": "AXE",
"toolGrade": "DIAMOND",
"efficiency": 5.0,
"ai": "Axe",
"coldTime": 16,
"entityWidth": 22,
"entityHeight": 40,
"handX": 8,
"handY": 32,
"holdType": "NORMAL",
"durable": 4040,
"damage": 5,
"knockBack": 1,
"crit": 0
}
}
================================================
FILE: items/axes/golden_axe.json
================================================
{
"golden_axe": {
"type": "TOOLS",
"iconTextureData": "golden_axe_entity.png",
"textureData": "golden_axe_entity.png",
"group": "GROUP_AXE",
"toolType": "AXE",
"toolGrade": "GOLD",
"efficiency": 4.0,
"ai": "Axe",
"coldTime": 18,
"entityWidth": 22,
"entityHeight": 40,
"handX": 8,
"handY": 32,
"holdType": "NORMAL",
"durable": 1856,
"damage": 4,
"knockBack": 1,
"crit": 0
}
}
================================================
FILE: items/axes/grass_axe.json
================================================
{
"grass_axe": {
"type": "TOOLS",
"iconTextureData": "grass_axe_entity.png",
"textureData": "grass_axe_entity.png",
"group": "GROUP_AXE",
"toolType": "AXE",
"toolGrade": "GRASS",
"efficiency": 1.0,
"ai": "Axe",
"coldTime": 20,
"entityWidth": 20,
"entityHeight": 30,
"handX": 5,
"handY": 26,
"holdType": "NORMAL",
"durable": 128,
"damage": 1,
"knockBack": 1,
"crit": 0,
"isNoBreaking": true,
"enchantments": [
{
"id": "phyton",
"level": 1
}
]
}
}
================================================
FILE: items/axes/iron_axe.json
================================================
{
"iron_axe": {
"type": "TOOLS",
"iconTextureData": "iron_axe_entity.png",
"textureData": "iron_axe_entity.png",
"group": "GROUP_AXE",
"toolType": "AXE",
"toolGrade": "IRON",
"efficiency": 3.0,
"ai": "Axe",
"coldTime": 18,
"entityWidth": 20,
"entityHeight": 36,
"handX": 8,
"handY": 32,
"holdType": "NORMAL",
"durable": 1000,
"damage": 4,
"knockBack": 1,
"crit": 0
}
}
================================================
FILE: items/axes/lead_axe.json
================================================
{
"lead_axe": {
"type": "TOOLS",
"iconTextureData": "lead_axe_entity.png",
"textureData": "lead_axe_entity.png",
"group": "GROUP_AXE",
"toolType": "AXE",
"toolGrade": "IRON",
"efficiency": 3.0,
"ai": "Axe",
"coldTime": 18,
"entityWidth": 22,
"entityHeight": 40,
"handX": 8,
"handY": 32,
"holdType": "NORMAL",
"durable": 1000,
"damage": 4,
"knockBack": 1,
"crit": 0
}
}
================================================
FILE: items/axes/nether_axe.json
================================================
{
"nether_axe": {
"type": "TOOLS",
"iconTextureData": "nether_axe_entity.png",
"textureData": "nether_axe_entity.png",
"group": "GROUP_AXE",
"toolType": "AXE",
"toolGrade": "DIAMOND",
"efficiency": 5.5,
"ai": "Axe",
"coldTime": 16,
"entityWidth": 22,
"entityHeight": 40,
"handX": 8,
"handY": 32,
"holdType": "NORMAL",
"durable": 4896,
"damage": 5,
"knockBack": 1,
"crit": 0,
"antiLava": true
}
}
================================================
FILE: items/axes/silver_axe.json
================================================
{
"silver_axe": {
"type": "TOOLS",
"iconTextureData": "silver_axe_entity.png",
"textureData": "silver_axe_entity.png",
"group": "GROUP_AXE",
"toolType": "AXE",
"toolGrade": "GOLD",
"efficiency": 4.0,
"ai": "Axe",
"coldTime": 18,
"entityWidth": 22,
"entityHeight": 40,
"handX": 8,
"handY": 32,
"holdType": "NORMAL",
"durable": 1856,
"damage": 4,
"knockBack": 1,
"crit": 0
}
}
================================================
FILE: items/axes/steel_axe.json
================================================
{
"steel_axe": {
"type": "TOOLS",
"iconTextureData": "steel_axe_entity.png",
"textureData": "steel_axe_entity.png",
"group": "GROUP_AXE",
"toolType": "AXE",
"toolGrade": "GOLD",
"efficiency": 3.5,
"ai": "Axe",
"coldTime": 18,
"entityWidth": 22,
"entityHeight": 40,
"handX": 8,
"handY": 32,
"holdType": "NORMAL",
"durable": 1248,
"damage": 4,
"knockBack": 1,
"crit": 0
}
}
================================================
FILE: items/axes/stone_axe.json
================================================
{
"stone_axe": {
"type": "TOOLS",
"iconTextureData": "stone_axe_entity.png",
"textureData": "stone_axe_entity.png",
"group": "GROUP_AXE",
"toolType": "AXE",
"toolGrade": "STONE",
"efficiency": 2.0,
"ai": "Axe",
"coldTime": 20,
"entityWidth": 20,
"entityHeight": 36,
"handX": 7,
"handY": 28,
"holdType": "NORMAL",
"durable": 524,
"damage": 3,
"knockBack": 1,
"crit": 0
}
}
================================================
FILE: items/axes/tin_axe.json
================================================
{
"tin_axe": {
"type": "TOOLS",
"iconTextureData": "tin_axe_entity.png",
"textureData": "tin_axe_entity.png",
"group": "GROUP_AXE",
"toolType": "AXE",
"toolGrade": "IRON",
"efficiency": 2.5,
"ai": "Axe",
"coldTime": 18,
"entityWidth": 22,
"entityHeight": 40,
"handX": 8,
"handY": 32,
"holdType": "NORMAL",
"durable": 824,
"damage": 4,
"knockBack": 1,
"crit": 0
}
}
================================================
FILE: items/axes/wooden_axe.json
================================================
{
"wooden_axe": {
"type": "TOOLS",
"iconTextureData": "wooden_axe_entity.png",
"textureData": "wooden_axe_entity.png",
"group": "GROUP_AXE",
"toolType": "AXE",
"toolGrade": "WOOD",
"efficiency": 1.5,
"ai": "Axe",
"coldTime": 20,
"entityWidth": 18,
"entityHeight": 30,
"handX": 5,
"handY": 26,
"holdType": "NORMAL",
"durable": 280,
"damage": 2,
"knockBack": 1,
"crit": 0,
"fuelTime": 40
}
}
================================================
FILE: items/bombs/bomb.json
================================================
{
"bomb": {
"type": "PROJECTILES",
"iconTextureData": "bomb_icon.png",
"group": "GROUP_BOMB",
"projectileId": "bomb",
"speed": 5.0,
"canThrow": true,
"damage": 12,
"knockBack": 8,
"coldTime": 180,
"shootable": true
}
}
================================================
FILE: items/bombs/glow_bomb.json
================================================
{
"glow_bomb": {
"type": "PROJECTILES",
"iconTextureData": "glow_bomb_icon.png",
"group": "GROUP_BOMB",
"projectileId": "glow_bomb",
"speed": 6.0,
"canThrow": true,
"damage": 3,
"knockBack": 8,
"coldTime": 400,
"shootable": true
}
}
================================================
FILE: items/bombs/grenade.json
================================================
{
"grenade": {
"type": "PROJECTILES",
"iconTextureData": "grenade_icon.png",
"group": "GROUP_BOMB",
"projectileId": "grenade",
"speed": 6.0,
"canThrow": true,
"damage": 5,
"knockBack": 5,
"coldTime": 180,
"shootable": true
}
}
================================================
FILE: items/boomerangs/boomerang.json
================================================
{
"boomerang": {
"type": "TOOLS",
"iconTextureData": "boomerang_icon.png",
"group": "GROUP_BOOMERANG",
"toolType": "BOOMERANG",
"projectileId": "boomerang",
"speed": 8.0,
"damage": 7,
"knockBack": 8,
"coldTime": 40,
"durable": 256,
"canThrow": true,
"attachThrowable": true
}
}
================================================
FILE: items/boomerangs/fire_boomerang.json
================================================
{
"fire_boomerang": {
"type": "TOOLS",
"iconTextureData": "fire_boomerang_icon.png",
"group": "GROUP_BOOMERANG",
"toolType": "BOOMERANG",
"projectileId": "fire_boomerang",
"speed": 12.0,
"damage": 5,
"knockBack": 6,
"coldTime": 20,
"durable": 256,
"canThrow": true,
"attachThrowable": true
}
}
================================================
FILE: items/boomerangs/wooden_boomerang.json
================================================
{
"wooden_boomerang": {
"type": "TOOLS",
"iconTextureData": "wooden_boomerang_icon.png",
"group": "GROUP_BOOMERANG",
"toolType": "BOOMERANG",
"projectileId": "wooden_boomerang",
"speed": 8.0,
"damage": 5,
"knockBack": 6,
"coldTime": 40,
"canThrow": true,
"durable": 64,
"attachThrowable": true,
"fuelTime": 40
}
}
================================================
FILE: items/bows/blood_bow.json
================================================
{
"blood_bow": {
"type": "TOOLS",
"iconTextureData": "blood_bow_icon.png",
"textureData": "blood_bow_entity.png",
"group": "GROUP_BOW",
"toolType": "BOW",
"ai": "Bow",
"ammo": "arrow",
"entityWidth": 22,
"entityHeight": 36,
"handX": 12,
"handY": 18,
"firePoints": [[22,18]],
"noConsumeChance": 0.0,
"speed": 14.0,
"deviation": 0.05,
"shootTimes": 1,
"ammoLevel": 3,
"shootProjectileId": "blood_arrow",
"usePosture": 1,
"useSound": "bow",
"coldTime": 50,
"holdType": "NORMAL",
"twoHands": true,
"durable": 512,
"damage": 14,
"knockBack": 5,
"crit": 3
}
}
================================================
FILE: items/bows/blue_shot_bow.json
================================================
{
"blue_shot_bow": {
"type": "TOOLS",
"iconTextureData": "blue_shot_bow.png",
"textureData": "blue_shot_bow.png",
"group": "GROUP_CROSS_BOW",
"toolType": "CROSS_BOW",
"ai": "Gun",
"ammo": "arrow",
"entityWidth": 60,
"entityHeight": 28,
"handX": 10,
"handY": 20,
"firePoints": [[60,12]],
"noConsumeChance": 0.60,
"speed": 12.0,
"deviation": 0.05,
"shootTimes": 3,
"ammoLevel": 6,
"shootProjectileId": "blue_arrow",
"usePosture": 0,
"useSound": "bow",
"coldTime": 30,
"holdType": "FOLLOW_MOUSE",
"twoHands": true,
"backForce": false,
"durable": 1000,
"damage": 13,
"knockBack": 5,
"crit": 3
}
}
================================================
FILE: items/bows/blue_stone_bow.json
================================================
{
"blue_stone_bow": {
"type": "TOOLS",
"iconTextureData": "blue_stone_bow_icon.png",
"textureData": "blue_stone_bow_entity.png",
"group": "GROUP_BOW",
"toolType": "BOW",
"ai": "Bow",
"ammo": "arrow",
"entityWidth": 20,
"entityHeight": 32,
"handX": 11,
"handY": 16,
"firePoints": [[20,16]],
"noConsumeChance": 0.0,
"speed": 16.0,
"deviation": 0.05,
"shootTimes": 1,
"ammoLevel": 0,
"shootProjectileId": "wooden_arrow",
"usePosture": 1,
"useSound": "bow",
"coldTime": 45,
"holdType": "NORMAL",
"twoHands": true,
"durable": 1024,
"damage": 15,
"knockBack": 5,
"crit": 3
}
}
================================================
FILE: items/bows/chast_bow.json
================================================
{
"chast_bow": {
"type": "TOOLS",
"iconTextureData": "chast_bow_icon.png",
"textureData": "chast_bow_entity.png",
"group": "GROUP_BOW",
"toolType": "BOW",
"ai": "Bow",
"ammo": "arrow",
"entityWidth": 20,
"entityHeight": 42,
"handX": 8,
"handY": 24,
"firePoints": [[20,21]],
"noConsumeChance": 0.0,
"speed": 8.0,
"deviation": 0.05,
"shootTimes": 1,
"ammoLevel": 5,
"shootProjectileId": "sword_arrow",
"usePosture": 1,
"useSound": "bow",
"coldTime": 50,
"holdType": "NORMAL",
"twoHands": true,
"durable": 1024,
"damage": 11,
"knockBack": 5,
"crit": 3
}
}
================================================
FILE: items/bows/cross_bow.json
================================================
{
"cross_bow": {
"type": "TOOLS",
"iconTextureData": "cross_bow_icon.png",
"textureData": "cross_bow_entity.png",
"group": "GROUP_CROSS_BOW",
"toolType": "CROSS_BOW",
"ai": "Bow",
"ammo": "arrow",
"entityWidth": 48,
"entityHeight": 18,
"handX": 12,
"handY": 14,
"firePoints": [[48,8]],
"noConsumeChance": 0.0,
"speed": 12.0,
"deviation": 0.06,
"shootTimes": 1,
"ammoLevel": 0,
"shootProjectileId": "wooden_arrow",
"usePosture": 0,
"useSound": "bow",
"coldTime": 32,
"holdType": "FOLLOW_MOUSE",
"twoHands": true,
"backForce": false,
"durable": 1000,
"damage": 14,
"knockBack": 5,
"crit": 3
}
}
================================================
FILE: items/bows/curse_bow.json
================================================
{
"curse_bow": {
"type": "TOOLS",
"iconTextureData": "curse_bow.png",
"textureData": "curse_bow.png",
"group": "GROUP_BOW",
"toolType": "BOW",
"ai": "InfBow",
"entityWidth": 24,
"entityHeight": 36,
"handX": 10,
"handY": 18,
"firePoints": [[24,18]],
"noConsumeChance": 0.0,
"speed": 8.0,
"deviation": 0.05,
"shootTimes": 3,
"shootProjectileId": "cursed_arrow",
"usePosture": 0,
"useSound": "bow",
"coldTime": 30,
"holdType": "FOLLOW_MOUSE",
"twoHands": true,
"backForce": false,
"damage": 8,
"knockBack": 3,
"crit": 3,
"consumeMana": 8
}
}
================================================
FILE: items/bows/ice_bow.json
================================================
{
"ice_bow": {
"type": "TOOLS",
"iconTextureData": "ice_bow_icon.png",
"textureData": "ice_bow_entity.png",
"group": "GROUP_BOW",
"toolType": "BOW",
"ai": "Bow",
"ammo": "arrow",
"entityWidth": 18,
"entityHeight": 36,
"handX": 8,
"handY": 18,
"firePoints": [[18,18]],
"noConsumeChance": 0.0,
"speed": 14.0,
"deviation": 0.05,
"shootTimes": 1,
"ammoLevel": 4,
"shootProjectileId": "ice_arrow",
"usePosture": 1,
"useSound": "bow",
"coldTime": 50,
"holdType": "NORMAL",
"twoHands": true,
"durable": 866,
"damage": 11,
"knockBack": 5,
"crit": 3
}
}
================================================
FILE: items/bows/lighting_bow.json
================================================
{
"lighting_bow": {
"type": "TOOLS",
"iconTextureData": "lighting_bow_icon.png",
"textureData": "lighting_bow_entity.png",
"group": "GROUP_BOW",
"toolType": "BOW",
"ai": "Bow",
"ammo": "arrow",
"entityWidth": 14,
"entityHeight": 40,
"handX": 8,
"handY": 20,
"firePoints": [[14,20]],
"noConsumeChance": 0.0,
"speed": 12.0,
"deviation": 0.05,
"shootTimes": 1,
"ammoLevel": 1,
"shootProjectileId": "lighting_arrow",
"usePosture": 1,
"useSound": "bow",
"coldTime": 55,
"holdType": "NORMAL",
"twoHands": true,
"durable": 368,
"damage": 14,
"knockBack": 5,
"crit": 3
}
}
================================================
FILE: items/bows/shot_bow.json
================================================
{
"shot_bow": {
"type": "TOOLS",
"iconTextureData": "shot_bow_icon.png",
"textureData": "shot_bow_entity.png",
"group": "GROUP_CROSS_BOW",
"toolType": "CROSS_BOW",
"ai": "Bow",
"ammo": "arrow",
"entityWidth": 60,
"entityHeight": 28,
"handX": 14,
"handY": 22,
"firePoints": [[60,12]],
"noConsumeChance": 0.0,
"speed": 12.0,
"deviation": 0.2,
"shootTimes": 3,
"ammoLevel": 0,
"shootProjectileId": "wooden_arrow",
"usePosture": 0,
"useSound": "bow",
"coldTime": 54,
"holdType": "FOLLOW_MOUSE",
"twoHands": true,
"backForce": false,
"durable": 1000,
"damage": 13,
"knockBack": 5,
"crit": 3
}
}
================================================
FILE: items/bows/super_cross_bow.json
================================================
{
"super_cross_bow": {
"type": "TOOLS",
"iconTextureData": "super_cross_bow_icon.png",
"textureData": "super_cross_bow_entity.png",
"group": "GROUP_CROSS_BOW",
"toolType": "CROSS_BOW",
"ai": "Bow",
"ammo": "arrow",
"entityWidth": 48,
"entityHeight": 28,
"handX": 14,
"handY": 24,
"firePoints": [[48,12]],
"noConsumeChance": 0.0,
"speed": 14.0,
"deviation": 0.06,
"shootTimes": 1,
"ammoLevel": 0,
"shootProjectileId": "wooden_arrow",
"usePosture": 0,
"useSound": "bow",
"coldTime": 24,
"holdType": "FOLLOW_MOUSE",
"twoHands": true,
"backForce": false,
"durable": 1000,
"damage": 15,
"knockBack": 5,
"crit": 6
}
}
================================================
FILE: items/bows/super_fire_shot_bow.json
================================================
{
"super_fire_shot_bow": {
"type": "TOOLS",
"iconTextureData": "super_fire_shot_bow.png",
"textureData": "super_fire_shot_bow.png",
"group": "GROUP_CROSS_BOW",
"toolType": "CROSS_BOW",
"ai": "Gun",
"ammo": "arrow",
"entityWidth": 60,
"entityHeight": 28,
"handX": 10,
"handY": 20,
"firePoints": [[60,12]],
"noConsumeChance": 0.0,
"speed": 16.0,
"deviation": 0.05,
"shootTimes": 3,
"ammoLevel": 0,
"shootProjectileId": "fire_arrow",
"usePosture": 0,
"useSound": "bow",
"coldTime": 40,
"holdType": "FOLLOW_MOUSE",
"twoHands": true,
"backForce": false,
"durable": 1000,
"damage": 13,
"knockBack": 5,
"crit": 3
}
}
================================================
FILE: items/bows/super_spike_shot_bow.json
================================================
{
"super_spike_shot_bow": {
"type": "TOOLS",
"iconTextureData": "super_spike_shot_bow.png",
"textureData": "super_spike_shot_bow.png",
"group": "GROUP_CROSS_BOW",
"toolType": "CROSS_BOW",
"ai": "Gun",
"ammo": "arrow",
"entityWidth": 60,
"entityHeight": 28,
"handX": 10,
"handY": 20,
"firePoints": [[60,12]],
"noConsumeChance": 0.0,
"speed": 16.0,
"deviation": 0.05,
"shootTimes": 3,
"ammoLevel": 0,
"shootProjectileId": "spike",
"usePosture": 0,
"useSound": "bow",
"coldTime": 40,
"holdType": "FOLLOW_MOUSE",
"twoHands": true,
"backForce": false,
"durable": 1000,
"damage": 13,
"knockBack": 5,
"crit": 3
}
}
================================================
FILE: items/bows/wooden_bow.json
================================================
{
"wooden_bow": {
"type": "TOOLS",
"iconTextureData": "wooden_bow_icon.png",
"textureData": "wooden_bow_entity.png",
"group": "GROUP_BOW",
"toolType": "BOW",
"ai": "Bow",
"ammo": "arrow",
"entityWidth": 16,
"entityHeight": 32,
"handX": 8,
"handY": 15,
"firePoints": [[16,16]],
"noConsumeChance": 0.0,
"speed": 11.0,
"deviation": 0.05,
"shootTimes": 1,
"ammoLevel": 0,
"shootProjectileId": "wooden_arrow",
"usePosture": 1,
"useSound": "bow",
"coldTime": 60,
"holdType": "NORMAL",
"twoHands": true,
"durable": 256,
"damage": 14,
"knockBack": 5,
"crit": 3,
"fuelTime": 60
}
}
================================================
FILE: items/buckets/bucket_empty.json
================================================
{
"bucket_empty": {
"type": "MATERIALS",
"iconTextureData": "bucket_empty_icon.png",
"group": "GROUP_BUCKET"
}
}
================================================
FILE: items/buckets/bucket_lava.json
================================================
{
"bucket_lava": {
"type": "MATERIALS",
"iconTextureData": "bucket_lava_icon.png",
"group": "GROUP_BUCKET",
"liquidId": "lava",
"fuelTime": 4000,
"fuelReturnId": "bucket_empty"
}
}
================================================
FILE: items/buckets/bucket_milk.json
================================================
{
"bucket_milk": {
"type": "MATERIALS",
"iconTextureData": "bucket_milk_icon.png",
"group": "GROUP_BUCKET",
"eatReturnId": "bucket_empty"
}
}
================================================
FILE: items/buckets/bucket_water.json
================================================
{
"bucket_water": {
"type": "MATERIALS",
"iconTextureData": "bucket_water_icon.png",
"group": "GROUP_BUCKET",
"liquidId": "water"
}
}
================================================
FILE: items/bullets/fire_bullet.json
================================================
{
"fire_bullet": {
"type": "PROJECTILES",
"iconTextureData": "fire_bullet_icon.png",
"group": "GROUP_BULLET",
"ammo": "bullet",
"ammoLevel": 0,
"projectileId": "bullet",
"speed": 0.0,
"shootable": true,
"damage": 3,
"knockBack": 1
}
}
================================================
FILE: items/bullets/iron_bullet.json
================================================
{
"iron_bullet": {
"type": "PROJECTILES",
"iconTextureData": "iron_bullet_icon.png",
"group": "GROUP_BULLET",
"ammo": "bullet",
"ammoLevel": 0,
"projectileId": "bullet",
"speed": 0.0,
"shootable": true,
"damage": 6,
"knockBack": 1
}
}
================================================
FILE: items/bullets/silver_bullet.json
================================================
{
"silver_bullet": {
"type": "PROJECTILES",
"iconTextureData": "silver_bullet_icon.png",
"group": "GROUP_BULLET",
"ammo": "bullet",
"ammoLevel": 0,
"projectileId": "bullet",
"speed": 1.0,
"shootable": true,
"damage": 8,
"knockBack": 1
}
}
================================================
FILE: items/dyes/dye_black.json
================================================
{
"dye_black": {
"type": "MATERIALS",
"iconTextureData": "dye_black_icon.png",
"group": "GROUP_DYE"
}
}
================================================
FILE: items/dyes/dye_blue.json
================================================
{
"dye_blue": {
"type": "MATERIALS",
"iconTextureData": "dye_blue_icon.png",
"group": "GROUP_DYE"
}
}
================================================
FILE: items/dyes/dye_brown.json
================================================
{
"dye_brown": {
"type": "MATERIALS",
"iconTextureData": "dye_brown_icon.png",
"group": "GROUP_DYE"
}
}
================================================
FILE: items/dyes/dye_cyan.json
================================================
{
"dye_cyan": {
"type": "MATERIALS",
"iconTextureData": "dye_cyan_icon.png",
"group": "GROUP_DYE"
}
}
================================================
FILE: items/dyes/dye_gray.json
================================================
{
"dye_gray": {
"type": "MATERIALS",
"iconTextureData": "dye_gray_icon.png",
"group": "GROUP_DYE"
}
}
================================================
FILE: items/dyes/dye_green.json
================================================
{
"dye_green": {
"type": "MATERIALS",
"iconTextureData": "dye_green_icon.png",
"group": "GROUP_DYE"
}
}
================================================
FILE: items/dyes/dye_light_blue.json
================================================
{
"dye_light_blue": {
"type": "MATERIALS",
"iconTextureData": "dye_light_blue_icon.png",
"group": "GROUP_DYE"
}
}
================================================
FILE: items/dyes/dye_light_gray.json
================================================
{
"dye_light_gray": {
"type": "MATERIALS",
"iconTextureData": "dye_light_gray_icon.png",
"group": "GROUP_DYE"
}
}
================================================
FILE: items/dyes/dye_lime.json
================================================
{
"dye_lime": {
"type": "MATERIALS",
"iconTextureData": "dye_lime_icon.png",
"group": "GROUP_DYE"
}
}
================================================
FILE: items/dyes/dye_magenta.json
================================================
{
"dye_magenta": {
"type": "MATERIALS",
"iconTextureData": "dye_magenta_icon.png",
"group": "GROUP_DYE"
}
}
================================================
FILE: items/dyes/dye_orange.json
================================================
{
"dye_orange": {
"type": "MATERIALS",
"iconTextureData": "dye_orange_icon.png",
"group": "GROUP_DYE"
}
}
================================================
FILE: items/dyes/dye_pink.json
================================================
{
"dye_pink": {
"type": "MATERIALS",
"iconTextureData": "dye_pink_icon.png",
"group": "GROUP_DYE"
}
}
================================================
FILE: items/dyes/dye_purple.json
================================================
{
"dye_purple": {
"type": "MATERIALS",
"iconTextureData": "dye_purple_icon.png",
"group": "GROUP_DYE"
}
}
================================================
FILE: items/dyes/dye_red.json
================================================
{
"dye_red": {
"type": "MATERIALS",
"iconTextureData": "dye_red_icon.png",
"group": "GROUP_DYE"
}
}
================================================
FILE: items/dyes/dye_white.json
================================================
{
"dye_white": {
"type": "MATERIALS",
"iconTextureData": "dye_white_icon.png",
"group": "GROUP_DYE"
}
}
================================================
FILE: items/dyes/dye_yellow.json
================================================
{
"dye_yellow": {
"type": "MATERIALS",
"iconTextureData": "dye_yellow_icon.png",
"group": "GROUP_DYE"
}
}
================================================
FILE: items/foods/apple.json
================================================
{
"apple": {
"ai": "Food",
"type": "MATERIALS",
"iconTextureData": "apple_icon.png",
"group": "GROUP_FOOD",
"eatable": true,
"useSoundGroup": "eat",
"food": 20,
"foodSaturation": 24
}
}
================================================
FILE: items/foods/baked_potato.json
================================================
{
"baked_potato": {
"ai": "Food",
"type": "MATERIALS",
"iconTextureData": "baked_potato_icon.png",
"group": "GROUP_FOOD",
"eatable": true,
"useSoundGroup": "eat",
"food": 30,
"foodSaturation": 60
}
}
================================================
FILE: items/foods/beetroot.json
================================================
{
"beetroot": {
"ai": "Food",
"type": "MATERIALS",
"iconTextureData": "beetroot_icon.png",
"group": "GROUP_FOOD",
"eatable": true,
"useSoundGroup": "eat",
"food": 10,
"foodSaturation": 12
}
}
================================================
FILE: items/foods/bread.json
================================================
{
"bread": {
"ai": "Food",
"type": "MATERIALS",
"iconTextureData": "bread_icon.png",
"group": "GROUP_FOOD",
"eatable": true,
"useSoundGroup": "eat",
"food": 25,
"foodSaturation": 60
}
}
================================================
FILE: items/foods/cake_piece.json
================================================
{
"cake_piece": {
"ai": "Food",
"type": "MATERIALS",
"iconTextureData": "cake_piece_icon.png",
"group": "GROUP_FOOD",
"eatable": true,
"useSoundGroup": "eat",
"food": 10,
"foodSaturation": 5
}
}
================================================
FILE: items/foods/carrot.json
================================================
{
"carrot": {
"ai": "Food",
"type": "MATERIALS",
"iconTextureData": "carrot_icon.png",
"group": "GROUP_FOOD",
"isSeed": true,
"eatable": true,
"useSoundGroup": "eat",
"food": 15,
"foodSaturation": 36,
"blockId": "carrot"
}
}
================================================
FILE: items/foods/chorus_fruit.json
================================================
{
"chorus_fruit": {
"ai": "Food",
"type": "MATERIALS",
"iconTextureData": "chorus_fruit_icon.png",
"group": "GROUP_FOOD",
"eatable": true,
"useSoundGroup": "eat",
"food": 20,
"foodSaturation": 24
}
}
================================================
FILE: items/foods/cooked_chicken.json
================================================
{
"cooked_chicken": {
"ai": "Food",
"type": "MATERIALS",
"iconTextureData": "cooked_chicken_icon.png",
"group": "GROUP_FOOD",
"eatable": true,
"useSoundGroup": "eat",
"food": 30,
"foodSaturation": 72
}
}
================================================
FILE: items/foods/cooked_cod.json
================================================
{
"cooked_cod": {
"ai": "Food",
"type": "MATERIALS",
"iconTextureData": "cooked_cod_icon.png",
"group": "GROUP_FOOD",
"eatable": true,
"useSoundGroup": "eat",
"food": 25,
"foodSaturation": 60
}
}
================================================
FILE: items/foods/cooked_mutton.json
================================================
{
"cooked_mutton": {
"ai": "Food",
"type": "MATERIALS",
"iconTextureData": "cooked_mutton_icon.png",
"group": "GROUP_FOOD",
"eatable": true,
"useSoundGroup": "eat",
"food": 30,
"foodSaturation": 96
}
}
================================================
FILE: items/foods/cooked_porkchop.json
================================================
{
"cooked_porkchop": {
"ai": "Food",
"type": "MATERIALS",
"iconTextureData": "cooked_porkchop_icon.png",
"group": "GROUP_FOOD",
"eatable": true,
"useSoundGroup": "eat",
"food": 40,
"foodSaturation": 100
}
}
================================================
FILE: items/foods/cooked_rabbit.json
================================================
{
"cooked_rabbit": {
"ai": "Food",
"type": "MATERIALS",
"iconTextureData": "cooked_rabbit_icon.png",
"group": "GROUP_FOOD",
"eatable": true,
"useSoundGroup": "eat",
"food": 25,
"foodSaturation": 60
}
}
================================================
FILE: items/foods/cooked_salmon.json
================================================
{
"cooked_salmon": {
"ai": "Food",
"type": "MATERIALS",
"iconTextureData": "cooked_salmon_icon.png",
"group": "GROUP_FOOD",
"eatable": true,
"useSoundGroup": "eat",
"food": 25,
"foodSaturation": 60
}
}
================================================
FILE: items/foods/cookie.json
================================================
{
"cookie": {
"ai": "Food",
"type": "MATERIALS",
"iconTextureData": "cookie_icon.png",
"group": "GROUP_FOOD",
"eatable": true,
"useSoundGroup": "eat",
"food": 10,
"foodSaturation": 4
}
}
================================================
FILE: items/foods/golden_apple.json
================================================
{
"golden_apple": {
"ai": "Food",
"type": "MATERIALS",
"iconTextureData": "golden_apple_icon.png",
"group": "GROUP_FOOD",
"eatable": true,
"useSoundGroup": "eat",
"food": 20,
"foodSaturation": 96,
"buffs": [
{
"id": "absorption",
"time": 7200
},
{
"id": "regeneration",
"time": 300
}
]
}
}
================================================
FILE: items/foods/golden_carrot.json
================================================
{
"golden_carrot": {
"ai": "Food",
"type": "MATERIALS",
"iconTextureData": "golden_carrot_icon.png",
"group": "GROUP_FOOD",
"eatable": true,
"useSoundGroup": "eat",
"food": 30,
"foodSaturation": 100
}
}
================================================
FILE: items/foods/melon_slice.json
================================================
{
"melon_slice": {
"ai": "Food",
"type": "MATERIALS",
"iconTextureData": "melon_slice_icon.png",
"group": "GROUP_FOOD",
"eatable": true,
"useSoundGroup": "eat",
"food": 10,
"foodSaturation": 12
}
}
================================================
FILE: items/foods/mushroom_stew.json
================================================
{
"mushroom_stew": {
"ai": "Food",
"type": "MATERIALS",
"iconTextureData": "mushroom_stew_icon.png",
"group": "GROUP_FOOD",
"eatable": true,
"useSoundGroup": "eat",
"eatReturnId": "bowl",
"food": 30,
"foodSaturation": 72
}
}
================================================
FILE: items/foods/potato.json
================================================
{
"potato": {
"ai": "Food",
"type": "MATERIALS",
"iconTextureData": "potato_icon.png",
"group": "GROUP_FOOD",
"isSeed": true,
"eatable": true,
"useSoundGroup": "eat",
"food": 10,
"foodSaturation": 6,
"blockId": "potato"
}
}
================================================
FILE: items/foods/pufferfish.json
================================================
{
"pufferfish": {
"ai": "Food",
"type": "MATERIALS",
"iconTextureData": "pufferfish_icon.png",
"group": "GROUP_FOOD",
"eatable": true,
"useSoundGroup": "eat",
"food": 10,
"foodSaturation": 12,
"buffs": [
{
"id": "hunger",
"time": 900
},
{
"id": "poison",
"time": 3600
}
]
}
}
================================================
FILE: items/foods/pumpkin_pie.json
================================================
{
"pumpkin_pie": {
"ai": "Food",
"type": "MATERIALS",
"iconTextureData": "pumpkin_pie_icon.png",
"group": "GROUP_FOOD",
"eatable": true,
"useSoundGroup": "eat",
"food": 40,
"foodSaturation": 48
}
}
================================================
FILE: items/foods/raw_beef.json
================================================
{
"raw_beef": {
"ai": "Food",
"type": "MATERIALS",
"iconTextureData": "raw_beef_icon.png",
"group": "GROUP_FOOD",
"eatable": true,
"useSoundGroup": "eat",
"food": 15,
"foodSaturation": 18
}
}
================================================
FILE: items/foods/raw_chicken.json
================================================
{
"raw_chicken": {
"ai": "Food",
"type": "MATERIALS",
"iconTextureData": "raw_chicken_icon.png",
"group": "GROUP_FOOD",
"eatable": true,
"useSoundGroup": "eat",
"food": 15,
"foodSaturation": 12,
"buffs": [
{
"id": "hunger",
"time": 10
}
]
}
}
================================================
FILE: items/foods/raw_cod.json
================================================
{
"raw_cod": {
"ai": "Food",
"type": "MATERIALS",
"iconTextureData": "raw_cod_icon.png",
"group": "GROUP_FOOD",
"eatable": true,
"useSoundGroup": "eat",
"food": 10,
"foodSaturation": 4
}
}
================================================
FILE: items/foods/raw_mutton.json
================================================
{
"raw_mutton": {
"ai": "Food",
"type": "MATERIALS",
"iconTextureData": "raw_mutton_icon.png",
"group": "GROUP_FOOD",
"eatable": true,
"useSoundGroup": "eat",
"food": 10,
"foodSaturation": 12
}
}
================================================
FILE: items/foods/raw_porkchop.json
================================================
{
"raw_porkchop": {
"ai": "Food",
"type": "MATERIALS",
"iconTextureData": "raw_porkchop_icon.png",
"group": "GROUP_FOOD",
"eatable": true,
"useSoundGroup": "eat",
"food": 15,
"foodSaturation": 18
}
}
================================================
FILE: items/foods/raw_rabbit.json
================================================
{
"raw_rabbit": {
"ai": "Food",
"type": "MATERIALS",
"iconTextureData": "raw_rabbit_icon.png",
"group": "GROUP_FOOD",
"eatable": true,
"useSoundGroup": "eat",
"food": 10,
"foodSaturation": 18
}
}
================================================
FILE: items/foods/raw_salmon.json
================================================
{
"raw_salmon": {
"ai": "Food",
"type": "MATERIALS",
"iconTextureData": "raw_salmon_icon.png",
"group": "GROUP_FOOD",
"eatable": true,
"useSoundGroup": "eat",
"food": 10,
"foodSaturation": 4
}
}
================================================
FILE: items/foods/steak.json
================================================
{
"steak": {
"ai": "Food",
"type": "MATERIALS",
"iconTextureData": "steak_icon.png",
"group": "GROUP_FOOD",
"eatable": true,
"useSoundGroup": "eat",
"food": 40,
"foodSaturation": 100
}
}
================================================
FILE: items/guns/fire_gun.json
================================================
{
"fire_gun": {
"type": "TOOLS",
"iconTextureData": "fire_gun_entity.png",
"textureData": "fire_gun_entity.png",
"group": "GROUP_GUN",
"toolType": "GUN",
"ai": "fire_gun",
"entityWidth": 40,
"entityHeight": 22,
"handX": 14,
"handY": 14,
"firePoints": [[40,5]],
"noConsumeChance": 0.0,
"speed": 10.0,
"deviation": 0.15,
"shootTimes": 1,
"special": 2,
"shootProjectileId": "gun_fire",
"usePosture": 0,
"coldTime": 2,
"holdType": "FOLLOW_MOUSE",
"twoHands": true,
"backForce": true,
"durable": 2020,
"damage": 2,
"knockBack": 0,
"crit": 3,
"noEnchanted": true
}
}
================================================
FILE: items/guns/fire_shooter.json
================================================
{
"fire_shooter": {
"type": "TOOLS",
"iconTextureData": "fire_shooter.png",
"textureData": "fire_shooter.png",
"group": "GROUP_GUN",
"toolType": "GUN",
"ai": "Gun",
"entityWidth": 50,
"entityHeight": 22,
"handX": 12,
"handY": 18,
"firePoints": [[50,6]],
"noConsumeChance": 0.0,
"speed": 12.0,
"deviation": 0.05,
"shootTimes": 1,
"special": 2,
"shootProjectileId": "super_fire",
"usePosture": 0,
"coldTime": 1,
"holdType": "FOLLOW_MOUSE",
"twoHands": true,
"backForce": true,
"durable": 2020,
"damage": 2,
"knockBack": 0,
"crit": 3,
"noEnchanted": true
}
}
================================================
FILE: items/guns/handgun.json
================================================
{
"handgun": {
"type": "TOOLS",
"iconTextureData": "handgun_entity.png",
"textureData": "handgun_entity.png",
"group": "GROUP_GUN",
"toolType": "GUN",
"ai": "Gun",
"ammo": "bullet",
"entityWidth": 36,
"entityHeight": 20,
"handX": 13,
"handY": 14,
"firePoints": [[35,4]],
"noConsumeChance": 0.0,
"speed": 20.0,
"deviation": 0.02,
"shootTimes": 1,
"ammoLevel": 0,
"special": 1,
"shootProjectileId": "bullet",
"usePosture": 0,
"useSound": "pistol_fire",
"coldTime": 30,
"holdType": "FOLLOW_MOUSE",
"twoHands": true,
"backForce": true,
"durable": 512,
"damage": 6,
"knockBack": 1,
"crit": 3,
"noEnchanted": true
}
}
================================================
FILE: items/guns/rifle.json
================================================
{
"rifle": {
"type": "TOOLS",
"iconTextureData": "rifle_entity.png",
"textureData": "rifle_entity.png",
"group": "GROUP_GUN",
"toolType": "GUN",
"ai": "Gun",
"ammo": "bullet",
"entityWidth": 56,
"entityHeight": 22,
"handX": 22,
"handY": 14,
"firePoints": [[55,8]],
"noConsumeChance": 0.43,
"speed": 22.0,
"deviation": 0.03,
"shootTimes": 1,
"ammoLevel": 0,
"special": 1,
"shootProjectileId": "bullet",
"usePosture": 0,
"useSound": "chain_gun_fire",
"coldTime": 8,
"holdType": "FOLLOW_MOUSE",
"twoHands": true,
"backForce": true,
"durable": 2048,
"damage": 5,
"knockBack": 1,
"crit": 3,
"noEnchanted": true
}
}
================================================
FILE: items/guns/rocket_launcher.json
================================================
{
"rocket_launcher": {
"type": "TOOLS",
"iconTextureData": "rocket_launcher_entity.png",
"textureData": "rocket_launcher_entity.png",
"group": "GROUP_GUN",
"toolType": "GUN",
"ai": "rocket_launcher",
"ammo": "rocket",
"entityWidth": 50,
"entityHeight": 28,
"handX": 24,
"handY": 22,
"firePoints": [[50,12]],
"noConsumeChance": 0.0,
"speed": 8.0,
"deviation": 0.05,
"shootTimes": 1,
"ammoLevel": 0,
"special": 1,
"shootProjectileId": "rocket",
"usePosture": 0,
"useSound": "launch",
"coldTime": 40,
"holdType": "FOLLOW_MOUSE",
"twoHands": true,
"backForce": true,
"durable": 256,
"damage": 5,
"knockBack": 3,
"crit": 4,
"noEnchanted": true
}
}
================================================
FILE: items/guns/shotgun.json
================================================
{
"shotgun": {
"type": "TOOLS",
"iconTextureData": "shotgun_entity.png",
"textureData": "shotgun_entity.png",
"group": "GROUP_GUN",
"toolType": "GUN",
"ai": "Gun",
"ammo": "bullet",
"entityWidth": 50,
"entityHeight": 22,
"handX": 16,
"handY": 14,
"firePoints": [[48,3]],
"noConsumeChance": 0.0,
"speed": 24.0,
"deviation": 0.09,
"shootTimes": 3,
"ammoLevel": 0,
"special": 1,
"shootProjectileId": "bullet",
"usePosture": 0,
"useSound": "shotgun_fire",
"coldTime": 32,
"holdType": "FOLLOW_MOUSE",
"twoHands": true,
"backForce": true,
"durable": 1024,
"damage": 8,
"knockBack": 1,
"crit": 3,
"noEnchanted": true
}
}
================================================
FILE: items/guns/sniper.json
================================================
{
"sniper": {
"type": "TOOLS",
"iconTextureData": "sniper.png",
"textureData": "sniper.png",
"group": "GROUP_GUN",
"toolType": "GUN",
"ai": "Gun",
"entityWidth": 56,
"entityHeight": 22,
"handX": 28,
"handY": 15,
"firePoints": [[56,8]],
"noConsumeChance": 0.7,
"speed": 22.0,
"deviation": 0.085,
"shootTimes": 1,
"special": 2,
"shootProjectileId": "bullet_super",
"usePosture": 0,
"coldTime": 64,
"holdType": "FOLLOW_MOUSE",
"twoHands": true,
"backForce": true,
"durable": 2020,
"damage": 20,
"knockBack": 0,
"crit": 3,
"noEnchanted": true,
"ammo": "bullet",
"ammoLevel": 0,
"useSound": "shotgun_fire"
}
}
================================================
FILE: items/hoes/stone_hoe.json
================================================
{
"stone_hoe": {
"type": "TOOLS",
"iconTextureData": "stone_hoe_icon.png",
"textureData": "stone_hoe_entity.png",
"group": "GROUP_HOE",
"toolType": "HOE",
"toolGrade": "STONE",
"efficiency": 2.0,
"coldTime": 16,
"entityWidth": 26,
"entityHeight": 36,
"handX": 13,
"handY": 26,
"holdType": "NORMAL",
"durable": 256,
"oreDictionary": [ "OD_HOE" ]
}
}
================================================
FILE: items/hoes/wooden_hoe.json
================================================
{
"wooden_hoe": {
"type": "TOOLS",
"iconTextureData": "wooden_hoe_icon.png",
"textureData": "wooden_hoe_entity.png",
"group": "GROUP_HOE",
"toolType": "HOE",
"toolGrade": "STONE",
"efficiency": 2.0,
"coldTime": 16,
"entityWidth": 26,
"entityHeight": 36,
"handX": 13,
"handY": 26,
"holdType": "NORMAL",
"durable": 128,
"oreDictionary": [ "OD_HOE" ]
}
}
================================================
FILE: items/ingots/aluminum_ingot.json
================================================
{
"aluminum_ingot": {
"ai": "Ingot",
"type": "MATERIALS",
"iconTextureData": "ingot_icon.png",
"iconColor": [ 255, 100, 160, 190 ],
"iconColor2": [ 0, 255, 255, 255 ],
"group": "GROUP_INGOT"
}
}
================================================
FILE: items/ingots/antimony_ingot.json
================================================
{
"antimony_ingot": {
"ai": "Ingot",
"type": "MATERIALS",
"iconTextureData": "ingot_icon.png",
"iconColor": [ 255, 190, 190, 200 ],
"iconColor2": [ 255, 240, 240, 255 ],
"group": "GROUP_INGOT"
}
}
================================================
FILE: items/ingots/beryllium_ingot.json
================================================
{
"beryllium_ingot": {
"ai": "Ingot",
"type": "MATERIALS",
"iconTextureData": "ingot_icon.png",
"iconColor": [ 255, 100, 180, 100 ],
"iconColor2": [ 0, 255, 255, 255 ],
"group": "GROUP_INGOT"
}
}
================================================
FILE: items/ingots/bismuth_ingot.json
================================================
{
"bismuth_ingot": {
"ai": "Ingot",
"type": "MATERIALS",
"iconTextureData": "ingot_icon.png",
"iconColor": [ 255, 80, 140, 140 ],
"iconColor2": [ 0, 255, 255, 255 ],
"group": "GROUP_INGOT"
}
}
================================================
FILE: items/ingots/bronze_ingot.json
================================================
{
"bronze_ingot": {
"ai": "Ingot",
"type": "MATERIALS",
"iconTextureData": "ingot_icon.png",
"iconColor": [ 255, 255, 128, 0 ],
"group": "GROUP_INGOT",
"iconColor2": [ 255, 255, 166, 80 ]
}
}
================================================
FILE: items/ingots/chromium_ingot.json
================================================
{
"chromium_ingot": {
"ai": "Ingot",
"type": "MATERIALS",
"iconTextureData": "ingot_icon.png",
"iconColor": [ 255, 220, 200, 200 ],
"iconColor2": [ 0, 255, 255, 255 ],
"group": "GROUP_INGOT"
}
}
================================================
FILE: items/ingots/cobalt_ingot.json
================================================
{
"cobalt_ingot": {
"ai": "Ingot",
"type": "MATERIALS",
"iconTextureData": "ingot_icon.png",
"iconColor": [ 255, 80, 80, 255 ],
"iconColor2": [ 0, 255, 255, 255 ],
"group": "GROUP_INGOT"
}
}
================================================
FILE: items/ingots/copper_ingot.json
================================================
{
"copper_ingot": {
"ai": "Ingot",
"type": "MATERIALS",
"iconTextureData": "ingot_icon.png",
"iconColor": [ 255, 226, 89, 0 ],
"group": "GROUP_INGOT",
"iconColor2": [ 255, 255, 210, 180 ]
}
}
================================================
FILE: items/ingots/gallium_ingot.json
================================================
{
"gallium_ingot": {
"ai": "Ingot",
"type": "MATERIALS",
"iconTextureData": "ingot_icon.png",
"iconColor": [ 255, 195, 195, 223 ],
"group": "GROUP_INGOT",
"iconColor2": [ 255, 240, 240, 255 ]
}
}
================================================
FILE: items/ingots/gold_ingot.json
================================================
{
"gold_ingot": {
"ai": "Ingot",
"type": "MATERIALS",
"iconTextureData": "ingot_icon.png",
"iconColor": [ 255, 255, 255, 0 ],
"iconColor2": [ 0, 255, 255, 255 ],
"group": "GROUP_INGOT"
}
}
================================================
FILE: items/ingots/indium_ingot.json
================================================
{
"indium_ingot": {
"ai": "Ingot",
"type": "MATERIALS",
"iconTextureData": "ingot_icon.png",
"iconColor": [ 255, 100, 0, 200 ],
"iconColor2": [ 0, 255, 255, 255 ],
"group": "GROUP_INGOT"
}
}
================================================
FILE: items/ingots/iridium_ingot.json
================================================
{
"iridium_ingot": {
"ai": "Ingot",
"type": "MATERIALS",
"iconTextureData": "ingot_icon.png",
"iconColor": [ 255, 180, 180, 191 ],
"iconColor2": [ 0, 255, 255, 255 ],
"group": "GROUP_INGOT"
}
}
================================================
FILE: items/ingots/iron_ingot.json
================================================
{
"iron_ingot": {
"ai": "Ingot",
"type": "MATERIALS",
"iconTextureData": "ingot_icon.png",
"iconColor": [ 255, 255, 255, 255 ],
"iconColor2": [ 0, 255, 255, 255 ],
"group": "GROUP_INGOT",
"oreDictionary": [ "OD_IRON_INGOT" ]
}
}
================================================
FILE: items/ingots/lead_ingot.json
================================================
{
"lead_ingot": {
"ai": "Ingot",
"type": "MATERIALS",
"iconTextureData": "ingot_icon.png",
"iconColor": [ 255, 110, 80, 110 ],
"iconColor2": [ 0, 255, 255, 255 ],
"group": "GROUP_INGOT"
}
}
================================================
FILE: items/ingots/lithium_ingot.json
================================================
{
"lithium_ingot": {
"ai": "Ingot",
"type": "MATERIALS",
"iconTextureData": "ingot_icon.png",
"iconColor": [ 255, 180, 180, 200 ],
"iconColor2": [ 0, 255, 255, 255 ],
"group": "GROUP_INGOT"
}
}
================================================
FILE: items/ingots/magnesium_ingot.json
================================================
{
"magnesium_ingot": {
"ai": "Ingot",
"type": "MATERIALS",
"iconTextureData": "ingot_icon.png",
"iconColor": [ 255, 255, 200, 200 ],
"iconColor2": [ 0, 255, 255, 255 ],
"group": "GROUP_INGOT"
}
}
================================================
FILE: items/ingots/manganese_ingot.json
================================================
{
"manganese_ingot": {
"ai": "Ingot",
"type": "MATERIALS",
"iconTextureData": "ingot_icon.png",
"iconColor": [ 255, 200, 200, 200 ],
"iconColor2": [ 0, 255, 255, 255 ],
"group": "GROUP_INGOT"
}
}
================================================
FILE: items/ingots/molybdenum_ingot.json
================================================
{
"molybdenum_ingot": {
"ai": "Ingot",
"type": "MATERIALS",
"iconTextureData": "ingot_icon.png",
"iconColor": [ 255, 160, 160, 200 ],
"group": "GROUP_INGOT",
"iconColor2": [ 255, 255, 255, 255 ]
}
}
================================================
FILE: items/ingots/netherite_ingot.json
================================================
{
"netherite_ingot": {
"ai": "Ingot",
"type": "MATERIALS",
"iconTextureData": "ingot_icon.png",
"iconColor": [ 255, 90, 87, 90 ],
"iconColor2": [ 0, 255, 255, 255 ],
"group": "GROUP_INGOT",
"antiLava": true
}
}
================================================
FILE: items/ingots/nickel_ingot.json
================================================
{
"nickel_ingot": {
"ai": "Ingot",
"type": "MATERIALS",
"iconTextureData": "ingot_icon.png",
"iconColor": [ 255, 200, 200, 255 ],
"iconColor2": [ 0, 255, 255, 255 ],
"group": "GROUP_INGOT"
}
}
================================================
FILE: items/ingots/niobium_ingot.json
================================================
{
"niobium_ingot": {
"ai": "Ingot",
"type": "MATERIALS",
"iconTextureData": "ingot_icon.png",
"iconColor": [ 255, 160, 150, 170 ],
"iconColor2": [ 0, 255, 255, 255 ],
"group": "GROUP_INGOT"
}
}
================================================
FILE: items/ingots/osmium_ingot.json
================================================
{
"osmium_ingot": {
"ai": "Ingot",
"type": "MATERIALS",
"iconTextureData": "ingot_icon.png",
"iconColor": [ 255, 40, 40, 222 ],
"iconColor2": [ 0, 255, 255, 255 ],
"group": "GROUP_INGOT"
}
}
================================================
FILE: items/ingots/palladium_ingot.json
================================================
{
"palladium_ingot": {
"ai": "Ingot",
"type": "MATERIALS",
"iconTextureData": "ingot_icon.png",
"iconColor": [ 255, 110, 110, 110 ],
"group": "GROUP_INGOT",
"iconColor2": [ 255, 222, 222, 222 ]
}
}
================================================
FILE: items/ingots/platinum_ingot.json
================================================
{
"platinum_ingot": {
"ai": "Ingot",
"type": "MATERIALS",
"iconTextureData": "ingot_icon.png",
"iconColor": [ 255, 222, 222, 160 ],
"group": "GROUP_INGOT",
"iconColor2": [ 255, 255, 255, 240 ]
}
}
================================================
FILE: items/ingots/redstone_ingot.json
================================================
{
"redstone_ingot": {
"ai": "Ingot",
"type": "MATERIALS",
"iconTextureData": "ingot_icon.png",
"iconColor": [ 255, 255, 120, 120 ],
"iconColor2": [ 0, 255, 255, 255 ],
"group": "GROUP_INGOT"
}
}
================================================
FILE: items/ingots/rhenium_ingot.json
================================================
{
"rhenium_ingot": {
"ai": "Ingot",
"type": "MATERIALS",
"iconTextureData": "ingot_icon.png",
"iconColor": [ 255, 66, 66, 66 ],
"iconColor2": [ 0, 255, 255, 255 ],
"group": "GROUP_INGOT"
}
}
================================================
FILE: items/ingots/silver_ingot.json
================================================
{
"silver_ingot": {
"ai": "Ingot",
"type": "MATERIALS",
"iconTextureData": "ingot_icon.png",
"iconColor": [ 255, 240, 240, 255 ],
"iconColor2": [ 0, 255, 255, 255 ],
"group": "GROUP_INGOT"
}
}
================================================
FILE: items/ingots/sodium_ingot.json
================================================
{
"sodium_ingot": {
"ai": "Ingot",
"type": "MATERIALS",
"iconTextureData": "ingot_icon.png",
"iconColor": [ 255, 66, 66, 255 ],
"iconColor2": [ 0, 255, 255, 255 ],
"group": "GROUP_INGOT"
}
}
================================================
FILE: items/ingots/steel_ingot.json
================================================
{
"steel_ingot": {
"ai": "Ingot",
"type": "MATERIALS",
"iconTextureData": "ingot_icon.png",
"iconColor": [ 255, 128, 128, 128 ],
"iconColor2": [ 0, 255, 255, 255 ],
"group": "GROUP_INGOT"
}
}
================================================
FILE: items/ingots/tantalum_ingot.json
================================================
{
"tantalum_ingot": {
"ai": "Ingot",
"type": "MATERIALS",
"iconTextureData": "ingot_icon.png",
"iconColor": [ 255, 210, 210, 210 ],
"group": "GROUP_INGOT",
"iconColor2": [ 255, 255, 255, 255 ]
}
}
================================================
FILE: items/ingots/tin_ingot.json
================================================
{
"tin_ingot": {
"ai": "Ingot",
"type": "MATERIALS",
"iconTextureData": "ingot_icon.png",
"iconColor": [ 255, 172, 172, 172 ],
"iconColor2": [ 0, 255, 255, 255 ],
"group": "GROUP_INGOT"
}
}
================================================
FILE: items/ingots/titanium_ingot.json
================================================
{
"titanium_ingot": {
"ai": "Ingot",
"type": "MATERIALS",
"iconTextureData": "ingot_icon.png",
"iconColor": [ 255, 220, 160, 240 ],
"iconColor2": [ 0, 255, 255, 255 ],
"group": "GROUP_INGOT"
}
}
================================================
FILE: items/ingots/vanadium_ingot.json
================================================
{
"vanadium_ingot": {
"ai": "Ingot",
"type": "MATERIALS",
"iconTextureData": "ingot_icon.png",
"iconColor": [ 255, 50, 50, 50 ],
"iconColor2": [ 0, 255, 255, 255 ],
"group": "GROUP_INGOT"
}
}
================================================
FILE: items/ingots/vibranium_ingot.json
================================================
{
"vibranium_ingot": {
"ai": "Ingot",
"type": "MATERIALS",
"iconTextureData": "ingot_icon.png",
"iconColor": [ 255, 200, 210, 220 ],
"group": "GROUP_INGOT",
"iconColor2": [ 255, 255, 255, 255 ]
}
}
================================================
FILE: items/ingots/wolfram_ingot.json
================================================
{
"wolfram_ingot": {
"ai": "Ingot",
"type": "MATERIALS",
"iconTextureData": "ingot_icon.png",
"iconColor": [ 255, 48, 48, 48 ],
"iconColor2": [ 0, 255, 255, 255 ],
"group": "GROUP_INGOT"
}
}
================================================
FILE: items/ingots/yttrium_ingot.json
================================================
{
"yttrium_ingot": {
"ai": "Ingot",
"type": "MATERIALS",
"iconTextureData": "ingot_icon.png",
"iconColor": [ 255, 180, 220, 180 ],
"iconColor2": [ 0, 255, 255, 255 ],
"group": "GROUP_INGOT"
}
}
================================================
FILE: items/ingots/zinc_ingot.json
================================================
{
"zinc_ingot": {
"ai": "Ingot",
"type": "MATERIALS",
"iconTextureData": "ingot_icon.png",
"iconColor": [ 255, 250, 250, 240 ],
"iconColor2": [ 0, 255, 255, 255 ],
"group": "GROUP_INGOT"
}
}
================================================
FILE: items/loots/guardian.json
================================================
{
"guardian": {
"type": "MATERIALS",
"iconTextureData": "guardian_icon.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/loots/nether_destroyer_loot.json
================================================
{
"nether_destroyer_loot": {
"type": "MATERIALS",
"iconTextureData": "nether_destroyer_loot_icon.png",
"group": "GROUP_LOOT",
"antiLava": true
}
}
================================================
FILE: items/loots/snow_queen_loot.json
================================================
{
"snow_queen_loot": {
"type": "MATERIALS",
"iconTextureData": "snow_queen_loot_icon.png",
"group": "GROUP_LOOT",
"antiLava": true
}
}
================================================
FILE: items/magic/bone_gun.json
================================================
{
"bone_gun": {
"type": "TOOLS",
"iconTextureData": "bone_gun.png",
"textureData": "bone_gun.png",
"group": "GROUP_STAFF",
"oreDictionary": [ "OD_STAFF" ],
"toolType": "BOW",
"ai": "InfBow",
"entityWidth": 56,
"entityHeight": 28,
"handX": 10,
"handY": 24,
"firePoints": [[56,14]],
"noConsumeChance": 0.0,
"speed": 8.0,
"deviation": 0.05,
"shootProjectileId": "bone",
"usePosture": 0,
"useSound": "bow",
"coldTime": 40,
"holdType": "FOLLOW_MOUSE",
"twoHands": true,
"backForce": false,
"damage": 14,
"knockBack": 3,
"crit": 3,
"consumeMana": 17
}
}
================================================
FILE: items/magic/dark_staff.json
================================================
{
"dark_staff": {
"type": "TOOLS",
"iconTextureData": "dark_staff.png",
"textureData": "dark_staff.png",
"group": "GROUP_STAFF",
"oreDictionary": [ "OD_STAFF" ],
"toolType": "STAFF",
"ai": "Staff",
"speed": 6.0,
"deviation": 0.00,
"shootTimes": 1,
"shootProjectileId": "black_hole",
"usePosture": 1,
"coldTime": 128,
"entityWidth": 16,
"entityHeight": 48,
"handX": 8,
"handY": 32,
"firePoints": [[4,4]],
"holdType": "HOLD_STAFF",
"twoHands": false,
"damage": 3,
"knockBack": 1,
"crit": 3,
"consumeMana": 17,
"useSound": "fireball"
}
}
================================================
FILE: items/magic/fire_book.json
================================================
{
"fire_book": {
"type": "TOOLS",
"iconTextureData": "fire_book.png",
"textureData": "fire_book.png",
"group": "GROUP_GUN",
"toolType": "GUN",
"ai": "InfBow",
"entityWidth": 32,
"entityHeight": 32,
"handX": 8,
"handY": 16,
"firePoints": [[32,16]],
"noConsumeChance": 0.0,
"speed": 8.0,
"deviation": 0.05,
"shootTimes": 1,
"special": 2,
"shootProjectileId": "fire_element",
"usePosture": 0,
"coldTime": 24,
"holdType": "FOLLOW_MOUSE",
"twoHands": false,
"backForce": true,
"damage": 12,
"knockBack": 0,
"crit": 3,
"noEnchanted": true,
"useSound": "fireball",
"consumeMana": 8
}
}
================================================
FILE: items/magic/mini_laser_gun.json
================================================
{
"mini_laser_gun": {
"type": "TOOLS",
"iconTextureData": "mini_laser_gun.png",
"textureData": "mini_laser_gun.png",
"group": "GROUP_GUN",
"toolType": "GUN",
"ai": "InfBow",
"entityWidth": 38,
"entityHeight": 22,
"handX": 5,
"handY": 15,
"firePoints": [[32,8]],
"noConsumeChance": 0.0,
"speed": 24.0,
"deviation": 0.085,
"shootTimes": 1,
"special": 2,
"shootProjectileId": "light_bullet_laser",
"usePosture": 0,
"coldTime": 12,
"holdType": "FOLLOW_MOUSE",
"twoHands": true,
"backForce": true,
"damage": 14,
"knockBack": 0,
"crit": 3,
"noEnchanted": true,
"consumeMana": 18,
"useSound": "sys3"
}
}
================================================
FILE: items/magic/mini_rocket_launcher.json
================================================
{
"mini_rocket_launcher": {
"type": "TOOLS",
"iconTextureData": "mini_rocket_launcher.png",
"textureData": "mini_rocket_launcher.png",
"group": "GROUP_GUN",
"toolType": "GUN",
"ai": "InfBow",
"entityWidth": 56,
"entityHeight": 28,
"handX": 30,
"handY": 24,
"firePoints": [[56,14]],
"noConsumeChance": 0.0,
"speed": 8.0,
"deviation": 0.085,
"shootTimes": 3,
"special": 2,
"shootProjectileId": "mini_rocket",
"usePosture": 0,
"coldTime": 64,
"holdType": "FOLLOW_MOUSE",
"twoHands": true,
"backForce": true,
"durable": 2020,
"damage": 12,
"knockBack": 0,
"crit": 3,
"noEnchanted": true,
"useSound": "launch",
"consumeMana": 18
}
}
================================================
FILE: items/magic/soul_laserer.json
================================================
{
"soul_laserer": {
"type": "TOOLS",
"iconTextureData": "soul_laserer.png",
"textureData": "soul_laserer.png",
"group": "GROUP_GUN",
"toolType": "GUN",
"ai": "InfBow",
"entityWidth": 56,
"entityHeight": 22,
"handX": 5,
"handY": 15,
"firePoints": [[56,8]],
"noConsumeChance": 0.0,
"speed": 16.0,
"deviation": 0.085,
"shootTimes": 1,
"special": 2,
"shootProjectileId": "magic_wave3",
"usePosture": 0,
"coldTime": 42,
"holdType": "FOLLOW_MOUSE",
"twoHands": true,
"backForce": true,
"damage": 24,
"knockBack": 0,
"crit": 3,
"noEnchanted": true,
"consumeMana": 20,
"useSound": "cannon"
}
}
================================================
FILE: items/magic/super_shark.json
================================================
{
"super_shark": {
"type": "TOOLS",
"iconTextureData": "super_shark.png",
"textureData": "super_shark.png",
"group": "GROUP_GUN",
"toolType": "GUN",
"ai": "InfBow",
"entityWidth": 56,
"entityHeight": 22,
"handX": 15,
"handY": 15,
"firePoints": [[56,8]],
"noConsumeChance": 0.0,
"speed": 6.0,
"deviation": 0.085,
"shootTimes": 1,
"special": 2,
"shootProjectileId": "lighting_bullet_red_invert2",
"usePosture": 0,
"coldTime": 32,
"holdType": "FOLLOW_MOUSE",
"twoHands": true,
"backForce": true,
"damage": 14,
"knockBack": 0,
"crit": 3,
"noEnchanted": true,
"useSound": "fireball",
"consumeMana": 10
}
}
================================================
FILE: items/magic/super_shark_ghost.json
================================================
{
"super_shark_ghost": {
"type": "TOOLS",
"iconTextureData": "super_shark.png",
"textureData": "super_shark.png",
"group": "GROUP_GUN",
"toolType": "GUN",
"ai": "Gun",
"entityWidth": 56,
"entityHeight": 22,
"handX": 15,
"handY": 15,
"firePoints": [[56,8]],
"noConsumeChance": 0.0,
"speed": 2.0,
"deviation": 0.085,
"shootTimes": 1,
"special": 2,
"shootProjectileId": "lighting_bullet_red_invert2",
"usePosture": 0,
"coldTime": 12,
"holdType": "FOLLOW_MOUSE",
"twoHands": true,
"backForce": true,
"damage": 8,
"knockBack": 0,
"crit": 3,
"noEnchanted": true,
"useSound": "sys3"
}
}
================================================
FILE: items/magic/sword_fish.json
================================================
{
"sword_fish": {
"type": "TOOLS",
"iconTextureData": "sword_fish.png",
"textureData": "sword_fish.png",
"group": "GROUP_GUN",
"toolType": "GUN",
"ai": "InfBow",
"entityWidth": 64,
"entityHeight": 26,
"handX": 5,
"handY": 15,
"firePoints": [[32,8]],
"noConsumeChance": 0.0,
"speed": 24.0,
"deviation": 0.085,
"shootTimes": 1,
"special": 2,
"shootProjectileId": "light_bullet_laser",
"usePosture": 0,
"coldTime": 12,
"holdType": "FOLLOW_MOUSE",
"twoHands": true,
"backForce": true,
"damage": 7,
"knockBack": 0,
"crit": 3,
"noEnchanted": true,
"useSound": "sys3",
"consumeMana": 4
}
}
================================================
FILE: items/magic/sword_fish_gun.json
================================================
{
"sword_fish_gun": {
"type": "TOOLS",
"iconTextureData": "sword_fish_gun.png",
"textureData": "sword_fish_gun.png",
"group": "GROUP_GUN",
"toolType": "GUN",
"ai": "InfBow",
"entityWidth": 56,
"entityHeight": 22,
"handX": 25,
"handY": 15,
"firePoints": [[56,8]],
"noConsumeChance": 0.0,
"speed": 8.0,
"deviation": 0.085,
"shootTimes": 1,
"special": 2,
"shootProjectileId": "air_wave",
"usePosture": 0,
"coldTime": 24,
"holdType": "FOLLOW_MOUSE",
"twoHands": true,
"backForce": true,
"damage": 12,
"knockBack": 0,
"crit": 3,
"noEnchanted": true,
"consumeMana": 6,
"useSound": "sys3"
}
}
================================================
FILE: items/magic/water_book.json
================================================
{
"water_book": {
"type": "TOOLS",
"iconTextureData": "water_book.png",
"textureData": "water_book.png",
"group": "GROUP_GUN",
"toolType": "GUN",
"ai": "InfBow",
"entityWidth": 32,
"entityHeight": 32,
"handX": 8,
"handY": 16,
"firePoints": [[32,16]],
"noConsumeChance": 0.0,
"speed": 8.0,
"deviation": 0.05,
"shootTimes": 1,
"special": 2,
"shootProjectileId": "water_flow",
"usePosture": 0,
"coldTime": 24,
"holdType": "FOLLOW_MOUSE",
"twoHands": true,
"backForce": true,
"damage": 16,
"knockBack": 0,
"crit": 3,
"noEnchanted": true,
"consumeMana": 8
}
}
================================================
FILE: items/misc/blaze_powder.json
================================================
{
"blaze_powder": {
"type": "MATERIALS",
"iconTextureData": "blaze_powder_icon.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc/blaze_rod.json
================================================
{
"blaze_rod": {
"type": "MATERIALS",
"iconTextureData": "blaze_rod_icon.png",
"group": "GROUP_MATERIAL",
"fuelTime": 480
}
}
================================================
FILE: items/misc/bone.json
================================================
{
"bone": {
"type": "MATERIALS",
"iconTextureData": "bone_icon.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc/bone_meal.json
================================================
{
"bone_meal": {
"type": "MATERIALS",
"iconTextureData": "bone_meal_icon.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc/book.json
================================================
{
"book": {
"type": "MATERIALS",
"iconTextureData": "book_icon.png",
"group": "GROUP_MATERIAL",
"fuelTime": 20
}
}
================================================
FILE: items/misc/bowl.json
================================================
{
"bowl": {
"type": "MATERIALS",
"iconTextureData": "bowl_icon.png",
"group": "GROUP_MATERIAL",
"fuelTime": 20
}
}
================================================
FILE: items/misc/charcoal.json
================================================
{
"charcoal": {
"type": "MATERIALS",
"iconTextureData": "charcoal_icon.png",
"group": "GROUP_MATERIAL",
"fuelTime": 160
}
}
================================================
FILE: items/misc/clay.json
================================================
{
"clay": {
"type": "MATERIALS",
"iconTextureData": "clay_icon.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc/coal.json
================================================
{
"coal": {
"type": "MATERIALS",
"iconTextureData": "coal_icon.png",
"group": "GROUP_MATERIAL",
"fuelTime": 320
}
}
================================================
FILE: items/misc/cocoa_bean.json
================================================
{
"cocoa_bean": {
"type": "MATERIALS",
"iconTextureData": "cocoa_bean_icon.png",
"group": "GROUP_SEED"
}
}
================================================
FILE: items/misc/diamond.json
================================================
{
"diamond": {
"type": "MATERIALS",
"iconTextureData": "diamond_icon.png",
"group": "GROUP_DIAMOND"
}
}
================================================
FILE: items/misc/dried_kelp.json
================================================
{
"dried_kelp": {
"ai": "Food",
"type": "MATERIALS",
"iconTextureData": "dried_kelp_icon.png",
"group": "GROUP_FOOD",
"eatable": true,
"useSoundGroup": "eat",
"food": 10,
"foodSaturation": 6
}
}
================================================
FILE: items/misc/egg.json
================================================
{
"egg": {
"type": "MATERIALS",
"iconTextureData": "egg_icon.png",
"group": "GROUP_FOOD"
}
}
================================================
FILE: items/misc/emerald.json
================================================
{
"emerald": {
"type": "MATERIALS",
"iconTextureData": "emerald_icon.png",
"group": "GROUP_EMERALD"
}
}
================================================
FILE: items/misc/enchanted_book.json
================================================
{
"enchanted_book": {
"type": "TOOLS",
"iconTextureData": "enchanted_book_icon.png",
"group": "GROUP_BOOK",
"toolType": "BOOK"
}
}
================================================
FILE: items/misc/ender_eye.json
================================================
{
"ender_eye": {
"type": "MATERIALS",
"iconTextureData": "ender_eye_icon.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc/ender_pearl.json
================================================
{
"ender_pearl": {
"type": "MATERIALS",
"iconTextureData": "ender_pearl_icon.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc/feather.json
================================================
{
"feather": {
"type": "MATERIALS",
"iconTextureData": "feather_icon.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc/fermented_spider_eye.json
================================================
{
"fermented_spider_eye": {
"type": "MATERIALS",
"iconTextureData": "fermented_spider_eye_icon.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc/fire_charge.json
================================================
{
"fire_charge": {
"type": "MATERIALS",
"iconTextureData": "fire_charge_icon.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc/firework_rocket.json
================================================
{
"firework_rocket": {
"type": "MATERIALS",
"iconTextureData": "firework_rocket_icon.png",
"group": "GROUP_MATERIAL",
"onTest": true
}
}
================================================
FILE: items/misc/fishing_rod.json
================================================
{
"fishing_rod": {
"type": "TOOLS",
"iconTextureData": "fishing_rod_icon.png",
"textureData": "fishing_rod_entity.png",
"group": "GROUP_FISHINGROD",
"toolType": "FISHING_ROD",
"ai": "fishing_rod",
"coldTime": 60,
"entityWidth": 38,
"entityHeight": 42,
"handX": 6,
"handY": 30,
"firePoints": [[36,1]],
"holdType": "FOLLOW_MOUSE",
"twoHands": true,
"durable": 256,
"fuelTime": 60,
"onTest": true
}
}
================================================
FILE: items/misc/flint.json
================================================
{
"flint": {
"type": "MATERIALS",
"iconTextureData": "flint_icon.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc/ghast_tear.json
================================================
{
"ghast_tear": {
"type": "MATERIALS",
"iconTextureData": "ghast_tear_icon.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc/glistering_melon_slice.json
================================================
{
"glistering_melon_slice": {
"type": "MATERIALS",
"iconTextureData": "glistering_melon_slice_icon.png",
"group": "GROUP_FOOD"
}
}
================================================
FILE: items/misc/glow_ball.json
================================================
{
"glow_ball": {
"type": "PROJECTILES",
"iconTextureData": "glow_ball_icon.png",
"group": "GROUP_DROPABLE",
"projectileId": "glow_ball",
"speed": 6.0,
"canThrow": true,
"damage": 3,
"knockBack": 2,
"coldTime": 1000,
"shootable": true
}
}
================================================
FILE: items/misc/glowstone_dust.json
================================================
{
"glowstone_dust": {
"type": "MATERIALS",
"iconTextureData": "glowstone_dust_icon.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc/gray_feather.json
================================================
{
"gray_feather": {
"type": "MATERIALS",
"iconTextureData": "gray_feather_icon.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc/gunpowder.json
================================================
{
"gunpowder": {
"type": "MATERIALS",
"iconTextureData": "gunpowder_icon.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc/heart_of_sea.json
================================================
{
"heart_of_sea": {
"type": "MATERIALS",
"iconTextureData": "heart_of_sea_icon.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc/ink_sac.json
================================================
{
"ink_sac": {
"type": "MATERIALS",
"iconTextureData": "ink_sac_icon.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc/kelp.json
================================================
{
"kelp": {
"type": "BLOCKS",
"iconTextureData": "kelp_icon.png",
"group": "GROUP_FOOD",
"blockId": "kelp"
}
}
================================================
FILE: items/misc/lapis_lazuli.json
================================================
{
"lapis_lazuli": {
"type": "MATERIALS",
"iconTextureData": "lapis_lazuli_icon.png",
"group": "GROUP_LAPIS"
}
}
================================================
FILE: items/misc/leather.json
================================================
{
"leather": {
"type": "MATERIALS",
"iconTextureData": "leather_icon.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc/lighter.json
================================================
{
"lighter": {
"type": "TOOLS",
"iconTextureData": "lighter_icon.png",
"textureData": "lighter_entity.png",
"group": "GROUP_LIGHTER",
"toolType": "SWORD",
"ai": "sword",
"coldTime": 22,
"handX": 10,
"handY": 48,
"holdType": "NORMAL",
"durable": 128,
"onTest": true
}
}
================================================
FILE: items/misc/magma_cream.json
================================================
{
"magma_cream": {
"type": "MATERIALS",
"iconTextureData": "magma_cream_icon.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc/mana_piece.json
================================================
{
"mana_piece": {
"ai": "Food",
"type": "MATERIALS",
"iconTextureData": "mana_piece_icon.png",
"group": "GROUP_MANA",
"eatable": true,
"useSoundGroup": "eat",
"addMagic": 10,
"addMaxMagic": 10
}
}
================================================
FILE: items/misc/map_paper.json
================================================
{
"map_paper": {
"type": "TOOLS",
"iconTextureData": "map_icon.png",
"textureData": "map_entity.png",
"group": "GROUP_MAP",
"toolType": "SWORD",
"ai": "sword",
"coldTime": 22,
"handX": 10,
"handY": 48,
"holdType": "NORMAL",
"durable": 128,
"onTest": true
}
}
================================================
FILE: items/misc/nautilus_shell.json
================================================
{
"nautilus_shell": {
"type": "MATERIALS",
"iconTextureData": "nautilus_shell_icon.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc/nether_brick.json
================================================
{
"nether_brick": {
"type": "MATERIALS",
"iconTextureData": "nether_brick_icon.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc/nether_star.json
================================================
{
"nether_star": {
"type": "MATERIALS",
"iconTextureData": "nether_star_icon.png",
"group": "GROUP_MATERIAL",
"onTest": true
}
}
================================================
FILE: items/misc/nether_wart.json
================================================
{
"nether_wart": {
"type": "MATERIALS",
"iconTextureData": "nether_wart_icon.png",
"group": "GROUP_MATERIAL",
"isSeed": true,
"blockId": "nether_wart"
}
}
================================================
FILE: items/misc/netherite_scrap.json
================================================
{
"netherite_scrap": {
"type": "MATERIALS",
"iconTextureData": "netherite_scrap_icon.png",
"group": "GROUP_MATERIAL",
"antiLava": true
}
}
================================================
FILE: items/misc/paper.json
================================================
{
"paper": {
"type": "MATERIALS",
"iconTextureData": "paper_icon.png",
"group": "GROUP_MATERIAL",
"fuelTime": 20
}
}
================================================
FILE: items/misc/phantom_membrane.json
================================================
{
"phantom_membrane": {
"type": "MATERIALS",
"iconTextureData": "phantom_membrane_icon.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc/popped_chorus_fruits.json
================================================
{
"popped_chorus_fruits": {
"type": "MATERIALS",
"iconTextureData": "popped_chorus_fruits_icon.png",
"group": "GROUP_FOOD"
}
}
================================================
FILE: items/misc/prismarine_crystals.json
================================================
{
"prismarine_crystals": {
"type": "MATERIALS",
"iconTextureData": "prismarine_crystals_icon.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc/prismarine_shard.json
================================================
{
"prismarine_shard": {
"type": "MATERIALS",
"iconTextureData": "prismarine_shard_icon.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc/quartz.json
================================================
{
"quartz": {
"type": "MATERIALS",
"iconTextureData": "quartz_icon.png",
"group": "GROUP_QUARTZ"
}
}
================================================
FILE: items/misc/rabbit_foot.json
================================================
{
"rabbit_foot": {
"type": "MATERIALS",
"iconTextureData": "rabbit_foot_icon.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc/rabbit_hide.json
================================================
{
"rabbit_hide": {
"type": "MATERIALS",
"iconTextureData": "rabbit_hide_icon.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc/red_brick.json
================================================
{
"red_brick": {
"type": "MATERIALS",
"iconTextureData": "brick_icon.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc/redstone.json
================================================
{
"redstone": {
"type": "MATERIALS",
"iconTextureData": "redstone_icon.png",
"group": "GROUP_REDSTONE"
}
}
================================================
FILE: items/misc/rocket.json
================================================
{
"rocket": {
"type": "PROJECTILES",
"iconTextureData": "rocket_icon.png",
"group": "GROUP_ROCKET",
"ammo": "rocket",
"ammoLevel": 0,
"projectileId": "rocket",
"speed": 0.0,
"shootable": true,
"damage": 10,
"knockBack": 1
}
}
================================================
FILE: items/misc/rotten_flesh.json
================================================
{
"rotten_flesh": {
"ai": "Food",
"type": "MATERIALS",
"iconTextureData": "rotten_flesh_icon.png",
"group": "GROUP_FOOD",
"eatable": true,
"useSoundGroup": "eat",
"food": 20,
"foodSaturation": 8,
"buffs": [
{
"id": "hunger",
"time": 1440
}
]
}
}
================================================
FILE: items/misc/scute.json
================================================
{
"scute": {
"type": "MATERIALS",
"iconTextureData": "scute_icon.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc/shears.json
================================================
{
"shears": {
"type": "TOOLS",
"iconTextureData": "shears_icon.png",
"textureData": "shears_entity.png",
"group": "GROUP_SHEARS",
"toolType": "SHEARS",
"toolGrade": "STONE",
"efficiency": 2.0,
"coldTime": 20,
"entityWidth": 20,
"entityHeight": 32,
"handX": 10,
"handY": 22,
"holdType": "NORMAL",
"durable": 128
}
}
================================================
FILE: items/misc/shulker_shell.json
================================================
{
"shulker_shell": {
"type": "MATERIALS",
"iconTextureData": "shulker_shell_icon.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc/slimeball.json
================================================
{
"slimeball": {
"type": "MATERIALS",
"iconTextureData": "slimeball_icon.png",
"group": "GROUP_MATERIAL",
"fuelTime": 20
}
}
================================================
FILE: items/misc/snowball.json
================================================
{
"snowball": {
"type": "MATERIALS",
"iconTextureData": "snowball_icon.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc/spider_eye.json
================================================
{
"spider_eye": {
"ai": "Food",
"type": "MATERIALS",
"iconTextureData": "spider_eye_icon.png",
"group": "GROUP_FOOD",
"eatable": true,
"useSoundGroup": "eat",
"food": 10,
"foodSaturation": 32,
"buffs": [
{
"id": "poison",
"time": 240
}
]
}
}
================================================
FILE: items/misc/stick.json
================================================
{
"stick": {
"type": "MATERIALS",
"iconTextureData": "stick_icon.png",
"group": "GROUP_STICK",
"fuelTime": 20
}
}
================================================
FILE: items/misc/string.json
================================================
{
"string": {
"type": "MATERIALS",
"iconTextureData": "string_icon.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc/sugar_cane.json
================================================
{
"sugar_cane": {
"type": "BLOCKS",
"iconTextureData": "sugar_cane_icon.png",
"group": "GROUP_SEED",
"isSeed": true,
"blockId": "sugar_cane"
}
}
================================================
FILE: items/misc/suger.json
================================================
{
"suger": {
"type": "MATERIALS",
"iconTextureData": "suger_icon.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc/totem_of_undying.json
================================================
{
"totem_of_undying": {
"type": "MATERIALS",
"iconTextureData": "totem_of_undying_icon.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc/vine.json
================================================
{
"vine": {
"type": "MATERIALS",
"iconTextureData": "vine_icon.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc/wheat.json
================================================
{
"wheat": {
"type": "MATERIALS",
"iconTextureData": "wheat_icon.png",
"group": "GROUP_FOOD"
}
}
================================================
FILE: items/misc/wire_cutter.json
================================================
{
"wire_cutter": {
"type": "TOOLS",
"iconTextureData": "wire_cutter_icon.png",
"textureData": "wire_cutter_entity.png",
"group": "GROUP_WIRE_CUTTER",
"toolType": "WIRE_CUTTER",
"toolGrade": "STONE",
"efficiency": 2.0,
"coldTime": 16,
"entityWidth": 20,
"entityHeight": 32,
"handX": 10,
"handY": 28,
"holdType": "NORMAL",
"durable": 512
}
}
================================================
FILE: items/misc2/ancient_ingot.json
================================================
{
"ancient_ingot": {
"type": "MATERIALS",
"iconTextureData": "ancient_ingot.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc2/ancient_sample.json
================================================
{
"ancient_sample": {
"type": "MATERIALS",
"iconTextureData": "ancient_sample.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc2/blood.json
================================================
{
"blood": {
"type": "MATERIALS",
"iconTextureData": "blood.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc2/blue_crystal.json
================================================
{
"blue_crystal": {
"type": "MATERIALS",
"iconTextureData": "blue_crystal.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc2/dark_shadow_ingot.json
================================================
{
"dark_shadow_ingot": {
"type": "MATERIALS",
"iconTextureData": "dark_shadow_ingot.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc2/dark_shadow_part.json
================================================
{
"dark_shadow_part": {
"type": "MATERIALS",
"iconTextureData": "dark_shadow_part.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc2/diamond_ingot.json
================================================
{
"diamond_ingot": {
"type": "MATERIALS",
"iconTextureData": "diamond_ingot.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc2/ender_mirror.json
================================================
{
"ender_mirror": {
"ai": "EnderMirror",
"type": "TOOLS",
"iconTextureData": "ender_mirror.png",
"textureData": "ender_mirror.png",
"group": "GROUP_MATERIAL",
"toolType": "ENDER_MIRROR",
"entityWidth": 32,
"entityHeight": 32,
"handX": 10,
"handY": 20
}
}
================================================
FILE: items/misc2/evil_part.json
================================================
{
"evil_part": {
"type": "MATERIALS",
"iconTextureData": "evil_part.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc2/flesh_ingot.json
================================================
{
"flesh_ingot": {
"type": "MATERIALS",
"iconTextureData": "flesh_ingot.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc2/flesh_machine_part.json
================================================
{
"flesh_machine_part": {
"type": "MATERIALS",
"iconTextureData": "flesh_machine_part.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc2/flesh_part.json
================================================
{
"flesh_part": {
"type": "MATERIALS",
"iconTextureData": "flesh_part.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc2/ghost.json
================================================
{
"ghost": {
"type": "MATERIALS",
"iconTextureData": "ghost.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc2/ghost_crystal.json
================================================
{
"ghost_crystal": {
"type": "MATERIALS",
"iconTextureData": "ghost_crystal.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc2/ghost_element.json
================================================
{
"ghost_element": {
"type": "MATERIALS",
"iconTextureData": "ghost_element.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc2/ice_element.json
================================================
{
"ice_element": {
"type": "MATERIALS",
"iconTextureData": "ice_element.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc2/ice_element_ball.json
================================================
{
"ice_element_ball": {
"type": "MATERIALS",
"iconTextureData": "ice_element_ball.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc2/knight_ingot.json
================================================
{
"knight_ingot": {
"type": "MATERIALS",
"iconTextureData": "knight_ingot.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc2/machine_part.json
================================================
{
"machine_part": {
"type": "MATERIALS",
"iconTextureData": "machine_part.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc2/magic_cell.json
================================================
{
"magic_cell": {
"type": "MATERIALS",
"iconTextureData": "magic_cell.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc2/magic_cell_group.json
================================================
{
"magic_cell_group": {
"type": "MATERIALS",
"iconTextureData": "magic_cell_group.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc2/magic_crystal.json
================================================
{
"magic_crystal": {
"type": "MATERIALS",
"iconTextureData": "magic_crystal.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc2/magic_silver_ingot.json
================================================
{
"magic_silver_ingot": {
"type": "MATERIALS",
"iconTextureData": "magic_silver_ingot.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc2/magma_gold_ingot.json
================================================
{
"magma_gold_ingot": {
"type": "MATERIALS",
"iconTextureData": "magma_gold_ingot.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc2/nether_destroyer.json
================================================
{
"dungeon_eater": {
"ai": "DungeonEater",
"type": "MATERIALS",
"iconTextureData": "dungeon_eater.png",
"group": "GROUP_BOSS"
}
}
================================================
FILE: items/misc2/pure_red_stone.json
================================================
{
"pure_red_stone": {
"type": "MATERIALS",
"iconTextureData": "pure_red_stone.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc2/red_crystal.json
================================================
{
"red_crystal": {
"type": "MATERIALS",
"iconTextureData": "red_crystal.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc2/red_gold_ingot.json
================================================
{
"red_gold_ingot": {
"type": "MATERIALS",
"iconTextureData": "red_gold_ingot.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc2/soul_element.json
================================================
{
"soul_element": {
"type": "MATERIALS",
"iconTextureData": "soul_element.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc2/star_ingot.json
================================================
{
"star_ingot": {
"type": "MATERIALS",
"iconTextureData": "star_ingot.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc2/strange_eye.json
================================================
{
"strange_eye": {
"ai": "CrisonEye",
"type": "MATERIALS",
"iconTextureData": "strange_eye.png",
"group": "GROUP_BOSS"
}
}
================================================
FILE: items/misc2/strange_len.json
================================================
{
"strange_len": {
"type": "MATERIALS",
"iconTextureData": "strange_len.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc2/tower_core.json
================================================
{
"tower_core": {
"type": "TOOLS",
"iconTextureData": "tower_core.png",
"textureData": "tower_core.png",
"group": "GROUP_TOWER_CORE",
"toolType": "TOWER_CORE",
"durable": 2000
}
}
================================================
FILE: items/misc2/white_crystal.json
================================================
{
"white_crystal": {
"type": "MATERIALS",
"iconTextureData": "white_crystal.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/misc2/yellow_crystal.json
================================================
{
"yellow_crystal": {
"type": "MATERIALS",
"iconTextureData": "yellow_crystal.png",
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/nuggets/gold_nugget.json
================================================
{
"gold_nugget": {
"type": "MATERIALS",
"iconTextureData": "nugget_icon.png",
"iconColor": [ 255, 255, 255, 0 ],
"group": "GROUP_NUGGET"
}
}
================================================
FILE: items/nuggets/iron_nugget.json
================================================
{
"iron_nugget": {
"type": "MATERIALS",
"iconTextureData": "nugget_icon.png",
"iconColor": [ 255, 255, 255, 255 ],
"group": "GROUP_NUGGET"
}
}
================================================
FILE: items/pickaxes/bronze_pickaxe.json
================================================
{
"bronze_pickaxe": {
"type": "TOOLS",
"iconTextureData": "bronze_pickaxe_entity.png",
"textureData": "bronze_pickaxe_entity.png",
"group": "GROUP_PICKAXE",
"toolType": "PICKAXE",
"toolGrade": "GOLD",
"efficiency": 3.5,
"ai": "Pickaxe",
"coldTime": 16,
"entityWidth": 30,
"entityHeight": 38,
"handX": 16,
"handY": 26,
"holdType": "NORMAL",
"durable": 1248,
"damage": 4,
"knockBack": 1,
"crit": 0
}
}
================================================
FILE: items/pickaxes/copper_pickaxe.json
================================================
{
"copper_pickaxe": {
"type": "TOOLS",
"iconTextureData": "copper_pickaxe_entity.png",
"textureData": "copper_pickaxe_entity.png",
"group": "GROUP_PICKAXE",
"toolType": "PICKAXE",
"toolGrade": "IRON",
"efficiency": 2.5,
"ai": "Pickaxe",
"coldTime": 16,
"entityWidth": 30,
"entityHeight": 38,
"handX": 16,
"handY": 26,
"holdType": "NORMAL",
"durable": 824,
"damage": 4,
"knockBack": 1,
"crit": 0
}
}
================================================
FILE: items/pickaxes/diamond_pickaxe.json
================================================
{
"diamond_pickaxe": {
"type": "TOOLS",
"iconTextureData": "diamond_pickaxe_entity.png",
"textureData": "diamond_pickaxe_entity.png",
"group": "GROUP_PICKAXE",
"toolType": "PICKAXE",
"toolGrade": "DIAMOND",
"efficiency": 5.0,
"ai": "Pickaxe",
"coldTime": 16,
"entityWidth": 30,
"entityHeight": 38,
"handX": 16,
"handY": 26,
"holdType": "NORMAL",
"durable": 4040,
"damage": 5,
"knockBack": 1,
"crit": 0
}
}
================================================
FILE: items/pickaxes/golden_pickaxe.json
================================================
{
"golden_pickaxe": {
"type": "TOOLS",
"iconTextureData": "golden_pickaxe_entity.png",
"textureData": "golden_pickaxe_entity.png",
"group": "GROUP_PICKAXE",
"toolType": "PICKAXE",
"toolGrade": "GOLD",
"efficiency": 4.0,
"ai": "Pickaxe",
"coldTime": 16,
"entityWidth": 30,
"entityHeight": 38,
"handX": 16,
"handY": 26,
"holdType": "NORMAL",
"durable": 1856,
"damage": 4,
"knockBack": 1,
"crit": 0
}
}
================================================
FILE: items/pickaxes/grass_pickaxe.json
================================================
{
"grass_pickaxe": {
"type": "TOOLS",
"iconTextureData": "grass_pickaxe_entity.png",
"textureData": "grass_pickaxe_entity.png",
"group": "GROUP_PICKAXE",
"toolType": "PICKAXE",
"toolGrade": "GRASS",
"efficiency": 1.0,
"ai": "Pickaxe",
"coldTime": 16,
"entityWidth": 30,
"entityHeight": 36,
"handX": 16,
"handY": 26,
"holdType": "NORMAL",
"durable": 128,
"damage": 1,
"knockBack": 1,
"crit": 0,
"isNoBreaking": true,
"enchantments": [
{
"id": "phyton",
"level": 1
}
]
}
}
================================================
FILE: items/pickaxes/iron_pickaxe.json
================================================
{
"iron_pickaxe": {
"type": "TOOLS",
"iconTextureData": "iron_pickaxe_entity.png",
"textureData": "iron_pickaxe_entity.png",
"group": "GROUP_PICKAXE",
"toolType": "PICKAXE",
"toolGrade": "IRON",
"efficiency": 3.0,
"ai": "Pickaxe",
"coldTime": 16,
"entityWidth": 30,
"entityHeight": 36,
"handX": 16,
"handY": 26,
"holdType": "NORMAL",
"durable": 1000,
"damage": 4,
"knockBack": 1,
"crit": 0
}
}
================================================
FILE: items/pickaxes/lead_pickaxe.json
================================================
{
"lead_pickaxe": {
"type": "TOOLS",
"iconTextureData": "lead_pickaxe_entity.png",
"textureData": "lead_pickaxe_entity.png",
"group": "GROUP_PICKAXE",
"toolType": "PICKAXE",
"toolGrade": "IRON",
"efficiency": 3.0,
"ai": "Pickaxe",
"coldTime": 16,
"entityWidth": 30,
"entityHeight": 38,
"handX": 16,
"handY": 26,
"holdType": "NORMAL",
"durable": 1000,
"damage": 4,
"knockBack": 1,
"crit": 0
}
}
================================================
FILE: items/pickaxes/nether_pickaxe.json
================================================
{
"nether_pickaxe": {
"type": "TOOLS",
"iconTextureData": "nether_pickaxe_entity.png",
"textureData": "nether_pickaxe_entity.png",
"group": "GROUP_PICKAXE",
"toolType": "PICKAXE",
"toolGrade": "DIAMOND",
"efficiency": 5.5,
"ai": "Pickaxe",
"coldTime": 16,
"entityWidth": 30,
"entityHeight": 38,
"handX": 16,
"handY": 26,
"holdType": "NORMAL",
"durable": 4896,
"damage": 5,
"knockBack": 1,
"crit": 0,
"antiLava": true
}
}
================================================
FILE: items/pickaxes/silver_pickaxe.json
================================================
{
"silver_pickaxe": {
"type": "TOOLS",
"iconTextureData": "silver_pickaxe_entity.png",
"textureData": "silver_pickaxe_entity.png",
"group": "GROUP_PICKAXE",
"toolType": "PICKAXE",
"toolGrade": "GOLD",
"efficiency": 4.0,
"ai": "Pickaxe",
"coldTime": 16,
"entityWidth": 30,
"entityHeight": 38,
"handX": 16,
"handY": 26,
"holdType": "NORMAL",
"durable": 1856,
"damage": 4,
"knockBack": 1,
"crit": 0
}
}
================================================
FILE: items/pickaxes/steel_pickaxe.json
================================================
{
"steel_pickaxe": {
"type": "TOOLS",
"iconTextureData": "steel_pickaxe_entity.png",
"textureData": "steel_pickaxe_entity.png",
"group": "GROUP_PICKAXE",
"toolType": "PICKAXE",
"toolGrade": "GOLD",
"efficiency": 3.5,
"ai": "Pickaxe",
"coldTime": 16,
"entityWidth": 30,
"entityHeight": 38,
"handX": 16,
"handY": 26,
"holdType": "NORMAL",
"durable": 1248,
"damage": 4,
"knockBack": 1,
"crit": 0
}
}
================================================
FILE: items/pickaxes/stone_pickaxe.json
================================================
{
"stone_pickaxe": {
"type": "TOOLS",
"iconTextureData": "stone_pickaxe_entity.png",
"textureData": "stone_pickaxe_entity.png",
"group": "GROUP_PICKAXE",
"toolType": "PICKAXE",
"toolGrade": "STONE",
"efficiency": 2.0,
"ai": "Pickaxe",
"coldTime": 16,
"entityWidth": 26,
"entityHeight": 36,
"handX": 13,
"handY": 28,
"holdType": "NORMAL",
"durable": 524,
"damage": 3,
"knockBack": 1,
"crit": 0
}
}
================================================
FILE: items/pickaxes/tin_pickaxe.json
================================================
{
"tin_pickaxe": {
"type": "TOOLS",
"iconTextureData": "tin_pickaxe_entity.png",
"textureData": "tin_pickaxe_entity.png",
"group": "GROUP_PICKAXE",
"toolType": "PICKAXE",
"toolGrade": "IRON",
"efficiency": 2.5,
"ai": "Pickaxe",
"coldTime": 16,
"entityWidth": 30,
"entityHeight": 38,
"handX": 16,
"handY": 26,
"holdType": "NORMAL",
"durable": 824,
"damage": 4,
"knockBack": 1,
"crit": 0
}
}
================================================
FILE: items/pickaxes/wooden_pickaxe.json
================================================
{
"wooden_pickaxe": {
"type": "TOOLS",
"iconTextureData": "wooden_pickaxe_entity.png",
"textureData": "wooden_pickaxe_entity.png",
"group": "GROUP_PICKAXE",
"toolType": "PICKAXE",
"toolGrade": "WOOD",
"efficiency": 1.5,
"ai": "Pickaxe",
"coldTime": 16,
"entityWidth": 30,
"entityHeight": 36,
"handX": 16,
"handY": 26,
"holdType": "NORMAL",
"durable": 280,
"fuelTime": 40,
"damage": 2,
"knockBack": 1,
"crit": 0
}
}
================================================
FILE: items/potions/glass_bottle.json
================================================
{
"glass_bottle": {
"ai": "Potion",
"type": "MATERIALS",
"iconTextureData": "glass_bottle_icon.png",
"iconColor2": [ 0, 255, 255, 255 ],
"group": "GROUP_MATERIAL"
}
}
================================================
FILE: items/potions/potion_awkward.json
================================================
{
"potion_awkward": {
"ai": "Potion",
"type": "MATERIALS",
"iconTextureData": "glass_bottle_icon.png",
"group": "GROUP_POTION",
"iconColor2": [ 255, 90, 140, 255 ],
"eatable": true,
"useSound": "drink",
"eatReturnId": "glass_bottle"
}
}
================================================
FILE: items/potions/potion_fire_resistance.json
================================================
{
"potion_fire_resistance": {
"ai": "Potion",
"type": "MATERIALS",
"iconTextureData": "glass_bottle_4_icon.png",
"group": "GROUP_POTION",
"iconColor2": [ 255, 228, 150, 50 ],
"eatable": true,
"useSound": "drink",
"eatReturnId": "glass_bottle",
"buffs": [
{
"id": "fire_defense",
"time": 10800
}
]
}
}
================================================
FILE: items/potions/potion_fire_resistance_long.json
================================================
{
"potion_fire_resistance_long": {
"ai": "Potion",
"type": "MATERIALS",
"iconTextureData": "glass_bottle_super_5_icon.png",
"group": "GROUP_POTION",
"iconColor2": [ 255, 228, 150, 50 ],
"eatable": true,
"useSound": "drink",
"eatReturnId": "glass_bottle",
"buffs": [
{
"id": "fire_defense",
"time": 28800
}
]
}
}
================================================
FILE: items/potions/potion_glowing.json
================================================
{
"potion_glowing": {
"ai": "Potion",
"type": "MATERIALS",
"iconTextureData": "glass_bottle_icon.png",
"group": "GROUP_POTION",
"iconColor2": [ 255, 244, 244, 64 ],
"eatable": true,
"useSound": "drink",
"eatReturnId": "glass_bottle",
"buffs": [
{
"id": "glowing",
"time": 10800
}
]
}
}
================================================
FILE: items/potions/potion_glowing_long.json
================================================
{
"potion_glowing_long": {
"ai": "Potion",
"type": "MATERIALS",
"iconTextureData": "glass_bottle_super_4_icon.png",
"group": "GROUP_POTION",
"iconColor2": [ 255, 244, 244, 64 ],
"eatable": true,
"useSound": "drink",
"eatReturnId": "glass_bottle",
"buffs": [
{
"id": "glowing",
"time": 28800
}
]
}
}
================================================
FILE: items/potions/potion_harming.json
================================================
{
"potion_harming": {
"ai": "Potion",
"type": "MATERIALS",
"iconTextureData": "glass_bottle_6_icon.png",
"group": "GROUP_POTION",
"iconColor2": [ 255, 120, 60, 60 ],
"eatable": true,
"useSound": "drink",
"eatReturnId": "glass_bottle",
"addHealth": -30
}
}
================================================
FILE: items/potions/potion_harming_super.json
================================================
{
"potion_harming_super": {
"ai": "Potion",
"type": "MATERIALS",
"iconTextureData": "glass_bottle_super_3_icon.png",
"group": "GROUP_POTION",
"iconColor2": [ 255, 120, 60, 60 ],
"eatable": true,
"useSound": "drink",
"eatReturnId": "glass_bottle",
"addHealth": -60
}
}
================================================
FILE: items/potions/potion_healing.json
================================================
{
"potion_healing": {
"ai": "Potion",
"type": "MATERIALS",
"iconTextureData": "glass_bottle_2_icon.png",
"group": "GROUP_POTION",
"iconColor2": [ 255, 255, 22, 22 ],
"eatable": true,
"useSound": "drink",
"eatReturnId": "glass_bottle",
"addHealth": 50,
"buffs": [
{
"id": "health_cold",
"time": 1800
}
]
}
}
================================================
FILE: items/potions/potion_healing_super.json
================================================
{
"potion_healing_super": {
"ai": "Potion",
"type": "MATERIALS",
"iconTextureData": "glass_bottle_super_3_icon.png",
"group": "GROUP_POTION",
"iconColor2": [ 255, 255, 22, 22 ],
"eatable": true,
"useSound": "drink",
"eatReturnId": "glass_bottle",
"addHealth": 100,
"buffs": [
{
"id": "health_cold",
"time": 2400
}
]
}
}
================================================
FILE: items/potions/potion_invisibility.json
================================================
{
"potion_invisibility": {
"ai": "Potion",
"type": "MATERIALS",
"iconTextureData": "glass_bottle_6_icon.png",
"group": "GROUP_POTION",
"iconColor2": [ 255, 130, 130, 140 ],
"eatable": true,
"useSound": "drink",
"eatReturnId": "glass_bottle",
"buffs": [
{
"id": "invisibility",
"time": 10800
}
]
}
}
================================================
FILE: items/potions/potion_invisibility_long.json
================================================
{
"potion_invisibility_long": {
"ai": "Potion",
"type": "MATERIALS",
"iconTextureData": "glass_bottle_super_2_icon.png",
"group": "GROUP_POTION",
"iconColor2": [ 255, 130, 130, 140 ],
"eatable": true,
"useSound": "drink",
"eatReturnId": "glass_bottle",
"buffs": [
{
"id": "invisibility",
"time": 28800
}
]
}
}
================================================
FILE: items/potions/potion_leaping.json
================================================
{
"potion_leaping": {
"ai": "Potion",
"type": "MATERIALS",
"iconTextureData": "glass_bottle_icon.png",
"group": "GROUP_POTION",
"iconColor2": [ 255, 24, 255, 67 ],
"eatable": true,
"useSound": "drink",
"eatReturnId": "glass_bottle",
"buffs": [
{
"id": "jump_boost",
"time": 10800
}
]
}
}
================================================
FILE: items/potions/potion_leaping_long.json
================================================
{
"potion_leaping_long": {
"ai": "Potion",
"type": "MATERIALS",
"iconTextureData": "glass_bottle_super_4_icon.png",
"group": "GROUP_POTION",
"iconColor2": [ 255, 24, 255, 67 ],
"eatable": true,
"useSound": "drink",
"eatReturnId": "glass_bottle",
"buffs": [
{
"id": "jump_boost",
"time": 28800
}
]
}
}
================================================
FILE: items/potions/potion_night_vision.json
================================================
{
"potion_night_vision": {
"ai": "Potion",
"type": "MATERIALS",
"iconTextureData": "glass_bottle_icon.png",
"group": "GROUP_POTION",
"iconColor2": [ 255, 80, 80, 240 ],
"eatable": true,
"useSound": "drink",
"eatReturnId": "glass_bottle",
"buffs": [
{
"id": "vision",
"time": 10800
}
]
}
}
================================================
FILE: items/potions/potion_night_vision_long.json
================================================
{
"potion_night_vision_long": {
"ai": "Potion",
"type": "MATERIALS",
"iconTextureData": "glass_bottle_super_4_icon.png",
"group": "GROUP_POTION",
"iconColor2": [ 255, 80, 80, 240 ],
"eatable": true,
"useSound": "drink",
"eatReturnId": "glass_bottle",
"buffs": [
{
"id": "vision",
"time": 28800
}
]
}
}
================================================
FILE: items/potions/potion_poison.json
================================================
{
"potion_poison": {
"ai": "Potion",
"type": "MATERIALS",
"iconTextureData": "glass_bottle_6_icon.png",
"group": "GROUP_POTION",
"iconColor2": [ 255, 70, 150, 40 ],
"eatable": true,
"useSound": "drink",
"eatReturnId": "glass_bottle",
"buffs": [
{
"id": "poison",
"time": 600
}
]
}
}
================================================
FILE: items/potions/potion_poison_long.json
================================================
{
"potion_poison_long": {
"ai": "Potion",
"type": "MATERIALS",
"iconTextureData": "glass_bottle_super_3_icon.png",
"group": "GROUP_POTION",
"iconColor2": [ 255, 70, 150, 40 ],
"eatable": true,
"useSound": "drink",
"eatReturnId": "glass_bottle",
"buffs": [
{
"id": "poison",
"time": 1800
}
]
}
}
================================================
FILE: items/potions/potion_regeneration.json
================================================
{
"potion_regeneration": {
"ai": "Potion",
"type": "MATERIALS",
"iconTextureData": "glass_bottle_4_icon.png",
"group": "GROUP_POTION",
"iconColor2": [ 255, 212, 74, 170 ],
"eatable": true,
"useSound": "drink",
"eatReturnId": "glass_bottle",
"buffs": [
{
"id": "regeneration",
"time": 3600
},
{
"id": "health_cold",
"time": 6000
}
],
"addHealth": 20
}
}
================================================
FILE: items/potions/potion_regeneration_long.json
================================================
{
"potion_regeneration_long": {
"ai": "Potion",
"type": "MATERIALS",
"iconTextureData": "glass_bottle_super_5_icon.png",
"group": "GROUP_POTION",
"iconColor2": [ 255, 212, 74, 170 ],
"eatable": true,
"useSound": "drink",
"eatReturnId": "glass_bottle",
"buffs": [
{
"id": "regeneration",
"time": 6000
},
{
"id": "health_cold",
"time": 9400
}
],
"addHealth": 20
}
}
================================================
FILE: items/potions/potion_slow_falling.json
================================================
{
"potion_slow_falling": {
"ai": "Potion",
"type": "MATERIALS",
"iconTextureData": "glass_bottle_4_icon.png",
"group": "GROUP_POTION",
"iconColor2": [ 255, 255, 250, 210 ],
"eatable": true,
"useSound": "drink",
"eatReturnId": "glass_bottle",
"buffs": [
{
"id": "slow_falling",
"time": 3600
}
]
}
}
================================================
FILE: items/potions/potion_slow_falling_long.json
================================================
{
"potion_slow_falling_long": {
"ai": "Potion",
"type": "MATERIALS",
"iconTextureData": "glass_bottle_super_5_icon.png",
"group": "GROUP_POTION",
"iconColor2": [ 255, 255, 250, 210 ],
"eatable": true,
"useSound": "drink",
"eatReturnId": "glass_bottle",
"buffs": [
{
"id": "slow_falling",
"time": 10800
}
]
}
}
================================================
FILE: items/potions/potion_slowness.json
================================================
{
"potion_slowness": {
"ai": "Potion",
"type": "MATERIALS",
"iconTextureData": "glass_bottle_2_icon.png",
"group": "GROUP_POTION",
"iconColor2": [ 255, 87, 105, 126 ],
"eatable": true,
"useSound": "drink",
"eatReturnId": "glass_bottle",
"buffs": [
{
"id": "slowness",
"time": 10800
}
]
}
}
================================================
FILE: items/potions/potion_slowness_long.json
================================================
{
"potion_slowness_long": {
"ai": "Potion",
"type": "MATERIALS",
"iconTextureData": "glass_bottle_super_3_icon.png",
"group": "GROUP_POTION",
"iconColor2": [ 255, 87, 105, 126 ],
"eatable": true,
"useSound": "drink",
"eatReturnId": "glass_bottle",
"buffs": [
{
"id": "slowness",
"time": 28800
}
]
}
}
================================================
FILE: items/potions/potion_strength.json
================================================
{
"potion_strength": {
"ai": "Potion",
"type": "MATERIALS",
"iconTextureData": "glass_bottle_3_icon.png",
"group": "GROUP_POTION",
"iconColor2": [ 255, 220, 50, 45 ],
"eatable": true,
"useSound": "drink",
"eatReturnId": "glass_bottle",
"buffs": [
{
"id": "strength",
"time": 10800
}
]
}
}
================================================
FILE: items/potions/potion_strength_long.json
================================================
{
"potion_strength_long": {
"ai": "Potion",
"type": "MATERIALS",
"iconTextureData": "glass_bottle_super_5_icon.png",
"group": "GROUP_POTION",
"iconColor2": [ 255, 220, 50, 45 ],
"eatable": true,
"useSound": "drink",
"eatReturnId": "glass_bottle",
"buffs": [
{
"id": "strength",
"time": 28800
}
]
}
}
================================================
FILE: items/potions/potion_swiftness.json
================================================
{
"potion_swiftness": {
"ai": "Potion",
"type": "MATERIALS",
"iconTextureData": "glass_bottle_6_icon.png",
"group": "GROUP_POTION",
"iconColor2": [ 255, 124, 178, 200 ],
"eatable": true,
"useSound": "drink",
"eatReturnId": "glass_bottle",
"buffs": [
{
"id": "speed",
"time": 10800
}
]
}
}
================================================
FILE: items/potions/potion_swiftness_long.json
================================================
{
"potion_swiftness_long": {
"ai": "Potion",
"type": "MATERIALS",
"iconTextureData": "glass_bottle_super_4_icon.png",
"group": "GROUP_POTION",
"iconColor2": [ 255, 124, 178, 200 ],
"eatable": true,
"useSound": "drink",
"eatReturnId": "glass_bottle",
"buffs": [
{
"id": "speed",
"time": 28800
}
]
}
}
================================================
FILE: items/potions/potion_water.json
================================================
{
"potion_water": {
"ai": "Potion",
"type": "MATERIALS",
"iconTextureData": "glass_bottle_icon.png",
"group": "GROUP_POTION",
"iconColor2": [ 255, 90, 140, 255 ],
"eatable": true,
"useSound": "drink",
"eatReturnId": "glass_bottle"
}
}
================================================
FILE: items/potions/potion_water_breathing.json
================================================
{
"potion_water_breathing": {
"ai": "Potion",
"type": "MATERIALS",
"iconTextureData": "glass_bottle_6_icon.png",
"group": "GROUP_POTION",
"iconColor2": [ 255, 60, 100, 200 ],
"eatable": true,
"useSound": "drink",
"eatReturnId": "glass_bottle",
"buffs": [
{
"id": "water_breathing",
"time": 10800
}
]
}
}
================================================
FILE: items/potions/potion_water_breathing_long.json
================================================
{
"potion_water_breathing_long": {
"ai": "Potion",
"type": "MATERIALS",
"iconTextureData": "glass_bottle_super_2_icon.png",
"group": "GROUP_POTION",
"iconColor2": [ 255, 60, 100, 200 ],
"eatable": true,
"useSound": "drink",
"eatReturnId": "glass_bottle",
"buffs": [
{
"id": "water_breathing",
"time": 28800
}
]
}
}
================================================
FILE: items/potions/potion_weakness.json
================================================
{
"potion_weakness": {
"ai": "Potion",
"type": "MATERIALS",
"iconTextureData": "glass_bottle_6_icon.png",
"group": "GROUP_POTION",
"iconColor2": [ 255, 130, 140, 120 ],
"eatable": true,
"useSound": "drink",
"eatReturnId": "glass_bottle",
"buffs": [
{
"id": "weak",
"time": 3600
}
]
}
}
================================================
FILE: items/potions/potion_weakness_long.json
================================================
{
"potion_weakness_long": {
"ai": "Potion",
"type": "MATERIALS",
"iconTextureData": "glass_bottle_super_icon.png",
"group": "GROUP_POTION",
"iconColor2": [ 255, 130, 140, 120 ],
"eatable": true,
"useSound": "drink",
"eatReturnId": "glass_bottle",
"buffs": [
{
"id": "weak",
"time": 10800
}
]
}
}
================================================
FILE: items/seeds/melon_seed.json
================================================
{
"melon_seed": {
"type": "MATERIALS",
"iconTextureData": "melon_seed_icon.png",
"group": "GROUP_SEED",
"isSeed": true,
"blockId": "melon_stem"
}
}
================================================
FILE: items/seeds/pumpkin_seed.json
================================================
{
"pumpkin_seed": {
"type": "MATERIALS",
"iconTextureData": "pumpkin_seed_icon.png",
"group": "GROUP_SEED",
"isSeed": true,
"blockId": "pumpkin_stem"
}
}
================================================
FILE: items/seeds/seed.json
================================================
{
"seed": {
"type": "MATERIALS",
"iconTextureData": "seed_icon.png",
"group": "GROUP_SEED",
"isSeed": true,
"blockId": "wheat"
}
}
================================================
FILE: items/staffs/amethyst_staff.json
================================================
{
"amethyst_staff": {
"type": "TOOLS",
"iconTextureData": "amethyst_staff_entity.png",
"textureData": "amethyst_staff_entity.png",
"group": "GROUP_STAFF",
"oreDictionary": [ "OD_STAFF" ],
"toolType": "STAFF",
"ai": "Staff",
"speed": 6.0,
"deviation": 0.03,
"shootTimes": 1,
"shootProjectileId": "amethyst_magic",
"usePosture": 1,
"useSound": "wand1",
"coldTime": 36,
"entityWidth": 12,
"entityHeight": 48,
"handX": 6,
"handY": 32,
"firePoints": [[6,6]],
"holdType": "HOLD_STAFF",
"twoHands": false,
"damage": 12,
"knockBack": 5,
"crit": 3,
"consumeMana": 4
}
}
================================================
FILE: items/staffs/fire_staff.json
================================================
{
"fire_staff": {
"type": "TOOLS",
"iconTextureData": "fire_staff.png",
"textureData": "fire_staff.png",
"group": "GROUP_STAFF",
"oreDictionary": [ "OD_STAFF" ],
"toolType": "STAFF",
"ai": "Staff",
"speed": 12.0,
"deviation": 0.05,
"shootTimes": 1,
"shootProjectileId": "fire_flow",
"usePosture": 1,
"coldTime": 8,
"entityWidth": 20,
"entityHeight": 52,
"handX": 10,
"handY": 32,
"firePoints": [[4,4]],
"holdType": "HOLD_STAFF",
"twoHands": false,
"damage": 5,
"knockBack": 1,
"crit": 3,
"consumeMana": 4
}
}
================================================
FILE: items/staffs/frosen_staff.json
================================================
{
"frosen_staff": {
"type": "TOOLS",
"iconTextureData": "frosen_staff.png",
"textureData": "frosen_staff.png",
"group": "GROUP_STAFF",
"oreDictionary": [ "OD_STAFF" ],
"toolType": "STAFF",
"ai": "Staff",
"speed": 12.0,
"deviation": 0.05,
"shootTimes": 1,
"shootProjectileId": "ice_magic",
"usePosture": 1,
"coldTime": 48,
"entityWidth": 16,
"entityHeight": 48,
"handX": 8,
"handY": 36,
"firePoints": [[4,4]],
"holdType": "HOLD_STAFF",
"twoHands": false,
"damage": 16,
"knockBack": 5,
"crit": 3,
"consumeMana": 10,
"useSound": "wand1"
}
}
================================================
FILE: items/staffs/ice_staff.json
================================================
{
"ice_staff": {
"type": "TOOLS",
"iconTextureData": "ice_staff_entity.png",
"textureData": "ice_staff_entity.png",
"group": "GROUP_STAFF",
"oreDictionary": [ "OD_STAFF" ],
"toolType": "STAFF",
"ai": "Staff",
"speed": 10.0,
"deviation": 0.03,
"shootTimes": 1,
"shootProjectileId": "ice_magic",
"usePosture": 1,
"useSound": "wand1",
"coldTime": 40,
"entityWidth": 16,
"entityHeight": 48,
"handX": 8,
"handY": 32,
"firePoints": [[8,8]],
"holdType": "HOLD_STAFF",
"twoHands": false,
"damage": 12,
"knockBack": 5,
"crit": 3,
"consumeMana": 5
}
}
================================================
FILE: items/staffs/lighting_staff.json
================================================
{
"lighting_staff": {
"type": "TOOLS",
"iconTextureData": "lighting_staff_entity.png",
"textureData": "lighting_staff_entity.png",
"group": "GROUP_STAFF",
"oreDictionary": [ "OD_STAFF" ],
"toolType": "STAFF",
"ai": "Staff",
"speed": 6.0,
"deviation": 0.03,
"shootTimes": 1,
"shootProjectileId": "star",
"usePosture": 1,
"useSound": "wand1",
"coldTime": 36,
"entityWidth": 8,
"entityHeight": 48,
"handX": 4,
"handY": 32,
"firePoints": [[4,4]],
"holdType": "HOLD_STAFF",
"twoHands": false,
"damage": 12,
"knockBack": 5,
"crit": 3,
"consumeMana": 6
}
}
================================================
FILE: items/staffs/shadow_staff.json
================================================
{
"shadow_staff": {
"type": "TOOLS",
"iconTextureData": "shadow_staff_entity.png",
"textureData": "shadow_staff_entity.png",
"group": "GROUP_STAFF",
"oreDictionary": [ "OD_STAFF" ],
"toolType": "STAFF",
"ai": "Staff",
"speed": 6.0,
"deviation": 0.05,
"shootTimes": 1,
"shootProjectileId": "shadow_magic",
"usePosture": 1,
"useSound": "wand1",
"coldTime": 40,
"entityWidth": 16,
"entityHeight": 48,
"handX": 8,
"handY": 32,
"firePoints": [[8,8]],
"holdType": "HOLD_STAFF",
"twoHands": false,
"damage": 12,
"knockBack": 5,
"crit": 3,
"consumeMana": 6
}
}
================================================
FILE: items/staffs/soul_staff.json
================================================
{
"soul_staff": {
"type": "TOOLS",
"iconTextureData": "soul_staff.png",
"textureData": "soul_staff.png",
"group": "GROUP_STAFF",
"oreDictionary": [ "OD_STAFF" ],
"toolType": "STAFF",
"ai": "Staff",
"speed": 8.0,
"deviation": 0.05,
"shootTimes": 1,
"shootProjectileId": "magic_wave3",
"usePosture": 1,
"coldTime": 58,
"entityWidth": 16,
"entityHeight": 56,
"handX": 8,
"handY": 46,
"firePoints": [[4,4]],
"holdType": "HOLD_STAFF",
"twoHands": false,
"damage": 18,
"knockBack": 1,
"crit": 3,
"consumeMana": 7,
"useSound": "wand1"
}
}
================================================
FILE: items/staffs/water_staff.json
================================================
{
"water_staff": {
"type": "TOOLS",
"iconTextureData": "water_staff_entity.png",
"textureData": "water_staff_entity.png",
"group": "GROUP_STAFF",
"oreDictionary": [ "OD_STAFF" ],
"toolType": "STAFF",
"ai": "Staff",
"speed": 12.0,
"deviation": 0.05,
"shootTimes": 1,
"shootProjectileId": "water_magic",
"usePosture": 1,
"coldTime": 4,
"entityWidth": 8,
"entityHeight": 48,
"handX": 4,
"handY": 32,
"firePoints": [[4,4]],
"holdType": "HOLD_STAFF",
"twoHands": false,
"damage": 1,
"knockBack": 1,
"crit": 3,
"consumeMana": 1
}
}
================================================
FILE: items/swords/air_sword.json
================================================
{
"air_sword": {
"type": "TOOLS",
"iconTextureData": "air_sword_entity.png",
"textureData": "air_sword_entity.png",
"group": "GROUP_SWORD",
"oreDictionary": [ "OD_SWORD" ],
"toolType": "SWORD",
"ai": "magic_sword",
"coldTime": 24,
"speed": 8.0,
"deviation": 0.04,
"shootTimes": 1,
"shootProjectileId": "small_air_bullet",
"entityWidth": 18,
"entityHeight": 56,
"firePoints": [[8,8]],
"handX": 9,
"handY": 48,
"holdType": "NORMAL",
"durable": 512,
"damage": 8,
"knockBack": 4,
"crit": 4,
"consumeMana": 4
}
}
================================================
FILE: items/swords/bronze_sword.json
================================================
{
"bronze_sword": {
"type": "TOOLS",
"iconTextureData": "bronze_sword_entity.png",
"textureData": "bronze_sword_entity.png",
"group": "GROUP_SWORD",
"oreDictionary": [ "OD_SWORD" ],
"toolType": "SWORD",
"ai": "Sword",
"coldTime": 24,
"entityWidth": 22,
"entityHeight": 56,
"handX": 10,
"handY": 48,
"firePoints": [[10,0]],
"holdType": "NORMAL",
"durable": 624,
"damage": 11,
"knockBack": 3,
"crit": 4
}
}
================================================
FILE: items/swords/copper_sword.json
================================================
{
"copper_sword": {
"type": "TOOLS",
"iconTextureData": "copper_sword_entity.png",
"textureData": "copper_sword_entity.png",
"group": "GROUP_SWORD",
"oreDictionary": [ "OD_SWORD" ],
"toolType": "SWORD",
"ai": "Sword",
"coldTime": 24,
"entityWidth": 22,
"entityHeight": 56,
"handX": 10,
"handY": 48,
"holdType": "NORMAL",
"durable": 412,
"damage": 9,
"knockBack": 3,
"crit": 4
}
}
================================================
FILE: items/swords/diamond_sword.json
================================================
{
"diamond_sword": {
"type": "TOOLS",
"iconTextureData": "diamond_sword_entity.png",
"textureData": "diamond_sword_entity.png",
"group": "GROUP_SWORD",
"oreDictionary": [ "OD_SWORD" ],
"toolType": "SWORD",
"ai": "Sword",
"coldTime": 24,
"entityWidth": 22,
"entityHeight": 56,
"handX": 10,
"handY": 48,
"holdType": "NORMAL",
"durable": 1552,
"damage": 14,
"knockBack": 5,
"crit": 5
}
}
================================================
FILE: items/swords/ghost_sword.json
================================================
{
"ghost_sword": {
"type": "TOOLS",
"iconTextureData": "ghost_sword_entity.png",
"textureData": "ghost_sword_entity.png",
"group": "GROUP_SWORD",
"oreDictionary": [ "OD_SWORD" ],
"toolType": "SWORD",
"ai": "Sword",
"coldTime": 16,
"entityWidth": 14,
"entityHeight": 76,
"handX": 8,
"handY": 66,
"holdType": "NORMAL",
"durable": 624,
"damage": 8,
"knockBack": 1,
"crit": 4,
"enchantments": [
{
"id": "smite",
"level": 4
}
]
}
}
================================================
FILE: items/swords/golden_sword.json
================================================
{
"golden_sword": {
"type": "TOOLS",
"iconTextureData": "golden_sword_entity.png",
"textureData": "golden_sword_entity.png",
"group": "GROUP_SWORD",
"oreDictionary": [ "OD_SWORD" ],
"toolType": "SWORD",
"ai": "Sword",
"coldTime": 22,
"entityWidth": 22,
"entityHeight": 56,
"handX": 10,
"handY": 48,
"holdType": "NORMAL",
"durable": 788,
"damage": 12,
"knockBack": 4,
"crit": 5
}
}
================================================
FILE: items/swords/grass_sword.json
================================================
{
"grass_sword": {
"type": "TOOLS",
"iconTextureData": "grass_sword_entity.png",
"textureData": "grass_sword_entity.png",
"group": "GROUP_SWORD",
"oreDictionary": [ "OD_SWORD" ],
"toolType": "SWORD",
"ai": "Sword",
"coldTime": 24,
"entityWidth": 22,
"entityHeight": 46,
"handX": 10,
"handY": 40,
"firePoints": [[10,0]],
"holdType": "NORMAL",
"durable": 128,
"damage": 3,
"knockBack": 2,
"crit": 3,
"isNoBreaking": true,
"enchantments": [
{
"id": "phyton",
"level": 1
}
]
}
}
================================================
FILE: items/swords/iron_sword.json
================================================
{
"iron_sword": {
"type": "TOOLS",
"iconTextureData": "iron_sword_entity.png",
"textureData": "iron_sword_entity.png",
"group": "GROUP_SWORD",
"oreDictionary": [ "OD_SWORD" ],
"toolType": "SWORD",
"ai": "Sword",
"coldTime": 24,
"entityWidth": 22,
"entityHeight": 56,
"handX": 10,
"handY": 48,
"holdType": "NORMAL",
"durable": 500,
"damage": 10,
"knockBack": 4,
"crit": 4
}
}
================================================
FILE: items/swords/lava_sword.json
================================================
{
"lava_sword": {
"type": "TOOLS",
"iconTextureData": "lava_sword.png",
"textureData": "lava_sword.png",
"group": "GROUP_SWORD",
"oreDictionary": [ "OD_SWORD" ],
"toolType": "SWORD",
"ai": "LavaSword",
"coldTime": 24,
"entityWidth": 22,
"entityHeight": 56,
"handX": 10,
"handY": 48,
"holdType": "NORMAL",
"durable": 412,
"damage": 12,
"knockBack": 3,
"crit": 4
}
}
================================================
FILE: items/swords/lead_sword.json
================================================
{
"lead_sword": {
"type": "TOOLS",
"iconTextureData": "lead_sword_entity.png",
"textureData": "lead_sword_entity.png",
"group": "GROUP_SWORD",
"oreDictionary": [ "OD_SWORD" ],
"toolType": "SWORD",
"ai": "Sword",
"coldTime": 24,
"entityWidth": 22,
"entityHeight": 56,
"handX": 10,
"handY": 48,
"holdType": "NORMAL",
"durable": 500,
"damage": 10,
"knockBack": 3,
"crit": 4
}
}
================================================
FILE: items/swords/nether_sword.json
================================================
{
"nether_sword": {
"type": "TOOLS",
"iconTextureData": "nether_sword_entity.png",
"textureData": "nether_sword_entity.png",
"group": "GROUP_SWORD",
"oreDictionary": [ "OD_SWORD" ],
"toolType": "SWORD",
"ai": "Sword",
"coldTime": 24,
"entityWidth": 22,
"entityHeight": 56,
"handX": 10,
"handY": 48,
"holdType": "NORMAL",
"durable": 1820,
"damage": 15,
"knockBack": 5,
"crit": 5,
"antiLava": true
}
}
================================================
FILE: items/swords/silver_sword.json
================================================
{
"silver_sword": {
"type": "TOOLS",
"iconTextureData": "silver_sword_entity.png",
"textureData": "silver_sword_entity.png",
"group": "GROUP_SWORD",
"oreDictionary": [ "OD_SWORD" ],
"toolType": "SWORD",
"ai": "Sword",
"coldTime": 24,
"entityWidth": 22,
"entityHeight": 56,
"handX": 10,
"handY": 48,
"holdType": "NORMAL",
"durable": 788,
"damage": 12,
"knockBack": 3,
"crit": 4
}
}
================================================
FILE: items/swords/steel_sword.json
================================================
{
"steel_sword": {
"type": "TOOLS",
"iconTextureData": "steel_sword_entity.png",
"textureData": "steel_sword_entity.png",
"group": "GROUP_SWORD",
"oreDictionary": [ "OD_SWORD" ],
"toolType": "SWORD",
"ai": "Sword",
"coldTime": 24,
"entityWidth": 22,
"entityHeight": 56,
"handX": 10,
"handY": 48,
"holdType": "NORMAL",
"durable": 624,
"damage": 11,
"knockBack": 3,
"crit": 4
}
}
================================================
FILE: items/swords/stone_sword.json
================================================
{
"stone_sword": {
"type": "TOOLS",
"iconTextureData": "stone_sword_entity.png",
"textureData": "stone_sword_entity.png",
"group": "GROUP_SWORD",
"oreDictionary": [ "OD_SWORD" ],
"toolType": "SWORD",
"ai": "Sword",
"coldTime": 26,
"entityWidth": 22,
"entityHeight": 56,
"handX": 10,
"handY": 48,
"holdType": "NORMAL",
"durable": 262,
"damage": 7,
"knockBack": 4,
"crit": 4
}
}
================================================
FILE: items/swords/super_air_sword.json
================================================
{
"super_air_sword": {
"type": "TOOLS",
"iconTextureData": "super_air_sword_entity.png",
"textureData": "super_air_sword_entity.png",
"group": "GROUP_SWORD",
"oreDictionary": [ "OD_SWORD" ],
"toolType": "SWORD",
"ai": "magic_sword",
"coldTime": 20,
"speed": 10.0,
"deviation": 0.04,
"shootTimes": 1,
"shootProjectileId": "air_bullet",
"entityWidth": 26,
"entityHeight": 66,
"firePoints": [[13,8]],
"handX": 13,
"handY": 54,
"holdType": "NORMAL",
"durable": 723,
"damage": 10,
"knockBack": 5,
"crit": 4,
"consumeMana": 5,
"antiLava": true
}
}
================================================
FILE: items/swords/super_bronze_sword.json
================================================
{
"super_bronze_sword": {
"type": "TOOLS",
"iconTextureData": "super_bronze_sword_entity.png",
"textureData": "super_bronze_sword_entity.png",
"group": "GROUP_SWORD",
"oreDictionary": [ "OD_SWORD" ],
"toolType": "SWORD",
"ai": "Sword",
"coldTime": 24,
"entityWidth": 22,
"entityHeight": 56,
"handX": 10,
"handY": 48,
"holdType": "NORMAL",
"durable": 676,
"damage": 12,
"knockBack": 3,
"crit": 4
}
}
================================================
FILE: items/swords/super_copper_sword.json
================================================
{
"super_copper_sword": {
"type": "TOOLS",
"iconTextureData": "super_copper_sword_entity.png",
"textureData": "super_copper_sword_entity.png",
"group": "GROUP_SWORD",
"oreDictionary": [ "OD_SWORD" ],
"toolType": "SWORD",
"ai": "Sword",
"coldTime": 24,
"entityWidth": 22,
"entityHeight": 56,
"handX": 10,
"handY": 48,
"holdType": "NORMAL",
"durable": 456,
"damage": 10,
"knockBack": 3,
"crit": 4
}
}
================================================
FILE: items/swords/super_diamond_sword.json
================================================
{
"super_diamond_sword": {
"type": "TOOLS",
"iconTextureData": "super_diamond_sword_entity.png",
"textureData": "super_diamond_sword_entity.png",
"group": "GROUP_SWORD",
"oreDictionary": [ "OD_SWORD" ],
"toolType": "SWORD",
"ai": "Sword",
"coldTime": 24,
"entityWidth": 22,
"entityHeight": 62,
"handX": 10,
"handY": 54,
"holdType": "NORMAL",
"durable": 1642,
"damage": 15,
"knockBack": 5,
"crit": 5
}
}
================================================
FILE: items/swords/super_golden_sword.json
================================================
{
"super_golden_sword": {
"type": "TOOLS",
"iconTextureData": "super_golden_sword_entity.png",
"textureData": "super_golden_sword_entity.png",
"group": "GROUP_SWORD",
"oreDictionary": [ "OD_SWORD" ],
"toolType": "SWORD",
"ai": "Sword",
"coldTime": 22,
"entityWidth": 22,
"entityHeight": 56,
"handX": 10,
"handY": 48,
"holdType": "NORMAL",
"durable": 820,
"damage": 13,
"knockBack": 4,
"crit": 5
}
}
================================================
FILE: items/swords/super_iron_sword.json
================================================
{
"super_iron_sword": {
"type": "TOOLS",
"iconTextureData": "super_iron_sword_entity.png",
"textureData": "super_iron_sword_entity.png",
"group": "GROUP_SWORD",
"oreDictionary": [ "OD_SWORD" ],
"toolType": "SWORD",
"ai": "Sword",
"coldTime": 24,
"entityWidth": 22,
"entityHeight": 56,
"handX": 10,
"handY": 48,
"holdType": "NORMAL",
"durable": 558,
"damage": 11,
"knockBack": 4,
"crit": 4
}
}
================================================
FILE: items/swords/super_lead_sword.json
================================================
{
"super_lead_sword": {
"type": "TOOLS",
"iconTextureData": "super_lead_sword_entity.png",
"textureData": "super_lead_sword_entity.png",
"group": "GROUP_SWORD",
"oreDictionary": [ "OD_SWORD" ],
"toolType": "SWORD",
"ai": "Sword",
"coldTime": 24,
"entityWidth": 22,
"entityHeight": 56,
"handX": 10,
"handY": 48,
"holdType": "NORMAL",
"durable": 558,
"damage": 11,
"knockBack": 3,
"crit": 4
}
}
================================================
FILE: items/swords/super_nether_sword.json
================================================
{
"super_nether_sword": {
"type": "TOOLS",
"iconTextureData": "super_nether_sword_entity.png",
"textureData": "super_nether_sword_entity.png",
"group": "GROUP_SWORD",
"oreDictionary": [ "OD_SWORD" ],
"toolType": "SWORD",
"ai": "Sword",
"coldTime": 24,
"entityWidth": 22,
"entityHeight": 62,
"handX": 10,
"handY": 54,
"holdType": "NORMAL",
"durable": 2020,
"damage": 16,
"knockBack": 5,
"crit": 5,
"antiLava": true
}
}
================================================
FILE: items/swords/super_silver_sword.json
================================================
{
"super_silver_sword": {
"type": "TOOLS",
"iconTextureData": "super_silver_sword_entity.png",
"textureData": "super_silver_sword_entity.png",
"group": "GROUP_SWORD",
"oreDictionary": [ "OD_SWORD" ],
"toolType": "SWORD",
"ai": "Sword",
"coldTime": 24,
"entityWidth": 22,
"entityHeight": 66,
"handX": 10,
"handY": 56,
"holdType": "NORMAL",
"durable": 820,
"damage": 13,
"knockBack": 3,
"crit": 4
}
}
================================================
FILE: items/swords/super_steel_sword.json
================================================
{
"super_steel_sword": {
"type": "TOOLS",
"iconTextureData": "super_steel_sword_entity.png",
"textureData": "super_steel_sword_entity.png",
"group": "GROUP_SWORD",
"oreDictionary": [ "OD_SWORD" ],
"toolType": "SWORD",
"ai": "Sword",
"coldTime": 16,
"entityWidth": 22,
"entityHeight": 72,
"handX": 10,
"handY": 62,
"holdType": "NORMAL",
"durable": 676,
"damage": 11,
"knockBack": 3,
"crit": 4
}
}
================================================
FILE: items/swords/super_tin_sword.json
================================================
{
"super_tin_sword": {
"type": "TOOLS",
"iconTextureData": "super_tin_sword_entity.png",
"textureData": "super_tin_sword_entity.png",
"group": "GROUP_SWORD",
"oreDictionary": [ "OD_SWORD" ],
"toolType": "SWORD",
"ai": "Sword",
"coldTime": 24,
"entityWidth": 22,
"entityHeight": 56,
"handX": 10,
"handY": 48,
"holdType": "NORMAL",
"durable": 456,
"damage": 10,
"knockBack": 3,
"crit": 4
}
}
================================================
FILE: items/swords/tin_sword.json
================================================
{
"tin_sword": {
"type": "TOOLS",
"iconTextureData": "tin_sword_entity.png",
"textureData": "tin_sword_entity.png",
"group": "GROUP_SWORD",
"oreDictionary": [ "OD_SWORD" ],
"toolType": "SWORD",
"ai": "Sword",
"coldTime": 24,
"entityWidth": 22,
"entityHeight": 56,
"handX": 10,
"handY": 48,
"holdType": "NORMAL",
"durable": 412,
"damage": 9,
"knockBack": 3,
"crit": 4
}
}
================================================
FILE: items/swords/wooden_sword.json
================================================
{
"wooden_sword": {
"type": "TOOLS",
"iconTextureData": "wooden_sword_entity.png",
"textureData": "wooden_sword_entity.png",
"group": "GROUP_SWORD",
"oreDictionary": [ "OD_SWORD" ],
"toolType": "SWORD",
"ai": "Sword",
"coldTime": 28,
"entityWidth": 22,
"entityHeight": 56,
"handX": 10,
"handY": 48,
"holdType": "NORMAL",
"durable": 140,
"damage": 5,
"knockBack": 3,
"crit": 4,
"fuelTime": 40
}
}
================================================
FILE: items/wires/blue_wire.json
================================================
{
"blue_wire": {
"type": "WIRES",
"iconTextureData": "blue_wire_icon.png",
"wireId": 3,
"group": "GROUP_REDSTONE_WIRE"
}
}
================================================
FILE: items/wires/green_wire.json
================================================
{
"green_wire": {
"type": "WIRES",
"iconTextureData": "green_wire_icon.png",
"wireId": 2,
"group": "GROUP_REDSTONE_WIRE"
}
}
================================================
FILE: items/wires/red_wire.json
================================================
{
"red_wire": {
"type": "WIRES",
"iconTextureData": "red_wire_icon.png",
"wireId": 1,
"group": "GROUP_REDSTONE_WIRE"
}
}
================================================
FILE: items/wires/yellow_wire.json
================================================
{
"yellow_wire": {
"type": "WIRES",
"iconTextureData": "yellow_wire_icon.png",
"wireId": 4,
"group": "GROUP_REDSTONE_WIRE"
}
}
================================================
FILE: languages/Locale.lua
================================================
local Locale = {
BACK = "",
DESC = "",
WEB = "",
OK = "",
SINGLE_PLAYER = "",
MULTI_PLAYER = "",
MOD_LIST = "",
COMMUNITY = "",
SETTING = "",
EXIT_GAME = "",
COPYRIGHT = "",
MOD_LOADER_INFO = "",
ENGINE_VERSION = "",
OPEN_MOD_FOLDER = "",
MANAGER_SOURCES = "",
ALL_MOD_LOADED = "",
MOD_VERSION = "",
MOD_AUTHORS = "",
MOD_FOLDER_UNSUPPORTED = "",
WEB_SOURCE_GITHUB = "",
WEB_HOME = "",
BACK_TO_GAME = "",
RECIPE_SEARCH = "",
ADVANCEMENT = "",
SAVE_AND_EXIT = "",
GAME_MENU = "",
LOADING = "",
SELECT_LANGUAGE = "",
LANGUAGE_LIST = "",
LANGUAGE_MAY_WRONG = "",
SELECT_PLAYER = "",
ARRANGE = "",
QUICK_PICK = "",
QUICK_PUSH = "",
QUICK_STACK = "",
STORAGE = "",
PRE_ITEM = "",
SEARCH_FROM_OUTPUT = "",
SEARCH_FROM_INPUT = "",
SOUND = "",
SETTING_PANEL = "",
CREATE_WORLD = "",
MORE_SETTINGS = "",
SURVIVAL_MODE = "",
BP_SHARED_MODE = "",
WORLD_SEED_Q = "",
WORLD_NAME_Q = "",
CREATE_NEW_WORLD = "",
ENTER_WORLD = "",
NEW_WORLD_B = "",
SELECT_WORLD = "",
CHANGE_POSTURE = "",
NAME_Q = "",
CREATE_PLAYER = "",
NEW_PLAYER_B = "",
TIPS = "",
GET_ADVANCEMENT = "",
EQUIPMENT = "",
CRAFT = "",
APPEAR_ACCESSORY = "",
INVENTORY = "",
FURNACE = "",
ENCHANT = "",
REPAIR = "",
BREWING_STAND = "",
YOU_DIED = "",
PENDING_SAVING = "",
PENDING_NO_CONNECTION = "",
RESPAWNING = "",
GAME_VER = "",
FORCE_NEW_PLAYER_MODE = "",
SURE_TO_DELETE_WORLD_1 = "",
SURE_TO_DELETE_WORLD_2 = "",
SURE_TO_DELETE_PLAYER_1 = "",
SURE_TO_DELETE_PLAYER_2 = "",
TIME_COST = "",
BURN_TIME_COST = "",
}
return Locale
================================================
FILE: languages/LocaleHelper.lua
================================================
local LocaleHelper = class("LocaleHelper")
function LocaleHelper.reload(locale)
for name, _ in pairs(locale) do
local modText = LangUtils.ModText(name)
if modText ~= nil and modText ~= "" then
locale[name] = modText
end
local content = locale[name]
if content == "" then
locale[name] = string.format("@[%s]", name)
print("Locale Missing: " .. locale[name])
end
end
end
return LocaleHelper
================================================
FILE: languages/chinese.json
================================================
{
"modTexts": [
[ "BACK", "返回" ],
[ "DESC", "描述" ],
[ "WEB", "网站" ],
[ "OK", "确定" ],
[ "SINGLE_PLAYER", "单人游戏" ],
[ "MULTI_PLAYER", "多人游戏" ],
[ "MOD_LIST", "模组列表"],
[ "COMMUNITY", "社区" ],
[ "SETTING", "选项" ],
[ "EXIT_GAME", "退出游戏" ],
[ "COPYRIGHT", "BlueYoshi.cn/TerraCraft 进击的蓝耀西(Bilibili)" ],
[ "MOD_LOADER_INFO", "[模组加载器] 已加载%d个模组" ],
[ "ENGINE_VERSION", "引擎版本 %s" ],
[ "OPEN_MOD_FOLDER", "打开模组文件夹" ],
[ "MANAGER_SOURCES", "管理源码.." ],
[ "ALL_MOD_LOADED", "所有模组(已加载:%d)" ],
[ "MOD_VERSION", "模组版本" ],
[ "MOD_AUTHORS", "模组作者" ],
[ "MOD_FOLDER_UNSUPPORTED", "移动端不支持打开模组文件夹功能。" ],
[ "WEB_SOURCE_GITHUB", "源代码仓库(Github)" ],
[ "WEB_HOME", "主页" ],
[ "BACK_TO_GAME", "返回游戏" ],
[ "RECIPE_SEARCH", "配方查询" ],
[ "ADVANCEMENT", "成就" ],
[ "SAVE_AND_EXIT", "保存并退出" ],
[ "GAME_MENU", "游戏菜单" ],
[ "LOADING", "加载中" ],
[ "SELECT_LANGUAGE", "选择语言" ],
[ "LANGUAGE_LIST", "语言列表" ],
[ "LANGUAGE_MAY_WRONG", "翻译并不是100%准确,如发现文本错误,请联系我们。" ],
[ "SELECT_PLAYER", "选择玩家" ],
[ "ARRANGE", "整理" ],
[ "QUICK_PICK", "快速取出" ],
[ "QUICK_PUSH", "快速放入" ],
[ "QUICK_STACK", "快速堆叠" ],
[ "STORAGE", "存储" ],
[ "PRE_ITEM", "上一项" ],
[ "SEARCH_FROM_OUTPUT", "从产物搜索" ],
[ "SEARCH_FROM_INPUT", "从原料搜索" ],
[ "SOUND", "音频" ],
[ "SETTING_PANEL", "设置面板" ],
[ "CREATE_WORLD", "创建世界" ],
[ "MORE_SETTINGS", "更多设置.." ],
[ "SURVIVAL_MODE", "生存模式" ],
[ "BP_SHARED_MODE", "背包共享模式" ],
[ "WORLD_SEED_Q", "世界种子:" ],
[ "WORLD_NAME_Q", "世界名称:" ],
[ "CREATE_NEW_WORLD", "创建新世界" ],
[ "ENTER_WORLD", "进入世界!" ],
[ "NEW_WORLD_B", "新世界.." ],
[ "SELECT_WORLD", "选择世界" ],
[ "CHANGE_POSTURE", "换个姿势" ],
[ "NAME_Q", "名称:" ],
[ "CREATE_PLAYER", "创建玩家" ],
[ "NEW_PLAYER_B", "新玩家.." ],
[ "TIPS", "提示" ],
[ "GET_ADVANCEMENT", "获得成就!" ],
[ "EQUIPMENT", "装备" ],
[ "CRAFT", "合成" ],
[ "APPEAR_ACCESSORY", "外观/饰品" ],
[ "INVENTORY", "背包" ],
[ "FURNACE", "熔炉" ],
[ "ENCHANT", "附魔" ],
[ "REPAIR", "修复" ],
[ "BREWING_STAND", "酿造台" ],
[ "YOU_DIED", "你 死 了" ],
[ "PENDING_SAVING", "保存数据中...请不要断开电源" ],
[ "PENDING_NO_CONNECTION", "与服务器连接中断,已安全退出..." ],
[ "RESPAWNING", "重生中... %d" ],
[ "GAME_VER", "(电脑/手机互通版)游戏版本 %s" ],
[ "FORCE_NEW_PLAYER_MODE", "强制开荒模式" ],
[ "SURE_TO_DELETE_WORLD_1", "确定删除" ],
[ "SURE_TO_DELETE_WORLD_2", "吗?该世界将被永远删除!" ],
[ "SURE_TO_DELETE_PLAYER_1", "确定删除" ],
[ "SURE_TO_DELETE_PLAYER_2", "吗?该玩家将被永远删除!" ],
[ "TIME_COST", "耗时: %.2f秒" ],
[ "BURN_TIME_COST", "燃烧耗时: %.2f秒" ],
[ "help:kill", "杀死自己" ],
[ "help:killp", "杀死指定玩家" ],
[ "help:buff", "添加BUFF并设定时长" ],
[ "help:buffp", "添加BUFF到指定玩家并设定时长" ],
[ "help:spawn", "传送到出生点" ],
[ "help:home", "传送到重生点" ],
[ "help:ex", "增加经验值" ],
[ "help:exp", "增加指定玩家经验值" ],
[ "help:give", "给予物品并设定数量" ],
[ "help:givep", "给予玩家物品并设定数量" ],
[ "help:gamemode", "设定自己的游戏模式" ],
[ "help:gamemodep", "设定指定玩家的游戏模式" ],
[ "help:gamemodew", "设定世界的游戏模式" ],
[ "help:npc", "在指定位置生成一个NPC" ],
[ "help:effect", "在指定位置生成一个特效" ],
[ "help:tp", "传送到指定位置" ],
[ "help:tpp", "传送玩家到指定位置" ],
[ "help:me", "显示一条关于自己的信息" ],
[ "help:msg", "向指定玩家发送一条私信" ],
[ "help:say", "广播一条消息" ],
[ "help:clear", "清空背包" ],
[ "help:clearp", "清空指定玩家的背包" ],
[ "help:day", "设置当日时间" ],
[ "help:dayf", "依次设置当日时间的 小时 分钟 秒" ],
[ "help:dayspeed", "设置时间的流逝速度" ],
[ "help:daylock", "锁定昼夜更替时间" ],
[ "help:dayunlock", "取消锁定昼夜更替时间" ],
[ "help:wea", "设置天气时间" ],
[ "help:stopwea", "取消天气事件" ],
[ "help:admin", "赋予指定玩家管理员权限" ],
[ "help:noadmin", "取消指定玩家管理员权限" ],
[ "help:master", "赋予指定玩家服主权限" ],
[ "help:nomaster", "取消指定玩家服主权限" ],
[ "help:save", "立即保存世界全部数据" ],
[ "help:autosave-on", "开启自动保存功能" ],
[ "help:autosave-off", "取消自动保存功能" ],
[ "help:port", "查看服务器端口号" ],
[ "help:state", "查看服务器运行状态" ],
[ "help:pvp-on", "开启PVP模式" ],
[ "help:pvp-off", "关闭PVP模式" ],
[ "help:safeblow-on", "开启爆炸保护模式" ],
[ "help:safeblow-off", "关闭爆炸保护模式" ],
[ "help:players", "查看所有在线玩家" ],
[ "help:kick", "将指定玩家踢出游戏" ],
[ "help:kickall", "将全部玩家踢出游戏" ],
[ "help:banip", "将指定IP加入服务器黑名单" ],
[ "help:nobanip", "将指定IP移出服务器黑名单" ],
[ "help:blacklist", "查看游戏黑名单" ],
[ "help:enchant", "对手持物品进行附魔并设置附魔等级" ],
[ "help:blueyoshiiscool", "神秘指令" ],
[ "ex_ok", "给予玩家 %s 经验值 %d" ],
[ "buff_ok", "给予玩家 %s 状态效果 %s 时长 %d 秒" ],
[ "em_ok", "给予玩家 %s 手持物品 %s 附魔 %s 等级 %d" ],
[ "em_fail", "附魔失败" ],
[ "spawn_ok", "传送玩家 %s 到出生点" ],
[ "home_ok", "传送玩家 %s 到重生点" ],
[ "home_fail", "玩家 %s 没有重生点记录" ],
[ "give_ok", "给予 %s 物品 %s * %d" ],
[ "clear_ok", "已清空玩家 %s 的背包" ],
[ "day_ok", "已设置当前日间时间为 %02d:%02d:%02d" ],
[ "dayspeed_ok", "已设置时间流逝速度为 %.2f 倍" ],
[ "wea_ok", "当前天气进度 %d%%" ],
[ "admin_ok", "已将玩家 %s 设置为管理员" ],
[ "noadmin_ok", "已取消玩家 %s 的管理员权限" ],
[ "master_ok", "已将玩家 %s 设置为服主" ],
[ "nomaster_ok", "已取消玩家 %s 的服主权限" ],
[ "save_ok", "已将 [立即保存] 加入服务端处理队列" ],
[ "player_info", "(%d) %s (%s:%d)" ],
[ "players_ok", "总共 %d 人在线" ],
[ "autosave_on_ok", "已开启 [自动保存] 功能" ],
[ "autosave_off_ok", "已关闭 [自动保存] 功能" ],
[ "pvp_on_ok", "已开启PVP" ],
[ "pvp_off_ok", "已关闭PVP" ],
[ "safeblow_on_ok", "已开启 [爆炸保护] 功能" ],
[ "safeblow_off_ok", "已关闭 [爆炸保护] 功能" ],
[ "port_ok", "服务器端口号为 %d" ],
[ "kick_ok", "已踢出 %s" ],
[ "blacklist_info", "(%d) %s" ],
[ "blacklist_ok", "黑名单共有 %d 项" ],
[ "banip_ok", "已封禁 IP %s 并加入到服务器黑名单" ],
[ "nobanip_ok", "已将 IP %s 移出服务器黑名单" ],
[ "nobanip_fail", "IP %s 不存在于服务器黑名单" ],
[ "gamemodep_s_ok", "玩家 %s 的游戏模式已变更为生存模式" ],
[ "gamemodep_c_ok", "玩家 %s 的游戏模式已变更为创造模式" ],
[ "gamemodep_a_ok", "玩家 %s 的游戏模式已变更为冒险模式" ],
[ "gamemodew_s_ok", "当前世界的游戏模式已变更为生存模式" ],
[ "gamemodew_c_ok", "当前世界的游戏模式已变更为创造模式" ],
[ "gamemodew_a_ok", "当前世界的游戏模式已变更为冒险模式" ],
[ "msg_content", "[来自玩家 %s 的私信] %s" ],
[ "msg_server_content", "[来自服务端的私信] %s" ],
[ "msg_to_content", "[给玩家 %s 的私信] %s" ],
[ "msg_server_to_content", "[给玩家 %s 的私信] %s" ],
[ "say", "[服务器] %s" ],
[ "npc_ok", "已生成 %s 于 (%d, %d)" ],
[ "tp_ok", "将玩家 %s 传送到 (%d, %d)" ],
[ "blueyoshiiscool_ok", "蓝耀西真酷!!!" ]
],
"enchantments": [
[ "silk_touch", "精准采集" ],
[ "fortune", "时运" ],
[ "phyton", "再生" ],
[ "unbreaking", "耐久" ],
[ "efficiency", "效率" ],
[ "aqua_affinity", "水下速掘" ],
[ "bane_of_arthropods", "节肢杀手" ],
[ "blast_protection", "爆炸保护" ],
[ "curse_of_binding", "绑定诅咒" ],
[ "curse_of_vanishing", "消失诅咒" ],
[ "depth_strider", "深海探索者" ],
[ "feather_falling", "摔落保护" ],
[ "fire_aspect", "火焰附加" ],
[ "fire_protection", "火焰保护" ],
[ "flame", "火矢" ],
[ "frost_walker", "冰霜使者" ],
[ "infinity", "无限" ],
[ "knockback", "击退" ],
[ "looting", "抢夺" ],
[ "luck_of_the_sea", "海之眷顾" ],
[ "lure", "饵钓" ],
[ "multishot", "多重射击" ],
[ "piercing", "穿透" ],
[ "power", "力量" ],
[ "projectile_protection", "弹射物保护" ],
[ "protection", "保护" ],
[ "punch", "冲击" ],
[ "quick_charge", "快速装填" ],
[ "respiration", "水下呼吸" ],
[ "sharpness", "锋利" ],
[ "smite", "亡灵杀手" ],
[ "thorns", "荆棘" ]
],
"buffs": [
[ "absorption", "吸血" ],
[ "blindness", "失明" ],
[ "fire", "着火" ],
[ "fire_defense", "防火" ],
[ "glowing", "发光" ],
[ "happiness", "高兴" ],
[ "health_boost", "生命提升" ],
[ "hunger", "饥饿" ],
[ "hurt", "受伤" ],
[ "invisibility", "隐身" ],
[ "jump_boost", "跳跃提升" ],
[ "levitation", "漂浮" ],
[ "luck", "幸运" ],
[ "mining_fatique", "急迫" ],
[ "nausea", "反胃" ],
[ "poison", "中毒" ],
[ "regeneration", "生命恢复" ],
[ "resistance", "抗性提升" ],
[ "sadness", "伤心" ],
[ "slow_falling", "缓降" ],
[ "slow_mining", "挖掘疲劳" ],
[ "slowness", "缓慢" ],
[ "speed", "速度" ],
[ "strength", "力量" ],
[ "vision", "夜视" ],
[ "water_breathing", "水下呼吸" ],
[ "weak", "虚弱" ],
[ "wither", "凋零" ],
[ "health_cold", "回复冷却" ]
],
"advancements": [
[ "inventory", "开始冒险", "初次进入泰拉世界" ],
[ "wood", "获得木头", "使用斧头砍倒一棵树以获得木头方块" ],
[ "crafting_table", "这是?工作台!", "用四个木板来制作一个工作台" ],
[ "farm", "耕种时间到!", "使用木板和木棍来制作木锄" ],
[ "bread", "烤面包", "用小麦来做面包" ],
[ "cake", "蛋糕是个谎言", "小麦、糖、牛奶和鸡蛋!" ],
[ "bow", "弓箭手!", "使用丝线和木棍制作一把弓" ],
[ "crossbow", "弩箭手!", "制作一把驽" ],
[ "mine", "采矿时间到!", "使用木板和木棍来制作木镐" ],
[ "stone", "石器时代", "用你的新镐挖掘石头" ],
[ "mine_up", "获得升级", "制作一把更好的石镐" ],
[ "furnace", "热门话题", "用八个圆石来制作一个熔炉" ],
[ "iron", "来硬的", "冶炼出一块金属锭" ],
[ "sword", "出击时间到!", "使用木板和木棍来制作一把木剑!" ],
[ "leather", "斗牛士", "获得一些皮革" ],
[ "hunter", "怪物猎人", "攻击并消灭一只怪物" ],
[ "staff", "魔力法杖", "制作一个消耗魔力的法杖" ],
[ "magic_limit", "魔法师", "吃掉一个提高魔法上限的魔法碎片" ],
[ "ender_pearl", "小黑杀手", "获得一个末影珍珠" ],
[ "steel", "精炼铁!", "烧制铁锭得到一个钢锭" ],
[ "bronze", "青铜时代", "获得一个青铜锭" ],
[ "diamond", "钻石!", "挖一些钻石吧" ],
[ "enchant", "附魔师", "使用书、黑曜石以及钻石来制作一个附魔台" ],
[ "nether", "还需要更深一些", "深入地狱层" ],
[ "blaze_rod", "与火共舞", "得到烈焰人的烈焰棒" ],
[ "brew", "本地的酿造厂", "制造一个酿造台" ],
[ "ghast", "见鬼去吧!", "干掉一只恶魂" ],
[ "netherite", "深藏不露", "获得远古残骸" ],
[ "gun", "军火商", "在地狱要塞中获得一把枪支" ],
[ "redstone", "发现红石!", "获得一个红石粉末" ],
[ "redstone_wire", "红石科技", "制作一根红石电线" ],
[ "lava", "超级燃料", "盛装一桶岩浆" ],
[ "pumpkin_helmet", "万圣节!", "制作一个万圣节风格的南瓜头盔" ],
[ "ender_chest", "异度空间", "制作一个末影箱" ],
[ "guardian", "入侵者!", "击败一只海底守卫者" ],
[ "snow_queen", "冰雪女王!", "从冰雪女王球中唤醒冰雪女王" ],
[ "snow_queen_killed", "解放极光宫殿", "击杀冰雪女王" ],
[ "nether_destroyer", "毁灭地狱!", "破坏地狱祭坛释放地狱毁灭者" ],
[ "nether_destroyer_killed", "拯救地狱", "击杀地狱毁灭者" ],
[ "diamond_wear", "用钻石包裹我", "穿上全套钻石盔甲" ],
[ "netherite_full_wear", "残骸裹身", "穿上一整套下界合金盔甲" ],
[ "go_ghost_house", "别惹鬼魂!", "探索鬼屋" ],
[ "go_bone_dungeon", "挺进骷髅地牢!", "探索骷髅地牢" ],
[ "go_dark_dungeon", "暗黑地牢!", "探索暗黑地牢" ],
[ "go_deep_snow", "可怕的雪洞!", "探索雪洞" ],
[ "go_ice_dungeon", "发现冰雪地牢!", "探索冰雪地牢" ],
[ "go_lava_dungeon", "庞大的熔岩城堡!", "探索熔岩城堡" ],
[ "go_desert_dungeon", "深入金字塔!", "探索金字塔" ],
[ "strange_len", "晶状体提取者", "杀死一个恶魔眼" ],
[ "crison_eye", "克苏鲁之眼!", "制作克苏鲁之眼召唤物,召唤克苏鲁之眼" ],
[ "crison_eye_killed", "盯着你", "打败克苏鲁之眼" ],
[ "dungeon_eater", "吃掉地牢!", "在暗黑地牢召唤地牢吞噬者" ],
[ "dungeon_eater_killed", "地牢英雄", "打败地牢吞噬者" ],
[ "rocket_boost", "我能飞了!", "找到或制作火箭靴" ],
[ "snow_guard", "极光宫殿入门", "杀死一个冰雪守卫" ],
[ "portal", "传送门!", "使用一次传送门" ],
[ "mine_copper", "获得升级II", "制作一把铜镐或锡镐" ],
[ "mine_iron", "获得升级III", "制作一把铁镐或铅镐" ],
[ "mine_bronze", "获得升级IV", "制作一把青铜镐或钢镐" ],
[ "mine_gold", "获得升级V", "制作一把金镐或银镐" ],
[ "mine_diamond", "极速挖掘", "制作一把钻石镐" ],
[ "mine_netherite", "镐子终结者", "制作一把下届合金镐" ],
[ "repair", "耐久修复学", "制作一个铁砧" ],
[ "recipe_book", "快速合成!", "使用配方书进行快速合成" ],
[ "mirror", "回家的诱惑", "使用末影魔镜快速传送回家" ],
[ "gold", "黄金!", "获得一个金锭" ],
[ "gold_wear", "金色传说", "穿上全套金盔甲" ],
[ "super_diamond_sword", "锋利的钻石", "制作一把强化钻石剑" ],
[ "ghost_crystal", "塔防入门", "杀死迷你幽魂,获得一个幽魂碎片" ],
[ "ghost", "压榨劳动力!", "制作一个幽魂" ],
[ "ice_element_ball", "冰雪元素球", "制作一个冰雪元素球" ],
[ "diamond_ingot", "魔法钻石!", "使用四种水晶和钻石合成一颗魔法钻石" ],
[ "ancient_ingot", "远古力量!", "获得一块远古合金" ],
[ "ancient_wear", "毕业了?", "穿上全套远古套装" ],
[ "super_diamond_wear", "魔法钻石包裹我", "穿上全套强化钻石套装" ],
[ "knight_ingot", "神秘的骑士锭", "获得一块骑士锭" ],
[ "knight_wear", "真正的骑士", "穿上全套骑士套装" ],
[ "star_wear", "星空!", "穿上全套星空套装" ],
[ "flesh_ingot", "染血的金属", "获得一个血腥锭" ],
[ "flesh_wear", "嗜血套装", "穿上全套血腥盔甲" ],
[ "magic_gold_wear", "魔法金色传说", "穿上全套魔金盔甲" ]
],
"npcs": [
[ "pig", "猪" ],
[ "zombie", "僵尸" ],
[ "husk", "尸壳" ],
[ "mummy", "木乃伊" ],
[ "waste_mummy", "废土木乃伊" ],
[ "villager_zombie", "僵尸村民" ],
[ "arrow_zombie", "中箭僵尸" ],
[ "bald_zombie", "秃头僵尸" ],
[ "doge_zombie", "狗头僵尸" ],
[ "iron_zombie", "钢铁僵尸" ],
[ "skeleton", "骷髅" ],
[ "tainted_skeleton", "腐化骷髅" ],
[ "blood_skeleton", "血腥骷髅" ],
[ "angry_skeleton", "愤怒的骷髅" ],
[ "black_skeleton", "黝黑骷髅" ],
[ "boney_skeleton", "多骨骷髅" ],
[ "creeper", "苦力怕" ],
[ "flower_creeper", "花花苦力怕" ],
[ "tainted_creeper", "腐化苦力怕" ],
[ "spider", "蜘蛛" ],
[ "bat", "蝙蝠" ],
[ "jungle_bat", "丛林蝙蝠" ],
[ "large_jungle_bat", "吐舌丛林蝙蝠" ],
[ "blood_bat", "血腥蝙蝠" ],
[ "man_eater", "食人花" ],
[ "blood_eye", "血腥之眼" ],
[ "chicken", "鸡" ],
[ "cow", "牛" ],
[ "sheep", "羊" ],
[ "red_mushroom_cow", "红哞菇" ],
[ "brown_mushroom_cow", "棕哞菇" ],
[ "cat", "猫咪" ],
[ "white_rabbit", "小白兔" ],
[ "brown_rabbit", "小棕兔" ],
[ "black_rabbit", "小黑兔" ],
[ "yellow_rabbit", "小黄兔" ],
[ "squid", "鱿鱼" ],
[ "turtle", "乌龟" ],
[ "pufferfish", "河豚" ],
[ "dolphin", "海豚" ],
[ "wolf", "狼" ],
[ "enderman", "末影人" ],
[ "zombie_pigman", "僵尸猪人" ],
[ "blaze", "烈焰人" ],
[ "drowned", "溺尸" ],
[ "guardian", "守卫者" ],
[ "ghast", "恶魂" ],
[ "ice_elf", "冰精" ],
[ "magma_elf", "熔岩精灵" ],
[ "waste_ghost", "废土幽灵" ],
[ "large_block_slime", "大方块史莱姆" ],
[ "block_slime", "方块史莱姆" ],
[ "large_ice_slime", "大冰块史莱姆" ],
[ "ice_slime", "冰块史莱姆" ],
[ "large_waste_block_slime", "大废土方块史莱姆" ],
[ "waste_block_slime", "废土方块史莱姆" ],
[ "green_slime", "绿史莱姆" ],
[ "large_green_slime", "大型绿史莱姆" ],
[ "large_black_slime", "大型黑史莱姆" ],
[ "large_waste_slime", "大型废土史莱姆" ],
[ "large_tainted_slime", "大型腐化史莱姆" ],
[ "blood_slime", "血腥史莱姆" ],
[ "yellow_slime", "黄史莱姆" ],
[ "desert_slime", "沙漠史莱姆" ],
[ "large_desert_slime", "大型沙漠史莱姆" ],
[ "blue_slime", "蓝史莱姆" ],
[ "purple_slime", "紫史莱姆" ],
[ "snow_slime", "雪史莱姆" ],
[ "tainted_slime", "腐化史莱姆" ],
[ "magma_slime", "岩浆史莱姆" ],
[ "phantom", "幻翼" ],
[ "eagle", "老鹰" ],
[ "magma_birdo", "烈焰鸟" ],
[ "meteor", "陨石怪" ],
[ "shulker", "潜影贝" ],
[ "evoker", "唤魔者" ],
[ "wither_skeleton", "凋灵骷髅" ],
[ "ender_dragon", "末影龙" ],
[ "light_blue_butterfly", "浅蓝色蝴蝶" ],
[ "yellow_butterfly", "黄蝴蝶" ],
[ "red_butterfly", "红蝴蝶" ],
[ "worm_head", "地狱毁灭者" ],
[ "worm_body", "地狱毁灭者" ],
[ "worm_tail", "地狱毁灭者" ],
[ "vine_man_eater_head", "食人蛇" ],
[ "vine_man_eater_body", "食人蛇" ],
[ "vine_man_eater_tail", "食人蛇" ],
[ "snow_queen", "冰雪女王" ],
[ "small_hell_eater", "地狱啃食者" ],
[ "snow_guardian", "冰雪守卫" ],
[ "snow_guardian_archer", "冰雪守卫弓箭手" ],
[ "small_fire_hell_eater", "火焰啃食者" ]
],
"projectiles": [
[ "wooden_arrow", "木箭" ],
[ "lighting_arrow", "光灵箭" ],
[ "star_arrow", "坠星箭" ],
[ "blood_arrow", "血腥箭" ],
[ "ice_arrow", "冰霜箭" ],
[ "sword_arrow", "剑气" ],
[ "air_bullet", "空气弹" ],
[ "small_air_bullet", "空气弹" ],
[ "amethyst_magic", "紫水晶魔法" ],
[ "star", "星星魔法" ],
[ "ice_magic", "冰霜魔法" ],
[ "shadow_magic", "影流魔法" ],
[ "water_magic", "水魔法" ],
[ "fire_magic", "火焰魔法" ],
[ "crystal_magic", "水晶魔法" ],
[ "ice_bullet", "冰弹" ],
[ "boomerang", "回旋镖" ],
[ "wooden_boomerang", "木制回旋镖" ],
[ "fire_boomerang", "烈焰回旋镖" ],
[ "rocket", "火箭弹" ],
[ "blaze_rod", "烈焰防护盾" ],
[ "fire_charge", "火球" ],
[ "shulker_bullet", "跟踪魔法" ],
[ "bullet", "子弹" ],
[ "gun_fire", "火焰" ],
[ "bullet_laser", "激光" ],
[ "bullet_super", "子弹" ],
[ "tnt", "TNT" ],
[ "bomb", "炸弹" ],
[ "grenade", "手榴弹" ],
[ "glow_bomb", "照明炸弹" ],
[ "glow_ball", "光球" ],
[ "snow_flake", "雪花" ]
],
"items": [
[ "stone_axe", "石斧", "石制的斧头,比木制的更高效" ],
[ "dirt", "泥土", "大量覆盖在地表的方块" ],
[ "stone", "石头", "表面更平滑的石头" ],
[ "cobblestone", "圆石", "基础石制材料,比石头稍稍粗糙" ],
[ "stick", "木棍", "这是一根木制的棍子" ],
[ "gravel", "沙砾", "混杂着各种杂质的沙砾" ],
[ "sand", "沙子", "松软的沙子,玻璃的来源" ],
[ "ore_coal", "煤矿石", "矿物原矿,需要进一步加工" ],
[ "ore_iron", "铁矿石", "矿物原矿,需要进一步加工" ],
[ "ore_gold", "金矿石", "矿物原矿,需要进一步加工" ],
[ "ore_lapis", "青金石矿石", "矿物原矿,需要进一步加工" ],
[ "ore_redstone", "红石矿石", "矿物原矿,需要进一步加工" ],
[ "ore_diamond", "钻石矿石", "矿物原矿,需要进一步加工" ],
[ "ore_emerald", "绿宝石矿石", "矿物原矿,需要进一步加工" ],
[ "stone_pickaxe", "石镐", "石制的镐子" ],
[ "stone_sword", "石剑", "石头打造而成的剑" ],
[ "furnace", "熔炉", "烧炼或者烹饪物品" ],
[ "chest", "箱子", "存储物品" ],
[ "oak_plank", "橡木木板", "常用的木制建筑材料" ],
[ "grass_axe", "杂草斧", "最初级的斧头,具有无尽的再生能力" ],
[ "grass_pickaxe", "杂草镐", "最初级的镐子,具有无尽的再生能力" ],
[ "grass_sword", "杂草剑", "一把弱不禁风的杂草剑" ],
[ "iron_ingot", "铁锭", "" ],
[ "gold_ingot", "金锭", "" ],
[ "redstone_ingot", "红石锭", "" ],
[ "copper_ingot", "铜锭", "" ],
[ "tin_ingot", "锡锭", "" ],
[ "bronze_ingot", "青铜锭", "" ],
[ "lead_ingot", "铅锭", "" ],
[ "silver_ingot", "银锭", "" ],
[ "steel_ingot", "钢锭", "" ],
[ "lithium_ingot", "锂锭", "" ],
[ "beryllium_ingot", "铍锭", "" ],
[ "sodium_ingot", "钠锭", "" ],
[ "magnesium_ingot", "镁锭", "" ],
[ "aluminum_ingot", "铝锭", "" ],
[ "titanium_ingot", "钛锭", "" ],
[ "vanadium_ingot", "钒锭", "" ],
[ "chromium_ingot", "铬锭", "" ],
[ "manganese_ingot", "锰锭", "" ],
[ "cobalt_ingot", "钴锭", "" ],
[ "nickel_ingot", "镍锭", "" ],
[ "zinc_ingot", "锌锭", "" ],
[ "gallium_ingot", "镓锭", "" ],
[ "yttrium_ingot", "钇锭", "" ],
[ "niobium_ingot", "铌锭", "" ],
[ "molybdenum_ingot", "钼锭", "" ],
[ "palladium_ingot", "钯锭", "" ],
[ "indium_ingot", "铟锭", "" ],
[ "antimony_ingot", "锑锭", "" ],
[ "tantalum_ingot", "钽锭", "" ],
[ "wolfram_ingot", "钨锭", "" ],
[ "rhenium_ingot", "铼锭", "" ],
[ "osmium_ingot", "锇锭", "" ],
[ "iridium_ingot", "铱锭", "" ],
[ "platinum_ingot", "铂锭", "" ],
[ "bismuth_ingot", "铋锭", "" ],
[ "vibranium_ingot", "振金锭", "" ],
[ "andesite", "安山岩", "一种石头的变种,富含钙碱性" ],
[ "andesite_polished", "磨制安山岩", "抛光后的安山岩材料" ],
[ "clay", "粘土", "这是一个粘土球" ],
[ "cobblestone_mossy", "青苔圆石", "布满青苔的圆石" ],
[ "diorite", "闪长岩", "一种石头的变种" ],
[ "diorite_polished", "磨制闪长岩", "抛光后的安山岩材料" ],
[ "glass", "玻璃", "可透光的玻璃" ],
[ "granite", "花岗岩", "一种石头的变种" ],
[ "granite_polished", "磨制花岗岩", "抛光后的安山岩材料" ],
[ "ice", "冰块", "寒冷又易碎的冰块" ],
[ "ice_cobblestone", "碎冰石", "冷冻的石头,表面覆盖着坚硬的表层" ],
[ "ice_packed", "浮冰", "易碎的浮冰,内部独特的结构使得它不会融化" ],
[ "obsidian", "黑曜石", "岩浆遇水瞬间冷却形成,有着很高的硬度" ],
[ "prismarine", "海晶石", "海底遗迹的建筑材料" ],
[ "prismarine_brick", "海晶石砖", "有着锯齿条纹的海晶石砖" ],
[ "prismarine_dark", "暗海晶石", "暗色的海晶石,有着网格状图案" ],
[ "red_sand", "红沙", "富含氧化铁的红色沙子" ],
[ "red_sand_carved", "錾制红沙石", "雕刻过的红沙石砖块" ],
[ "red_sand_smooth", "平滑沙石", "表面平滑的红沙石砖块" ],
[ "sandstone", "沙石", "硬质的沙子" ],
[ "sandstone_carved", "錾制沙石", "雕刻过的沙石砖块" ],
[ "sandstone_smooth", "平滑沙石", "表面平滑的沙石砖块" ],
[ "snow", "雪块", "松软的雪块" ],
[ "stone_brick", "石砖", "一种建筑用石制材料" ],
[ "stone_brick_carved", "錾制石砖", "雕刻过的石制建筑材料" ],
[ "stone_brick_cracked", "裂石砖", "布满裂痕的石制建筑材料" ],
[ "stone_brick_mossy", "苔石砖", "布满青苔的石制建筑材料" ],
[ "bucket_empty", "桶", "一个空桶,可以盛放液体" ],
[ "bucket_water", "水桶", "一个装满水的桶, 左键以倒出水" ],
[ "bucket_lava", "岩浆桶", "一个装满岩浆的桶, 左键以倒出岩浆" ],
[ "bucket_milk", "牛奶桶", "一个装满牛奶的桶, 饮用牛奶可解除所有状态" ],
[ "snowball", "雪球", "圆乎乎的雪球" ],
[ "vine", "藤蔓", "这是一根藤蔓" ],
[ "sugar_cane", "甘蔗", "制造蔗糖的原料" ],
[ "suger", "糖", "尝起来甜甜的" ],
[ "paper", "纸", "一张白纸" ],
[ "leather", "皮革", "动物的毛皮" ],
[ "book", "书", "这是一本书" ],
[ "wheat", "小麦", "可加工成各种主食" ],
[ "bread", "面包", "甜甜的面包" ],
[ "bone", "骨头", "一根骨头" ],
[ "bone_meal", "骨粉", "一撮骨头粉,可以用来催熟农作物" ],
[ "crafting_table", "合成台", "使用 3x3 的方阵来合成更多的物品" ],
[ "torch", "火把", "基础而廉价的照明工具" ],
[ "coal", "煤炭", "" ],
[ "charcoal", "木炭", "" ],
[ "string", "线", "一根长长的细线" ],
[ "wooden_bow", "木弓", "木制弓,适合远程攻击" ],
[ "flint", "燧石", "尖锐的燧石" ],
[ "feather", "羽毛", "这是一根羽毛" ],
[ "wooden_arrow", "木箭", "木制的箭" ],
[ "rocket_launcher", "火箭发射器", "摧毁一切!!!!" ],
[ "redstone_lamp", "红石灯", "充能后照亮周围环境" ],
[ "red_wire", "红色红石线缆", "放置以连接红石电路" ],
[ "clay_block", "粘土块", "最具用途的建筑材料来源" ],
[ "brick", "红砖方块", "最具用途的建筑材料" ],
[ "spruce_plank", "云杉木板", "常用的木制建筑材料" ],
[ "birch_plank", "桦树木板", "常用的木制建筑材料" ],
[ "jungle_plank", "丛林木板", "常用的木制建筑材料" ],
[ "acacia_plank", "金合欢木板", "常用的木制建筑材料" ],
[ "dark_oak_plank", "深色橡木木板", "常用的木制建筑材料" ],
[ "block_iron", "铁块", "铁锭压制而成的块" ],
[ "block_gold", "金块", "金锭压制而成的块" ],
[ "block_coal", "煤块", "煤炭压制而成的煤块,有着很大的燃值" ],
[ "block_diamond", "钻石块", "钻石制成的方块" ],
[ "block_emerald", "绿宝石块", "绿宝石制成的方块" ],
[ "block_lapis", "青金石块", "青金石制成的方块" ],
[ "block_redstone", "红石块", "红石压制而成的方块" ],
[ "bone_block", "骨块", "钙质丰富的方块" ],
[ "red_brick", "红砖", "粘土烧成的红色砖块" ],
[ "brown_mushroom_block", "棕色蘑菇块", "巨型棕色蘑菇的伞块" ],
[ "coarse_dirt", "灰化土", "泥土的变种,有着较强的酸性" ],
[ "cobblestone_fence", "圆石墙", "石制的栅栏" ],
[ "end_stone", "末地石", "末地的主要构成方块" ],
[ "end_stone_brick", "末地石砖", "末地石打造的砖块" ],
[ "farmland", "耕地", "可以在上面播种与收获作物" ],
[ "fence_oak", "橡木栅栏", "木制的栅栏" ],
[ "fence_birch", "桦树栅栏", "木制的栅栏" ],
[ "fence_spruce", "云杉栅栏", "木制的栅栏" ],
[ "fence_jungle", "丛林栅栏", "木制的栅栏" ],
[ "fence_acacia", "金合欢栅栏", "木制的栅栏" ],
[ "fence_dark_oak", "深色橡木栅栏", "木制的栅栏" ],
[ "fence_nether", "地狱栅栏", "地狱的深黑色栅栏" ],
[ "glowstone", "萤石", "会发光的石头" ],
[ "hay_bale", "干草块", "一捆小麦" ],
[ "ice_brick", "冰砖", "冰块做成的砖块" ],
[ "iron_bar", "铁栅栏", "铁窗" ],
[ "magma_block", "岩浆块", "固态岩浆" ],
[ "mossy_cobblestone_fence", "苔石墙", "布满青苔的石制栅栏" ],
[ "mushroom_stem", "蘑菇梗", "巨型蘑菇的梗" ],
[ "netherrack", "地狱岩", "地狱的主要方块" ],
[ "nether_brick_block", "地狱砖", "深黑色的地狱砖块" ],
[ "purpur_block", "紫珀块", "紫珀制成的方块" ],
[ "red_mushroom_block", "红蘑菇块", "巨型红蘑菇的伞块" ],
[ "red_nether_brick", "红地狱砖", "深红色的地狱砖块" ],
[ "red_sand_stone", "红沙石", "硬质的红沙" ],
[ "sea_lantern", "海晶灯", "海中发光的方块" ],
[ "slime_block", "史莱姆块", "黏糊糊的明胶方块" ],
[ "snow_brick", "雪砖", "硬化的雪砖块" ],
[ "soul_sand", "灵魂沙", "脆弱的沙块,内部似乎封印着灵魂" ],
[ "sponge", "海绵", "蓬松的海绵块,能够大量吸收水分" ],
[ "wet_sponge", "湿海绵", "吸过水的饱和海绵,烘干后可以循环使用" ],
[ "terracotta_white", "白色陶瓦", "坚硬的陶瓦" ],
[ "terracotta_orange", "橙色陶瓦", "坚硬的陶瓦" ],
[ "terracotta_magenta", "品红色陶瓦", "坚硬的陶瓦" ],
[ "terracotta_light_blue", "淡蓝色陶瓦", "坚硬的陶瓦" ],
[ "terracotta_yellow", "黄色陶瓦", "坚硬的陶瓦" ],
[ "terracotta_lime", "浅绿色陶瓦", "坚硬的陶瓦" ],
[ "terracotta_pink", "粉红色陶瓦", "坚硬的陶瓦" ],
[ "terracotta_gray", "灰色陶瓦", "坚硬的陶瓦" ],
[ "terracotta_light_gray", "浅灰色陶瓦", "坚硬的陶瓦" ],
[ "terracotta_cyan", "青色陶瓦", "坚硬的陶瓦" ],
[ "terracotta_purple", "紫色陶瓦", "坚硬的陶瓦" ],
[ "terracotta_blue", "蓝色陶瓦", "坚硬的陶瓦" ],
[ "terracotta_brown", "棕色陶瓦", "坚硬的陶瓦" ],
[ "terracotta_green", "绿色陶瓦", "坚硬的陶瓦" ],
[ "terracotta_red", "红色陶瓦", "坚硬的陶瓦" ],
[ "terracotta_black", "黑色陶瓦", "坚硬的陶瓦" ],
[ "tnt", "TNT", "被激活后会发生爆炸" ],
[ "wood_oak", "橡木木头", "刚砍下来的新鲜原木" ],
[ "wood_birch", "桦树木头", "刚砍下来的新鲜原木" ],
[ "wood_spruce", "云杉木头", "刚砍下来的新鲜原木" ],
[ "wood_jungle", "丛林木头", "刚砍下来的新鲜原木" ],
[ "wood_acacia", "金合欢木头", "刚砍下来的新鲜原木" ],
[ "wood_dark_oak", "深色橡木木头", "刚砍下来的新鲜原木" ],
[ "fishing_rod", "钓鱼竿", "愿者上钩" ],
[ "wood_stripped_oak", "橡木去皮木头", "剥掉了树皮的原木" ],
[ "wood_stripped_birch", "桦树去皮木头", "剥掉了树皮的原木" ],
[ "wood_stripped_spruce", "云杉去皮木头", "剥掉了树皮的原木" ],
[ "wood_stripped_jungle", "丛林去皮木头", "剥掉了树皮的原木" ],
[ "wood_stripped_acacia", "金合欢去皮木头", "剥掉了树皮的原木" ],
[ "wood_stripped_dark_oak", "深色橡木去皮木头", "剥掉了树皮的原木" ],
[ "allium", "绒球葱", "一种小型花" ],
[ "anvil", "铁砧", "用来修复破损的工具" ],
[ "azure_bluet", "茜草花", "一种小型花" ],
[ "wooden_bed_red", "红色床", "这是一张床,用于重置重生点" ],
[ "blue_orchid", "兰花", "一种小型花" ],
[ "book_block", "书堆", "知识的海洋" ],
[ "bookcase_oak", "橡木书架", "摆放着很多书籍的书架,可存储物品" ],
[ "brewing_stand", "酿造台", "酿造各种效果的药水" ],
[ "brown_mushroom", "蘑菇", "一朵棕色蘑菇" ],
[ "cake", "蛋糕", "奶油味的蛋糕,可切成蛋糕片食用" ],
[ "candle", "蜡烛", "这是一支蜡烛" ],
[ "candle_holder", "蜡烛台", "西方特色的蜡烛台" ],
[ "cauldron", "炼药锅", "这是一个炼药锅" ],
[ "chair_oak", "橡木椅子", "一张木制的椅子" ],
[ "chandeliers", "水晶吊灯", "明亮而奢华的水晶吊灯" ],
[ "stone_chest", "石制箱子", "存放物品" ],
[ "cobweb", "蜘蛛网", "一张蜘蛛网,能够困住各种生物" ],
[ "dandelion", "蒲公英", "一种小型花" ],
[ "daylight_sensor", "日光传感器", "太阳光照射下持续输出红石信号" ],
[ "daylight_sensor_inverted", "夜光传感器", "月光照射下持续输出红石信号" ],
[ "dispenser", "发射器", "红石信号激活时发射一个物品" ],
[ "ender_chest", "末影箱", "量子效应使得所有的末影箱共用一个空间" ],
[ "fern", "蕨类", "一种孢子植物" ],
[ "fire_lamp", "火焰吊灯", "提供明亮的照明" ],
[ "wooden_pressure_plate", "木制压力板", "踩下后激活红石信号" ],
[ "stone_pressure_plate", "石制压力板", "踩下后激活红石信号" ],
[ "iron_pressure_plate", "铁制压力板", "踩下后激活红石信号" ],
[ "golden_pressure_plate", "金制压力板", "踩下后激活红石信号" ],
[ "jukebox", "唱片机", "放入唱片,享受音乐" ],
[ "grass", "草", "野火烧不尽,春风吹又生" ],
[ "iron_door", "铁门", "房子必不可少的部分" ],
[ "lilac", "欧丁香", "一种大型植物" ],
[ "orange_tulip", "橙色郁金香", "一种小型花" ],
[ "red_tulip", "红色郁金香", "一种小型花" ],
[ "white_tulip", "白色郁金香", "一种小型花" ],
[ "pink_tulip", "粉红色郁金香", "一种小型花" ],
[ "painting_2x2", "画 2x2", "目前收录MC原版画作,欢迎各位大大投稿 0w0" ],
[ "peony", "牡丹", "一种大型植物" ],
[ "poppy", "虞美人", "一种小型花" ],
[ "pumpkin", "南瓜", "完整的南瓜" ],
[ "pumpkin_carved", "雕刻的南瓜", "雕刻有万圣节图案的南瓜" ],
[ "red_mushroom", "红蘑菇", "一朵红色的蘑菇" ],
[ "rose_bush", "玫瑰丛", "一种大型植物" ],
[ "sapling_oak", "橡木树苗", "一种树苗,种植后会成长为橡树" ],
[ "sapling_birch", "桦树树苗", "一种树苗,种植后会成长为桦木树" ],
[ "sapling_jungle", "丛林树苗", "一种树苗,种植后会成长为丛林树" ],
[ "sapling_spruce", "云杉树苗", "一种树苗,种植后会成长为云杉树" ],
[ "sapling_acacia", "金合欢树苗", "一种树苗,种植后会成长为金合欢树" ],
[ "sapling_dark_oak", "深色橡木树苗", "一种树苗,种植后会成长为深色橡树" ],
[ "sign", "牌子", "暂不可用" ],
[ "stone_button", "石制开关", "控制红石电路的激活状态" ],
[ "wooden_button", "木制开关", "控制红石电路的激活状态" ],
[ "sunflower", "向日葵", "一种大型植物" ],
[ "watermelon", "西瓜", "一个完整的西瓜,看起来十分饱满甜美" ],
[ "wooden_door_oak", "橡木门", "房子必不可少的部分" ],
[ "wooden_door_birch", "桦树门", "房子必不可少的部分" ],
[ "wooden_door_spruce", "云杉门", "房子必不可少的部分" ],
[ "wooden_door_jungle", "丛林门", "房子必不可少的部分" ],
[ "wooden_door_acacia", "金合欢门", "房子必不可少的部分" ],
[ "wooden_door_dark_oak", "深色橡木门", "房子必不可少的部分" ],
[ "table_oak", "橡木木桌", "一张木桌" ],
[ "cabinet_oak", "橡木桌柜", "一张桌柜,可存储物品" ],
[ "apple", "苹果", "一个熟透的红苹果" ],
[ "baked_potato", "烤马铃薯", "烤熟了的马铃薯" ],
[ "blaze_powder", "烈焰粉", "药水酿造的热量来源" ],
[ "blaze_rod", "烈焰棒", "这是一根烫手的烈焰棒" ],
[ "bowl", "碗", "又大又圆的碗" ],
[ "cake_piece", "蛋糕片", "一片蛋糕" ],
[ "carrot", "胡萝卜", "富含维生素的胡萝卜" ],
[ "chorus_fruit", "紫颂果", "紫颂树的果实" ],
[ "cooked_chicken", "烤火鸡", "烤熟的火鸡,鸡肉味嘎嘣脆" ],
[ "cookie", "曲奇", "一块曲奇饼干" ],
[ "diamond", "钻石", "" ],
[ "dried_kelp", "干海带", "硬邦邦的干燥海带" ],
[ "egg", "蛋", "这是一个蛋" ],
[ "emerald", "绿宝石", "" ],
[ "ender_eye", "末影之眼", "你感受到了有什么东西在注视着你" ],
[ "ender_pearl", "末影珍珠", "这是一颗释放着未知魔法能量的珍珠" ],
[ "fermented_spider_eye", "发酵蜘蛛眼", "发酵过的蜘蛛眼" ],
[ "ghast_tear", "恶灵之泪", "这是恶灵的泪水晶体" ],
[ "glass_bottle", "玻璃瓶", "透明的玻璃瓶子" ],
[ "glistering_melon_slice", "闪烁的西瓜片", "用于酿造,不可食用" ],
[ "glowstone_dust", "萤石粉", "发光的萤石粉末" ],
[ "golden_apple", "金苹果", "食用后有特殊效果加成" ],
[ "golden_carrot", "金胡萝卜", "食用后有特殊效果加成" ],
[ "gunpowder", "火药", "易燃的硫化混合物" ],
[ "heart_of_sea", "海洋之心", "海洋的精华" ],
[ "ink_sac", "墨囊", "这是一根墨鱼的触须" ],
[ "lapis_lazuli", "青金石", "" ],
[ "magma_cream", "岩浆膏", "一种岩浆胶状物" ],
[ "melon_seed", "西瓜种子", "西瓜的种子,播种在耕地上可成长为西瓜" ],
[ "melon_slice", "西瓜片", "这是一片西瓜,夏日必备" ],
[ "mushroom_stew", "蘑菇煲", "一碗蘑菇汤" ],
[ "nether_brick", "地狱砖头", "一个地狱砖头,可堆砌成地狱砖块" ],
[ "nether_star", "下界之星", "凋零的掉落物" ],
[ "nether_wart", "地狱疣", "地狱的特产作物" ],
[ "phantom_membrane", "幻翼翅", "一个透明的幻翼翅膀" ],
[ "popped_chorus_fruits", "爆浆紫颂果", "果汁真丰富" ],
[ "potato", "马铃薯", "生的土豆" ],
[ "prismarine_crystals", "海晶砂粒", "一块海晶的砂粒" ],
[ "prismarine_shard", "海晶碎片", "一块海晶的碎片" ],
[ "quartz", "石英", "" ],
[ "pufferfish", "河豚", "一只味道十分甜美的河豚" ],
[ "pumpkin_pie", "南瓜派", "一个南瓜饼" ],
[ "pumpkin_seed", "南瓜种子", "南瓜的种子,播种在耕地上可成长为南瓜" ],
[ "raw_beef", "生牛肉", "一块生的牛肉,烤过更好吃" ],
[ "raw_chicken", "生鸡肉", "生的鸡肉,不烤熟了再吃吗?" ],
[ "scute", "鳞甲", "乌龟的鳞甲片" ],
[ "seed", "小麦种子", "小麦的种子,播种在耕地上来种植小麦" ],
[ "shulker_shell", "潜影贝壳", "一块潜影贝的坚硬外壳" ],
[ "slimeball", "史莱姆球", "看起来很好吃的样子" ],
[ "steak", "牛排", "看起来很好吃的样子" ],
[ "beetroot", "甜菜根", "这是一个甜菜根" ],
[ "raw_cod", "生鳕鱼", "一条活蹦乱跳的鳕鱼" ],
[ "cooked_cod", "熟鳕鱼", "一条美味的鳕鱼" ],
[ "raw_mutton", "生羊肉", "生的羊肉" ],
[ "cooked_mutton", "熟羊肉", "熟透了的羊肉" ],
[ "raw_porkchop", "生猪肉", "这是一片生的猪肉" ],
[ "cooked_porkchop", "猪排", "一片美味的猪排" ],
[ "raw_rabbit", "生兔肉", "生的兔子肉" ],
[ "cooked_rabbit", "熟兔肉", "熟透了的兔子肉" ],
[ "raw_salmon", "生鲑鱼", "一条活蹦乱跳的鲑鱼" ],
[ "cooked_salmon", "熟鲑鱼", "一条美味的三文鱼" ],
[ "dye_white", "白色染料", "一种染料,可用来染色" ],
[ "dye_orange", "橙色染料", "一种染料,可用来染色" ],
[ "dye_magenta", "品红色染料", "一种染料,可用来染色" ],
[ "dye_light_blue", "淡蓝色染料", "一种染料,可用来染色" ],
[ "dye_yellow", "黄色染料", "一种染料,可用来染色" ],
[ "dye_lime", "黄绿色染料", "一种染料,可用来染色" ],
[ "dye_pink", "粉红色染料", "一种染料,可用来染色" ],
[ "dye_gray", "灰色染料", "一种染料,可用来染色" ],
[ "dye_light_gray", "浅灰色染料", "一种染料,可用来染色" ],
[ "dye_cyan", "青色染料", "一种染料,可用来染色" ],
[ "dye_purple", "紫色染料", "一种染料,可用来染色" ],
[ "dye_blue", "蓝色染料", "一种染料,可用来染色" ],
[ "dye_brown", "棕色染料", "一种染料,可用来染色" ],
[ "dye_green", "绿色染料", "一种染料,可用来染色" ],
[ "dye_red", "红色染料", "一种染料,可用来染色" ],
[ "dye_black", "黑色染料", "一种染料,可用来染色" ],
[ "fire_charge", "火焰弹", "一颗燃烧的火焰弹" ],
[ "firework_rocket", "烟花火箭", "这是一个烟花火箭" ],
[ "iron_nugget", "铁粒", "" ],
[ "gold_nugget", "金粒", "" ],
[ "kelp", "海带", "一根长长的海带" ],
[ "lighter", "打火石", "让火焰燃烧得更猛烈些吧!" ],
[ "map_paper", "地图", "记录每个区块的地图" ],
[ "nautilus_shell", "鹦鹉海螺", "为什么不问问神奇的鹦鹉海螺呢" ],
[ "rabbit_foot", "兔子脚", "兔子健壮的脚" ],
[ "rabbit_hide", "兔子皮", "兔子毛茸茸的毛皮" ],
[ "redstone", "红石", "" ],
[ "rotten_flesh", "腐肉", "已经腐烂很久的肉块" ],
[ "spider_eye", "蜘蛛眼", "一只蜘蛛的眼睛" ],
[ "totem_of_undying", "不死图腾", "使用它来逃离一次死亡" ],
[ "wool_white", "白色羊毛", "柔软有弹性的羊毛" ],
[ "wool_orange", "橙色羊毛", "柔软有弹性的羊毛" ],
[ "wool_magenta", "品红色羊毛", "柔软有弹性的羊毛" ],
[ "wool_light_blue", "淡蓝色羊毛", "柔软有弹性的羊毛" ],
[ "wool_yellow", "黄色羊毛", "柔软有弹性的羊毛" ],
[ "wool_lime", "浅绿色羊毛", "柔软有弹性的羊毛" ],
[ "wool_pink", "粉红色羊毛", "柔软有弹性的羊毛" ],
[ "wool_gray", "灰色羊毛", "柔软有弹性的羊毛" ],
[ "wool_light_gray", "浅灰色羊毛", "柔软有弹性的羊毛" ],
[ "wool_cyan", "青色羊毛", "柔软有弹性的羊毛" ],
[ "wool_purple", "紫色羊毛", "柔软有弹性的羊毛" ],
[ "wool_blue", "蓝色羊毛", "柔软有弹性的羊毛" ],
[ "wool_brown", "棕色羊毛", "柔软有弹性的羊毛" ],
[ "wool_green", "绿色羊毛", "柔软有弹性的羊毛" ],
[ "wool_red", "红色羊毛", "柔软有弹性的羊毛" ],
[ "wool_black", "黑色羊毛", "柔软有弹性的羊毛" ],
[ "wooden_axe", "木斧", "木制的斧头" ],
[ "wooden_pickaxe", "木镐", "木制的镐子" ],
[ "wooden_sword", "木剑", "木头制成的剑" ],
[ "platform_oak", "橡木平台", "一种木制的平台" ],
[ "platform_birch", "桦树平台", "一种木制的平台" ],
[ "platform_spruce", "云杉平台", "一种木制的平台" ],
[ "platform_jungle", "丛林平台", "一种木制的平台" ],
[ "platform_acacia", "金合欢平台", "一种木制的平台" ],
[ "platform_dark_oak", "深色橡木平台", "一种木制的平台" ],
[ "iron_axe", "铁斧", "铁制的斧头" ],
[ "iron_pickaxe", "铁镐", "铁制的镐子" ],
[ "iron_sword", "铁剑", "铁器打造成的剑" ],
[ "golden_axe", "金斧", "金制的斧头" ],
[ "golden_pickaxe", "金镐", "金制的镐子" ],
[ "golden_sword", "金剑", "黄金炼成的剑" ],
[ "diamond_axe", "钻石斧", "钻石制成的斧头" ],
[ "diamond_pickaxe", "钻石镐", "钻石制成的镐子" ],
[ "diamond_sword", "钻石剑", "锋利的钻石剑" ],
[ "leather_helmet", "皮革帽子", "皮革制成的帽子" ],
[ "leather_chestplate", "皮革衣服", "皮革制成的衣服" ],
[ "leather_leggings", "皮革裤子", "皮革制成的裤子" ],
[ "iron_helmet", "铁头盔", "铁皮制成的头盔" ],
[ "iron_chestplate", "铁胸甲", "铁皮制成的胸甲" ],
[ "iron_leggings", "铁护胫", "铁皮制成的裤甲" ],
[ "golden_helmet", "金头盔", "黄金制成的头盔" ],
[ "golden_chestplate", "金胸甲", "黄金制成的胸甲" ],
[ "golden_leggings", "金护胫", "黄金制成的裤甲" ],
[ "diamond_helmet", "钻石头盔", "钻石制成的头盔" ],
[ "diamond_chestplate", "钻石胸甲", "钻石制成的胸甲" ],
[ "diamond_leggings", "钻石护胫", "钻石制成的裤甲" ],
[ "potion_water", "水瓶", "一瓶水,可酿造为各种效果的药水" ],
[ "potion_awkward", "粗制的药水", "一瓶粗制的药水,将不同材料提炼后可得到不同效果的药水" ],
[ "potion_strength", "力量药水", "一瓶充满力量的药水" ],
[ "potion_strength_long", "长效力量药水", "一瓶充满力量的药水" ],
[ "potion_swiftness", "迅捷药水", "一瓶饮用后行动更快的药水" ],
[ "potion_swiftness_long", "长效迅捷药水", "一瓶饮用后行动更快的药水" ],
[ "potion_slowness", "迟缓药水", "一瓶慢节奏的药水" ],
[ "potion_slowness_long", "长效迟缓药水", "一瓶慢节奏的药水" ],
[ "potion_leaping", "跳跃药水", "一瓶提高跳跃力的药水" ],
[ "potion_leaping_long", "长效跳跃药水", "一瓶提高跳跃力的药水" ],
[ "potion_healing", "治疗药水", "一瓶瞬间恢复生命值的药水" ],
[ "potion_healing_super", "强力治疗药水", "一瓶瞬间恢复生命值的药水" ],
[ "potion_harming", "伤害药水", "一瓶含有各种有害物质的药水" ],
[ "potion_harming_super", "强力伤害药水", "一瓶含有各种有害物质的药水" ],
[ "potion_poison", "剧毒药水", "一瓶有毒的药水" ],
[ "potion_poison_long", "长效剧毒药水", "一瓶有毒的药水" ],
[ "potion_regeneration", "再生药水", "一瓶持续提高生命力的药水" ],
[ "potion_regeneration_long", "长效再生药水", "一瓶持续提高生命力的药水" ],
[ "potion_fire_resistance", "抗火药水", "一瓶饮用后免疫火焰和岩浆的药水" ],
[ "potion_fire_resistance_long", "长效抗火药水", "一瓶饮用后免疫火焰和岩浆的药水" ],
[ "potion_water_breathing", "水肺药水", "一瓶饮用后可在水中呼吸的药水" ],
[ "potion_water_breathing_long", "长效水肺药水", "一瓶饮用后可在水中呼吸的药水" ],
[ "potion_night_vision", "夜视药水", "一瓶可以看透黑暗的药水" ],
[ "potion_night_vision_long", "长效夜视药水", "一瓶可以看透黑暗的药水" ],
[ "potion_invisibility", "隐身药水", "一瓶不科学的药水" ],
[ "potion_invisibility_long", "长效隐身药水", "一瓶不科学的药水" ],
[ "potion_slow_falling", "缓降药水", "一瓶饮用后缓慢降落的药水" ],
[ "potion_slow_falling_long", "长效缓降药水", "一瓶饮用后缓慢降落的药水" ],
[ "potion_weakness", "虚弱药水", "一瓶饮用后会虚脱的药水" ],
[ "potion_weakness_long", "长效虚弱药水", "一瓶饮用后会虚脱的药水" ],
[ "enchantment_table", "附魔台", "给工具附魔!" ],
[ "enchanted_book", "附魔书", "一本写满了魔咒的书" ],
[ "shears", "剪刀", "用来剪羊毛或雕刻" ],
[ "shotgun", "霰弹枪", "强力的霰弹枪" ],
[ "stone_hoe", "石锄", "用于开垦土地" ],
[ "green_wire", "绿色红石线缆", "放置以连接红石电路" ],
[ "blue_wire", "蓝色红石线缆", "放置以连接红石电路" ],
[ "yellow_wire", "黄色红石线缆", "放置以连接红石电路" ],
[ "wire_cutter", "红石线钳", "用于移除红石线缆" ],
[ "lever", "拉杆", "控制红石电路的激活状态" ],
[ "redstone_torch", "红石火把", "右键以激活或取消激活" ],
[ "bomb", "炸弹", "可以破坏图格的炸弹" ],
[ "grenade", "手榴弹", "对敌人造成伤害,不会破坏图格" ],
[ "handgun", "手枪", "一把手枪" ],
[ "rifle", "步枪", "一把步枪" ],
[ "fire_gun", "喷火枪", "一把喷火枪" ],
[ "super_iron_sword", "锻铁剑", "铁器打造成的剑" ],
[ "super_golden_sword", "宽金剑", "黄金炼成的剑" ],
[ "super_diamond_sword", "加强钻石剑", "锋利的钻石剑" ],
[ "copper_sword", "铜剑", "铜器打造成的剑" ],
[ "super_copper_sword", "宽铜剑", "铜器打造成的剑" ],
[ "tin_sword", "锡剑", "用锡打造成的剑" ],
[ "super_tin_sword", "宽锡剑", "用锡打造成的剑" ],
[ "lead_sword", "铅剑", "用铅打造成的剑" ],
[ "super_lead_sword", "大铅剑", "用铅打造成的剑" ],
[ "silver_sword", "银剑", "用银打造成的剑" ],
[ "super_silver_sword", "长银剑", "用银打造成的剑" ],
[ "bronze_sword", "青铜剑", "用青铜打造成的剑" ],
[ "super_bronze_sword", "宽青铜剑", "用青铜打造成的剑" ],
[ "steel_sword", "钢剑", "用钢打造成的剑" ],
[ "super_steel_sword", "长钢剑", "用钢打造成的剑" ],
[ "ghost_sword", "日光刀", "注入阳光能量的刀(鬼灭之刃?)" ],
[ "glow_ball", "烈焰光球", "提供较长时间的照明" ],
[ "glow_bomb", "强光炸弹", "对敌人造成伤害,不会破坏图格,提供短暂强光照明" ],
[ "lighting_bow", "光灵弓", "射出光灵箭,命中时提供照明加成" ],
[ "fire_bullet", "土子弹", "最普通的子弹" ],
[ "iron_bullet", "铁子弹", "铁质的子弹" ],
[ "silver_bullet", "银子弹", "银制的子弹" ],
[ "lighting_arrow", "光灵箭", "发光的箭" ],
[ "cross_bow", "连弩", "快速发射弓箭" ],
[ "shot_bow", "散射弩", "快速发射多个弓箭" ],
[ "super_cross_bow", "强化连弩", "快速发射弓箭" ],
[ "boomerang", "回旋镖", "扔出去然后飞回来!" ],
[ "wooden_boomerang", "木制回旋镖", "扔出去然后飞回来!" ],
[ "star_arrow", "坠星箭", "发射的时候再次坠落一支箭" ],
[ "fire_boomerang", "烈焰回旋镖", "着火的回旋镖!" ],
[ "blood_arrow", "血腥箭", "持续吸血" ],
[ "blood_bow", "血腥弓", "射出血腥箭" ],
[ "blue_stone_bow", "蓝石弓", "具有更快的攻速和攻击频率" ],
[ "ice_arrow", "冰雪箭", "散发着寒冷气息的箭" ],
[ "ice_bow", "冰雪弓", "射出冰雪箭" ],
[ "chast_bow", "跟踪剑弓", "射出跟踪剑箭" ],
[ "sword_arrow", "跟踪箭", "半辅助瞄准目标" ],
[ "air_sword", "空气剑", "斩破空气,发射空气弹" ],
[ "super_air_sword", "破隙剑", "斩破空气,发射空气弹" ],
[ "amethyst_staff", "紫水晶法杖", "一个充满魔力的法杖" ],
[ "lighting_staff", "光之法杖", "一个散发光辉的法杖" ],
[ "water_staff", "水之法杖", "一个魔法法杖" ],
[ "ice_staff", "冰霜法杖", "一个散发寒气的法杖" ],
[ "shadow_staff", "影流法杖", "一个受到黑暗魔法控制的法杖" ],
[ "red_torch", "红光火把", "散发着红色光的火把" ],
[ "yellow_torch", "黄光火把", "散发着黄色光的火把" ],
[ "blue_torch", "蓝光火把", "散发着蓝色光的火把" ],
[ "green_torch", "绿光火把", "散发着绿色光的火把" ],
[ "white_torch", "白光火把", "散发着白色光的火把" ],
[ "flesh_stone", "血石块", "由不可名状物凝固而成的方块" ],
[ "flesh_dirt", "肉块", "不知名的肉类方块" ],
[ "flesh_gut", "肠块", "不可名状的方块" ],
[ "mycelium", "菌丝", "由真菌组成的方块" ],
[ "tainted_stone", "腐化石", "受到腐化的石头" ],
[ "tainted_dirt", "腐化土", "受到腐化的泥土" ],
[ "volcano_stone", "熔岩石", "长时间熔岩接触凝结的石头" ],
[ "volcano_dirt", "熔岩泥", "松散的熔岩泥土" ],
[ "ore_tin", "锡矿石", "矿物原矿,需要进一步加工" ],
[ "ore_copper", "铜矿石", "矿物原矿,需要进一步加工" ],
[ "ore_lead", "铅矿石", "矿物原矿,需要进一步加工" ],
[ "ore_silver", "银矿石", "矿物原矿,需要进一步加工" ],
[ "bronze_helmet", "青铜头盔", "青铜制成的头盔" ],
[ "bronze_chestplate", "青铜胸甲", "青铜制成的胸甲" ],
[ "bronze_leggings", "青铜护胫", "青铜制成的护胫" ],
[ "copper_helmet", "铜头盔", "铜制成的头盔" ],
[ "copper_chestplate", "铜胸甲", "铜制成的胸甲" ],
[ "copper_leggings", "铜护胫", "铜制成的护胫" ],
[ "lead_helmet", "铅头盔", "铅制成的头盔" ],
[ "lead_chestplate", "铅胸甲", "铅制成的胸甲" ],
[ "lead_leggings", "铅护胫", "铅制成的护胫" ],
[ "nether_helmet", "下界合金头盔", "下界合金锭加固制成的头盔" ],
[ "nether_chestplate", "下界合金胸甲", "下界合金锭加固制成的胸甲" ],
[ "nether_leggings", "下界合金护胫", "下界合金锭加固制成的护胫" ],
[ "silver_helmet", "银头盔", "银器制成的头盔" ],
[ "silver_chestplate", "银胸甲", "银器制成的胸甲" ],
[ "silver_leggings", "银护胫", "银器制成的护胫" ],
[ "steel_helmet", "钢头盔", "钢制成的头盔" ],
[ "steel_chestplate", "钢胸甲", "钢制成的胸甲" ],
[ "steel_leggings", "钢护胫", "钢制成的护胫" ],
[ "tin_helmet", "锡头盔", "锡制成的头盔" ],
[ "tin_chestplate", "锡胸甲", "锡制成的胸甲" ],
[ "tin_leggings", "锡护胫", "锡制成的护胫" ],
[ "palm_plank", "棕榈木板", "常用的木制建筑材料" ],
[ "volcano_plank", "熔岩木板", "常用的木制建筑材料" ],
[ "tainted_plank", "腐化木板", "被腐化的木制建筑材料" ],
[ "wood_palm", "棕榈木头", "刚砍下来的新鲜原木" ],
[ "wood_volcano", "熔岩木头", "长期处在熔岩环境的木头" ],
[ "wood_tainted", "腐化木头", "刚砍下来的新鲜原木" ],
[ "wood_stripped_palm", "棕榈去皮木头", "剥掉了树皮的原木" ],
[ "wood_stripped_volcano", "熔岩去皮木头", "剥掉了树皮的原木" ],
[ "wood_stripped_tainted", "腐化去皮木头", "剥掉了树皮的原木" ],
[ "sapling_tainted", "腐化树苗", "一种树苗,种植后会成长为腐化树" ],
[ "sapling_palm", "棕榈树苗", "一种树苗,种植后会成长为棕榈树" ],
[ "sapling_cactus", "仙人掌", "一个小仙人掌,种植后会成长为大仙人掌" ],
[ "sapling_volcano", "熔岩树苗", "一种树苗,种植后会成长为熔岩树" ],
[ "sapling_bare_oak", "秃橡木树苗", "一种树苗,种植后会成长为秃橡木树" ],
[ "platform_palm", "棕榈平台", "一种木制的平台" ],
[ "platform_volcano", "熔岩木平台", "一种木制的平台" ],
[ "platform_tainted", "腐化木平台", "一种木制的平台" ],
[ "wooden_door_palm", "棕榈门", "房子必不可少的部分" ],
[ "wooden_door_volcano", "熔岩木门", "房子必不可少的部分" ],
[ "wooden_door_tainted", "腐化木门", "房子必不可少的部分" ],
[ "fence_palm", "棕榈栅栏", "木制的栅栏" ],
[ "fence_volcano", "熔岩木栅栏", "木制的栅栏" ],
[ "fence_tainted", "腐化木栅栏", "木制的栅栏" ],
[ "ore_ancient_debris", "远古残骸", "矿物原矿,需要进一步加工" ],
[ "block_netherite", "下界合金块", "下界合金而成的方块" ],
[ "netherite_ingot", "下界合金锭", "" ],
[ "netherite_scrap", "下界合金碎片", "用于合成下界合金锭" ],
[ "dried_kelp_block", "干海带块", "一捆干海带" ],
[ "blue_ice", "蓝冰", "比浮冰更光滑,内部独特的结构使得它能发出微弱的光芒" ],
[ "ore_nether_quartz", "下界石英矿", "矿物原矿,需要进一步加工" ],
[ "block_quartz", "石英块", "石英压缩而成的方块,常用的建筑材料" ],
[ "platform_end_stone", "末地石平台", "由末地石制作而成的平台" ],
[ "platform_nether_brick", "地狱平台", "由地狱砖制作而成的平台" ],
[ "platform_prismarine", "海晶石平台", "由海晶石制作而成的平台" ],
[ "platform_prismarine_dark", "暗海晶石平台", "由暗海晶石制作而成的平台" ],
[ "platform_purpur", "紫珀平台", "由紫珀砖制作而成的平台" ],
[ "platform_quartz", "石英平台", "由石英制作而成的平台" ],
[ "platform_red_sand_stone", "红沙石平台", "由红沙石制作而成的平台" ],
[ "platform_sandstone", "沙石平台", "由沙石制作而成的平台" ],
[ "platform_stone_brick", "石砖平台", "由石砖制作而成的平台" ],
[ "stained_glass_white", "白色染色玻璃", "这是一块染色玻璃" ],
[ "stained_glass_orange", "橙色染色玻璃", "这是一块染色玻璃" ],
[ "stained_glass_magenta", "品红色染色玻璃", "这是一块染色玻璃" ],
[ "stained_glass_light_blue", "淡蓝色染色玻璃", "这是一块染色玻璃" ],
[ "stained_glass_yellow", "黄色染色玻璃", "这是一块染色玻璃" ],
[ "stained_glass_lime", "浅绿色染色玻璃", "这是一块染色玻璃" ],
[ "stained_glass_pink", "粉红色染色玻璃", "这是一块染色玻璃" ],
[ "stained_glass_gray", "灰色染色玻璃", "这是一块染色玻璃" ],
[ "stained_glass_light_gray", "浅灰色染色玻璃", "这是一块染色玻璃" ],
[ "stained_glass_cyan", "青色染色玻璃", "这是一块染色玻璃" ],
[ "stained_glass_purple", "紫色染色玻璃", "这是一块染色玻璃" ],
[ "stained_glass_blue", "蓝色染色玻璃", "这是一块染色玻璃" ],
[ "stained_glass_brown", "棕色染色玻璃", "这是一块染色玻璃" ],
[ "stained_glass_green", "绿色染色玻璃", "这是一块染色玻璃" ],
[ "stained_glass_red", "红色染色玻璃", "这是一块染色玻璃" ],
[ "stained_glass_black", "黑色染色玻璃", "这是一块染色玻璃" ],
[ "wooden_bed_white", "白色床", "这是一张床,用于重置重生点" ],
[ "wooden_bed_orange", "橙色床", "这是一张床,用于重置重生点" ],
[ "wooden_bed_magenta", "品红色床", "这是一张床,用于重置重生点" ],
[ "wooden_bed_light_blue", "淡蓝色床", "这是一张床,用于重置重生点" ],
[ "wooden_bed_yellow", "黄色床", "这是一张床,用于重置重生点" ],
[ "wooden_bed_lime", "浅绿色床", "这是一张床,用于重置重生点" ],
[ "wooden_bed_pink", "粉红色床", "这是一张床,用于重置重生点" ],
[ "wooden_bed_gray", "灰色床", "这是一张床,用于重置重生点" ],
[ "wooden_bed_light_gray", "浅灰色床", "这是一张床,用于重置重生点" ],
[ "wooden_bed_cyan", "青色床", "这是一张床,用于重置重生点" ],
[ "wooden_bed_purple", "紫色床", "这是一张床,用于重置重生点" ],
[ "wooden_bed_blue", "蓝色床", "这是一张床,用于重置重生点" ],
[ "wooden_bed_brown", "棕色床", "这是一张床,用于重置重生点" ],
[ "wooden_bed_green", "绿色床", "这是一张床,用于重置重生点" ],
[ "wooden_bed_black", "黑色床", "这是一张床,用于重置重生点" ],
[ "jack_o_lantern", "南瓜灯", "雕刻有万圣节图案的南瓜灯" ],
[ "pumpkin_helmet", "雕刻南瓜头套", "一个南瓜头套" ],
[ "shulker_box", "潜影盒", "以物品的形式继续存放物品" ],
[ "end_rod", "末地烛", "末地的照明工具" ],
[ "lantern", "灯笼", "这是一个可以悬挂的灯笼" ],
[ "barrel", "木桶", "存储物品" ],
[ "campfire", "营火", "提供照明" ],
[ "painting_4x2", "画 4x2", "目前收录MC原版画作,欢迎各位大大投稿 0w0" ],
[ "painting_2x4", "画 2x4", "目前收录MC原版画作,欢迎各位大大投稿 0w0" ],
[ "painting_4x4", "画 4x4", "目前收录MC原版画作,欢迎各位大大投稿 0w0" ],
[ "painting_8x4", "画 2x2", "目前收录MC原版画作,欢迎各位大大投稿 0w0" ],
[ "painting_8x6", "画 8x6", "目前收录MC原版画作,欢迎各位大大投稿 0w0" ],
[ "painting_8x8", "画 8x8", "目前收录MC原版画作,欢迎各位大大投稿 0w0" ],
[ "flower_pot", "花盆", "可以放置小型花的花盆" ],
[ "flower_pot_large", "大型花盆", "可以放置大型花的花盆" ],
[ "trapped_chest", "陷阱箱", "存储物品,打开时发出红石信号" ],
[ "cocoa_bean", "可可豆", "生长在丛林木上的食物材料" ],
[ "table_spruce", "云杉木桌", "一张木桌" ],
[ "table_birch", "桦树木桌", "一张木桌" ],
[ "table_jungle", "丛林木桌", "一张木桌" ],
[ "table_acacia", "金合欢木桌", "一张木桌" ],
[ "table_dark_oak", "深色橡木木桌", "一张木桌" ],
[ "table_palm", "棕榈木桌", "一张木桌" ],
[ "table_volcano", "熔岩木木桌", "一张木桌" ],
[ "table_tainted", "腐化木木桌", "一张木桌" ],
[ "cabinet_spruce", "云杉桌柜", "一张桌柜,可存储物品" ],
[ "cabinet_birch", "桦树桌柜", "一张桌柜,可存储物品" ],
[ "cabinet_jungle", "丛林桌柜", "一张桌柜,可存储物品" ],
[ "cabinet_acacia", "金合欢桌柜", "一张桌柜,可存储物品" ],
[ "cabinet_dark_oak", "深色橡木桌柜", "一张桌柜,可存储物品" ],
[ "cabinet_palm", "棕榈桌柜", "一张桌柜,可存储物品" ],
[ "cabinet_volcano", "熔岩木桌柜", "一张桌柜,可存储物品" ],
[ "cabinet_tainted", "腐化木桌柜", "一张桌柜,可存储物品" ],
[ "chair_spruce", "云杉椅子", "一张木制的椅子" ],
[ "chair_birch", "桦树椅子", "一张木制的椅子" ],
[ "chair_jungle", "丛林椅子", "一张木制的椅子" ],
[ "chair_acacia", "金合欢椅子", "一张木制的椅子" ],
[ "chair_dark_oak", "深色橡木椅子", "一张木制的椅子" ],
[ "chair_palm", "棕榈椅子", "一张木制的椅子" ],
[ "chair_volcano", "熔岩木椅子", "一张木制的椅子" ],
[ "chair_tainted", "腐化木椅子", "一张木制的椅子" ],
[ "bookcase_spruce", "云杉书架", "摆放着很多书籍的书架,可存储物品" ],
[ "bookcase_birch", "桦树书架", "摆放着很多书籍的书架,可存储物品" ],
[ "bookcase_jungle", "丛林书架", "摆放着很多书籍的书架,可存储物品" ],
[ "bookcase_acacia", "金合欢书架", "摆放着很多书籍的书架,可存储物品" ],
[ "bookcase_dark_oak", "深色橡木书架", "摆放着很多书籍的书架,可存储物品" ],
[ "bookcase_palm", "棕榈书架", "摆放着很多书籍的书架,可存储物品" ],
[ "bookcase_volcano", "熔岩木书架", "摆放着很多书籍的书架,可存储物品" ],
[ "bookcase_tainted", "腐化木书架", "摆放着很多书籍的书架,可存储物品" ],
[ "bench_oak", "橡木长椅", "一张长椅" ],
[ "bench_spruce", "云杉长椅", "一张长椅" ],
[ "bench_birch", "桦树长椅", "一张长椅" ],
[ "bench_jungle", "丛林长椅", "一张长椅" ],
[ "bench_acacia", "金合欢长椅", "一张长椅" ],
[ "bench_dark_oak", "深色橡木长椅", "一张长椅" ],
[ "bench_palm", "棕榈长椅", "一张长椅" ],
[ "bench_volcano", "熔岩木长椅", "一张长椅" ],
[ "bench_tainted", "腐化木长椅", "一张长椅" ],
[ "prismarine_mud", "海晶泥", "大量存在于海底的方块" ],
[ "snow_queen_loot", "冰雪女王战利品", "纪念击败冰雪女王" ],
[ "nether_destroyer_loot", "地狱毁灭者战利品", "纪念击败地狱毁灭者" ],
[ "table_nether", "地狱桌", "一张地狱要塞的桌子" ],
[ "cabinet_nether", "地狱桌柜", "一张地狱要塞的桌柜,可储存物品" ],
[ "bench_nether", "地狱长椅", "一张长椅" ],
[ "chair_nether", "地狱椅子", "一张地狱要塞的椅子" ],
[ "bookcase_nether", "地狱书架", "摆放着很多书籍的书架,可存储物品" ],
[ "door_nether", "地狱门", "房子必不可少的部分" ],
[ "nether_chest", "地狱箱子", "存放物品" ],
[ "nether_lamp", "地狱吊灯", "提供明亮的照明" ],
[ "mana_piece", "魔法碎片", "食用后提高10魔法上限" ],
[ "wooden_hoe", "木锄", "用于开垦土地" ],
[ "steel_axe", "钢斧", "钢制成的斧头" ],
[ "bronze_axe", "青铜斧", "青铜制成的斧头" ],
[ "silver_axe", "银斧", "银制成的斧头" ],
[ "lead_axe", "铅斧", "铅制成的斧头" ],
[ "tin_axe", "锡斧", "锡制成的斧头" ],
[ "copper_axe", "铜斧", "铜制成的斧头" ],
[ "steel_pickaxe", "钢镐", "钢制成的镐子" ],
[ "bronze_pickaxe", "青铜镐", "青铜制成的镐子" ],
[ "silver_pickaxe", "银镐", "银制成的镐子" ],
[ "lead_pickaxe", "铅镐", "铅制成的镐子" ],
[ "tin_pickaxe", "锡镐", "锡制成的镐子" ],
[ "copper_pickaxe", "铜镐", "铜制成的镐子" ],
[ "potion_glowing", "发光药水", "一瓶饮用后全身发光的药水" ],
[ "potion_glowing_long", "长效发光药水", "一瓶饮用后全身发光的药水" ],
[ "glowing_mushroom", "发光蘑菇", "一个散发着光芒的蘑菇" ],
[ "poison_mushroom", "毒蘑菇", "禁止食用!" ],
[ "large_brown_mushroom", "大型棕色蘑菇", "一个巨大的棕色蘑菇" ],
[ "large_red_mushroom", "大型红蘑菇", "一个巨大的红色蘑菇" ],
[ "large_poison_mushroom", "大型毒蘑菇", "一个巨大的毒蘑菇" ],
[ "gray_feather", "灰羽毛", "这是一根灰色的羽毛" ],
[ "nether_axe", "下界合金斧", "下界合金加固制成的斧头" ],
[ "nether_pickaxe", "下界合金镐", "下界合金加固制成的镐子" ],
[ "nether_sword", "下界合金剑", "下界合金加固制成的剑" ],
[ "super_nether_sword", "加强下界合金剑", "下界合金加固制成的加强剑" ],
[ "rocket", "火箭", "需要火箭筒来发射" ],
[ "nether_altar", "地狱祭坛", "内部似乎封印着可怕的敌人" ],
[ "snow_glass_ball", "冰雪女王玻璃球", "冰雪女王沉睡在这个玻璃球中" ],
[ "blue_shot_bow", "魔蓝速射驽", "" ],
[ "bone_gun", "魔法骨枪", "" ],
[ "curse_bow", "魔法诅咒弓", "" ],
[ "dark_staff", "暗黑法杖", "" ],
[ "fire_book", "火焰之书", "" ],
[ "fire_shooter", "喷火器", "" ],
[ "fire_staff", "火之法杖", "" ],
[ "frosen_staff", "强力冰冻法杖", "" ],
[ "lava_sword", "熔岩剑", "" ],
[ "mini_laser_gun", "迷你激光枪", "" ],
[ "mini_rocket_launcher", "魔法三分火箭发射器", "" ],
[ "sniper", "狙击枪", "" ],
[ "soul_laserer", "灵魂迷你炮", "" ],
[ "soul_staff", "灵魂法杖", "" ],
[ "super_fire_shot_bow", "强力连弩", "" ],
[ "super_shark", "鲨鱼枪", "" ],
[ "super_shark_ghost", "鲨鱼枪", "" ],
[ "super_spike_shot_bow", "钉刺枪", "" ],
[ "sword_fish", "鱼枪", "" ],
[ "sword_fish_gun", "剑鱼枪", "" ],
[ "water_book", "水之书", "" ],
[ "blue_arrow", "蓝魔箭", "可以产生穿透伤害" ],
[ "rocket_boost", "火箭靴", "允许持续飞行一段时间" ],
[ "blue_talisman", "魔力护符", "加速回复魔力" ],
[ "heart_talisman", "生命护符", "加速回复生命" ],
[ "gold_talisman", "黄金护符", "减少死亡经验损失" ],
[ "lava_necklace", "熔岩护符", "免疫火焰伤害" ],
[ "lighting_talisman", "星星护符", "持续提供照明" ],
[ "ancient_ingot", "远古合金", "古老的合金" ],
[ "ancient_sample", "远古鳞片样本", "远古生物身上的鳞片" ],
[ "blood", "凝固血滴", "硬邦邦的血滴" ],
[ "blue_crystal", "魔力蓝水晶", "充满魔力的蓝水晶" ],
[ "dark_shadow_ingot", "魔影锭", "融入魔法力量的金属" ],
[ "dark_shadow_part", "暗影碎片", "来自另一个世界的碎片" ],
[ "diamond_ingot", "魔力钻石锭", "充满魔法的钻石锭" ],
[ "ender_mirror", "末影魔镜", "快速传送至重生点" ],
[ "evil_part", "恶魔鳞片", "来自恶魔身上的鳞片" ],
[ "flesh_ingot", "血腥锭", "一块极具攻击性的未知金属" ],
[ "flesh_machine_part", "生物机械零件", "拥有生物能力的机械零件" ],
[ "flesh_part", "血腥碎片", "血肉模糊的碎片" ],
[ "ghost", "幽魂", "为魔法系/塔防系设施提供幽魂驱动力" ],
[ "ghost_crystal", "幽魂碎片", "魔法系/塔防系的基本元素" ],
[ "ghost_element", "幽魂元素", "魔法系/塔防系的基本元素" ],
[ "ice_element", "冰霜元素", "摸起来冷冷的" ],
[ "ice_element_ball", "冰霜元素球", "摸起来冷冷的" ],
[ "knight_ingot", "骑士锭", "从骑士身上掉落的未知金属" ],
[ "machine_part", "机械零件", "一块机械零件" ],
[ "magic_cell", "魔影细胞", "一个不断蠕动的魔法细胞" ],
[ "magic_cell_group", "魔影细胞群", "一团不断蠕动的魔法细胞" ],
[ "magic_crystal", "魔力水晶", "" ],
[ "magic_silver_ingot", "魔银锭", "充满魔法的银锭" ],
[ "magma_gold_ingot", "熔岩金锭", "熔岩包裹的金锭" ],
[ "dungeon_eater", "地牢吞噬者召唤物", "可在暗黑地牢召唤地牢吞噬者" ],
[ "pure_red_stone", "纯净红石", "" ],
[ "red_crystal", "魔力红水晶", "充满魔力的红水晶" ],
[ "red_gold_ingot", "魔金锭", "充满魔法的红色金锭" ],
[ "soul_element", "灵魂元素", "" ],
[ "star_ingot", "星空锭", "似乎是来自太空的未知金属" ],
[ "strange_eye", "克苏鲁之眼召唤物", "可在夜晚召唤克苏鲁之眼" ],
[ "strange_len", "可疑晶状体", "来自于另一个时空的晶状体" ],
[ "tower_core", "防御塔核心", "放置于防御能量塔中,为所有防御塔提供能量" ],
[ "white_crystal", "魔力白水晶", "充满魔力的白水晶" ],
[ "yellow_crystal", "魔力黄水晶", "充满魔力的黄水晶" ],
[ "ancient_helmet", "远古头盔", "全套奖励:抗火+照明 +12防御 +7攻击力 +30%移速" ],
[ "ancient_chestplate", "远古胸甲", "全套奖励:抗火+照明 +12防御 +7攻击力 +30%移速" ],
[ "ancient_leggings", "远古护胫", "全套奖励:抗火+照明 +12防御 +7攻击力 +30%移速" ],
[ "fine_tin_helmet", "精锡头盔", "全套奖励:+3攻击力 +20%移速" ],
[ "fine_tin_chestplate", "精锡胸甲", "全套奖励:+3攻击力 +20%移速" ],
[ "fine_tin_leggings", "精锡护胫", "全套奖励:+3攻击力 +20%移速" ],
[ "flesh_helmet", "猩红头盔", "全套奖励:+7攻击力" ],
[ "flesh_chestplate", "猩红胸甲", "全套奖励:+7攻击力" ],
[ "flesh_leggings", "猩红护胫", "全套奖励:+7攻击力" ],
[ "knight_helmet", "骑士头盔", "全套奖励:+6防御 +5攻击力" ],
[ "knight_chestplate", "骑士胸甲", "全套奖励:+6防御 +5攻击力" ],
[ "knight_leggings", "骑士护胫", "全套奖励:+6防御 +5攻击力" ],
[ "lava_helmet", "熔岩头盔", "全套奖励:抗火+照明" ],
[ "lava_chestplate", "熔岩胸甲", "全套奖励:抗火+照明" ],
[ "lava_leggings", "熔岩护胫", "全套奖励:抗火+照明" ],
[ "magic_gold_helmet", "魔金头盔", "全套奖励:+2防御 +40%魔力恢复速度" ],
[ "magic_gold_chestplate", "魔金胸甲", "全套奖励:+2防御 +40%魔力恢复速度" ],
[ "magic_gold_leggings", "魔金护胫", "全套奖励:+2防御 +40%魔力恢复速度" ],
[ "magic_shadow_helmet", "魔影头盔", "全套奖励:+3防御 +30%移速 +60%魔力恢复速度" ],
[ "magic_shadow_chestplate", "魔影胸甲", "全套奖励:+3防御 +30%移速 +60%魔力恢复速度" ],
[ "magic_shadow_leggings", "魔影护胫", "全套奖励:+3防御 +30%移速 +60%魔力恢复速度" ],
[ "magic_silver_helmet", "魔银头盔", "全套奖励:+2防御 +40%魔力恢复速度" ],
[ "magic_silver_chestplate", "魔银胸甲", "全套奖励:+2防御 +40%魔力恢复速度" ],
[ "magic_silver_leggings", "魔银护胫", "全套奖励:+2防御 +40%魔力恢复速度" ],
[ "shadow_helmet", "暗影头盔", "全套奖励:+100%魔力恢复速度" ],
[ "shadow_chestplate", "暗影胸甲", "全套奖励:+100%魔力恢复速度" ],
[ "shadow_leggings", "暗影护胫", "全套奖励:+100%魔力恢复速度" ],
[ "star_helmet", "星空头盔", "全套奖励:照明 +4防御 +5攻击力 +20%魔力恢复速度" ],
[ "star_chestplate", "星空胸甲", "全套奖励:照明 +4防御 +5攻击力 +20%魔力恢复速度" ],
[ "star_leggings", "星空护胫", "全套奖励:照明 +4防御 +5攻击力 +20%魔力恢复速度" ],
[ "super_diamond_helmet", "强化钻石头盔", "全套奖励:+8防御" ],
[ "super_diamond_chestplate", "强化钻石胸甲", "全套奖励:+8防御" ],
[ "super_diamond_leggings", "强化钻石护胫", "全套奖励:+8防御" ],
[ "blue_mushroom", "蓝蘑菇", "" ],
[ "large_blue_mushroom", "大型蓝蘑菇", "" ],
[ "blue_mushroom_dirt", "蓝蘑菇泥", "" ],
[ "blue_mushroom_stem", "蓝蘑菇梗", "" ],
[ "ice_cobblestone_hard", "坚硬冰圆石", "" ],
[ "lava_block_pile", "岩浆凝块墙", "" ],
[ "pile_cobblestone", "圆石排墙", "" ],
[ "snow_soft", "软雪泥", "" ],
[ "volcano_burn_stone", "火山石", "" ],
[ "volcano_cobblestone", "燃烧火山石", "" ]
],
"chemicalFormulas": [
[ "coal", "C" ],
[ "charcoal", "C" ],
[ "diamond", "C" ],
[ "emerald", "Be3Al2(SiO3)6" ],
[ "lapis_lazuli", "(Al6Si6Ca8Na8)12(Al3Si3Na4Cl)2FeS2CaCO3" ],
[ "quartz", "SiO2" ],
[ "redstone", "Si(FeS2)5CrAl2O3Hg3" ],
[ "iron_nugget", "Fe" ],
[ "gold_nugget", "Au" ],
[ "iron_ingot", "Fe" ],
[ "gold_ingot", "Au" ],
[ "redstone_ingot", "Si(FeS2)5CrAl2O3Hg3" ],
[ "copper_ingot", "Cu" ],
[ "tin_ingot", "Sn" ],
[ "bronze_ingot", "SnCu3" ],
[ "lead_ingot", "Pb" ],
[ "silver_ingot", "Ag" ],
[ "steel_ingot", "Fe50C" ],
[ "lithium_ingot", "Li" ],
[ "beryllium_ingot", "Be" ],
[ "sodium_ingot", "Na" ],
[ "magnesium_ingot", "Mg" ],
[ "aluminum_ingot", "Al" ],
[ "titanium_ingot", "Ti" ],
[ "vanadium_ingot", "V" ],
[ "chromium_ingot", "Cr" ],
[ "manganese_ingot", "Mn" ],
[ "cobalt_ingot", "Co" ],
[ "nickel_ingot", "Ni" ],
[ "zinc_ingot", "Zn" ],
[ "gallium_ingot", "Ga" ],
[ "yttrium_ingot", "Y" ],
[ "niobium_ingot", "Nb" ],
[ "molybdenum_ingot", "Mo" ],
[ "palladium_ingot", "Pd" ],
[ "indium_ingot", "In" ],
[ "antimony_ingot", "Sb" ],
[ "tantalum_ingot", "Ta" ],
[ "wolfram_ingot", "W" ],
[ "rhenium_ingot", "Re" ],
[ "osmium_ingot", "Os" ],
[ "iridium_ingot", "Ir" ],
[ "platinum_ingot", "Pt" ],
[ "bismuth_ingot", "Bi" ],
[ "vibranium_ingot", "Vb" ]
]
}
================================================
FILE: languages/english.json
================================================
{
"modTexts": [
[ "BACK", "Back" ],
[ "DESC", "Description" ],
[ "WEB", "Website" ],
[ "OK", "OK" ],
[ "SINGLE_PLAYER", "Singleplayer" ],
[ "MULTI_PLAYER", "Multiplayer" ],
[ "MOD_LIST", "Mod List"],
[ "COMMUNITY", "Community" ],
[ "SETTING", "Option" ],
[ "EXIT_GAME", "Exit Game" ],
[ "COPYRIGHT", "BlueYoshi.cn/TerraCraft 进击的蓝耀西(Bilibili)" ],
[ "MOD_LOADER_INFO", "[Mod Loader] Total %d mods loaded" ],
[ "ENGINE_VERSION", "Engine Version %s" ],
[ "OPEN_MOD_FOLDER", "Open Mods Folder" ],
[ "MANAGER_SOURCES", "Manager Sources.." ],
[ "ALL_MOD_LOADED", "All mods (%d loaded)" ],
[ "MOD_VERSION", "Mod Version" ],
[ "MOD_AUTHORS", "Mod Authors" ],
[ "MOD_FOLDER_UNSUPPORTED", "Mobile version does not support opening mods folder function." ],
[ "WEB_SOURCE_GITHUB", "Sources (Github)" ],
[ "WEB_HOME", "Homepage" ],
[ "help:kill", "Kill yourself." ],
[ "help:killp", "Kill the targeted player." ],
[ "help:buff", "Add BUFF and set the duration." ],
[ "help:buffp", "Add BUFF to the targeted player and set the duration." ],
[ "help:spawn", "Teleport to spawn point." ],
[ "help:home", "Teleport to respawn point." ],
[ "help:ex", "Increase experience points." ],
[ "help:exp", "Increase experience points to the targeted player." ],
[ "help:give", "Give items and set the count." ],
[ "help:givep", "Give items to the targeted player and set the count." ],
[ "help:gamemode", "Set the game mode of yourself." ],
[ "help:gamemodep", "Set the game mode of the targeted player." ],
[ "help:gamemodew", "Set the game mode of world." ],
[ "help:npc", "Create an NPC at the specified location." ],
[ "help:effect", "Create an Effect at the specified location." ],
[ "help:tp", "Teleport to a specified location." ],
[ "help:tpp", "Teleport the targeted player to a specified location." ],
[ "help:me", "Display a message about yourself." ],
[ "help:msg", "Send a private message to the targeted player." ],
[ "help:say", "Broadcast a message." ],
[ "help:clear", "Clear your backpack." ],
[ "help:clearp", "Clear backpack of the targeted player." ],
[ "help:day", "Set the time of day." ],
[ "help:dayf", "Set the hour, minute, second of the time of day." ],
[ "help:dayspeed", "Set the elapsed speed of time." ],
[ "help:daylock", "Lock the time of day." ],
[ "help:dayunlock", "Unlock the time of day." ],
[ "help:wea", "Set the weather time." ],
[ "help:stopwea", "Cancel the weather event." ],
[ "help:admin", "Give the targeted player administrator authority." ],
[ "help:noadmin", "Deprive the targeted player administrator authority." ],
[ "help:master", "Give the targeted player server owner authority." ],
[ "help:nomaster", "Deprive the targeted player server owner authority." ],
[ "help:save", "Save the world immediately." ],
[ "help:autosave-on", "Open autosave mode." ],
[ "help:autosave-off", "Close autosave mode." ],
[ "help:port", "Display the server port." ],
[ "help:state", "Display server running status." ],
[ "help:pvp-on", "Open PVP mode." ],
[ "help:pvp-off", "Close PVP mode." ],
[ "help:safeblow-on", "All explosions will destroy tiles." ],
[ "help:safeblow-off", "All explosions will not destroy tiles." ],
[ "help:players", "Display all online players." ],
[ "help:kick", "Kick a player with a certain name." ],
[ "help:kickall", "Kick all players." ],
[ "help:banip", "Do not allow an ip to access the server." ],
[ "help:nobanip", "Allow an ip to access the server." ],
[ "help:blacklist", "Show all banned IPs." ],
[ "help:enchant", "Enchant the hand-held item and set the level." ],
[ "help:blueyoshiiscool", "An easter egg." ],
[ "ex_ok", "Give %s experience levels %d." ],
[ "buff_ok", "Give %s buff %s duration %d seconds." ],
[ "em_ok", "Give %s's item %s enchantment %s level %d." ],
[ "em_fail", "Enchanting failed." ],
[ "spawn_ok", "Teleport %s to spawn point." ],
[ "home_ok", "Teleport %s to home." ],
[ "home_fail", "Cannot find the home of %s." ],
[ "give_ok", "Give %s item %s * %d" ],
[ "clear_ok", "The backpack of %s has been cleared." ],
[ "day_ok", "The current day time is set to %02d:%02d:%02d" ],
[ "dayspeed_ok", "The time lapse speed has been set to %.2f times." ],
[ "wea_ok", "The current weather progress is %d%%." ],
[ "admin_ok", "The player %s has been set as an administrator." ],
[ "noadmin_ok", "The admin rights of player %s have been cancelled." ],
[ "master_ok", "The player %s has been set as an server owner." ],
[ "nomaster_ok", "The owner rights of player %s have been cancelled." ],
[ "save_ok", "[Saving] has been added to the server processing queue." ],
[ "player_info", "(%d) %s (%s:%d)" ],
[ "players_ok", "%d players online." ],
[ "autosave_on_ok", "The [Auto Save] mode is turned on." ],
[ "autosave_off_ok", "The [Auto Save] mode is turned off." ],
[ "pvp_on_ok", "The [PVP] mode is turned on." ],
[ "pvp_off_ok", "The [PVP] mode is turned oFF." ],
[ "safeblow_on_ok", "The [Explosion Protection] mode is turned on." ],
[ "safeblow_off_ok", "The [Explosion Protection] mode is turned off." ],
[ "port_ok", "The server port number is %d" ],
[ "kick_ok", "Kicked %s" ],
[ "blacklist_info", "(%d) %s" ],
[ "blacklist_ok", "There are %d entries in blacklist." ],
[ "banip_ok", "IP %s has been banned and added to the server blacklist." ],
[ "nobanip_ok", "IP %s has been removed from the server blacklist." ],
[ "nobanip_fail", "IP %s does not exist in the server blacklist." ],
[ "gamemodep_s_ok", "The game mode of player %s has been changed to survival mode." ],
[ "gamemodep_c_ok", "The game mode of player %s has been changed to creative mode." ],
[ "gamemodep_a_ok", "The game mode of player %s has been changed to adventure mode." ],
[ "gamemodew_s_ok", "The game mode of world has been changed to survival mode." ],
[ "gamemodew_c_ok", "The game mode of world has been changed to creative mode." ],
[ "gamemodew_a_ok", "The game mode of world has been changed to adventure mode." ],
[ "msg_content", "[PM from %s] %s" ],
[ "msg_server_content", "[PM from server] %s" ],
[ "msg_to_content", "[PM to %s] %s" ],
[ "msg_server_to_content", "[PM to %s] %s" ],
[ "say", "[Server] %s" ],
[ "npc_ok", "Created npc %s at (%d, %d)" ],
[ "tp_ok", "Teleported player %s to (%d, %d)" ],
[ "blueyoshiiscool_ok", "Blueyoshi is cool!!!" ]
],
"enchantments": [
[ "silk_touch", "Silk Youch" ],
[ "fortune", "Fortune" ],
[ "phyton", "Phyton" ],
[ "unbreaking", "Unbreaking" ],
[ "efficiency", "Efficiency" ],
[ "aqua_affinity", "Aqua Affinity" ],
[ "bane_of_arthropods", "Bane of Arthropods" ],
[ "blast_protection", "Blast Protection" ],
[ "curse_of_binding", "Curse of Binding" ],
[ "curse_of_vanishing", "Curse of Vanishing" ],
[ "depth_strider", "Depth Strider" ],
[ "feather_falling", "Feather Falling" ],
[ "fire_aspect", "Fire Aspect" ],
[ "fire_protection", "Fire Protection" ],
[ "flame", "Flame" ],
[ "frost_walker", "Frost Walker" ],
[ "infinity", "Infinity" ],
[ "knockback", "Knockback" ],
[ "looting", "Looting" ],
[ "luck_of_the_sea", "Luck of the Sea" ],
[ "lure", "Lure" ],
[ "multishot", "Multishot" ],
[ "piercing", "Piercing" ],
[ "power", "Power" ],
[ "projectile_protection", "Projectile Protection" ],
[ "protection", "Protection" ],
[ "punch", "Punch" ],
[ "quick_charge", "Quick Charge" ],
[ "respiration", "Respiration" ],
[ "sharpness", "Sharpness" ],
[ "smite", "Smite" ],
[ "thorns", "Thorns" ]
],
"buffs": [
[ "absorption", "Absorption" ],
[ "blindness", "Blindness" ],
[ "fire", "Fire" ],
[ "fire_defense", "Fire Defense" ],
[ "glowing", "Glowing" ],
[ "happiness", "Happiness" ],
[ "health_boost", "Health Boost" ],
[ "hunger", "Hunger" ],
[ "hurt", "Hurt" ],
[ "invisibility", "Invisibility" ],
[ "jump_boost", "Jump Boost" ],
[ "levitation", "Levitation" ],
[ "luck", "Luck" ],
[ "mining_fatique", "Mining Fatique" ],
[ "nausea", "Nausea" ],
[ "poison", "Poison" ],
[ "regeneration", "Regeneration" ],
[ "resistance", "Resistance" ],
[ "sadness", "Sadness" ],
[ "slow_falling", "Slow Falling" ],
[ "slow_mining", "Slow Mining" ],
[ "slowness", "Slowness" ],
[ "speed", "Speed" ],
[ "strength", "Strength" ],
[ "vision", "Night Vision" ],
[ "water_breathing", "Water Breathing" ],
[ "weak", "Weak" ],
[ "wither", "Wither" ],
[ "health_cold", "Health Cold" ]
],
"advancements": [
[ "inventory", "Start Terracraft!", "WASD: Move\nSPACE: Jump\nSHIFT+Left Click: Place/Dig Wall\nLeft Click: Place/Use\nRight Click: Interact\nCTRL: Auto Mode\nQ: Drop\nE: Inventory\nR: Recipes\nF: Advancements\nT: Chat\nTAB: Ping List\nF1: Hide UI\nF3: Debug" ],
[ "wood", "Getting Wood", "Punch a tree until a block of wood pops out." ],
[ "crafting_table", "Benchmaking", "Craft a workbench with four blocks of wooden wood planks." ],
[ "farm", "Time to Farm!", "Make a Hoe." ],
[ "bread", "Bake Bread", "Turn wheat into bread." ],
[ "cake", "The Lie", "Bake a cake using: wheat, sugar, milk, and eggs." ],
[ "bow", "Archer!", "Use strings and wooden sticks to make a bow." ],
[ "crossbow", "Crossbow archer!", "Make a crossbow." ],
[ "mine", "Time to Mine!", "Use planks and sticks to make a pickaxe." ],
[ "stone", "Stone Age", "Mine stone with your new pickaxe." ],
[ "mine_up", "Getting an Upgrade", "Construct a better pickaxe." ],
[ "furnace", "Hot Topic", "Construct a furnace out of eight cobblestone blocks." ],
[ "iron", "Acquire Hardware", "Smelt metal ore in the furnace." ],
[ "sword", "Time to Strike!", "Use planks and sticks to make a sword." ],
[ "leather", "Cow Tipper", "Harvest some leather." ],
[ "hunter", "Monster Hunter", "Attack and destroy a monster." ],
[ "staff", "Magic Staff", "Make a magic staff." ],
[ "magic_limit", "Magician", "Eat a magic fragment that increases the upper limit of magic." ],
[ "ender_pearl", "Enderman Killer", "Obtain an ender pearl." ],
[ "steel", "Refined Iron!", "Smelt an iron ingot to get a steel ingot." ],
[ "bronze", "Bronze Age", "Obtain a bronze ingot" ],
[ "diamond", "DIAMONDS!", "Acquire diamonds with your metal tools." ],
[ "enchant", "Enchanter", "Construct an Enchantment Table." ],
[ "nether", "Need to go deeper", "Get into nether layer." ],
[ "blaze_rod", "Into Fire", "Relieve a Blaze of its rod." ],
[ "brew", "Local Brewery", "Make a brewing stand." ],
[ "ghast", "Go to hell!", "Defeat a Ghast." ],
[ "netherite", "Hidden in the Depths", "Obtain Ancient Debris." ],
[ "gun", "Arms Dealer", "Obtain a gun in the nether fortress." ],
[ "redstone", "Redstone Found!", "Obtain a redstone powder." ],
[ "redstone_wire", "Redstone Technology", "Make a redstone wire." ],
[ "lava", "Super Fuel", "Get a bucket of lava." ],
[ "pumpkin_helmet", "Halloween!", "Make a Halloween-style pumpkin helmet." ],
[ "ender_chest", "Alien Space", "Make an ender box." ],
[ "guardian", "Intruder!", "Defeat a guardian on the seabed." ],
[ "snow_queen", "Snow Queen!", "Awaken the Snow Queen from the Snow Queen Glass Ball." ],
[ "snow_queen_killed", "Liberation of the Aurora Palace", "Defeat the Snow Queen." ],
[ "nether_destroyer", "Destroy the Nether!", "Destroy the nether altar to release the Nether Destroyer." ],
[ "nether_destroyer_killed", "Save the Nether", "Defeat the Nether Destroyer." ],
[ "diamond_wear", "Cover Me With Diamonds", "Diamond armor saves lives." ],
[ "netherite_full_wear", "Cover Me in Debris", "Get a full suit of Netherite armor." ]
],
"npcs": [
[ "pig", "Pig" ],
[ "zombie", "Zombie" ],
[ "husk", "Husk" ],
[ "mummy", "Mummy" ],
[ "waste_mummy", "Waste Mummy" ],
[ "villager_zombie", "Villager Zombie" ],
[ "arrow_zombie", "Arrow Zombie" ],
[ "bald_zombie", "Bald Zombie" ],
[ "doge_zombie", "Doge Zombie" ],
[ "iron_zombie", "Iron Zombie" ],
[ "skeleton", "Skeleton" ],
[ "tainted_skeleton", "Tainted Skeleton" ],
[ "blood_skeleton", "Bloody Skeleton" ],
[ "angry_skeleton", "Angry Skeleton" ],
[ "black_skeleton", "Black Skeleton" ],
[ "boney_skeleton", "Boney Skeleton" ],
[ "creeper", "Creeper" ],
[ "flower_creeper", "Flower Creeper" ],
[ "tainted_creeper", "Tainted Creeper" ],
[ "spider", "Spider" ],
[ "bat", "Bat" ],
[ "jungle_bat", "Jungle Bat" ],
[ "large_jungle_bat", "Large Jungle Bat" ],
[ "blood_bat", "Bloody Bat" ],
[ "man_eater", "Man Eater" ],
[ "blood_eye", "Bloody Eye" ],
[ "chicken", "Chicken" ],
[ "cow", "Cow" ],
[ "sheep", "Sheep" ],
[ "red_mushroom_cow", "Mooshroom" ],
[ "brown_mushroom_cow", "Mooshroom" ],
[ "cat", "Cat" ],
[ "white_rabbit", "White Rabbit" ],
[ "brown_rabbit", "Brown Rabbit" ],
[ "black_rabbit", "Black Rabbit" ],
[ "yellow_rabbit", "Yellow Rabbit" ],
[ "squid", "Squid" ],
[ "turtle", "Turtle" ],
[ "pufferfish", "Pufferfish" ],
[ "dolphin", "Dolphin" ],
[ "wolf", "Wolf" ],
[ "enderman", "Enderman" ],
[ "zombie_pigman", "Zombie Pigman" ],
[ "blaze", "Blaze" ],
[ "drowned", "Drowned" ],
[ "guardian", "Guardian" ],
[ "ghast", "Ghast" ],
[ "ice_elf", "Ice Elf" ],
[ "magma_elf", "Magma Elf" ],
[ "waste_ghost", "Waste Ghost" ],
[ "large_block_slime", "Large Block Slime" ],
[ "block_slime", "Block Slime" ],
[ "large_ice_slime", "Large Ice Slime" ],
[ "ice_slime", "Ice Slime" ],
[ "large_waste_block_slime", "Large Waste Block Slime" ],
[ "waste_block_slime", "Waste Block Slime" ],
[ "green_slime", "Green Slime" ],
[ "large_green_slime", "Large Green Slime" ],
[ "large_black_slime", "Large Black Slime" ],
[ "large_waste_slime", "Large Waste Slime" ],
[ "large_tainted_slime", "Large Tainted Slime" ],
[ "blood_slime", "Bloody Slime" ],
[ "yellow_slime", "Yellow Slime" ],
[ "desert_slime", "Desert Slime" ],
[ "large_desert_slime", "Large_desert Slime" ],
[ "blue_slime", "Blue Slime" ],
[ "purple_slime", "Purple Slime" ],
[ "snow_slime", "Snow Slime" ],
[ "tainted_slime", "Tainted Slime" ],
[ "magma_slime", "Magma Slime" ],
[ "phantom", "Phantom" ],
[ "eagle", "Eagle" ],
[ "magma_birdo", "Magma Birdo" ],
[ "meteor", "Meteor" ],
[ "shulker", "Shulker" ],
[ "evoker", "Evoker" ],
[ "wither_skeleton", "Wither Skeleton" ],
[ "ender_dragon", "Ender Dragon" ],
[ "light_blue_butterfly", "Light Blue Butterfly" ],
[ "yellow_butterfly", "Yellow Butterfly" ],
[ "red_butterfly", "Red Butterfly" ],
[ "worm_head", "Nether Destroyer" ],
[ "worm_body", "Nether Destroyer" ],
[ "worm_tail", "Nether Destroyer" ],
[ "vine_man_eater_head", "Jungle Man Eater" ],
[ "vine_man_eater_body", "Jungle Man Eater" ],
[ "vine_man_eater_tail", "Jungle Man Eater" ],
[ "snow_queen", "Snow Queen" ],
[ "small_hell_eater", "Hell Eater" ],
[ "snow_guardian", "Snow Guardian" ],
[ "snow_guardian_archer", "Snow Guardian Archer" ],
[ "small_fire_hell_eater", "Burning Eater" ]
],
"projectiles": [
[ "wooden_arrow", "Wooden Arrow" ],
[ "lighting_arrow", "Lighting Arrow" ],
[ "star_arrow", "Star Arrow" ],
[ "blood_arrow", "Bloody Arrow" ],
[ "ice_arrow", "Ice Arrow" ],
[ "sword_arrow", "Sword Arrow" ],
[ "air_bullet", "Air Bullet" ],
[ "small_air_bullet", "Air Bullet" ],
[ "amethyst_magic", "Amethyst Magic" ],
[ "star", "Star Magic" ],
[ "ice_magic", "Ice Magic" ],
[ "shadow_magic", "Shadow Magic" ],
[ "water_magic", "Water Magic" ],
[ "fire_magic", "Fire Magic" ],
[ "crystal_magic", "Crystal Magic" ],
[ "ice_bullet", "Ice Bullet" ],
[ "boomerang", "Boomerang" ],
[ "wooden_boomerang", "Wooden Boomerang" ],
[ "fire_boomerang", "Fire Boomerang" ],
[ "rocket", "Rocket" ],
[ "blaze_rod", "Blaze Rod" ],
[ "fire_charge", "Fireball" ],
[ "shulker_bullet", "Shulker bullet" ],
[ "bullet", "Bullet" ],
[ "gun_fire", "Fire" ],
[ "bullet_laser", "Laser" ],
[ "bullet_super", "Buper" ],
[ "tnt", "TNT" ],
[ "bomb", "Bomb" ],
[ "grenade", "Grenade" ],
[ "glow_bomb", "Glowing Bomb" ],
[ "glow_ball", "Glowing Ball" ],
[ "snow_flake", "Snow Flake" ]
],
"items": [
[ "stone_axe", "Stone Axe", "More efficient than the wooden one." ],
[ "dirt", "Dirt", "A dirt block covering the ground." ],
[ "stone", "Stone", "A smoother stone." ],
[ "cobblestone", "Cobblestone", "A Basic stone material." ],
[ "stick", "Stick", "A wooden stick." ],
[ "gravel", "Gravel", "A block mixed with various impurities." ],
[ "sand", "Sand", "The source of glass." ],
[ "ore_coal", "Coal Ore", "A mineral ore, require further processing." ],
[ "ore_iron", "Iron Ore", "A mineral ore, require further processing." ],
[ "ore_gold", "Gold Ore", "A mineral ore, require further processing." ],
[ "ore_lapis", "Lapis Ore", "A mineral ore, require further processing." ],
[ "ore_redstone", "Redstone Ore", "A mineral ore, require further processing." ],
[ "ore_diamond", "Diamond Ore", "A mineral ore, require further processing." ],
[ "ore_emerald", "Emerald Ore", "A mineral ore, require further processing." ],
[ "stone_pickaxe", "Stone Pickaxe", "Better than the wooden one." ],
[ "stone_sword", "Stone Sword", "A sword made of stone." ],
[ "furnace", "Furnace", "Smelt or cook items." ],
[ "chest", "Chest", "Store items." ],
[ "oak_plank", "Oak Plank", "A wooden building material." ],
[ "grass_axe", "Grass Axe", "Endless regeneration ability." ],
[ "grass_pickaxe", "Grass Pickaxe", "Endless regeneration ability." ],
[ "grass_sword", "Grass Sword", "A weak grass sword." ],
[ "iron_ingot", "Iron Ingot", "" ],
[ "gold_ingot", "Gold Ingot", "" ],
[ "redstone_ingot", "Redstone Ingot", "" ],
[ "copper_ingot", "Copper Ingot", "" ],
[ "tin_ingot", "Tin Ingot", "" ],
[ "bronze_ingot", "Bronze Ingot", "" ],
[ "lead_ingot", "Lead Ingot", "" ],
[ "silver_ingot", "Silver Ingot", "" ],
[ "steel_ingot", "Steel Ingot", "" ],
[ "lithium_ingot", "Lithium Ingot", "" ],
[ "beryllium_ingot", "Beryllium Ingot", "" ],
[ "sodium_ingot", "Sodium Ingot", "" ],
[ "magnesium_ingot", "Magnesium Ingot", "" ],
[ "aluminum_ingot", "Aluminum Ingot", "" ],
[ "titanium_ingot", "Titanium Ingot", "" ],
[ "vanadium_ingot", "Vanadium Ingot", "" ],
[ "chromium_ingot", "Chromium Ingot", "" ],
[ "manganese_ingot", "Manganese Ingot", "" ],
[ "cobalt_ingot", "Cobalt Ingot", "" ],
[ "nickel_ingot", "Nickel Ingot", "" ],
[ "zinc_ingot", "Zinc Ingot", "" ],
[ "gallium_ingot", "Gallium Ingot", "" ],
[ "yttrium_ingot", "Yttrium Ingot", "" ],
[ "niobium_ingot", "Niobium Ingot", "" ],
[ "molybdenum_ingot", "Molybdenum Ingot", "" ],
[ "palladium_ingot", "Palladium Ingot", "" ],
[ "indium_ingot", "Indium Ingot", "" ],
[ "antimony_ingot", "Antimony Ingot", "" ],
[ "tantalum_ingot", "Tantalum Ingot", "" ],
[ "wolfram_ingot", "Wolfram Ingot", "" ],
[ "rhenium_ingot", "Rhenium Ingot", "" ],
[ "osmium_ingot", "Osmium Ingot", "" ],
[ "iridium_ingot", "Iridium Ingot", "" ],
[ "platinum_ingot", "Platinum Ingot", "" ],
[ "bismuth_ingot", "Bismuth Ingot", "" ],
[ "vibranium_ingot", "Vibranium Ingot", "" ],
[ "andesite", "Andesite", "Rich in calcium and alkaline." ],
[ "andesite_polished", "Polished Andesite", "Andesite material after polishing." ],
[ "clay", "Clay", "This is a clay ball." ],
[ "cobblestone_mossy", "Mossy Cobblestone", "Cobblestone covered with moss." ],
[ "diorite", "Diorite", "A variant of stone." ],
[ "diorite_polished", "Polished Diorite", "Andesite material after polishing." ],
[ "glass", "Glass", "Light-transmissive glass." ],
[ "granite", "Granite", "A variant of stone." ],
[ "granite_polished", "Polished Granite", "Andesite material after polishing." ],
[ "ice", "Ice", "Cold and fragile ice." ],
[ "ice_cobblestone", "Ice Cobblestone", "Frozen stone" ],
[ "ice_packed", "Packed Ice", "The unique internal structure make it never melt." ],
[ "obsidian", "Obsidian", "Forms when Magma meets water, and has a high hardness." ],
[ "prismarine", "Prismarine", "Building materials for underwater ruins." ],
[ "prismarine_brick", "Prismarine Brick", "Prismarine brick with jagged stripes." ],
[ "prismarine_dark", "Dark Prismarine", "Has a grid-like pattern." ],
[ "red_sand", "Red Sand", "Rich in iron oxide red sand." ],
[ "red_sand_carved", "Carved Red Sand", "Carved red sand bricks." ],
[ "red_sand_smooth", "Smooth Red Sand", "Red sand brick with smooth surface." ],
[ "sandstone", "Sandstone", "Hard sand." ],
[ "sandstone_carved", "Carved Sandstone", "Carved sandstone bricks." ],
[ "sandstone_smooth", "Smooth Sandstone", "Sandstone bricks with smooth surfaces." ],
[ "snow", "Snow", "Soft snow block." ],
[ "stone_brick", "Stone Brick", "A stone material for construction." ],
[ "stone_brick_carved", "Carved Stone Brick", "Carved stone building materials." ],
[ "stone_brick_cracked", "Cracked Stone Brick", "Cracked stone building material." ],
[ "stone_brick_mossy", "Mossy Stone Brick", "Stone brick covered with moss." ],
[ "bucket_empty", "Bucket Empty", "An empty bucket, can hold liquid." ],
[ "bucket_water", "Bucket Water", "A bucket full of water, left-click to pour out water." ],
[ "bucket_lava", "Bucket Lava", "A bucket full of lava, left click to pour out the lava." ],
[ "bucket_milk", "Bucket Milk", "A bucket full of milk, can remove all buffs." ],
[ "snowball", "Snowball", "Round snowball." ],
[ "vine", "Vine", "This is a vine." ],
[ "sugar_cane", "Sugar Cane", "For making sugars or books." ],
[ "suger", "Suger", "It tastes sweet." ],
[ "paper", "Paper", "A piece of paper." ],
[ "leather", "Leather", "Animal fur." ],
[ "book", "Book", "this is a book." ],
[ "wheat", "Wheat", "Can be processed into many foods." ],
[ "bread", "Bread", "Sweet bread." ],
[ "bone", "Bone", "A bone." ],
[ "bone_meal", "Bone Meal", "Can be used to ripen crops." ],
[ "crafting_table", "Crafting Table", "Use a 3x3 square matrix to craft more items." ],
[ "torch", "Torch", "Basic and cheap lighting tools." ],
[ "coal", "Coal", "" ],
[ "charcoal", "Charcoal", "" ],
[ "string", "String", "A long thin thread." ],
[ "wooden_bow", "Wooden Bow", "Suitable for long-range attacks." ],
[ "flint", "Flint", "Sharp flint." ],
[ "feather", "Feather", "This is a feather." ],
[ "wooden_arrow", "Wooden Arrow", "A shootable arrow." ],
[ "rocket_launcher", "Rocket Launcher", "Destroy everything!!!!" ],
[ "redstone_lamp", "Redstone Lamp", "Light up after charging." ],
[ "red_wire", "Red Wire", "Can transmit redstone power." ],
[ "clay_block", "Clay Block", "Source of construction materials." ],
[ "brick", "Brick", "A Construction material." ],
[ "spruce_plank", "Spruce Plank", "Wooden building materials." ],
[ "birch_plank", "Birch Plank", "Wooden building materials." ],
[ "jungle_plank", "Jungle Plank", "Wooden building materials." ],
[ "acacia_plank", "Acacia Plank", "Wooden building materials." ],
[ "dark_oak_plank", "Dark Oak Plank", "Dark wooden building materials." ],
[ "block_iron", "Iron Block", "Made of pressed iron ingots." ],
[ "block_gold", "Gold Block", "Made of pressed gold ingots" ],
[ "block_coal", "Coal Block", "Has a great burning value." ],
[ "block_diamond", "Diamond Block", "Made of diamonds." ],
[ "block_emerald", "Emerald Block", "Made of emeralds." ],
[ "block_lapis", "Lapis Block", "Made of lapis lazuli." ],
[ "block_redstone", "RedstoneBlock", "Made of redstones." ],
[ "bone_block", "Bone Block", "Calcium-rich." ],
[ "red_brick", "Red Brick", "Red brick fired from clay." ],
[ "brown_mushroom_block", "Brown Mushroom Block", "From giant brown mushrooms." ],
[ "coarse_dirt", "Coarse Dirt", "Mud variants, has a strong acidity." ],
[ "cobblestone_fence", "Cobblestone Fence", "Made of stone." ],
[ "end_stone", "End Stone", "The main blocks of the end." ],
[ "end_stone_brick", "End Stone Brick", "Brick made of end stone." ],
[ "farmland", "Farmland", "You can sow and harvest crops on this." ],
[ "fence_oak", "Oak Fence", "Wooden fence." ],
[ "fence_birch", "Birch Fence", "Wooden fence." ],
[ "fence_spruce", "Spruce Fence", "Wooden fence." ],
[ "fence_jungle", "Jungle Fence", "Wooden fence." ],
[ "fence_acacia", "Acacia Fence", "Wooden fence." ],
[ "fence_dark_oak", "Dark Oak Fence", "Wooden fence." ],
[ "fence_nether", "Nether Fence", "Dark black fence of nether." ],
[ "glowstone", "Glowstone", "A shining stone." ],
[ "hay_bale", "Hay Bale", "A sheaf of wheat." ],
[ "ice_brick", "Ice Brick", "A Brick made of ice." ],
[ "iron_bar", "Iron Bar", "Window with iron grating." ],
[ "magma_block", "Magma Block", "Solid magma." ],
[ "mossy_cobblestone_fence", "Mossy Cobblestone Fence", "Stone fence covered with moss." ],
[ "mushroom_stem", "Mushroom Stem", "The stem of giant mushroom." ],
[ "netherrack", "Netherrack", "The main block of nether." ],
[ "nether_brick_block", "Nether Brick Block", "Dark black nether brick." ],
[ "purpur_block", "Purpur Block", "A Block made of purpur." ],
[ "red_mushroom_block", "Red Mushroom Block", "From giant red mushrooms." ],
[ "red_nether_brick", "Red Nether Brick", "Red dark nether brick." ],
[ "red_sand_stone", "Red Sand Stone", "Hard red sand." ],
[ "sea_lantern", "Sea Lantern", "Glowing block in the sea." ],
[ "slime_block", "Slime Block", "Sticky gelatin block." ],
[ "snow_brick", "Snow Brick", "Hardened snow brick." ],
[ "soul_sand", "Soul Sand", "The fragile sand block seems to seal the soul inside." ],
[ "sponge", "Sponge", "The fluffy sponge block can absorb a lot of water." ],
[ "wet_sponge", "Wet Sponge", "Saturated sponge absorbed in water, can be recycled after drying." ],
[ "terracotta_white", "White Terracotta", "Hard terracotta." ],
[ "terracotta_orange", "Orange Terracotta", "Hard terracotta." ],
[ "terracotta_magenta", "Magenta Terracotta", "Hard terracotta." ],
[ "terracotta_light_blue", "Light Blue Terracotta", "Hard terracotta." ],
[ "terracotta_yellow", "Yellow Terracotta", "Hard terracotta." ],
[ "terracotta_lime", "Lime Terracotta", "Hard terracotta." ],
[ "terracotta_pink", "Pink Terracotta", "Hard terracotta." ],
[ "terracotta_gray", "Gray Terracotta", "Hard terracotta." ],
[ "terracotta_light_gray", "Light Gray Terracotta", "Hard terracotta." ],
[ "terracotta_cyan", "Cyan Terracotta", "Hard terracotta." ],
[ "terracotta_purple", "Purple Terracotta", "Hard terracotta." ],
[ "terracotta_blue", "Blue Terracotta", "Hard terracotta." ],
[ "terracotta_brown", "Brown Terracotta", "Hard terracotta." ],
[ "terracotta_green", "Green Terracotta", "Hard terracotta." ],
[ "terracotta_red", "Red Terracotta", "Hard terracotta." ],
[ "terracotta_black", "Black Terracotta", "Hard terracotta." ],
[ "tnt", "Tnt", "It will explode after being activated." ],
[ "wood_oak", "Oak Wood", "Fresh log just cut down." ],
[ "wood_birch", "Birch Wood", "Fresh log just cut down." ],
[ "wood_spruce", "Spruce Wood", "Fresh log just cut down." ],
[ "wood_jungle", "Jungle Wood", "Fresh log just cut down." ],
[ "wood_acacia", "Acacia Wood", "Fresh log just cut down." ],
[ "wood_dark_oak", "Dark Oak Wood", "Fresh log just cut down." ],
[ "fishing_rod", "Fishing Rod", "Can be used for fishing." ],
[ "wood_stripped_oak", "Oak Stripped Wood", "A Log peeled off the bark." ],
[ "wood_stripped_birch", "Birch Stripped Wood", "A Log peeled off the bark." ],
[ "wood_stripped_spruce", "Spruce Stripped Wood", "A Log peeled off the bark." ],
[ "wood_stripped_jungle", "Jungle Stripped Wood", "A Log peeled off the bark." ],
[ "wood_stripped_acacia", "Acacia Stripped Wood", "A Log peeled off the bark." ],
[ "wood_stripped_dark_oak", "Dark Oak Stripped Wood", "A Log peeled off the bark." ],
[ "allium", "Allium", "A small flower." ],
[ "anvil", "Anvil", "Used to repair broken tools." ],
[ "azure_bluet", "Azure Bluet", "A small flower." ],
[ "wooden_bed_red", "Wooden Bed Red", "This is a bed, used to reset the respawn point." ],
[ "blue_orchid", "Blue Orchid", "A small flower." ],
[ "book_block", "Book Block", "The ocean of knowledge." ],
[ "bookcase_oak", "Bookcase Oak", "A shelf with many books, can store items." ],
[ "brewing_stand", "Brewing Stand", "Brew potion with various effects." ],
[ "brown_mushroom", "Brown Mushroom", "A brown mushroom." ],
[ "cake", "Cake", "A Creamy cake, can be cut into slices." ],
[ "candle", "Candle", "This is a candle." ],
[ "candle_holder", "Candle Holder", "Candlestick with western characteristics." ],
[ "cauldron", "Cauldron", "This is a cauldron." ],
[ "chair_oak", "Wooden Chair Oak", "A wooden chair." ],
[ "chandeliers", "Chandeliers", "Bright and luxurious crystal chandelier." ],
[ "stone_chest", "Stone Chest", "Store items." ],
[ "cobweb", "Cobweb", "A spider web, can trap various creatures." ],
[ "dandelion", "Dandelion", "A small flower." ],
[ "daylight_sensor", "Daylight Sensor", "Continuously output the redstone signal under the sunlight." ],
[ "daylight_sensor_inverted", "Moonlight Sensor", "Continuously output the redstone signal under the moonlight." ],
[ "dispenser", "Dispenser", "Launches an item when the redstone signal is activated." ],
[ "ender_chest", "Ender Chest", "The quantum effect makes all ender chests share a space." ],
[ "fern", "Fern", "A spore plant." ],
[ "fire_lamp", "Fire Lamp", "Provides bright lighting." ],
[ "wooden_pressure_plate", "Wooden Pressure Plate", "Activate the redstone signal after stepping." ],
[ "stone_pressure_plate", "Stone Pressure Plate", "Activate the redstone signal after stepping." ],
[ "iron_pressure_plate", "Iron Pressure Plate", "Activate the redstone signal after stepping." ],
[ "golden_pressure_plate", "Golden Pressure Plate", "Activate the redstone signal after stepping." ],
[ "jukebox", "Jukebox", "Put in a record and enjoy the music." ],
[ "grass", "Grass", "This is a grass." ],
[ "iron_door", "Iron Door", "The essential part of the house." ],
[ "lilac", "Lilac", "A large plant." ],
[ "orange_tulip", "Orange Tulip", "A small flower." ],
[ "red_tulip", "Red Tulip", "A small flower." ],
[ "white_tulip", "White Tulip", "A small flower." ],
[ "pink_tulip", "Pink Tulip", "A small flower." ],
[ "painting_2x2", "Painting 2X2", "Welcome to contribute. 0w0" ],
[ "peony", "Peony", "A large plant." ],
[ "poppy", "Poppy", "A small flower." ],
[ "pumpkin", "Pumpkin", "A whole pumpkin." ],
[ "pumpkin_carved", "Carved Pumpkin", "Carved pumpkin with Halloween pattern." ],
[ "red_mushroom", "Red Mushroom", "A red mushroom." ],
[ "rose_bush", "Rose Bush", "A large plant." ],
[ "sapling_oak", "Oak Sapling", "A sapling, grows into an oak tree after planting." ],
[ "sapling_birch", "Birch Sapling", "A sapling, grows into a birch tree after planting." ],
[ "sapling_jungle", "Jungle Sapling", "A sapling, grows into a jungle tree after planting." ],
[ "sapling_spruce", "Spruce Sapling", "A sapling, grows into a spruce tree after planting." ],
[ "sapling_acacia", "Acacia Sapling", "A sapling, grows into an acacia tree after planting." ],
[ "sapling_dark_oak", "Dark Oak Sapling", "A sapling, grows into a dark oak tree after planting." ],
[ "sign", "Sign", "Not available for now." ],
[ "stone_button", "Stone Button", "Controls the activation state of the redstone circuit." ],
[ "wooden_button", "Wooden Button", "Controls the activation state of the redstone circuit." ],
[ "sunflower", "Sunflower", "A large plant." ],
[ "watermelon", "Watermelon", "A whole watermelon, looks very full and sweet." ],
[ "wooden_door_oak", "Wooden Oak Door", "The essential part of the house." ],
[ "wooden_door_birch", "Wooden Birch Door", "The essential part of the house." ],
[ "wooden_door_spruce", "Wooden Spruce Door", "The essential part of the house." ],
[ "wooden_door_jungle", "Wooden Jungle Door", "The essential part of the house." ],
[ "wooden_door_acacia", "Wooden Acacia Door", "The essential part of the house." ],
[ "wooden_door_dark_oak", "Wooden Dark Oak Door", "The essential part of the house." ],
[ "table_oak", "Wooden Oak Table", "A wooden table." ],
[ "cabinet_oak", "Wooden Oak Cabinet", "A table cabinet, can store items." ],
[ "apple", "Apple", "A ripe red apple." ],
[ "baked_potato", "Baked Potato", "Roasted potatoes." ],
[ "blaze_powder", "Blaze Powder", "The energy source of brewing." ],
[ "blaze_rod", "Blaze Rod", "This is a hot rod." ],
[ "bowl", "Bowl", "A big and round bowl." ],
[ "cake_piece", "Cake Piece", "A piece of cake." ],
[ "carrot", "Carrot", "A vitamin-rich carrots." ],
[ "chorus_fruit", "Chorus Fruit", "A fruit of chorus trees." ],
[ "cooked_chicken", "Cooked Chicken", "A roasted turkey, has a crispy chicken flavor." ],
[ "cookie", "Cookie", "A sweet cookie." ],
[ "diamond", "Diamond", "" ],
[ "dried_kelp", "Dried Kelp", "A dry kelp." ],
[ "egg", "Egg", "This is an egg." ],
[ "emerald", "Emerald", "" ],
[ "ender_eye", "Ender Eye", "You feel something is watching you." ],
[ "ender_pearl", "Ender Pearl", "This is a pearl that releases unknown magical energy." ],
[ "fermented_spider_eye", "Fermented Spider Eye", "A fermented spider eye." ],
[ "ghast_tear", "Ghast Tear", "This is a tear crystal of ghast." ],
[ "glass_bottle", "Glass Bottle", "A transparent glass bottle." ],
[ "glistering_melon_slice", "Glistering Melon Slice", "Can be used for brewing." ],
[ "glowstone_dust", "Glowstone Dust", "Glowing glowstone powder." ],
[ "golden_apple", "Golden Apple", "There are special effects bonus after eating." ],
[ "golden_carrot", "Golden Carrot", "There are special effects bonus after eating." ],
[ "gunpowder", "Gunpowder", "A flammable sulfurized mixture." ],
[ "heart_of_sea", "Heart Of Sea", "The essence of the ocean." ],
[ "ink_sac", "Ink Sac", "This is a cuttlefish tentacle." ],
[ "lapis_lazuli", "Lapis Lazuli", "" ],
[ "magma_cream", "Magma Cream", "A magma jelly." ],
[ "melon_seed", "Melon Seed", "Watermelon seeds, can be grown into watermelon." ],
[ "melon_slice", "Melon Slice", "A slice of watermelon, a must for summer." ],
[ "mushroom_stew", "Mushroom Stew", "A bowl of mushroom soup." ],
[ "nether_brick", "Nether Brick", "A nether brick, can be stacked into nether brick blocks." ],
[ "nether_star", "Nether Star", "A wither's drop." ],
[ "nether_wart", "Nether Wart", "Special crops of hell." ],
[ "phantom_membrane", "Phantom Membrane", "A transparent phantom wing." ],
[ "popped_chorus_fruits", "Popped Chorus Fruits", "Rich juice!" ],
[ "potato", "Potato", "A Raw potato." ],
[ "prismarine_crystals", "Prismarine Crystals", "A piece of prismarine crystals." ],
[ "prismarine_shard", "Prismarine Shard", "A prismarine shard." ],
[ "quartz", "Quartz", "" ],
[ "pufferfish", "Pufferfish", "A very sweet puffer fish." ],
[ "pumpkin_pie", "Pumpkin Pie", "A big pumpkin pie." ],
[ "pumpkin_seed", "Pumpkin Seed", "Pumpkin seeds, can grow into pumpkins." ],
[ "raw_beef", "Raw Beef", "A piece of raw beef." ],
[ "raw_chicken", "Raw Chicken", "Would you like to eat raw chicken if it is not cooked?" ],
[ "scute", "Scute", "A scale of the turtle." ],
[ "seed", "Seed", "Seeds of wheat, can grow into wheat." ],
[ "shulker_shell", "Shulker Shell", "A hard shell of a shulker." ],
[ "slimeball", "Slimeball", "Looks very tasty." ],
[ "steak", "Steak", "Looks very tasty." ],
[ "beetroot", "Beetroot", "This is a beetroot." ],
[ "raw_cod", "Raw Cod", "A lively cod." ],
[ "cooked_cod", "Cooked Cod", "A delicious cod." ],
[ "raw_mutton", "Raw Mutton", "Raw lamb." ],
[ "cooked_mutton", "Cooked Mutton", "Cooked lamb." ],
[ "raw_porkchop", "Raw Porkchop", "This is a piece of raw pork." ],
[ "cooked_porkchop", "Cooked Porkchop", "A delicious pork chop." ],
[ "raw_rabbit", "Raw Rabbit", "Raw rabbit meat." ],
[ "cooked_rabbit", "Cooked Rabbit", "Cooked rabbit meat." ],
[ "raw_salmon", "Raw Salmon", "A lively salmon." ],
[ "cooked_salmon", "Cooked Salmon", "A delicious salmon." ],
[ "dye_white", "White Dye", "A dye that can be used for dyeing." ],
[ "dye_orange", "Orange Dye", "A dye that can be used for dyeing." ],
[ "dye_magenta", "Magenta Dye", "A dye that can be used for dyeing." ],
[ "dye_light_blue", "Light Blue Dye", "A dye that can be used for dyeing." ],
[ "dye_yellow", "Yellow Dye", "A dye that can be used for dyeing." ],
[ "dye_lime", "Lime Dye", "A dye that can be used for dyeing." ],
[ "dye_pink", "Pink Dye", "A dye that can be used for dyeing." ],
[ "dye_gray", "Gray Dye", "A dye that can be used for dyeing." ],
[ "dye_light_gray", "Light Gray Dye", "A dye that can be used for dyeing." ],
[ "dye_cyan", "Cyan Dye", "A dye that can be used for dyeing." ],
[ "dye_purple", "Purple Dye", "A dye that can be used for dyeing." ],
[ "dye_blue", "Blue Dye", "A dye that can be used for dyeing." ],
[ "dye_brown", "Brown Dye", "A dye that can be used for dyeing." ],
[ "dye_green", "Green Dye", "A dye that can be used for dyeing." ],
[ "dye_red", "Red Dye", "A dye that can be used for dyeing." ],
[ "dye_black", "Black Dye", "A dye that can be used for dyeing." ],
[ "fire_charge", "Fire Charge", "A burning flame bomb." ],
[ "firework_rocket", "Firework Rocket", "This is a firework rocket." ],
[ "iron_nugget", "Iron Nugget", "" ],
[ "gold_nugget", "Gold Nugget", "" ],
[ "kelp", "Kelp", "A long kelp." ],
[ "lighter", "Lighter", "Let the flame burn more violently!" ],
[ "map_paper", "Map Paper", "Record a map of each chunk." ],
[ "nautilus_shell", "Nautilus Shell", "Why not ask the magical parrot conch?" ],
[ "rabbit_foot", "Rabbit Foot", "Rabbit's sturdy foot." ],
[ "rabbit_hide", "Rabbit Hide", "Rabbit furry fur." ],
[ "redstone", "Redstone", "" ],
[ "rotten_flesh", "Rotten Flesh", "A piece of meat that have been rotting for a long time." ],
[ "spider_eye", "Spider Eye", "A spider eye." ],
[ "totem_of_undying", "Totem Of Undying", "Use it to escape a death." ],
[ "wool_white", "White Wool", "Soft and elastic wool." ],
[ "wool_orange", "Orange Wool", "Soft and elastic wool." ],
[ "wool_magenta", "Magenta Wool", "Soft and elastic wool." ],
[ "wool_light_blue", "Light Blue Wool", "Soft and elastic wool." ],
[ "wool_yellow", "Yellow Wool", "Soft and elastic wool." ],
[ "wool_lime", "Lime Wool", "Soft and elastic wool." ],
[ "wool_pink", "Pink Wool", "Soft and elastic wool." ],
[ "wool_gray", "Gray Wool", "Soft and elastic wool." ],
[ "wool_light_gray", "Light Gray Wool", "Soft and elastic wool." ],
[ "wool_cyan", "Cyan Wool", "Soft and elastic wool." ],
[ "wool_purple", "Purple Wool", "Soft and elastic wool." ],
[ "wool_blue", "Blue Wool", "Soft and elastic wool." ],
[ "wool_brown", "Brown Wool", "Soft and elastic wool." ],
[ "wool_green", "Green Wool", "Soft and elastic wool." ],
[ "wool_red", "Red Wool", "Soft and elastic wool." ],
[ "wool_black", "Black Wool", "Soft and elastic wool." ],
[ "wooden_axe", "Wooden Axe", "A wooden Axe, better than the grass one." ],
[ "wooden_pickaxe", "Wooden Pickaxe", "A wooden pickaxe, better than the grass one." ],
[ "wooden_sword", "Wooden Sword", "A sword made of wood." ],
[ "platform_oak", "Oak Platform", "A wooden platform." ],
[ "platform_birch", "Birch Platform", "A wooden platform." ],
[ "platform_spruce", "Spruce Platform", "A wooden platform." ],
[ "platform_jungle", "Jungle Platform", "A wooden platform." ],
[ "platform_acacia", "Acacia Platform", "A wooden platform." ],
[ "platform_dark_oak", "Dark Oak Platform", "A wooden platform." ],
[ "iron_axe", "Iron Axe", "An axe made of iron." ],
[ "iron_pickaxe", "Iron Pickaxe", "A pickaxe made of iron." ],
[ "iron_sword", "Iron Sword", "A sword made of iron." ],
[ "golden_axe", "Golden Axe", "An axe made of gold." ],
[ "golden_pickaxe", "Golden Pickaxe", "A pickaxe made of gold." ],
[ "golden_sword", "Golden Sword", "A sword made of gold." ],
[ "diamond_axe", "Diamond Axe", "An axe made of diamond." ],
[ "diamond_pickaxe", "Diamond Pickaxe", "A pickaxe made of diamond." ],
[ "diamond_sword", "Diamond Sword", "A sword made of diamond." ],
[ "leather_helmet", "Leather Helmet", "A hat made of leather." ],
[ "leather_chestplate", "Leather Chestplate", "A cloth made of leather." ],
[ "leather_leggings", "Leather Leggings", "A pant made of leather." ],
[ "iron_helmet", "Iron Helmet", "A helmet made of iron." ],
[ "iron_chestplate", "Iron Chestplate", "A chestplate made of iron." ],
[ "iron_leggings", "Iron Leggings", "leggings made of iron." ],
[ "golden_helmet", "Golden Helmet", "A helmet made of gold." ],
[ "golden_chestplate", "Golden Chestplate", "A chestplate made of gold." ],
[ "golden_leggings", "Golden Leggings", "leggings made of gold." ],
[ "diamond_helmet", "Diamond Helmet", "A helmet made of diamond." ],
[ "diamond_chestplate", "Diamond Chestplate", "A chestplate made of diamond." ],
[ "diamond_leggings", "Diamond Leggings", "leggings made of diamond." ],
[ "potion_water", "Water Potion", "A bottle of water, can be brewed into potions with various effects." ],
[ "potion_awkward", "Awkward Potion", "A bottle of crude potion, can be obtained by refining different materials." ],
[ "potion_strength", "Strength Potion", "A potion full of power." ],
[ "potion_strength_long", "Super Strength Potion", "A potion full of power." ],
[ "potion_swiftness", "Swiftness Potion", "Move faster after drinking." ],
[ "potion_swiftness_long", "Super Swiftness Potion", "Move faster after drinking." ],
[ "potion_slowness", "Slowness Potion", "A slow-paced potion." ],
[ "potion_slowness_long", "Super Slowness Potion", "A slow-paced potion." ],
[ "potion_leaping", "Leaping Potion", "Improve jumping power." ],
[ "potion_leaping_long", "Super Leaping Potion", "Improve jumping power." ],
[ "potion_healing", "Healing Potion", "Instantly restores health." ],
[ "potion_healing_super", "Super Healing Potion", "Instantly restores health." ],
[ "potion_harming", "Harming Potion", "Contains various harmful substances." ],
[ "potion_harming_super", "SuperHarming Potion", "Contains various harmful substances." ],
[ "potion_poison", "Poison Potion", "A poisonous potion." ],
[ "potion_poison_long", "Super Poison Potion", "A poisonous potion." ],
[ "potion_regeneration", "Regeneration Potion", "Continuously improves health." ],
[ "potion_regeneration_long", "Super Regeneration Potion", "Continuously improves health." ],
[ "potion_fire_resistance", "Fire Resistance Potion", "Immune to flame and lava." ],
[ "potion_fire_resistance_long", "Super Fire Resistance Potion", "Immune to flame and lava." ],
[ "potion_water_breathing", "Water-Breathing Potion", "You can breathe in water after drinking." ],
[ "potion_water_breathing_long", "Super Water-Breathing Potion", "You can breathe in water after drinking." ],
[ "potion_night_vision", "Night Vision Potion", "See in dark." ],
[ "potion_night_vision_long", "Super Night Vision Potion", "See in dark." ],
[ "potion_invisibility", "Invisibility Potion", "A unscientific potion." ],
[ "potion_invisibility_long", "Super Invisibility Potion", "A unscientific potion." ],
[ "potion_slow_falling", "Slow Falling Potion", "Fall very slowly." ],
[ "potion_slow_falling_long", "Super Slow Falling Potion", "Fall very slowly." ],
[ "potion_weakness", "Weakness Potion", "Collapse after drinking." ],
[ "potion_weakness_long", "Super Weakness Potion", "Collapse after drinking." ],
[ "enchantment_table", "Enchantment Table", "Enchant every tools!" ],
[ "enchanted_book", "Enchanted Book", "A book full of spells." ],
[ "shears", "Shears", "Used for shearing or carving." ],
[ "shotgun", "Shotgun", "A powerful shotgun." ],
[ "stone_hoe", "Stone Hoe", "Used to reclaim land." ],
[ "green_wire", "Green Wire", "Place to connect the redstone circuit." ],
[ "blue_wire", "Blue Wire", "Place to connect the redstone circuit." ],
[ "yellow_wire", "Yellow Wire", "Place to connect the redstone circuit." ],
[ "wire_cutter", "Wire Cutter", "Place to connect the redstone circuit." ],
[ "lever", "Lever", "Controls the activation state of the redstone circuit." ],
[ "redstone_torch", "Redstone Torch", "Right click to activate or deactivate." ],
[ "bomb", "Bomb", "A bomb that can destroy the tiles." ],
[ "grenade", "Grenade", "Do damage to enemies without destroying the tiles." ],
[ "handgun", "Handgun", "A handgun." ],
[ "rifle", "Rifle", "A rifle." ],
[ "fire_gun", "Fire Gun", "A fire gun." ],
[ "super_iron_sword", "Wrought Iron Sword", "A sword made of iron." ],
[ "super_golden_sword", "Wide Golden Sword", "A sword made of gold." ],
[ "super_diamond_sword", "Super Diamond Sword", "A sharp diamond sword." ],
[ "copper_sword", "Copper Sword", "A sword made of copper." ],
[ "super_copper_sword", "Wide Copper Sword", "A sword made of copper." ],
[ "tin_sword", "Tin Sword", "A sword made of tin." ],
[ "super_tin_sword", "Wide Tin Sword", "A sword made of tin." ],
[ "lead_sword", "Lead Sword", "A sword made of lead." ],
[ "super_lead_sword", "Heavy Lead Sword", "A sword made of lead." ],
[ "silver_sword", "Silver Sword", "A sword made of silver." ],
[ "super_silver_sword", "Long Silver Sword", "A sword made of silver." ],
[ "bronze_sword", "Bronze Sword", "A sword made of bronze." ],
[ "super_bronze_sword", "Wide Bronze Sword", "A sword made of bronze." ],
[ "steel_sword", "Steel Sword", "A sword made of steel." ],
[ "super_steel_sword", "Long Steel Sword", "A sword made of steel." ],
[ "ghost_sword", "Sun Light Sword", "A sword that injects sunlight energy." ],
[ "glow_ball", "Glow Ball", "Provide lighting." ],
[ "glow_bomb", "Glow Bomb", "Makes damage to enemies, does not destroy the tile, provides short-term bright lighting." ],
[ "lighting_bow", "Lighting Bow", "Shoots light arrows and provides lighting effects." ],
[ "fire_bullet", "Soil Bullet", "A common bullet." ],
[ "iron_bullet", "Iron Bullet", "An iron bullet." ],
[ "silver_bullet", "Silver Bullet", "A silver bullet." ],
[ "lighting_arrow", "Lighting Arrow", "A glowing arrow." ],
[ "cross_bow", "Cross Bow", "Shoot arrows quickly." ],
[ "shot_bow", "Shot Bow", "Shoot multiple arrows quickly." ],
[ "super_cross_bow", "Super Cross Bow", "Shoot arrows very quick." ],
[ "boomerang", "Boomerang", "Throw out and fly back!" ],
[ "wooden_boomerang", "Wooden Boomerang", "Throw out and fly back!" ],
[ "star_arrow", "Star Arrow", "A dropped arrow." ],
[ "fire_boomerang", "Fire Boomerang", "A burning boomerang!" ],
[ "blood_arrow", "Bloody Arrow", "Keep sucking blood." ],
[ "blood_bow", "Bloody Bow", "Shoots bloody arrows." ],
[ "blue_stone_bow", "Blue Stone Bow", "Has a faster attack speed and attack frequency." ],
[ "ice_arrow", "Ice Arrow", "A cold arrow." ],
[ "ice_bow", "Ice Bow", "Shoots ice arrows." ],
[ "chast_bow", "Sword Bow", "Shoots swrod arrows." ],
[ "sword_arrow", "Sword Arrow", "A sword shape arrow, auto aiminig at the target." ],
[ "air_sword", "Air Sword", "Cut through the air." ],
[ "super_air_sword", "Super Air Sword", "Cut through the air." ],
[ "amethyst_staff", "Amethyst Staff", "A magical staff." ],
[ "lighting_staff", "Lighting Staff", "A radiant staff." ],
[ "water_staff", "Water Staff", "A water magic staff." ],
[ "ice_staff", "Ice Staff", "A cold staff." ],
[ "shadow_staff", "Shadow Staff", "A staff controlled by dark magic." ],
[ "red_torch", "Red Torch", "A torch glowing red." ],
[ "yellow_torch", "Yellow Torch", "A torch glowing yellow." ],
[ "blue_torch", "Blue Torch", "A torch glowing blue." ],
[ "green_torch", "Green Torch", "A torch glowing green." ],
[ "white_torch", "White Torch", "A torch glowing white." ],
[ "flesh_stone", "Flesh Stone", "A block made of unnamed objects." ],
[ "flesh_dirt", "Flesh Dirt", "A block made of unknown meat." ],
[ "flesh_gut", "Flesh Gut", "An Inexplicable block." ],
[ "mycelium", "Mycelium", "A Block made of fungi." ],
[ "tainted_stone", "Tainted Stone", "A corroded stone." ],
[ "tainted_dirt", "Tainted Dirt", "A corroded dirt." ],
[ "volcano_stone", "Volcano Stone", "A stone has been contact with lava for a long time." ],
[ "volcano_dirt", "Volcano Dirt", "A loose lava soil." ],
[ "ore_tin", "Tin Ore", "A mineral ore, require further processing." ],
[ "ore_copper", "Copper Ore", "A mineral ore, require further processing." ],
[ "ore_lead", "Lead Ore", "A mineral ore, require further processing." ],
[ "ore_silver", "Silver Ore", "A mineral ore, require further processing." ],
[ "bronze_helmet", "Bronze Helmet", "A helmet made of bronze." ],
[ "bronze_chestplate", "Bronze Chestplate", "A chestplate made of bronze." ],
[ "bronze_leggings", "Bronze Leggings", "Leggings made of bronze." ],
[ "copper_helmet", "Copper Helmet", "A helmet made of copper." ],
[ "copper_chestplate", "Copper Chestplate", "A chestplate made of copper." ],
[ "copper_leggings", "Copper Leggings", "Leggings made of copper." ],
[ "lead_helmet", "Lead Helmet", "A helmet made of lead." ],
[ "lead_chestplate", "Lead Chestplate", "A chestplate made of lead." ],
[ "lead_leggings", "Lead Leggings", "Leggings made of lead." ],
[ "nether_helmet", "Netherite Helmet", "An equipment reinforced by netherite." ],
[ "nether_chestplate", "Netherite Chestplate", "An equipment reinforced by netherite." ],
[ "nether_leggings", "Netherite Leggings", "An equipment reinforced by netherite." ],
[ "silver_helmet", "Silver Helmet", "A helmet made of silver." ],
[ "silver_chestplate", "Silver Chestplate", "A chestplate made of silver." ],
[ "silver_leggings", "Silver Leggings", "Leggings made of silver." ],
[ "steel_helmet", "Steel Helmet", "A helmet made of steel." ],
[ "steel_chestplate", "Steel Chestplate", "A chestplate made of steel." ],
[ "steel_leggings", "Steel Leggings", "Leggings made of steel." ],
[ "tin_helmet", "Tin Helmet", "A helmet made of tin." ],
[ "tin_chestplate", "Tin Chestplate", "A chestplate made of tin." ],
[ "tin_leggings", "Tin Leggings", "Leggings made of tin." ],
[ "palm_plank", "Palm Plank", "A wooden building material." ],
[ "volcano_plank", "Volcano Plank", "A red wooden building material." ],
[ "tainted_plank", "Tainted Plank", "A tainted wooden building material." ],
[ "wood_palm", "Palm Wood", "A fresh log just cut down." ],
[ "wood_volcano", "Volcano Wood", "A wood that lives in a lava environment." ],
[ "wood_tainted", "Tainted Wood", "A fresh log just cut down." ],
[ "wood_stripped_palm", "Palm Stripped Wood", "A log stripped of bark." ],
[ "wood_stripped_volcano", "Volcano Stripped Wood", "A log stripped of bark." ],
[ "wood_stripped_tainted", "Tainted Stripped Wood", "A log stripped of bark." ],
[ "sapling_tainted", "Tainted Sapling", "A sapling, grows into a tainted tree after planting." ],
[ "sapling_palm", "Palm Sapling", "A sapling, grows into a palm tree after planting." ],
[ "sapling_cactus", "Cactus", "A small cactus, will grow into a large cactus after planting." ],
[ "sapling_volcano", "Volcano Sapling", "A sapling, grows into a volcano tree after planting." ],
[ "sapling_bare_oak", "Bare Oak Sapling", "A sapling, grows into a bark oak tree after planting." ],
[ "platform_palm", "Palm Platform", "A wooden platform." ],
[ "platform_volcano", "Volcano Platform", "A wooden platform." ],
[ "platform_tainted", "Tainted Platform", "A wooden platform." ],
[ "wooden_door_palm", "Wooden Palm Door", "The essential part of the house." ],
[ "wooden_door_volcano", "Wooden Volcano Door", "The essential part of the house." ],
[ "wooden_door_tainted", "Wooden Tainted Door", "The essential part of the house." ],
[ "fence_palm", "Palm Fence", "A wooden fence." ],
[ "fence_volcano", "Volcano Fence", "A wooden fence." ],
[ "fence_tainted", "Tainted Fence", "A wooden fence." ],
[ "ore_ancient_debris", "Ancient Debris", "A mineral ore, require further processing." ],
[ "block_netherite", "Netherite Block", "A block made of netherite." ],
[ "netherite_ingot", "Netherite Ingot", "" ],
[ "netherite_scrap", "Netherite Scrap", "Used to craft netherite ingot." ],
[ "dried_kelp_block", "Dried Kelp Block", "A bundle of dried kelp." ],
[ "blue_ice", "Blue Ice", "Smoother than packed ice, the unique structure inside makes it emit a faint light." ],
[ "ore_nether_quartz", "Nether Quartz Ore", "A mineral ore, require further processing." ],
[ "block_quartz", "Quartz Block", "A Quartz compressed block, building material." ],
[ "platform_end_stone", "End Stone Platform", "A platform made of end stone." ],
[ "platform_nether_brick", "Nether Brick Platform", "A platform made of nether bricks." ],
[ "platform_prismarine", "Prismarine Platform", "A platform made of prismarine." ],
[ "platform_prismarine_dark", "Prismarine Dark Platform", "A platform made of dark prismarine." ],
[ "platform_purpur", "Purpur Platform", "A platform made of purpur." ],
[ "platform_quartz", "Quartz Platform", "A platform made of quartz." ],
[ "platform_red_sand_stone", "Red Sand Stone Platform ", "A platform made of red sandstone." ],
[ "platform_sandstone", "Sandstone Platform", "A platform made of sand stone." ],
[ "platform_stone_brick", "Stone Brick Platform", "A platform made of stone bricks." ],
[ "stained_glass_white", "White Stained Glass", "This is a stained glass." ],
[ "stained_glass_orange", "Orange Stained Glass", "This is a stained glass." ],
[ "stained_glass_magenta", "Magenta Stained Glass", "This is a stained glass." ],
[ "stained_glass_light_blue", "Light Blue Stained Glass", "This is a stained glass." ],
[ "stained_glass_yellow", "Yellow Stained Glass", "This is a stained glass." ],
[ "stained_glass_lime", "Lime Stained Glass", "This is a stained glass." ],
[ "stained_glass_pink", "Pink Stained Glass", "This is a stained glass." ],
[ "stained_glass_gray", "Gray Stained Glass", "This is a stained glass." ],
[ "stained_glass_light_gray", "Light Gray Stained Glass", "This is a stained glass." ],
[ "stained_glass_cyan", "Cyan Stained Glass", "This is a stained glass." ],
[ "stained_glass_purple", "Purple Stained Glass", "This is a stained glass." ],
[ "stained_glass_blue", "Blue Stained Glass", "This is a stained glass." ],
[ "stained_glass_brown", "Brown Stained Glass", "This is a stained glass." ],
[ "stained_glass_green", "Green Stained Glass", "This is a stained glass." ],
[ "stained_glass_red", "Red Stained Glass", "This is a stained glass." ],
[ "stained_glass_black", "Black Stained Glass", "This is a stained glass." ],
[ "wooden_bed_white", "White Wooden Bed", "This is a bed, used to reset the respawn point." ],
[ "wooden_bed_orange", "Orange Wooden Bed", "This is a bed, used to reset the respawn point." ],
[ "wooden_bed_magenta", "Magenta Wooden Bed", "This is a bed, used to reset the respawn point." ],
[ "wooden_bed_light_blue", "Light Blue Wooden Bed", "This is a bed, used to reset the respawn point." ],
[ "wooden_bed_yellow", "Yellow Wooden Bed", "This is a bed, used to reset the respawn point." ],
[ "wooden_bed_lime", "Lime Wooden Bed", "This is a bed, used to reset the respawn point." ],
[ "wooden_bed_pink", "Pink Wooden Bed", "This is a bed, used to reset the respawn point." ],
[ "wooden_bed_gray", "Gray Wooden Bed", "This is a bed, used to reset the respawn point." ],
[ "wooden_bed_light_gray", "Light Gray Wooden Bed", "This is a bed, used to reset the respawn point." ],
[ "wooden_bed_cyan", "Cyan Wooden Bed", "This is a bed, used to reset the respawn point." ],
[ "wooden_bed_purple", "Purple Wooden Bed", "This is a bed, used to reset the respawn point." ],
[ "wooden_bed_blue", "Blue Wooden Bed", "This is a bed, used to reset the respawn point." ],
[ "wooden_bed_brown", "Brown Wooden Bed", "This is a bed, used to reset the respawn point." ],
[ "wooden_bed_green", "Green Wooden Bed", "This is a bed, used to reset the respawn point." ],
[ "wooden_bed_black", "Black Wooden Bed", "This is a bed, used to reset the respawn point." ],
[ "jack_o_lantern", "Jack-o-Lantern", "A carved jack-o-lantern with halloween motifs." ],
[ "pumpkin_helmet", "Pumpkin Helmet", "A pumpkin balaclava." ],
[ "shulker_box", "Shulker Box", "Store items in this item." ],
[ "end_rod", "End Rod", "An end lighting tool." ],
[ "lantern", "Lantern", "This is a lantern that can be hung." ],
[ "barrel", "Barrel", "Store items." ],
[ "campfire", "Campfire", "Provide lighting." ],
[ "painting_4x2", "Painting 4X2", "Welcome to contribute. 0w0" ],
[ "painting_2x4", "Painting 2X4", "Welcome to contribute. 0w0" ],
[ "painting_4x4", "Painting 4X4", "Welcome to contribute. 0w0" ],
[ "painting_8x4", "Painting 8X4", "Welcome to contribute. 0w0" ],
[ "painting_8x6", "Painting 8X6", "Welcome to contribute. 0w0" ],
[ "painting_8x8", "Painting 8X8", "Welcome to contribute. 0w0" ],
[ "flower_pot", "Flower Pot", "A flower pot where small flowers can be placed." ],
[ "flower_pot_large", "Large Flower Pot", "A flower pot where large flowers can be placed." ],
[ "trapped_chest", "Trapped Chest", "Store items and send a redstone signal when opened." ],
[ "cocoa_bean", "Cocoa Bean", "A food material growing on jungle wood." ],
[ "table_spruce", "Spruce Table", "A wooden table." ],
[ "table_birch", "Birch Table", "A wooden table." ],
[ "table_jungle", "Jungle Table", "A wooden table." ],
[ "table_acacia", "Acacia Table", "A wooden table." ],
[ "table_dark_oak", "Dark Oak Table", "A wooden table." ],
[ "table_palm", "Palm Table", "A wooden table." ],
[ "table_volcano", "Wooden Volcano Table", "A wooden table." ],
[ "table_tainted", "Wooden Tainted Table", "A wooden table." ],
[ "cabinet_spruce", "Spruce Cabinet", "A table cabinet, can store items." ],
[ "cabinet_birch", "Birch Cabinet", "A table cabinet, can store items." ],
[ "cabinet_jungle", "Jungle Cabinet", "A table cabinet, can store items." ],
[ "cabinet_acacia", "Acacia Cabinet", "A table cabinet, can store items." ],
[ "cabinet_dark_oak", "Dark Oak Cabinet", "A table cabinet, can store items." ],
[ "cabinet_palm", "Palm Cabinet", "A table cabinet, can store items." ],
[ "cabinet_volcano", "Wooden Volcano Cabinet", "A table cabinet, can store items." ],
[ "cabinet_tainted", "Wooden Tainted Cabinet", "A table cabinet, can store items." ],
[ "chair_spruce", "Spruce Chair", "A wooden chair." ],
[ "chair_birch", "Birch Chair", "A wooden chair." ],
[ "chair_jungle", "Jungle Chair", "A wooden chair." ],
[ "chair_acacia", "Acacia Chair", "A wooden chair." ],
[ "chair_dark_oak", "Dark Oak Chair", "A wooden chair." ],
[ "chair_palm", "Palm Chair", "A wooden chair." ],
[ "chair_volcano", "Wooden Volcano Chair", "A wooden chair." ],
[ "chair_tainted", "Wooden Tainted Chair", "A wooden chair." ],
[ "bookcase_spruce", "Spruce Bookcase", "A shelf with many books, can store items." ],
[ "bookcase_birch", "Birch Bookcase", "A shelf with many books, can store items." ],
[ "bookcase_jungle", "Jungle Bookcase", "A shelf with many books, can store items." ],
[ "bookcase_acacia", "Acacia Bookcase", "A shelf with many books, can store items." ],
[ "bookcase_dark_oak", "Dark Oak Bookcase", "A shelf with many books, can store items." ],
[ "bookcase_palm", "Palm Bookcase", "A shelf with many books, can store items." ],
[ "bookcase_volcano", "Wooden Volcano Bookcase", "A shelf with many books, can store items." ],
[ "bookcase_tainted", "Wooden Tainted Bookcase", "A shelf with many books, can store items." ],
[ "bench_oak", "Oak Bench", "A bench." ],
[ "bench_spruce", "Spruce Bench", "A bench." ],
[ "bench_birch", "Birch Bench", "A bench." ],
[ "bench_jungle", "Jungle Bench", "A bench." ],
[ "bench_acacia", "Acacia Bench", "A bench." ],
[ "bench_dark_oak", "Dark Oak Bench", "A bench." ],
[ "bench_palm", "Palm Bench", "A bench." ],
[ "bench_volcano", "Volcano Bench", "A bench." ],
[ "bench_tainted", "Tainted Bench", "A bench." ],
[ "prismarine_mud", "Prismarine Mud", "A block covering the sea floor." ],
[ "snow_queen_loot", "Loot of Snow Queen", "To celebrate the defeat of the Snow Queen." ],
[ "nether_destroyer_loot", "Loot of Nether Destroyer", "To celebrate the defeat of the Nether Destroyer." ],
[ "table_nether", "Nether Table", "A table in nether." ],
[ "cabinet_nether", "Nether Cabinet", "A table cabinet, can store items." ],
[ "bench_nether", "Nether Bench", "A bench." ],
[ "chair_nether", "Nether Chair", "A chair in nether." ],
[ "bookcase_nether", "Nether Bookcase", "A shelf with many books, can store items." ],
[ "door_nether", "Nether Door", "The essential part of the house." ],
[ "nether_chest", "Nether Chest", "Store items." ],
[ "nether_lamp", "Nether Lamp", "Provides bright lighting." ],
[ "mana_piece", "Magic Fragment", "Increase the limit of magic by 10 when eating." ],
[ "wooden_hoe", "Wooden Hoe", "Used to reclaim land." ],
[ "steel_axe", "Steel Axe", "An axe made of steel." ],
[ "bronze_axe", "Bronze Axe", "An axe made of bronze." ],
[ "silver_axe", "Silver Axe", "An axe made of silver." ],
[ "lead_axe", "Lead Axe", "An axe made of lead." ],
[ "tin_axe", "Tin Axe", "An axe made of tin." ],
[ "copper_axe", "Copper Axe", "An axe made of copper." ],
[ "steel_pickaxe", "Steel Pickaxe", "A pickaxe made of steel." ],
[ "bronze_pickaxe", "Bronze Pickaxe", "A pickaxe made of bronze." ],
[ "silver_pickaxe", "Silver Pickaxe", "A pickaxe made of silver." ],
[ "lead_pickaxe", "Lead Pickaxe", "A pickaxe made of lead." ],
[ "tin_pickaxe", "Tin Pickaxe", "A pickaxe made of tin." ],
[ "copper_pickaxe", "Copper Pickaxe", "A pickaxe made of copper." ],
[ "potion_glowing", "Glowing Potion", "You will glow all over after drinking." ],
[ "potion_glowing_long", "Super Glowing Potion", "You will glow all over after drinking." ],
[ "glowing_mushroom", "Glowing Mushroom", "A mushroom with slight light." ],
[ "poison_mushroom", "Poison Mushroom", "Do not eat!" ],
[ "large_brown_mushroom", "Large Brown Mushroom", "A bigger brown mushroom." ],
[ "large_red_mushroom", "Large Red Mushroom", "A bigger red mushroom." ],
[ "large_poison_mushroom", "Large Poison Mushroom", "A bigger poison mushroom." ],
[ "gray_feather", "Gray Feather", "This is a gray feather." ],
[ "nether_axe", "Netherite Axe", "An axe reinforced by netherite." ],
[ "nether_pickaxe", "Netherite Pickaxe", "A pickaxe reinforced by netherite." ],
[ "nether_sword", "Netherite Sword", "A sword reinforced by netherite." ],
[ "super_nether_sword", "Super Netherite Sword", "A super sword reinforced by netherite." ],
[ "rocket", "Rocket", "You need a rocket launcher to launch this." ],
[ "nether_altar", "Nether Altar", "There seems to be a terrible enemy sealed inside." ],
[ "snow_glass_ball", "Snow Queue Glass Ball", "The snow queen is sleeping in this glass ball." ],
[ "guardian", "Guardian", "To commemorate defeating a guardian." ]
],
"chemicalFormulas": [
[ "coal", "C" ],
[ "charcoal", "C" ],
[ "diamond", "C" ],
[ "emerald", "Be3Al2(SiO3)6" ],
[ "lapis_lazuli", "(Al6Si6Ca8Na8)12(Al3Si3Na4Cl)2FeS2CaCO3" ],
[ "quartz", "SiO2" ],
[ "redstone", "Si(FeS2)5CrAl2O3Hg3" ],
[ "iron_nugget", "Fe" ],
[ "gold_nugget", "Au" ],
[ "iron_ingot", "Fe" ],
[ "gold_ingot", "Au" ],
[ "redstone_ingot", "Si(FeS2)5CrAl2O3Hg3" ],
[ "copper_ingot", "Cu" ],
[ "tin_ingot", "Sn" ],
[ "bronze_ingot", "SnCu3" ],
[ "lead_ingot", "Pb" ],
[ "silver_ingot", "Ag" ],
[ "steel_ingot", "Fe50C" ],
[ "lithium_ingot", "Li" ],
[ "beryllium_ingot", "Be" ],
[ "sodium_ingot", "Na" ],
[ "magnesium_ingot", "Mg" ],
[ "aluminum_ingot", "Al" ],
[ "titanium_ingot", "Ti" ],
[ "vanadium_ingot", "V" ],
[ "chromium_ingot", "Cr" ],
[ "manganese_ingot", "Mn" ],
[ "cobalt_ingot", "Co" ],
[ "nickel_ingot", "Ni" ],
[ "zinc_ingot", "Zn" ],
[ "gallium_ingot", "Ga" ],
[ "yttrium_ingot", "Y" ],
[ "niobium_ingot", "Nb" ],
[ "molybdenum_ingot", "Mo" ],
[ "palladium_ingot", "Pd" ],
[ "indium_ingot", "In" ],
[ "antimony_ingot", "Sb" ],
[ "tantalum_ingot", "Ta" ],
[ "wolfram_ingot", "W" ],
[ "rhenium_ingot", "Re" ],
[ "osmium_ingot", "Os" ],
[ "iridium_ingot", "Ir" ],
[ "platinum_ingot", "Pt" ],
[ "bismuth_ingot", "Bi" ],
[ "vibranium_ingot", "Vb" ]
]
}
================================================
FILE: liquids/lava.json
================================================
{
"lava": {
"textureData": "lava.png",
"borderTextureData": "lava_border.png",
"texWidth": 1024,
"texHeight": 1024,
"color": [ 244, 255, 255, 255 ],
"paticularColor": [ 255, 200, 100, 0 ],
"isLighting": true,
"lightColor": [ 32, 20, 10, 0 ],
"offsetSpeedX": 0.5,
"offsetSpeedY": 0.5,
"delay": 8,
"stickyRate": 0.4,
"damage": 8,
"buffs": [
{
"id": "fire",
"time": 300
}
],
"noBuffs": []
}
}
================================================
FILE: liquids/water.json
================================================
{
"water": {
"textureData": "water.png",
"borderTextureData": "water_border.png",
"texWidth": 256,
"texHeight": 16,
"color": [ 96, 122, 122, 255 ],
"paticularColor": [ 255, 32, 160, 200 ],
"offsetSpeedX": 0,
"offsetSpeedY": 0,
"delay": 4,
"stickyRate": 0.5,
"damage": 0,
"buffs": [],
"noBuffs": [ "fire" ]
}
}
================================================
FILE: mod_textures/ModTextures.lua
================================================
---@class TC.ModTextures
local ModTextures = class("ModTextures")
local s_instance
---@return TC.ModTextures
function ModTextures.getInstance()
if s_instance == nil then
s_instance = ModTextures.new()
end
return s_instance
end
function ModTextures:__init()
self.textureNameDict = {}
self:loadAll()
end
function ModTextures:loadAll()
local allPngNames = AssetManager.getAllFiles(Path.join(Mod.current.assetRootPath, "mod_textures"), ".png", true, false, false)
for _, pngName in ipairs(allPngNames) do
local realPath = Path.join(Mod.current.assetRootPath, "mod_textures", pngName .. ".png")
self.textureNameDict[pngName] = TextureManager.load(realPath)
end
end
function ModTextures:getTexture(pngName)
return self.textureNameDict[pngName]
end
return ModTextures
================================================
FILE: mod_textures/blade.json
================================================
{
"blade": {
"textureData": "blade.png",
"width": 64,
"height": 64,
"frameXs": 1,
"bringToFront": true
}
}
================================================
FILE: mod_textures/candle_fire.json
================================================
{
"candle_fire": {
"textureData": "candle_fire.png",
"width": 16,
"height": 16,
"frameXs": 4,
"frameSpeed": 8,
"loopPlay": true
}
}
================================================
FILE: mod_textures/candle_fire_blue.json
================================================
{
"candle_fire_blue": {
"textureData": "candle_fire_blue.png",
"width": 16,
"height": 16,
"frameXs": 4,
"frameSpeed": 8,
"loopPlay": true
}
}
================================================
FILE: mod_textures/crack.json
================================================
{
"crack": {
"textureData": "crack.png",
"width": 16,
"height": 16,
"frameXs": 5,
"userDisabled": true
}
}
================================================
FILE: mod_textures/electric_direction.json
================================================
{
"electric_direction": {
"textureData": "electric_direction.png",
"width": 16,
"height": 16,
"frameXs": 4
}
}
================================================
FILE: mod_textures/fire.json
================================================
{
"fire": {
"textureData": "fire.png",
"width": 24,
"height": 24,
"frameXs": 4,
"frameSpeed": 8,
"loopPlay": true
}
}
================================================
FILE: mod_textures/flesh_grass.json
================================================
{
"flesh_grass": {
"textureData": "flesh_grass.png",
"width": 32,
"height": 32,
"frameXs": 5,
"frameYs": 2,
"userDisabled": true
}
}
================================================
FILE: mod_textures/fly_book.json
================================================
{
"fly_book": {
"textureData": "fly_book.png",
"width": 32,
"height": 32,
"userDisabled": true
}
}
================================================
FILE: mod_textures/grass.json
================================================
{
"grass": {
"textureData": "grass.png",
"width": 32,
"height": 32,
"frameXs": 5,
"frameYs": 2,
"userDisabled": true
}
}
================================================
FILE: mod_textures/mycelium_grass.json
================================================
{
"mycelium_grass": {
"textureData": "mycelium_grass.png",
"width": 32,
"height": 32,
"frameXs": 5,
"frameYs": 2,
"userDisabled": true
}
}
================================================
FILE: mod_textures/tainted_grass.json
================================================
{
"tainted_grass": {
"textureData": "tainted_grass.png",
"width": 32,
"height": 32,
"frameXs": 5,
"frameYs": 2,
"userDisabled": true
}
}
================================================
FILE: mod_textures/torch_fire.json
================================================
{
"torch_fire": {
"textureData": "torch_fire.png",
"width": 16,
"height": 16,
"frameXs": 4,
"frameSpeed": 8,
"loopPlay": true
}
}
================================================
FILE: mod_textures/torch_fire_blue.json
================================================
{
"torch_fire_blue": {
"textureData": "torch_fire_blue.png",
"width": 16,
"height": 16,
"frameXs": 4,
"frameSpeed": 8,
"loopPlay": true
}
}
================================================
FILE: mod_textures/torch_fire_green.json
================================================
{
"torch_fire_green": {
"textureData": "torch_fire_green.png",
"width": 16,
"height": 16,
"frameXs": 4,
"frameSpeed": 8,
"loopPlay": true
}
}
================================================
FILE: mod_textures/torch_fire_red.json
================================================
{
"torch_fire_red": {
"textureData": "torch_fire_red.png",
"width": 16,
"height": 16,
"frameXs": 4,
"frameSpeed": 8,
"loopPlay": true
}
}
================================================
FILE: mod_textures/torch_fire_white.json
================================================
{
"torch_fire_white": {
"textureData": "torch_fire_white.png",
"width": 16,
"height": 16,
"frameXs": 4,
"frameSpeed": 8,
"loopPlay": true
}
}
================================================
FILE: mod_textures/torch_fire_yellow.json
================================================
{
"torch_fire_yellow": {
"textureData": "torch_fire_yellow.png",
"width": 16,
"height": 16,
"frameXs": 4,
"frameSpeed": 8,
"loopPlay": true
}
}
================================================
FILE: mod_textures/torch_redstone.json
================================================
{
"torch_redstone": {
"textureData": "torch_redstone.png",
"width": 16,
"height": 16,
"frameXs": 4,
"frameSpeed": 8,
"loopPlay": true,
"tagUsage": "TAG_ADD_FRAME_INDEX_Y"
}
}
================================================
FILE: network/ClientBoundResponse.lua
================================================
---@class Portal.ClientBoundResponse
local ClientBoundResponse = class("ClientBoundResponse")
local s_instance
---@return Portal.ClientBoundResponse
function ClientBoundResponse.getInstance()
if s_instance == nil then
s_instance = ClientBoundResponse.new()
end
return s_instance
end
function ClientBoundResponse:__init()
self.modResponseCallbacks = {}
end
---addResponseCallback
---@param mod Mod
---@param rpcID int
---@param func function
---@param caller any
function ClientBoundResponse:addResponseCallback(mod, rpcID, func, caller)
local found = false
if self.modResponseCallbacks[mod.modId] == nil then
self.modResponseCallbacks[mod.modId] = {}
end
if self.modResponseCallbacks[mod.modId][rpcID] == nil then
self.modResponseCallbacks[mod.modId][rpcID] = {}
end
for _, cb in ipairs(self.modResponseCallbacks[mod.modId][rpcID]) do
if cb[1] == func and cb[2] == caller then
found = true
break
end
end
if found then
return
end
table.insert(self.modResponseCallbacks[mod.modId][rpcID], { func, caller })
end
function ClientBoundResponse:removeResponse(caller)
for _, responseCallbacks in pairs(self.modResponseCallbacks) do
for _, cbs in pairs(responseCallbacks) do
for i = #cbs, 1, -1 do
if cbs[i][2] == caller then
table.remove(cbs, i)
end
end
end
end
end
function ClientBoundResponse:doResponse(mod, rpcID, ...)
local responseCallbacks = self.modResponseCallbacks[mod.modId]
if responseCallbacks == nil then
return
end
local cbs = responseCallbacks[rpcID]
if cbs == nil then
return
end
for _, cb in ipairs(cbs) do
cb[1](cb[2], ...)
end
end
return ClientBoundResponse
================================================
FILE: network/ModNetworkProxyHandler.lua
================================================
---@class TC.ModNetworkProxyHandler
local ModNetworkProxyHandler = class("ModNetworkProxyHandler")
---__init
---@param mod Mod
function ModNetworkProxyHandler:__init(mod)
self.mod = mod
self.isServer = NetMode.current == NetMode.Server
if self.isServer then
self.mod:RegisterServerBoundReaderCallback({
ModNetworkProxyHandler.HandleProxyServerBound, self
})
else
self.mod:RegisterClientBoundReaderCallback({
ModNetworkProxyHandler.HandleProxyClientBound, self
})
end
self.rpcHandlerFuncSB = {}
self.rpcHandlerFuncCB = {}
end
function ModNetworkProxyHandler:RegisterRPCHandlerServerBoundMappings(mappings)
for k, v in ipairs(mappings) do
self:RegisterRPCHandlerServerBound(k, v)
end
end
function ModNetworkProxyHandler:RegisterRPCHandlerClientBoundMappings(mappings)
for k, v in ipairs(mappings) do
self:RegisterRPCHandlerClientBound(k, v)
end
end
function ModNetworkProxyHandler:RegisterRPCHandlerServerBound(rpcID, rpcFunc)
self.rpcHandlerFuncSB[rpcID] = rpcFunc
end
function ModNetworkProxyHandler:RegisterRPCHandlerClientBound(rpcID, rpcFunc)
self.rpcHandlerFuncCB[rpcID] = rpcFunc
end
---RPCWriteVar
---@param buffer ByteStream
local function RPCReadVar(buffer)
local flag = buffer:readIntVarLen()
local v
if flag == 1 then
local isDouble = buffer:readBoolean()
if isDouble then
v = buffer:readDouble()
else
v = buffer:readIntVarLen()
end
elseif flag == 2 then
v = buffer:readBoolean()
elseif flag == 3 then
v = buffer:readString()
elseif flag == 4 then
v = {}
local tableCount = buffer:readIntVarLen()
for i = 1, tableCount do
local tk, tv
local isKeyNum = buffer:readBoolean()
if isKeyNum then
tk = buffer:readIntVarLen()
else
tk = buffer:readString()
end
tv = RPCReadVar(buffer)
v[tk] = tv
end
elseif flag == 5 then
v = nil
else
assert(false, "RPC failed")
end
return v
end
---RPCRead
---@param buffer ByteStream
function ModNetworkProxyHandler:_RPCRead(buffer, player, sb)
local values = {}
local rpcID = buffer:readIntVarLen()
local argCount = buffer:readIntVarLen()
while argCount > 0 do
local v = RPCReadVar(buffer)
table.insert(values, v)
argCount = argCount - 1
end
local rpcFunc
if sb then
rpcFunc = self.rpcHandlerFuncSB[rpcID]
if rpcFunc ~= nil then
rpcFunc(self, player, unpack(values))
end
else
rpcFunc = self.rpcHandlerFuncCB[rpcID]
if rpcFunc ~= nil then
rpcFunc(self, unpack(values))
end
end
end
function ModNetworkProxyHandler:HandleProxyServerBound(player)
assert(self.isServer)
local serverBoundPacket = self.mod.serverBoundPacket
local buffer = serverBoundPacket.readerBuffer
self:_RPCRead(buffer, player, true)
end
function ModNetworkProxyHandler:HandleProxyClientBound()
assert(not self.isServer)
local clientBoundPacket = self.mod.clientBoundPacket
local buffer = clientBoundPacket.readerBuffer
self:_RPCRead(buffer, nil, false)
end
return ModNetworkProxyHandler
================================================
FILE: network/NetworkProxy.lua
================================================
---@class TC.NetworkProxy
local NetworkProxy = class("NetworkProxy")
---RPCWriteVar
---@param buffer ByteStream
---@param v any
local function RPCWriteVar(buffer, v)
local typeName = type(v)
if typeName == "number" then
buffer:writeIntVarLen(1)
if math.floor(v) == v then
buffer:writeBoolean(false)
buffer:writeIntVarLen(v)
else
buffer:writeBoolean(true)
buffer:writeDouble(v)
end
elseif typeName == "boolean" then
buffer:writeIntVarLen(2)
buffer:writeBoolean(v)
elseif typeName == "string" then
buffer:writeIntVarLen(3)
buffer:writeString(v)
elseif typeName == "table" then
buffer:writeIntVarLen(4)
local tableCount = 0
for _ in pairs(v) do
tableCount = tableCount + 1
end
buffer:writeIntVarLen(tableCount)
for tk, kv in pairs(v) do
local tkTypeName = type(tk)
if tkTypeName == "string" then
buffer:writeBoolean(false)
buffer:writeString(tk)
else
buffer:writeBoolean(true)
buffer:writeIntVarLen(tk)
end
RPCWriteVar(buffer, kv)
end
elseif typeName == "nil" then
buffer:writeIntVarLen(5)
else
assert(false, "RPC failed")
end
end
---RPCWrite
---@param buffer ByteStream
---@param rpcID int
function NetworkProxy._RPCWrite(buffer, rpcID, ...)
local argCount = select('#', ...)
buffer:writeIntVarLen(rpcID)
buffer:writeIntVarLen(argCount)
for _, v in ipairs { ... } do
RPCWriteVar(buffer, v)
end
end
---RPCSendServerBound
---@param mod Mod
---@param rpcID int
function NetworkProxy.RPCSendServerBound(mod, rpcID, ...)
if NetMode.current ~= NetMode.Client then
return
end
local serverBoundPacket = mod.serverBoundPacket
local buffer = serverBoundPacket.writerBuffer
NetworkProxy._RPCWrite(buffer, rpcID, ...)
serverBoundPacket:Send()
end
---RPCSendClientBound
---@param mod Mod
---@param rpcID int
---@param player Player
function NetworkProxy.RPCSendClientBound(mod, rpcID, player, ...)
if NetMode.current ~= NetMode.Server then
return
end
local clientBoundPacket = mod.clientBoundPacket
local buffer = clientBoundPacket.writerBuffer
NetworkProxy._RPCWrite(buffer, rpcID, ...)
clientBoundPacket:Send(player)
end
return NetworkProxy
================================================
FILE: network/RPC_ID.lua
================================================
local RPC_ID = {
SB_PLAYER_MAP_OPERATION = 1,
SB_PLAYER_THROWING = 2,
SB_REMOVE_WIRE = 3,
SB_DROP_ITEM_HELD = 4,
SB_DROP_ITEM_MOUSE = 5,
}
return RPC_ID
================================================
FILE: network/TCNetworkProxyHandler.lua
================================================
---@class TC.TCNetworkProxyHandler:TC.ModNetworkProxyHandler
local TCNetworkProxyHandler = class("TCNetworkProxyHandler", require("ModNetworkProxyHandler"))
local RPC_ID = require("RPC_ID")
local GPlayer = require("player.GPlayer")
function TCNetworkProxyHandler:__init()
TCNetworkProxyHandler.super.__init(self, Mod.current)
local SERVER_BOUND_MAPPINGS = {
[RPC_ID.SB_PLAYER_MAP_OPERATION] = TCNetworkProxyHandler.PlayerMapOperation,
[RPC_ID.SB_PLAYER_THROWING] = TCNetworkProxyHandler.PlayerThrowing,
[RPC_ID.SB_REMOVE_WIRE] = TCNetworkProxyHandler.RemoveWire,
[RPC_ID.SB_DROP_ITEM_HELD] = TCNetworkProxyHandler.DropItemHeld,
[RPC_ID.SB_DROP_ITEM_MOUSE] = TCNetworkProxyHandler.DropItemMouse,
}
self:RegisterRPCHandlerServerBoundMappings(SERVER_BOUND_MAPPINGS)
end
function TCNetworkProxyHandler:PlayerMapOperation(player, opType, xi, yi)
GPlayer.GetInstance(player):OnMapOpServerBound(opType, xi, yi)
end
function TCNetworkProxyHandler:PlayerThrowing(player, angle)
GPlayer.GetInstance(player):OnThrowingServerBound(angle)
end
function TCNetworkProxyHandler:RemoveWire(player, xi, yi)
GPlayer.GetInstance(player):OnRemovingWireBound(xi, yi)
end
---DropItemHeld
---@param player Player
function TCNetworkProxyHandler:DropItemHeld(player, onlyOne)
local heldSlot = player.backpackInventory:GetSlot(player.heldSlotIndex)
if heldSlot.hasStack then
player:DropItem(heldSlot:GetStack(), onlyOne)
if onlyOne then
heldSlot:DecrStackSize(1)
else
heldSlot:ClearStack()
end
end
end
---DropItemHeld
---@param player Player
function TCNetworkProxyHandler:DropItemMouse(player)
local mouseSlot = player.mouseInventory:GetSlot(0)
if mouseSlot.hasStack then
player:DropItem(mouseSlot:GetStack())
mouseSlot:ClearStack()
end
end
return TCNetworkProxyHandler
================================================
FILE: npc_ai/AngrySkeleton.json
================================================
{
"AngrySkeleton": {
"script": {
"path": "AngrySkeleton.lua"
}
}
}
================================================
FILE: npc_ai/AngrySkeleton.lua
================================================
---@class TC.AngrySkeleton:TC.SwordHumanFighter
local AngrySkeleton = class("AngrySkeleton", require("SwordHumanFighter"))
function AngrySkeleton:Init()
AngrySkeleton.super.Init(self)
self:SetHeldItemByIDName("lead_sword")
end
function AngrySkeleton:Update()
AngrySkeleton.super.Update(self)
end
return AngrySkeleton
================================================
FILE: npc_ai/Animal.json
================================================
{
"Animal": {
"script": {
"path": "Animal.lua"
}
}
}
================================================
FILE: npc_ai/Animal.lua
================================================
---@class TC.Animal:ModNpc
local Animal = class("Animal", ModNpc)
function Animal:Init()
-- all animal can save to file
self.npc.isAutoSave = true
end
function Animal:Update()
local npc = self.npc
if npc.hurry then
if Utils.RandTry(256) then
npc.hurry = false
end
end
if npc.hurry then
npc.maxSpeed = npc.maxSpeed * 2
end
npc:TryMakeSound()
npc:RandomWalk()
end
function Animal:PostUpdate()
if self.npc.speedX == 0 then
self.npc.frameTickTime = 0
end
end
function Animal:OnHit()
self.npc.hurry = true
end
--function Animal:Save()
-- return {
-- say = "I'm an animal!",
-- value = 123
-- }
--end
--
--function Animal:Load(tagTable)
-- print(tagTable)
--end
--
--function Animal:OnLoot()
-- ItemUtils.CreateDrop(ItemStack.new(ItemRegistry.GetItemByIDName("diamond"), 2),
-- self.npc.centerX, self.npc.centerY, 0, -3)
--end
return Animal
================================================
FILE: npc_ai/Archer.json
================================================
{
"Archer": {
"script": {
"path": "Archer.lua"
}
}
}
================================================
FILE: npc_ai/Archer.lua
================================================
---@class TC.Archer:TC.HumanFighter
local Archer = class("Archer", require("HumanFighter"))
local State = {
NORMAL = 0,
NO_MOVE = 1
}
function Archer:Init()
Archer.super.Init(self)
self.inventory = Inventory.new(1)
self.npc.dataWatcher:AddInventory(self.inventory)
self.itemSlotHeld = self.inventory:GetSlot(0)
self.shootTimes = 0
self.shootOffsetAngle = 0
self.SHOOT_TIMES = self.npc.dataWatcher:AddInteger(0)
end
function Archer:Update()
self:RecvSync()
local npc = self.npc
npc.noMove = true
local playerTarget = PlayerUtils.Get(npc.playerTargetIndex)
npc.state = State.NORMAL
if playerTarget ~= nil then
npc.direction = (playerTarget.centerX > npc.centerX)
end
local watchAngle = Utils.FixAngle(npc.watchAngle)
local offsetDir = 1
if watchAngle >= -math.pi / 2 and watchAngle < math.pi / 2 then
offsetDir = -1
end
watchAngle = watchAngle + self.shootOffsetAngle * offsetDir
self.isHeadLook = true
self.headLookAngle = watchAngle
self.headLookDenominator = 2.0
self.isBackHandLook = true
self.isFrontHandLook = true
self.backHandLookAngle = watchAngle
self.frontHandLookAngle = watchAngle
npc.state = State.NORMAL
if playerTarget ~= nil then
npc.direction = (playerTarget.centerX > npc.centerX)
local distance = npc:GetDistance(playerTarget.centerX, playerTarget.centerY)
if distance < 540 and self.shootTimes ~= 0 then
npc.state = State.NO_MOVE
end
if distance < 1200 then
if npc.stand or npc.gravity == 0 then
if (npc.tickTime % 200 == 0) then
self.isUsingItemForAnimation = true
self.shootTimes = self.shootTimes + 1
end
end
end
if self.shootTimes > 1 and Utils.RandTry(128) then
self.shootTimes = 0
end
end
if npc.state == State.NORMAL then
npc.noMove = false
elseif npc.state == State.NO_MOVE then
npc.noMove = true
end
if npc.gravity ~= 0 then
npc:Walk()
elseif npc.noMove then
npc.speedX, npc.speedY = Utils.SlowSpeed2D(npc.speedX, npc.speedY, 0.1)
else
npc:Fly()
end
if npc.inLiquid then
npc.speedY = - 8
end
self:SendSync()
end
function Archer:SendSync()
if NetMode.current == NetMode.Server then
self.npc.dataWatcher:UpdateInteger(self.SHOOT_TIMES, self.shootTimes)
end
end
function Archer:RecvSync()
if NetMode.current == NetMode.Client then
self.shootTimes = self.npc.dataWatcher:GetInteger(self.SHOOT_TIMES)
end
end
return Archer
================================================
FILE: npc_ai/BallMagic.json
================================================
{
"BallMagic": {
"script": {
"path": "BallMagic.lua"
}
}
}
================================================
FILE: npc_ai/BallMagic.lua
================================================
---@class TC.BallMagic:ModNpc
local BallMagic = class("BallMagic", ModNpc)
function BallMagic:Init()
self.npc.noHurt = true
self.npc.noCollisionByWeapon = true
end
function BallMagic:Update()
local npc = self.npc
---@type Player
local target = PlayerUtils.SearchNearestPlayer(npc.centerX, npc.centerY, 1000)
if target ~= nil then
if npc:GetDistance(target.centerX, target.centerY) < 128 then
npc.speedX, npc.speedY = Utils.SlowSpeed2D(npc.speedX, npc.speedY, 0.2)
npc.speedY = npc.speedY + math.sin(npc.tickTime / 8) / 4
npc.speedX = npc.speedX + math.cos(npc.tickTime / 18) / 6
else
local targetAngle = npc:GetAngleTo(target.centerX, target.centerY)
npc.speedX, npc.speedY = Utils.ForceSpeed2D(npc.speedX, npc.speedY, 0.2, targetAngle, npc.maxSpeed)
end
npc.direction = npc.centerX < target.centerX
else
npc.direction = npc.speedX > 0
end
if npc.tickTime % 2 == 0 then
local effectAngle = Utils.RandSym(math.pi)
local d = 128
local effectX = npc.centerX + math.cos(effectAngle) * d
local effectY = npc.centerY + math.sin(effectAngle) * d
local effectSpeed = 6
local effectSpeedAngle = Utils.FixAngle(effectAngle + math.pi)
local spx = npc.speedX + math.cos(effectSpeedAngle) * effectSpeed
local spy = npc.speedY + math.sin(effectSpeedAngle) * effectSpeed
local colorChannel = Utils.RandIntArea(200, 50)
EffectUtils.Create(
Reg.EffectID("flash2"),
effectX,
effectY,
spx,
spy,
Utils.RandSym(0.5),
Utils.RandDoubleArea(1.25, 0.5),
0.9,
Color.new(colorChannel, colorChannel, colorChannel)
)
end
local npcTarget = NpcUtils.SearchNearestEnemy(npc.centerX, npc.centerY, 300, true)
if npcTarget ~= nil then
local targetAngle = npc:GetAngleTo(npcTarget.centerX, npcTarget.centerY)
if npc.tickTime % 16 == 0 then
local rotCenterX = npc.centerX
local rotCenterY = npc.centerY - 8
local angle = targetAngle
local shootX = rotCenterX + 24 * math.cos(angle) + Utils.RandSym(20)
local shootY = rotCenterY + 24 * math.sin(angle) + Utils.RandSym(20)
local speed = 12
local attack = Attack.new(11, 1, 1)
local proj = ProjectileUtils.CreateFromNpc(npc, Reg.ProjectileID("air_wave"),
shootX, shootY,
speed * math.cos(angle),
speed * math.sin(angle),
attack)
proj.isCheckNpc = true
SoundUtils.PlaySound(Reg.SoundID("bow"), npc.centerXi, npc.centerYi)
end
end
LightingUtils.Add(npc.centerXi, npc.centerYi, 32)
end
function BallMagic:OnDraw()
local npc = self.npc
if npc.maxSpeed > 0 then
npc.spriteEx.angle = npc.spriteEx.angle + 0.1
end
end
return BallMagic
================================================
FILE: npc_ai/BaseSnake.lua
================================================
---@class TC.BaseSnake:ModNpc
local BaseSnake = class("BaseSnake", ModNpc)
local SnakeModel = require("util.SnakeModel")
-- TODO: 网络同步优化!不能每帧都同步坐标!!
function BaseSnake:Init()
local npc = self.npc
self.npc.netUpdate = false
self._snakeModel = SnakeModel.new()
self._npcIndices = {}
npc.isWatchAngleForTarget = false
npc.rotateAngle = 0
end
function BaseSnake:SetSnakeData(totalJointCount, bodyID, tailID, headDistance, bodyDistance, tailDistance, bodySize, tailSize)
if NetMode.current ~= NetMode.Server then
return
end
if totalJointCount < 2 then
return
end
local npc = self.npc
local cx, cy = npc.centerX, npc.centerY
local lastDistance = headDistance
local headRotateAngle = npc.rotateAngle
local backAngle = Utils.FixAngle(headRotateAngle + math.pi)
self._snakeModel:addHead(cx, cy, headRotateAngle, headDistance)
for i = 2, totalJointCount do
local id = bodyID
local distance = bodyDistance
local size = bodySize
if i == totalJointCount then
id = tailID
distance = tailDistance
size = tailSize
end
local d = (lastDistance + distance) * 0.5
cx = cx + math.cos(backAngle) * d
cy = cy + math.sin(backAngle) * d
local nextNpc = NpcUtils.Create(id, cx - size.width / 2, cy - size.height / 2)
nextNpc.rotateAngle = headRotateAngle
lastDistance = distance
local entityIndex = EntityIndex.new(nextNpc.entityIndex.entityID, nextNpc.entityIndex.uniqueID)
table.insert(self._npcIndices, entityIndex)
self._snakeModel:addBody(Utils.FixAngle(nextNpc.rotateAngle + math.pi), distance)
local modNpc = nextNpc:GetModNpc()
if modNpc ~= nil and modNpc.SetHeadOwner ~= nil then
modNpc:SetHeadOwner(self.npc.entityIndex)
end
end
end
function BaseSnake:PostUpdate()
if NetMode.current == NetMode.Server then
local npc = self.npc
--npc.gravity = 0.1
--npc.speedY = npc.speedY + 0.05
--npc.speedX = 1
self._snakeModel:update(npc.centerX, npc.centerY, npc.speedX, npc.speedY, npc.rotateAngle)
local cx, cy, angle = self._snakeModel:getRes(1)
npc:SetCenterX(cx)
npc:SetCenterY(cy)
npc.rotateAngle = angle
npc.watchAngle = npc.rotateAngle
for i = 1, #self._npcIndices do
local entityIndex = self._npcIndices[i]
if NpcUtils.IsAlive(entityIndex) then
local npcPart = NpcUtils.Get(entityIndex)
cx, cy, angle = self._snakeModel:getRes(i + 1)
npcPart:SetCenterX(cx)
npcPart:SetCenterY(cy)
npcPart.rotateAngle = angle
npcPart.watchAngle = npcPart.rotateAngle
end
end
npc.x = npc.x - npc.speedX
npc.y = npc.y - npc.speedY
end
end
function BaseSnake:OnDraw()
local npc = self.npc
npc.spriteEx.angle = npc.watchAngle + math.pi
end
function BaseSnake:OnKilled()
for i = 1, #self._npcIndices do
local entityIndex = self._npcIndices[i]
if NpcUtils.IsAlive(entityIndex) then
local npcPart = NpcUtils.Get(entityIndex)
npcPart.noLooting = true
npcPart:KillByStrike()
end
end
end
return BaseSnake
================================================
FILE: npc_ai/BaseSnakeBody.lua
================================================
---@class TC.BaseSnakeBody:ModNpc
local BaseSnakeBody = class("BaseSnakeBody", ModNpc)
function BaseSnakeBody:Init()
self.npc.netUpdate = false
self.headOwnerNpcIndex = nil
self.npc.isAntiLava = true
end
function BaseSnakeBody:Update()
if self.npc.tickTime % 64 == 0 then
if self.headOwnerNpcIndex ~= nil then
if not NpcUtils.IsAlive(self.headOwnerNpcIndex) then
self.npc:Kill()
end
end
end
end
function BaseSnakeBody:SetHeadOwner(npcIndex)
self.headOwnerNpcIndex = npcIndex
end
function BaseSnakeBody:OnDraw()
local npc = self.npc
npc.spriteEx.angle = npc.watchAngle + math.pi
end
function BaseSnakeBody:ModifyHit(attack)
local headNpc = NpcUtils.Get(self.headOwnerNpcIndex)
if headNpc ~= nil then
attack.attack = attack.attack * 0.7
headNpc:Strike(attack)
return false
end
return true
end
return BaseSnakeBody
================================================
FILE: npc_ai/Bat.json
================================================
{
"Bat": {
"script": {
"path": "Bat.lua"
}
}
}
================================================
FILE: npc_ai/Bat.lua
================================================
---@type ModNpc
local Bat = class("Bat", ModNpc)
function Bat:Update()
self.npc:Fly()
end
function Bat:OnDraw()
local npc = self.npc
if npc.maxSpeed > 0 then
npc.spriteEx.angle = npc.speedX / npc.maxSpeed / 2
end
end
return Bat
================================================
FILE: npc_ai/BlackSkeleton.json
================================================
{
"BlackSkeleton": {
"script": {
"path": "BlackSkeleton.lua"
}
}
}
================================================
FILE: npc_ai/BlackSkeleton.lua
================================================
---@class TC.BlackSkeleton:TC.SwordHumanFighter
local BlackSkeleton = class("BlackSkeleton", require("SwordHumanFighter"))
function BlackSkeleton:Init()
BlackSkeleton.super.Init(self)
self:SetHeldItemByIDName("golden_pickaxe")
end
function BlackSkeleton:Update()
BlackSkeleton.super.Update(self)
self:DoExternArmsAnimation(1, 16)
end
return BlackSkeleton
================================================
FILE: npc_ai/Blaze.json
================================================
{
"Blaze": {
"script": {
"path": "Blaze.lua"
}
}
}
================================================
FILE: npc_ai/Blaze.lua
================================================
---@class TC.Blaze:ModNpc
local Blaze = class("Blaze", ModNpc)
function Blaze:Init()
local npc = self.npc
-- 有BUG,砍了算了
--for i = 1, 4 do
-- local proj = ProjectileUtils.CreateFromNpc(npc, Reg.ProjectileID("blaze_rod"), npc.centerX, npc.centerY, 0, 0, npc.baseAttack)
-- proj.isCheckPlayer = true
-- if proj.modData:DataOf("Blaze_Rod") then
-- proj.modData.beginDir = i - 1
-- end
--end
end
function Blaze:Update()
local npc = self.npc
local playerTarget = PlayerUtils.Get(npc.playerTargetIndex)
if playerTarget ~= nil then
local distance = npc:GetDistance(playerTarget.centerX, playerTarget.centerY)
if distance < 360 then
npc:Fly(false) -- random fly
else
npc:Fly()
end
if distance < 640 then
if npc.tickTime > 0 and npc.tickTime % 128 == 0 then
if MiscUtils.RayReach(npc.centerX, npc.centerY, playerTarget.centerX, playerTarget.centerY) then
local angle = npc:GetAngleTo(playerTarget.centerX, playerTarget.centerY)
local proj = ProjectileUtils.CreateFromNpc(npc, Reg.ProjectileID("fire_charge"),
npc.centerX, npc.centerY, 5 * math.cos(angle), 5 * math.sin(angle), npc.baseAttack)
proj.isCheckPlayer = true
SoundUtils.PlaySound(Reg.SoundID("fireball"), npc.centerXi, npc.centerYi)
end
end
end
else
npc:Fly(false)
end
if npc.tickTime % 4 == 0 then
EffectUtils.Create(Reg.EffectID("flame_star"), npc.randX, npc.randY,
-npc.speedX, -npc.speedY,
Utils.RandSym(1.0), Utils.RandDoubleArea(1, 2))
end
LightingUtils.Add(npc.centerXi, npc.centerYi, 24, 12, 0, 0)
end
function Blaze:OnDraw()
local npc = self.npc
if npc.maxSpeed > 0 then
npc.spriteEx.angle = npc.speedX / npc.maxSpeed / 4
else
npc.spriteEx.angle = 0
end
end
return Blaze
================================================
FILE: npc_ai/BlockSlime.json
================================================
{
"BlockSlime": {
"script": {
"path": "BlockSlime.lua"
}
}
}
================================================
FILE: npc_ai/BlockSlime.lua
================================================
---@class TC.BlockSlime:ModNpc
local BlockSlime = class("BlockSlime", ModNpc)
local State = {
NORMAL = 0,
READY_TO_JUMP = 1,
FALLEN = 2,
}
function BlockSlime:Update()
local npc = self.npc
if not npc.stand then
npc.state = State.FALLEN
if npc.direction then
npc.speedX = npc.speedX + 0.1
else
npc.speedX = npc.speedX - 0.1
end
npc.speedX = math.max(npc.speedX, -npc.maxSpeed)
npc.speedX = math.min(npc.speedX, npc.maxSpeed)
else
local playerTarget = PlayerUtils.Get(npc.playerTargetIndex)
if playerTarget ~= nil then
npc.direction = (playerTarget.centerX > npc.centerX)
npc.speedX = Utils.SlowSpeed1D(npc.speedX, 0.1)
if npc.state == State.NORMAL then
npc.stateTimer = npc.stateTimer + 1
-- if Utils.RandTry(32) then
if npc.stateTimer > 32 then
npc.stateTimer = 0
npc.state = State.READY_TO_JUMP
end
elseif npc.state == State.READY_TO_JUMP then
npc.stateTimer = npc.stateTimer + 1
if npc.stateTimer > 16 then
npc.stateTimer = 0
npc.state = State.FALLEN
if npc.direction then
npc.speedX = Utils.RandDoubleArea(npc.maxSpeed / 2, npc.maxSpeed / 2)
else
npc.speedX = -Utils.RandDoubleArea(npc.maxSpeed / 2, npc.maxSpeed / 2)
end
npc.speedY = -Utils.RandDoubleArea(8, 4)
end
elseif npc.state == State.FALLEN then
npc.stateTimer = npc.stateTimer + 1
if npc.stateTimer > 16 then
npc.stateTimer = 0
npc.state = State.NORMAL
end
end
else
npc.stateTimer = 0
npc.state = State.NORMAL
end
end
end
function BlockSlime:OnDraw()
local npc = self.npc
npc.frameTickTime = 0
if not npc.stand then
npc.spriteRect.x = npc.spriteDefaultWidth * 2
else
if npc.state == State.NORMAL then
npc.spriteRect.x = 0
else
npc.spriteRect.x = npc.spriteDefaultWidth
end
end
end
return BlockSlime
================================================
FILE: npc_ai/BloodSkeleton.json
================================================
{
"BloodSkeleton": {
"script": {
"path": "BloodSkeleton.lua"
}
}
}
================================================
FILE: npc_ai/BloodSkeleton.lua
================================================
---@type ModNpc
local BloodSkeleton = class("BloodSkeleton", require("Archer"))
function BloodSkeleton:Init()
BloodSkeleton.super.Init(self)
self.itemSlotHeld:PushStack(ItemStack.new(ItemRegistry.GetItemByIDName("blood_bow")))
self.shootOffsetAngle = 0.2
end
return BloodSkeleton
================================================
FILE: npc_ai/BloodyEye.json
================================================
{
"BloodyEye": {
"script": {
"path": "BloodyEye.lua"
}
}
}
================================================
FILE: npc_ai/BloodyEye.lua
================================================
---@type ModNpc
local BloodyEye = class("BloodyEye", ModNpc)
function BloodyEye:Update()
local npc = self.npc
npc:Fly()
local playerTarget = PlayerUtils.Get(npc.playerTargetIndex)
local useShootTimer = false
if playerTarget ~= nil then
local distance = npc:GetDistance(playerTarget.centerX, playerTarget.centerY)
if distance < 560 then
local angle = npc.speedAngle
useShootTimer = true
npc.stateTimer = npc.stateTimer + 1
if npc.stateTimer >= 128 then
npc.stateTimer = 0
if MiscUtils.RayReach(npc.centerX, npc.centerY, playerTarget.centerX, playerTarget.centerY) then
local proj = ProjectileUtils.CreateFromNpc(npc, Reg.ProjectileID("bullet_super"),
npc.centerX + math.cos(angle) * 20, npc.centerY + math.sin(angle) * 20,
16 * math.cos(angle), 16 * math.sin(angle), npc.baseAttack)
proj.isCheckPlayer = true
SoundUtils.PlaySound(Reg.SoundID("gore1"), npc.centerXi, npc.centerYi)
end
end
if npc.tickTime % 32 == 0 then
angle = angle + Utils.RandSym(0.5)
EffectUtils.Create(Reg.EffectID("fire_flame"),
npc.centerX + math.cos(angle) * 20, npc.centerY + math.sin(angle) * 20,
3 * math.cos(angle), 3 * math.sin(angle), 1,
Utils.RandDoubleArea(0.5, 0.5), Utils.RandDoubleArea(0.75, 0.25))
end
end
end
if not useShootTimer then
npc.stateTimer = 0
end
end
function BloodyEye:OnDraw()
self.npc.spriteEx.angle = self.npc.speedAngle
end
return BloodyEye
================================================
FILE: npc_ai/BoneArcher.json
================================================
{
"BoneArcher": {
"script": {
"path": "BoneArcher.lua"
}
}
}
================================================
FILE: npc_ai/BoneArcher.lua
================================================
---@class TC.BoneArcher:TC.Archer
local BoneArcher = class("BoneArcher", require("Archer"))
function BoneArcher:Init()
BoneArcher.super.Init(self)
self.itemSlotHeld:PushStack(ItemStack.new(ItemRegistry.GetItemByIDName("wooden_bow")))
self.shootOffsetAngle = 0.2
end
return BoneArcher
================================================
FILE: npc_ai/BoneLee.json
================================================
{
"BoneLee": {
"script": {
"path": "BoneLee.lua"
}
}
}
================================================
FILE: npc_ai/BoneLee.lua
================================================
---@class TC.BoneLee:TC.HumanFighter
local BoneLee = class("BoneLee", require("HumanFighter"))
function BoneLee:Update()
BoneLee.super.Update(self)
local npc = self.npc
if npc.inLiquid then
npc.speedY = - 8
end
end
return BoneLee
================================================
FILE: npc_ai/BoneOfficer.json
================================================
{
"BoneOfficer": {
"script": {
"path": "BoneOfficer.lua"
}
}
}
================================================
FILE: npc_ai/BoneOfficer.lua
================================================
---@class TC.BoneOfficer:TC.Archer
local BoneOfficer = class("BoneOfficer", require("Archer"))
function BoneOfficer:Init()
BoneOfficer.super.Init(self)
self.itemSlotHeld:PushStack(ItemStack.new(ItemRegistry.GetItemByIDName("soul_laserer")))
end
return BoneOfficer
================================================
FILE: npc_ai/BoneSniper.json
================================================
{
"BoneSniper": {
"script": {
"path": "BoneSniper.lua"
}
}
}
================================================
FILE: npc_ai/BoneSniper.lua
================================================
---@class TC.BoneSniper:TC.Archer
local BoneSniper = class("BoneSniper", require("Archer"))
function BoneSniper:Init()
BoneSniper.super.Init(self)
self.itemSlotHeld:PushStack(ItemStack.new(ItemRegistry.GetItemByIDName("sword_fish_gun")))
end
return BoneSniper
================================================
FILE: npc_ai/BoneySkeleton.json
================================================
{
"BoneySkeleton": {
"script": {
"path": "BoneySkeleton.lua"
}
}
}
================================================
FILE: npc_ai/BoneySkeleton.lua
================================================
---@class TC.BoneySkeleton:TC.SwordHumanFighter
local BoneySkeleton = class("BoneySkeleton", require("SwordHumanFighter"))
function BoneySkeleton:Init()
BoneySkeleton.super.Init(self)
self:SetHeldItemByIDName("iron_axe")
end
function BoneySkeleton:Update()
BoneySkeleton.super.Update(self)
self:DoExternArmsAnimation(1, 32)
end
return BoneySkeleton
================================================
FILE: npc_ai/BouncySlime.json
================================================
{
"BouncySlime": {
"script": {
"path": "BouncySlime.lua"
}
}
}
================================================
FILE: npc_ai/BouncySlime.lua
================================================
---@class TC.BouncySlime:TC.BlockSlime
local BouncySlime = class("BouncySlime", require("BlockSlime"))
return BouncySlime
================================================
FILE: npc_ai/Butterfly.json
================================================
{
"Butterfly": {
"script": {
"path": "Butterfly.lua"
}
}
}
================================================
FILE: npc_ai/Butterfly.lua
================================================
---@type ModNpc
local Butterfly = class("Butterfly", ModNpc)
function Butterfly:Update()
self.npc:Fly()
end
function Butterfly:OnDraw()
local npc = self.npc
if npc.maxSpeed > 0 then
npc.spriteEx.angle = npc.speedX / npc.maxSpeed / 2
end
npc.spriteEx.scaleRateX = 0.55 + Utils.SinValue(npc.frameTickTime, 16) * 0.45
npc.spriteOffsetX = -(npc.spriteEx.scaleRateX - 1) * npc.spriteDefaultWidth / 2
end
return Butterfly
================================================
FILE: npc_ai/Cat.json
================================================
{
"Cat": {
"script": {
"path": "Cat.lua"
}
}
}
================================================
FILE: npc_ai/Cat.lua
================================================
---@type ModNpc
local Cat = class("Cat", require("Animal"))
function Cat:OnDraw()
local npc = self.npc
if npc.frameTickTime > 0 then
npc.spriteRect.x = npc.spriteRect.x + npc.spriteDefaultWidth
end
end
return Cat
================================================
FILE: npc_ai/Chicken.json
================================================
{
"Chicken": {
"script": {
"path": "Chicken.lua"
}
}
}
================================================
FILE: npc_ai/Chicken.lua
================================================
---@type ModNpc
local Chicken = class("Chicken", require("Animal"))
function Chicken:PostUpdate()
local npc = self.npc
if not npc.hurry then
if npc.stand and npc.speedX == 0 and Utils.RandTry(2048) then
-- lay eggs
ItemUtils.CreateDrop(Reg.ItemID("egg"), 1, npc.centerX, npc.centerY)
SoundUtils.PlaySound(Reg.SoundID("pop"), npc.centerXi, npc.centerYi)
end
end
if npc.speedY > 3 then -- fall slowly
npc.speedY = 3
end
if npc.stand and npc.speedX == 0 then
npc.frameTickTime = 0
end
end
function Chicken:OnDraw()
local npc = self.npc
if not npc.stand then
npc.spriteRect.y = npc.spriteDefaultHeight
end
end
return Chicken
================================================
FILE: npc_ai/Creeper.json
================================================
{
"Creeper": {
"script": {
"path": "Creeper.lua"
}
}
}
================================================
FILE: npc_ai/Creeper.lua
================================================
---@class TC.Creeper:ModNpc
local Creeper = class("Creeper", ModNpc)
local ST_NORMAL = 0
local ST_EXPANDING_EXPLOSION = 1
local ST_CANCELING_EXPLOSION = 2
function Creeper:Init()
self.boomPower = 8
self.boomHurtNpc = true
self.boomHurtPlayer = true
self.boomKillTile = true
self.boomKillWall = true
self.boomWaitTime = 128
self.boomCancelTime = 240
self.triggerExpandingDistance = 64
end
function Creeper:Update()
local npc = self.npc
local playerTarget = PlayerUtils.Get(npc.playerTargetIndex)
npc.noMove = false
if npc.state == ST_NORMAL then
if npc.stand then
if playerTarget ~= nil then
local distance = npc:GetDistance(playerTarget.centerX, playerTarget.centerY)
if distance < self.triggerExpandingDistance then
npc.state = ST_EXPANDING_EXPLOSION
SoundUtils.PlaySound(Reg.SoundID("fuse"), npc.centerXi, npc.centerYi)
end
end
end
elseif npc.state == ST_EXPANDING_EXPLOSION then
npc.noMove = true
npc.stateTimer = npc.stateTimer + 1
local canceling = false
if playerTarget ~= nil then
local distance = npc:GetDistance(playerTarget.centerX, playerTarget.centerY)
if distance > self.boomCancelTime then
npc.state = ST_CANCELING_EXPLOSION
canceling = true
end
end
if not canceling then
if npc.stateTimer > self.boomWaitTime then
npc:Kill()
MiscUtils.CreateExplosion(npc.centerXi, npc.centerYi, self.boomPower, self.boomHurtNpc, self.boomHurtPlayer, self.boomKillTile, self.boomKillWall)
self:OnCreateBoomEffect(npc.centerX, npc.centerY)
end
end
elseif npc.state == ST_CANCELING_EXPLOSION then
npc.noMove = true
npc.stateTimer = npc.stateTimer - 8
if npc.stateTimer <= 0 then
npc.stateTimer = 0
npc.state = ST_NORMAL
end
end
npc:Walk()
end
function Creeper:OnCreateBoomEffect(centerX, centerY)
EffectUtils.CreateExplosion(centerX, centerY)
end
function Creeper:OnDraw()
local npc = self.npc
if npc.state == ST_EXPANDING_EXPLOSION or npc.state == ST_CANCELING_EXPLOSION then
local scale = 1 + npc.stateTimer / 200
npc.spriteEx.scaleRateX = scale
npc.spriteEx.scaleRateY = scale
npc.spriteRect.x = npc.spriteDefaultWidth * npc.frames
npc.spriteOffsetX = math.floor(-(scale - 1) * npc.spriteDefaultWidth / 2)
npc.spriteOffsetY = math.floor(-(scale - 1) * npc.spriteDefaultHeight)
else
npc.spriteEx.scaleRateX = 1
npc.spriteEx.scaleRateY = 1
npc.spriteOffsetX = 0
npc.spriteOffsetY = 0
if npc.speedX == 0 and npc.stand then
npc.frameTickTime = 0
end
end
end
return Creeper
================================================
FILE: npc_ai/CrisonEye.json
================================================
{
"CrisonEye": {
"script": {
"path": "CrisonEye.lua"
}
}
}
================================================
FILE: npc_ai/CrisonEye.lua
================================================
---@class TC.CrisonEye:ModNpc
local CrisonEye = class("ManEater", ModNpc)
local ST_READY = 0
local ST_DASH = 1
local ST_TRANSFORM = 2
local ST_LEAVE = 3
local IDLE_TIME = 128
local MAD_IDLE_TIME = 64
local TRANSFORM_TIME = 100
local TRANSFORM_TIME_HALF = TRANSFORM_TIME / 2
local DISTANCE = 360
local MAD_DISTANCE = 500
local DASH_TIME = 48
local DASH_TIMES = 1
local DASH_SPEED_SCALE = 2.5
local MAD_DASH_TIME = 80
local MAD_DASH_TIMES = 2
local MAD_DASH_SPEED_SCALE = 2.7
function CrisonEye:Init()
self.facingAngle = 0
self:NotifyAllPlayer("crison_eye")
self.isMad = false
self.dashRemainTimes = 0
self.IS_MAD = self.npc.dataWatcher:AddBool(self.isMad)
self.DASH_REMAIN_TIMES = self.npc.dataWatcher:AddInteger(self.dashRemainTimes)
end
function CrisonEye:Update()
self:RecvSync()
local npc = self.npc
if not MiscUtils.isNight then
npc.state = ST_LEAVE
npc.stateTimer = 0
npc.speedX = 1
npc.speedY = -7
self.facingAngle = npc.speedAngle
end
if npc.state ~= ST_LEAVE then
if not self.isMad and npc.health < npc.maxHealth * 0.4 then
self.isMad = true
npc.state = ST_TRANSFORM
npc.stateTimer = 0
self:MakeMonsterSound()
end
if npc.state == ST_TRANSFORM then
npc.speedX, npc.speedY = Utils.SlowSpeed2D(npc.speedX, npc.speedY, 0.1)
npc.stateTimer = npc.stateTimer + 1
if npc.tickTime % 32 == 0 then
local rid = Reg.NpcID("fly_mouth")
NpcUtils.Create(rid, npc.centerX + 60, npc.centerY + 60)
end
self.facingAngle = self.facingAngle + 0.4 * (1.0 - math.abs(npc.stateTimer - TRANSFORM_TIME_HALF) / TRANSFORM_TIME_HALF)
if npc.stateTimer >= TRANSFORM_TIME then
npc.state = ST_READY
npc.stateTimer = 0
end
else
local flyFollowOnly = true
local playerTarget = PlayerUtils.Get(npc.playerTargetIndex)
if playerTarget ~= nil then
local distance = npc:GetDistance(playerTarget.centerX, playerTarget.centerY)
local checkDistance = self.isMad and 320 or DISTANCE
if distance < checkDistance then
flyFollowOnly = false
npc.maxSpeed = 3.2
if npc.state == ST_READY then
local force = 0.1
if self.isMad then
force = 0.2
end
npc.speedX, npc.speedY = Utils.SlowSpeed2D(npc.speedX, npc.speedY, force)
npc.stateTimer = npc.stateTimer + 1
local angle = npc:GetAngleTo(playerTarget.centerX, playerTarget.centerY)
if not self.isMad and npc.stateTimer == 16 and Utils.RandTry(7) then
local rid = Reg.NpcID("fly_mouth")
NpcUtils.Create(rid,
npc.centerX + 60 * math.cos(angle),
npc.centerY + 60 * math.sin(angle),
2 * math.cos(angle),
2 * math.sin(angle)
)
end
local idleTime = self.isMad and 128 or IDLE_TIME
if npc.stateTimer >= idleTime then
local speedScale = self.isMad and MAD_DASH_SPEED_SCALE or DASH_SPEED_SCALE
npc.speedX = npc.maxSpeed * math.cos(angle) * speedScale
npc.speedY = npc.maxSpeed * math.sin(angle) * speedScale
self.facingAngle = angle
npc.state = ST_DASH
npc.stateTimer = 0
if self.isMad then
self:MakeMonsterSound()
end
self.dashRemainTimes = self.isMad and MAD_DASH_TIMES or DASH_TIMES
npc:SyncAll()
else
self.facingAngle = self.facingAngle + Utils.FixAngle(angle - self.facingAngle) * 0.1
end
elseif npc.state == ST_DASH then
npc.stateTimer = npc.stateTimer + 1
local dashTime = self.isMad and MAD_DASH_TIME or DASH_TIME
if npc.stateTimer >= dashTime then
self.dashRemainTimes = self.dashRemainTimes - 1
if self.dashRemainTimes <= 0 then
npc.state = ST_READY
npc.stateTimer = 0
else
local angle = npc:GetAngleTo(playerTarget.centerX, playerTarget.centerY)
local speedScale = self.isMad and MAD_DASH_SPEED_SCALE or DASH_SPEED_SCALE
npc.speedX = npc.maxSpeed * math.cos(angle) * speedScale
npc.speedY = npc.maxSpeed * math.sin(angle) * speedScale
npc.state = ST_DASH
npc.stateTimer = 0
if self.isMad then
self:MakeMonsterSound()
end
end
npc:SyncAll()
end
if self.isMad then
local angle = npc:GetAngleTo(playerTarget.centerX, playerTarget.centerY)
self.facingAngle = angle
end
end
end
end
if flyFollowOnly then
if playerTarget ~= nil then
self.facingAngle = npc:GetAngleTo(playerTarget.centerX, playerTarget.centerY)
else
self.facingAngle = npc.speedAngle
end
self.dashRemainTimes = 0
npc.state = ST_READY
npc.stateTimer = npc.stateTimer + 1
npc.maxSpeed = 4
local force = 0.1
if self.isMad then
npc.maxSpeed = 8
force = 0.4
end
npc:Fly(true, force, true)
end
end
end
self:SendSync()
npc:SyncAll()
end
function CrisonEye:MakeMonsterSound()
SoundUtils.PlaySound(Reg.SoundID("monster"), self.npc.centerXi, self.npc.centerYi)
end
function CrisonEye:OnDraw()
local npc = self.npc
npc.spriteEx.angle = self.facingAngle
end
function CrisonEye:OnRender()
local npc = self.npc
local GW, GH = 184, 112
local rect = Rect.new(0, 0, GW, GH)
if self.isMad then
rect.y = rect.y + GH
end
local pos = Vector2.new(npc.centerX - MiscUtils.screenX, npc.centerY - MiscUtils.screenY)
local spriteEx = SpriteExData.new()
spriteEx.originX = GW / 2
spriteEx.originY = GH / 2
spriteEx.angle = self.facingAngle
Sprite.draw(npc.texture, pos, rect, Color.White, spriteEx, 0.0)
end
function CrisonEye:OnKilled()
self:NotifyAllPlayer("crison_eye_killed")
end
function CrisonEye:NotifyAllPlayer(advancementIDName)
local advancementID = Reg.AdvancementID(advancementIDName)
local players = PlayerUtils.SearchByCircle(self.npc.centerX, self.npc.centerY, 300 * 16)
---@param player Player
for _, player in each(players) do
player:FinishAdvancement(advancementID)
end
end
function CrisonEye:SendSync()
if NetMode.current == NetMode.Server then
self.npc.dataWatcher:UpdateBool(self.IS_MAD, self.isMad)
self.npc.dataWatcher:UpdateInteger(self.DASH_REMAIN_TIMES, self.dashRemainTimes)
end
end
function CrisonEye:RecvSync()
if NetMode.current == NetMode.Client then
self.isMad = self.npc.dataWatcher:GetBool(self.IS_MAD)
self.dashRemainTimes = self.npc.dataWatcher:GetInteger(self.DASH_REMAIN_TIMES)
end
end
return CrisonEye
================================================
FILE: npc_ai/CrystalMonster.json
================================================
{
"CrystalMonster": {
"script": {
"path": "CrystalMonster.lua"
}
}
}
================================================
FILE: npc_ai/CrystalMonster.lua
================================================
---@class TC.CrystalMonster:ModNpc
local CrystalMonster = class("CrystalMonster", ModNpc)
function CrystalMonster:Update()
local npc = self.npc
if npc.state == 0 then
npc.stateTimer = npc.stateTimer + 1
if npc.stateTimer > 128 then
npc.stateTimer = 0
npc.state = 1
end
npc:Fly()
elseif npc.state == 1 then
npc.speedX, npc.speedY = Utils.SlowSpeed2D(npc.speedX, npc.speedY, 0.55)
if npc.tickTime % 2 == 0 then
local effectAngle = Utils.RandSym(math.pi)
local d = 128
local effectX = npc.centerX + math.cos(effectAngle) * d
local effectY = npc.centerY + math.sin(effectAngle) * d
local effectSpeed = 6
local effectSpeedAngle = Utils.FixAngle(effectAngle + math.pi)
local spx = npc.speedX + math.cos(effectSpeedAngle) * effectSpeed
local spy = npc.speedY + math.sin(effectSpeedAngle) * effectSpeed
local colorChannel = Utils.RandIntArea(200, 50)
EffectUtils.Create(
Reg.EffectID("circle"),
effectX,
effectY,
spx,
spy,
Utils.RandSym(0.5),
Utils.RandDoubleArea(0.25, 0.5),
0.7,
Color.new(colorChannel, colorChannel, colorChannel)
)
EffectUtils.Create(
Reg.EffectID("flash2"),
effectX,
effectY,
spx * 0.5,
spy * 0.5,
Utils.RandSym(0.5),
Utils.RandDoubleArea(0.25, 0.5),
0.9,
Color.new(colorChannel, colorChannel, colorChannel)
)
end
npc.stateTimer = npc.stateTimer + 1
if npc.stateTimer > 128 then
npc.stateTimer = 0
npc.state = 0
for i = 0, 8 do
local angle = math.pi * 2 / 8 * i
local proj = ProjectileUtils.CreateFromNpc(npc,
Reg.ProjectileID("magic_wave"),
npc.centerX, npc.centerY,
3 * math.cos(angle), 3 * math.sin(angle), npc.baseAttack)
proj.isCheckPlayer = true
end
SoundUtils.PlaySound(Reg.SoundID("wand1"), npc.centerXi, npc.centerYi)
end
end
local effect = EffectUtils.Create(Reg.EffectID("chip"),
self.npc.randX, self.npc.bottomY + Utils.RandSym(12),
Utils.RandSym(0.1), Utils.RandDoubleArea(1, 1),
Utils.RandSym(1), 1.0, 0.8,
Color.new(200, 200, 200))
effect:SetDisappearTime(30)
LightingUtils.Add(npc.centerXi, npc.centerYi, 32)
end
function CrystalMonster:OnDraw()
local npc = self.npc
if npc.maxSpeed > 0 then
npc.spriteEx.angle = npc.speedX / npc.maxSpeed / 2
else
npc.spriteEx.angle = 0
end
end
return CrystalMonster
================================================
FILE: npc_ai/CursedSkull.json
================================================
{
"CursedSkull": {
"script": {
"path": "CursedSkull.lua"
}
}
}
================================================
FILE: npc_ai/CursedSkull.lua
================================================
---@class TC.CursedSkull:ModNpc
local CursedSkull = class("CursedSkull", ModNpc)
local ST_READY = 0
local ST_DASH = 1
function CursedSkull:Init()
self.facingAngle = 0
end
function CursedSkull:Update()
local npc = self.npc
local flyOnly = true
local playerTarget = PlayerUtils.Get(npc.playerTargetIndex)
if playerTarget ~= nil then
local distance = npc:GetDistance(playerTarget.centerX, playerTarget.centerY)
if distance < 340 then
flyOnly = false
if npc.state == ST_READY then
npc.speedX, npc.speedY = Utils.SlowSpeed2D(npc.speedX, npc.speedY, 0.1)
npc.stateTimer = npc.stateTimer + 1
local angle = npc:GetAngleTo(playerTarget.centerX, playerTarget.centerY)
if npc.stateTimer >= 32 then
npc.speedX = npc.maxSpeed * math.cos(angle) * 2
npc.speedY = npc.maxSpeed * math.sin(angle) * 2
self.facingAngle = angle
npc.state = ST_DASH
npc.stateTimer = 0
else
self.facingAngle = self.facingAngle + Utils.FixAngle(angle - self.facingAngle) * 0.1
end
elseif npc.state == ST_DASH then
npc.maxSpeed = 3
npc:Fly(true, 0.1, true)
npc.stateTimer = npc.stateTimer + 1
if npc.stateTimer >= 128 then
npc.state = ST_READY
npc.stateTimer = 0
end
end
end
end
if flyOnly then
npc.maxSpeed = 1.25
if playerTarget ~= nil then
self.facingAngle = npc:GetAngleTo(playerTarget.centerX, playerTarget.centerY)
else
self.facingAngle = npc.speedAngle
end
npc.state = ST_READY
npc.stateTimer = 0
npc:Fly(true, 0.1, true)
end
if npc.speedX > 0 then
npc.direction = true
elseif npc.speedX < 0 then
npc.direction = false
end
if npc.tickTime % 8 == 0 then
EffectUtils.Create(Reg.EffectID("flame_star"), npc.randX, npc.randY, Utils.RandSym(1), Utils.RandSym(1), 0,
Utils.RandDoubleArea(1, 1))
EffectUtils.Create(Reg.EffectID("flame_star"), npc.randX, npc.randY, Utils.RandSym(1), -Utils.RandDouble(2), 0,
Utils.RandDoubleArea(0.5, 0.5))
end
end
function CursedSkull:OnDraw()
local npc = self.npc
npc.spriteEx.angle = npc.speedX / npc.maxSpeed / 3
end
return CursedSkull
================================================
FILE: npc_ai/DarkMage.json
================================================
{
"DarkMage": {
"script": {
"path": "DarkMage.lua"
}
}
}
================================================
FILE: npc_ai/DarkMage.lua
================================================
---@class TC.DarkMage:ModNpc
local DarkMage = class("DarkMage", ModNpc)
local ST_NORMAL = 0
local ST_FIRING = 1
local SHOOT_TIMES = 3
function DarkMage:Init()
self.shootTimes = 0
end
function DarkMage:Update()
local npc = self.npc
npc.speedX = Utils.SlowSpeed1D(npc.speedX, 0.1)
local playerTarget = PlayerUtils.Get(npc.playerTargetIndex)
if playerTarget ~= nil then
npc.direction = (playerTarget.centerX > npc.centerX)
end
if npc.state == ST_NORMAL then
npc.stateTimer = npc.stateTimer + 1
if self.shootTimes < SHOOT_TIMES and npc.stateTimer > 64 then
npc.stateTimer = 0
npc.state = ST_FIRING
self.shootTimes = self.shootTimes + 1
if playerTarget ~= nil then
local angle = npc:GetAngleTo(playerTarget.centerX, playerTarget.centerY)
local proj = ProjectileUtils.CreateFromNpc(npc, Reg.ProjectileID("shulker_bullet"), npc.centerX, npc.centerY,
2 * math.cos(angle), 2 * math.sin(angle), npc.baseAttack)
proj.isCheckPlayer = true
SoundUtils.PlaySound(Reg.SoundID("fireball"), npc.centerXi, npc.centerYi)
end
end
if npc.speedY > 6 or (self.shootTimes >= SHOOT_TIMES and npc.stateTimer > 64) then
npc.state = 0
self.shootTimes = 0
npc.stateTimer = 0
local currentX = npc.x
local currentY = npc.y
local teleportSuccess = npc:RandomTeleport(32)
if teleportSuccess then
local e_ender_flash = Reg.EffectID("ender_flash")
for i = 1, 16 do
EffectUtils.Create(e_ender_flash, currentX + Utils.RandInt(npc.width),
currentY + Utils.RandInt(npc.height), Utils.RandSym(1), Utils.RandSym(1), Utils.RandSym(1), 2)
end
for i = 1, 16 do
EffectUtils.Create(e_ender_flash, npc.randX, npc.randY, Utils.RandSym(1), Utils.RandSym(1),
Utils.RandSym(1), 2)
end
SoundUtils.PlaySoundGroup(Reg.SoundGroupID("portal"), npc.centerXi, npc.centerYi)
end
end
elseif npc.state == ST_FIRING then
npc.stateTimer = npc.stateTimer + 1
if npc.stateTimer > 16 then
npc.stateTimer = 0
npc.state = ST_NORMAL
end
end
end
function DarkMage:OnDraw()
local npc = self.npc
npc.spriteEx.angle = npc.speedX / 8
if npc.state == ST_NORMAL then
npc.spriteRect.x = 0
elseif npc.state == ST_FIRING then
npc.spriteRect.x = npc.spriteDefaultWidth
end
end
return DarkMage
================================================
FILE: npc_ai/DeadMage.json
================================================
{
"DeadMage": {
"script": {
"path": "DeadMage.lua"
}
}
}
================================================
FILE: npc_ai/DeadMage.lua
================================================
---@class TC.DeadMage:ModNpc
local DeadMage = class("DeadMage", ModNpc)
local ST_NORMAL = 0
local ST_FIRING = 1
local SHOOT_TIMES = 3
function DeadMage:Init()
self.shootTimes = 0
end
function DeadMage:Update()
local npc = self.npc
npc.speedX = Utils.SlowSpeed1D(npc.speedX, 0.1)
local playerTarget = PlayerUtils.Get(npc.playerTargetIndex)
if playerTarget ~= nil then
npc.direction = (playerTarget.centerX > npc.centerX)
end
if npc.state == ST_NORMAL then
npc.stateTimer = npc.stateTimer + 1
if self.shootTimes < SHOOT_TIMES and npc.stateTimer > 64 then
npc.stateTimer = 0
npc.state = ST_FIRING
self.shootTimes = self.shootTimes + 1
if playerTarget ~= nil then
local angle = npc:GetAngleTo(playerTarget.centerX, playerTarget.centerY)
local proj = ProjectileUtils.CreateFromNpc(npc, Reg.ProjectileID("shulker_bullet"), npc.centerX, npc.centerY,
2 * math.cos(angle), 2 * math.sin(angle), npc.baseAttack)
proj.isCheckPlayer = true
SoundUtils.PlaySound(Reg.SoundID("fireball"), npc.centerXi, npc.centerYi)
end
end
if npc.speedY > 6 or (self.shootTimes >= SHOOT_TIMES and npc.stateTimer > 64) then
npc.state = 0
self.shootTimes = 0
npc.stateTimer = 0
local currentX = npc.x
local currentY = npc.y
local teleportSuccess = npc:RandomTeleport(32)
if teleportSuccess then
local e_ender_flash = Reg.EffectID("ender_flash")
for i = 1, 16 do
EffectUtils.Create(e_ender_flash, currentX + Utils.RandInt(npc.width),
currentY + Utils.RandInt(npc.height), Utils.RandSym(1), Utils.RandSym(1), Utils.RandSym(1), 2)
end
for i = 1, 16 do
EffectUtils.Create(e_ender_flash, npc.randX, npc.randY, Utils.RandSym(1), Utils.RandSym(1),
Utils.RandSym(1), 2)
end
SoundUtils.PlaySoundGroup(Reg.SoundGroupID("portal"), npc.centerXi, npc.centerYi)
end
end
elseif npc.state == ST_FIRING then
npc.stateTimer = npc.stateTimer + 1
if npc.stateTimer > 16 then
npc.stateTimer = 0
npc.state = ST_NORMAL
end
end
end
function DeadMage:OnDraw()
local npc = self.npc
npc.spriteEx.angle = npc.speedX / 8
if npc.state == ST_NORMAL then
npc.spriteRect.x = 0
elseif npc.state == ST_FIRING then
npc.spriteRect.x = npc.spriteDefaultWidth
end
end
return DeadMage
================================================
FILE: npc_ai/Dolphin.json
================================================
{
"Dolphin": {
"script": {
"path": "Dolphin.lua"
}
}
}
================================================
FILE: npc_ai/Dolphin.lua
================================================
---@type ModNpc
local Dolphin = class("Dolphin", ModNpc)
function Dolphin:Update()
local npc = self.npc
npc:TryMakeSound()
npc:Swim()
-- always want to swim up
if npc.inLiquid then
npc.maxSpeed = npc.maxSpeed * 2
end
if npc.inLiquid and Utils.RandTry(128) then
npc.speedY = npc.speedY - 0.1
end
-- jump out of the liquid
if not npc.inLiquid and npc.oldInLiquid and npc.speedY < 0 then
if (npc.direction and npc.speedX > 0) or (not npc.direction and npc.speedX < 0) then
npc.speedY = -npc.jumpForce
end
npc:MakeSound()
end
end
function Dolphin:OnDraw()
local npc = self.npc
local angle = Utils.GetAngle(math.abs(npc.speedX), npc.speedY) * 0.5
if (npc.direction and npc.speedX > 0) or (not npc.direction and npc.speedX < 0) then
angle = -angle
end
npc.spriteEx.angle = angle
end
return Dolphin
================================================
FILE: npc_ai/DungeonCreeper.json
================================================
{
"DungeonCreeper": {
"script": {
"path": "DungeonCreeper.lua"
}
}
}
================================================
FILE: npc_ai/DungeonCreeper.lua
================================================
---@class TC.DungeonCreeper:TC.Creeper
local DungeonCreeper = class("DungeonCreeper", require("Creeper"))
function DungeonCreeper:Init()
DungeonCreeper.super.Init(self)
self.boomPower = 8
--self.boomHurtNpc = true
--self.boomHurtPlayer = true
self.boomKillTile = false
self.boomKillWall = false
end
function DungeonCreeper:OnCreateBoomEffect(centerX, centerY)
EffectUtils.CreateExplosion(centerX, centerY)
local npc = self.npc
local cnt = 16
for i = 0, cnt do
local angle = math.pi * 2 / cnt * i
local proj = ProjectileUtils.CreateFromNpc(npc,
Reg.ProjectileID("lighting_arrow"),
npc.centerX, npc.centerY,
8 * math.cos(angle), 8 * math.sin(angle), npc.baseAttack)
proj.isCheckPlayer = true
end
end
return DungeonCreeper
================================================
FILE: npc_ai/DungeonEater.lua
================================================
---@class TC.DungeonEater:TC.BaseSnake
local DungeonEater = class("DungeonEater", require("BaseSnake"))
local PhysicsUtil = require("util.PhysicsUtil")
function DungeonEater:Init()
DungeonEater.super.Init(self)
self:SetSnakeData(12, Reg.NpcID("dungeon_eater_body"), Reg.NpcID("dungeon_eater_tail"),
48, 34, 48, Size.new(44, 36), Size.new(54, 40)
)
self.npc.isAntiLava = true
self.hungerTick = 0
self:NotifyAllPlayer("dungeon_eater")
end
function DungeonEater:Update()
local npc = self.npc
if NetMode.current == NetMode.Server then
local playerTarget = PlayerUtils.Get(npc.playerTargetIndex)
local isMad = self.hungerTick > 128
local force = 0.15
local maxSpeed = 4
if isMad then
force = 0.10
maxSpeed = 5
end
if self.hungerTick > 1500 then
npc.speedY = math.min(4, npc.speedY + 0.3)
else
if playerTarget ~= nil then
npc.speedX, npc.speedY = PhysicsUtil.SightChaseSpeed2D(npc.speedX, npc.speedY, force,
Utils.GetAngle(playerTarget.centerX - npc.centerX, playerTarget.centerY - npc.centerY),
maxSpeed)
npc.speedX = npc.speedX + Utils.RandSym(0.5)
npc.speedY = npc.speedY + Utils.RandSym(0.5)
end
end
if isMad then
if playerTarget ~= nil then
local iv = 64
if self.hungerTick < 400 then
iv = 64
elseif self.hungerTick < 700 then
iv = 32
end
if npc.tickTime > 0 and npc.tickTime % iv == 0 then
local angle = npc:GetAngleTo(playerTarget.centerX, playerTarget.centerY)
local proj = ProjectileUtils.CreateFromNpc(npc, Reg.ProjectileID("ice_bullet"),
npc.centerX, npc.centerY, 7 * math.cos(angle), 7 * math.sin(angle), npc.baseAttack)
proj.isCheckPlayer = true
SoundUtils.PlaySound(Reg.SoundID("fireball"), npc.centerXi, npc.centerYi)
end
end
end
if npc.tickTime % 8 == 0 then
local eat = DungeonEater.DoEatDungeonBlocks(npc)
if eat then
self.hungerTick = 0
end
end
self.hungerTick = self.hungerTick + 1
end
LightingUtils.Add(npc.centerXi, npc.centerYi, 26)
end
function DungeonEater:OnKilled()
DungeonEater.super.OnKilled(self)
self:NotifyAllPlayer("dungeon_eater_killed")
end
function DungeonEater:NotifyAllPlayer(advancementIDName)
local advancementID = Reg.AdvancementID(advancementIDName)
local players = PlayerUtils.SearchByCircle(self.npc.centerX, self.npc.centerY, 300 * 16)
---@param player Player
for _, player in each(players) do
player:FinishAdvancement(advancementID)
end
end
local EATABLE_DUNGEON_BLOCKS = {
[Reg.BlockID("more_dungeons:dungeon_brick_green")] = true,
}
function DungeonEater.DoEatDungeonBlocks(npc)
local eat = false
local cxi, cyi = npc.centerXi, npc.centerYi
for i = -1, 1 do
for j = -1, 1 do
local xi, yi = cxi + i, cyi + j
local ok = false
local blockID = MapUtils.GetFrontID(xi, yi)
if blockID > 0 and EATABLE_DUNGEON_BLOCKS[blockID] then
local hasAttachBlock = false
if (MapUtils.HasFront(xi, yi - 1) and not MapUtils.IsSolid(xi, yi - 1)) or
(MapUtils.HasFront(xi, yi + 1) and not MapUtils.IsSolid(xi, yi + 1)) then
hasAttachBlock = true
end
if not hasAttachBlock then
ok = MapUtils.RemoveFront(xi, yi, false, true)
if ok then
eat = true
if Utils.RandTry(16) then
local effect = EffectUtils.SendFromServer(Reg.EffectID("flame_star"),
xi * 16 + 8, yi * 16 + 8,
Utils.RandSym(1.0), Utils.RandSym(1.0),
Utils.RandSym(1.0), Utils.RandDoubleArea(1, 2))
effect:SetDisappearTime(120)
end
end
end
end
end
end
return eat
end
return DungeonEater
================================================
FILE: npc_ai/DungeonEaterBody.lua
================================================
---@class TC.DungeonEaterBody:TC.BaseSnakeBody
local DungeonEaterBody = class("DungeonEaterBody", require("BaseSnakeBody"))
local DungeonEater = require("DungeonEater")
function DungeonEaterBody:Init()
DungeonEaterBody.super.Init(self)
end
function DungeonEaterBody:Update()
DungeonEaterBody.super.Update(self)
local npc = self.npc
DungeonEater.DoEatDungeonBlocks(npc)
LightingUtils.Add(npc.centerXi, npc.centerYi, 26)
end
return DungeonEaterBody
================================================
FILE: npc_ai/DungeonEater_Body.json
================================================
{
"DungeonEater_Body": {
"script": {
"path": "DungeonEaterBody.lua"
}
}
}
================================================
FILE: npc_ai/DungeonEater_Head.json
================================================
{
"DungeonEater_Head": {
"script": {
"path": "DungeonEater.lua"
}
}
}
================================================
FILE: npc_ai/DungeonKnight.json
================================================
{
"DungeonKnight": {
"script": {
"path": "DungeonKnight.lua"
}
}
}
================================================
FILE: npc_ai/DungeonKnight.lua
================================================
---@class TC.DungeonKnight:TC.HumanFighter
local DungeonKnight = class("DungeonKnight", require("HumanFighter"))
function DungeonKnight:Init()
self.boneSizeIndex = 1
DungeonKnight.super.Init(self)
self.inventory = Inventory.new(1)
self.npc.dataWatcher:AddInventory(self.inventory)
self.itemSlotHeld = self.inventory:GetSlot(0)
self.itemSlotHeld:PushStack(ItemStack.new(ItemRegistry.GetItemByIDName("iron_sword")))
self.isBackHandLook = true
self.isFrontHandLook = true
self.isBackHandLookAngleSameDirection = true
self.isFrontHandLookAngleSameDirection = true
end
function DungeonKnight:Update()
DungeonKnight.super.Update(self)
local npc = self.npc
local playerTarget = PlayerUtils.Get(npc.playerTargetIndex)
if playerTarget ~= nil then
npc.direction = (playerTarget.centerX > npc.centerX)
end
if math.fmod(npc.tickTime, 8) == 0 then
self.isUsingItemForAnimation = true
end
self.isHeadLook = true
self.headLookAngle = npc.watchAngle
self.headLookDenominator = 2.0
self.backHandLookAngle = math.pi / 3
self.frontHandLookAngle = math.pi / 3
if npc.state == 0 then
npc.stateTimer = npc.stateTimer + 1
if npc.stateTimer > 100 then
npc.stateTimer = 0
npc.state = 1
end
elseif npc.state == 1 then
npc.stateTimer = npc.stateTimer + 1
local TIME = 30
local angle = npc.stateTimer / TIME * math.pi * 1.0 - math.pi / 3 * 2
self.backHandLookAngle = angle
self.frontHandLookAngle = angle
if npc.stateTimer > TIME then
npc.stateTimer = 0
npc.state = 0
local ba = npc.watchAngle
local step = math.pi / 8
local cnt = 3
local speed = 3
local cx = npc.centerX + (npc.direction and 32 or -32)
local cy = npc.centerY
for i = 0, cnt - 1 do
local angle = ba - step * cnt / 2 + step * i
local proj = ProjectileUtils.CreateFromNpc(npc,
Reg.ProjectileID("lighting_bullet_blue"),
cx, cy,
speed * math.cos(angle), speed * math.sin(angle),
npc.baseAttack)
proj.isCheckPlayer = true
end
end
end
end
return DungeonKnight
================================================
FILE: npc_ai/DungeonSkeleton.json
================================================
{
"DungeonSkeleton": {
"script": {
"path": "DungeonSkeleton.lua"
}
}
}
================================================
FILE: npc_ai/DungeonSkeleton.lua
================================================
---@class TC.DungeonSkeleton:TC.SwordHumanFighter
local DungeonSkeleton = class("DungeonSkeleton", require("SwordHumanFighter"))
function DungeonSkeleton:Init()
DungeonSkeleton.super.Init(self)
if self.style == 0 then
self.itemSlotHeld:PushStack(ItemStack.new(ItemRegistry.GetItemByIDName("stone_sword")))
elseif self.style == 1 then
self.itemSlotHeld:PushStack(ItemStack.new(ItemRegistry.GetItemByIDName("lead_sword")))
elseif self.style == 2 then
self.itemSlotHeld:PushStack(ItemStack.new(ItemRegistry.GetItemByIDName("super_lead_sword")))
elseif self.style == 3 then
self.itemSlotHeld:PushStack(ItemStack.new(ItemRegistry.GetItemByIDName("super_copper_sword")))
end
if self.style == 0 then
self.isFrontHandLook = false
self.isBackHandLook = false
end
end
function DungeonSkeleton:Update()
DungeonSkeleton.super.Update(self)
local npc = self.npc
if Utils.RandTry(128) and npc.stand then
npc.speedY = -6
npc.speedX = npc.speedX * 1.5
end
if npc.inLiquid then
npc.speedY = - 8
end
end
function DungeonSkeleton:OnWaitSwing()
local npc = self.npc
if self.style == 1 then
self.frontHandLookAngle = math.cos(npc.tickTime / 16) / 4
self.backHandLookAngle = math.sin(npc.tickTime / 16) / 4
elseif self.style == 2 then
self.frontHandLookAngle = math.pi / 3 + math.cos(npc.tickTime / 8) / 8
self.backHandLookAngle = math.pi / 3 + math.cos(npc.tickTime / 8) / 8
elseif self.style == 3 then
self.frontHandLookAngle = -math.pi / 3 + math.cos(npc.tickTime / 12) / 4
self.backHandLookAngle = -math.pi / 3 + math.cos(npc.tickTime / 12) / 4
end
end
return DungeonSkeleton
================================================
FILE: npc_ai/DungeonSoul.json
================================================
{
"DungeonSoul": {
"script": {
"path": "DungeonSoul.lua"
}
}
}
================================================
FILE: npc_ai/DungeonSoul.lua
================================================
---@class TC.DungeonSoul:ModNpc
local DungeonSoul = class("DungeonSoul", ModNpc)
function DungeonSoul:Init()
end
function DungeonSoul:Update()
local npc = self.npc
local playerTarget = PlayerUtils.Get(npc.playerTargetIndex)
if playerTarget ~= nil then
local distance = npc:GetDistance(playerTarget.centerX, playerTarget.centerY)
if distance < 360 then
npc:Fly(false) -- random fly
else
npc:Fly()
end
if distance < 640 then
if npc.tickTime > 0 and npc.tickTime % 128 == 0 then
if MiscUtils.RayReach(npc.centerX, npc.centerY, playerTarget.centerX, playerTarget.centerY) then
local angle = npc:GetAngleTo(playerTarget.centerX, playerTarget.centerY)
local proj = ProjectileUtils.CreateFromNpc(npc, Reg.ProjectileID("fire_charge"),
npc.centerX, npc.centerY, 5 * math.cos(angle), 5 * math.sin(angle), npc.baseAttack)
proj.isCheckPlayer = true
SoundUtils.PlaySound(Reg.SoundID("fireball"), npc.centerXi, npc.centerYi)
end
end
end
else
npc:Fly(false)
end
if npc.tickTime % 4 == 0 then
EffectUtils.Create(Reg.EffectID("flame_star"), npc.randX, npc.randY,
-npc.speedX, -npc.speedY,
Utils.RandSym(1.0), Utils.RandDoubleArea(1, 2))
end
LightingUtils.Add(npc.centerXi, npc.centerYi, 24, 12, 0, 0)
end
function DungeonSoul:OnDraw()
local npc = self.npc
if npc.maxSpeed > 0 then
npc.spriteEx.angle = npc.speedX / npc.maxSpeed / 4
else
npc.spriteEx.angle = 0
end
end
return DungeonSoul
================================================
FILE: npc_ai/Eagle.json
================================================
{
"Eagle": {
"script": {
"path": "Eagle.lua"
}
}
}
================================================
FILE: npc_ai/Eagle.lua
================================================
---@type ModNpc
local Eagle = class("Eagle", ModNpc)
function Eagle:Update()
self.npc:Fly()
end
function Eagle:OnDraw()
local npc = self.npc
if npc.maxSpeed > 0 then
npc.spriteEx.angle = npc.speedX / npc.maxSpeed / 2
end
end
return Eagle
================================================
FILE: npc_ai/Ender_Dragon.json
================================================
{
"Ender_Dragon": {
"pAI": "Ender_Dragon_AI"
}
}
================================================
FILE: npc_ai/Enderman.json
================================================
{
"Enderman": {
"script": {
"path": "Enderman.lua"
}
}
}
================================================
FILE: npc_ai/Enderman.lua
================================================
---@type ModNpc
local Enderman = class("Enderman", require("HumanFighter"))
local function Teleport(npc)
local currentX = npc.x
local currentY = npc.y
local teleportSuccess = npc:RandomTeleport(32)
if teleportSuccess then
local sg_portal = Reg.SoundGroupID("portal")
local e_ender_flash = Reg.EffectID("ender_flash")
for _ = 1, 16 do
EffectUtils.Create(e_ender_flash, currentX + Utils.RandInt(npc.width),
currentY + Utils.RandInt(npc.height),
Utils.RandSym(1), Utils.RandSym(1), Utils.RandSym(1), 2)
end
for _ = 1, 16 do
EffectUtils.Create(e_ender_flash, npc.randX, npc.randY,
Utils.RandSym(1), Utils.RandSym(1), Utils.RandSym(1), 2)
end
SoundUtils.PlaySoundGroup(sg_portal, npc.centerXi, npc.centerYi)
end
end
function Enderman:Init()
self.boneSizeIndex = 1
Enderman.super.Init(self)
end
function Enderman:Update()
local npc = self.npc
if npc.angry then
print("aaaa")
npc.maxSpeed = npc.maxSpeed * 1.5
if npc.stand and Utils.RandTry(32) then
npc.speedY = -6
end
else
npc:TryMakeSound()
end
npc:Walk()
local tp = false
if npc.inLiquid then
tp = true
elseif npc.stand and Utils.RandTry(256) then
tp = true
else
-- check projectiles
local projectiles = ProjectileUtils.SearchByCircle(npc.centerX, npc.centerY, 80)
for i = 1, projectiles.length do
local proj = projectiles[i]
if proj.isCheckNpc then
tp = true
break
end
end
end
if tp then
Teleport(npc)
end
end
function Enderman:OnHit()
Teleport(self.npc)
end
return Enderman
================================================
FILE: npc_ai/Evil.json
================================================
{
"Evil": {
"script": {
"path": "Evil.lua"
}
}
}
================================================
FILE: npc_ai/Evil.lua
================================================
---@class TC.Evil:ModNpc
local Evil = class("Evil", ModNpc)
function Evil:Update()
local npc = self.npc
npc:Fly()
if npc.speedY >= 0 then
local b1 = Utils.RandTry(8)
local b2 = Utils.RandTry(8)
if b1 or b2 then
local angle = npc.speedX / npc.maxSpeed / 2
local ex = 32 * math.cos(angle)
local ey = 32 * math.sin(angle)
if b1 then
EffectUtils.Create(Reg.EffectID("ender_flash"), npc.centerX + ex, npc.centerY + ey, Utils.RandSym(0.25),
Utils.RandSym(0.25), 0, Utils.RandDoubleArea(1, 1))
end
if b2 then
EffectUtils.Create(Reg.EffectID("ender_flash"), npc.centerX - ex, npc.centerY - ey, Utils.RandSym(0.25),
Utils.RandSym(0.25), 0, Utils.RandDoubleArea(1, 1))
end
end
else
if Utils.RandTry(4) then
EffectUtils.Create(Reg.EffectID("ender_flash"), npc.centerX + Utils.RandSym(8), npc.centerY + 8, Utils.RandSym(1),
Utils.RandSym(1), 0, Utils.RandDoubleArea(1, 1))
end
end
end
function Evil:OnDraw()
local npc = self.npc
if npc.maxSpeed > 0 then
npc.spriteEx.angle = npc.speedX / npc.maxSpeed / 2
end
local noChangeFrame = false
--if npc.speedY >= 0 then
-- if npc.frameTickTime <= 1 then
-- noChangeFrame = true
-- end
--end
if npc.frameTickTime > npc.frames * npc.frameSpeed then
noChangeFrame = true
end
if noChangeFrame then
npc.frameTickTime = 0
end
end
return Evil
================================================
FILE: npc_ai/Evoker.json
================================================
{
"Evoker": {
"script": {
"path": "Evoker.lua"
}
}
}
================================================
FILE: npc_ai/Evoker.lua
================================================
---@class TC.Evoker:ModNpc
local Evoker = class("Evoker", ModNpc)
local ST_NORMAL = 0
local ST_FIRING = 1
local SHOOT_TIMES = 3
function Evoker:Init()
self.shootTimes = 0
end
function Evoker:Update()
local npc = self.npc
npc.speedX = Utils.SlowSpeed1D(npc.speedX, 0.1)
local playerTarget = PlayerUtils.Get(npc.playerTargetIndex)
if playerTarget ~= nil then
npc.direction = (playerTarget.centerX > npc.centerX)
end
if npc.state == ST_NORMAL then
npc.stateTimer = npc.stateTimer + 1
if self.shootTimes < SHOOT_TIMES and npc.stateTimer > 64 then
npc.stateTimer = 0
npc.state = ST_FIRING
self.shootTimes = self.shootTimes + 1
if playerTarget ~= nil then
local angle = npc:GetAngleTo(playerTarget.centerX, playerTarget.centerY)
local proj = ProjectileUtils.CreateFromNpc(npc, Reg.ProjectileID("shulker_bullet"), npc.centerX, npc.centerY,
2 * math.cos(angle), 2 * math.sin(angle), npc.baseAttack)
proj.isCheckPlayer = true
SoundUtils.PlaySound(Reg.SoundID("fireball"), npc.centerXi, npc.centerYi)
end
end
if npc.speedY > 6 or (self.shootTimes >= SHOOT_TIMES and npc.stateTimer > 64) then
npc.state = 0
self.shootTimes = 0
npc.stateTimer = 0
local currentX = npc.x
local currentY = npc.y
local teleportSuccess = npc:RandomTeleport(32)
if teleportSuccess then
local e_ender_flash = Reg.EffectID("ender_flash")
for i = 1, 16 do
EffectUtils.Create(e_ender_flash, currentX + Utils.RandInt(npc.width),
currentY + Utils.RandInt(npc.height), Utils.RandSym(1), Utils.RandSym(1), Utils.RandSym(1), 2)
end
for i = 1, 16 do
EffectUtils.Create(e_ender_flash, npc.randX, npc.randY, Utils.RandSym(1), Utils.RandSym(1),
Utils.RandSym(1), 2)
end
SoundUtils.PlaySoundGroup(Reg.SoundGroupID("portal"), npc.centerXi, npc.centerYi)
end
end
elseif npc.state == ST_FIRING then
npc.stateTimer = npc.stateTimer + 1
if npc.stateTimer > 16 then
npc.stateTimer = 0
npc.state = ST_NORMAL
end
end
end
function Evoker:OnDraw()
local npc = self.npc
npc.spriteEx.angle = npc.speedX / 8
if npc.state == ST_NORMAL then
npc.spriteRect.x = 0
elseif npc.state == ST_FIRING then
npc.spriteRect.x = npc.spriteDefaultWidth
end
end
return Evoker
================================================
FILE: npc_ai/EyeGuard.json
================================================
{
"EyeGuard": {
"script": {
"path": "EyeGuard.lua"
}
}
}
================================================
FILE: npc_ai/EyeGuard.lua
================================================
---@class TC.EyeGuard:ModNpc
local EyeGuard = class("EyeGuard", ModNpc)
function EyeGuard:Init()
end
function EyeGuard:Update()
local npc = self.npc
local playerTarget = PlayerUtils.Get(npc.playerTargetIndex)
if playerTarget ~= nil then
local distance = npc:GetDistance(playerTarget.centerX, playerTarget.centerY)
if distance < 180 then
npc:Fly(false) -- random fly
else
npc:Fly()
end
else
npc:Fly(false, 0.5)
end
LightingUtils.Add(npc.centerXi, npc.centerYi, 24, 12, 0, 0)
end
function EyeGuard:OnDraw()
local npc = self.npc
if npc.maxSpeed > 0 then
npc.spriteEx.angle = npc.speedX / npc.maxSpeed / 4
else
npc.spriteEx.angle = 0
end
end
return EyeGuard
================================================
FILE: npc_ai/EyeGuardLaser.json
================================================
{
"EyeGuardLaser": {
"script": {
"path": "EyeGuardLaser.lua"
}
}
}
================================================
FILE: npc_ai/EyeGuardLaser.lua
================================================
---@class TC.EyeGuardLaser:ModNpc
local EyeGuardLaser = class("EyeGuardLaser", ModNpc)
function EyeGuardLaser:Init()
end
function EyeGuardLaser:Update()
local npc = self.npc
local playerTarget = PlayerUtils.Get(npc.playerTargetIndex)
if playerTarget ~= nil then
local distance = npc:GetDistance(playerTarget.centerX, playerTarget.centerY)
if distance < 360 then
npc:Fly(false) -- random fly
else
npc:Fly()
end
npc.direction = npc.centerX < playerTarget.centerX
if distance < 640 then
if npc.tickTime > 0 and npc.tickTime % 128 == 0 then
local angle = npc:GetAngleTo(playerTarget.centerX, playerTarget.centerY)
if angle > -math.pi / 2 and angle < math.pi / 2 then
angle = angle - 0.5
else
angle = angle + 0.5
end
local proj = ProjectileUtils.CreateFromNpc(npc, Reg.ProjectileID("fire_wave"),
npc.centerX, npc.centerY, 6 * math.cos(angle), 6 * math.sin(angle), npc.baseAttack)
proj.isCheckPlayer = true
end
end
else
npc:Fly(false)
end
if npc.tickTime % 64 == 0 then
EffectUtils.Create(Reg.EffectID("flame_star"), npc.randX, npc.randY,
-npc.speedX, -npc.speedY,
Utils.RandSym(1.0), Utils.RandDoubleArea(1, 2))
end
LightingUtils.Add(npc.centerXi, npc.centerYi, 24, 12, 0, 0)
end
function EyeGuardLaser:OnDraw()
local npc = self.npc
if npc.maxSpeed > 0 then
npc.spriteEx.angle = npc.speedX / npc.maxSpeed / 4
else
npc.spriteEx.angle = 0
end
end
return EyeGuardLaser
================================================
FILE: npc_ai/Fighter.json
================================================
{
"Fighter": {
"script": {
"path": "Fighter.lua"
}
}
}
================================================
FILE: npc_ai/Fighter.lua
================================================
---@class TC.Fighter:ModNpc
local Fighter = class("Fighter", ModNpc)
function Fighter:Update()
self.npc:TryMakeSound()
self.npc:Walk()
end
return Fighter
================================================
FILE: npc_ai/FireHellEater.json
================================================
{
"FireHellEater": {
"script": {
"path": "FireHellEater.lua"
}
}
}
================================================
FILE: npc_ai/FireHellEater.lua
================================================
---@class TC.FireHellEater:TC.HellEater
local FireHellEater = class("FireHellEater", require("HellEater"))
function FireHellEater:OnTileCollide(oldSpeedX, oldSpeedY)
end
return FireHellEater
================================================
FILE: npc_ai/FlameSoul.json
================================================
{
"FlameSoul": {
"script": {
"path": "FlameSoul.lua"
}
}
}
================================================
FILE: npc_ai/FlameSoul.lua
================================================
---@class TC.FlameSoul:ModNpc
local FlameSoul = class("FlameSoul", ModNpc)
function FlameSoul:Init()
end
function FlameSoul:Update()
local npc = self.npc
local playerTarget = PlayerUtils.Get(npc.playerTargetIndex)
if playerTarget ~= nil then
local distance = npc:GetDistance(playerTarget.centerX, playerTarget.centerY)
if distance < 360 then
npc:Fly(false) -- random fly
else
npc:Fly()
end
else
npc:Fly(false)
end
if npc.tickTime % 4 == 0 then
EffectUtils.Create(Reg.EffectID("flame_star"), npc.randX, npc.randY,
-npc.speedX, -npc.speedY,
Utils.RandSym(1.0), Utils.RandDoubleArea(1, 2))
end
LightingUtils.Add(npc.centerXi, npc.centerYi, 24, 12, 0, 0)
end
function FlameSoul:OnDraw()
local npc = self.npc
if npc.maxSpeed > 0 then
npc.spriteEx.angle = npc.speedX / npc.maxSpeed / 4
else
npc.spriteEx.angle = 0
end
end
return FlameSoul
================================================
FILE: npc_ai/FlyEye.json
================================================
{
"FlyEye": {
"script": {
"path": "FlyEye.lua"
}
}
}
================================================
FILE: npc_ai/FlyEye.lua
================================================
---@class TC.FlyEye:ModNpc
local FlyEye = class("FlyEye", ModNpc)
function FlyEye:Update()
self.npc:Fly()
end
function FlyEye:OnDraw()
local npc = self.npc
if npc.maxSpeed > 0 then
npc.spriteEx.angle = npc.speedX / npc.maxSpeed / 2
end
end
return FlyEye
================================================
FILE: npc_ai/FlySkeleton.json
================================================
{
"FlySkeleton": {
"script": {
"path": "FlySkeleton.lua"
}
}
}
================================================
FILE: npc_ai/FlySkeleton.lua
================================================
---@class TC.FlySkeleton:TC.HumanFighter
local FlySkeleton = class("FlySkeleton", require("HumanFighter"))
function FlySkeleton:Init()
FlySkeleton.super.Init(self)
end
function FlySkeleton:Update()
local npc = self.npc
npc:Fly()
if npc.tickTime % 4 == 0 then
EffectUtils.Create(Reg.EffectID("flash2"), npc.randX, npc.randY, Utils.RandSym(0.2), Utils.RandSym(0.2), 0,
Utils.RandDoubleArea(0.5, 0.5))
end
self.isFrontLegOverwrite = true
self.isBackLegOverwrite = true
self.frontLegOverwriteAngle = math.cos(npc.tickTime / 16) * 0.2 + 0.4
self.backLegOverwriteAngle = math.sin(npc.tickTime / 16) * 0.2 + 0.4
end
return FlySkeleton
================================================
FILE: npc_ai/Ghast.json
================================================
{
"Ghast": {
"script": {
"path": "Ghast.lua"
}
}
}
================================================
FILE: npc_ai/Ghast.lua
================================================
---@type ModNpc
local Ghast = class("Ghast", ModNpc)
local ST_NORMAL = 0
local ST_FIRING = 1
function Ghast:Update()
local npc = self.npc
npc:TryMakeSound()
npc:Fly(false)
local playerTarget = PlayerUtils.Get(npc.playerTargetIndex)
if playerTarget ~= nil then
npc.direction = (playerTarget.centerX > npc.centerX)
if npc.state == ST_NORMAL then
npc.stateTimer = npc.stateTimer + 1
if npc.stateTimer > 256 then
npc.stateTimer = 0
local angle = npc:GetAngleTo(playerTarget.centerX, playerTarget.centerY)
local shootX = 0
local shootY = npc.centerY
if npc.direction then
shootX = npc.rightX - 16
else
shootX = npc.x + 16
end
local shootXi = Utils.Cell(shootX)
local shootYi = Utils.Cell(shootY)
if not MapUtils.IsSolid(shootXi, shootYi) then
local proj = ProjectileUtils.CreateFromNpc(npc, Reg.ProjectileID("fire_charge"), shootX, shootY, 4 * math.cos(angle),
4 * math.sin(angle), npc.baseAttack)
if proj.modData:DataOf("Fireball") then
proj.isCheckPlayer = true
proj.modData.boom = true -- explosion when hit
end
SoundUtils.PlaySound(Reg.SoundID("ghast_charge"), npc.centerXi, npc.centerYi)
npc.state = ST_FIRING
end
end
elseif npc.state == ST_FIRING then
npc.stateTimer = npc.stateTimer + 1
if npc.stateTimer > 32 then
npc.stateTimer = 0
npc.state = ST_NORMAL
end
end
else
npc.stateTimer = 0
npc.state = ST_NORMAL
end
end
function Ghast:OnDraw()
local npc = self.npc
if npc.state == ST_FIRING then
npc.spriteRect.x = npc.spriteDefaultWidth
end
if npc.maxSpeed > 0 then
npc.spriteEx.angle = npc.speedX / npc.maxSpeed / 8
end
end
return Ghast
================================================
FILE: npc_ai/GhostGunner.json
================================================
{
"GhostGunner": {
"script": {
"path": "GhostGunner.lua"
}
}
}
================================================
FILE: npc_ai/GhostGunner.lua
================================================
---@class TC.GhostGunner:TC.HumanFighter
local GhostGunner = class("GhostGunner", require("HumanFighter"))
function GhostGunner:Init()
GhostGunner.super.Init(self)
self.inventory = Inventory.new(1)
self.npc.dataWatcher:AddInventory(self.inventory)
self.itemSlotHeld = self.inventory:GetSlot(0)
self.itemSlotHeld:PushStack(ItemStack.new(ItemRegistry.GetItemByIDName("super_shark_ghost")))
self.isFrontHandLook = true
self.isBackHandLook = true
self.ghostAllowToShoot = false
self.isGhostGuard = true
self.GHOST_ALLOW_TO_SHOOT = self.npc.dataWatcher:AddBool(self.ghostAllowToShoot)
end
function GhostGunner:OnHit()
self.ghostAllowToShoot = true
end
function GhostGunner:Update()
local npc = self.npc
if NetMode.current == NetMode.Server then
npc.dataWatcher:UpdateBool(self.GHOST_ALLOW_TO_SHOOT, self.ghostAllowToShoot)
else
self.ghostAllowToShoot = npc.dataWatcher:GetBool(self.GHOST_ALLOW_TO_SHOOT)
end
npc:Fly(self.ghostAllowToShoot)
if npc.tickTime % 4 == 0 then
EffectUtils.Create(Reg.EffectID("flash2"), npc.randX, npc.randY, Utils.RandSym(0.2), Utils.RandSym(0.2), 0,
Utils.RandDoubleArea(0.5, 0.5))
end
if self.ghostAllowToShoot then
local watchAngle = npc.watchAngle
self.backHandLookAngle = watchAngle
self.frontHandLookAngle = watchAngle
if npc.tickTime % 64 == 0 then
self.isUsingItemForAnimation = true
end
else
self.frontHandLookAngle = math.cos(self.npc.tickTime / 16) / 4
self.backHandLookAngle = math.sin(self.npc.tickTime / 16) / 4
end
end
return GhostGunner
================================================
FILE: npc_ai/GhostSoul.json
================================================
{
"GhostSoul": {
"script": {
"path": "GhostSoul.lua"
}
}
}
================================================
FILE: npc_ai/GhostSoul.lua
================================================
---@class TC.GhostSoul:ModNpc
local GhostSoul = class("GhostSoul", ModNpc)
function GhostSoul:Update()
self.npc:Fly()
end
function GhostSoul:OnDraw()
local npc = self.npc
if npc.maxSpeed > 0 then
npc.spriteEx.angle = npc.speedX / npc.maxSpeed / 2
end
end
return GhostSoul
================================================
FILE: npc_ai/GiantCursedSkull.json
================================================
{
"GiantCursedSkull": {
"script": {
"path": "GiantCursedSkull.lua"
}
}
}
================================================
FILE: npc_ai/GiantCursedSkull.lua
================================================
---@class TC.GiantCursedSkull:ModNpc
local GiantCursedSkull = class("GiantCursedSkull", ModNpc)
local ST_READY = 0
local ST_DASH = 1
function GiantCursedSkull:Init()
self.facingAngle = 0
end
function GiantCursedSkull:Update()
local npc = self.npc
local flyOnly = true
local playerTarget = PlayerUtils.Get(npc.playerTargetIndex)
if playerTarget ~= nil then
local distance = npc:GetDistance(playerTarget.centerX, playerTarget.centerY)
if distance < 340 then
flyOnly = false
if npc.state == ST_READY then
npc.speedX, npc.speedY = Utils.SlowSpeed2D(npc.speedX, npc.speedY, 0.1)
npc.stateTimer = npc.stateTimer + 1
local angle = npc:GetAngleTo(playerTarget.centerX, playerTarget.centerY)
if npc.stateTimer >= 32 then
npc.speedX = npc.maxSpeed * math.cos(angle) * 2
npc.speedY = npc.maxSpeed * math.sin(angle) * 2
self.facingAngle = angle
npc.state = ST_DASH
npc.stateTimer = 0
else
self.facingAngle = self.facingAngle + Utils.FixAngle(angle - self.facingAngle) * 0.1
end
elseif npc.state == ST_DASH then
npc.maxSpeed = 3
npc:Fly(true, 0.1, true)
npc.stateTimer = npc.stateTimer + 1
if npc.stateTimer >= 128 then
npc.state = ST_READY
npc.stateTimer = 0
end
end
end
end
if flyOnly then
npc.maxSpeed = 1.25
if playerTarget ~= nil then
self.facingAngle = npc:GetAngleTo(playerTarget.centerX, playerTarget.centerY)
else
self.facingAngle = npc.speedAngle
end
npc.state = ST_READY
npc.stateTimer = 0
npc:Fly(true, 0.1, true)
end
if npc.speedX > 0 then
npc.direction = true
elseif npc.speedX < 0 then
npc.direction = false
end
if npc.tickTime % 8 == 0 then
EffectUtils.Create(Reg.EffectID("flame_star"), npc.randX, npc.randY, Utils.RandSym(1), Utils.RandSym(1), 0,
Utils.RandDoubleArea(1, 1))
EffectUtils.Create(Reg.EffectID("flame_star"), npc.randX, npc.randY, Utils.RandSym(1), -Utils.RandDouble(2), 0,
Utils.RandDoubleArea(0.5, 0.5))
end
end
function GiantCursedSkull:OnDraw()
local npc = self.npc
npc.spriteEx.angle = npc.speedX / npc.maxSpeed / 3
end
return GiantCursedSkull
================================================
FILE: npc_ai/GrimReaper.json
================================================
{
"GrimReaper": {
"script": {
"path": "GrimReaper.lua"
}
}
}
================================================
FILE: npc_ai/GrimReaper.lua
================================================
---@class TC.GrimReaper:ModNpc
local GrimReaper = class("GrimReaper", ModNpc)
local ST_NORMAL = 0
local ST_FIRING = 1
local SHOOT_TIMES = 3
function GrimReaper:Init()
self.shootTimes = 0
end
function GrimReaper:Update()
local npc = self.npc
npc.speedX = Utils.SlowSpeed1D(npc.speedX, 0.1)
local playerTarget = PlayerUtils.Get(npc.playerTargetIndex)
if playerTarget ~= nil then
npc.direction = (playerTarget.centerX > npc.centerX)
end
if npc.state == ST_NORMAL then
npc.stateTimer = npc.stateTimer + 1
if self.shootTimes < SHOOT_TIMES and npc.stateTimer > 64 then
npc.stateTimer = 0
npc.state = ST_FIRING
self.shootTimes = self.shootTimes + 1
if playerTarget ~= nil then
local angle = npc:GetAngleTo(playerTarget.centerX, playerTarget.centerY)
local proj = ProjectileUtils.CreateFromNpc(npc, Reg.ProjectileID("shulker_bullet"), npc.centerX, npc.centerY,
2 * math.cos(angle), 2 * math.sin(angle), npc.baseAttack)
proj.isCheckPlayer = true
SoundUtils.PlaySound(Reg.SoundID("fireball"), npc.centerXi, npc.centerYi)
end
end
if npc.speedY > 6 or (self.shootTimes >= SHOOT_TIMES and npc.stateTimer > 64) then
npc.state = 0
self.shootTimes = 0
npc.stateTimer = 0
local currentX = npc.x
local currentY = npc.y
local teleportSuccess = npc:RandomTeleport(32)
if teleportSuccess then
local e_ender_flash = Reg.EffectID("ender_flash")
for i = 1, 16 do
EffectUtils.Create(e_ender_flash, currentX + Utils.RandInt(npc.width),
currentY + Utils.RandInt(npc.height), Utils.RandSym(1), Utils.RandSym(1), Utils.RandSym(1), 2)
end
for i = 1, 16 do
EffectUtils.Create(e_ender_flash, npc.randX, npc.randY, Utils.RandSym(1), Utils.RandSym(1),
Utils.RandSym(1), 2)
end
SoundUtils.PlaySoundGroup(Reg.SoundGroupID("portal"), npc.centerXi, npc.centerYi)
end
end
elseif npc.state == ST_FIRING then
npc.stateTimer = npc.stateTimer + 1
if npc.stateTimer > 16 then
npc.stateTimer = 0
npc.state = ST_NORMAL
end
end
end
function GrimReaper:OnDraw()
local npc = self.npc
npc.spriteEx.angle = npc.speedX / 8
if npc.state == ST_NORMAL then
npc.spriteRect.x = 0
elseif npc.state == ST_FIRING then
npc.spriteRect.x = npc.spriteDefaultWidth
end
end
return GrimReaper
================================================
FILE: npc_ai/Guardian.json
================================================
{
"Guardian": {
"script": {
"path": "Guardian.lua"
}
}
}
================================================
FILE: npc_ai/Guardian.lua
================================================
---@type ModNpc
local Guardian = class("Guardian", ModNpc)
local ST_NORMAL = 0
local ST_ANGRY = 1
local ST_SHOOTING = 2
function Guardian:Update()
local npc = self.npc
npc:Swim()
local playerTarget = PlayerUtils.Get(npc.playerTargetIndex)
if playerTarget ~= nil then
local distance = npc:GetDistance(playerTarget.centerX, playerTarget.centerY)
if distance < 360 then
if npc.state == ST_NORMAL then
npc.stateTimer = npc.stateTimer + 1
if npc.stateTimer > 16 then
npc.stateTimer = 0
npc.state = ST_ANGRY
end
elseif npc.state == ST_ANGRY then
npc.direction = (playerTarget.centerX > npc.centerX)
npc.stateTimer = npc.stateTimer + 1
if npc.stateTimer > 64 then
npc.stateTimer = 0
npc.state = ST_SHOOTING
end
elseif npc.state == ST_SHOOTING then
npc.direction = (playerTarget.centerX > npc.centerX)
local shootAngle = npc:GetAngleTo(playerTarget.centerX, playerTarget.centerY)
if npc.tickTime % 16 == 0 then
local proj = ProjectileUtils.CreateFromNpc(npc, Reg.ProjectileID("bullet_laser"), npc.centerX, npc.centerY,
9 * math.cos(shootAngle), 9 * math.sin(shootAngle), npc.baseAttack)
proj.isCheckPlayer = true
SoundUtils.PlaySound(Reg.SoundID("rifle_fire"), npc.centerXi, npc.centerYi)
end
npc.stateTimer = npc.stateTimer + 1
if npc.stateTimer > 100 then
npc.stateTimer = 0
npc.state = ST_NORMAL
end
end
else
npc.stateTimer = 0
npc.state = ST_NORMAL
end
else
npc.stateTimer = 0
npc.state = ST_NORMAL
end
end
function Guardian:OnDraw()
local npc = self.npc
npc.spriteOffsetX = 0
npc.spriteOffsetY = 0
if npc.state == ST_ANGRY then
local rate = Utils.SinValue(npc.tickTime, 16)
local scaleRate = 1.05 + rate * 0.05
npc.spriteEx.scaleRateX = scaleRate
npc.spriteEx.scaleRateY = scaleRate
npc.spriteOffsetX = -(scaleRate - 1) * npc.spriteDefaultWidth / 2
npc.spriteOffsetY = -(scaleRate - 1) * npc.spriteDefaultHeight / 2
end
end
return Guardian
================================================
FILE: npc_ai/HellDestroyer.lua
================================================
---@class TC.HellDestroyer:TC.BaseSnake
local HellDestroyer = class("HellDestroyer", require("BaseSnake"))
local PhysicsUtil = require("util.PhysicsUtil")
function HellDestroyer:Init()
HellDestroyer.super.Init(self)
self:SetSnakeData(24, Reg.NpcID("worm_body"), Reg.NpcID("worm_tail"),
72, 34, 48, Size.new(46, 52), Size.new(60, 64)
)
self.npc.isAntiLava = true
self:NotifyAllPlayer("nether_destroyer")
end
function HellDestroyer:Update()
local npc = self.npc
if NetMode.current == NetMode.Server then
local playerTarget = PlayerUtils.Get(npc.playerTargetIndex)
if playerTarget ~= nil then
npc.speedX, npc.speedY = PhysicsUtil.SightChaseSpeed2D(npc.speedX, npc.speedY, 0.2,
Utils.GetAngle(playerTarget.centerX - npc.centerX, playerTarget.centerY - npc.centerY),
8)
npc.speedX = npc.speedX + Utils.RandSym(0.5)
npc.speedY = npc.speedY + Utils.RandSym(0.5)
end
local makeShoot = false
if npc.tickTime > 0 then
if npc.health > npc.maxHealth / 3 then
makeShoot = npc.tickTime % 512 == 0
else
makeShoot = npc.tickTime % 256 == 0
end
end
if makeShoot then
local cxi, cyi = npc.centerXi, npc.centerYi
if not MapUtils.IsSolid(cxi, cyi) then
NpcUtils.Create(Reg.NpcID("small_hell_eater"), npc.centerX, npc.centerY,
Utils.RandSym(2), Utils.RandSym(2))
SoundUtils.PlaySound(Reg.SoundID("fireball"), cxi, cyi)
end
end
makeShoot = false
if npc.tickTime > 0 then
if npc.health > npc.maxHealth / 2 then
makeShoot = (npc.tickTime + 64) % 1024 == 0
else
makeShoot = (npc.tickTime + 64) % 512 == 0
end
end
if makeShoot then
local cxi, cyi = npc.centerXi, npc.centerYi
NpcUtils.Create(Reg.NpcID("small_fire_hell_eater"), npc.centerX, npc.centerY,
Utils.RandSym(2), Utils.RandSym(2))
SoundUtils.PlaySound(Reg.SoundID("fireball"), cxi, cyi)
end
end
end
function HellDestroyer:OnKilled()
HellDestroyer.super.OnKilled(self)
self:NotifyAllPlayer("nether_destroyer_killed")
end
function HellDestroyer:NotifyAllPlayer(advancementIDName)
local advancementID = Reg.AdvancementID(advancementIDName)
local players = PlayerUtils.SearchByCircle(self.npc.centerX, self.npc.centerY, 300 * 16)
---@param player Player
for _, player in each(players) do
player:FinishAdvancement(advancementID)
end
end
return HellDestroyer
================================================
FILE: npc_ai/HellDestroyer_Head.json
================================================
{
"HellDestroyer_Head": {
"script": {
"path": "HellDestroyer.lua"
}
}
}
================================================
FILE: npc_ai/HellEater.json
================================================
{
"HellEater": {
"script": {
"path": "HellEater.lua"
}
}
}
================================================
FILE: npc_ai/HellEater.lua
================================================
---@class TC.HellEater:ModNpc
local HellEater = class("HellEater", ModNpc)
local ST_READY = 0
local ST_DASH = 1
function HellEater:Init()
self.dashTimes = 0
self.dashAngle = 0
self.DASH_ANGLE = self.npc.dataWatcher:AddDouble(0.0)
end
function HellEater:Update()
self:RecvSync()
local npc = self.npc
local flyOnly = true
local playerTarget = PlayerUtils.Get(npc.playerTargetIndex)
if playerTarget ~= nil then
local distance = npc:GetDistance(playerTarget.centerX, playerTarget.centerY)
if distance < 640 then
flyOnly = false
if npc.state == ST_READY then
npc.speedX, npc.speedY = Utils.SlowSpeed2D(npc.speedX, npc.speedY, 0.1)
npc.stateTimer = npc.stateTimer + 1
local angle = npc:GetAngleTo(playerTarget.centerX, playerTarget.centerY)
if npc.stateTimer >= 64 then
npc.speedX = npc.maxSpeed * math.cos(angle) * 2
npc.speedY = npc.maxSpeed * math.sin(angle) * 2
self.dashAngle = angle
npc.state = ST_DASH
npc.stateTimer = 0
self.dashTimes = self.dashTimes + 1
else
self.dashAngle = self.dashAngle + Utils.FixAngle(angle - self.dashAngle) *
0.1
end
elseif npc.state == ST_DASH then
-- self.dashAngle = self.speedAngle
npc.stateTimer = npc.stateTimer + 1
if self.dashTimes < 4 and npc.stateTimer >= 32 then
npc.state = ST_READY
npc.stateTimer = 0
end
if npc.tickTime % 2 == 0 then
EffectUtils.Create(Reg.EffectID("fire_flame"), npc.randX, npc.randY, Utils.RandSym(0.15), Utils.RandSym(0.15),
1, Utils.RandDoubleArea(0.5, 0.25), Utils.RandDoubleArea(0.75, 0.25))
end
end
end
end
if flyOnly then
self.dashAngle = npc.speedAngle
npc.state = ST_READY
npc.stateTimer = 0
self.dashTimes = 0
npc.maxSpeed = npc.maxSpeed * 4
npc:Fly(false, 0.1, true)
end
self:SendSync()
end
function HellEater:OnTileCollide(oldSpeedX, oldSpeedY)
local npc = self.npc
npc:Kill()
MiscUtils.CreateExplosion(npc.centerXi, npc.centerYi, 6, false, true, false)
EffectUtils.CreateExplosion(npc.centerX, npc.centerY)
end
function HellEater:OnDraw()
self.npc.spriteEx.angle = self.dashAngle
end
function HellEater:SendSync()
if NetMode.current == NetMode.Server then
self.npc.dataWatcher:UpdateDouble(self.DASH_ANGLE, self.dashAngle)
end
end
function HellEater:RecvSync()
if NetMode.current == NetMode.Client then
self.dashAngle = self.npc.dataWatcher:GetDouble(self.DASH_ANGLE)
end
end
return HellEater
================================================
FILE: npc_ai/HumanFighter.json
================================================
{
"HumanFighter": {
"script": {
"path": "HumanFighter.lua"
}
}
}
================================================
FILE: npc_ai/HumanFighter.lua
================================================
---@class TC.HumanFighter:TC.Fighter
local HumanFighter = class("HumanFighter", require("Fighter"))
local NpcHumanBoneInfo = require("bone2d.NpcHumanBoneInfo")
local cameraInGameInstance = require("client.CameraInGame").getInstance()
function HumanFighter:Init()
local npc = self.npc
if self.boneSizeIndex == nil then
self.boneSizeIndex = 0
end
self.bone = NpcHumanBoneInfo.getInstance():load(npc.id, npc.texture, self.boneSizeIndex)
self.itemSlotHeld = nil ---@type Slot
self.isUsingItemForAnimation = false
self.normalActionStyle = "NORMAL"
self.isHeadLook = false
self.headLookAngle = 0
self.headLookDenominator = 1.0
self.isBackHandLook = false
self.backHandLookAngle = 0
self.isBackHandLookAngleSameDirection = false
self.isFrontHandLook = false
self.frontHandLookAngle = 0
self.isFrontHandLookAngleSameDirection = false
self.isFrontLegOverwrite = false
self.frontLegOverwriteAngle = 0
self.isFrontLegLookAngleSameDirection = false
self.isBackLegOverwrite = false
self.backLegOverwriteAngle = 0
self.isBackLegLookAngleSameDirection = false
self.backItemCache = {}
end
function HumanFighter:PostUpdate()
self:UpdateBone()
end
function HumanFighter:UpdateBone()
local npc = self.npc
self.bone.joints.position = Vector2.new(npc.centerX, npc.bottomY)
if self.itemSlotHeld then
NpcHumanBoneInfo.checkHandItem(self:GetHeldItemJoint(), self.itemSlotHeld, self.backItemCache)
end
local animator = self.bone.animator
animator:setBool("OnGround", npc.stand)
local speedRate = 0
if npc.maxSpeed > 0 then
speedRate = math.abs(npc.speedX) / npc.maxSpeed
end
speedRate = math.min(math.max(speedRate, 0), 1)
animator:setFloat("Speed", speedRate)
self.bone.joints.flip = not npc.direction
self.bone.joints.scale = Vector2.new(1, 1)
self.bone:update()
self:UpdateSpecialAnimation()
end
function HumanFighter:UpdateSpecialAnimation()
local hasJointChanged = false
if self.isHeadLook and self.headLookDenominator > 0 then
hasJointChanged = true
local head = self.bone.joints:getJoint("base.body.head")
head.angle = self:GetLookAngleInFacingDirection(self.headLookAngle) / self.headLookDenominator
end
if self.isBackHandLook then
hasJointChanged = true
local arm = self.bone.joints:getJoint("base.body.back_arm")
if self.isBackHandLookAngleSameDirection then
arm.angle = self.backHandLookAngle - math.pi * 0.5
else
arm.angle = self:GetLookAngleInFacingDirection(self.backHandLookAngle) - math.pi * 0.5
end
end
if self.isFrontHandLook then
hasJointChanged = true
local arm = self.bone.joints:getJoint("base.body.front_arm")
if self.isFrontHandLookAngleSameDirection then
arm.angle = self.frontHandLookAngle - math.pi * 0.5
else
arm.angle = self:GetLookAngleInFacingDirection(self.frontHandLookAngle) - math.pi * 0.5
end
end
if self.isFrontLegOverwrite then
hasJointChanged = true
local leg = self.bone.joints:getJoint("base.body.front_leg")
if self.isFrontLegLookAngleSameDirection then
leg.angle = self.frontLegOverwriteAngle
else
leg.angle = self:GetLookAngleInFacingDirection(self.frontLegOverwriteAngle)
end
end
if self.isBackLegOverwrite then
hasJointChanged = true
local leg = self.bone.joints:getJoint("base.body.back_leg")
if self.isBackLegLookAngleSameDirection then
leg.angle = self.backLegOverwriteAngle
else
leg.angle = self:GetLookAngleInFacingDirection(self.backLegOverwriteAngle)
end
end
if hasJointChanged then
self.bone:update(false)
end
if self.isUsingItemForAnimation then
self.isUsingItemForAnimation = false
if self.itemSlotHeld and self.itemSlotHeld.hasStack then
local stack = self.itemSlotHeld:GetStack()
stack:RunOnUsedByNpcEvent(self.npc)
local item = stack:GetItem()
if item.useSoundGroupID > 0 then
SoundUtils.PlaySoundGroup(item.useSoundGroupID, self.npc.centerXi, self.npc.centerYi)
end
if item.useSoundID > 0 then
SoundUtils.PlaySound(item.useSoundID, self.npc.centerXi, self.npc.centerYi)
end
end
end
end
function HumanFighter:GetLookAngleInFacingDirection(rawAngle)
local lookAngle = rawAngle
if not (lookAngle > -math.pi * 0.5 and lookAngle < math.pi * 0.5) then
lookAngle = math.pi - lookAngle
lookAngle = Utils.FixAngle(lookAngle)
end
return lookAngle
end
function HumanFighter:GetHeldItemJoint()
return NpcHumanBoneInfo.getItemJoint(self.bone, true)
end
function HumanFighter:OnRender()
self.bone.joints:render(cameraInGameInstance.camera)
end
function HumanFighter:DoExternArmsAnimation(amplitude, period)
if amplitude == nil then
amplitude = 0.25
end
if period == nil then
period = 16
end
amplitude = math.max(amplitude, 0.0)
period = math.max(period, 1)
local npc = self.npc
self.frontHandLookAngle = math.cos(npc.tickTime / period) * amplitude
self.backHandLookAngle = math.sin(npc.tickTime / period) * amplitude
end
return HumanFighter
================================================
FILE: npc_ai/IceElf.json
================================================
{
"IceElf": {
"script": {
"path": "IceElf.lua"
}
}
}
================================================
FILE: npc_ai/IceElf.lua
================================================
---@type ModNpc
local IceElf = class("IceElf", ModNpc)
local e_liquid_paticular = Reg.EffectID("liquid_paticular")
function IceElf:Update()
local npc = self.npc
npc:Fly()
if Utils.RandTry(16) then
EffectUtils.Create(e_liquid_paticular, npc.randX, npc.randY,
Utils.RandSym(1.0), Utils.RandSym(1.0))
end
end
function IceElf:OnDraw()
local npc = self.npc
if npc.maxSpeed > 0 then
npc.spriteEx.angle = npc.speedX / npc.maxSpeed / 2
else
npc.spriteEx.angle = 0
end
end
return IceElf
================================================
FILE: npc_ai/JungleSnake.lua
================================================
---@class TC.JungleSnake:TC.BaseSnake
local JungleSnake = class("JungleSnake", require("BaseSnake"))
function JungleSnake:Init()
JungleSnake.super.Init(self)
self:SetSnakeData(5, Reg.NpcID("vine_man_eater_body"), Reg.NpcID("vine_man_eater_tail"),
34, 36, 46, Size.new(44, 32), Size.new(54, 40)
)
end
function JungleSnake:Update()
if NetMode.current == NetMode.Server then
return
end
end
return JungleSnake
================================================
FILE: npc_ai/JungleSnake_Head.json
================================================
{
"JungleSnake_Head": {
"script": {
"path": "JungleSnake.lua"
}
}
}
================================================
FILE: npc_ai/LargeBat.json
================================================
{
"LargeBat": {
"script": {
"path": "LargeBat.lua"
}
}
}
================================================
FILE: npc_ai/LargeBat.lua
================================================
---@class TC.LargeBat:ModNpc
local LargeBat = class("LargeBat", ModNpc)
function LargeBat:Update()
local npc = self.npc
if npc.state == 0 then
npc.stateTimer = npc.stateTimer + 1
if npc.stateTimer > 64 then
npc.stateTimer = 0
npc.state = 1
end
npc:Fly()
elseif npc.state == 1 then
npc.speedX, npc.speedY = Utils.SlowSpeed2D(npc.speedX, npc.speedY, 0.35)
npc.stateTimer = npc.stateTimer + 1
if npc.stateTimer > 64 then
npc.stateTimer = 0
npc.state = 0
local ba = Utils.RandDouble(math.pi / 2)
for i = 0, 3 do
local angle = math.pi * 2 / 3 * i + ba
local proj = ProjectileUtils.CreateFromNpc(npc,
Reg.ProjectileID("lighting_bullet_blue"),
npc.centerX, npc.centerY,
3 * math.cos(angle), 3 * math.sin(angle), npc.baseAttack)
proj.isCheckPlayer = true
end
end
end
local effect = EffectUtils.Create(Reg.EffectID("chip"),
self.npc.randX, self.npc.bottomY + Utils.RandSym(12),
Utils.RandSym(0.1), Utils.RandDoubleArea(1, 1),
Utils.RandSym(1), 1.0, 0.8,
Color.new(200, 200, 200))
effect:SetDisappearTime(30)
LightingUtils.Add(npc.centerXi, npc.centerYi, 32)
end
function LargeBat:OnDraw()
local npc = self.npc
if npc.maxSpeed > 0 then
npc.spriteEx.angle = npc.speedX / npc.maxSpeed / 2
else
npc.spriteEx.angle = 0
end
end
return LargeBat
================================================
FILE: npc_ai/LargeSpider.json
================================================
{
"LargeSpider": {
"script": {
"path": "LargeSpider.lua"
}
}
}
================================================
FILE: npc_ai/LargeSpider.lua
================================================
---@class TC.LargeSpider:ModNpc
local LargeSpider = class("LargeSpider", ModNpc)
local State = {
NORMAL = 0,
READY_TO_JUMP = 1,
FALLEN = 2,
}
function LargeSpider:Update()
local npc = self.npc
if not npc.stand then
npc.state = State.FALLEN
if npc.direction then
npc.speedX = npc.speedX + 0.1
else
npc.speedX = npc.speedX - 0.1
end
npc.speedX = math.max(npc.speedX, -npc.maxSpeed)
npc.speedX = math.min(npc.speedX, npc.maxSpeed)
else
local playerTarget = PlayerUtils.Get(npc.playerTargetIndex)
if playerTarget ~= nil then
npc.direction = (playerTarget.centerX > npc.centerX)
npc.speedX = Utils.SlowSpeed1D(npc.speedX, 0.1)
if npc.state == State.NORMAL then
npc.stateTimer = npc.stateTimer + 1
-- if Utils.RandTry(32) then
if npc.stateTimer > 8 then
npc.stateTimer = 0
npc.state = State.READY_TO_JUMP
end
elseif npc.state == State.READY_TO_JUMP then
npc.stateTimer = npc.stateTimer + 1
if npc.stateTimer > 16 then
npc.stateTimer = 0
npc.state = State.FALLEN
if npc.direction then
npc.speedX = Utils.RandDoubleArea(npc.maxSpeed / 2, npc.maxSpeed / 2)
else
npc.speedX = -Utils.RandDoubleArea(npc.maxSpeed / 2, npc.maxSpeed / 2)
end
npc.speedY = -Utils.RandDoubleArea(8, 4)
end
elseif npc.state == State.FALLEN then
npc.stateTimer = npc.stateTimer + 1
if npc.stateTimer > 16 then
npc.stateTimer = 0
npc.state = State.NORMAL
end
end
else
npc.stateTimer = 0
npc.state = State.NORMAL
end
end
if npc.stand then
npc.speedX = Utils.SlowSpeed1D(npc.speedX, 0.8)
end
end
function LargeSpider:OnDraw()
local npc = self.npc
npc.frameTickTime = 0
if not npc.stand then
npc.spriteRect.x = npc.spriteDefaultWidth
else
if npc.state == State.NORMAL then
npc.spriteRect.x = 0
else
npc.spriteRect.x = npc.spriteDefaultWidth
end
end
end
return LargeSpider
================================================
FILE: npc_ai/MagmaBirdo.json
================================================
{
"MagmaBirdo": {
"script": {
"path": "MagmaBirdo.lua"
}
}
}
================================================
FILE: npc_ai/MagmaBirdo.lua
================================================
---@type ModNpc
local MagmaBirdo = class("MagmaBirdo", ModNpc)
local ST_NORMAL = 0
local ST_READY_TO_FIRE = 1
local ST_FIRING = 2
function MagmaBirdo:Update()
local npc = self.npc
if npc.state == ST_NORMAL then
local playerTarget = PlayerUtils.Get(npc.playerTargetIndex)
if playerTarget ~= nil then
local distance = npc:GetDistance(playerTarget.centerX, playerTarget.centerY)
if distance < 240 then
if Utils.RandTry(64) then
npc.state = ST_READY_TO_FIRE
end
end
end
elseif npc.state == ST_READY_TO_FIRE then
npc.maxSpeed = npc.maxSpeed * 0.5
npc.stateTimer = npc.stateTimer + 1
if npc.stateTimer > 128 then
npc.stateTimer = 0
npc.state = ST_FIRING
end
elseif npc.state == ST_FIRING then
npc.maxSpeed = npc.maxSpeed * 0.25
if npc.tickTime % 8 == 0 then
local angle = npc.speedAngle
local proj = ProjectileUtils.CreateFromNpc(npc, Reg.ProjectileID("gun_fire"),
npc.centerX + math.cos(angle) * 20, npc.centerY + math.sin(angle) * 20,
10 * math.cos(angle), 10 * math.sin(angle), Attack.new(npc.baseAttack.attack * 0.4, 0, 0))
proj.isCheckPlayer = true
end
npc.stateTimer = npc.stateTimer + 1
if npc.stateTimer > 128 then
npc.stateTimer = 0
npc.state = ST_NORMAL
end
end
npc:Fly()
end
function MagmaBirdo:OnDraw()
local npc = self.npc
if npc.maxSpeed > 0 then
npc.spriteEx.angle = npc.speedX / npc.maxSpeed / 2
end
end
return MagmaBirdo
================================================
FILE: npc_ai/MagmaElf.json
================================================
{
"MagmaElf": {
"script": {
"path": "MagmaElf.lua"
}
}
}
================================================
FILE: npc_ai/MagmaElf.lua
================================================
---@type ModNpc
local MagmaElf = class("MagmaElf", ModNpc)
function MagmaElf:Update()
local npc = self.npc
npc:Walk()
if npc.inLiquid then
-- in lava
npc.gravity = 0
if npc.speedY > 0 then
npc.speedY = math.min(npc.speedY + 0.1, npc.maxSpeed)
else
npc.speedY = math.max(npc.speedY - 0.1, -npc.maxSpeed)
end
elseif not npc.inLiquid and npc.oldInLiquid then
-- just jump out of lava
if npc.speedY > -npc.jumpForce * 1.5 then
npc.speedY = -npc.jumpForce * 1.5
end
else
-- in air
npc.gravity = npc.gravity * 0.25
if npc.tickTime % 16 == 0 then
EffectUtils.Create(Reg.EffectID("fire_flame"), npc.randX, npc.randY, Utils.RandSym(0.25), Utils.RandSym(0.25), 0,
Utils.RandDoubleArea(0.5, 0.5))
end
end
LightingUtils.Add(npc.centerXi, npc.centerYi, 24, 12, 0, 0)
end
function MagmaElf:OnTileCollide(oldSpeedX, oldSpeedY)
local npc = self.npc
if npc.stand then
npc.speedY = -npc.jumpForce
end
end
function MagmaElf:OnDraw()
local npc = self.npc
npc.spriteEx.angle = npc.speedAngle
npc.spriteEx.flipHorizontal = false
end
return MagmaElf
================================================
FILE: npc_ai/MagmaSlime.json
================================================
{
"MagmaSlime": {
"script": {
"path": "MagmaSlime.lua"
}
}
}
================================================
FILE: npc_ai/MagmaSlime.lua
================================================
---@type ModNpc
local MagmaSlime = class("MagmaSlime", require("Slime"))
function MagmaSlime:Update()
MagmaSlime.super.Update(self)
local npc = self.npc
if npc.tickTime % 32 == 0 then
EffectUtils.Create(Reg.EffectID("fire_flame"), npc.randX, npc.y,
Utils.RandSym(1), -Utils.RandDouble(2),
0, Utils.RandDoubleArea(0.75, 0.25))
end
LightingUtils.Add(npc.centerXi, npc.centerYi, 24, 12, 0, 0)
end
return MagmaSlime
================================================
FILE: npc_ai/ManEater.json
================================================
{
"ManEater": {
"script": {
"path": "ManEater.lua"
}
}
}
================================================
FILE: npc_ai/ManEater.lua
================================================
---@type ModNpc
local ManEater = class("ManEater", ModNpc)
local ST_READY = 0
local ST_DASH = 1
function ManEater:Init()
self.dashAngle = 0.0
self.DASH_ANGLE = self.npc.dataWatcher:AddDouble(0.0)
end
function ManEater:Update()
self:RecvSync()
local npc = self.npc
local flyOnly = true
local playerTarget = PlayerUtils.Get(npc.playerTargetIndex)
if playerTarget ~= nil then
local distance = npc:GetDistance(playerTarget.centerX, playerTarget.centerY)
if distance < 440 then
flyOnly = false
if npc.state == ST_READY then
npc.speedX, npc.speedY = Utils.SlowSpeed2D(npc.speedX, npc.speedY, 0.1)
npc.stateTimer = npc.stateTimer + 1
local angle = npc:GetAngleTo(playerTarget.centerX, playerTarget.centerY)
if npc.stateTimer >= 64 then
npc.speedX = npc.maxSpeed * math.cos(angle) * 2
npc.speedY = npc.maxSpeed * math.sin(angle) * 2
self.dashAngle = angle
npc.state = ST_DASH
npc.stateTimer = 0
else
self.dashAngle = self.dashAngle + Utils.FixAngle(angle - self.dashAngle) * 0.1
end
elseif npc.state == ST_DASH then
npc.stateTimer = npc.stateTimer + 1
if npc.stateTimer >= 64 then
npc.state = ST_READY
npc.stateTimer = 0
end
if npc.tickTime % 4 == 0 then
EffectUtils.Create(
Reg.EffectID("liquid_paticular"),
npc.randX,
npc.randY,
Utils.RandSym(0.25),
Utils.RandSym(0.25),
1,
Utils.RandDoubleArea(1.0, 0.5),
Utils.RandDoubleArea(0.75, 0.25),
Color.new(255, 100, 100)
)
end
end
end
end
if flyOnly then
self.dashAngle = npc.speedAngle
npc.state = ST_READY
npc.stateTimer = 0
npc:Fly(true, 0.1, true)
end
self:SendSync()
end
function ManEater:OnDraw()
local npc = self.npc
npc.spriteEx.angle = self.dashAngle
end
function ManEater:SendSync()
if NetMode.current == NetMode.Server then
self.npc.dataWatcher:UpdateDouble(self.DASH_ANGLE, self.dashAngle)
end
end
function ManEater:RecvSync()
if NetMode.current == NetMode.Client then
self.dashAngle = self.npc.dataWatcher:GetDouble(self.DASH_ANGLE)
end
end
return ManEater
================================================
FILE: npc_ai/Meteor.json
================================================
{
"Meteor": {
"script": {
"path": "Meteor.lua"
}
}
}
================================================
FILE: npc_ai/Meteor.lua
================================================
---@type ModNpc
local Meteor = class("Meteor", ModNpc)
function Meteor:Update()
self.npc:Fly()
end
function Meteor:OnDraw()
self.npc.spriteEx.angle = self.npc.spriteEx.angle + 0.1
end
function Meteor:OnTileCollide(oldSpeedX, oldSpeedY)
local npc = self.npc
if npc.isCollisionLeft then
npc.speedX = npc.maxSpeed
elseif npc.isCollisionRight then
npc.speedX = -npc.maxSpeed
elseif npc.stand then
npc.speedY = -npc.maxSpeed
elseif npc.isCollisionTop then
npc.speedY = npc.maxSpeed
end
local playerTarget = PlayerUtils.Get(npc.playerTargetIndex)
if playerTarget ~= nil then
local distance = npc:GetDistance(playerTarget.centerX, playerTarget.centerY)
if distance < 360 then
npc:Kill()
MiscUtils.CreateExplosion(npc.centerXi, npc.centerYi, 4, true, true)
EffectUtils.CreateExplosion(npc.centerX, npc.centerY)
end
end
end
return Meteor
================================================
FILE: npc_ai/MiniGhast.json
================================================
{
"MiniGhast": {
"script": {
"path": "MiniGhast.lua"
}
}
}
================================================
FILE: npc_ai/MiniGhast.lua
================================================
---@class TC.MiniGhast:ModNpc
local MiniGhast = class("MiniGhast", ModNpc)
local ST_NORMAL = 0
local ST_FIRING = 1
function MiniGhast:Update()
local npc = self.npc
npc:TryMakeSound(1000)
npc:Fly(false)
local playerTarget = PlayerUtils.Get(npc.playerTargetIndex)
if playerTarget ~= nil then
npc.direction = (playerTarget.centerX > npc.centerX)
if npc.state == ST_NORMAL then
npc.stateTimer = npc.stateTimer + 1
if npc.stateTimer > 256 then
npc.stateTimer = 0
local shootX = 0
local shootY = npc.centerY
if npc.direction then
shootX = npc.rightX - 16
else
shootX = npc.x + 16
end
end
elseif npc.state == ST_FIRING then
npc.stateTimer = npc.stateTimer + 1
if npc.stateTimer > 32 then
npc.stateTimer = 0
npc.state = ST_NORMAL
end
end
else
npc.stateTimer = 0
npc.state = ST_NORMAL
end
npc.color = Color.new(255, 255, 255, 180)
end
function MiniGhast:OnDraw()
local npc = self.npc
if npc.state == ST_FIRING then
npc.spriteRect.x = npc.spriteDefaultWidth
end
if npc.maxSpeed > 0 then
npc.spriteEx.angle = npc.speedX / npc.maxSpeed / 8
end
end
function MiniGhast:OnHit()
local npc = self.npc
-- Let ghost gunners around shoot the players!
local npcList = NpcUtils.SearchByCircle(npc.centerX, npc.centerY, 60 * 16)
---@param n Npc
for _, n in each(npcList) do
local modNpc = n:GetModNpc()
if modNpc ~= nil and modNpc.isGhostGuard and modNpc.ghostAllowToShoot == false then
SoundUtils.PlaySound(Reg.SoundID("ghast_charge"), n.centerXi, n.centerYi)
modNpc.ghostAllowToShoot = true
print("TRIGGER GHOST GUNNER")
end
end
end
return MiniGhast
================================================
FILE: npc_ai/Paimon.json
================================================
{
"Paimon": {
"script": {
"path": "Paimon.lua"
}
}
}
================================================
FILE: npc_ai/Paimon.lua
================================================
---@class TC.Paimon:ModNpc
local Paimon = class("Paimon", ModNpc)
function Paimon:Init()
self.npc.noHurt = true
self.npc.noCollisionByWeapon = true
end
function Paimon:Update()
local npc = self.npc
---@type Player
local target = PlayerUtils.SearchNearestPlayer(npc.centerX, npc.centerY, 1000)
if target ~= nil then
if npc:GetDistance(target.centerX, target.centerY) < 128 then
npc.speedX, npc.speedY = Utils.SlowSpeed2D(npc.speedX, npc.speedY, 0.2)
npc.speedY = npc.speedY + math.sin(npc.tickTime / 8) / 4
npc.speedX = npc.speedX + math.cos(npc.tickTime / 18) / 6
else
local targetAngle = npc:GetAngleTo(target.centerX, target.centerY)
npc.speedX, npc.speedY = Utils.ForceSpeed2D(npc.speedX, npc.speedY, 0.2, targetAngle, npc.maxSpeed)
end
npc.direction = npc.centerX < target.centerX
else
npc.direction = npc.speedX > 0
end
end
function Paimon:OnDraw()
local npc = self.npc
if npc.maxSpeed > 0 then
npc.spriteEx.angle = npc.speedX / npc.maxSpeed / 4
end
end
return Paimon
================================================
FILE: npc_ai/Phantom.json
================================================
{
"Phantom": {
"script": {
"path": "Phantom.lua"
}
}
}
================================================
FILE: npc_ai/Phantom.lua
================================================
---@type ModNpc
local Phantom = class("Phantom", ModNpc)
function Phantom:Update()
local npc = self.npc
npc:Fly()
if npc.speedY >= 0 then
local b1 = Utils.RandTry(8)
local b2 = Utils.RandTry(8)
if b1 or b2 then
local angle = npc.speedX / npc.maxSpeed / 2
local ex = 32 * math.cos(angle)
local ey = 32 * math.sin(angle)
if b1 then
EffectUtils.Create(Reg.EffectID("ender_flash"), npc.centerX + ex, npc.centerY + ey, Utils.RandSym(0.25),
Utils.RandSym(0.25), 0, Utils.RandDoubleArea(1, 1))
end
if b2 then
EffectUtils.Create(Reg.EffectID("ender_flash"), npc.centerX - ex, npc.centerY - ey, Utils.RandSym(0.25),
Utils.RandSym(0.25), 0, Utils.RandDoubleArea(1, 1))
end
end
else
if Utils.RandTry(4) then
EffectUtils.Create(Reg.EffectID("ender_flash"), npc.centerX + Utils.RandSym(8), npc.centerY + 8, Utils.RandSym(1),
Utils.RandSym(1), 0, Utils.RandDoubleArea(1, 1))
end
end
end
function Phantom:OnDraw()
local npc = self.npc
if npc.maxSpeed > 0 then
npc.spriteEx.angle = npc.speedX / npc.maxSpeed / 2
end
local noChangeFrame = false
if npc.speedY >= 0 then
if npc.frameTickTime <= 1 then
noChangeFrame = true
end
end
if npc.frameTickTime > npc.frames * npc.frameSpeed then
noChangeFrame = true
end
if noChangeFrame then
npc.frameTickTime = 0
end
end
return Phantom
================================================
FILE: npc_ai/Pufferfish.json
================================================
{
"Pufferfish": {
"script": {
"path": "Pufferfish.lua"
}
}
}
================================================
FILE: npc_ai/Pufferfish.lua
================================================
---@type ModNpc
local Pufferfish = class("Pufferfish", ModNpc)
local ST_NORMAL = 0
local ST_EXPANDING = 1
function Pufferfish:Update()
local npc = self.npc
npc:Swim()
npc.state = ST_NORMAL
local playerTarget = PlayerUtils.Get(npc.playerTargetIndex)
if playerTarget ~= nil then
local distance = npc:GetDistance(playerTarget.centerX, playerTarget.centerY)
if distance < 128 then
npc.state = ST_EXPANDING
end
end
end
function Pufferfish:OnDraw()
local npc = self.npc
local scaleRate = npc.spriteEx.scaleRateX
if npc.state == ST_EXPANDING then
scaleRate = math.min(scaleRate + 0.01, 2)
else
scaleRate = math.max(scaleRate - 0.01, 1)
end
npc.spriteEx.scaleRateX = scaleRate
npc.spriteEx.scaleRateY = scaleRate
if scaleRate > 1 then
npc.spriteRect.x = npc.spriteRect.x + npc.spriteDefaultWidth
npc.spriteOffsetX = -(scaleRate - 1)* npc.spriteDefaultWidth / 2
npc.spriteOffsetY = -(scaleRate - 1)* npc.spriteDefaultHeight / 2
end
end
return Pufferfish
================================================
FILE: npc_ai/RaggedMage.json
================================================
{
"RaggedMage": {
"script": {
"path": "RaggedMage.lua"
}
}
}
================================================
FILE: npc_ai/RaggedMage.lua
================================================
---@class TC.RaggedMage:ModNpc
local RaggedMage = class("RaggedMage", ModNpc)
local ST_NORMAL = 0
local ST_FIRING = 1
local SHOOT_TIMES = 3
function RaggedMage:Init()
self.shootTimes = 0
end
function RaggedMage:Update()
local npc = self.npc
npc.speedX = Utils.SlowSpeed1D(npc.speedX, 0.1)
local playerTarget = PlayerUtils.Get(npc.playerTargetIndex)
if playerTarget ~= nil then
npc.direction = (playerTarget.centerX > npc.centerX)
end
if npc.state == ST_NORMAL then
npc.stateTimer = npc.stateTimer + 1
if self.shootTimes < SHOOT_TIMES and npc.stateTimer > 64 then
npc.stateTimer = 0
npc.state = ST_FIRING
self.shootTimes = self.shootTimes + 1
if playerTarget ~= nil then
local angle = npc:GetAngleTo(playerTarget.centerX, playerTarget.centerY)
local proj = ProjectileUtils.CreateFromNpc(npc, Reg.ProjectileID("lighting_bullet_red_invert2"), npc.centerX, npc.centerY,
2 * math.cos(angle), 2 * math.sin(angle), npc.baseAttack)
proj.isCheckPlayer = true
SoundUtils.PlaySound(Reg.SoundID("fireball"), npc.centerXi, npc.centerYi)
end
end
if npc.speedY > 6 or (self.shootTimes >= SHOOT_TIMES and npc.stateTimer > 64) then
npc.state = 0
self.shootTimes = 0
npc.stateTimer = 0
local currentX = npc.x
local currentY = npc.y
local teleportSuccess = npc:RandomTeleport(32)
if teleportSuccess then
local e_ender_flash = Reg.EffectID("ender_flash")
for i = 1, 16 do
EffectUtils.Create(e_ender_flash, currentX + Utils.RandInt(npc.width),
currentY + Utils.RandInt(npc.height), Utils.RandSym(1), Utils.RandSym(1), Utils.RandSym(1), 2)
end
for i = 1, 16 do
EffectUtils.Create(e_ender_flash, npc.randX, npc.randY, Utils.RandSym(1), Utils.RandSym(1),
Utils.RandSym(1), 2)
end
SoundUtils.PlaySoundGroup(Reg.SoundGroupID("portal"), npc.centerXi, npc.centerYi)
end
end
elseif npc.state == ST_FIRING then
npc.stateTimer = npc.stateTimer + 1
if npc.stateTimer > 16 then
npc.stateTimer = 0
npc.state = ST_NORMAL
end
end
end
function RaggedMage:OnDraw()
local npc = self.npc
npc.spriteEx.angle = npc.speedX / 8
if npc.state == ST_NORMAL then
npc.spriteRect.x = 0
elseif npc.state == ST_FIRING then
npc.spriteRect.x = npc.spriteDefaultWidth
end
end
return RaggedMage
================================================
FILE: npc_ai/RedMage.json
================================================
{
"RedMage": {
"script": {
"path": "RedMage.lua"
}
}
}
================================================
FILE: npc_ai/RedMage.lua
================================================
---@class TC.RedMage:ModNpc
local RedMage = class("RedMage", ModNpc)
local ST_NORMAL = 0
local ST_FIRING = 1
local SHOOT_TIMES = 3
function RedMage:Init()
self.shootTimes = 0
end
function RedMage:Update()
local npc = self.npc
npc.speedX = Utils.SlowSpeed1D(npc.speedX, 0.1)
local playerTarget = PlayerUtils.Get(npc.playerTargetIndex)
if playerTarget ~= nil then
npc.direction = (playerTarget.centerX > npc.centerX)
end
if npc.state == ST_NORMAL then
npc.stateTimer = npc.stateTimer + 1
if self.shootTimes < SHOOT_TIMES and npc.stateTimer > 64 then
npc.stateTimer = 0
npc.state = ST_FIRING
self.shootTimes = self.shootTimes + 1
if playerTarget ~= nil then
local angle = npc:GetAngleTo(playerTarget.centerX, playerTarget.centerY)
local proj = ProjectileUtils.CreateFromNpc(npc, Reg.ProjectileID("shulker_bullet"), npc.centerX, npc.centerY,
2 * math.cos(angle), 2 * math.sin(angle), npc.baseAttack)
proj.isCheckPlayer = true
SoundUtils.PlaySound(Reg.SoundID("fireball"), npc.centerXi, npc.centerYi)
end
end
if npc.speedY > 6 or (self.shootTimes >= SHOOT_TIMES and npc.stateTimer > 64) then
npc.state = 0
self.shootTimes = 0
npc.stateTimer = 0
local currentX = npc.x
local currentY = npc.y
local teleportSuccess = npc:RandomTeleport(32)
if teleportSuccess then
local e_ender_flash = Reg.EffectID("ender_flash")
for i = 1, 16 do
EffectUtils.Create(e_ender_flash, currentX + Utils.RandInt(npc.width),
currentY + Utils.RandInt(npc.height), Utils.RandSym(1), Utils.RandSym(1), Utils.RandSym(1), 2)
end
for i = 1, 16 do
EffectUtils.Create(e_ender_flash, npc.randX, npc.randY, Utils.RandSym(1), Utils.RandSym(1),
Utils.RandSym(1), 2)
end
SoundUtils.PlaySoundGroup(Reg.SoundGroupID("portal"), npc.centerXi, npc.centerYi)
end
end
elseif npc.state == ST_FIRING then
npc.stateTimer = npc.stateTimer + 1
if npc.stateTimer > 16 then
npc.stateTimer = 0
npc.state = ST_NORMAL
end
end
end
function RedMage:OnDraw()
local npc = self.npc
npc.spriteEx.angle = npc.speedX / 8
if npc.state == ST_NORMAL then
npc.spriteRect.x = 0
elseif npc.state == ST_FIRING then
npc.spriteRect.x = npc.spriteDefaultWidth
end
end
return RedMage
================================================
FILE: npc_ai/RedPhantom.json
================================================
{
"RedPhantom": {
"script": {
"path": "RedPhantom.lua"
}
}
}
================================================
FILE: npc_ai/RedPhantom.lua
================================================
---@class TC.RedPhantom:ModNpc
local RedPhantom = class("RedPhantom", ModNpc)
function RedPhantom:Update()
local npc = self.npc
npc:Fly()
if npc.speedY >= 0 then
local b1 = Utils.RandTry(8)
local b2 = Utils.RandTry(8)
if b1 or b2 then
local angle = npc.speedX / npc.maxSpeed / 2
local ex = 32 * math.cos(angle)
local ey = 32 * math.sin(angle)
if b1 then
EffectUtils.Create(Reg.EffectID("ender_flash"), npc.centerX + ex, npc.centerY + ey, Utils.RandSym(0.25),
Utils.RandSym(0.25), 0, Utils.RandDoubleArea(1, 1))
end
if b2 then
EffectUtils.Create(Reg.EffectID("ender_flash"), npc.centerX - ex, npc.centerY - ey, Utils.RandSym(0.25),
Utils.RandSym(0.25), 0, Utils.RandDoubleArea(1, 1))
end
end
else
if Utils.RandTry(4) then
EffectUtils.Create(Reg.EffectID("ender_flash"), npc.centerX + Utils.RandSym(8), npc.centerY + 8, Utils.RandSym(1),
Utils.RandSym(1), 0, Utils.RandDoubleArea(1, 1))
end
end
end
function RedPhantom:OnDraw()
local npc = self.npc
if npc.maxSpeed > 0 then
npc.spriteEx.angle = npc.speedX / npc.maxSpeed / 2
end
local noChangeFrame = false
if npc.speedY >= 0 then
if npc.frameTickTime <= 1 then
noChangeFrame = true
end
end
if npc.frameTickTime > npc.frames * npc.frameSpeed then
noChangeFrame = true
end
if noChangeFrame then
npc.frameTickTime = 0
end
end
return RedPhantom
================================================
FILE: npc_ai/RockMan.json
================================================
{
"RockMan": {
"script": {
"path": "RockMan.lua"
}
}
}
================================================
FILE: npc_ai/RockMan.lua
================================================
---@class TC.RockMan:TC.Archer
local RockMan = class("RockMan", require("Archer"))
function RockMan:Init()
RockMan.super.Init(self)
self.itemSlotHeld:PushStack(ItemStack.new(ItemRegistry.GetItemByIDName("soul_laserer")))
end
return RockMan
================================================
FILE: npc_ai/RollingFireBall.json
================================================
{
"RollingFireBall": {
"script": {
"path": "RollingFireBall.lua"
}
}
}
================================================
FILE: npc_ai/RollingFireBall.lua
================================================
---@class TC.RollingFireBall:ModNpc
local RollingFireBall = class("RollingFireBall", ModNpc)
function RollingFireBall:Update()
self.npc:Fly()
end
function RollingFireBall:OnDraw()
self.npc.spriteEx.angle = self.npc.spriteEx.angle + 0.1
end
function RollingFireBall:OnTileCollide(oldSpeedX, oldSpeedY)
local npc = self.npc
if npc.isCollisionLeft then
npc.speedX = npc.maxSpeed
elseif npc.isCollisionRight then
npc.speedX = -npc.maxSpeed
elseif npc.stand then
npc.speedY = -npc.maxSpeed
elseif npc.isCollisionTop then
npc.speedY = npc.maxSpeed
end
local playerTarget = PlayerUtils.Get(npc.playerTargetIndex)
if playerTarget ~= nil then
local distance = npc:GetDistance(playerTarget.centerX, playerTarget.centerY)
if distance < 360 then
npc:Kill()
MiscUtils.CreateExplosion(npc.centerXi, npc.centerYi, 4, true, true)
EffectUtils.CreateExplosion(npc.centerX, npc.centerY)
end
end
end
return RollingFireBall
================================================
FILE: npc_ai/Sheep.json
================================================
{
"Sheep": {
"pAI": "Sheep_AI",
"pDraw": "Sheep_Draw"
}
}
================================================
FILE: npc_ai/Shulker.json
================================================
{
"Shulker": {
"script": {
"path": "Shulker.lua"
}
}
}
================================================
FILE: npc_ai/Shulker.lua
================================================
---@type ModNpc
local Shulker = class("Shulker", ModNpc)
local ST_NORMAL = 0
local ST_OPENING = 1
local ST_OPENED = 2
local ST_CLOSING = 3
function Shulker:Teleport()
local npc = self.npc
local currentX = npc.x
local currentY = npc.y
local teleportSuccess = npc:RandomTeleport(16, true)
if teleportSuccess then
for i = 1, 16 do
EffectUtils.Create(Reg.EffectID("ender_flash"), currentX + Utils.RandInt(npc.width),
currentY + Utils.RandInt(npc.height),
Utils.RandSym(1), Utils.RandSym(1), Utils.RandSym(1), 2)
end
for i = 1, 16 do
EffectUtils.Create(Reg.EffectID("ender_flash"), npc.randX, npc.randY,
Utils.RandSym(1), Utils.RandSym(1), Utils.RandSym(1), 2)
end
SoundUtils.PlaySoundGroup(Reg.SoundGroupID("portal"), npc.centerXi, npc.centerYi)
end
end
function Shulker:Update()
local npc = self.npc
npc.speedX = Utils.SlowSpeed1D(npc.speedX, 0.05)
npc.speedY = Utils.SinValue(npc.tickTime, 128)
local playerTarget = PlayerUtils.Get(npc.playerTargetIndex)
if playerTarget ~= nil then
npc.direction = (playerTarget.centerX > npc.centerX)
end
if npc.state == ST_NORMAL then
if Utils.RandTry(128) then
npc.stateTimer = 0
npc.state = ST_OPENING
SoundUtils.PlaySound(Reg.SoundID("shulker_open"), npc.centerXi, npc.centerYi)
end
elseif npc.state == ST_OPENING then
npc.stateTimer = npc.stateTimer + 1
if npc.stateTimer >= 32 then
npc.stateTimer = 0
npc.state = ST_OPENED
end
elseif npc.state == ST_OPENED then
if playerTarget ~= nil then
local distance = npc:GetDistance(playerTarget.centerX, playerTarget.centerY)
if distance < 640 then
if npc.tickTime % 128 == 0 then
local angle = npc:GetAngleTo(playerTarget.centerX, playerTarget.centerY)
local proj = ProjectileUtils.CreateFromNpc(npc, Reg.ProjectileID("shulker_bullet"),
npc.centerX, npc.centerY, 4 * math.cos(angle), 4 * math.sin(angle), npc.baseAttack)
proj.isCheckPlayer = true
SoundUtils.PlaySound(Reg.SoundID("fireball"), npc.centerXi, npc.centerYi)
end
end
end
npc.stateTimer = npc.stateTimer + 1
if npc.stateTimer >= 256 then
npc.stateTimer = 0
npc.state = ST_CLOSING
SoundUtils.PlaySound(Reg.SoundID("shulker_close"), npc.centerXi, npc.centerYi)
end
elseif npc.state == ST_CLOSING then
npc.stateTimer = npc.stateTimer + 1
if npc.stateTimer >= 32 then
npc.stateTimer = 0
npc.state = ST_NORMAL
end
end
if npc.tickTime % 128 == 0 then
if Utils.RandTry(2) then
self:Teleport()
end
end
end
function Shulker:OnHit()
self:Teleport()
end
function Shulker:OnDraw()
local npc = self.npc
npc.spriteEx.angle = npc.speedY / 16 + npc.speedY / 8
if npc.state == ST_NORMAL then
npc.frameTickTime = 0
elseif npc.state == ST_OPENING then
elseif npc.state == ST_OPENED then
npc.frameTickTime = (npc.frames - 1) * npc.frameSpeed
elseif npc.state == ST_CLOSING then
npc.frameTickTime = npc.frameTickTime - 2
end
npc.frameTickTime = math.max(npc.frameTickTime, 0)
npc.frameTickTime = math.min(npc.frameTickTime, (npc.frames - 1) * npc.frameSpeed)
npc.spriteEx.x = npc.spriteDefaultWidth * npc.frameIndex
end
return Shulker
================================================
FILE: npc_ai/SkeletonAssaulter.json
================================================
{
"SkeletonAssaulter": {
"script": {
"path": "SkeletonAssaulter.lua"
}
}
}
================================================
FILE: npc_ai/SkeletonAssaulter.lua
================================================
---@class TC.SkeletonAssaulter:TC.HumanFighter
local SkeletonAssaulter = class("SkeletonAssaulter", require("HumanFighter"))
local State = {
NORMAL = 0,
NO_MOVE = 1
}
function SkeletonAssaulter:Init()
SkeletonAssaulter.super.Init(self)
self.inventory = Inventory.new(1)
self.npc.dataWatcher:AddInventory(self.inventory)
self.itemSlotHeld = self.inventory:GetSlot(0)
self.itemSlotHeld:PushStack(ItemStack.new(ItemRegistry.GetItemByIDName("sniper")))
self.shootTimes = 0
end
function SkeletonAssaulter:Update()
local npc = self.npc
npc.noMove = true
local playerTarget = PlayerUtils.Get(npc.playerTargetIndex)
npc.state = State.NORMAL
if playerTarget ~= nil then
npc.direction = (playerTarget.centerX > npc.centerX)
end
self.isHeadLook = true
self.headLookAngle = npc.watchAngle
self.headLookDenominator = 2.0
self.isBackHandLook = true
self.isFrontHandLook = true
self.backHandLookAngle = npc.watchAngle
self.frontHandLookAngle = npc.watchAngle
npc.state = State.NORMAL
if playerTarget ~= nil then
npc.direction = (playerTarget.centerX > npc.centerX)
local distance = npc:GetDistance(playerTarget.centerX, playerTarget.centerY)
if distance < 540 and self.shootTimes ~= 0 then
npc.state = State.NO_MOVE
end
if distance < 540 then
if npc.stand or npc.gravity == 0 then
if (npc.tickTime % 64 == 0) then
self.isUsingItemForAnimation = true
self.shootTimes = self.shootTimes + 1
end
end
end
end
if npc.state == State.NORMAL then
npc.noMove = false
elseif npc.state == State.NO_MOVE then
npc.noMove = true
end
if npc.gravity ~= 0 then
npc:Walk()
elseif npc.noMove then
npc.speedX, npc.speedY = Utils.SlowSpeed2D(npc.speedX, npc.speedY, 0.1)
else
npc:Fly()
end
end
return SkeletonAssaulter
================================================
FILE: npc_ai/SkeletonGuard.json
================================================
{
"SkeletonGuard": {
"script": {
"path": "SkeletonGuard.lua"
}
}
}
================================================
FILE: npc_ai/SkeletonGuard.lua
================================================
---@class TC.SkeletonGuard:TC.HumanFighter
local SkeletonGuard = class("SkeletonGuard", require("HumanFighter"))
function SkeletonGuard:Init()
SkeletonGuard.super.Init(self)
self.isFrontHandLook = true
self.isBackHandLook = true
self.isFrontHandLookAngleSameDirection = true
self.isBackHandLookAngleSameDirection = true
self.shootColdTime = 0
self.shootingAnimation = false
end
function SkeletonGuard:Update()
SkeletonGuard.super.Update(self)
local npc = self.npc
self.frontHandLookAngle = math.cos(self.npc.tickTime / 16) / 16
self.backHandLookAngle = math.sin(self.npc.tickTime / 16) / 16
self.npc:Fly(true)
local effect = EffectUtils.Create(Reg.EffectID("chip"),
self.npc.randX, self.npc.bottomY + Utils.RandSym(12),
Utils.RandSym(0.1), Utils.RandDoubleArea(1, 1),
Utils.RandSym(1), 1.0, 0.7,
Color.new(200, 200, 200))
effect:SetDisappearTime(20)
local playerTarget = PlayerUtils.Get(npc.playerTargetIndex)
if playerTarget ~= nil then
local distance = npc:GetDistance(playerTarget.centerX, playerTarget.centerY)
if distance < 360 then
npc:Fly(false) -- random fly
else
npc:Fly()
end
npc.direction = npc.centerX < playerTarget.centerX
if distance < 640 then
if npc.tickTime > 0 and npc.tickTime % 128 == 0 then
local angle = npc:GetAngleTo(playerTarget.centerX, playerTarget.centerY)
local proj = ProjectileUtils.CreateFromNpc(npc, Reg.ProjectileID("lighting_wheel"),
npc.centerX, npc.centerY, 3 * math.cos(angle), 3 * math.sin(angle), npc.baseAttack)
proj.isCheckPlayer = true
self.shootColdTime = 0
self.shootingAnimation = true
end
end
else
npc:Fly(false)
end
if self.shootingAnimation then
self.frontHandLookAngle = -math.sin(self.shootColdTime / 30 * math.pi)
self.backHandLookAngle = self.frontHandLookAngle
self.shootColdTime = self.shootColdTime + 1
if self.shootColdTime > 30 then
self.shootColdTime = 0
self.shootingAnimation = false
end
npc.speedX = npc.speedX / 2
npc.speedY = npc.speedY / 2
end
end
return SkeletonGuard
================================================
FILE: npc_ai/Slime.json
================================================
{
"Slime": {
"script": {
"path": "Slime.lua"
}
}
}
================================================
FILE: npc_ai/Slime.lua
================================================
---@class TC.Slime:ModNpc
local Slime = class("Slime", ModNpc)
local ST_NORMAL = 0
local ST_READY_TO_JUMP = 1
function Slime:Init()
local npc = self.npc
local playerTarget = PlayerUtils.Get(npc.playerTargetIndex)
if playerTarget ~= nil then
npc.direction = (playerTarget.centerX > npc.centerX)
end
self.jumpTryTimes = 0
self.JUMP_TRY_TIMES = npc.dataWatcher:AddInteger(0)
end
function Slime:Update()
self:RecvSync()
local npc = self.npc
local following = (npc.y > MapUtils.UNDERGROUND_LINE * 16)
if npc.inLiquid then
npc.gravity = 0
if npc.stand then
npc.speedY = -1
elseif npc.speedY > -1 then
npc.speedY = npc.speedY - npc.defaultGravity
end
end
if not npc.stand then
if npc.direction then
npc.speedX = npc.speedX + 0.0625
else
npc.speedX = npc.speedX - 0.0625
end
npc.speedX = math.max(npc.speedX, -npc.maxSpeed)
npc.speedX = math.min(npc.speedX, npc.maxSpeed)
end
if not npc.inLiquid and npc.stand then
if following then
local playerTarget = PlayerUtils.Get(npc.playerTargetIndex)
if playerTarget ~= nil then
npc.direction = (playerTarget.centerX > npc.centerX)
end
end
npc.speedX = Utils.SlowSpeed1D(npc.speedX, 0.25)
if npc.state == ST_NORMAL then
if Utils.RandTry(32) then
npc.state = ST_READY_TO_JUMP
end
elseif npc.state == ST_READY_TO_JUMP then
npc.stateTimer = npc.stateTimer + 1
if npc.stateTimer > 64 then
npc.stateTimer = 0
npc.state = ST_NORMAL
if npc.direction then
npc.speedX = npc.maxSpeed
else
npc.speedX = -(npc.maxSpeed)
end
npc.speedY = -Utils.RandDoubleArea(8, 2)
end
end
end
self:SendSync()
end
--- Called when NPC collides the tiles.
---@param oldSpeedX double Represents the X speed before colliding tiles.
---@param oldSpeedY double Represents the Y speed before colliding tiles.
function Slime:OnTileCollide(oldSpeedX, oldSpeedY)
local npc = self.npc
if npc.stand then
if not npc.isCollisionLeft and not npc.isCollisionRight then
self.jumpTryTimes = 0
end
if npc.isCollisionLeft and not npc.direction then
if self.jumpTryTimes >= 1 then
self.jumpTryTimes = 0
npc.direction = true
else
npc.speedY = -npc.jumpForce
self.jumpTryTimes = self.jumpTryTimes + 1
end
elseif npc.isCollisionRight and npc.direction then
if self.jumpTryTimes >= 1 then
self.jumpTryTimes = 0
npc.direction = false
else
npc.speedY = -npc.jumpForce
self.jumpTryTimes = self.jumpTryTimes + 1
end
end
elseif npc.inLiquid then
if npc.isCollisionLeft and not npc.direction then
npc.direction = true
elseif npc.isCollisionRight and npc.direction then
npc.direction = false
end
end
self:SendSync()
end
function Slime:SendSync()
if NetMode.current == NetMode.Server then
self.npc.dataWatcher:UpdateInteger(self.JUMP_TRY_TIMES, self.jumpTryTimes)
end
end
function Slime:RecvSync()
if NetMode.current == NetMode.Client then
self.jumpTryTimes = self.npc.dataWatcher:GetInteger(self.JUMP_TRY_TIMES)
end
end
function Slime:OnDraw()
local npc = self.npc
if not npc.stand then
npc.spriteRect.x = npc.spriteDefaultWidth
end
end
return Slime
================================================
FILE: npc_ai/Snake_Body.json
================================================
{
"Snake_Body": {
"script": {
"path": "BaseSnakeBody.lua"
}
}
}
================================================
FILE: npc_ai/Snake_Head.json
================================================
{
"Snake_Head": {
"script": {
"path": "BaseSnake.lua"
}
}
}
================================================
FILE: npc_ai/SnowGuardian.json
================================================
{
"SnowGuardian": {
"script": {
"path": "SnowGuardian.lua"
}
}
}
================================================
FILE: npc_ai/SnowGuardian.lua
================================================
---@class TC.SnowGuardian:TC.SwordHumanFighter
local SnowGuardian = class("SnowGuardian", require("SwordHumanFighter"))
function SnowGuardian:Init()
SnowGuardian.super.Init(self)
self:SetHeldItemByIDName("stone_sword")
end
function SnowGuardian:Update()
SnowGuardian.super.Update(self)
local npc = self.npc
npc:Fly()
if npc.tickTime % 4 == 0 then
EffectUtils.Create(Reg.EffectID("flash2"), npc.randX, npc.randY, Utils.RandSym(0.2), Utils.RandSym(0.2), 0,
Utils.RandDoubleArea(0.5, 0.5))
end
end
return SnowGuardian
================================================
FILE: npc_ai/SnowGuardianArcher.json
================================================
{
"SnowGuardianArcher": {
"script": {
"path": "SnowGuardianArcher.lua"
}
}
}
================================================
FILE: npc_ai/SnowGuardianArcher.lua
================================================
---@class TC.SnowGuardianArcher:TC.Archer
local SnowGuardianArcher = class("SnowGuardianArcher", require("Archer"))
function SnowGuardianArcher:Init()
SnowGuardianArcher.super.Init(self)
self.itemSlotHeld:PushStack(ItemStack.new(ItemRegistry.GetItemByIDName("ice_bow")))
end
function SnowGuardianArcher:Update()
SnowGuardianArcher.super.Update(self)
local npc = self.npc
if npc.tickTime % 4 == 0 then
EffectUtils.Create(Reg.EffectID("flash2"), npc.randX, npc.randY, Utils.RandSym(0.2), Utils.RandSym(0.2), 0,
Utils.RandDoubleArea(0.5, 0.5))
end
end
return SnowGuardianArcher
================================================
FILE: npc_ai/SnowQueen.json
================================================
{
"SnowQueen": {
"script": {
"path": "SnowQueen.lua"
}
}
}
================================================
FILE: npc_ai/SnowQueen.lua
================================================
---@class TC.SnowQueen:TC.HumanFighter
local SnowQueen = class("SnowQueen", require("HumanFighter"))
local ST_STAGE_START = 0
local ST_STAGE_MID = 1
local ST_STAGE_LAST = 2
function SnowQueen:Init()
SnowQueen.super.Init(self)
self.isFrontHandLook = true
self.isBackHandLook = true
self.isFrontLegOverwrite = true
self.isBackLegOverwrite = true
self.isFrontHandLookAngleSameDirection = false
self.isBackHandLookAngleSameDirection = false
self.isFrontLegLookAngleSameDirection = true
self.isBackLegLookAngleSameDirection = true
self.shootAngle = 0
self:NotifyAllPlayer("snow_queen")
end
function SnowQueen:Update()
local npc = self.npc
-- get the target player
local playerTarget = PlayerUtils.Get(npc.playerTargetIndex)
if playerTarget ~= nil then
npc.direction = (playerTarget.centerX > npc.centerX)
end
-- set the boss stage
npc.state = ST_STAGE_START
if npc.health < npc.maxHealth / 3 then
npc.state = ST_STAGE_LAST
elseif npc.health < npc.maxHealth / 3 * 2 then
npc.state = ST_STAGE_MID
end
-- if else state machine
if npc.state == ST_STAGE_START then
npc:Fly()
if npc.tickTime > 0 and npc.tickTime % 64 == 0 then
if playerTarget ~= nil then
local angle = npc:GetAngleTo(playerTarget.centerX, playerTarget.centerY)
local proj = ProjectileUtils.CreateFromNpc(npc, Reg.ProjectileID("snow_flake"), npc.centerX + math.cos(angle) * 32,
npc.centerY + math.sin(angle) * 32, 0.5 * math.cos(angle), 0.5 * math.sin(angle),
npc.baseAttack)
proj.isCheckPlayer = true
SoundUtils.PlaySound(Reg.SoundID("fireball"), npc.centerXi, npc.centerYi)
end
end
elseif npc.state == ST_STAGE_MID then
npc:Fly()
if npc.tickTime % 64 == 0 then
if playerTarget ~= nil then
local angle = npc:GetAngleTo(playerTarget.centerX, playerTarget.centerY)
local initSpeed = 4
for i = 1, 3 do
local proj = ProjectileUtils.CreateFromNpc(npc, Reg.ProjectileID("ice_bullet"), npc.centerX + math.cos(angle) * 32,
npc.centerY + math.sin(angle) * 32, initSpeed * math.cos(angle),
initSpeed * math.sin(angle), npc.baseAttack)
proj.isCheckPlayer = true
initSpeed = initSpeed + 1
end
SoundUtils.PlaySound(Reg.SoundID("fireball"), npc.centerXi, npc.centerYi)
end
end
elseif npc.state == ST_STAGE_LAST then
npc:Fly(false)
npc.speedY = npc.speedY - 0.01
self.shootAngle = self.shootAngle + 0.1
if npc.tickTime % 4 == 0 then
if playerTarget ~= nil then
local angle = self.shootAngle
local proj = ProjectileUtils.CreateFromNpc(npc, Reg.ProjectileID("ice_bullet"), npc.centerX + math.cos(angle) * 32,
npc.centerY + math.sin(angle) * 32, 4 * math.cos(angle), 4 * math.sin(angle),
npc.baseAttack)
proj.isCheckPlayer = true
if npc.tickTime % 16 == 0 then
SoundUtils.PlaySound(Reg.SoundID("fireball2"), npc.centerXi, npc.centerYi)
end
end
end
end
if npc.stand then
npc.speedY = -6
end
if npc.tickTime % 4 == 0 then
EffectUtils.Create(Reg.EffectID("liquid_paticular"), npc.randX, npc.bottomY, Utils.RandSym(0.2), 1)
end
self.frontLegOverwriteAngle = -Utils.SinValue(npc.frameTickTime, 128) * 0.3 - math.pi / 6 + 0.1
self.backLegOverwriteAngle = -Utils.CosValue(npc.frameTickTime, 128) * 0.3 - math.pi / 4 + 0.1
self.frontHandLookAngle = -Utils.SinValue(npc.frameTickTime, 256) * 0.8 - math.pi / 12 + 2.2
self.backHandLookAngle = -Utils.CosValue(npc.frameTickTime, 256) * 0.4 - math.pi / 8 + 1.8
end
function SnowQueen:OnKilled()
self:NotifyAllPlayer("snow_queen_killed")
if self.hookXi ~= nil and self.hookYi ~= nil then
for i = 1, 12 do
local effect = EffectUtils.SendFromServer(Reg.EffectID("chip"),
self.hookXi * 16 + 8,
self.hookYi * 16 + 8,
Utils.RandSym(5),
Utils.RandSym(5),
0,
Utils.RandDoubleArea(1, 1),
1.0,
Color.White
)
effect.disappearTime = 64
effect.gravity = false
end
MapUtils.RemoveFront(self.hookXi, self.hookYi)
end
end
function SnowQueen:NotifyAllPlayer(advancementIDName)
local advancementID = Reg.AdvancementID(advancementIDName)
local players = PlayerUtils.SearchByCircle(self.npc.centerX, self.npc.centerY, 300 * 16)
---@param player Player
for _, player in each(players) do
player:FinishAdvancement(advancementID)
end
end
return SnowQueen
================================================
FILE: npc_ai/Squid.json
================================================
{
"Squid": {
"script": {
"path": "Squid.lua"
}
}
}
================================================
FILE: npc_ai/Squid.lua
================================================
---@type ModNpc
local Squid = class("Squid", ModNpc)
function Squid:Update()
local npc = self.npc
if not npc.inLiquid then
-- bounce in air
if npc.stand then
npc.speedY = -npc.jumpForce
npc.speedX = Utils.RandSym(npc.maxSpeed)
end
if npc.isCollisionLeft then
npc.direction = true
npc.speedX = npc.maxSpeed * 0.5
elseif npc.isCollisionRight then
npc.direction = false
npc.speedX = -npc.maxSpeed * 0.5
end
else
-- in liquid
npc.gravity = 0
if npc.stateTimer == 0 then
local rate = Utils.RandDouble(1)
local PI = math.pi
local angle = 0
if npc.stand then
if npc.isCollisionLeft then
angle = -rate * PI / 2
elseif npc.isCollisionRight then
angle = -rate * PI / 2 - PI / 2
else
angle = rate * PI - PI
end
elseif npc.isCollisionTop then
if npc.isCollisionLeft then
angle = rate * PI / 2
elseif npc.isCollisionRight then
angle = rate * PI / 2 + PI / 2
else
angle = rate * PI
end
elseif npc.isCollisionLeft then
angle = rate * PI - PI / 2
elseif npc.isCollisionRight then
angle = rate * PI + PI / 2
else
angle = rate * 2 * PI - PI
end
npc.rotateAngle = angle
npc.speedX, npc.speedY = Utils.GetXYFromPolar(npc.maxSpeed, angle)
end
npc.speedX, npc.speedY = Utils.SlowSpeed2D(npc.speedX, npc.speedY, 0.03125)
npc.stateTimer = npc.stateTimer + 1
if npc.stateTimer > 64 then
npc.stateTimer = 0
end
end
if npc.stateTimer == 0 then
npc.frameTickTime = 0
end
end
function Squid:OnDraw()
self.npc.spriteEx.angle = self.npc.rotateAngle + math.pi / 2
end
return Squid
================================================
FILE: npc_ai/SwordHumanFighter.lua
================================================
---@class TC.SwordHumanFighter:TC.HumanFighter
local SwordHumanFighter = class("SwordHumanFighter", require("HumanFighter"))
local SwingState = {
Waiting = 0,
Swinging = 1,
}
function SwordHumanFighter:Init()
self.boneSizeIndex = 0
self.style = 0
if self.npc.data and self.npc.data.tc then
local dataTable = self.npc.data.tc
if dataTable.boneSizeIndex ~= nil then
self.boneSizeIndex = dataTable.boneSizeIndex
end
if dataTable.style ~= nil then
self.style = dataTable.style
end
end
SwordHumanFighter.super.Init(self)
self.inventory = Inventory.new(1)
self.npc.dataWatcher:AddInventory(self.inventory)
self.itemSlotHeld = self.inventory:GetSlot(0)
self.isFrontHandLook = true
self.isBackHandLook = true
self.isFrontHandLookAngleSameDirection = true
self.isBackHandLookAngleSameDirection = true
self.totalSwingTime = 30
self.totalSwingIntervalTime = 120
self.swingDistance = 120
self.alwaysTrySwing = true
self.swingState = 0
self.swingTime = 0
self.SWING_STATE = self.npc.dataWatcher:AddInteger(0)
end
function SwordHumanFighter:Update()
SwordHumanFighter.super.Update(self)
self:UpdateSwordSwingLogic()
end
function SwordHumanFighter:UpdateSwordSwingLogic()
if self.alwaysTrySwing and self:HasHeldSword() then
local npc = self.npc
local isServer = NetMode.current == NetMode.Server
if not isServer then
local newSwingState = npc.dataWatcher:GetInteger(self.SWING_STATE)
if self.swingState ~= newSwingState then
self.swingState = newSwingState
self.swingTime = 0
end
end
if self.swingState == SwingState.Waiting then
self:OnWaitSwing()
local inDistance = false
local playerTarget = PlayerUtils.Get(npc.playerTargetIndex)
if playerTarget ~= nil then
local d = Utils.GetDistance(playerTarget.centerX - npc.centerX, playerTarget.centerY - npc.centerY)
if d < self.swingDistance then
inDistance = true
end
end
if inDistance then
self.swingTime = self.swingTime + 1
if isServer and self.swingTime >= self.totalSwingIntervalTime then
self.swingState = SwingState.Swinging
self.swingTime = 0
end
end
elseif self.swingState == SwingState.Swinging then
self.isUsingItemForAnimation = true
self:OnSwing()
self.swingTime = self.swingTime + 1
if self.swingTime >= self.totalSwingTime then
self.swingState = SwingState.Waiting
self.swingTime = 0
end
end
if isServer then
npc.dataWatcher:UpdateInteger(self.SWING_STATE, self.swingState)
end
end
end
function SwordHumanFighter:HasHeldSword()
if self.itemSlotHeld.hasStack then
local stack = self.itemSlotHeld:GetStack()
if stack:GetItem().toolType == "SWORD" then
return true
end
end
return false
end
function SwordHumanFighter:SetHeldItemByIDName(itemIDName)
self.itemSlotHeld:PushStack(ItemStack.new(ItemRegistry.GetItemByIDName(itemIDName)))
end
function SwordHumanFighter:OnWaitSwing()
self:DoExternArmsAnimation()
end
function SwordHumanFighter:OnSwing()
local rate = 0
if self.totalSwingTime > 0 then
rate = self.swingTime * 1.0 / self.totalSwingTime
end
self.frontHandLookAngle = -math.pi / 3 + (rate) * 3
self.backHandLookAngle = -math.pi / 3 + (rate) * 3
end
return SwordHumanFighter
================================================
FILE: npc_ai/TaintedSlime.json
================================================
{
"TaintedSlime": {
"script": {
"path": "TaintedSlime.lua"
}
}
}
================================================
FILE: npc_ai/TaintedSlime.lua
================================================
---@type ModNpc
local TaintedSlime = class("TaintedSlime", require("Slime"))
function TaintedSlime:Update()
TaintedSlime.super.Update(self)
local npc = self.npc
if npc.tickTime % 16 == 0 then
EffectUtils.Create(Reg.EffectID("ender_flash"), npc.randX, npc.randY, Utils.RandSym(1), Utils.RandSym(1))
end
end
return TaintedSlime
================================================
FILE: npc_ai/UndeadMiner.json
================================================
{
"UndeadMiner": {
"script": {
"path": "UndeadMiner.lua"
}
}
}
================================================
FILE: npc_ai/UndeadMiner.lua
================================================
---@class TC.UndeadMiner:TC.SwordHumanFighter
local UndeadMiner = class("UndeadMiner", require("SwordHumanFighter"))
function UndeadMiner:Init()
UndeadMiner.super.Init(self)
self:SetHeldItemByIDName("iron_pickaxe")
end
function UndeadMiner:Update()
UndeadMiner.super.Update(self)
LightingUtils.Add(self.npc.centerXi, self.npc.centerYi, 24)
self:DoExternArmsAnimation()
end
return UndeadMiner
================================================
FILE: npc_ai/Villager.json
================================================
{
"Villager": {
"pAI": "Villager_AI"
}
}
================================================
FILE: npc_ai/WasteGhost.json
================================================
{
"WasteGhost": {
"script": {
"path": "WasteGhost.lua"
}
}
}
================================================
FILE: npc_ai/WasteGhost.lua
================================================
---@type ModNpc
local WasteGhost = class("WasteGhost", ModNpc)
function WasteGhost:Update()
local npc = self.npc
npc.gravity = npc.gravity * 0.2
npc:Walk()
if npc.tickTime % 16 == 0 then
local cy = npc.y
if npc.speedY < 0 then
cy = npc.bottomY
end
EffectUtils.Create(
Reg.EffectID("liquid_paticular"),
npc.randX,
cy,
Utils.RandSym(0.5),
0,
0,
Utils.RandDoubleArea(0.5, 0.5),
0,
Color.new(255, 200, 100)
)
end
end
function WasteGhost:OnTileCollide(_, _)
local npc = self.npc
if npc.stand then
npc.speedY = -npc.jumpForce
end
end
function WasteGhost:OnDraw()
local npc = self.npc
if npc.maxSpeed > 0 then
npc.spriteEx.angle = npc.speedX / npc.maxSpeed / 2
end
end
return WasteGhost
================================================
FILE: npc_ai/WitherSkeleton.json
================================================
{
"WitherSkeleton": {
"script": {
"path": "WitherSkeleton.lua"
}
}
}
================================================
FILE: npc_ai/WitherSkeleton.lua
================================================
---@class TC.WitherSkeleton:TC.SwordHumanFighter
local WitherSkeleton = class("WitherSkeleton", require("SwordHumanFighter"))
function WitherSkeleton:Init()
self.boneSizeIndex = 1
WitherSkeleton.super.Init(self)
self:SetHeldItemByIDName("iron_sword")
end
return WitherSkeleton
================================================
FILE: npc_ai/Wolf.json
================================================
{
"Wolf": {
"script": {
"path": "Wolf.lua"
}
}
}
================================================
FILE: npc_ai/Wolf.lua
================================================
---@type ModNpc
local Wolf = class("Wolf", ModNpc)
function Wolf:Update()
local npc = self.npc
if npc.angry then
if Utils.RandTry(512) then
npc.angry = false
end
end
npc:TryMakeSound()
if npc.angry then
npc.maxSpeed = npc.maxSpeed * 1.5
npc:Walk()
else
npc:RandomWalk()
end
end
function Wolf:PostUpdate()
local npc = self.npc
if npc.speedX == 0 then
npc.frameTickTime = 0
end
end
function Wolf:OnDraw()
local npc = self.npc
if npc.angry then
npc.spriteRect.y = npc.spriteDefaultHeight
end
if npc.frameTickTime > 0 then
npc.spriteRect.x = npc.spriteRect.x + npc.spriteDefaultWidth
end
end
return Wolf
================================================
FILE: npc_ai/Zombie.json
================================================
{
"Zombie": {
"script": {
"path": "Zombie.lua"
}
}
}
================================================
FILE: npc_ai/Zombie.lua
================================================
---@class TC.Zombie:TC.SwordHumanFighter
local Zombie = class("Zombie", require("SwordHumanFighter"))
function Zombie:Init()
Zombie.super.Init(self)
if Utils.RandTry(20) then
self:SetHeldItemByIDName("stone_sword")
end
end
function Zombie:Update()
Zombie.super.Update(self)
if not self:HasHeldSword() then
self:DoExternArmsAnimation()
end
end
return Zombie
================================================
FILE: npc_ai/Zpig.json
================================================
{
"Zpig": {
"script": {
"path": "Zpig.lua"
}
}
}
================================================
FILE: npc_ai/Zpig.lua
================================================
---@class TC.ZPig:TC.SwordHumanFighter
local ZPig = class("ZPig", require("SwordHumanFighter"))
function ZPig:Init()
ZPig.super.Init(self)
self:SetHeldItemByIDName("golden_sword")
self.alwaysTrySwing = false
end
function ZPig:Update()
ZPig.super.Update(self)
local npc = self.npc
npc:TryMakeSound()
self.alwaysTrySwing = false
if npc.angry then
npc.maxSpeed = npc.maxSpeed * 1.5
npc:Walk()
self.alwaysTrySwing = true
else
npc:RandomWalk()
end
end
return ZPig
================================================
FILE: npc_ai_global/GNpc.lua
================================================
---@type GlobalNpc
local GNpc = class("GNpc", GlobalNpc)
function GNpc.CheckCreateInstance(npc)
return true
end
function GNpc:CanUpdate()
return true
end
function GNpc:Update()
if self.npc.stand then
--self.npc.speedY = -5
end
end
return GNpc
================================================
FILE: npc_ai_global/GlobalNpc.json
================================================
{
"GlobalClass": [
"GNpc"
]
}
================================================
FILE: npcs/angry_skeleton.json
================================================
{
"angry_skeleton": {
"ai": "AngrySkeleton",
"textureData": "angry_skeleton.png",
"type": "SMITE",
"width": 24,
"height": 46,
"gfxWidth": 48,
"gfxHeight": 48,
"gfxOffsetX": 4,
"gfxOffsetY": 8,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 1.25,
"jumpForce": 8.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 50,
"defense": 6,
"attack": 12,
"knockBack": 5,
"knockBackDefense": 0.50,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 7,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"skeleton_death",
"skeleton1",
"skeleton2",
"skeleton3"
],
"loots": [
{
"item": "bone",
"min": 0,
"max": 5
}
],
"special": 0,
"paticularColor": [ 255, 150, 150, 150 ],
"spawn": "LAND",
"gore": "gore_angry_skeleton",
"magicRate": 25,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/arrow_zombie.json
================================================
{
"arrow_zombie": {
"ai": "Zombie",
"textureData": "arrow_zombie.png",
"type": "SMITE",
"width": 24,
"height": 46,
"gfxWidth": 48,
"gfxHeight": 48,
"gfxOffsetX": 4,
"gfxOffsetY": 8,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 1.0,
"jumpForce": 9.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 45,
"defense": 6,
"attack": 14,
"knockBack": 5,
"knockBackDefense": 0.50,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 5,
"sunBurning": true,
"angry": false,
"antiLava": false,
"saySounds": [
"zombie_say1",
"zombie_say2",
"zombie_say3"
],
"hurtSounds": [
"zombie_death",
"zombie_hurt1",
"zombie_hurt2"
],
"noBurnSound": true,
"loots": [
{
"item": "rotten_flesh",
"count": [ 1, 4 ]
},
{
"item": "wooden_arrow",
"count": [ 1, 2 ]
}
],
"special": 0,
"paticularColor": [ 255, 200, 50, 20 ],
"spawn": "LAND",
"gore": "gore_arrow_zombie",
"magicRate": 30,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/bald_zombie.json
================================================
{
"bald_zombie": {
"ai": "Zombie",
"textureData": "bald_zombie.png",
"type": "SMITE",
"width": 24,
"height": 46,
"gfxWidth": 48,
"gfxHeight": 48,
"gfxOffsetX": 4,
"gfxOffsetY": 8,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 1.0,
"jumpForce": 9.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 45,
"defense": 6,
"attack": 14,
"knockBack": 5,
"knockBackDefense": 0.50,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 5,
"sunBurning": true,
"angry": false,
"antiLava": false,
"saySounds": [
"zombie_say1",
"zombie_say2",
"zombie_say3"
],
"hurtSounds": [
"zombie_death",
"zombie_hurt1",
"zombie_hurt2"
],
"noBurnSound": true,
"loots": [
{
"item": "rotten_flesh",
"count": [ 1, 4 ]
},
{
"item": "dark_shadow_part",
"count": [ 1, 3 ]
}
],
"special": 0,
"paticularColor": [ 255, 200, 50, 20 ],
"spawn": "LAND",
"gore": "gore_bald_zombie",
"magicRate": 30,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/bat.json
================================================
{
"bat": {
"ai": "Bat",
"textureData": "bat.png",
"type": "NORMAL",
"width": 32,
"height": 32,
"gfxWidth": 72,
"gfxHeight": 46,
"gfxOffsetX": -20,
"gfxOffsetY": -7,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 4,
"shape": "BOX",
"maxSpeed": 3.0,
"jumpForce": 5.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 40,
"defense": 6,
"attack": 7,
"knockBack": 4,
"knockBackDefense": 0.10,
"gravity": false,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 5,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"bat_death",
"bat_hurt1",
"bat_hurt2",
"bat_hurt3"
],
"loots": [
{
"item": "gray_feather",
"count": [ 3, 8 ]
}
],
"special": 0,
"paticularColor": [ 255, 50, 50, 20 ],
"spawn": "AIR",
"gore": "gore_bat",
"magicRate": 30,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/black_rabbit.json
================================================
{
"black_rabbit": {
"ai": "Animal",
"textureData": "black_rabbit.png",
"type": "ANIMAL",
"width": 24,
"height": 24,
"gfxWidth": 32,
"gfxHeight": 32,
"gfxOffsetX": -4,
"gfxOffsetY": -8,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 6,
"shape": "BOX",
"maxSpeed": 1.0,
"jumpForce": 6.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 10,
"defense": 0,
"attack": 1,
"knockBack": 0,
"knockBackDefense": 0.10,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": true,
"exps": 2,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"rabbit_hurt1",
"rabbit_hurt1",
"rabbit_hurt2",
"rabbit_hurt3"
],
"loots": [
{
"item": "rabbit_foot",
"possibility": 0.5
},
{
"item": "rabbit_hide",
"count": [1, 2],
"possibility": 1.0
},
{
"item": "raw_rabbit",
"possibility": 0.5
}
],
"burnLoots": [
{
"item": "rabbit_foot",
"count": [1],
"possibility": 0.5
},
{
"item": "rabbit_hide",
"count": [1, 2],
"possibility": 1.0
},
{
"item": "cooked_rabbit",
"count": [1],
"possibility": 0.5
}
],
"special": 0,
"paticularColor": [ 255, 200, 100, 50 ],
"spawn": "LAND",
"gore": "gore_black_rabbit",
"magicRate": 0,
"checkPlayerTarget": false,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/black_skeleton.json
================================================
{
"black_skeleton": {
"ai": "BlackSkeleton",
"textureData": "black_skeleton.png",
"type": "SMITE",
"width": 24,
"height": 46,
"gfxWidth": 48,
"gfxHeight": 48,
"gfxOffsetX": 4,
"gfxOffsetY": 8,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 1.5,
"jumpForce": 8.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 60,
"defense": 6,
"attack": 12,
"knockBack": 5,
"knockBackDefense": 0.50,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 7,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"skeleton_death",
"skeleton1",
"skeleton2",
"skeleton3"
],
"loots": [
{
"item": "bone",
"min": 0,
"max": 2
},
{
"item": "steel_ingot",
"min": 0,
"max": 1
},
{
"item": "dark_shadow_part",
"count": [ 1, 3 ]
}
],
"special": 0,
"paticularColor": [ 255, 100, 100, 100 ],
"spawn": "LAND",
"gore": "gore_black_skeleton",
"magicRate": 25,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/blaze.json
================================================
{
"blaze": {
"ai": "Blaze",
"textureData": "blaze.png",
"type": "SMITE",
"width": 32,
"height": 32,
"gfxWidth": 40,
"gfxHeight": 40,
"gfxOffsetX": -4,
"gfxOffsetY": -4,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 1.25,
"jumpForce": 9.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 80,
"defense": 6,
"attack": 18,
"knockBack": 5,
"knockBackDefense": 0.40,
"gravity": false,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 10,
"sunBurning": false,
"angry": false,
"antiLava": true,
"saySounds": [],
"hurtSounds": [
"blaze_death",
"blaze_hit1",
"blaze_hit2",
"blaze_hit3"
],
"loots": [
{
"item": "blaze_rod",
"count": [ 3, 6 ]
}
],
"special": 0,
"paticularColor": [ 255, 200, 100, 50 ],
"spawn": "AIR",
"magicRate": 30,
"checkPlayerTarget": true,
"visionNoCrossTile": false,
"checkTargetDistance": 640
}
}
================================================
FILE: npcs/block_slime.json
================================================
{
"block_slime": {
"ai": "BlockSlime",
"textureData": "block_slime.png",
"type": "NORMAL",
"width": 24,
"height": 24,
"gfxWidth": 32,
"gfxHeight": 32,
"gfxOffsetX": -4,
"gfxOffsetY": -8,
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 2.0,
"jumpForce": 8.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 20,
"defense": 0,
"attack": 5,
"knockBack": 2,
"knockBackDefense": 0.03,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 4,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"slime_attack1",
"slime_attack1",
"slime_attack2"
],
"loots": [
{
"item": "slimeball",
"min": 1,
"max": 2
}
],
"special": 0,
"paticularColor": [ 255, 120, 200, 100 ],
"spawn": "LAND",
"magicRate": 50,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/blood_bat.json
================================================
{
"blood_bat": {
"ai": "Bat",
"textureData": "blood_bat.png",
"type": "NORMAL",
"width": 32,
"height": 32,
"gfxWidth": 72,
"gfxHeight": 46,
"gfxOffsetX": -20,
"gfxOffsetY": -7,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 4,
"shape": "BOX",
"maxSpeed": 3.0,
"jumpForce": 5.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 40,
"defense": 6,
"attack": 7,
"knockBack": 4,
"knockBackDefense": 0.10,
"gravity": false,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 5,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"bat_death",
"bat_hurt1",
"bat_hurt2",
"bat_hurt3"
],
"loots": [
{
"item": "gray_feather",
"count": [ 1, 13 ]
}
],
"special": 0,
"paticularColor": [ 255, 200, 0, 0 ],
"spawn": "AIR",
"gore": "gore_blood_bat",
"magicRate": 30,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/blood_eye.json
================================================
{
"blood_eye": {
"ai": "BloodyEye",
"textureData": "blood_eye.png",
"type": "NORMAL",
"width": 40,
"height": 40,
"gfxWidth": 40,
"gfxHeight": 40,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"frameStyle": 0,
"frames": 1,
"frameSpeed": 4,
"shape": "BOX",
"maxSpeed": 1.25,
"jumpForce": 5.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 40,
"defense": 6,
"attack": 15,
"knockBack": 4,
"knockBackDefense": 0.10,
"gravity": false,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 5,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"gore3",
"gore1",
"gore2"
],
"loots": [
{
"item": "gold_nugget",
"count": [ 1, 5 ]
}
],
"special": 0,
"paticularColor": [ 255, 200, 100, 50 ],
"spawn": "AIR",
"gore": "gore_blood_eye",
"magicRate": 30,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/blood_skeleton.json
================================================
{
"blood_skeleton": {
"ai": "BloodSkeleton",
"textureData": "blood_skeleton.png",
"type": "SMITE",
"width": 24,
"height": 46,
"gfxWidth": 48,
"gfxHeight": 48,
"gfxOffsetX": 4,
"gfxOffsetY": 8,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 1.5,
"jumpForce": 8.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 50,
"defense": 6,
"attack": 12,
"knockBack": 5,
"knockBackDefense": 0.50,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 5,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"skeleton_death",
"skeleton1",
"skeleton2",
"skeleton3"
],
"loots": [
{
"item": "bone",
"min": 0,
"max": 2
},
{
"item": "blood_arrow",
"min": 0,
"max": 2
}
],
"special": 0,
"paticularColor": [ 255, 150, 150, 150 ],
"spawn": "LAND",
"gore": "gore_blood_skeleton",
"magicRate": 25,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/blood_slime.json
================================================
{
"blood_slime": {
"ai": "Slime",
"textureData": "blood_slime.png",
"type": "NORMAL",
"width": 32,
"height": 32,
"gfxWidth": 40,
"gfxHeight": 40,
"gfxOffsetX": -4,
"gfxOffsetY": -4,
"frameStyle": 1,
"frames": 2,
"frameSpeed": 16,
"shape": "BOX",
"maxSpeed": 3.0,
"jumpForce": 8.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 40,
"defense": 0,
"attack": 6,
"knockBack": 2,
"knockBackDefense": 0.05,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 4,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"slime_attack1",
"slime_attack1",
"slime_attack2"
],
"loots": [
{
"item": "slimeball",
"count": [ 2, 5 ]
}
],
"special": 0,
"paticularColor": [ 255, 200, 90, 80 ],
"spawn": "LAND",
"magicRate": 80,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/blue_slime.json
================================================
{
"blue_slime": {
"ai": "Slime",
"textureData": "blue_slime.png",
"type": "NORMAL",
"width": 24,
"height": 24,
"gfxWidth": 32,
"gfxHeight": 32,
"gfxOffsetX": -4,
"gfxOffsetY": -8,
"frameStyle": 1,
"frames": 2,
"frameSpeed": 16,
"shape": "BOX",
"maxSpeed": 3.5,
"jumpForce": 8.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 40,
"defense": 0,
"attack": 6,
"knockBack": 2,
"knockBackDefense": 0.05,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 5,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"slime_attack1",
"slime_attack1",
"slime_attack2"
],
"loots": [
{
"item": "slimeball",
"count": [ 1, 4 ]
}
],
"special": 0,
"paticularColor": [ 255, 0, 0, 60 ],
"spawn": "LAND",
"magicRate": 80,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/bone_lee.json
================================================
{
"bone_lee": {
"ai": "BoneLee",
"textureData": "bone_lee.png",
"type": "SMITE",
"width": 24,
"height": 46,
"gfxWidth": 48,
"gfxHeight": 48,
"gfxOffsetX": 4,
"gfxOffsetY": 8,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 4.5,
"jumpForce": 12.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 120,
"defense": 7,
"attack": 26,
"knockBack": 5,
"knockBackDefense": 0.50,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 17,
"sunBurning": false,
"angry": false,
"antiLava": true,
"saySounds": [],
"hurtSounds": [
"skeleton_death",
"skeleton1",
"skeleton2",
"skeleton3"
],
"loots": [
{
"item": "bone",
"min": 0,
"max": 5
}
],
"special": 0,
"paticularColor": [ 255, 150, 150, 150 ],
"spawn": "LAND",
"gore": "gore_bone_lee",
"magicRate": 25,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/bone_officer.json
================================================
{
"bone_officer": {
"ai": "BoneOfficer",
"textureData": "bone_officer.png",
"type": "SMITE",
"width": 24,
"height": 46,
"gfxWidth": 48,
"gfxHeight": 48,
"gfxOffsetX": 4,
"gfxOffsetY": 8,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 1.5,
"jumpForce": 12.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 80,
"defense": 7,
"attack": 25,
"knockBack": 5,
"knockBackDefense": 0.60,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 15,
"sunBurning": true,
"angry": false,
"antiLava": true,
"saySounds": [],
"hurtSounds": [
"skeleton_death",
"skeleton1",
"skeleton2",
"skeleton3"
],
"loots": [
{
"item": "bone",
"min": 0,
"max": 2
},
{
"item": "magic_cell",
"count": [ 3, 5 ]
}
],
"special": 0,
"paticularColor": [ 255, 150, 150, 150 ],
"spawn": "LAND",
"gore": "gore_bone_officer",
"magicRate": 25,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/bone_sniper.json
================================================
{
"bone_sniper": {
"ai": "BoneSniper",
"textureData": "bone_sniper.png",
"type": "SMITE",
"width": 24,
"height": 46,
"gfxWidth": 48,
"gfxHeight": 48,
"gfxOffsetX": 4,
"gfxOffsetY": 8,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 1.5,
"jumpForce": 12.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 70,
"defense": 6,
"attack": 22,
"knockBack": 5,
"knockBackDefense": 0.50,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 15,
"sunBurning": true,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"skeleton_death",
"skeleton1",
"skeleton2",
"skeleton3"
],
"loots": [
{
"item": "bone",
"min": 0,
"max": 2
},
{
"item": "magic_cell",
"count": [ 3, 5 ]
}
],
"special": 0,
"paticularColor": [ 255, 150, 150, 150 ],
"spawn": "LAND",
"gore": "gore_bone_sniper",
"magicRate": 25,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/boney_skeleton.json
================================================
{
"boney_skeleton": {
"ai": "BoneySkeleton",
"textureData": "boney_skeleton.png",
"type": "SMITE",
"width": 24,
"height": 46,
"gfxWidth": 48,
"gfxHeight": 48,
"gfxOffsetX": 4,
"gfxOffsetY": 8,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 1.75,
"jumpForce": 8.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 60,
"defense": 6,
"attack": 12,
"knockBack": 5,
"knockBackDefense": 0.50,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 7,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"skeleton_death",
"skeleton1",
"skeleton2",
"skeleton3"
],
"loots": [
{
"item": "bone",
"min": 3,
"max": 9
}
],
"special": 0,
"paticularColor": [ 255, 150, 150, 150 ],
"spawn": "LAND",
"gore": "gore_boney_skeleton",
"magicRate": 25,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/bouncy_slime.json
================================================
{
"bouncy_slime": {
"ai": "BouncySlime",
"textureData": "bouncy_slime.png",
"type": "NORMAL",
"width": 32,
"height": 32,
"gfxWidth": 40,
"gfxHeight": 40,
"gfxOffsetX": -4,
"gfxOffsetY": -4,
"frameStyle": 1,
"frames": 2,
"frameSpeed": 16,
"shape": "BOX",
"maxSpeed": 5.0,
"jumpForce": 8.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 50,
"defense": 0,
"attack": 6,
"knockBack": 2,
"knockBackDefense": 0.05,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 4,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"slime_attack1",
"slime_attack1",
"slime_attack2"
],
"loots": [
{
"item": "slimeball",
"min": 2,
"max": 5
}
],
"special": 0,
"paticularColor": [ 255, 77, 77, 77 ],
"spawn": "LAND",
"magicRate": 80,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/brown_mushroom_cow.json
================================================
{
"brown_mushroom_cow": {
"ai": "Animal",
"textureData": "brown_mushroom_cow.png",
"type": "ANIMAL",
"width": 60,
"height": 60,
"gfxWidth": 64,
"gfxHeight": 72,
"gfxOffsetX": -2,
"gfxOffsetY": -12,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 6,
"shape": "BOX",
"maxSpeed": 1.5,
"jumpForce": 5.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 15,
"defense": 0,
"attack": 1,
"knockBack": 0,
"knockBackDefense": 0.10,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": true,
"exps": 3,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [
"cow_say1",
"cow_say2",
"cow_say3"
],
"hurtSounds": [
"cow_hurt1",
"cow_hurt1",
"cow_hurt2",
"cow_hurt3"
],
"loots": [
{
"item": "raw_beef",
"count": [1, 3],
"possibility": 1.0
},
{
"item": "leather",
"count": [1, 2],
"possibility": 0.5
},
{
"item": "brown_mushroom",
"count": [1, 4],
"possibility": 1.0
}
],
"burnLoots": [
{
"item": "steak",
"count": [1, 3],
"possibility": 1.0
},
{
"item": "leather",
"count": [1, 2],
"possibility": 0.5
},
{
"item": "brown_mushroom",
"count": [1, 4],
"possibility": 1.0
}
],
"special": 0,
"paticularColor": [ 255, 200, 100, 50 ],
"spawn": "LAND",
"gore": "gore_brown_mushroom_cow",
"magicRate": 0,
"checkPlayerTarget": false,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/brown_rabbit.json
================================================
{
"brown_rabbit": {
"ai": "Animal",
"textureData": "brown_rabbit.png",
"type": "ANIMAL",
"width": 24,
"height": 24,
"gfxWidth": 32,
"gfxHeight": 32,
"gfxOffsetX": -4,
"gfxOffsetY": -8,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 6,
"shape": "BOX",
"maxSpeed": 1.0,
"jumpForce": 6.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 10,
"defense": 0,
"attack": 1,
"knockBack": 0,
"knockBackDefense": 0.10,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": true,
"exps": 2,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"rabbit_hurt1",
"rabbit_hurt1",
"rabbit_hurt2",
"rabbit_hurt3"
],
"loots": [
{
"item": "rabbit_foot",
"possibility": 0.5
},
{
"item": "rabbit_hide",
"count": [ 1, 2 ]
},
{
"item": "raw_rabbit",
"possibility": 0.5
}
],
"burnLoots": [
{
"item": "rabbit_foot",
"possibility": 0.5
},
{
"item": "rabbit_hide",
"count": [ 1, 2 ]
},
{
"item": "cooked_rabbit",
"possibility": 0.5
}
],
"special": 0,
"paticularColor": [ 255, 200, 100, 50 ],
"spawn": "LAND",
"gore": "gore_brown_rabbit",
"magicRate": 0,
"checkPlayerTarget": false,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/cat.json
================================================
{
"cat": {
"ai": "Cat",
"textureData": "cat.png",
"type": "ANIMAL",
"width": 32,
"height": 32,
"gfxWidth": 48,
"gfxHeight": 48,
"gfxOffsetX": -8,
"gfxOffsetY": -16,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 6,
"shape": "BOX",
"maxSpeed": 4.0,
"jumpForce": 6.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 20,
"defense": 0,
"attack": 1,
"knockBack": 0,
"knockBackDefense": 0.10,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": true,
"exps": 3,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [
"cat_meow1",
"cat_meow2",
"cat_meow3"
],
"hurtSounds": [
"cat_hit1",
"cat_hit1",
"cat_hit2",
"cat_hit3"
],
"loots": [
{
"item": "leather",
"count": [ 1, 3 ],
"possibility": 0.5
}
],
"special": 0,
"paticularColor": [ 255, 200, 100, 50 ],
"spawn": "LAND",
"magicRate": 0,
"checkPlayerTarget": false,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/chicken.json
================================================
{
"chicken": {
"ai": "Chicken",
"textureData": "chicken.png",
"type": "ANIMAL",
"width": 24,
"height": 24,
"gfxWidth": 28,
"gfxHeight": 28,
"gfxOffsetX": -2,
"gfxOffsetY": -4,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 1.0,
"jumpForce": 5.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 10,
"defense": 0,
"attack": 1,
"knockBack": 0,
"knockBackDefense": 0.10,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": true,
"exps": 3,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [
"chicken_say1",
"chicken_say2",
"chicken_say3"
],
"hurtSounds": [
"chicken_hurt1",
"chicken_hurt1",
"chicken_hurt2"
],
"loots": [
{
"item": "raw_chicken",
"count": [ 1, 3 ]
},
{
"item": "feather",
"count": [ 1, 4 ],
"possibility": 0.5
}
],
"burnLoots": [
{
"item": "cooked_chicken",
"count": [ 1, 3 ]
},
{
"item": "feather",
"count": [ 1, 4 ],
"possibility": 0.5
}
],
"special": 0,
"paticularColor": [ 255, 200, 100, 50 ],
"spawn": "LAND",
"gore": "gore_chicken",
"magicRate": 0,
"checkPlayerTarget": false,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/cow.json
================================================
{
"cow": {
"ai": "Animal",
"textureData": "cow.png",
"type": "ANIMAL",
"width": 60,
"height": 60,
"gfxWidth": 64,
"gfxHeight": 64,
"gfxOffsetX": -2,
"gfxOffsetY": -4,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 6,
"shape": "BOX",
"maxSpeed": 1.5,
"jumpForce": 5.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 20,
"defense": 0,
"attack": 1,
"knockBack": 0,
"knockBackDefense": 0.10,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": true,
"exps": 3,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [
"cow_say1",
"cow_say2",
"cow_say3"
],
"hurtSounds": [
"cow_hurt1",
"cow_hurt1",
"cow_hurt2",
"cow_hurt3"
],
"loots": [
{
"item": "raw_beef",
"count": [ 1, 3 ]
},
{
"item": "leather",
"count": [ 1, 3 ],
"possibility": 0.5
}
],
"burnLoots": [
{
"item": "steak",
"count": [ 1, 3 ]
},
{
"item": "leather",
"count": [ 1, 3 ],
"possibility": 0.5
}
],
"special": 0,
"paticularColor": [ 255, 200, 100, 50 ],
"spawn": "LAND",
"gore": "gore_cow",
"magicRate": 0,
"checkPlayerTarget": false,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/creeper.json
================================================
{
"creeper": {
"ai": "Creeper",
"textureData": "creeper.png",
"type": "NORMAL",
"width": 24,
"height": 50,
"gfxWidth": 32,
"gfxHeight": 64,
"gfxOffsetX": -4,
"gfxOffsetY": -14,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 1.0,
"jumpForce": 8.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 60,
"defense": 8,
"attack": 10,
"knockBack": 2,
"knockBackDefense": 0.15,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 5,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"creeper_death",
"creeper1",
"creeper2",
"creeper3"
],
"loots": [
{
"item": "gunpowder",
"min": 2,
"max": 4
}
],
"special": 0,
"paticularColor": [ 255, 200, 50, 20 ],
"spawn": "LAND",
"gore": "gore_creeper",
"magicRate": 22,
"checkPlayerTarget": true,
"visionNoCrossTile": true
}
}
================================================
FILE: npcs/crison_eye.json
================================================
{
"crison_eye": {
"ai": "CrisonEye",
"textureData": "crison_eye.png",
"type": "NORMAL",
"width": 112,
"height": 112,
"gfxWidth": 192,
"gfxHeight": 112,
"gfxOffsetX": -48,
"gfxOffsetY": 0,
"frameStyle": 0,
"frames": 1,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 3.2,
"jumpForce": 5.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 2600,
"defense": 5,
"attack": 22,
"knockBack": 8,
"knockBackDefense": 0.99,
"gravity": false,
"climbWall": false,
"foreground": true,
"noFixByBlock": true,
"friendly": false,
"exps": 217,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"gore3",
"gore1",
"gore2"
],
"loots": [
{
"item": "diamond",
"count": [ 1, 2 ]
},
{
"item": "star_ingot",
"count": [ 5, 12 ]
},
{
"item": "evil_part",
"count": [ 8, 20 ]
},
{
"item": "magic_cell",
"count": [ 18, 25 ]
}
],
"special": 0,
"paticularColor": [ 255, 50, 50, 20 ],
"spawn": "AIR",
"magicRate": 30,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/crystal_monster.json
================================================
{
"crystal_monster": {
"ai": "CrystalMonster",
"textureData": "crystal_monster.png",
"type": "SMITE",
"width": 48,
"height": 64,
"gfxWidth": 48,
"gfxHeight": 64,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"maxSpeed": 2.0,
"jumpForce": 5.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 100,
"defense": 10,
"attack": 18,
"knockBack": 5,
"knockBackDefense": 0.10,
"gravity": false,
"climbWall": false,
"foreground": true,
"noFixByBlock": false,
"friendly": false,
"exps": 22,
"sunBurning": false,
"angry": false,
"antiLava": true,
"saySounds": [],
"hurtSounds": [
"gore3",
"gore1",
"gore2"
],
"loots": [
{
"item": "white_crystal",
"min": 1,
"max": 2
}
],
"special": 0,
"paticularColor": [ 255, 200, 100, 50 ],
"spawn": "AIR",
"magicRate": 50,
"checkPlayerTarget": true,
"visionNoCrossTile": false,
"checkTargetDistance": 256
}
}
================================================
FILE: npcs/cursed_skull.json
================================================
{
"cursed_skull": {
"ai": "CursedSkull",
"textureData": "cursed_skull.png",
"type": "NORMAL",
"width": 32,
"height": 32,
"gfxWidth": 32,
"gfxHeight": 32,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"frameStyle": 1,
"frames": 2,
"frameSpeed": 16,
"shape": "BOX",
"maxSpeed": 1.2,
"jumpForce": 5.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 100,
"defense": 6,
"attack": 17,
"knockBack": 5,
"knockBackDefense": 0.10,
"gravity": false,
"climbWall": false,
"foreground": true,
"noFixByBlock": true,
"friendly": false,
"exps": 10,
"sunBurning": false,
"angry": false,
"antiLava": true,
"saySounds": [],
"hurtSounds": [
"gore3",
"gore1",
"gore2"
],
"loots": [],
"special": 0,
"paticularColor": [ 255, 50, 50, 20 ],
"spawn": "AIR",
"gore": "gore_cursed_skull",
"magicRate": 30,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/dark_mage.json
================================================
{
"dark_mage": {
"ai": "DarkMage",
"textureData": "dark_mage.png",
"type": "NORMAL",
"width": 28,
"height": 48,
"gfxWidth": 40,
"gfxHeight": 48,
"gfxOffsetX": -6,
"gfxOffsetY": 0,
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 0.0,
"jumpForce": 9.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 80,
"defense": 8,
"attack": 18,
"knockBack": 2,
"knockBackDefense": 0.10,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 10,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"shulker_hit1",
"shulker_hit1"
],
"loots": [
{
"item": "emerald",
"min": 0,
"max": 1
},
{
"item": "red_crystal",
"min": 0,
"max": 1
},
{
"item": "yellow_crystal",
"min": 0,
"max": 1
}
],
"special": 0,
"paticularColor": [ 255, 33, 33, 33 ],
"spawn": "LAND",
"gore": "gore_evoker",
"magicRate": 25,
"checkPlayerTarget": true,
"visionNoCrossTile": false,
"checkTargetDistance": 720
}
}
================================================
FILE: npcs/dead_mage.json
================================================
{
"dead_mage": {
"ai": "DeadMage",
"textureData": "dead_mage.png",
"type": "NORMAL",
"width": 28,
"height": 64,
"gfxWidth": 40,
"gfxHeight": 64,
"gfxOffsetX": -6,
"gfxOffsetY": 0,
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 0.0,
"jumpForce": 9.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 60,
"defense": 10,
"attack": 10,
"knockBack": 2,
"knockBackDefense": 0.10,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 10,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"shulker_hit1",
"shulker_hit1"
],
"loots": [
{
"item": "emerald",
"min": 0,
"max": 1
},
{
"item": "red_crystal",
"min": 0,
"max": 1
},
{
"item": "yellow_crystal",
"min": 0,
"max": 1
}
],
"special": 0,
"paticularColor": [ 255, 33, 33, 33 ],
"spawn": "LAND",
"gore": "gore_evoker",
"magicRate": 25,
"checkPlayerTarget": true,
"visionNoCrossTile": false,
"checkTargetDistance": 720
}
}
================================================
FILE: npcs/desert_slime.json
================================================
{
"desert_slime": {
"ai": "Slime",
"textureData": "desert_slime.png",
"type": "NORMAL",
"width": 24,
"height": 24,
"gfxWidth": 32,
"gfxHeight": 32,
"gfxOffsetX": -4,
"gfxOffsetY": -8,
"frameStyle": 1,
"frames": 2,
"frameSpeed": 16,
"shape": "BOX",
"maxSpeed": 3.0,
"jumpForce": 11.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 40,
"defense": 0,
"attack": 6,
"knockBack": 2,
"knockBackDefense": 0.05,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 5,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"slime_attack1",
"slime_attack1",
"slime_attack2"
],
"loots": [
{
"item": "slimeball",
"count": [ 1, 3 ]
}
],
"special": 0,
"paticularColor": [ 255, 220, 160, 0 ],
"spawn": "LAND",
"magicRate": 80,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/doge_zombie.json
================================================
{
"doge_zombie": {
"ai": "Zombie",
"textureData": "doge_zombie.png",
"type": "SMITE",
"width": 24,
"height": 46,
"gfxWidth": 48,
"gfxHeight": 48,
"gfxOffsetX": 4,
"gfxOffsetY": 8,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 1.0,
"jumpForce": 9.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 45,
"defense": 6,
"attack": 14,
"knockBack": 5,
"knockBackDefense": 0.50,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 8,
"sunBurning": true,
"angry": false,
"antiLava": false,
"saySounds": [
"wolf_bark1",
"wolf_bark2",
"wolf_bark3"
],
"hurtSounds": [
"wolf_hurt1",
"wolf_hurt2",
"wolf_hurt3"
],
"loots": [
{
"item": "rotten_flesh",
"min": 1,
"max": 4
},
{
"item": "bone",
"min": 1,
"max": 2
}
],
"special": 0,
"paticularColor": [ 255, 200, 50, 20 ],
"spawn": "LAND",
"gore": "gore_doge_zombie",
"magicRate": 28,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/dolphin.json
================================================
{
"dolphin": {
"ai": "Dolphin",
"textureData": "dolphin.png",
"type": "ANIMAL",
"width": 72,
"height": 40,
"gfxWidth": 96,
"gfxHeight": 48,
"gfxOffsetX": -8,
"gfxOffsetY": -4,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 16,
"shape": "BOX",
"maxSpeed": 4.0,
"jumpForce": 12.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 30,
"defense": 3,
"attack": 1,
"knockBack": 0,
"knockBackDefense": 0.30,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": true,
"exps": 3,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"dolphin_hurt1",
"dolphin_hurt1",
"dolphin_hurt2",
"dolphin_hurt3"
],
"loots": [
{
"item": "raw_cod",
"count": [ 1, 3 ]
},
{
"item": "raw_salmon",
"count": [ 1, 2 ],
"possibility": 0.5
}
],
"special": 0,
"paticularColor": [ 255, 200, 100, 50 ],
"spawn": "WATER",
"gore": "gore_dolphin",
"magicRate": 0,
"checkPlayerTarget": false,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/dragon_skull.json
================================================
{
"dragon_skull": {
"ai": "CursedSkull",
"textureData": "dragon_skull.png",
"type": "NORMAL",
"width": 64,
"height": 32,
"gfxWidth": 64,
"gfxHeight": 32,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"frameStyle": 1,
"frames": 2,
"frameSpeed": 16,
"shape": "BOX",
"maxSpeed": 1.2,
"jumpForce": 5.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 120,
"defense": 16,
"attack": 17,
"knockBack": 15,
"knockBackDefense": 0.10,
"gravity": false,
"climbWall": false,
"foreground": true,
"noFixByBlock": true,
"friendly": false,
"exps": 11,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"gore3",
"gore1",
"gore2"
],
"drops": [],
"special": 0,
"paticularColor": [ 255, 50, 50, 20 ],
"spawn": "AIR",
"magicRate": 30,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/drowned.json
================================================
{
"drowned": {
"ai": "Zombie",
"textureData": "drowned.png",
"type": "SMITE",
"width": 24,
"height": 46,
"gfxWidth": 48,
"gfxHeight": 48,
"gfxOffsetX": 4,
"gfxOffsetY": 8,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 1.5,
"jumpForce": 9.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 45,
"defense": 6,
"attack": 14,
"knockBack": 5,
"knockBackDefense": 0.50,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 5,
"sunBurning": true,
"angry": false,
"antiLava": false,
"saySounds": [
"zombie_say1",
"zombie_say2",
"zombie_say3"
],
"hurtSounds": [
"zombie_death",
"zombie_hurt1",
"zombie_hurt2"
],
"noBurnSound": true,
"loots": [
{
"item": "rotten_flesh",
"count": [ 1, 4 ]
},
{
"item": "gold_ingot",
"count": [ 1, 2 ],
"possibility": 0.5
}
],
"special": 0,
"paticularColor": [ 255, 200, 50, 20 ],
"spawn": "WATER",
"gore": "gore_drowned",
"magicRate": 30,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/dungeon_creeper.json
================================================
{
"dungeon_creeper": {
"ai": "DungeonCreeper",
"textureData": "dungeon_creeper.png",
"type": "NORMAL",
"width": 24,
"height": 50,
"gfxWidth": 32,
"gfxHeight": 64,
"gfxOffsetX": -4,
"gfxOffsetY": -14,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 2.0,
"jumpForce": 8.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 100,
"defense": 8,
"attack": 13,
"knockBack": 3,
"knockBackDefense": 0.35,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 8,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"creeper_death",
"creeper1",
"creeper2",
"creeper3"
],
"drops": [
{
"item": "gunpowder",
"min": 2,
"max": 4
},
{
"item": "magic_cell",
"count": [ 3, 5 ]
}
],
"special": 0,
"paticularColor": [ 255, 200, 50, 20 ],
"spawn": "LAND",
"gore": "gore_creeper",
"magicRate": 22,
"checkPlayerTarget": true,
"visionNoCrossTile": true
}
}
================================================
FILE: npcs/dungeon_eater_body.json
================================================
{
"dungeon_eater_body": {
"ai": "DungeonEater_Body",
"textureData": "dungeon_eater_body.png",
"type": "ARTHROPODS",
"width": 44,
"height": 36,
"gfxWidth": 44,
"gfxHeight": 36,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "ROTATED_BOX",
"maxSpeed": 5.0,
"jumpForce": 1.0,
"disappearTime": 100000000,
"spawnCount": 0.20,
"health": 80,
"defense": 4,
"attack": 15,
"knockBack": 10,
"knockBackDefense": 1.0,
"gravity": false,
"climbWall": false,
"foreground": false,
"noFixByBlock": true,
"friendly": false,
"exps": 7,
"sunBurning": false,
"angry": false,
"antiLava": true,
"saySounds": [],
"hurtSounds": [],
"loots": [],
"special": 0,
"paticularColor": [ 255, 100, 100, 100 ],
"spawn": "AIR",
"noShowHp": true,
"gore": "gore_lava_snake_body"
}
}
================================================
FILE: npcs/dungeon_eater_head.json
================================================
{
"dungeon_eater_head": {
"ai": "DungeonEater_Head",
"textureData": "dungeon_eater_head.png",
"type": "ARTHROPODS",
"width": 50,
"height": 40,
"gfxWidth": 50,
"gfxHeight": 40,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "ROTATED_BOX",
"maxSpeed": 5.0,
"jumpForce": 1.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 2600,
"defense": 4,
"attack": 20,
"knockBack": 10,
"knockBackDefense": 0.9,
"gravity": false,
"climbWall": false,
"foreground": false,
"noFixByBlock": true,
"friendly": false,
"exps": 600,
"sunBurning": false,
"angry": false,
"antiLava": true,
"saySounds": [],
"hurtSounds": [
"attack1",
"attack2"
],
"loots": [
{
"item": "ancient_sample",
"count": [ 10, 13 ]
}
],
"special": 0,
"paticularColor": [ 255, 100, 100, 100 ],
"spawn": "AIR",
"isBoss": true,
"noShowHp": true,
"gore": "gore_lava_snake_head",
"magicRate": 1,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/dungeon_eater_tail.json
================================================
{
"dungeon_eater_tail": {
"ai": "DungeonEater_Body",
"textureData": "dungeon_eater_tail.png",
"type": "ARTHROPODS",
"width": 54,
"height": 40,
"gfxWidth": 54,
"gfxHeight": 40,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "ROTATED_BOX",
"maxSpeed": 5.0,
"jumpForce": 1.0,
"disappearTime": 100000000,
"spawnCount": 1.0,
"health": 80,
"defense": 4,
"attack": 25,
"knockBack": 10,
"knockBackDefense": 1.0,
"gravity": false,
"climbWall": false,
"foreground": false,
"noFixByBlock": true,
"friendly": false,
"exps": 7,
"sunBurning": false,
"angry": false,
"antiLava": true,
"saySounds": [],
"hurtSounds": [],
"loots": [],
"special": 0,
"paticularColor": [ 255, 100, 100, 100 ],
"spawn": "AIR",
"noShowHp": true,
"gore": "gore_lava_snake_tail"
}
}
================================================
FILE: npcs/dungeon_knight.json
================================================
{
"dungeon_knight": {
"ai": "DungeonKnight",
"textureData": "dungeon_knight.png",
"type": "SMITE",
"width": 24,
"height": 64,
"gfxWidth": 48,
"gfxHeight": 48,
"gfxOffsetX": 4,
"gfxOffsetY": 10,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 1.5,
"jumpForce": 12.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 300,
"defense": 20,
"attack": 25,
"knockBack": 5,
"knockBackDefense": 0.90,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 17,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"skeleton_death",
"skeleton1",
"skeleton2",
"skeleton3"
],
"drops": [
{
"item": "knight_ingot",
"min": 4,
"max": 6
},
{
"item": "diamond",
"min": 1,
"max": 2
}
],
"special": 0,
"paticularColor": [ 255, 150, 150, 150 ],
"spawn": "LAND",
"gore": "gore_angry_skeleton",
"magicRate": 25,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/dungeon_slime.json
================================================
{
"dungeon_slime": {
"ai": "BlockSlime",
"textureData": "dungeon_slime.png",
"type": "NORMAL",
"width": 32,
"height": 32,
"gfxWidth": 40,
"gfxHeight": 40,
"gfxOffsetX": -4,
"gfxOffsetY": -4,
"frameStyle": 1,
"frames": 2,
"frameSpeed": 16,
"shape": "BOX",
"maxSpeed": 2.0,
"jumpForce": 6.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 100,
"defense": 0,
"attack": 10,
"knockBack": 2,
"knockBackDefense": 0.05,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 7,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"slime_attack1",
"slime_attack1",
"slime_attack2"
],
"drops": [
{
"item": "slimeball",
"min": 2,
"max": 5
}
],
"special": 0,
"paticularColor": [ 255, 77, 77, 77 ],
"spawn": "LAND",
"magicRate": 80,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/dungeon_soul.json
================================================
{
"dungeon_soul": {
"ai": "DungeonSoul",
"textureData": "dungeon_soul.png",
"type": "SMITE",
"width": 32,
"height": 32,
"gfxWidth": 32,
"gfxHeight": 32,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"frameStyle": 1,
"frames": 6,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 1.25,
"jumpForce": 9.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 80,
"defense": 6,
"attack": 18,
"knockBack": 5,
"knockBackDefense": 0.40,
"gravity": false,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 10,
"sunBurning": false,
"angry": false,
"antiLava": true,
"saySounds": [],
"hurtSounds": [
"blaze_death",
"blaze_hit1",
"blaze_hit2",
"blaze_hit3"
],
"drops": [
{
"item": "blaze_rod",
"min": 3,
"max": 6
}
],
"special": 0,
"paticularColor": [ 255, 200, 100, 50 ],
"spawn": "AIR",
"magicRate": 30,
"checkPlayerTarget": true,
"visionNoCrossTile": false,
"checkTargetDistance": 640
}
}
================================================
FILE: npcs/eagle.json
================================================
{
"eagle": {
"ai": "Eagle",
"textureData": "eagle.png",
"type": "SMITE",
"width": 32,
"height": 32,
"gfxWidth": 96,
"gfxHeight": 96,
"gfxOffsetX": -32,
"gfxOffsetY": -32,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 6,
"shape": "BOX",
"maxSpeed": 5.0,
"jumpForce": 5.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 60,
"defense": 2,
"attack": 18,
"knockBack": 6,
"knockBackDefense": 0.20,
"gravity": false,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 7,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"gore3",
"gore1",
"gore2"
],
"loots": [
{
"item": "gray_feather",
"count": [ 3, 7 ]
}
],
"special": 0,
"paticularColor": [ 255, 200, 100, 50 ],
"spawn": "AIR",
"gore": "gore_eagle",
"magicRate": 40,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/ender_dragon.json
================================================
{
"ender_dragon": {
"ai": "Ender_Dragon",
"textureData": "ender_dragon.png",
"type": "BOSS",
"width": 240,
"height": 200,
"gfxWidth": 360,
"gfxHeight": 320,
"gfxOffsetX": -60,
"gfxOffsetY": -60,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 4,
"shape": "BOX",
"maxSpeed": 9.0,
"jumpForce": 12.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 100,
"defense": 20,
"attack": 20,
"knockBack": 10,
"knockBackDefense": 0.80,
"gravity": false,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 66,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [],
"loots": [],
"special": 0,
"paticularColor": [ 255, 33, 33, 33 ],
"spawn": "AIR",
"magicRate": 1
}
}
================================================
FILE: npcs/enderman.json
================================================
{
"enderman": {
"ai": "Enderman",
"textureData": "enderman.png",
"type": "NORMAL",
"width": 24,
"height": 64,
"gfxWidth": 48,
"gfxHeight": 48,
"gfxOffsetX": 4,
"gfxOffsetY": 10,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 6,
"shape": "BOX",
"maxSpeed": 2.0,
"jumpForce": 8.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 80,
"defense": 9,
"attack": 18,
"knockBack": 5,
"knockBackDefense": 0.30,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": true,
"exps": 15,
"sunBurning": false,
"angry": true,
"antiLava": false,
"saySounds": [
"enderman_idle1",
"enderman_idle2",
"enderman_idle3"
],
"hurtSounds": [
"enderman_death",
"enderman_hit1",
"enderman_hit2",
"enderman_hit3"
],
"loots": [
{
"item": "ender_pearl",
"count": [ 1, 3 ]
}
],
"special": 0,
"paticularColor": [ 255, 50, 50, 50 ],
"spawn": "LAND",
"gore": "gore_enderman",
"magicRate": 20,
"checkPlayerTarget": false,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/evil.json
================================================
{
"evil": {
"ai": "Evil",
"textureData": "evil.png",
"type": "SMITE",
"width": 32,
"height": 32,
"gfxWidth": 96,
"gfxHeight": 96,
"gfxOffsetX": -32,
"gfxOffsetY": -32,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 4,
"shape": "BOX",
"maxSpeed": 3.0,
"jumpForce": 5.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 160,
"defense": 2,
"attack": 18,
"knockBack": 6,
"knockBackDefense": 0.20,
"gravity": false,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 14,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"phantom_death",
"phantom_hurt1",
"phantom_hurt2",
"phantom_hurt3"
],
"drops": [
{
"item": "evil_part",
"min": 1,
"max": 3
}
],
"special": 0,
"paticularColor": [ 255, 50, 50, 50 ],
"spawn": "AIR",
"gore": "gore_phantom",
"magicRate": 25,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/evoker.json
================================================
{
"evoker": {
"ai": "Evoker",
"textureData": "evoker.png",
"type": "NORMAL",
"width": 28,
"height": 48,
"gfxWidth": 40,
"gfxHeight": 48,
"gfxOffsetX": -6,
"gfxOffsetY": 0,
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 0.0,
"jumpForce": 9.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 60,
"defense": 10,
"attack": 10,
"knockBack": 2,
"knockBackDefense": 0.10,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 10,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"shulker_hit1",
"shulker_hit1"
],
"loots": [
{
"item": "emerald",
"possibility": 0.5
}
],
"special": 0,
"paticularColor": [ 255, 33, 33, 33 ],
"spawn": "LAND",
"gore": "gore_evoker",
"magicRate": 25,
"checkPlayerTarget": true,
"visionNoCrossTile": false,
"checkTargetDistance": 720
}
}
================================================
FILE: npcs/eye_guard.json
================================================
{
"eye_guard": {
"ai": "EyeGuard",
"textureData": "eye_guard.png",
"type": "SMITE",
"width": 48,
"height": 48,
"gfxWidth": 48,
"gfxHeight": 48,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"frameStyle": 1,
"frames": 2,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 2.25,
"jumpForce": 9.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 180,
"defense": 6,
"attack": 18,
"knockBack": 5,
"knockBackDefense": 0.20,
"gravity": false,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 15,
"sunBurning": false,
"angry": false,
"antiLava": true,
"saySounds": [],
"hurtSounds": [
"blaze_death",
"blaze_hit1",
"blaze_hit2",
"blaze_hit3"
],
"drops": [
{
"item": "blaze_rod",
"min": 3,
"max": 6
}
],
"special": 0,
"paticularColor": [ 255, 200, 100, 50 ],
"spawn": "AIR",
"magicRate": 30,
"checkPlayerTarget": true,
"visionNoCrossTile": false,
"checkTargetDistance": 640
}
}
================================================
FILE: npcs/eye_guard_laser.json
================================================
{
"eye_guard_laser": {
"ai": "EyeGuardLaser",
"textureData": "eye_guard_laser.png",
"type": "SMITE",
"width": 48,
"height": 48,
"gfxWidth": 48,
"gfxHeight": 48,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"frameStyle": 1,
"frames": 2,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 1.25,
"jumpForce": 9.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 180,
"defense": 6,
"attack": 18,
"knockBack": 5,
"knockBackDefense": 0.40,
"gravity": false,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 15,
"sunBurning": false,
"angry": false,
"antiLava": true,
"saySounds": [],
"hurtSounds": [
"blaze_death",
"blaze_hit1",
"blaze_hit2",
"blaze_hit3"
],
"drops": [
{
"item": "blaze_rod",
"min": 3,
"max": 6
}
],
"special": 0,
"paticularColor": [ 255, 200, 100, 50 ],
"spawn": "AIR",
"magicRate": 30,
"checkPlayerTarget": true,
"visionNoCrossTile": false,
"checkTargetDistance": 640
}
}
================================================
FILE: npcs/flame_soul.json
================================================
{
"flame_soul": {
"ai": "FlameSoul",
"textureData": "flame_soul.png",
"type": "SMITE",
"width": 32,
"height": 32,
"gfxWidth": 32,
"gfxHeight": 32,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"frameStyle": 1,
"frames": 6,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 1.25,
"jumpForce": 9.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 80,
"defense": 6,
"attack": 18,
"knockBack": 5,
"knockBackDefense": 0.40,
"gravity": false,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 10,
"sunBurning": false,
"angry": false,
"antiLava": true,
"saySounds": [],
"hurtSounds": [
"blaze_death",
"blaze_hit1",
"blaze_hit2",
"blaze_hit3"
],
"drops": [
{
"item": "blaze_rod",
"min": 3,
"max": 6
}
],
"special": 0,
"paticularColor": [ 255, 200, 100, 50 ],
"spawn": "AIR",
"magicRate": 30,
"checkPlayerTarget": true,
"visionNoCrossTile": false,
"checkTargetDistance": 640
}
}
================================================
FILE: npcs/flower_creeper.json
================================================
{
"flower_creeper": {
"ai": "Creeper",
"textureData": "flower_creeper.png",
"type": "NORMAL",
"width": 24,
"height": 50,
"gfxWidth": 32,
"gfxHeight": 64,
"gfxOffsetX": -4,
"gfxOffsetY": -14,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 1.0,
"jumpForce": 8.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 60,
"defense": 8,
"attack": 10,
"knockBack": 2,
"knockBackDefense": 0.15,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 5,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"creeper_death",
"creeper1",
"creeper2",
"creeper3"
],
"loots": [
{
"item": "gunpowder",
"count": [ 3, 5 ]
}
],
"special": 0,
"paticularColor": [ 255, 200, 50, 20 ],
"spawn": "LAND",
"gore": "gore_flower_creeper",
"magicRate": 22,
"checkPlayerTarget": true,
"visionNoCrossTile": true
}
}
================================================
FILE: npcs/fly_eye.json
================================================
{
"fly_eye": {
"ai": "FlyEye",
"textureData": "fly_eye.png",
"type": "NORMAL",
"width": 32,
"height": 32,
"gfxWidth": 72,
"gfxHeight": 46,
"gfxOffsetX": -20,
"gfxOffsetY": -7,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 4,
"shape": "BOX",
"maxSpeed": 3.0,
"jumpForce": 5.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 70,
"defense": 6,
"attack": 7,
"knockBack": 4,
"knockBackDefense": 0.10,
"gravity": false,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 5,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"gore3",
"gore1",
"gore2"
],
"loots": [
{
"item": "strange_len",
"count": [1, 2]
}
],
"special": 0,
"paticularColor": [ 255, 50, 50, 20 ],
"spawn": "AIR",
"magicRate": 30,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/fly_mouth.json
================================================
{
"fly_mouth": {
"ai": "FlyEye",
"textureData": "fly_mouth.png",
"type": "NORMAL",
"width": 32,
"height": 32,
"gfxWidth": 72,
"gfxHeight": 46,
"gfxOffsetX": -20,
"gfxOffsetY": -7,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 4,
"shape": "BOX",
"maxSpeed": 5.0,
"jumpForce": 5.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 70,
"defense": 4,
"attack": 12,
"knockBack": 4,
"knockBackDefense": 0.10,
"gravity": false,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 5,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"gore3",
"gore1",
"gore2"
],
"drops": [],
"special": 0,
"paticularColor": [ 255, 50, 50, 20 ],
"spawn": "AIR",
"magicRate": 30,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/fly_skeleton.json
================================================
{
"fly_skeleton": {
"ai": "FlySkeleton",
"textureData": "fly_skeleton.png",
"type": "SMITE",
"width": 24,
"height": 46,
"gfxWidth": 48,
"gfxHeight": 48,
"gfxOffsetX": 4,
"gfxOffsetY": 8,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 2.0,
"jumpForce": 9.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 45,
"defense": 6,
"attack": 16,
"knockBack": 5,
"knockBackDefense": 0.50,
"gravity": false,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 8,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"gore3",
"gore1",
"gore2"
],
"drops": [],
"special": 1,
"paticularColor": [ 255, 200, 50, 20 ],
"spawn": "AIR",
"spawnWall": "aurora_block",
"magicRate": 100,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/ghast.json
================================================
{
"ghast": {
"ai": "Ghast",
"textureData": "ghast.png",
"type": "SMITE",
"width": 72,
"height": 72,
"gfxWidth": 96,
"gfxHeight": 96,
"gfxOffsetX": -12,
"gfxOffsetY": -12,
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"maxSpeed": 1.0,
"jumpForce": 5.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 80,
"defense": 10,
"attack": 10,
"knockBack": 5,
"knockBackDefense": 0.10,
"gravity": false,
"climbWall": false,
"foreground": true,
"noFixByBlock": true,
"friendly": false,
"exps": 14,
"sunBurning": false,
"angry": false,
"antiLava": true,
"saySounds": [
"ghast_moan1",
"ghast_moan2",
"ghast_moan3"
],
"hurtSounds": [
"ghast_death",
"affectionate_scream"
],
"loots": [
{
"item": "ghast_tear",
"count": [ 1, 4 ]
}
],
"special": 0,
"paticularColor": [ 255, 200, 100, 50 ],
"spawn": "AIR",
"magicRate": 20,
"checkPlayerTarget": true,
"visionNoCrossTile": false,
"checkTargetDistance": 640
}
}
================================================
FILE: npcs/ghost_gunner.json
================================================
{
"ghost_gunner": {
"ai": "GhostGunner",
"textureData": "ghost_gunner.png",
"type": "SMITE",
"width": 24,
"height": 46,
"gfxWidth": 48,
"gfxHeight": 48,
"gfxOffsetX": 4,
"gfxOffsetY": 8,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 2.0,
"jumpForce": 9.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 65,
"defense": 7,
"attack": 18,
"knockBack": 5,
"knockBackDefense": 0.50,
"gravity": false,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 13,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"gore3",
"gore1",
"gore2"
],
"drops": [
{
"item": "ghost_element",
"min": 0,
"max": 1
}
],
"special": 1,
"paticularColor": [ 255, 200, 50, 20 ],
"spawn": "AIR",
"spawnWall": "more_dungeons:stone_wall_white",
"magicRate": 100,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/ghost_soul.json
================================================
{
"ghost_soul": {
"ai": "GhostSoul",
"textureData": "ghost_soul.png",
"type": "SMITE",
"width": 32,
"height": 32,
"gfxWidth": 48,
"gfxHeight": 48,
"gfxOffsetX": -8,
"gfxOffsetY": -8,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 1.25,
"jumpForce": 9.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 80,
"defense": 6,
"attack": 18,
"knockBack": 5,
"knockBackDefense": 0.40,
"gravity": false,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 10,
"sunBurning": false,
"angry": false,
"antiLava": true,
"saySounds": [],
"hurtSounds": [
"blaze_death",
"blaze_hit1",
"blaze_hit2",
"blaze_hit3"
],
"drops": [
{
"item": "blaze_rod",
"min": 3,
"max": 6
}
],
"special": 0,
"paticularColor": [ 255, 200, 100, 50 ],
"spawn": "AIR",
"magicRate": 30,
"checkPlayerTarget": true,
"visionNoCrossTile": false,
"checkTargetDistance": 640
}
}
================================================
FILE: npcs/giant_cursed_skull.json
================================================
{
"giant_cursed_skull": {
"ai": "GiantCursedSkull",
"textureData": "giant_cursed_skull.png",
"type": "NORMAL",
"width": 64,
"height": 64,
"gfxWidth": 64,
"gfxHeight": 64,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"frameStyle": 1,
"frames": 2,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 1.2,
"jumpForce": 5.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 220,
"defense": 16,
"attack": 27,
"knockBack": 5,
"knockBackDefense": 0.10,
"gravity": false,
"climbWall": false,
"foreground": true,
"noFixByBlock": true,
"friendly": false,
"exps": 17,
"sunBurning": false,
"angry": false,
"antiLava": true,
"saySounds": [],
"hurtSounds": [
"gore3",
"gore1",
"gore2"
],
"drops": [],
"special": 0,
"paticularColor": [ 255, 50, 50, 20 ],
"spawn": "AIR",
"gore": "gore_giant_cursed_skull",
"magicRate": 30,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/green_slime.json
================================================
{
"green_slime": {
"ai": "Slime",
"textureData": "green_slime.png",
"type": "NORMAL",
"width": 24,
"height": 24,
"gfxWidth": 32,
"gfxHeight": 32,
"gfxOffsetX": -4,
"gfxOffsetY": -8,
"frameStyle": 1,
"frames": 2,
"frameSpeed": 16,
"shape": "BOX",
"maxSpeed": 3.0,
"jumpForce": 8.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 16,
"defense": 0,
"attack": 4,
"knockBack": 2,
"knockBackDefense": 0.05,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 4,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"slime_attack1",
"slime_attack1",
"slime_attack2"
],
"loots": [
{
"item": "slimeball",
"count": [ 1, 2 ]
}
],
"special": 0,
"paticularColor": [ 255, 120, 200, 100 ],
"spawn": "LAND",
"magicRate": 80,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/grim_reaper.json
================================================
{
"grim_reaper": {
"ai": "GrimReaper",
"textureData": "grim_reaper.png",
"type": "NORMAL",
"width": 28,
"height": 48,
"gfxWidth": 40,
"gfxHeight": 48,
"gfxOffsetX": -6,
"gfxOffsetY": 0,
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 0.0,
"jumpForce": 9.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 60,
"defense": 10,
"attack": 10,
"knockBack": 2,
"knockBackDefense": 0.10,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 15,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"shulker_hit1",
"shulker_hit1"
],
"drops": [
{
"item": "emerald",
"min": 0,
"max": 1
}
],
"special": 0,
"paticularColor": [ 255, 33, 33, 33 ],
"spawn": "LAND",
"gore": "gore_evoker",
"magicRate": 25,
"checkPlayerTarget": true,
"visionNoCrossTile": false,
"checkTargetDistance": 720
}
}
================================================
FILE: npcs/guardian.json
================================================
{
"guardian": {
"ai": "Guardian",
"textureData": "guardian.png",
"type": "NORMAL",
"width": 32,
"height": 32,
"gfxWidth": 52,
"gfxHeight": 48,
"gfxOffsetX": -10,
"gfxOffsetY": -8,
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 1.0,
"jumpForce": 5.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 100,
"defense": 10,
"attack": 10,
"knockBack": 5,
"knockBackDefense": 0.10,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 10,
"sunBurning": false,
"angry": false,
"antiLava": true,
"saySounds": [],
"hurtSounds": [
"blaze_death",
"blaze_hit1",
"blaze_hit2",
"blaze_hit3"
],
"loots": [
{
"item": "guardian"
},
{
"item": "prismarine_crystals",
"count": [ 1, 4 ]
},
{
"item": "raw_cod",
"count": [ 1, 2 ],
"possibility": 0.5
},
{
"item": "prismarine_shard",
"count": [ 2, 5 ]
}
],
"special": 0,
"paticularColor": [ 255, 200, 100, 50 ],
"spawn": "WATER",
"magicRate": 30,
"checkPlayerTarget": true,
"visionNoCrossTile": false,
"checkTargetDistance": 400
}
}
================================================
FILE: npcs/husk.json
================================================
{
"husk": {
"ai": "Zombie",
"textureData": "husk.png",
"type": "SMITE",
"width": 24,
"height": 46,
"gfxWidth": 48,
"gfxHeight": 48,
"gfxOffsetX": 4,
"gfxOffsetY": 8,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 1.0,
"jumpForce": 9.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 45,
"defense": 6,
"attack": 14,
"knockBack": 5,
"knockBackDefense": 0.50,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 5,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [
"zombie_say1",
"zombie_say2",
"zombie_say3"
],
"hurtSounds": [
"zombie_death",
"zombie_hurt1",
"zombie_hurt2"
],
"noBurnSound": true,
"loots": [
{
"item": "rotten_flesh",
"count": [ 1, 4 ]
}
],
"special": 0,
"paticularColor": [ 255, 200, 50, 20 ],
"spawn": "LAND",
"gore": "gore_husk",
"magicRate": 30,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/ice_elf.json
================================================
{
"ice_elf": {
"ai": "IceElf",
"textureData": "ice_elf.png",
"type": "SMITE",
"width": 50,
"height": 50,
"gfxWidth": 50,
"gfxHeight": 50,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"frameStyle": 1,
"frames": 2,
"frameSpeed": 8,
"maxSpeed": 2.0,
"jumpForce": 5.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 40,
"defense": 10,
"attack": 7,
"knockBack": 5,
"knockBackDefense": 0.10,
"gravity": false,
"climbWall": false,
"foreground": true,
"noFixByBlock": true,
"friendly": false,
"exps": 6,
"sunBurning": false,
"angry": false,
"antiLava": true,
"saySounds": [],
"hurtSounds": [
"gore3",
"gore1",
"gore2"
],
"loots": [],
"special": 0,
"paticularColor": [ 255, 200, 100, 50 ],
"spawn": "AIR",
"magicRate": 50,
"checkPlayerTarget": true,
"visionNoCrossTile": false,
"checkTargetDistance": 256
}
}
================================================
FILE: npcs/ice_slime.json
================================================
{
"ice_slime": {
"ai": "BlockSlime",
"textureData": "ice_slime.png",
"type": "NORMAL",
"width": 24,
"height": 24,
"gfxWidth": 32,
"gfxHeight": 32,
"gfxOffsetX": -4,
"gfxOffsetY": -8,
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 2.0,
"jumpForce": 8.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 20,
"defense": 0,
"attack": 5,
"knockBack": 2,
"knockBackDefense": 0.03,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 4,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"slime_attack1",
"slime_attack1",
"slime_attack2"
],
"loots": [
{
"item": "slimeball",
"min": 1,
"max": 2
},
{
"item": "ice",
"min": 1,
"max": 2
}
],
"special": 0,
"paticularColor": [ 255, 0, 200, 255 ],
"spawn": "LAND",
"magicRate": 80,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/iron_zombie.json
================================================
{
"iron_zombie": {
"ai": "Zombie",
"textureData": "iron_zombie.png",
"type": "SMITE",
"width": 24,
"height": 46,
"gfxWidth": 48,
"gfxHeight": 48,
"gfxOffsetX": 4,
"gfxOffsetY": 8,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 2.0,
"jumpForce": 9.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 65,
"defense": 6,
"attack": 14,
"knockBack": 5,
"knockBackDefense": 0.50,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 7,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [
"zombie_say1",
"zombie_say2",
"zombie_say3"
],
"hurtSounds": [
"blaze_death",
"blaze_hit1",
"blaze_hit2",
"blaze_hit3"
],
"loots": [
{
"item": "rotten_flesh",
"count": [ 1, 4 ]
},
{
"item": "magic_cell",
"count": [ 1, 3 ]
},
{
"item": "iron_ingot",
"possibility": 0.5
}
],
"special": 0,
"paticularColor": [ 255, 200, 50, 20 ],
"spawn": "LAND",
"gore": "gore_iron_zombie",
"magicRate": 30,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/jungle_bat.json
================================================
{
"jungle_bat": {
"ai": "Bat",
"textureData": "jungle_bat.png",
"type": "NORMAL",
"width": 32,
"height": 32,
"gfxWidth": 72,
"gfxHeight": 46,
"gfxOffsetX": -20,
"gfxOffsetY": -7,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 4,
"shape": "BOX",
"maxSpeed": 4.0,
"jumpForce": 5.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 40,
"defense": 6,
"attack": 7,
"knockBack": 4,
"knockBackDefense": 0.10,
"gravity": false,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 5,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"bat_death",
"bat_hurt1",
"bat_hurt2",
"bat_hurt3"
],
"loots": [
{
"item": "gray_feather",
"count": [ 4, 8 ]
}
],
"special": 0,
"paticularColor": [ 255, 50, 50, 20 ],
"spawn": "AIR",
"gore": "gore_jungle_bat",
"magicRate": 30,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/large_bat.json
================================================
{
"large_bat": {
"ai": "LargeBat",
"textureData": "large_bat.png",
"type": "NORMAL",
"width": 32,
"height": 32,
"gfxWidth": 96,
"gfxHeight": 96,
"gfxOffsetX": -32,
"gfxOffsetY": -32,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 3.0,
"jumpForce": 5.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 80,
"defense": 6,
"attack": 17,
"knockBack": 4,
"knockBackDefense": 0.10,
"gravity": false,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 12,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"bat_death",
"bat_hurt1",
"bat_hurt2",
"bat_hurt3"
],
"drops": [
{
"item": "blue_crystal",
"min": 1,
"max": 2
}
],
"special": 0,
"paticularColor": [ 255, 50, 50, 20 ],
"spawn": "AIR",
"gore": "gore_bat",
"magicRate": 30,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/large_black_slime.json
================================================
{
"large_black_slime": {
"ai": "Slime",
"textureData": "large_black_slime.png",
"type": "NORMAL",
"width": 32,
"height": 32,
"gfxWidth": 40,
"gfxHeight": 40,
"gfxOffsetX": -4,
"gfxOffsetY": -4,
"frameStyle": 1,
"frames": 2,
"frameSpeed": 16,
"shape": "BOX",
"maxSpeed": 3.0,
"jumpForce": 8.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 50,
"defense": 0,
"attack": 6,
"knockBack": 2,
"knockBackDefense": 0.05,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 4,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"slime_attack1",
"slime_attack1",
"slime_attack2"
],
"loots": [
{
"item": "slimeball",
"count": [ 2, 5 ]
}
],
"special": 0,
"paticularColor": [ 255, 77, 77, 77 ],
"spawn": "LAND",
"magicRate": 80,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/large_block_slime.json
================================================
{
"large_block_slime": {
"ai": "BlockSlime",
"textureData": "large_block_slime.png",
"type": "NORMAL",
"width": 48,
"height": 48,
"gfxWidth": 64,
"gfxHeight": 64,
"gfxOffsetX": -8,
"gfxOffsetY": -16,
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 3.0,
"jumpForce": 8.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 40,
"defense": 0,
"attack": 6,
"knockBack": 2,
"knockBackDefense": 0.05,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 5,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"slime_attack1",
"slime_attack1",
"slime_attack2"
],
"loots": [
{
"item": "slimeball",
"min": 1,
"max": 4
},
{
"item": "slime_block",
"min": 0,
"max": 1
}
],
"special": 0,
"paticularColor": [ 255, 120, 200, 100 ],
"spawn": "LAND",
"magicRate": 50,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/large_desert_slime.json
================================================
{
"large_desert_slime": {
"ai": "Slime",
"textureData": "large_desert_slime.png",
"type": "NORMAL",
"width": 32,
"height": 32,
"gfxWidth": 40,
"gfxHeight": 40,
"gfxOffsetX": -4,
"gfxOffsetY": -4,
"frameStyle": 1,
"frames": 2,
"frameSpeed": 16,
"shape": "BOX",
"maxSpeed": 3.0,
"jumpForce": 11.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 60,
"defense": 0,
"attack": 8,
"knockBack": 2,
"knockBackDefense": 0.05,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 5,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"slime_attack1",
"slime_attack1",
"slime_attack2"
],
"loots": [
{
"item": "slimeball",
"count": [ 3, 5 ]
}
],
"special": 0,
"paticularColor": [ 255, 220, 160, 0 ],
"spawn": "LAND",
"magicRate": 80,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/large_green_slime.json
================================================
{
"large_green_slime": {
"ai": "Slime",
"textureData": "large_green_slime.png",
"type": "NORMAL",
"width": 32,
"height": 32,
"gfxWidth": 40,
"gfxHeight": 40,
"gfxOffsetX": -4,
"gfxOffsetY": -4,
"frameStyle": 1,
"frames": 2,
"frameSpeed": 16,
"shape": "BOX",
"maxSpeed": 3.0,
"jumpForce": 8.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 40,
"defense": 0,
"attack": 6,
"knockBack": 2,
"knockBackDefense": 0.05,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 4,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"slime_attack1",
"slime_attack1",
"slime_attack2"
],
"loots": [
{
"item": "slimeball",
"count": [ 2, 5 ]
}
],
"special": 0,
"paticularColor": [ 255, 120, 200, 100 ],
"spawn": "LAND",
"magicRate": 80,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/large_ice_slime.json
================================================
{
"large_ice_slime": {
"ai": "BlockSlime",
"textureData": "large_ice_slime.png",
"type": "NORMAL",
"width": 48,
"height": 48,
"gfxWidth": 64,
"gfxHeight": 64,
"gfxOffsetX": -8,
"gfxOffsetY": -16,
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 3.0,
"jumpForce": 8.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 40,
"defense": 0,
"attack": 6,
"knockBack": 2,
"knockBackDefense": 0.05,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 5,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"slime_attack1",
"slime_attack1",
"slime_attack2"
],
"loots": [
{
"item": "slimeball",
"min": 1,
"max": 4
},
{
"item": "slime_block",
"min": 0,
"max": 1
},
{
"item": "ice",
"min": 3,
"max": 6
}
],
"special": 0,
"paticularColor": [ 255, 0, 200, 255 ],
"spawn": "LAND",
"magicRate": 50,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/large_jungle_bat.json
================================================
{
"large_jungle_bat": {
"ai": "Bat",
"textureData": "large_jungle_bat.png",
"type": "NORMAL",
"width": 32,
"height": 32,
"gfxWidth": 72,
"gfxHeight": 46,
"gfxOffsetX": -20,
"gfxOffsetY": -7,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 4,
"shape": "BOX",
"maxSpeed": 3.5,
"jumpForce": 5.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 60,
"defense": 6,
"attack": 7,
"knockBack": 4,
"knockBackDefense": 0.10,
"gravity": false,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 7,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"bat_death",
"bat_hurt1",
"bat_hurt2",
"bat_hurt3"
],
"loots": [
{
"item": "gray_feather",
"count": [ 1, 4 ]
}
],
"special": 0,
"paticularColor": [ 255, 50, 50, 20 ],
"spawn": "AIR",
"gore": "gore_large_jungle_bat",
"magicRate": 30,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/large_spider.json
================================================
{
"large_spider": {
"ai": "LargeSpider",
"textureData": "large_spider.png",
"type": "NORMAL",
"width": 32,
"height": 48,
"gfxWidth": 48,
"gfxHeight": 48,
"gfxOffsetX": -8,
"gfxOffsetY": 0,
"frameStyle": 1,
"frames": 2,
"frameSpeed": 16,
"shape": "BOX",
"maxSpeed": 8.0,
"jumpForce": 3.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 70,
"defense": 0,
"attack": 6,
"knockBack": 2,
"knockBackDefense": 0.05,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 6,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"slime_attack1",
"slime_attack1",
"slime_attack2"
],
"drops": [
{
"item": "red_crystal",
"min": 0,
"max": 1
}
],
"special": 0,
"paticularColor": [ 255, 77, 77, 77 ],
"spawn": "LAND",
"magicRate": 80,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/large_tainted_slime.json
================================================
{
"large_tainted_slime": {
"ai": "TaintedSlime",
"textureData": "large_tainted_slime.png",
"type": "NORMAL",
"width": 32,
"height": 32,
"gfxWidth": 40,
"gfxHeight": 40,
"gfxOffsetX": -4,
"gfxOffsetY": -4,
"frameStyle": 1,
"frames": 2,
"frameSpeed": 16,
"shape": "BOX",
"maxSpeed": 3.0,
"jumpForce": 8.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 60,
"defense": 0,
"attack": 6,
"knockBack": 2,
"knockBackDefense": 0.05,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 4,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"slime_attack1",
"slime_attack1",
"slime_attack2"
],
"loots": [
{
"item": "slimeball",
"count": [ 2, 5 ]
}
],
"special": 1,
"paticularColor": [ 255, 144, 100, 194 ],
"spawn": "LAND",
"magicRate": 80,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/large_waste_block_slime.json
================================================
{
"large_waste_block_slime": {
"ai": "BlockSlime",
"textureData": "large_waste_block_slime.png",
"type": "NORMAL",
"width": 48,
"height": 48,
"gfxWidth": 64,
"gfxHeight": 64,
"gfxOffsetX": -8,
"gfxOffsetY": -16,
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 3.0,
"jumpForce": 8.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 40,
"defense": 0,
"attack": 6,
"knockBack": 2,
"knockBackDefense": 0.05,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 5,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"slime_attack1",
"slime_attack1",
"slime_attack2"
],
"loots": [
{
"item": "slimeball",
"min": 1,
"max": 4
},
{
"item": "slime_block",
"min": 0,
"max": 1
}
],
"special": 0,
"paticularColor": [ 255, 160, 100, 60 ],
"spawn": "LAND",
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/large_waste_slime.json
================================================
{
"large_waste_slime": {
"ai": "Slime",
"textureData": "large_waste_slime.png",
"type": "NORMAL",
"width": 32,
"height": 32,
"gfxWidth": 40,
"gfxHeight": 40,
"gfxOffsetX": -4,
"gfxOffsetY": -4,
"frameStyle": 1,
"frames": 2,
"frameSpeed": 16,
"shape": "BOX",
"maxSpeed": 3.0,
"jumpForce": 8.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 40,
"defense": 0,
"attack": 6,
"knockBack": 2,
"knockBackDefense": 0.05,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 4,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"slime_attack1",
"slime_attack1",
"slime_attack2"
],
"loots": [
{
"item": "slimeball",
"count": [ 2, 5 ]
}
],
"special": 0,
"paticularColor": [ 255, 100, 70, 40 ],
"spawn": "LAND",
"magicRate": 80,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/light_blue_butterfly.json
================================================
{
"light_blue_butterfly": {
"ai": "Butterfly",
"textureData": "light_blue_butterfly.png",
"type": "ANIMAL",
"width": 16,
"height": 16,
"gfxWidth": 22,
"gfxHeight": 22,
"gfxOffsetX": -3,
"gfxOffsetY": -3,
"frameStyle": 0,
"frames": 1,
"frameSpeed": 6,
"shape": "BOX",
"maxSpeed": 1.0,
"jumpForce": 5.0,
"disappearTime": 750,
"spawnCount": 0.25,
"health": 5,
"defense": 0,
"attack": 1,
"knockBack": 0,
"knockBackDefense": 0.10,
"gravity": false,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": true,
"exps": 0,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"rabbit_hurt1",
"rabbit_hurt1",
"rabbit_hurt2",
"rabbit_hurt3"
],
"loots": [],
"special": 0,
"paticularColor": [ 255, 100, 150, 200 ],
"spawn": "AIR",
"magicRate": 0,
"checkPlayerTarget": false,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/mad_skeleton.json
================================================
{
"mad_skeleton": {
"ai": "DungeonSkeleton",
"textureData": "mad_skeleton.png",
"type": "SMITE",
"width": 24,
"height": 46,
"gfxWidth": 48,
"gfxHeight": 48,
"gfxOffsetX": 4,
"gfxOffsetY": 8,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 2.5,
"jumpForce": 8.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 100,
"defense": 8,
"attack": 20,
"knockBack": 5,
"knockBackDefense": 0.20,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 15,
"sunBurning": true,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"skeleton_death",
"skeleton1",
"skeleton2",
"skeleton3"
],
"drops": [
{
"item": "bone",
"min": 0,
"max": 2
},
{
"item": "lead_ingot",
"min": 0,
"max": 1
}
],
"special": 0,
"paticularColor": [ 255, 150, 150, 150 ],
"spawn": "LAND",
"gore": "gore_mad_skeleton",
"magicRate": 25,
"checkPlayerTarget": true,
"visionNoCrossTile": false,
"data": {
"tc": {
"boneSizeIndex": 0,
"style": 0
}
}
}
}
================================================
FILE: npcs/mad_skeleton_armed.json
================================================
{
"mad_skeleton_armed": {
"ai": "DungeonSkeleton",
"textureData": "mad_skeleton_armed.png",
"type": "SMITE",
"width": 24,
"height": 46,
"gfxWidth": 48,
"gfxHeight": 48,
"gfxOffsetX": 4,
"gfxOffsetY": 8,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 2.65,
"jumpForce": 8.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 140,
"defense": 12,
"attack": 20,
"knockBack": 5,
"knockBackDefense": 0.30,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 15,
"sunBurning": true,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"skeleton_death",
"skeleton1",
"skeleton2",
"skeleton3"
],
"drops": [
{
"item": "bone",
"min": 0,
"max": 2
},
{
"item": "wooden_arrow",
"min": 0,
"max": 2
},
{
"item": "flesh_part",
"min": 0,
"max": 2
}
],
"special": 0,
"paticularColor": [ 255, 150, 150, 150 ],
"spawn": "LAND",
"gore": "gore_mad_skeleton_armed",
"magicRate": 25,
"checkPlayerTarget": true,
"visionNoCrossTile": false,
"data": {
"tc": {
"boneSizeIndex": 0,
"style": 1
}
}
}
}
================================================
FILE: npcs/mad_skeleton_tall.json
================================================
{
"mad_skeleton_tall": {
"ai": "DungeonSkeleton",
"textureData": "mad_skeleton_tall.png",
"type": "SMITE",
"width": 24,
"height": 64,
"gfxWidth": 48,
"gfxHeight": 48,
"gfxOffsetX": 4,
"gfxOffsetY": 10,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 1.65,
"jumpForce": 12.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 150,
"defense": 10,
"attack": 25,
"knockBack": 5,
"knockBackDefense": 0.40,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 15,
"sunBurning": true,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"skeleton_death",
"skeleton1",
"skeleton2",
"skeleton3"
],
"drops": [
{
"item": "bone",
"min": 0,
"max": 2
},
{
"item": "wooden_arrow",
"min": 0,
"max": 2
},
{
"item": "flesh_part",
"min": 0,
"max": 2
}
],
"special": 0,
"paticularColor": [ 255, 150, 150, 150 ],
"spawn": "LAND",
"gore": "gore_mad_skeleton_tall",
"magicRate": 25,
"checkPlayerTarget": true,
"visionNoCrossTile": false,
"data": {
"tc": {
"boneSizeIndex": 1,
"style": 2
}
}
}
}
================================================
FILE: npcs/mad_skeleton_tall_armed.json
================================================
{
"mad_skeleton_tall_armed": {
"ai": "DungeonSkeleton",
"textureData": "mad_skeleton_tall_armed.png",
"type": "SMITE",
"width": 24,
"height": 64,
"gfxWidth": 48,
"gfxHeight": 48,
"gfxOffsetX": 4,
"gfxOffsetY": 10,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 2.0,
"jumpForce": 12.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 150,
"defense": 8,
"attack": 34,
"knockBack": 5,
"knockBackDefense": 0.40,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 15,
"sunBurning": true,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"skeleton_death",
"skeleton1",
"skeleton2",
"skeleton3"
],
"drops": [
{
"item": "bone",
"min": 0,
"max": 2
},
{
"item": "wooden_arrow",
"min": 0,
"max": 2
},
{
"item": "copper_ingot",
"min": 0,
"max": 1
},
{
"item": "flesh_part",
"min": 0,
"max": 2
}
],
"special": 0,
"paticularColor": [ 255, 150, 150, 150 ],
"spawn": "LAND",
"gore": "gore_mad_skeleton_tall_armed",
"magicRate": 25,
"checkPlayerTarget": true,
"visionNoCrossTile": false,
"data": {
"tc": {
"boneSizeIndex": 1,
"style": 2
}
}
}
}
================================================
FILE: npcs/mad_skeleton_tall_helmet_armed.json
================================================
{
"mad_skeleton_tall_helmet_armed": {
"ai": "DungeonSkeleton",
"textureData": "mad_skeleton_tall_helmet_armed.png",
"type": "SMITE",
"width": 24,
"height": 64,
"gfxWidth": 48,
"gfxHeight": 48,
"gfxOffsetX": 4,
"gfxOffsetY": 10,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 2.0,
"jumpForce": 12.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 160,
"defense": 12,
"attack": 30,
"knockBack": 5,
"knockBackDefense": 0.50,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 15,
"sunBurning": true,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"skeleton_death",
"skeleton1",
"skeleton2",
"skeleton3"
],
"drops": [
{
"item": "bone",
"min": 0,
"max": 2
},
{
"item": "wooden_arrow",
"min": 0,
"max": 2
},
{
"item": "steel_ingot",
"min": 0,
"max": 1
},
{
"item": "flesh_part",
"min": 0,
"max": 2
}
],
"special": 0,
"paticularColor": [ 255, 150, 150, 150 ],
"spawn": "LAND",
"gore": "gore_mad_skeleton_tall_helmet_armed",
"magicRate": 25,
"checkPlayerTarget": true,
"visionNoCrossTile": false,
"data": {
"tc": {
"boneSizeIndex": 1,
"style": 3
}
}
}
}
================================================
FILE: npcs/magma_birdo.json
================================================
{
"magma_birdo": {
"ai": "MagmaBirdo",
"textureData": "magma_birdo.png",
"type": "SMITE",
"width": 32,
"height": 32,
"gfxWidth": 96,
"gfxHeight": 96,
"gfxOffsetX": -32,
"gfxOffsetY": -32,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 6,
"shape": "BOX",
"maxSpeed": 3.0,
"jumpForce": 5.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 60,
"defense": 2,
"attack": 18,
"knockBack": 6,
"knockBackDefense": 0.20,
"gravity": false,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 7,
"sunBurning": true,
"angry": false,
"antiLava": true,
"saySounds": [],
"hurtSounds": [
"gore3",
"gore1",
"gore2"
],
"loots": [
{
"item": "gray_feather",
"count": [ 3, 7 ]
},
{
"item": "gunpowder",
"count": [ 1, 3 ]
}
],
"special": 1,
"paticularColor": [ 255, 200, 100, 50 ],
"spawn": "AIR",
"gore": "gore_magma_birdo",
"magicRate": 30,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/magma_elf.json
================================================
{
"magma_elf": {
"ai": "MagmaElf",
"textureData": "magma_elf.png",
"type": "SMITE",
"width": 32,
"height": 32,
"gfxWidth": 48,
"gfxHeight": 32,
"gfxOffsetX": -8,
"gfxOffsetY": 0,
"frameStyle": 1,
"frames": 2,
"frameSpeed": 8,
"maxSpeed": 2.0,
"jumpForce": 5.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 40,
"defense": 10,
"attack": 7,
"knockBack": 5,
"knockBackDefense": 0.10,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 7,
"sunBurning": false,
"angry": false,
"antiLava": true,
"saySounds": [],
"hurtSounds": [
"gore3",
"gore1",
"gore2"
],
"loots": [],
"special": 0,
"paticularColor": [ 255, 255, 200, 0 ],
"spawn": "LAND",
"magicRate": 50,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/magma_slime.json
================================================
{
"magma_slime": {
"ai": "MagmaSlime",
"textureData": "magma_slime.png",
"type": "NORMAL",
"width": 32,
"height": 32,
"gfxWidth": 40,
"gfxHeight": 40,
"gfxOffsetX": -4,
"gfxOffsetY": -8,
"frameStyle": 1,
"frames": 2,
"frameSpeed": 16,
"shape": "BOX",
"maxSpeed": 4.0,
"jumpForce": 8.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 60,
"defense": 10,
"attack": 12,
"knockBack": 2,
"knockBackDefense": 0.30,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 5,
"sunBurning": false,
"angry": false,
"antiLava": true,
"saySounds": [],
"hurtSounds": [
"slime_attack1",
"slime_attack1",
"slime_attack2"
],
"loots": [
{
"item": "magma_cream",
"count": [ 1, 3 ]
}
],
"special": 2,
"paticularColor": [ 255, 200, 100, 50 ],
"spawn": "LAND",
"magicRate": 80,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/man_eater.json
================================================
{
"man_eater": {
"ai": "ManEater",
"textureData": "man_eater.png",
"type": "NORMAL",
"width": 32,
"height": 32,
"gfxWidth": 64,
"gfxHeight": 52,
"gfxOffsetX": -16,
"gfxOffsetY": -10,
"frameStyle": 0,
"frames": 2,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 3.5,
"jumpForce": 5.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 60,
"defense": 2,
"attack": 7,
"knockBack": 4,
"knockBackDefense": 0.10,
"gravity": false,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 7,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"gore3",
"gore1",
"gore2"
],
"loots": [],
"special": 0,
"paticularColor": [ 255, 50, 50, 20 ],
"spawn": "AIR",
"gore": "gore_man_eater",
"magicRate": 30,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/meteor.json
================================================
{
"meteor": {
"ai": "Meteor",
"textureData": "meteor.png",
"type": "SMITE",
"width": 32,
"height": 32,
"gfxWidth": 32,
"gfxHeight": 32,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"frameStyle": 1,
"frames": 1,
"frameSpeed": 6,
"shape": "BOX",
"maxSpeed": 2.0,
"jumpForce": 5.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 60,
"defense": 2,
"attack": 18,
"knockBack": 6,
"knockBackDefense": 0.20,
"gravity": false,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 5,
"sunBurning": false,
"angry": false,
"antiLava": true,
"saySounds": [],
"hurtSounds": [
"gore3",
"gore1",
"gore2"
],
"loots": [
{
"item": "gunpowder",
"count": [ 2, 5 ]
}
],
"special": 1,
"paticularColor": [ 255, 200, 100, 50 ],
"spawn": "AIR",
"magicRate": 25,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/mini_ghast.json
================================================
{
"mini_ghast": {
"ai": "MiniGhast",
"textureData": "mini_ghast.png",
"type": "SMITE",
"width": 48,
"height": 48,
"gfxWidth": 48,
"gfxHeight": 48,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"frameStyle": 1,
"frames": 2,
"frameSpeed": 8,
"maxSpeed": 1.0,
"jumpForce": 5.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 70,
"defense": 5,
"attack": 10,
"knockBack": 5,
"knockBackDefense": 0.10,
"gravity": false,
"climbWall": false,
"foreground": true,
"noFixByBlock": true,
"friendly": false,
"exps": 2,
"sunBurning": false,
"angry": false,
"antiLava": true,
"saySounds": [
"ghast_moan1",
"ghast_moan2",
"ghast_moan3"
],
"hurtSounds": [
"ghast_death",
"affectionate_scream"
],
"loots": [
{
"item": "ghost_crystal"
}
],
"special": 0,
"paticularColor": [ 255, 200, 100, 50 ],
"spawn": "AIR",
"spawnWall": "more_dungeons:stone_wall_white",
"magicRate": 20,
"checkPlayerTarget": true,
"visionNoCrossTile": false,
"checkTargetDistance": 640
}
}
================================================
FILE: npcs/mummy.json
================================================
{
"mummy": {
"ai": "Zombie",
"textureData": "mummy.png",
"type": "SMITE",
"width": 24,
"height": 46,
"gfxWidth": 48,
"gfxHeight": 48,
"gfxOffsetX": 4,
"gfxOffsetY": 8,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 1.0,
"jumpForce": 9.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 45,
"defense": 6,
"attack": 14,
"knockBack": 5,
"knockBackDefense": 0.50,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 5,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [
"zombie_say1",
"zombie_say2",
"zombie_say3"
],
"hurtSounds": [
"zombie_death",
"zombie_hurt1",
"zombie_hurt2"
],
"noBurnSound": true,
"loots": [
{
"item": "rotten_flesh",
"count": [ 1, 4 ]
},
{
"item": "string",
"count": [ 1, 4 ]
}
],
"special": 0,
"paticularColor": [ 255, 200, 50, 20 ],
"spawn": "LAND",
"gore": "gore_mummy",
"magicRate": 30,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/phantom.json
================================================
{
"phantom": {
"ai": "Phantom",
"textureData": "phantom.png",
"type": "SMITE",
"width": 32,
"height": 32,
"gfxWidth": 96,
"gfxHeight": 96,
"gfxOffsetX": -32,
"gfxOffsetY": -32,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 3.0,
"jumpForce": 5.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 60,
"defense": 2,
"attack": 18,
"knockBack": 6,
"knockBackDefense": 0.20,
"gravity": false,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 5,
"sunBurning": true,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"phantom_death",
"phantom_hurt1",
"phantom_hurt2",
"phantom_hurt3"
],
"loots": [
{
"item": "phantom_membrane",
"count": [ 1, 3 ]
},
{
"item": "dark_shadow_part",
"count": [ 1, 3 ]
}
],
"special": 0,
"paticularColor": [ 255, 50, 50, 50 ],
"spawn": "AIR",
"gore": "gore_phantom",
"magicRate": 25,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/pig.json
================================================
{
"pig": {
"ai": "Animal",
"textureData": "pig.png",
"type": "ANIMAL",
"width": 48,
"height": 40,
"gfxWidth": 64,
"gfxHeight": 48,
"gfxOffsetX": -8,
"gfxOffsetY": -8,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 1.0,
"jumpForce": 5.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 12,
"defense": 0,
"attack": 1,
"knockBack": 0,
"knockBackDefense": 0.10,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": true,
"exps": 3,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [
"pig_say1",
"pig_say2",
"pig_say3"
],
"hurtSounds": [
"pig_death",
"pig_say1",
"pig_say2",
"pig_say3"
],
"loots": [
{
"item": "raw_porkchop",
"count": [ 1, 3 ]
}
],
"burnLoots": [
{
"item": "cooked_porkchop",
"count": [ 1, 3 ]
}
],
"special": 0,
"paticularColor": [ 255, 200, 100, 50 ],
"spawn": "LAND",
"gore": "gore_pig",
"magicRate": 0,
"checkPlayerTarget": false,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/pufferfish.json
================================================
{
"pufferfish": {
"ai": "Pufferfish",
"textureData": "pufferfish.png",
"type": "ANIMAL",
"width": 32,
"height": 32,
"gfxWidth": 40,
"gfxHeight": 32,
"gfxOffsetX": -4,
"gfxOffsetY": 0,
"frameStyle": 1,
"frames": 1,
"frameSpeed": 6,
"shape": "BOX",
"maxSpeed": 2.0,
"jumpForce": 6.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 60,
"defense": 10,
"attack": 10,
"knockBack": 4,
"knockBackDefense": 0.30,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 5,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"pufferfish_hurt1",
"pufferfish_hurt1",
"pufferfish_hurt2"
],
"loots": [
{
"item": "pufferfish"
},
{
"item": "bone",
"possibility": 0.5
},
{
"item": "bone_meal",
"possibility": 0.5
}
],
"special": 0,
"paticularColor": [ 255, 200, 100, 50 ],
"spawn": "WATER",
"magicRate": 0,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/purple_slime.json
================================================
{
"purple_slime": {
"ai": "Slime",
"textureData": "purple_slime.png",
"type": "NORMAL",
"width": 24,
"height": 24,
"gfxWidth": 32,
"gfxHeight": 32,
"gfxOffsetX": -4,
"gfxOffsetY": -8,
"frameStyle": 1,
"frames": 2,
"frameSpeed": 16,
"shape": "BOX",
"maxSpeed": 4.0,
"jumpForce": 8.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 50,
"defense": 0,
"attack": 7,
"knockBack": 2,
"knockBackDefense": 0.05,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 6,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"slime_attack1",
"slime_attack1",
"slime_attack2"
],
"loots": [
{
"item": "slimeball",
"count": [ 1, 5 ]
}
],
"special": 0,
"paticularColor": [ 255, 60, 0, 60 ],
"spawn": "LAND",
"magicRate": 80,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/ragged_mage.json
================================================
{
"ragged_mage": {
"ai": "RaggedMage",
"textureData": "ragged_mage.png",
"type": "NORMAL",
"width": 28,
"height": 48,
"gfxWidth": 40,
"gfxHeight": 48,
"gfxOffsetX": -6,
"gfxOffsetY": 0,
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 0.0,
"jumpForce": 9.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 130,
"defense": 10,
"attack": 20,
"knockBack": 2,
"knockBackDefense": 0.10,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 10,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"shulker_hit1",
"shulker_hit1"
],
"drops": [
{
"item": "red_crystal",
"min": 0,
"max": 1
},
{
"item": "yellow_crystal",
"min": 0,
"max": 1
}
],
"special": 0,
"paticularColor": [ 255, 33, 33, 33 ],
"spawn": "LAND",
"gore": "gore_evoker",
"magicRate": 25,
"checkPlayerTarget": true,
"visionNoCrossTile": false,
"checkTargetDistance": 720
}
}
================================================
FILE: npcs/red_butterfly.json
================================================
{
"red_butterfly": {
"ai": "Butterfly",
"textureData": "red_butterfly.png",
"type": "ANIMAL",
"width": 16,
"height": 16,
"gfxWidth": 22,
"gfxHeight": 22,
"gfxOffsetX": -3,
"gfxOffsetY": -3,
"frameStyle": 0,
"frames": 1,
"frameSpeed": 6,
"shape": "BOX",
"maxSpeed": 1.0,
"jumpForce": 5.0,
"disappearTime": 750,
"spawnCount": 0.25,
"health": 5,
"defense": 0,
"attack": 1,
"knockBack": 0,
"knockBackDefense": 0.10,
"gravity": false,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": true,
"exps": 0,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"rabbit_hurt1",
"rabbit_hurt1",
"rabbit_hurt2",
"rabbit_hurt3"
],
"loots": [],
"special": 0,
"paticularColor": [ 255, 200, 0, 0 ],
"spawn": "AIR",
"magicRate": 0,
"checkPlayerTarget": false,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/red_mage.json
================================================
{
"red_mage": {
"ai": "RedMage",
"textureData": "red_mage.png",
"type": "NORMAL",
"width": 28,
"height": 48,
"gfxWidth": 40,
"gfxHeight": 48,
"gfxOffsetX": -6,
"gfxOffsetY": 0,
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 0.0,
"jumpForce": 9.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 130,
"defense": 4,
"attack": 10,
"knockBack": 2,
"knockBackDefense": 0.10,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 10,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"shulker_hit1",
"shulker_hit1"
],
"drops": [
{
"item": "emerald",
"min": 0,
"max": 1
},
{
"item": "red_crystal",
"min": 0,
"max": 1
},
{
"item": "yellow_crystal",
"min": 0,
"max": 1
}
],
"special": 0,
"paticularColor": [ 255, 33, 33, 33 ],
"spawn": "LAND",
"gore": "gore_evoker",
"magicRate": 25,
"checkPlayerTarget": true,
"visionNoCrossTile": false,
"checkTargetDistance": 720
}
}
================================================
FILE: npcs/red_mushroom_cow.json
================================================
{
"red_mushroom_cow": {
"ai": "Animal",
"textureData": "red_mushroom_cow.png",
"type": "ANIMAL",
"width": 60,
"height": 60,
"gfxWidth": 64,
"gfxHeight": 72,
"gfxOffsetX": -2,
"gfxOffsetY": -12,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 6,
"shape": "BOX",
"maxSpeed": 1.5,
"jumpForce": 5.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 15,
"defense": 0,
"attack": 1,
"knockBack": 0,
"knockBackDefense": 0.10,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": true,
"exps": 3,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [
"cow_say1",
"cow_say2",
"cow_say3"
],
"hurtSounds": [
"cow_hurt1",
"cow_hurt1",
"cow_hurt2",
"cow_hurt3"
],
"loots": [
{
"item": "raw_beef",
"count": [ 1, 3 ]
},
{
"item": "leather",
"count": [ 1, 3 ],
"possibility": 0.5
},
{
"item": "red_mushroom",
"count": [ 1, 4 ]
}
],
"burnLoots": [
{
"item": "steak",
"count": [ 1, 3 ]
},
{
"item": "leather",
"count": [ 1, 3 ],
"possibility": 0.5
},
{
"item": "red_mushroom",
"count": [ 1, 4 ]
}
],
"special": 0,
"paticularColor": [ 255, 200, 100, 50 ],
"spawn": "LAND",
"gore": "gore_red_mushroom_cow",
"magicRate": 0,
"checkPlayerTarget": false,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/red_phantom.json
================================================
{
"red_phantom": {
"ai": "RedPhantom",
"textureData": "red_phantom.png",
"type": "SMITE",
"width": 32,
"height": 32,
"gfxWidth": 96,
"gfxHeight": 96,
"gfxOffsetX": -32,
"gfxOffsetY": -32,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 3.0,
"jumpForce": 5.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 80,
"defense": 2,
"attack": 18,
"knockBack": 6,
"knockBackDefense": 0.20,
"gravity": false,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 10,
"sunBurning": true,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"phantom_death",
"phantom_hurt1",
"phantom_hurt2",
"phantom_hurt3"
],
"drops": [
{
"item": "phantom_membrane",
"min": 1,
"max": 3
},
{
"item": "dark_shadow_part",
"count": [ 1, 3 ]
}
],
"special": 0,
"paticularColor": [ 255, 50, 50, 50 ],
"spawn": "AIR",
"gore": "gore_phantom",
"magicRate": 25,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/rock_man.json
================================================
{
"rock_man": {
"ai": "RockMan",
"textureData": "rock_man.png",
"type": "SMITE",
"width": 24,
"height": 46,
"gfxWidth": 48,
"gfxHeight": 48,
"gfxOffsetX": 4,
"gfxOffsetY": 8,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 3.5,
"jumpForce": 12.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 100,
"defense": 19,
"attack": 13,
"knockBack": 10,
"knockBackDefense": 0.50,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 22,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"skeleton_death",
"skeleton1",
"skeleton2",
"skeleton3"
],
"drops": [
{
"item": "gold_ingot",
"min": 0,
"max": 1
}
],
"special": 0,
"paticularColor": [ 255, 150, 150, 150 ],
"spawn": "LAND",
"gore": "gore_angry_skeleton",
"magicRate": 25,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/rolling_fire_ball.json
================================================
{
"rolling_fire_ball": {
"ai": "RollingFireBall",
"textureData": "rolling_fire_ball.png",
"type": "SMITE",
"width": 48,
"height": 48,
"gfxWidth": 48,
"gfxHeight": 48,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"frameStyle": 1,
"frames": 1,
"frameSpeed": 6,
"shape": "BOX",
"maxSpeed": 2.0,
"jumpForce": 5.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 120,
"defense": 2,
"attack": 18,
"knockBack": 6,
"knockBackDefense": 0.20,
"gravity": false,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 15,
"sunBurning": false,
"angry": false,
"antiLava": true,
"saySounds": [],
"hurtSounds": [
"gore3",
"gore1",
"gore2"
],
"drops": [
{
"item": "gunpowder",
"min": 2,
"max": 5
}
],
"special": 1,
"paticularColor": [ 255, 200, 100, 50 ],
"spawn": "AIR",
"magicRate": 25,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/sheep.json
================================================
{
"sheep": {
"ai": "Sheep",
"textureData": "sheep.png",
"type": "ANIMAL",
"width": 48,
"height": 40,
"gfxWidth": 64,
"gfxHeight": 48,
"gfxOffsetX": -8,
"gfxOffsetY": -8,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 6,
"shape": "BOX",
"maxSpeed": 1.5,
"jumpForce": 5.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 15,
"defense": 0,
"attack": 1,
"knockBack": 0,
"knockBackDefense": 0.10,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": true,
"exps": 3,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [
"sheep_say1",
"sheep_say2",
"sheep_say3"
],
"hurtSounds": [
"sheep_say1",
"sheep_say1",
"sheep_say2",
"sheep_say3"
],
"loots": [
{
"item": "wool_white",
"count": [ 2, 4 ]
},
{
"item": "raw_mutton",
"count": [ 1, 3 ]
}
],
"burnLoots": [
{
"item": "wool_white",
"count": [ 2, 4 ]
},
{
"item": "cooked_mutton",
"count": [ 1, 3 ]
}
],
"special": 0,
"paticularColor": [ 255, 200, 100, 50 ],
"spawn": "LAND",
"gore": "gore_sheep",
"magicRate": 0,
"checkPlayerTarget": false,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/shulker.json
================================================
{
"shulker": {
"ai": "Shulker",
"textureData": "shulker.png",
"type": "NORMAL",
"width": 32,
"height": 32,
"gfxWidth": 32,
"gfxHeight": 48,
"gfxOffsetX": 0,
"gfxOffsetY": -8,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 1.0,
"jumpForce": 5.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 75,
"defense": 7,
"attack": 17,
"knockBack": 6,
"knockBackDefense": 0.80,
"gravity": false,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 7,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"shulker_hit1",
"shulker_hit1"
],
"loots": [
],
"special": 0,
"paticularColor": [ 255, 120, 100, 80 ],
"spawn": "AIR",
"gore": "gore_shulker",
"magicRate": 25,
"checkPlayerTarget": true,
"visionNoCrossTile": false,
"checkTargetDistance": 666
}
}
================================================
FILE: npcs/skeleton.json
================================================
{
"skeleton": {
"ai": "BoneArcher",
"textureData": "skeleton.png",
"type": "SMITE",
"width": 24,
"height": 46,
"gfxWidth": 48,
"gfxHeight": 48,
"gfxOffsetX": 4,
"gfxOffsetY": 8,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 1.5,
"jumpForce": 8.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 50,
"defense": 6,
"attack": 12,
"knockBack": 5,
"knockBackDefense": 0.50,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 5,
"sunBurning": true,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"skeleton_death",
"skeleton1",
"skeleton2",
"skeleton3"
],
"loots": [
{
"item": "bone",
"min": 0,
"max": 2
},
{
"item": "wooden_arrow",
"min": 0,
"max": 2
}
],
"special": 0,
"paticularColor": [ 255, 150, 150, 150 ],
"spawn": "LAND",
"gore": "gore_skull",
"magicRate": 25,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/skeleton_assaulter.json
================================================
{
"skeleton_assaulter": {
"ai": "SkeletonAssaulter",
"textureData": "skeleton_assaulter.png",
"type": "SMITE",
"width": 24,
"height": 46,
"gfxWidth": 48,
"gfxHeight": 48,
"gfxOffsetX": 4,
"gfxOffsetY": 8,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 1.5,
"jumpForce": 8.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 100,
"defense": 6,
"attack": 30,
"knockBack": 2,
"knockBackDefense": 0.50,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 25,
"sunBurning": true,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"skeleton_death",
"skeleton1",
"skeleton2",
"skeleton3"
],
"drops": [
{
"item": "bone",
"min": 0,
"max": 2
},
{
"item": "wooden_arrow",
"min": 0,
"max": 2
}
],
"special": 0,
"paticularColor": [ 255, 150, 150, 150 ],
"spawn": "LAND",
"gore": "gore_skeleton_assaulter",
"magicRate": 25,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/skeleton_blue_armed.json
================================================
{
"skeleton_blue_armed": {
"ai": "DungeonSkeleton",
"textureData": "skeleton_blue_armed.png",
"type": "SMITE",
"width": 24,
"height": 46,
"gfxWidth": 48,
"gfxHeight": 48,
"gfxOffsetX": 4,
"gfxOffsetY": 8,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 1.5,
"jumpForce": 8.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 100,
"defense": 7,
"attack": 12,
"knockBack": 5,
"knockBackDefense": 0.50,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 15,
"sunBurning": true,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"skeleton_death",
"skeleton1",
"skeleton2",
"skeleton3"
],
"drops": [
{
"item": "bone",
"min": 0,
"max": 2
},
{
"item": "wooden_arrow",
"min": 0,
"max": 2
},
{
"item": "iron_ingot",
"min": 0,
"max": 1
}
],
"special": 0,
"paticularColor": [ 255, 150, 150, 150 ],
"spawn": "LAND",
"gore": "gore_skeleton_blue_armed",
"magicRate": 25,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/skeleton_blue_armed_masked.json
================================================
{
"skeleton_blue_armed_masked": {
"ai": "DungeonSkeleton",
"textureData": "skeleton_blue_armed_masked.png",
"type": "SMITE",
"width": 24,
"height": 46,
"gfxWidth": 48,
"gfxHeight": 48,
"gfxOffsetX": 4,
"gfxOffsetY": 8,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 1.5,
"jumpForce": 8.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 110,
"defense": 7,
"attack": 12,
"knockBack": 5,
"knockBackDefense": 0.50,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 15,
"sunBurning": true,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"skeleton_death",
"skeleton1",
"skeleton2",
"skeleton3"
],
"drops": [
{
"item": "bone",
"min": 0,
"max": 2
},
{
"item": "wooden_arrow",
"min": 0,
"max": 2
},
{
"item": "tin_ingot",
"min": 0,
"max": 1
}
],
"special": 0,
"paticularColor": [ 255, 150, 150, 150 ],
"spawn": "LAND",
"gore": "gore_skeleton_blue_armed_masked",
"magicRate": 25,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/skeleton_blue_knight.json
================================================
{
"skeleton_blue_knight": {
"ai": "DungeonSkeleton",
"textureData": "skeleton_blue_knight.png",
"type": "SMITE",
"width": 24,
"height": 46,
"gfxWidth": 48,
"gfxHeight": 48,
"gfxOffsetX": 4,
"gfxOffsetY": 8,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 1.5,
"jumpForce": 12.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 120,
"defense": 16,
"attack": 18,
"knockBack": 5,
"knockBackDefense": 0.50,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 15,
"sunBurning": true,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"skeleton_death",
"skeleton1",
"skeleton2",
"skeleton3"
],
"drops": [
{
"item": "bone",
"min": 0,
"max": 2
},
{
"item": "wooden_arrow",
"min": 0,
"max": 2
},
{
"item": "knight_ingot",
"min": 1,
"max": 2
}
],
"special": 0,
"paticularColor": [ 255, 150, 150, 150 ],
"spawn": "LAND",
"gore": "gore_skeleton_blue_knight",
"magicRate": 25,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/skeleton_fire_armed.json
================================================
{
"skeleton_fire_armed": {
"ai": "DungeonSkeleton",
"textureData": "skeleton_fire_armed.png",
"type": "SMITE",
"width": 24,
"height": 46,
"gfxWidth": 48,
"gfxHeight": 48,
"gfxOffsetX": 4,
"gfxOffsetY": 8,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 3.5,
"jumpForce": 8.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 150,
"defense": 13,
"attack": 24,
"knockBack": 5,
"knockBackDefense": 0.50,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 15,
"sunBurning": true,
"angry": false,
"antiLava": true,
"saySounds": [],
"hurtSounds": [
"skeleton_death",
"skeleton1",
"skeleton2",
"skeleton3"
],
"drops": [
{
"item": "bone",
"min": 0,
"max": 2
},
{
"item": "wooden_arrow",
"min": 0,
"max": 2
}
],
"special": 0,
"paticularColor": [ 255, 150, 150, 150 ],
"spawn": "LAND",
"gore": "gore_skeleton_fire_armed",
"magicRate": 25,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/skeleton_fire_armed_swordsman.json
================================================
{
"skeleton_fire_armed_swordsman": {
"ai": "DungeonSkeleton",
"textureData": "skeleton_fire_armed_swordsman.png",
"type": "SMITE",
"width": 24,
"height": 46,
"gfxWidth": 48,
"gfxHeight": 48,
"gfxOffsetX": 4,
"gfxOffsetY": 8,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 2.5,
"jumpForce": 8.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 130,
"defense": 8,
"attack": 28,
"knockBack": 5,
"knockBackDefense": 0.50,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 15,
"sunBurning": true,
"angry": false,
"antiLava": true,
"saySounds": [],
"hurtSounds": [
"skeleton_death",
"skeleton1",
"skeleton2",
"skeleton3"
],
"drops": [
{
"item": "bone",
"min": 0,
"max": 2
},
{
"item": "iron_ingot",
"min": 0,
"max": 1
}
],
"special": 0,
"paticularColor": [ 255, 150, 150, 150 ],
"spawn": "LAND",
"gore": "gore_skeleton_fire_armed_swordsman",
"magicRate": 25,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/skeleton_guard.json
================================================
{
"skeleton_guard": {
"ai": "SkeletonGuard",
"textureData": "skeleton_guard.png",
"type": "SMITE",
"width": 24,
"height": 46,
"gfxWidth": 48,
"gfxHeight": 48,
"gfxOffsetX": 4,
"gfxOffsetY": 8,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 1.5,
"jumpForce": 8.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 80,
"defense": 6,
"attack": 12,
"knockBack": 5,
"knockBackDefense": 0.50,
"gravity": false,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 15,
"sunBurning": true,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"skeleton_death",
"skeleton1",
"skeleton2",
"skeleton3"
],
"drops": [
{
"item": "bone",
"min": 0,
"max": 5
},
{
"item": "wooden_arrow",
"min": 0,
"max": 2
}
],
"special": 0,
"paticularColor": [ 255, 150, 150, 150 ],
"spawn": "LAND",
"gore": "gore_skeleton_guard",
"magicRate": 25,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/small_fire_hell_eater.json
================================================
{
"small_fire_hell_eater": {
"ai": "FireHellEater",
"textureData": "small_fire_hell_eater.png",
"type": "NORMAL",
"width": 32,
"height": 32,
"gfxWidth": 48,
"gfxHeight": 32,
"gfxOffsetX": -8,
"gfxOffsetY": 0,
"frameStyle": 0,
"frames": 2,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 4.0,
"jumpForce": 5.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 8,
"defense": 6,
"attack": 16,
"knockBack": 4,
"knockBackDefense": 0.10,
"gravity": false,
"climbWall": false,
"foreground": true,
"noFixByBlock": true,
"friendly": false,
"exps": 5,
"sunBurning": false,
"angry": false,
"antiLava": true,
"saySounds": [],
"hurtSounds": [
"gore3",
"gore1",
"gore2"
],
"loots": [],
"special": 2,
"paticularColor": [ 255, 50, 50, 20 ],
"spawn": "AIR",
"gore": "gore_small_hell_eater",
"magicRate": 200,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/small_hell_eater.json
================================================
{
"small_hell_eater": {
"ai": "HellEater",
"textureData": "small_hell_eater.png",
"type": "NORMAL",
"width": 32,
"height": 32,
"gfxWidth": 48,
"gfxHeight": 32,
"gfxOffsetX": -8,
"gfxOffsetY": 0,
"frameStyle": 0,
"frames": 2,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 3.5,
"jumpForce": 5.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 10,
"defense": 6,
"attack": 16,
"knockBack": 4,
"knockBackDefense": 0.10,
"gravity": false,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 5,
"sunBurning": false,
"angry": false,
"antiLava": true,
"saySounds": [],
"hurtSounds": [
"gore3",
"gore1",
"gore2"
],
"loots": [],
"special": 1,
"paticularColor": [ 255, 50, 50, 20 ],
"spawn": "AIR",
"gore": "gore_small_hell_eater",
"magicRate": 200,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/snow_guardian.json
================================================
{
"snow_guardian": {
"ai": "SnowGuardian",
"textureData": "snow_guardian.png",
"type": "SMITE",
"width": 24,
"height": 46,
"gfxWidth": 48,
"gfxHeight": 48,
"gfxOffsetX": 4,
"gfxOffsetY": 8,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 2.0,
"jumpForce": 9.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 45,
"defense": 6,
"attack": 16,
"knockBack": 5,
"knockBackDefense": 0.50,
"gravity": false,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 8,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"gore3",
"gore1",
"gore2"
],
"loots": [
{
"item": "ice_element"
}
],
"special": 1,
"paticularColor": [ 255, 200, 50, 20 ],
"spawn": "AIR",
"spawnWall": "aurora_block",
"magicRate": 100,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/snow_guardian_archer.json
================================================
{
"snow_guardian_archer": {
"ai": "SnowGuardianArcher",
"textureData": "snow_guardian.png",
"type": "SMITE",
"width": 24,
"height": 46,
"gfxWidth": 48,
"gfxHeight": 48,
"gfxOffsetX": 4,
"gfxOffsetY": 8,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 1.0,
"jumpForce": 9.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 45,
"defense": 6,
"attack": 16,
"knockBack": 5,
"knockBackDefense": 0.50,
"gravity": false,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 8,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"gore3",
"gore1",
"gore2"
],
"loots": [],
"special": 1,
"paticularColor": [ 255, 200, 50, 20 ],
"spawn": "AIR",
"spawnWall": "aurora_block",
"magicRate": 100,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/snow_queen.json
================================================
{
"snow_queen": {
"ai": "SnowQueen",
"textureData": "snow_queen.png",
"type": "SMITE",
"width": 24,
"height": 46,
"gfxWidth": 48,
"gfxHeight": 48,
"gfxOffsetX": 4,
"gfxOffsetY": 8,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 1.0,
"jumpForce": 9.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 2100,
"defense": 6,
"attack": 20,
"knockBack": 5,
"knockBackDefense": 0.50,
"gravity": false,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 350,
"sunBurning": false,
"angry": false,
"antiLava": true,
"saySounds": [],
"hurtSounds": [
"gore3",
"gore1",
"gore2"
],
"loots": [
{
"item": "snow_queen_loot"
},
{
"item": "ice_bow"
},
{
"item": "blue_ice",
"count": [ 12, 16 ]
},
{
"item": "diamond",
"count": [ 1, 2 ]
},
{
"item": "ice_element",
"count": [ 32, 48 ]
}
],
"special": 0,
"paticularColor": [ 255, 200, 50, 20 ],
"spawn": "LAND",
"isBoss": true,
"noShowHp": true,
"magicRate": 1,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/snow_slime.json
================================================
{
"snow_slime": {
"ai": "Slime",
"textureData": "snow_slime.png",
"type": "NORMAL",
"width": 24,
"height": 24,
"gfxWidth": 32,
"gfxHeight": 32,
"gfxOffsetX": -4,
"gfxOffsetY": -8,
"frameStyle": 1,
"frames": 2,
"frameSpeed": 16,
"shape": "BOX",
"maxSpeed": 3.0,
"jumpForce": 8.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 16,
"defense": 0,
"attack": 4,
"knockBack": 2,
"knockBackDefense": 0.05,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 5,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"slime_attack1",
"slime_attack1",
"slime_attack2"
],
"loots": [
{
"item": "slimeball",
"count": [ 1, 2 ]
}
],
"special": 0,
"paticularColor": [ 255, 160, 220, 255 ],
"spawn": "LAND",
"magicRate": 80,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/spider.json
================================================
{
"spider": {
"ai": "Fighter",
"textureData": "spider.png",
"type": "ARTHROPODS",
"width": 32,
"height": 28,
"gfxWidth": 48,
"gfxHeight": 32,
"gfxOffsetX": -8,
"gfxOffsetY": -4,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 2.0,
"jumpForce": 6.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 40,
"defense": 6,
"attack": 8,
"knockBack": 3,
"knockBackDefense": 0.30,
"gravity": true,
"climbWall": true,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 5,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [
"spider_say1",
"spider_say2",
"spider_say3"
],
"hurtSounds": [
"spider_death",
"spider_say1",
"spider_say2",
"spider_say3"
],
"loots": [
{
"item": "string",
"count": [ 1, 4 ]
},
{
"item": "spider_eye",
"count": [ 1, 2 ],
"possibility": 0.5
}
],
"special": 0,
"paticularColor": [ 255, 50, 50, 20 ],
"spawn": "LAND",
"gore": "gore_spider",
"magicRate": 30,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/squid.json
================================================
{
"squid": {
"ai": "Squid",
"textureData": "squid.png",
"type": "ANIMAL",
"width": 20,
"height": 20,
"gfxWidth": 32,
"gfxHeight": 48,
"gfxOffsetX": -6,
"gfxOffsetY": -14,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 6,
"shape": "BOX",
"maxSpeed": 2.0,
"jumpForce": 5.0,
"disappearTime": 750,
"spawnCount": 0.25,
"health": 10,
"defense": 0,
"attack": 1,
"knockBack": 0,
"knockBackDefense": 0.10,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": true,
"exps": 3,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"rabbit_hurt1",
"rabbit_hurt1",
"rabbit_hurt2",
"rabbit_hurt3"
],
"loots": [
{
"item": "ink_sac",
"count": [ 2, 4 ]
}
],
"special": 0,
"paticularColor": [ 255, 200, 100, 50 ],
"spawn": "WATER",
"gore": "gore_squid",
"magicRate": 0,
"checkPlayerTarget": false,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/tainted_creeper.json
================================================
{
"tainted_creeper": {
"ai": "Creeper",
"textureData": "tainted_creeper.png",
"type": "NORMAL",
"width": 24,
"height": 50,
"gfxWidth": 32,
"gfxHeight": 64,
"gfxOffsetX": -4,
"gfxOffsetY": -14,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 2.0,
"jumpForce": 8.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 60,
"defense": 8,
"attack": 10,
"knockBack": 2,
"knockBackDefense": 0.15,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 5,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"creeper_death",
"creeper1",
"creeper2",
"creeper3"
],
"loots": [
{
"item": "gunpowder",
"count": [ 8, 12 ]
},
{
"item": "magic_cell",
"count": [ 2, 3 ]
},
{
"item": "dark_shadow_part",
"count": [ 1, 3 ]
}
],
"special": 0,
"paticularColor": [ 255, 200, 50, 20 ],
"spawn": "LAND",
"gore": "gore_tainted_creeper",
"magicRate": 22,
"checkPlayerTarget": true,
"visionNoCrossTile": true
}
}
================================================
FILE: npcs/tainted_skeleton.json
================================================
{
"tainted_skeleton": {
"ai": "BoneArcher",
"textureData": "tainted_skeleton.png",
"type": "SMITE",
"width": 24,
"height": 46,
"gfxWidth": 48,
"gfxHeight": 48,
"gfxOffsetX": 4,
"gfxOffsetY": 8,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 1.5,
"jumpForce": 8.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 60,
"defense": 6,
"attack": 14,
"knockBack": 5,
"knockBackDefense": 0.50,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 7,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"skeleton_death",
"skeleton1",
"skeleton2",
"skeleton3"
],
"loots": [
{
"item": "bone",
"min": 0,
"max": 2
},
{
"item": "fire_bullet",
"min": 0,
"max": 6
},
{
"item": "dark_shadow_part",
"count": [ 1, 3 ]
}
],
"special": 0,
"paticularColor": [ 255, 150, 150, 150 ],
"spawn": "LAND",
"gore": "gore_tainted_skeleton",
"magicRate": 25,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/tainted_slime.json
================================================
{
"tainted_slime": {
"ai": "TaintedSlime",
"textureData": "tainted_slime.png",
"type": "NORMAL",
"width": 24,
"height": 24,
"gfxWidth": 32,
"gfxHeight": 32,
"gfxOffsetX": -4,
"gfxOffsetY": -8,
"frameStyle": 1,
"frames": 2,
"frameSpeed": 16,
"shape": "BOX",
"maxSpeed": 4.0,
"jumpForce": 12.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 50,
"defense": 0,
"attack": 8,
"knockBack": 2,
"knockBackDefense": 0.05,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 5,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"slime_attack1",
"slime_attack1",
"slime_attack2"
],
"loots": [
{
"item": "slimeball",
"count": [ 1, 6 ]
}
],
"special": 1,
"paticularColor": [ 255, 155, 88, 226 ],
"spawn": "LAND",
"magicRate": 80,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/turtle.json
================================================
{
"turtle": {
"ai": "Animal",
"textureData": "turtle.png",
"type": "ANIMAL",
"width": 32,
"height": 24,
"gfxWidth": 48,
"gfxHeight": 32,
"gfxOffsetX": -8,
"gfxOffsetY": -8,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 6,
"shape": "BOX",
"maxSpeed": 0.5,
"jumpForce": 5.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 35,
"defense": 10,
"attack": 1,
"knockBack": 0,
"knockBackDefense": 0.50,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": true,
"exps": 3,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"turtle_death",
"turtle_hurt1",
"turtle_hurt2",
"turtle_hurt3"
],
"loots": [
{
"item": "scute",
"count": [ 1, 4 ]
},
{
"item": "kelp",
"count": [ 1, 3 ],
"possibility": 0.5
}
],
"special": 0,
"paticularColor": [ 255, 200, 100, 50 ],
"spawn": "LAND",
"gore": "gore_turtle",
"magicRate": 0,
"checkPlayerTarget": false,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/undead_miner.json
================================================
{
"undead_miner": {
"ai": "UndeadMiner",
"textureData": "undead_miner.png",
"type": "SMITE",
"width": 24,
"height": 46,
"gfxWidth": 48,
"gfxHeight": 48,
"gfxOffsetX": 4,
"gfxOffsetY": 8,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 1.5,
"jumpForce": 8.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 70,
"defense": 7,
"attack": 14,
"knockBack": 5,
"knockBackDefense": 0.50,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 5,
"sunBurning": true,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"skeleton_death",
"skeleton1",
"skeleton2",
"skeleton3"
],
"drops": [
{
"item": "bone",
"min": 0,
"max": 2
},
{
"item": "iron_pickaxe",
"min": 0,
"max": 1
},
{
"item": "flesh_part",
"min": 0,
"max": 2
}
],
"special": 0,
"paticularColor": [ 255, 150, 150, 150 ],
"spawn": "LAND",
"gore": "gore_undead_miner",
"magicRate": 25,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/vampire_miner.json
================================================
{
"vampire_miner": {
"ai": "Zombie",
"textureData": "vampire_miner.png",
"type": "SMITE",
"width": 24,
"height": 46,
"gfxWidth": 48,
"gfxHeight": 48,
"gfxOffsetX": 4,
"gfxOffsetY": 8,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 2.5,
"jumpForce": 8.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 120,
"defense": 7,
"attack": 22,
"knockBack": 5,
"knockBackDefense": 0.50,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 15,
"sunBurning": true,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"zombie_death",
"zombie_hurt1",
"zombie_hurt2"
],
"drops": [
{
"item": "blood",
"min": 0,
"max": 2
}
],
"special": 0,
"paticularColor": [ 255, 150, 150, 150 ],
"spawn": "LAND",
"gore": "gore_vampire_miner",
"magicRate": 25,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/villager_zombie.json
================================================
{
"villager_zombie": {
"ai": "Zombie",
"textureData": "villager_zombie.png",
"type": "SMITE",
"width": 24,
"height": 46,
"gfxWidth": 48,
"gfxHeight": 48,
"gfxOffsetX": 4,
"gfxOffsetY": 8,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 1.0,
"jumpForce": 9.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 45,
"defense": 6,
"attack": 14,
"knockBack": 5,
"knockBackDefense": 0.50,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 5,
"sunBurning": true,
"angry": false,
"antiLava": false,
"saySounds": [
"zombie_say1",
"zombie_say2",
"zombie_say3"
],
"hurtSounds": [
"zombie_death",
"zombie_hurt1",
"zombie_hurt2"
],
"noBurnSound": true,
"loots": [
{
"item": "rotten_flesh",
"count": [ 1, 4 ]
}
],
"special": 0,
"paticularColor": [ 255, 200, 50, 20 ],
"spawn": "LAND",
"gore": "gore_villager_zombie",
"magicRate": 30,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/vine_man_eater_body.json
================================================
{
"vine_man_eater_body": {
"ai": "Snake_Body",
"textureData": "vine_man_eater_body.png",
"type": "ARTHROPODS",
"width": 44,
"height": 32,
"gfxWidth": 44,
"gfxHeight": 32,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "ROTATED_BOX",
"maxSpeed": 5.0,
"jumpForce": 1.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 10,
"defense": 10,
"attack": 10,
"knockBack": 10,
"knockBackDefense": 99.0,
"gravity": false,
"climbWall": false,
"foreground": false,
"noFixByBlock": true,
"friendly": false,
"exps": 7,
"sunBurning": false,
"angry": false,
"antiLava": true,
"linkNpcId": "vine_man_eater_tail",
"linkValue": 36,
"saySounds": [],
"hurtSounds": [],
"loots": [],
"special": 0,
"paticularColor": [ 255, 100, 100, 100 ],
"spawn": "AIR",
"noShowHp": true
}
}
================================================
FILE: npcs/vine_man_eater_head.json
================================================
{
"vine_man_eater_head": {
"ai": "JungleSnake_Head",
"textureData": "vine_man_eater_head.png",
"type": "ARTHROPODS",
"width": 50,
"height": 32,
"gfxWidth": 50,
"gfxHeight": 32,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "ROTATED_BOX",
"maxSpeed": 3.0,
"jumpForce": 1.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 20,
"defense": 10,
"attack": 10,
"knockBack": 10,
"knockBackDefense": 99.0,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": true,
"friendly": false,
"exps": 20,
"sunBurning": false,
"angry": false,
"antiLava": true,
"linkNpcId": "vine_man_eater_body",
"linkValue": 34,
"linkCount": 24,
"saySounds": [],
"hurtSounds": [],
"loots": [],
"special": 0,
"paticularColor": [ 255, 100, 100, 100 ],
"spawn": "AIR",
"magicRate": 10
}
}
================================================
FILE: npcs/vine_man_eater_tail.json
================================================
{
"vine_man_eater_tail": {
"ai": "Snake_Body",
"textureData": "vine_man_eater_tail.png",
"type": "ARTHROPODS",
"width": 54,
"height": 40,
"gfxWidth": 54,
"gfxHeight": 40,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "ROTATED_BOX",
"maxSpeed": 5.0,
"jumpForce": 1.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 10,
"defense": 10,
"attack": 10,
"knockBack": 10,
"knockBackDefense": 1.0,
"gravity": false,
"climbWall": false,
"foreground": false,
"noFixByBlock": true,
"friendly": false,
"exps": 7,
"sunBurning": false,
"angry": false,
"antiLava": true,
"linkValue": 46,
"saySounds": [],
"hurtSounds": [],
"loots": [],
"special": 0,
"paticularColor": [ 255, 100, 100, 100 ],
"spawn": "AIR",
"noShowHp": true
}
}
================================================
FILE: npcs/waste_block_slime.json
================================================
{
"waste_block_slime": {
"ai": "BlockSlime",
"textureData": "waste_block_slime.png",
"type": "NORMAL",
"width": 24,
"height": 24,
"gfxWidth": 32,
"gfxHeight": 32,
"gfxOffsetX": -4,
"gfxOffsetY": -8,
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 2.0,
"jumpForce": 8.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 20,
"defense": 0,
"attack": 5,
"knockBack": 2,
"knockBackDefense": 0.03,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 4,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"slime_attack1",
"slime_attack1",
"slime_attack2"
],
"loots": [
{
"item": "slimeball",
"min": 1,
"max": 2
}
],
"special": 0,
"paticularColor": [ 255, 160, 100, 60 ],
"spawn": "LAND",
"magicRate": 80,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/waste_ghost.json
================================================
{
"waste_ghost": {
"ai": "WasteGhost",
"textureData": "waste_ghost.png",
"type": "SMITE",
"width": 38,
"height": 38,
"gfxWidth": 38,
"gfxHeight": 38,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"maxSpeed": 2.0,
"jumpForce": 5.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 40,
"defense": 10,
"attack": 7,
"knockBack": 5,
"knockBackDefense": 0.10,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 5,
"sunBurning": false,
"angry": false,
"antiLava": true,
"saySounds": [],
"hurtSounds": [
"gore3",
"gore1",
"gore2"
],
"loots": [],
"special": 0,
"paticularColor": [ 255, 200, 100, 50 ],
"spawn": "AIR",
"magicRate": 50,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/waste_mummy.json
================================================
{
"waste_mummy": {
"ai": "Zombie",
"textureData": "waste_mummy.png",
"type": "SMITE",
"width": 24,
"height": 46,
"gfxWidth": 48,
"gfxHeight": 48,
"gfxOffsetX": 4,
"gfxOffsetY": 8,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 1.0,
"jumpForce": 9.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 45,
"defense": 6,
"attack": 14,
"knockBack": 5,
"knockBackDefense": 0.50,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 5,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [
"zombie_say1",
"zombie_say2",
"zombie_say3"
],
"hurtSounds": [
"zombie_death",
"zombie_hurt1",
"zombie_hurt2"
],
"noBurnSound": true,
"loots": [
{
"item": "rotten_flesh",
"count": [ 1, 4 ]
},
{
"item": "string",
"min": 1,
"max": 4
}
],
"special": 0,
"paticularColor": [ 255, 200, 50, 20 ],
"spawn": "LAND",
"gore": "gore_waste_mummy",
"magicRate": 30,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/white_rabbit.json
================================================
{
"white_rabbit": {
"ai": "Animal",
"textureData": "white_rabbit.png",
"type": "ANIMAL",
"width": 24,
"height": 24,
"gfxWidth": 32,
"gfxHeight": 32,
"gfxOffsetX": -4,
"gfxOffsetY": -8,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 6,
"shape": "BOX",
"maxSpeed": 1.0,
"jumpForce": 6.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 10,
"defense": 0,
"attack": 1,
"knockBack": 0,
"knockBackDefense": 0.10,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": true,
"exps": 2,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"rabbit_hurt1",
"rabbit_hurt1",
"rabbit_hurt2",
"rabbit_hurt3"
],
"loots": [
{
"item": "rabbit_foot",
"possibility": 0.5
},
{
"item": "rabbit_hide",
"count": [ 1, 2 ]
},
{
"item": "raw_rabbit",
"possibility": 0.5
}
],
"burnLoots": [
{
"item": "rabbit_foot",
"possibility": 0.5
},
{
"item": "rabbit_hide",
"count": [ 1, 2 ]
},
{
"item": "cooked_rabbit",
"possibility": 0.5
}
],
"special": 0,
"paticularColor": [ 255, 200, 100, 50 ],
"spawn": "LAND",
"gore": "gore_white_rabbit",
"magicRate": 0,
"checkPlayerTarget": false,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/wither_skeleton.json
================================================
{
"wither_skeleton": {
"ai": "WitherSkeleton",
"textureData": "wither_skeleton.png",
"type": "SMITE",
"width": 24,
"height": 64,
"gfxWidth": 48,
"gfxHeight": 48,
"gfxOffsetX": 4,
"gfxOffsetY": 10,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 1.5,
"jumpForce": 9.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 100,
"defense": 13,
"attack": 20,
"knockBack": 7,
"knockBackDefense": 0.60,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 10,
"sunBurning": false,
"angry": false,
"antiLava": true,
"saySounds": [],
"hurtSounds": [
"skeleton_death",
"skeleton1",
"skeleton2",
"skeleton3"
],
"loots": [
{
"item": "bone",
"min": 0,
"max": 2
},
{
"item": "coal",
"min": 0,
"max": 2
}
],
"special": 0,
"paticularColor": [ 255, 33, 33, 33 ],
"spawn": "LAND",
"gore": "gore_wither_skeleton",
"magicRate": 25,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/wolf.json
================================================
{
"wolf": {
"ai": "Wolf",
"textureData": "wolf.png",
"type": "ANIMAL",
"width": 48,
"height": 48,
"gfxWidth": 80,
"gfxHeight": 64,
"gfxOffsetX": -16,
"gfxOffsetY": -16,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 6.0,
"jumpForce": 8.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 40,
"defense": 5,
"attack": 5,
"knockBack": 5,
"knockBackDefense": 0.35,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": true,
"exps": 5,
"sunBurning": false,
"angry": true,
"antiLava": false,
"saySounds": [
"wolf_bark1",
"wolf_bark2",
"wolf_bark3"
],
"hurtSounds": [
"wolf_death",
"wolf_hurt1",
"wolf_hurt2",
"wolf_hurt3"
],
"loots": [
{
"item": "leather",
"count": [ 1, 3 ]
}
],
"special": 0,
"paticularColor": [ 255, 200, 100, 50 ],
"spawn": "LAND",
"magicRate": 0,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/worm_body.json
================================================
{
"worm_body": {
"ai": "Snake_Body",
"textureData": "worm_body.png",
"type": "ARTHROPODS",
"width": 46,
"height": 52,
"gfxWidth": 46,
"gfxHeight": 52,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "ROTATED_BOX",
"maxSpeed": 5.0,
"jumpForce": 1.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 80,
"defense": 5,
"attack": 25,
"knockBack": 10,
"knockBackDefense": 1.0,
"gravity": false,
"climbWall": false,
"foreground": false,
"noFixByBlock": true,
"friendly": false,
"exps": 7,
"sunBurning": false,
"angry": false,
"antiLava": true,
"saySounds": [],
"hurtSounds": [],
"loots": [],
"special": 0,
"paticularColor": [ 255, 100, 100, 100 ],
"spawn": "AIR",
"noShowHp": true,
"gore": "gore_worm_body"
}
}
================================================
FILE: npcs/worm_head.json
================================================
{
"worm_head": {
"ai": "HellDestroyer_Head",
"textureData": "worm_head.png",
"type": "ARTHROPODS",
"width": 78,
"height": 52,
"gfxWidth": 78,
"gfxHeight": 52,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "ROTATED_BOX",
"maxSpeed": 5.0,
"jumpForce": 1.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 2800,
"defense": 5,
"attack": 25,
"knockBack": 10,
"knockBackDefense": 0.9,
"gravity": false,
"climbWall": false,
"foreground": false,
"noFixByBlock": true,
"friendly": false,
"exps": 400,
"sunBurning": false,
"angry": false,
"antiLava": true,
"saySounds": [],
"hurtSounds": [
"attack1",
"attack2"
],
"loots": [
{
"item": "nether_destroyer_loot"
},
{
"item": "super_air_sword"
},
{
"item": "dungeon_eater"
},
{
"item": "ancient_sample",
"count": [ 3, 4 ]
},
{
"item": "netherite_ingot",
"count": [ 2, 3 ]
}
],
"special": 0,
"paticularColor": [ 255, 100, 100, 100 ],
"spawn": "AIR",
"isBoss": true,
"noShowHp": true,
"gore": "gore_worm_head",
"magicRate": 1,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/worm_tail.json
================================================
{
"worm_tail": {
"ai": "Snake_Body",
"textureData": "worm_tail.png",
"type": "ARTHROPODS",
"width": 60,
"height": 64,
"gfxWidth": 60,
"gfxHeight": 64,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "ROTATED_BOX",
"maxSpeed": 5.0,
"jumpForce": 1.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 80,
"defense": 5,
"attack": 25,
"knockBack": 10,
"knockBackDefense": 1.0,
"gravity": false,
"climbWall": false,
"foreground": false,
"noFixByBlock": true,
"friendly": false,
"exps": 7,
"sunBurning": false,
"angry": false,
"antiLava": true,
"saySounds": [],
"hurtSounds": [],
"loots": [],
"special": 0,
"paticularColor": [ 255, 100, 100, 100 ],
"spawn": "AIR",
"noShowHp": true,
"gore": "gore_worm_tail"
}
}
================================================
FILE: npcs/yellow_butterfly.json
================================================
{
"yellow_butterfly": {
"ai": "Butterfly",
"textureData": "yellow_butterfly.png",
"type": "ANIMAL",
"width": 16,
"height": 16,
"gfxWidth": 22,
"gfxHeight": 22,
"gfxOffsetX": -3,
"gfxOffsetY": -3,
"frameStyle": 0,
"frames": 1,
"frameSpeed": 6,
"shape": "BOX",
"maxSpeed": 1.0,
"jumpForce": 5.0,
"disappearTime": 750,
"spawnCount": 0.25,
"health": 5,
"defense": 0,
"attack": 1,
"knockBack": 0,
"knockBackDefense": 0.10,
"gravity": false,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": true,
"exps": 0,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"rabbit_hurt1",
"rabbit_hurt1",
"rabbit_hurt2",
"rabbit_hurt3"
],
"loots": [],
"special": 0,
"paticularColor": [ 255, 200, 200, 0 ],
"spawn": "AIR",
"magicRate": 0,
"checkPlayerTarget": false,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/yellow_rabbit.json
================================================
{
"yellow_rabbit": {
"ai": "Animal",
"textureData": "yellow_rabbit.png",
"type": "ANIMAL",
"width": 24,
"height": 24,
"gfxWidth": 32,
"gfxHeight": 32,
"gfxOffsetX": -4,
"gfxOffsetY": -8,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 6,
"shape": "BOX",
"maxSpeed": 1.0,
"jumpForce": 6.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 10,
"defense": 0,
"attack": 1,
"knockBack": 0,
"knockBackDefense": 0.10,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": true,
"exps": 2,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"rabbit_hurt1",
"rabbit_hurt1",
"rabbit_hurt2",
"rabbit_hurt3"
],
"loots": [
{
"item": "rabbit_foot",
"possibility": 0.5
},
{
"item": "rabbit_hide",
"count": [ 1, 2 ]
},
{
"item": "raw_rabbit",
"possibility": 0.5
}
],
"burnLoots": [
{
"item": "rabbit_foot",
"possibility": 0.5
},
{
"item": "rabbit_hide",
"count": [ 1, 2 ]
},
{
"item": "cooked_rabbit",
"possibility": 0.5
}
],
"special": 0,
"paticularColor": [ 255, 200, 100, 50 ],
"spawn": "LAND",
"gore": "gore_yellow_rabbit",
"magicRate": 0,
"checkPlayerTarget": false,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/yellow_slime.json
================================================
{
"yellow_slime": {
"ai": "Slime",
"textureData": "yellow_slime.png",
"type": "NORMAL",
"width": 24,
"height": 24,
"gfxWidth": 32,
"gfxHeight": 32,
"gfxOffsetX": -4,
"gfxOffsetY": -8,
"frameStyle": 1,
"frames": 2,
"frameSpeed": 16,
"shape": "BOX",
"maxSpeed": 3.0,
"jumpForce": 9.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 24,
"defense": 0,
"attack": 5,
"knockBack": 2,
"knockBackDefense": 0.05,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 5,
"sunBurning": false,
"angry": false,
"antiLava": false,
"saySounds": [],
"hurtSounds": [
"slime_attack1",
"slime_attack1",
"slime_attack2"
],
"loots": [
{
"item": "slimeball",
"count": [ 1, 3 ]
}
],
"special": 0,
"paticularColor": [ 255, 160, 160, 0 ],
"spawn": "LAND",
"magicRate": 80,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: npcs/zombie.json
================================================
{
"zombie": {
"ai": "Zombie",
"textureData": "zombie.png",
"type": "SMITE",
"width": 24,
"height": 46,
"gfxWidth": 48,
"gfxHeight": 48,
"gfxOffsetX": 4,
"gfxOffsetY": 8,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 1.0,
"jumpForce": 9.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 45,
"defense": 6,
"attack": 14,
"knockBack": 5,
"knockBackDefense": 0.50,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": false,
"exps": 5,
"sunBurning": true,
"angry": false,
"antiLava": false,
"saySounds": [
"zombie_say1",
"zombie_say2",
"zombie_say3"
],
"hurtSounds": [
"zombie_death",
"zombie_hurt1",
"zombie_hurt2"
],
"noBurnSound": true,
"loots": [
{
"item": "rotten_flesh",
"count": [ 1, 4 ]
}
],
"special": 0,
"paticularColor": [ 255, 200, 50, 20 ],
"spawn": "LAND",
"gore": "gore_zombie",
"magicRate": 30,
"checkPlayerTarget": true,
"visionNoCrossTile": false,
"data": {
"tc": {
"message": "this is a test message!!",
"testValue": 123
}
}
}
}
================================================
FILE: npcs/zombie_pigman.json
================================================
{
"zombie_pigman": {
"ai": "Zpig",
"textureData": "zombie_pigman.png",
"type": "SMITE",
"width": 24,
"height": 46,
"gfxWidth": 48,
"gfxHeight": 48,
"gfxOffsetX": 4,
"gfxOffsetY": 8,
"frameStyle": 1,
"frames": 4,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 1.0,
"jumpForce": 9.0,
"disappearTime": 750,
"spawnCount": 1.0,
"health": 45,
"defense": 7,
"attack": 14,
"knockBack": 5,
"knockBackDefense": 0.10,
"gravity": true,
"climbWall": false,
"foreground": false,
"noFixByBlock": false,
"friendly": true,
"exps": 5,
"sunBurning": false,
"angry": true,
"antiLava": true,
"saySounds": [
"zpig1",
"zpig2",
"zpig3"
],
"hurtSounds": [
"zpigdeath",
"zpighurt1"
],
"loots": [
{
"item": "rotten_flesh",
"count": [ 1, 4 ]
},
{
"item": "gold_nugget",
"count": [ 1, 4 ],
"possibility": 0.5
}
],
"special": 0,
"paticularColor": [ 255, 200, 50, 20 ],
"spawn": "LAND",
"gore": "gore_zombie_pigman",
"magicRate": 60,
"checkPlayerTarget": true,
"visionNoCrossTile": false
}
}
================================================
FILE: package.json
================================================
{
"id": "tc",
"displayName": "TerraCraft",
"version": "1.1.0",
"description": "Vanilla Mod of TerraCraft.",
"tips": "Vanilla Mod of TerraCraft.",
"gameVersion": "Obsidian Edition",
"useSaver": true,
"authors": [
"BlueYoshi"
],
"credits": "",
"websites": [
{
"title": "Github",
"url": "https://github.com/skyblueyoshi/TerraCraft"
},
{
"title": "Homepage",
"url": "http://blueyoshi.cn/terracraft"
}
],
"objectFolders": {
"advancements": "advancements",
"biome_types": "biome_types",
"biomes": "biomes",
"block_entity_ai": "block_entity_ai",
"block_presets": "block_presets",
"blocks": "blocks",
"buffs": "buffs",
"buildings": "buildings",
"commands": "contents/commands",
"effect_ai": "effect_ai",
"effects": "effects",
"enchantments": "enchantments",
"item_ai": "item_ai",
"items": "items",
"liquids": "liquids",
"mod_textures": "mod_textures",
"npc_ai": "npc_ai",
"npc_ai_global": "npc_ai_global",
"npcs": "npcs",
"player": "player",
"projectile_ai": "projectile_ai",
"projectile_ai_global": "projectile_ai_global",
"projectiles": "projectiles",
"recipe_config": "recipe_config",
"recipes": "recipes",
"skeletons": "contents/skeletons",
"skins": "skins",
"spawns": "spawns",
"trees": "trees"
}
}
================================================
FILE: player/GPlayer.lua
================================================
---@class TC.GPlayer:GlobalPlayer
local GPlayer = class("GPlayer", GlobalPlayer)
local InputControl = require("client.InputControl")
local PlayerBoneInfo = require("bone2d.PlayerBoneInfo")
local ControlAimMode = require("client.ControlAimMode")
local cameraInGameInstance = require("client.CameraInGame").getInstance()
local EnchantmentProxies = require("enchantments.EnchantmentProxies")
local BuffProxies = require("buffs.BuffProxies")
local AdvancementTriggers = require("advancements.AdvancementTriggers")
local MiscHelper = require("util.MiscHelper")
local NetworkProxy = require("network.NetworkProxy")
local RPC_ID = require("network.RPC_ID")
local SettingsData = require("settings.SettingsData")
local DebugHelper = require("DebugHelper")
local PlayerConstants = require("PlayerConstants")
local GRAVITY = PlayerConstants.GRAVITY
local WALK_FORCE = PlayerConstants.WALK_FORCE
local TURN_FORCE = PlayerConstants.TURN_FORCE
local DECELERATE_STOP = PlayerConstants.DECELERATE_STOP
local DECELERATE_STOP_AIR = PlayerConstants.DECELERATE_STOP_AIR
local MAX_SPEED_WALK = PlayerConstants.MAX_SPEED_WALK
local MAX_SPEED_UP = PlayerConstants.MAX_SPEED_UP
local MAX_SPEED_DOWN = PlayerConstants.MAX_SPEED_DOWN
local JUMP_SPEED = PlayerConstants.JUMP_SPEED
local JUMP_UP_TIME = PlayerConstants.JUMP_UP_TIME
local INTERACTION_DISTANCE = PlayerConstants.INTERACTION_DISTANCE
local MOVE_RATE_DISTANCE = PlayerConstants.MOVE_RATE_DISTANCE
local Behavior = {
None = 0,
Placing = 1,
Digging = 2,
SwordAttacking = 3,
BowShooting = 4,
StaffShooting = 5,
GunShooting = 6,
Eating = 7,
LoadingLiquid = 8,
PullingLiquid = 9,
LoadingBottle = 10,
Throwing = 11,
PlacingWire = 12,
RemovingWire = 13,
LoadingBowl = 14,
Shearing = 15,
Seeding = 16,
Ripening = 17,
Farming = 18,
}
local ToolBehaviorProxies = {
AXE = Behavior.Digging,
PICKAXE = Behavior.Digging,
DRILL = Behavior.Digging,
SAW = Behavior.Digging,
SWORD = Behavior.SwordAttacking,
BOW = Behavior.BowShooting,
CROSS_BOW = Behavior.GunShooting,
GUN = Behavior.GunShooting,
STAFF = Behavior.StaffShooting,
WIRE_CUTTER = Behavior.RemovingWire,
SHEARS = Behavior.Shearing,
HOE = Behavior.Farming,
BOOMERANG = Behavior.Throwing,
ENDER_MIRROR = Behavior.Eating,
}
local BoneAction = {
None = 0,
Placing = 1,
Digging = 2,
SwordAttacking = 3,
BowShooting = 4,
StaffShooting = 5,
GunShooting = 6,
HoldLooking = 7,
Eating = 8,
}
local MapOpType = {
None = 0,
LoadingLiquid = 1,
PullingLiquid = 2,
LoadingBottle = 3,
LoadingBowl = 4,
Farming = 5,
Seeding = 6,
Ripening = 7,
}
local FullDress = {
diamond = {
items = {
Reg.ItemID("diamond_helmet"),
Reg.ItemID("diamond_chestplate"),
Reg.ItemID("diamond_leggings"),
},
advancementID = Reg.AdvancementID("diamond_wear"),
},
netherite = {
items = {
Reg.ItemID("nether_helmet"),
Reg.ItemID("nether_chestplate"),
Reg.ItemID("nether_leggings"),
},
advancementID = Reg.AdvancementID("netherite_full_wear"),
},
gold = {
items = {
Reg.ItemID("golden_helmet"),
Reg.ItemID("golden_chestplate"),
Reg.ItemID("golden_leggings"),
},
advancementID = Reg.AdvancementID("gold_wear"),
},
super_diamond = {
items = {
Reg.ItemID("super_diamond_helmet"),
Reg.ItemID("super_diamond_chestplate"),
Reg.ItemID("super_diamond_leggings"),
},
defense = 8,
advancementID = Reg.AdvancementID("super_diamond_wear"),
},
lava = {
items = {
Reg.ItemID("lava_helmet"),
Reg.ItemID("lava_chestplate"),
Reg.ItemID("lava_leggings"),
},
fireDefense = true,
lighting = true,
},
ancient = {
items = {
Reg.ItemID("ancient_helmet"),
Reg.ItemID("ancient_chestplate"),
Reg.ItemID("ancient_leggings"),
},
defense = 12,
attack = 7,
fireDefense = true,
lighting = true,
speed = 0.3,
advancementID = Reg.AdvancementID("ancient_wear"),
},
knight = {
items = {
Reg.ItemID("knight_helmet"),
Reg.ItemID("knight_chestplate"),
Reg.ItemID("knight_leggings"),
},
defense = 6,
attack = 5,
advancementID = Reg.AdvancementID("knight_wear"),
},
magic_gold = {
items = {
Reg.ItemID("magic_gold_helmet"),
Reg.ItemID("magic_gold_chestplate"),
Reg.ItemID("magic_gold_leggings"),
},
defense = 2,
manaAddSpeed = 0.8,
advancementID = Reg.AdvancementID("magic_gold_wear"),
},
magic_silver = {
items = {
Reg.ItemID("magic_silver_helmet"),
Reg.ItemID("magic_silver_chestplate"),
Reg.ItemID("magic_silver_leggings"),
},
defense = 2,
manaAddSpeed = 0.8,
},
magic_shadow = {
items = {
Reg.ItemID("magic_shadow_helmet"),
Reg.ItemID("magic_shadow_chestplate"),
Reg.ItemID("magic_shadow_leggings"),
},
defense = 3,
speed = 0.3,
manaAddSpeed = 0.8,
},
star = {
items = {
Reg.ItemID("star_helmet"),
Reg.ItemID("star_chestplate"),
Reg.ItemID("star_leggings"),
},
defense = 4,
attack = 5,
lighting = true,
manaAddSpeed = 0.9,
advancementID = Reg.AdvancementID("star_wear"),
},
flesh = {
items = {
Reg.ItemID("flesh_helmet"),
Reg.ItemID("flesh_chestplate"),
Reg.ItemID("flesh_leggings"),
},
attack = 7,
advancementID = Reg.AdvancementID("flesh_wear"),
},
fine_tin = {
items = {
Reg.ItemID("fine_tin_helmet"),
Reg.ItemID("fine_tin_chestplate"),
Reg.ItemID("fine_tin_leggings"),
},
attack = 3,
speed = 0.2,
},
shadow = {
items = {
Reg.ItemID("shadow_helmet"),
Reg.ItemID("shadow_chestplate"),
Reg.ItemID("shadow_leggings"),
},
manaAddSpeed = 0.5,
},
}
local DressMappings = { {}, {}, {} }
for k, v in pairs(FullDress) do
for i, id in ipairs(v.items) do
DressMappings[i][id] = k
end
end
function GPlayer:Awake()
-- player bone data
--- @type JointBody2D
self.bone = PlayerBoneInfo.createBySkinID(self.player.skinID)
self.frontItemJoint = PlayerBoneInfo.getItemJoint(self.bone, false)
self.backItemJoint = PlayerBoneInfo.getItemJoint(self.bone, true)
self.frontItemCache = {}
self.backItemCache = {}
self.currentAction = BoneAction.None
self.lastTickAction = BoneAction.None
self.currentActionTick = 0
self.currentActionMaxTicks = 0
self.throwingBoomerang = false
self.throwingBoomerangTime = 0
self.manaAddSpeed = 128
-- 先做3个饰品格子,以后谁有模组开发需求再加格子
self.accessoryInventory = Inventory.new(3)
self.player.dataWatcher:AddInventory(self.accessoryInventory)
self.trashInventory = Inventory.new(1)
self.player.dataWatcher:AddInventory(self.trashInventory)
self.BONE_ACTION = self.player.remoteDataWatcher:AddInteger(BoneAction.None, true)
if NetMode.current == NetMode.Client then
-- control and movement data
self.left = false
self.right = false
self.up = false
self.down = false
self.jump = false
self.justJump = false
self.moving = false
self.jumpUpTime = 0
self.swimTime = 0
self.walkingSoundTime = 0
self.lastAimOffsetX = 0
self.lastAimOffsetY = 0
self.aimOffsetX = 0
self.aimOffsetY = 0
self.showingAimPoint = false
self.placeColdTime = 0
self.equipmentSkinCacheData = nil
self.observeMode = false
self.doorOpenColdTime = 0
self.doorCloseColdTime = 0
self.recipeBookHookUI = nil
self.deathUI = nil
self._clientInteractProxies = {
[Behavior.Placing] = GPlayer.ClientPlacing,
[Behavior.PlacingWire] = GPlayer.ClientPlacingWire,
[Behavior.RemovingWire] = GPlayer.ClientRemovingWire,
[Behavior.Eating] = GPlayer.ClientEating,
[Behavior.LoadingLiquid] = GPlayer.ClientLoadingLiquid,
[Behavior.LoadingBowl] = GPlayer.ClientLoadingBowl,
[Behavior.PullingLiquid] = GPlayer.ClientPullingLiquid,
[Behavior.LoadingBottle] = GPlayer.ClientLoadingBottle,
[Behavior.Shearing] = GPlayer.ClientShearing,
[Behavior.Seeding] = GPlayer.ClientSeeding,
[Behavior.Ripening] = GPlayer.ClientRipening,
[Behavior.Throwing] = GPlayer.ClientThrowing,
[Behavior.Digging] = GPlayer.ClientDigging,
[Behavior.Farming] = GPlayer.ClientFarming,
[Behavior.SwordAttacking] = GPlayer.ClientSwordAttacking,
[Behavior.BowShooting] = GPlayer.ClientBowShooting,
[Behavior.GunShooting] = GPlayer.ClientGunShooting,
[Behavior.StaffShooting] = GPlayer.ClientStaffShooting,
}
else
self.player.health = PlayerConstants.StartHealth
self.player.maxHealth = PlayerConstants.StartMaxHealth
self.player.mana = PlayerConstants.StartMana
self.player.maxMana = PlayerConstants.StartMaxMana
self.player.foodLevel = PlayerConstants.StartFoodLevel
self.player.foodSaturationLevel = PlayerConstants.StartSaturationLevel
self._mapOpFunc = {
[MapOpType.LoadingLiquid] = self.ServerLoadingLiquid,
[MapOpType.PullingLiquid] = self.ServerPullingLiquid,
[MapOpType.LoadingBottle] = self.ServerLoadingBottle,
[MapOpType.LoadingBowl] = self.ServerLoadingBowl,
[MapOpType.Farming] = self.ServerFarming,
[MapOpType.Seeding] = self.ServerSeeding,
[MapOpType.Ripening] = self.ServerRipen,
}
end
-- animation event
self._animationBeginFunc = {
[BoneAction.Placing] = self.OnPlacingAnimationBegin,
[BoneAction.Eating] = self.OnEatingAnimationBegin,
[BoneAction.Digging] = self.OnDiggingAnimationBegin,
[BoneAction.SwordAttacking] = self.OnSwordAttackingAnimationBegin,
[BoneAction.BowShooting] = self.OnBowShootingAnimationBegin,
[BoneAction.StaffShooting] = self.OnStaffShootingAnimationBegin,
[BoneAction.GunShooting] = self.OnGunShootingAnimationBegin,
[BoneAction.HoldLooking] = self.OnHoldLookingAnimationBegin,
}
self._animationUpdateFunc = {
[BoneAction.Digging] = self.OnDiggingAnimationUpdate,
[BoneAction.SwordAttacking] = self.OnSwordAttackingAnimationUpdate,
[BoneAction.BowShooting] = self.OnBowShootingAnimationUpdate,
[BoneAction.StaffShooting] = self.OnStaffShootingAnimationUpdate,
[BoneAction.GunShooting] = self.OnGunShootingAnimationUpdate,
[BoneAction.HoldLooking] = self.OnHoldLookingAnimationUpdate,
}
self._animationEndFunc = {
[BoneAction.Placing] = self.OnPlacingAnimationEnd,
[BoneAction.Eating] = self.OnEatingAnimationEnd,
[BoneAction.Digging] = self.OnDiggingAnimationEnd,
[BoneAction.SwordAttacking] = self.OnSwordAttackingAnimationEnd,
[BoneAction.BowShooting] = self.OnBowShootingAnimationEnd,
[BoneAction.StaffShooting] = self.OnStaffShootingAnimationEnd,
[BoneAction.GunShooting] = self.OnGunShootingAnimationEnd,
[BoneAction.HoldLooking] = self.OnHoldLookingAnimationEnd,
}
self.bone.animator:createEventAtTimePoint("Placing", 1.0):addListener(
{ self.OnPlacingAnimationEnd, self }
)
self.bone.animator:createEventAtTimePoint("Eating", 1.0):addListener(
{ self.OnEatingAnimationEnd, self }
)
self.bone.animator:createEventAtTimePoint("SwordAttacking", 1.0):addListener(
{ self.OnSwordAttackingAnimationEnd, self }
)
end
function GPlayer:Init()
self.player:FinishAdvancement(Reg.AdvancementID("inventory"))
DebugHelper.RunDebugStart(self.player)
end
function GPlayer:OnFirstTimeJoin()
self:BackpackAddItemByIDName("grass_sword")
self:BackpackAddItemByIDName("grass_axe")
self:BackpackAddItemByIDName("grass_pickaxe")
self:BackpackAddItemByIDName("torch", 16)
end
function GPlayer:BackpackAddItemByIDName(idName, count)
if count == nil then
count = 1
end
self.player.backpackInventory:AddItemStack(ItemStack.new(ItemRegistry.GetItemByIDName(idName), count))
end
function GPlayer:Motion()
-- only control current client player
if not self.player.isCurrentClientPlayer then
return
end
local player = self.player
local lastJump = self.jump
player.defaultMaxSpeed = MAX_SPEED_WALK
player.defaultJumpTime = JUMP_UP_TIME
player.defaultFallSpeed = MAX_SPEED_DOWN
player.defaultJumpSpeed = JUMP_SPEED
local inputControl = InputControl.getInstance()
if not player.dying then
self.left = InputControl.isPressing("left")
self.right = InputControl.isPressing("right")
self.up = InputControl.isPressing("up")
self.down = InputControl.isPressing("down")
self.jump = InputControl.isPressing("jump")
else
-- do not move when dying
self.left = false
self.right = false
self.up = false
self.down = false
self.jump = false
end
self.justJump = not lastJump and self.jump
-- ignore if pressing two reverse direction buttons at the same time
if self.left and self.right then
self.left, self.right = false, false
end
if self.up and self.down then
self.up, self.down = false, false
end
self.moving = self.left or self.right
player.isDownPlatform = player.stand and self.down
local stickyRate = 1.0
if player.inLiquid then
--TODO:LiquidNS::Data &ld = liquidData->GetData(e.touchLiquidID); stickyRate = ld.stickyRate;
stickyRate = 0.5
end
local maxSpeed = player.defaultMaxSpeed * player.speedRate * stickyRate
if self.moving then
-- change direction
player.direction = self.right
-- walking
local walkForce = WALK_FORCE * stickyRate
-- TODO:walkForce *= blockData->GetData(hostBlockId).slipperiness
local turnForce = TURN_FORCE
local speedFlag = player.speedX > 0
player.speedX = player.speedX +
(((self.right and speedFlag) or (self.left and not speedFlag))
and walkForce or turnForce) *
(self.right and 1.0 or -1.0)
else
-- slowing down
local decelerateForce = player.stand and DECELERATE_STOP or DECELERATE_STOP_AIR
-- TODO:if (e.stand && hostBlockId > 0) decelerateForce *= hostSlipperiness;
player.speedX = Utils.SlowSpeed1D(player.speedX, decelerateForce)
end
if player.speedX > maxSpeed then
player.speedX = Utils.SlowSpeed1D(player.speedX, DECELERATE_STOP)
if player.speedX < maxSpeed then
player.speedX = maxSpeed
end
elseif player.speedX < -maxSpeed then
player.speedX = Utils.SlowSpeed1D(player.speedX, DECELERATE_STOP)
if player.speedX > -maxSpeed then
player.speedX = -maxSpeed
end
end
local gravity = GRAVITY
local maxFallSpeed = player.defaultFallSpeed * player.fallSpeedRate
local maxUpSpeed = MAX_SPEED_UP * player.jumpSpeedRate
if player.inLiquid then
maxFallSpeed = maxFallSpeed * stickyRate * 0.5
maxUpSpeed = maxFallSpeed
end
if not (self.jump and self.jumpUpTime > 0) then
-- no press jump
if player.inLiquid then
player.speedY = player.speedY + gravity * stickyRate
if self.jump then
player.speedY = player.speedY - gravity
self.swimTime = self.swimTime + 1
end
else
player.speedY = player.speedY + gravity
self.swimTime = 0
end
end
if not player.inLiquid then
self.swimTime = 0
end
local maxJumpTime = math.ceil(player.defaultJumpTime * player.jumpRate)
if player.stand and self.justJump then
self.jumpUpTime = maxJumpTime
elseif self.jump and not player.isCollisionTop then
-- Jump from water
if player.speedY < 0 and player.oldInLiquid and not player.inLiquid then
self.jumpUpTime = math.ceil(maxJumpTime * 0.8)
player.speedY = math.max(player.speedY, -maxUpSpeed)
end
self.jumpUpTime = math.max(self.jumpUpTime - 1, 0)
else
self.jumpUpTime = 0
end
if self.jumpUpTime > 0 then
player.speedY = -player.defaultJumpSpeed * player.jumpSpeedRate
end
player.speedY = math.min(math.max(player.speedY, -maxUpSpeed), maxFallSpeed)
if self.observeMode then
local s = 24
if self.left then
player.speedX = -s
elseif self.right then
player.speedX = s
else
player.speedX = 0
end
if self.up then
player.speedY = -s
elseif self.down then
player.speedY = s
else
player.speedY = 0
end
end
player.ignoreCollisionWithTiles = self.observeMode
if player.stand and math.abs(player.speedX) > 1.0 then
self.walkingSoundTime = self.walkingSoundTime + 1
else
self.walkingSoundTime = 0
end
if player.stand then
local blockID = MapUtils.GetFrontID(player.hostXi, player.hostYi)
if blockID then
local data = BlockUtils.GetData(blockID)
if self.walkingSoundTime > 24 then
self.walkingSoundTime = 0
if data.stepSoundId then
SoundUtils.PlaySound(data.stepSoundId)
end
if data.stepSoundGroupId then
SoundUtils.PlaySoundGroup(data.stepSoundGroupId)
end
end
end
end
self.showingAimPoint = true
-- aim by joystick
if inputControl.aimMode == ControlAimMode.PressOnly then
self.aimOffsetX = 0
self.aimOffsetY = 0
self.lastAimOffsetX = 0
self.lastAimOffsetY = 0
elseif inputControl.aimMode == ControlAimMode.LookDirectionOrShoot then
self.lastAimOffsetX = 0
self.lastAimOffsetY = 0
if SettingsData.isMobileOperation then
if inputControl.aimDistance > 0 then
self.aimOffsetX = math.cos(inputControl.aimAngle) * INTERACTION_DISTANCE * 1.6
self.aimOffsetY = math.sin(inputControl.aimAngle) * INTERACTION_DISTANCE * 1.3
end
else
-- PC
self.aimOffsetX = inputControl.pcMouseAtMapX - player.centerX
self.aimOffsetY = inputControl.pcMouseAtMapY - player.centerY
end
elseif inputControl.aimMode == ControlAimMode.LookPositionOrUse then
if SettingsData.isMobileOperation then
if inputControl.aimInstanceClicked then
self.lastAimOffsetX = self.aimOffsetX
self.lastAimOffsetY = self.aimOffsetY
end
if inputControl.aimPressing then
local angle = inputControl.aimAngle
self.aimOffsetX = self.lastAimOffsetX + math.cos(angle) * MOVE_RATE_DISTANCE * inputControl.aimDistance
self.aimOffsetY = self.lastAimOffsetY + math.sin(angle) * MOVE_RATE_DISTANCE * inputControl.aimDistance
local tempVec2 = Vector2.new(self.aimOffsetX, self.aimOffsetY)
inputControl.aimAngle = tempVec2.angle
if tempVec2.length > INTERACTION_DISTANCE then
self.aimOffsetX = math.cos(inputControl.aimAngle) * INTERACTION_DISTANCE
self.aimOffsetY = math.sin(inputControl.aimAngle) * INTERACTION_DISTANCE
end
end
else
-- PC
self.lastAimOffsetX = 0
self.lastAimOffsetY = 0
self.aimOffsetX = inputControl.pcMouseAtMapX - player.centerX
self.aimOffsetY = inputControl.pcMouseAtMapY - player.centerY
end
end
-- Mouse scrolling
self:CheckScrollMouse()
-- Drop items
if InputControl.isInstantPressing("Drop") then
local dropOne = true
if InputControl.isPressing("Shift") then
dropOne = false
end
NetworkProxy.RPCSendServerBound(Mod.current, RPC_ID.SB_DROP_ITEM_HELD, dropOne)
end
end
function GPlayer:Update()
local player = self.player
PlayerBoneInfo.checkHandItem(self.backItemJoint, self:GetHeldSlot(), self.backItemCache)
self.bone.joints.position = Vector2.new(player.centerX, player.bottomY)
local animator = self.bone.animator
animator:setBool("OnGround", player.stand)
local speedRate = 0
local speed = math.abs(player.speedX)
local lastSpeed = animator:getFloat("Speed")
if speed > 3 then
speedRate = 0.5
elseif player.isCollisionLeft or player.isCollisionRight then
speedRate = 0
else
speedRate = speed / 3.0 * 0.5
end
if speedRate == 0 and lastSpeed ~= 0 then
speedRate = Utils.SlowSpeed1D(lastSpeed, 0.1)
end
local heldSlot = self:GetHeldSlot()
self.player.holdColdTime = 0
if heldSlot.hasStack then
local itemStack = heldSlot:GetStack()
local item = itemStack:GetItem()
if item.isBlock then
elseif item.isTool then
self.player.holdColdTime = math.max(8, item.coldTime)
end
end
if NetMode.current == NetMode.Server then
-- drop item
local trashSlot = self.trashInventory:GetSlot(0)
if trashSlot.hasStack then
player:DropItem(trashSlot:GetStack())
trashSlot:ClearStack()
end
local biomeID = player.biomeID
AdvancementTriggers.getInstance():TriggerEnterBiome(player, biomeID)
if self.throwingBoomerang then
self.throwingBoomerangTime = self.throwingBoomerangTime - 1
if self.throwingBoomerangTime <= 0 then
self.throwingBoomerangTime = 0
self.throwingBoomerang = false
end
end
end
DebugHelper.RunDebug(player)
if NetMode.current == NetMode.Client then
if player.isCurrentClientPlayer then
self:ClientInteract()
end
end
self.bone.joints.scale = Vector2.new(1.0, 1.0)
animator:setFloat("Speed", speedRate)
animator:setFloat("AirSpeed", player.speedY)
self.bone.joints.flip = not player.facingDirection
self.bone:update()
self:UpdateBone()
heldSlot = self:GetHeldSlot()
if heldSlot.hasStack then
heldSlot:GetStack():RunOnHeldEvent(player)
end
end
function GPlayer:UpdateBone()
local player = self.player
local isServer = NetMode.current == NetMode.Server
local heldSlot = self:GetHeldSlot()
self.bone.animator:setLayerTimeScale(1, 1.0)
self.lastTickAction = self.currentAction
-- change the skin by equipment
if not isServer then
local changeSkinData = false
if self.equipmentSkinCacheData == nil then
changeSkinData = true
else
local equipmentInventory = player.equipmentInventory
for i = 0, 5 do
local slot = equipmentInventory:GetSlot(i)
local cacheID = self.equipmentSkinCacheData[i + 1]
if slot.hasStack then
if slot:GetStack():GetItem().id ~= cacheID then
changeSkinData = true
break
end
elseif cacheID ~= 0 then
changeSkinData = true
break
end
end
end
if changeSkinData then
-- save equipment data to cache
self.equipmentSkinCacheData = {}
local equipmentInventory = player.equipmentInventory
for i = 0, 5 do
local slot = equipmentInventory:GetSlot(i)
if slot.hasStack then
self.equipmentSkinCacheData[i + 1] = slot:GetStack():GetItem().id
else
self.equipmentSkinCacheData[i + 1] = 0
end
end
local HAT_INDICES = { 3, 0 }
local CLOTH_INDICES = { 4, 1 }
local PANT_INDICES = { 5, 2 }
local hatTex, clothTex, pantTex
local showHair = true
for i = 1, 2 do
local index = HAT_INDICES[i]
local slot = equipmentInventory:GetSlot(index)
if slot.hasStack and slot:GetStack():GetItem().toolType == "HELMET" then
hatTex = slot:GetStack():GetItem().entityTextureLocation
showHair = slot:GetStack():GetItem().showHair
break
end
end
for i = 1, 2 do
local index = CLOTH_INDICES[i]
local slot = equipmentInventory:GetSlot(index)
if slot.hasStack and slot:GetStack():GetItem().toolType == "CHESTPLATE" then
clothTex = slot:GetStack():GetItem().entityTextureLocation
break
end
end
for i = 1, 2 do
local index = PANT_INDICES[i]
local slot = equipmentInventory:GetSlot(index)
if slot.hasStack and slot:GetStack():GetItem().toolType == "LEGGINGS" then
pantTex = slot:GetStack():GetItem().entityTextureLocation
break
end
end
PlayerBoneInfo.setSkinByID(self.bone, self.player.skinID)
local skinTable = PlayerBoneInfo.getSkinTableByID(self.player.skinID)
if not showHair then
skinTable.hair = nil
end
if hatTex then
skinTable.hat = hatTex
end
if clothTex then
skinTable.cloth = clothTex
end
if pantTex then
skinTable.pant = pantTex
end
PlayerBoneInfo.setSkin(self.bone, skinTable)
end
end
if self.currentAction == BoneAction.None then
-- client: using current action by specify item
-- server: get the new action from client side
self.currentAction = player.remoteDataWatcher:GetInteger(self.BONE_ACTION)
self.currentActionTick = 0
self.currentActionMaxTicks = 0
local beginFunc = self._animationBeginFunc[self.currentAction]
if beginFunc then
beginFunc(self)
else
self.currentAction = BoneAction.None
end
end
if heldSlot.hasStack then
local item = heldSlot:GetStack():GetItem()
local holdingItemAnm = false
if item.isBlock or item.isMaterial then
holdingItemAnm = true
end
self.bone.animator:setBool("HoldingItem", holdingItemAnm)
end
if self.currentAction ~= BoneAction.None then
local updateFunc = self._animationUpdateFunc[self.currentAction]
if updateFunc then
updateFunc(self)
end
if self.currentActionTick >= self.currentActionMaxTicks + 1 then
local endFunc = self._animationEndFunc[self.currentAction]
if endFunc then
endFunc(self)
end
self.currentActionTick = 0
self.bone.animator:setTrigger("StopAction")
else
self.currentActionTick = self.currentActionTick + 1
end
end
if not isServer then
-- swim animation (kicking legs)
if not player.stand and self.swimTime > 0 then
local angle1 = -Utils.SinValue(self.swimTime, 32) * 0.5
local angle2 = -angle1
local body = self.bone.joints:getJoint("base.body")
local front_leg = body:getChild("front_leg")
local back_leg = body:getChild("back_leg")
front_leg.angle = angle1
back_leg.angle = angle2
end
end
if player.dying then
self.bone.animator:setBool("Death", true)
if not isServer then
if self.deathUI == nil then
self.deathUI = require("ui.DeathUI").new()
-- TODO:关闭其他打开的GUI
end
end
else
self.bone.animator:setBool("Death", false)
if not isServer then
if self.deathUI ~= nil then
self.deathUI:closeWindow()
self.deathUI = nil
end
end
end
self.bone:update(false)
end
function GPlayer:OnSwordAttackingAnimationBegin()
self.bone.animator:setTrigger("SwordAttacking")
self.currentActionMaxTicks = self.player.holdColdTime
end
function GPlayer:EndAction()
if self.currentAction ~= BoneAction.None then
self.currentAction = BoneAction.None
self.currentActionTick = 0
return true
end
return false
end
function GPlayer:OnSwordAttackingAnimationEnd()
self:EndAction()
end
function GPlayer:OnSwordAttackingAnimationUpdate()
local timeScale = self.currentActionMaxTicks > 0 and (60.0 / self.currentActionMaxTicks) or 1.0
self.bone.animator:setLayerTimeScale(1, timeScale)
self:UseHeldItem()
end
function GPlayer:OnPlacingAnimationBegin()
self.bone.animator:setTrigger("Placing")
self.currentActionMaxTicks = 16
end
function GPlayer:OnPlacingAnimationEnd()
self:EndAction()
end
function GPlayer:OnEatingAnimationBegin()
self.bone.animator:setTrigger("Eating")
self.currentActionMaxTicks = 16
if NetMode.current == NetMode.Server then
self:TryUseHeldItem()
else
local xi = Utils.Cell(self.player.centerX)
local yi = Utils.Cell(self.player.centerY)
SoundUtils.PlaySound(Reg.SoundID("drink"), xi, yi)
end
end
function GPlayer:OnEatingAnimationEnd()
self:EndAction()
end
function GPlayer:OnDiggingAnimationBegin()
self.bone.animator:setTrigger("StopAction")
self.currentActionMaxTicks = self.player.holdColdTime
end
function GPlayer:OnDiggingAnimationEnd()
if self:EndAction() then
self.player.direction = self.player.facingDirection
end
end
function GPlayer:OnDiggingAnimationUpdate()
if self.currentActionMaxTicks <= 0 then
return
end
self:UpdateLookAngle()
local body = self.bone.joints:getJoint("base.body")
local head = body:getChild("head")
local back_arm = body:getChild("back_arm")
local rate = self.currentActionTick / self.currentActionMaxTicks
local lookAngle = self:GetLookAngleInFacingDirection()
back_arm.angle = lookAngle + math.pi * 0.5 * (2 * rate - 2.0)
head.angle = (math.abs(lookAngle + math.pi / 2) - math.pi / 2) / 8
end
function GPlayer:OnBowShootingAnimationBegin()
self.bone.animator:setTrigger("StopAction")
self.currentActionMaxTicks = self.player.holdColdTime
self:UseHeldItem()
end
function GPlayer:OnBowShootingAnimationEnd()
self:EndAction()
end
function GPlayer:OnBowShootingAnimationUpdate()
if self.currentActionMaxTicks <= 0 then
return
end
self:UpdateLookAngle()
end
function GPlayer:OnStaffShootingAnimationBegin()
self.bone.animator:setTrigger("StopAction")
self.currentActionMaxTicks = self.player.holdColdTime
end
function GPlayer:OnStaffShootingAnimationEnd()
self:EndAction()
end
function GPlayer:OnStaffShootingAnimationUpdate()
if self.currentActionMaxTicks <= 0 then
return
end
self:UpdateLookAngle()
self:UseHeldItem()
end
function GPlayer:OnGunShootingAnimationBegin()
self.bone.animator:setTrigger("StopAction")
self.currentActionMaxTicks = self.player.holdColdTime
end
function GPlayer:OnGunShootingAnimationEnd()
self:EndAction()
end
function GPlayer:OnGunShootingAnimationUpdate()
if self.currentActionMaxTicks <= 0 then
return
end
self:UpdateLookAngle()
self:UseHeldItem()
end
function GPlayer:OnHoldLookingAnimationBegin()
self.bone.animator:setTrigger("StopAction")
self.currentActionMaxTicks = 11
end
function GPlayer:OnHoldLookingAnimationEnd()
self:EndAction()
end
function GPlayer:OnHoldLookingAnimationUpdate()
if self.currentActionMaxTicks <= 0 then
return
end
self:UpdateLookAngle()
end
function GPlayer:CheckScrollMouse()
local player = self.player
if not player.isCurrentClientPlayer then
return
end
local deltaY = InputControl.getInstance().pcMouseScrollDeltaY
if deltaY == 0 then
return
end
InputControl.getInstance().pcMouseScrollDeltaY = 0
local UIManager = require("ui.UIManager")
if UIManager.getInstance():hasUIGroup(require("ui.UIDefault").GROUP_GAME_WINDOW) then
return
end
if deltaY > 0 then
if player.heldSlotIndex == 0 then
player.heldSlotIndex = 9
else
player.heldSlotIndex = player.heldSlotIndex - 1
end
else
if player.heldSlotIndex == 9 then
player.heldSlotIndex = 0
else
player.heldSlotIndex = player.heldSlotIndex + 1
end
end
end
function GPlayer:CheckDoorAutoOperation()
-- Auto door operation is only available in mobile.
if not SettingsData.isMobileOperation then
return
end
local player = self.player
if self.doorOpenColdTime > 0 then
self.doorOpenColdTime = self.doorOpenColdTime - 1
end
if self.doorCloseColdTime > 0 then
self.doorCloseColdTime = self.doorCloseColdTime - 1
end
if math.abs(player.speedX) < 0.5 then
return
end
local frontDir = player.speedX > 0 and 1 or -1
local xi = player.centerXi + frontDir * 2
local xi2 = player.centerXi - frontDir * 2
local yi = player.centerYi
if self.doorOpenColdTime == 0 then
local frontID = MapUtils.GetFrontID(xi, yi)
if frontID > 0 then
local blockData = BlockUtils.GetData(frontID)
if blockData.isDoorClosed then
player:RequestClickMap(xi, yi)
self.doorOpenColdTime = 32
end
end
end
if self.doorCloseColdTime == 0 then
local frontID = MapUtils.GetFrontID(xi2, yi)
if frontID > 0 then
local blockData = BlockUtils.GetData(frontID)
if blockData.isDoorOpened then
player:RequestClickMap(xi2, yi)
self.doorCloseColdTime = 32
end
end
end
end
function GPlayer:ClientInteract()
local player = self.player
if not player.isCurrentClientPlayer then
return
end
if player.heldSlotIndexJustChanged then
self.aimOffsetX = 0
self.aimOffsetY = 0
self.lastAimOffsetX = 0
self.lastAimOffsetY = 0
end
local inputControl = InputControl.getInstance()
local pressingNum = InputControl.getCurrentPressingKeyNum()
if pressingNum ~= -1 and (pressingNum >= 0 and pressingNum <= 9) then
if pressingNum == 0 then
player.heldSlotIndex = 9
else
player.heldSlotIndex = pressingNum - 1
end
end
if inputControl.isMapClicking then
inputControl.isMapClicking = false
local clickPosition = inputControl.touchMapPosition:clone()
local realPosition = Vector2.new(clickPosition.x + MiscUtils.screenX, clickPosition.y + MiscUtils.screenY)
if realPosition:getDistance(Vector2.new(player.centerX, player.centerY)) < INTERACTION_DISTANCE then
local xi = Utils.Cell(realPosition.x)
local yi = Utils.Cell(realPosition.y)
player:RequestClickMap(xi, yi)
end
end
-- hide wire render
MapUtils.SetWireVisible(false)
-- hide block preview
MapUtils.ClearBlockRenderPreview()
-- auto open or close door
self:CheckDoorAutoOperation()
player:SetSmartMode(SmartMode.None)
local heldSlot = self:GetHeldSlot()
local behavior = Behavior.None
-- refresh the player action
player.remoteDataWatcher:UpdateInteger(self.BONE_ACTION, BoneAction.None)
-- refresh placing time
if self.placeColdTime ~= 0 then
self.placeColdTime = math.max(self.placeColdTime - 1, 0)
end
self.player.holdColdTime = 0
player.facingDirection = player.direction
if heldSlot.hasStack then
local itemStack = heldSlot:GetStack()
local item = itemStack:GetItem()
if item.isBlock then
-- holding a block item
behavior = Behavior.Placing
elseif item.isTool then
-- holding a tool item
local tempBehavior = ToolBehaviorProxies[item.toolType]
if tempBehavior ~= nil then
behavior = tempBehavior
end
self.player.holdColdTime = math.max(8, item.coldTime)
elseif item.isMaterial then
-- holding a material item
local itemID = item.id
if item.isSeed then
behavior = Behavior.Seeding
elseif item.eatable then
behavior = Behavior.Eating
elseif MiscHelper.IsEmptyBucket(itemID) then
behavior = Behavior.LoadingLiquid
elseif MiscHelper.IsEmptyGrassBottle(itemID) then
behavior = Behavior.LoadingBottle
elseif MiscHelper.IsPullableBucket(itemID) then
behavior = Behavior.PullingLiquid
elseif MiscHelper.IsEmptyBowl(itemID) then
behavior = Behavior.LoadingBowl
elseif MiscHelper.IsBoneMeal(itemID) then
behavior = Behavior.Ripening
else
local modItem = itemStack:GetModItem()
if modItem then
if modItem.isBossCaller then
behavior = Behavior.Eating
end
end
end
else
if item.type == ItemType.Projectile then
if item.canThrow then
behavior = Behavior.Throwing
end
elseif item.type == ItemType.Wire then
behavior = Behavior.PlacingWire
end
end
end
if behavior ~= Behavior.None then
local fun = self._clientInteractProxies[behavior]
if fun then
fun(self)
end
end
end
function GPlayer:ClientSwordAttacking()
local inputControl = InputControl.getInstance()
inputControl.aimMode = ControlAimMode.PressOnly
local player = self.player
local heldSlot = self:GetHeldSlot()
if heldSlot.hasStack and (inputControl.aimTriggerUsing or inputControl.isPcMouseLeftPressingAtMap) then
if not SettingsData.isMobileOperation then
-- PC
end
player.remoteDataWatcher:UpdateInteger(self.BONE_ACTION, BoneAction.SwordAttacking)
local item = heldSlot:GetStack():GetItem()
player.holdColdTime = item.coldTime
end
end
function GPlayer:ClientBowShooting()
local inputControl = InputControl.getInstance()
inputControl.aimMode = ControlAimMode.LookDirectionOrShoot
local player = self.player
local heldSlot = self:GetHeldSlot()
if heldSlot.hasStack and (inputControl.aimTriggerUsing or inputControl.isPcMouseLeftPressingAtMap) then
self.player.direction = self.player.facingDirection
player.remoteDataWatcher:UpdateInteger(self.BONE_ACTION, BoneAction.BowShooting)
local item = heldSlot:GetStack():GetItem()
player.holdColdTime = item.coldTime
end
self:UpdateLookAngle()
end
function GPlayer:ClientStaffShooting()
local inputControl = InputControl.getInstance()
inputControl.aimMode = ControlAimMode.LookDirectionOrShoot
local player = self.player
local heldSlot = self:GetHeldSlot()
if heldSlot.hasStack and (inputControl.aimTriggerUsing or inputControl.isPcMouseLeftPressingAtMap) then
self.player.direction = self.player.facingDirection
player.remoteDataWatcher:UpdateInteger(self.BONE_ACTION, BoneAction.StaffShooting)
local item = heldSlot:GetStack():GetItem()
player.holdColdTime = item.coldTime
end
end
function GPlayer:ClientGunShooting()
local inputControl = InputControl.getInstance()
inputControl.aimMode = ControlAimMode.LookDirectionOrShoot
local player = self.player
local heldSlot = self:GetHeldSlot()
player.lookAngle = 0
if not player.facingDirection then
player.lookAngle = math.pi
end
if heldSlot.hasStack and (not SettingsData.isMobileOperation or inputControl.aimPressing) then
self:UpdateLookAngle()
self.player.direction = self.player.facingDirection
if inputControl.aimTriggerUsing or inputControl.isPcMouseLeftPressingAtMap then
player.remoteDataWatcher:UpdateInteger(self.BONE_ACTION, BoneAction.GunShooting)
local item = heldSlot:GetStack():GetItem()
player.holdColdTime = item.coldTime
--else
-- player.remoteDataWatcher:UpdateInteger(self.BONE_ACTION, BoneAction.HoldLooking)
-- player.holdColdTime = 1
end
end
end
function GPlayer:ClientPlacing()
local xi, yi, op = self:CheckAimPositionInMap()
local player = self.player
local heldSlot = self:GetHeldSlot()
if heldSlot.hasStack then
local blockID = heldSlot:GetStack():GetItem().blockID
if blockID > 0 then
local canPlace = false
if InputControl.getInstance().operatingWall then
canPlace = MapUtils.CanPlaceWall(xi, yi, blockID)
else
canPlace = MapUtils.CanPlaceFront(xi, yi, blockID)
end
if canPlace and not SettingsData.isMobileOperation and not self:InInteractionDistanceIPos(xi, yi) then
canPlace = false
end
local ox = self.player.centerX + self.aimOffsetX
local oy = self.player.centerY + self.aimOffsetY
MapUtils.SetBlockRenderPreview(blockID, ox, oy, canPlace, player.centerX, player.centerY)
end
end
if heldSlot.hasStack and op == 1 then
player.remoteDataWatcher:UpdateInteger(self.BONE_ACTION, BoneAction.Placing)
-- skip placing
if self.placeColdTime > 0 then
return
end
if not SettingsData.isMobileOperation and not self:InInteractionDistanceIPos(xi, yi) then
return
end
player:RequestPlaceBlock(xi, yi, player.heldSlotIndex, InputControl.getInstance().operatingWall)
self.placeColdTime = 8
player.direction = xi * 16 + 8 > player.centerX
end
end
function GPlayer:ClientPlacingWire()
local xi, yi, op = self:CheckAimPositionInMap()
local player = self.player
local heldSlot = self:GetHeldSlot()
MapUtils.SetWireVisible(true)
-- skip placing
if self.placeColdTime > 0 then
return
end
if not SettingsData.isMobileOperation and not self:InInteractionDistanceIPos(xi, yi) then
return
end
if heldSlot.hasStack and op == 1 then
player.remoteDataWatcher:UpdateInteger(self.BONE_ACTION, BoneAction.Placing)
if player:RequestPlaceWire(xi, yi, player.heldSlotIndex) then
SoundUtils.PlaySoundGroup(Reg.SoundGroupID("cloth"))
end
self.placeColdTime = 8
player.direction = xi * 16 + 8 > player.centerX
end
end
function GPlayer:_CanRemoveWire(xi, yi)
local heldSlot = self:GetHeldSlot()
if not heldSlot.hasStack then
return false
end
local item = heldSlot:GetStack():GetItem()
if item.toolType ~= "WIRE_CUTTER" then
return false
end
return MapUtils.HasWire(xi, yi)
end
function GPlayer:ClientRemovingWire()
local xi, yi, op = self:CheckAimPositionInMap()
local player = self.player
MapUtils.SetWireVisible(true)
if not SettingsData.isMobileOperation and not self:InInteractionDistanceIPos(xi, yi) then
return
end
if op == 1 then
if self:_CanRemoveWire(xi, yi) then
MapUtils.RemoveWire(xi, yi)
player.remoteDataWatcher:UpdateInteger(self.BONE_ACTION, BoneAction.Placing)
self.placeColdTime = 8
player.direction = xi * 16 + 8 > player.centerX
NetworkProxy.RPCSendServerBound(Mod.current, RPC_ID.SB_REMOVE_WIRE, xi, yi)
end
end
end
function GPlayer:OnRemovingWireBound(xi, yi)
if self:_CanRemoveWire(xi, yi) then
MapUtils.RemoveWireAndDrop(xi, yi)
SoundUtils.PlaySoundGroup(Reg.SoundGroupID("cloth"), xi, yi)
else
MapUtils.SyncUnit(xi, yi)
end
end
function GPlayer:ClientEating()
local inputControl = InputControl.getInstance()
local player = self.player
local heldSlot = self:GetHeldSlot()
if heldSlot.hasStack and (inputControl.aimTriggerUsing or inputControl.isPcMouseLeftInstantDownAtMap) then
local stack = heldSlot:GetStack()
if stack:CanUse(player) then
player.remoteDataWatcher:UpdateInteger(self.BONE_ACTION, BoneAction.Eating)
end
end
end
function GPlayer:ClientThrowing()
local inputControl = InputControl.getInstance()
inputControl.aimMode = ControlAimMode.LookDirectionOrShoot
local player = self.player
local heldSlot = self:GetHeldSlot()
player.lookAngle = 0
if not player.facingDirection then
player.lookAngle = math.pi
end
if heldSlot.hasStack and (inputControl.aimPressing or not SettingsData.isMobileOperation) then
self:UpdateLookAngle()
self.player.direction = self.player.facingDirection
if inputControl.aimTriggerUsing or inputControl.isPcMouseLeftInstantDownAtMap then
if self.placeColdTime > 0 then
return
end
player.remoteDataWatcher:UpdateInteger(self.BONE_ACTION, BoneAction.Placing)
self.placeColdTime = 16
NetworkProxy.RPCSendServerBound(Mod.current, RPC_ID.SB_PLAYER_THROWING, player.lookAngle)
end
end
end
function GPlayer:CheckThrowing(angle)
local heldSlot = self:GetHeldSlot()
if not heldSlot.hasStack then
return false
end
local item = heldSlot:GetStack():GetItem()
local player = self.player
-- Check if item is boomerang
if item.toolType == "BOOMERANG" then
if self.throwingBoomerang then
return false
end
local proj = ProjectileUtils.CreateFromPlayer(player, item.projectileID,
player.centerX, player.centerY,
item.speed * math.cos(angle), item.speed * math.sin(angle),
item.baseAttack
)
proj.targetTime = 100
proj.isCheckPlayer = false
proj.isCheckNpc = true
local mp = proj:GetModProjectile()
if mp then
mp.playerOwnerIndex = EntityIndex.new(player.entityIndex.entityID, player.entityIndex.uniqueID)
self.throwingBoomerangTime = 1000
self.throwingBoomerang = true
end
else
if not (item.type == ItemType.Projectile and item.canThrow) then
return false
end
local proj = ProjectileUtils.CreateFromPlayer(player, item.projectileID,
player.centerX, player.centerY,
item.speed * math.cos(angle), item.speed * math.sin(angle),
item.baseAttack
)
proj.isCheckPlayer = false
proj.isCheckNpc = true
proj.targetTime = item.coldTime
heldSlot:DecrStackSize(1)
end
return true
end
function GPlayer:OnThrowingServerBound(angle)
local ok = self:CheckThrowing(angle)
if not ok then
self:GetHeldSlot():SyncAll()
end
end
function GPlayer:ClientDoMapOp(opType, conditionFunc, removeOneOnSend)
local xi, yi, op = self:CheckAimPositionInMap()
local player = self.player
local heldSlot = self:GetHeldSlot()
if heldSlot.hasStack and op == 1 then
if self.placeColdTime > 0 then
return
end
if not SettingsData.isMobileOperation and not self:InInteractionDistanceIPos(xi, yi) then
return
end
player.remoteDataWatcher:UpdateInteger(self.BONE_ACTION, BoneAction.Placing)
if conditionFunc ~= nil and not conditionFunc(self, xi, yi, heldSlot) then
return
end
if removeOneOnSend == nil then
removeOneOnSend = true
end
if removeOneOnSend then
heldSlot:DecrStackSize(1)
end
NetworkProxy.RPCSendServerBound(Mod.current, RPC_ID.SB_PLAYER_MAP_OPERATION,
opType, xi, yi
)
self.placeColdTime = 8
player.direction = xi * 16 + 8 > player.centerX
end
end
---_CanLoadLiquid
---@param xi int
---@param yi int
---@param heldSlot Slot
function GPlayer:_CanLoadLiquid(xi, yi, heldSlot)
if not (heldSlot.hasStack and MiscHelper.IsEmptyBucket(heldSlot:GetStack():GetItem().id)) then
return false
end
local npcs = NpcUtils.SearchByRect(xi * 16 + 8, yi * 16 + 8, 1, 1)
---@param npc Npc
for _, npc in each(npcs) do
if MiscHelper.IsCow(npc.id) then
return true
end
end
local liquidID, amount = MapUtils.GetLiquidIDAmount(xi, yi)
if not (liquidID > 0 and amount > 60) then
return false
end
if MiscHelper.GetBucketIDFromLiquidID(liquidID) == 0 then
return false
end
return true
end
function GPlayer:ServerLoadingLiquid(xi, yi)
local player = self.player
local heldSlot = self:GetHeldSlot()
if not self:_CanLoadLiquid(xi, yi, heldSlot) then
return false
end
local npcs = NpcUtils.SearchByRect(xi * 16 + 8, yi * 16 + 8, 1, 1)
---@param npc Npc
for _, npc in each(npcs) do
if MiscHelper.IsCow(npc.id) then
heldSlot:DecrStackSize(1)
local remain = player.backpackInventory:AddItemStack(ItemStack.new(ItemRegistry.GetItemByID(MiscHelper.GetMilkBucketID())))
if remain:Valid() then
player:DropItem(remain)
end
SoundUtils.PlaySoundGroup(Reg.SoundGroupID("swim"), xi, yi)
return true
end
end
local liquidID = MapUtils.GetLiquidID(xi, yi)
if liquidID == 0 then
return false
end
heldSlot:DecrStackSize(1)
MapUtils.RemoveLiquid(xi, yi)
MapUtils.TriggerLiquid(xi - 1, yi)
MapUtils.TriggerLiquid(xi, yi - 1)
MapUtils.TriggerLiquid(xi, yi + 1)
MapUtils.TriggerLiquid(xi + 1, yi)
local liquidBucketID = MiscHelper.GetBucketIDFromLiquidID(liquidID)
if liquidBucketID > 0 then
local remain = player.backpackInventory:AddItemStack(ItemStack.new(ItemRegistry.GetItemByID(liquidBucketID)))
if remain:Valid() then
player:DropItem(remain)
end
end
SoundUtils.PlaySoundGroup(Reg.SoundGroupID("swim"), xi, yi)
return true
end
function GPlayer:ClientLoadingLiquid()
self:ClientDoMapOp(MapOpType.LoadingLiquid, self._CanLoadLiquid)
end
---_GetLoadBowlNpc
---@param xi int
---@param yi int
---@return Npc
function GPlayer:_GetLoadBowlNpc(xi, yi)
local npcs = NpcUtils.SearchByRect(xi * 16 + 8, yi * 16 + 8, 1, 1)
---@param npc Npc
for _, npc in each(npcs) do
if MiscHelper.IsMushroomCow(npc.id) then
return npc
end
end
return nil
end
---_CanLoadBowl
---@param xi int
---@param yi int
---@param heldSlot Slot
function GPlayer:_CanLoadBowl(xi, yi, heldSlot)
if not (heldSlot.hasStack and MiscHelper.IsEmptyBowl(heldSlot:GetStack():GetItem().id)) then
return false
end
return self:_GetLoadBowlNpc(xi, yi) ~= nil
end
function GPlayer:ServerLoadingBowl(xi, yi)
local player = self.player
local heldSlot = self:GetHeldSlot()
if not self:_CanLoadBowl(xi, yi, heldSlot) then
return false
end
local npc = self:_GetLoadBowlNpc(xi, yi)
if npc == nil then
return false
end
heldSlot:DecrStackSize(1)
local remain = player.backpackInventory:AddItemStack(ItemStack.new(ItemRegistry.GetItemByID(MiscHelper.GetMushroomBowl())))
if remain:Valid() then
player:DropItem(remain)
end
SoundUtils.PlaySoundGroup(Reg.SoundGroupID("swim"), xi, yi)
return true
end
function GPlayer:ClientLoadingBowl()
self:ClientDoMapOp(MapOpType.LoadingBowl, self._CanLoadBowl)
end
function GPlayer:ClientShearing()
--TODO:
--self:ClientDoMapOp(MapOpType.Shearing, self._CanShearing)
end
---_CanLoadBottle
---@param xi int
---@param yi int
---@param heldSlot Slot
function GPlayer:_CanLoadBottle(xi, yi, heldSlot)
local liquidID = MapUtils.GetLiquidID(xi, yi)
if not (heldSlot.hasStack and MiscHelper.IsEmptyGrassBottle(heldSlot:GetStack():GetItem().id)) then
return false
end
if not (liquidID > 0) then
return false
end
return liquidID == Reg.LiquidID("water")
end
function GPlayer:ServerLoadingBottle(xi, yi)
local player = self.player
local heldSlot = self:GetHeldSlot()
if not self:_CanLoadBottle(xi, yi, heldSlot) then
return false
end
heldSlot:DecrStackSize(1)
local remain = player.backpackInventory:AddItemStack(ItemStack.new(ItemRegistry.GetItemByID(Reg.ItemID("potion_water"))))
if remain:Valid() then
player:DropItem(remain)
end
SoundUtils.PlaySoundGroup(Reg.SoundGroupID("swim"), xi, yi)
return true
end
function GPlayer:ClientLoadingBottle()
self:ClientDoMapOp(MapOpType.LoadingBottle, self._CanLoadBottle)
end
function GPlayer:_CanPullLiquid(xi, yi, heldSlot)
if not heldSlot.hasStack then
return false
end
if MapUtils.IsSolid(xi, yi) then
return false
end
local liquidPullID = MiscHelper.GetLiquidIDFromBucket(heldSlot:GetStack():GetItem().id)
if liquidPullID == 0 then
return
end
local liquidID = MapUtils.GetLiquidID(xi, yi)
if liquidID == 0 or liquidID == liquidPullID then
return true
end
return false
end
function GPlayer:ServerPullingLiquid(xi, yi)
local player = self.player
local heldSlot = self:GetHeldSlot()
if not self:_CanPullLiquid(xi, yi, heldSlot) then
return false
end
local liquidPullID = MiscHelper.GetLiquidIDFromBucket(heldSlot:GetStack():GetItem().id)
MapUtils.SetLiquid(xi, yi, liquidPullID)
MapUtils.TriggerLiquid(xi, yi)
heldSlot:DecrStackSize(1)
local remain = player.backpackInventory:AddItemStack(ItemStack.new(ItemRegistry.GetItemByID(MiscHelper.GetEmptyBucketID())))
if remain:Valid() then
player:DropItem(remain)
end
SoundUtils.PlaySoundGroup(Reg.SoundGroupID("swim"), xi, yi)
return true
end
function GPlayer:ClientPullingLiquid()
self:ClientDoMapOp(MapOpType.PullingLiquid, self._CanPullLiquid)
end
---_CanFarm
---@param xi int
---@param yi int
---@param heldSlot Slot
function GPlayer:_CanFarm(xi, yi, heldSlot)
if not heldSlot.hasStack then
return false
end
if heldSlot:GetStack():GetItem().toolType ~= "HOE" then
return
end
local blockID = MapUtils.GetFrontID(xi, yi)
if blockID == 0 then
return false
end
return MiscHelper.CanTransformToFramland(blockID)
end
function GPlayer:ServerFarming(xi, yi)
local player = self.player
local heldSlot = self:GetHeldSlot()
if not self:_CanFarm(xi, yi, heldSlot) then
return false
end
MapUtils.RemoveFront(xi, yi)
MapUtils.PlaceFront(xi, yi, MiscHelper.GetFarmlandID())
if player.gameMode ~= GameMode.Creative then
--heldSlot:GetStack():LoseDurable(1)
end
SoundUtils.PlaySoundGroup(Reg.SoundGroupID("farm"), xi, yi)
return true
end
function GPlayer:ClientFarming()
self:ClientDoMapOp(MapOpType.Farming, self._CanFarm, false)
end
---@param xi int
---@param yi int
---@param heldSlot Slot
function GPlayer:_CanSeeding(xi, yi, heldSlot)
if not heldSlot.hasStack then
return false
end
if not MapUtils.IsAreaValid(xi, yi, 1, 2) then
return false
end
if MapUtils.HasFront(xi, yi) then
return false
end
local downID = MapUtils.GetFrontID(xi, yi + 1)
if downID == 0 then
return false
end
if not MapUtils.IsSolid(xi, yi + 1) then
return false
end
local item = heldSlot:GetStack():GetItem()
if not (item.isSeed and item.blockID > 0) then
return false
end
if not MapUtils.CanPlaceFront(xi, yi, item.blockID) then
return false
end
local data = BlockUtils.GetData(downID)
if not data:CanSeed(item.id) then
return false
end
return true
end
function GPlayer:ServerSeeding(xi, yi)
local heldSlot = self:GetHeldSlot()
if not self:_CanSeeding(xi, yi, heldSlot) then
return false
end
local item = heldSlot:GetStack():GetItem()
MapUtils.PlaceFront(xi, yi, item.blockID)
heldSlot:DecrStackSize(1)
SoundUtils.PlaySoundGroup(Reg.SoundGroupID("farm"), xi, yi)
return true
end
function GPlayer:ClientSeeding()
self:ClientDoMapOp(MapOpType.Seeding, self._CanSeeding)
end
---@param xi int
---@param yi int
---@param heldSlot Slot
function GPlayer:_CanRipen(xi, yi, heldSlot)
if not heldSlot.hasStack then
return false
end
if not MiscHelper.IsBoneMeal(heldSlot:GetStack():GetItem().id) then
return false
end
if not MapUtils.HasFront(xi, yi) then
return false
end
return true
end
function GPlayer:ServerRipen(xi, yi)
local heldSlot = self:GetHeldSlot()
if not self:_CanRipen(xi, yi, heldSlot) then
return false
end
MapUtils.DoRandomTick(xi, yi)
heldSlot:DecrStackSize(1)
SoundUtils.PlaySound(Reg.SoundID("shear"), xi, yi)
return true
end
function GPlayer:ClientRipening()
self:ClientDoMapOp(MapOpType.Ripening, self._CanRipen)
end
function GPlayer:OnMapOpServerBound(opType, xi, yi)
local heldSlot = self:GetHeldSlot()
local success = false
local func = self._mapOpFunc[opType]
if func ~= nil then
success = func(self, xi, yi)
end
if not success then
MapUtils.SyncUnit(xi, yi)
heldSlot:SyncAll()
end
end
function GPlayer.GetMiningToolType(toolType)
if toolType == "DRILL" then
return "PICKAXE"
elseif toolType == "SAW" then
return "AXE"
end
return toolType
end
function GPlayer:ClientDigging()
local xi, yi, op = self:CheckAimPositionInMap()
local player = self.player
-- Just switch the held slot, skip process
if player.heldSlotIndexJustChanged then
return
end
local operatingWall = InputControl.getInstance().operatingWall
local heldSlot = self:GetHeldSlot()
if not heldSlot.hasStack then
return
end
local stack = heldSlot:GetStack()
local item = stack:GetItem()
local isSmart = InputControl.getInstance().isSmart
if not item.isTool then
return
end
local toolType = GPlayer.GetMiningToolType(item.toolType)
if isSmart then
player:SetSmartMode(SmartMode.Digging, xi, yi, operatingWall, stack, toolType)
end
if op == 1 then
local readyToRequest = false
if isSmart and player.isSmartPositionFound then
xi, yi = player:GetSmartPosition()
readyToRequest = true
else
if SettingsData.isMobileOperation then
readyToRequest = true
else
readyToRequest = self:InInteractionDistanceIPos(xi, yi)
end
end
if readyToRequest then
player:RequestDigBlock(xi, yi, player.heldSlotIndex, operatingWall, toolType)
player.remoteDataWatcher:UpdateInteger(self.BONE_ACTION, BoneAction.Digging)
end
end
end
function GPlayer:InInteractionDistanceIPos(xi, yi)
local player = self.player
return player:GetDistance(xi * 16 + 8, yi * 16 + 8) < INTERACTION_DISTANCE
end
function GPlayer:OnRender()
self.bone.joints:render(cameraInGameInstance.camera)
local slot = self:GetHeldSlot()
if slot.hasStack then
local stack = slot:GetStack()
stack:RunOnHeldRenderEvent(self.player)
end
end
function GPlayer:TryUseHeldItem()
local slot = self:GetHeldSlot()
if slot.hasStack then
local stack = slot:GetStack()
if stack:CanUse(self.player) then
self:UseHeldItem()
end
end
end
function GPlayer:UseHeldItem()
local slot = self:GetHeldSlot()
if slot.hasStack then
local stack = slot:GetStack()
stack:RunOnUsedEvent(self.player)
local killed = false
if stack:GetItem().maxDurable > 0 and stack.durable == 0 then
if stack:RunOnDurableEmptyEvent(self.player) then
slot:ClearStack()
killed = true
end
end
if not killed then
local modItem = stack:GetModItem()
if modItem ~= nil and modItem.IsKilledAfterUsed ~= nil and modItem:IsKilledAfterUsed() then
if modItem.OnKilledAfterUsed then
modItem:OnKilledAfterUsed(self.player)
end
slot:DecrStackSize(1)
killed = true
end
end
end
end
function GPlayer:GetHeldItemJoint()
return self.bone.joints:getJoint("base.body.back_arm.back_hand.back_item")
end
function GPlayer:UpdateLookAngle()
if NetMode.current == NetMode.Client and self.player.isCurrentClientPlayer then
self.player.lookAngle = 0
if SettingsData.isMobileOperation then
if InputControl.getInstance().aimDistance > 0 then
self.player.lookAngle = Vector2.new(self.aimOffsetX, self.aimOffsetY).angle
else
if not self.player.facingDirection then
self.player.lookAngle = math.pi
end
end
else
-- PC
self.player.lookAngle = Vector2.new(self.aimOffsetX, self.aimOffsetY).angle
end
self:FacingByLookAngle()
end
end
function GPlayer:FacingByLookAngle()
if self.aimOffsetX ~= 0 then
local lastFacing = self.player.facingDirection
self.player.facingDirection = self.aimOffsetX > 0
if self.player.facingDirection ~= lastFacing then
self.bone.joints.flip = not self.player.facingDirection
self.bone:update(false)
end
end
end
function GPlayer:GetLookAngleInFacingDirection()
local lookAngle = self.player.lookAngle
if not (lookAngle > -math.pi * 0.5 and lookAngle < math.pi * 0.5) then
lookAngle = math.pi - lookAngle
lookAngle = Utils.FixAngle(lookAngle)
end
return lookAngle
end
function GPlayer:CheckAimPositionInMap()
InputControl.getInstance().aimMode = ControlAimMode.LookPositionOrUse
return self:GetAimPositionInMap()
end
function GPlayer:GetAimPositionInMap()
local xi = Utils.Cell(self.player.centerX + self.aimOffsetX)
local yi = Utils.Cell(self.player.centerY + self.aimOffsetY)
local op = 0
if SettingsData.isMobileOperation then
if InputControl.getInstance().aimTriggerUsing then
op = 1
end
else
-- PC
if InputControl.getInstance().isPcMouseLeftPressingAtMap then
op = 1
elseif InputControl.getInstance().isPcMouseRightPressingAtMap then
op = 2
end
end
return xi, yi, op
end
function GPlayer:GetHeldSlot()
return self.player.backpackInventory:GetSlot(self.player.heldSlotIndex)
end
function GPlayer:GetAmmoIndexInBackpack(ammoID, ammoLevel, searchBest)
local backpack = self.player.backpackInventory
local count = backpack.slotCount
local res = -1
local baseAmmoRes = -1
local minBestAmmoLevel = -1
for i = 1, count do
local slot = backpack:GetSlot(i - 1)
if slot.hasStack then
local item = slot:GetStack():GetItem()
if item.isProjectile and item.ammoID == ammoID then
if not searchBest and item.ammoLevel == ammoLevel then
res = i - 1
break
elseif searchBest and item.ammoLevel > minBestAmmoLevel then
minBestAmmoLevel = item.ammoLevel
res = i - 1
elseif baseAmmoRes ~= -1 and item.ammoLevel == 0 then
baseAmmoRes = i - 1
end
end
end
end
-- Use the same ammo level slot first.
-- If no same level slot found, then we use level 0 slot.
if res == -1 then
res = baseAmmoRes
end
return res
end
function GPlayer:RecalculateProperties()
local player = self.player
local enchantmentProxies = EnchantmentProxies.getInstance()
local buffProxies = BuffProxies.getInstance()
player.baseAttack:Restore()
player.baseDefense:Restore()
self.manaAddSpeed = 128
if player.dying then
return
end
DebugHelper.RunDebugProp(player)
local heldSlot = self:GetHeldSlot()
if heldSlot.hasStack then
local stack = heldSlot:GetStack()
local item = stack:GetItem()
player.baseAttack.attack = player.baseAttack.attack + item.baseAttack.attack
player.baseAttack.knockBack = player.baseAttack.knockBack + item.baseAttack.knockBack
player.baseAttack.crit = player.baseAttack.crit + item.baseAttack.crit
enchantmentProxies:OnHeld(stack, player)
end
local equipmentInventory = player.equipmentInventory
local fullDressName = nil
for i = 0, 2 do
local equipmentSlot = equipmentInventory:GetSlot(i)
if equipmentSlot.hasStack then
local stack = equipmentSlot:GetStack()
local item = stack:GetItem()
player.baseDefense.defense = player.baseDefense.defense + item.defense
enchantmentProxies:OnEquipped(i, stack, player)
if i == 0 then
fullDressName = DressMappings[i + 1][item.id]
elseif fullDressName then
local name = DressMappings[i + 1][item.id]
if name ~= fullDressName then
fullDressName = nil
end
end
else
fullDressName = nil
end
end
if player.tickTime % 64 == 0 then
local backpackInventory = player.backpackInventory
for i = 0, backpackInventory.slotCount - 1 do
local slot = backpackInventory:GetSlot(i)
if slot.hasStack then
enchantmentProxies:OnUpdateSecond(slot:GetStack(), player)
end
end
for i = 0, 2 do
local slot = equipmentInventory:GetSlot(i)
if slot.hasStack then
enchantmentProxies:OnUpdateSecond(slot:GetStack(), player)
end
end
end
buffProxies:OnUpdatePlayer(player)
if fullDressName then
self:OnFullDress(fullDressName)
end
if NetMode.current == NetMode.Server then
-- food
if player.gameMode ~= GameMode.Creative then
local interval = 256
if math.abs(player.speedX) < 0.5 then
interval = 1024
end
if player.foodSaturationLevel > 0 then
if player.tickTime % interval == 0 then
player.foodSaturationLevel = player.foodSaturationLevel - 1
end
else
player.foodSaturationLevel = 0
if player.foodLevel > 0 then
if player.tickTime % interval == 0 then
player.foodLevel = player.foodLevel - 1
end
else
if player.tickTime % 32 == 0 then
player:Strike(DeathReason.STARVE, Attack.new(1, 0, 0))
end
end
end
end
-- auto add hp
if player.health < player.maxHealth then
if player.foodLevel >= 90 then
if player.foodLevel == 100 then
if player.tickTime % 64 == 0 then
player:Heal(1, false)
end
else
if player.tickTime % 128 == 0 then
player:Heal(1, false)
end
end
end
end
-- auto add magic
local maxAutoMana = math.floor(player.maxMana * 0.80)
if player.mana < maxAutoMana then
local sp = math.max(1, math.ceil(self.manaAddSpeed))
if player.tickTime % sp == 0 then
local offset = math.min(4, maxAutoMana - player.mana)
if offset > 0 then
player:AddMagic(offset, false)
end
end
end
end
for i = 1, self.accessoryInventory.slotCount do
local slot = self.accessoryInventory:GetSlot(i - 1)
if slot.hasStack then
local stack = slot:GetStack()
local modItem = stack:GetModItem()
if modItem ~= nil and modItem.OnAccessoryUpdate ~= nil then
modItem:OnAccessoryUpdate(player)
end
end
end
end
function GPlayer:OnFullDress(fullDressName)
local data = FullDress[fullDressName]
if data == nil then
return
end
local player = self.player
if data.advancementID ~= nil then
player:FinishAdvancement(data.advancementID)
end
if data.defense ~= nil then
player.baseDefense.defense = player.baseDefense.defense + data.defense
end
if data.attack ~= nil then
player.baseAttack.attack = player.baseAttack.attack + data.attack
end
if data.fireDefense then
if player.tickTime % 64 == 0 then
player:AddBuff(Reg.BuffID("fire_defense"), 100)
end
end
if data.lighting then
LightingUtils.Add(player.centerXi, player.centerYi, 32)
end
if data.speed ~= nil then
player.speedRate = player.speedRate + data.speed
if math.abs(player.speedX) > 2 then
if player.tickTime % 8 == 0 then
if player.stand then
EffectUtils.Create(Reg.EffectID("smoke"),
player.randX,
player.bottomY,
Utils.RandSym(0.25),
Utils.RandSym(0.25),
Utils.RandSym(0.1), 0.25)
else
EffectUtils.Create(Reg.EffectID("smoke"),
player.randX,
player.randY,
-player.speedX / 8 + Utils.RandSym(0.5),
-player.speedY / 8 + Utils.RandSym(0.5),
Utils.RandSym(0.1), 0.5, 0.2)
end
end
end
end
if data.manaAddSpeed ~= nil then
self.manaAddSpeed = self.manaAddSpeed * data.manaAddSpeed
end
end
function GPlayer:HasAccessory(itemID)
for i = 1, self.accessoryInventory.slotCount do
local slot = self.accessoryInventory:GetSlot(i - 1)
if slot.hasStack then
local stack = slot:GetStack()
if stack:GetItem().id == itemID then
return true
end
end
end
return false
end
function GPlayer:OnHitByNpc(npc)
local player = self.player
local enchantmentProxies = EnchantmentProxies.getInstance()
for i = 0, 2 do
local equipmentSlot = equipmentInventory:GetSlot(i)
if equipmentSlot.hasStack then
local stack = equipmentSlot:GetStack()
enchantmentProxies:OnEquippedHitByNpc(i, stack, player, npc)
end
end
end
function GPlayer:OnHitByProjectile(projectile)
local player = self.player
local enchantmentProxies = EnchantmentProxies.getInstance()
for i = 0, 2 do
local equipmentSlot = equipmentInventory:GetSlot(i)
if equipmentSlot.hasStack then
local stack = equipmentSlot:GetStack()
enchantmentProxies:OnEquippedHitByProjectile(i, stack, player, projectile)
end
end
end
---GetInstance
---@param player Player
---@return TC.GPlayer
function GPlayer.GetInstance(player)
return player:GetGlobalPlayer("tc:GPlayer")
end
function GPlayer:Save()
return {
accessoryInventory = self.accessoryInventory:Serialization(),
}
end
function GPlayer:Load(tagTable)
if tagTable.accessoryInventory ~= nil then
Inventory.Deserialization(self.accessoryInventory, tagTable.accessoryInventory)
end
end
function GPlayer:SaveCSC()
local player = self.player
local csc = {
health = player.health,
maxHealth = player.maxHealth,
mana = player.mana,
maxMana = player.maxMana,
foodSaturationLevel = player.foodSaturationLevel,
foodLevel = player.foodLevel,
expLevel = player.expLevel,
remainExp = player.remainExp,
backpackInventory = player.backpackInventory:Serialization(),
equipmentInventory = player.equipmentInventory:Serialization(),
enderInventory = player.enderInventory:Serialization(),
accessoryInventory = self.accessoryInventory:Serialization(),
}
--print("save csc:", csc)
return csc
end
function GPlayer:LoadCSC(csc)
--print("load csc:", csc)
local player = self.player
if csc.health ~= nil then
player.health = csc.health
end
if csc.maxHealth ~= nil then
player.maxHealth = csc.maxHealth
end
if csc.mana ~= nil then
player.mana = csc.mana
end
if csc.maxMana ~= nil then
player.maxMana = csc.maxMana
end
if csc.foodSaturationLevel ~= nil then
player.foodSaturationLevel = csc.foodSaturationLevel
end
if csc.foodLevel ~= nil then
player.foodLevel = csc.foodLevel
end
if csc.expLevel ~= nil then
player.expLevel = csc.expLevel
end
if csc.remainExp ~= nil then
player.remainExp = csc.remainExp
end
if csc.backpackInventory ~= nil then
Inventory.Deserialization(player.backpackInventory, csc.backpackInventory)
end
if csc.equipmentInventory ~= nil then
Inventory.Deserialization(player.equipmentInventory, csc.equipmentInventory)
end
if csc.enderInventory ~= nil then
Inventory.Deserialization(player.enderInventory, csc.enderInventory)
end
if csc.accessoryInventory ~= nil then
Inventory.Deserialization(self.accessoryInventory, csc.accessoryInventory)
end
end
function GPlayer:OnInventoryChanged()
--print("OnInventoryChanged")
end
function GPlayer:OnInventoryItemAdded(itemID, stackSize)
--print("OnInventoryItemAdded", Reg.ItemIDName(itemID), stackSize)
AdvancementTriggers.getInstance():TriggerGetItem(self.player, itemID, stackSize)
if self.recipeBookHookUI ~= nil then
self.recipeBookHookUI:RefreshDisplayState()
end
end
function GPlayer:OnInventoryItemRemoved(itemID, stackSize)
--print("OnInventoryItemRemoved", Reg.ItemIDName(itemID), stackSize)
end
function GPlayer:OnAdvancementMade(advancementID)
--print("OnAdvancementMade", Reg.AdvancementIDName(advancementID))
local HudUI = require("ui.hud.HudUI")
HudUI.showAdvancementTip(advancementID)
end
function GPlayer:OnAdvancementRemoved(advancementID)
--print("OnAdvancementRemoved", Reg.AdvancementIDName(advancementID))
end
function GPlayer:OnKilled()
--print("player killed")
end
local s_advancement_hunter = Reg.AdvancementID("hunter")
local s_advancement_leather = Reg.AdvancementID("leather")
---OnKillNpc
---@param npc Npc
function GPlayer:OnKillNpc(npc)
AdvancementTriggers.getInstance():TriggerKillNpc(self.player, npc)
-- kill any npc
if not self.player:IsAdvancementFinished(s_advancement_leather) then
self.player:FinishAdvancement(s_advancement_leather)
end
-- kill enemy
if not self.player:IsAdvancementFinished(s_advancement_hunter) then
if not npc.friendly or npc.angry then
self.player:FinishAdvancement(s_advancement_hunter)
end
end
end
function GPlayer:OnRespawn()
--print("player respawn")
local player = self.player
player.health = 100
if player.health > player.maxHealth then
player.health = player.maxHealth
end
player.mana = 0
player.foodLevel = 100
player.foodSaturationLevel = 100
if not self:HasAccessory(Reg.ItemID("gold_talisman")) then
player.expLevel = math.floor(player.expLevel * 0.8)
else
player.expLevel = math.floor(player.expLevel * 0.9)
end
player.remainExp = 0
end
return GPlayer
================================================
FILE: player/GlobalPlayer.json
================================================
{
"GlobalClass": [
"GPlayer"
]
}
================================================
FILE: player/PlayerConstants.lua
================================================
local PlayerConstants = {
StartHealth = 100,
StartMaxHealth = 100,
StartMana = 100,
StartMaxMana = 100,
StartFoodLevel = 100,
StartSaturationLevel = 100,
MaxHealthA = 400, -- 暮色森林层前,最大400
MaxManaA = 1000, -- 暮色森林层前,最大1000
GRAVITY = 0.40625,
WALK_FORCE = 0.1,
TURN_FORCE = 0.2,
DECELERATE_STOP = 0.2131,
DECELERATE_STOP_AIR = 0.1,
MAX_SPEED_WALK = 3.0,
MAX_SPEED_UP = 9.25,
MAX_SPEED_DOWN = 12.0,
JUMP_SPEED = 5.1,
JUMP_UP_TIME = 19,
INTERACTION_DISTANCE = 144,
MOVE_RATE_DISTANCE = 192,
}
return PlayerConstants
================================================
FILE: projectile_ai/AirBullet.json
================================================
{
"AirBullet": {
"script": {
"path": "AirBullet.lua"
},
"modData": [
[ "int", "bounceTimes" ]
]
}
}
================================================
FILE: projectile_ai/AirBullet.lua
================================================
---@type ModProjectile
local AirBullet = class("AirBullet", ModProjectile)
---@param oldSpeedX double
---@param oldSpeedY double
function AirBullet:TileBounce(oldSpeedX, oldSpeedY)
local projectile = self.projectile
if projectile.stand or projectile.isCollisionTop then
projectile.speedY = -oldSpeedY
elseif projectile.isCollisionLeft or projectile.isCollisionRight then
projectile.speedX = -oldSpeedX
end
projectile.modData.bounceTimes = projectile.modData.bounceTimes + 1
end
function AirBullet:TouchBounce()
local projectile = self.projectile
local angle = projectile.speedAngle
angle = angle + math.pi + Utils.RandSym(0.2)
local speed = Utils.GetDistance(projectile.speedX, projectile.speedY)
projectile.speedX = speed * math.cos(angle)
projectile.speedY = speed * math.sin(angle)
projectile.modData.bounceTimes = projectile.modData.bounceTimes + 1
end
function AirBullet:Update()
local projectile = self.projectile
projectile.rotateAngle = projectile.speedAngle
if projectile.tickTime % 4 == 0 then
EffectUtils.Create(
Reg.EffectID("chip"),
projectile.hots[1].x,
projectile.hots[1].y,
projectile.speedX / 4 + Utils.RandSym(0.5),
projectile.speedY / 4 - Utils.RandDouble(2),
Utils.RandSym(1),
Utils.RandDoubleArea(1, 0.5),
0,
Color.new(200, 200, 255)
)
end
if projectile.tickTime % 8 == 0 then
EffectUtils.Create(
Reg.EffectID("flash2"),
projectile.hots[1].x,
projectile.hots[1].y,
projectile.speedX / 4 + Utils.RandSym(0.5),
projectile.speedY / 4 - Utils.RandDouble(2),
0,
Utils.RandDoubleArea(1, 0.5),
0,
Color.new(200, 200, 255)
)
end
end
function AirBullet:OnKilled()
local projectile = self.projectile
local chipId = Reg.EffectID("chip")
for _ = 1, 8 do
EffectUtils.Create(
chipId, projectile.centerX, projectile.centerY,
-projectile.speedX / 4 + Utils.RandSym(2),
-projectile.speedY / 4 - Utils.RandDouble(3),
Utils.RandSym(1),
Utils.RandDoubleArea(1, 0.5)
)
end
end
function AirBullet:OnHitNpc(_, _)
if self.projectile.modData.bounceTimes > 1 then
self.projectile:Kill()
else
self:TouchBounce()
end
end
function AirBullet:OnHitPlayer(_, _)
if self.projectile.modData.bounceTimes > 1 then
self.projectile:Kill()
else
self:TouchBounce()
end
end
---OnTileCollide
---@param oldSpeedX double
---@param oldSpeedY double
function AirBullet:OnTileCollide(oldSpeedX, oldSpeedY)
if self.projectile.modData.bounceTimes > 4 then
self.projectile:Kill()
else
self:TileBounce(oldSpeedX, oldSpeedY)
end
end
return AirBullet
================================================
FILE: projectile_ai/AirWave.json
================================================
{
"AirWave": {
"script": {
"path": "AirWave.lua"
}
}
}
================================================
FILE: projectile_ai/AirWave.lua
================================================
---@class TC.AirWave:ModProjectile
local AirWave = class("AirWave", ModProjectile)
function AirWave:TouchEffect()
local projectile = self.projectile
for _ = 1, 4 do
EffectUtils.Create(
Reg.EffectID("star"),
projectile.centerX,
projectile.centerY,
Utils.RandSym(1),
Utils.RandSym(1),
0,
Utils.RandDoubleArea(0.4, 0.1),
Utils.RandDoubleArea(0.5, 0.5),
Color.new(177, 177, 255)
)
end
end
function AirWave:Update()
local projectile = self.projectile
projectile.rotateAngle = projectile.speedAngle
local effect = EffectUtils.Create(
Reg.EffectID("circle"),
projectile.hots[1].x + Utils.RandSym(10),
projectile.hots[1].y + Utils.RandSym(10),
projectile.speedX / 4 + Utils.RandSym(0.25),
projectile.speedY / 4 + Utils.RandSym(0.25),
Utils.RandSym(1),
Utils.RandDoubleArea(0.15, 0.15),
1.0,
Color.new(200, 255, 255)
)
effect:SetDisappearTime(30)
end
function AirWave:OnHitNpc(_, _)
self:TouchEffect()
self.projectile:Kill()
end
function AirWave:OnHitPlayer(_, _)
self:TouchEffect()
self.projectile:Kill()
end
function AirWave:OnTileCollide(_, _)
self:TouchEffect()
self.projectile:Kill()
end
return AirWave
================================================
FILE: projectile_ai/AmethystMagic.json
================================================
{
"AmethystMagic": {
"script": {
"path": "AmethystMagic.lua"
}
}
}
================================================
FILE: projectile_ai/AmethystMagic.lua
================================================
---@type ModProjectile
local AmethystMagic = class("AmethystMagic", ModProjectile)
function AmethystMagic:Update()
local projectile = self.projectile
projectile:Rotate(0.4)
if projectile.tickTime % 8 == 0 then
EffectUtils.Create(
Reg.EffectID("star"),
projectile.hots[1].x,
projectile.hots[1].y,
projectile.speedX / 4 + Utils.RandSym(1),
projectile.speedY / 4 + Utils.RandSym(1),
Utils.RandSym(0.1),
Utils.RandDoubleArea(0.5, 0.5),
1.0,
Color.new(160, 100, 255)
)
end
if projectile.tickTime % 4 == 0 then
EffectUtils.Create(
Reg.EffectID("flash2"),
projectile.hots[1].x,
projectile.hots[1].y,
projectile.speedX / 4 + Utils.RandSym(2),
projectile.speedY / 4 + Utils.RandSym(2),
0,
Utils.RandDoubleArea(1, 1),
1.0,
Color.new(160, 100, 255)
)
end
LightingUtils.AddDelay(projectile.centerXi, projectile.centerYi, 32, 24, 8, 0, 16)
end
function AmethystMagic:OnKilled()
local projectile = self.projectile
local flash2 = Reg.EffectID("flash2")
for _ = 1, 8 do
EffectUtils.Create(
flash2,
projectile.centerX,
projectile.centerY,
Utils.RandSym(2),
Utils.RandSym(2),
0,
Utils.RandDoubleArea(1, 1),
1.0,
Color.new(160, 100, 255)
)
end
end
function AmethystMagic:OnHitNpc(_, _)
self.projectile:Kill()
end
function AmethystMagic:OnHitPlayer(_, _)
self.projectile:Kill()
end
function AmethystMagic:OnTileCollide(_, _)
self.projectile:Kill()
end
return AmethystMagic
================================================
FILE: projectile_ai/Arrow.json
================================================
{
"Arrow": {
"script": {
"path": "Arrow.lua"
},
"modData": [
[ "int", "attachItemID" ],
[ "int", "flameLevel" ],
[ "int", "piercingCount" ]
]
}
}
================================================
FILE: projectile_ai/Arrow.lua
================================================
---@type ModProjectile
local Arrow = class("AmethystMagic", ModProjectile)
function Arrow:Update()
local projectile = self.projectile
projectile.rotateAngle = projectile.speedAngle
if projectile.modData.flameLevel > 0 then
if projectile.tickTime % 4 == 0 then
EffectUtils.Create(
Reg.EffectID("fire_flame"),
projectile.hots[1].x,
projectile.hots[1].y,
Utils.RandSym(2),
Utils.RandSym(2),
Utils.RandSym(0.1),
Utils.RandDoubleArea(0.5, 0.5)
)
end
end
end
function Arrow:PostUpdate()
local projectile = self.projectile
if projectile.modData.flameLevel == 0 then
if projectile.tickTime % 2 == 0 then
EffectUtils.Create(
Reg.EffectID("arrow_paticular"),
projectile.hots[1].x,
projectile.hots[1].y,
Utils.RandSym(0.5),
Utils.RandSym(0.5),
Utils.RandSym(0.25)
)
end
end
end
function Arrow:OnKilled()
local projectile = self.projectile
if projectile.modData.flameLevel > 0 then
local effectId = Reg.EffectID("fire_flame")
for _ = 1, 4 do
EffectUtils.Create(
effectId,
projectile.centerX,
projectile.centerY,
Utils.RandSym(2),
Utils.RandDoubleArea(-2, 3),
Utils.RandSym(1),
Utils.RandDoubleArea(1, 0.5),
1.0,
Color.new(200, 200, 200)
)
end
else
local effectId = Reg.EffectID("chip")
for _ = 1, 4 do
EffectUtils.Create(
effectId,
projectile.centerX,
projectile.centerY,
Utils.RandSym(2),
Utils.RandDoubleArea(-2, 3),
Utils.RandSym(1),
Utils.RandDoubleArea(1, 0.5),
1.0,
Color.new(200, 200, 200)
)
end
end
SoundUtils.PlaySound(Reg.SoundID("bowhit"), projectile.centerXi, projectile.centerYi)
--EffectUtils.CreateExplosion(projectile.centerX, projectile.centerY)
end
function Arrow:OnHitNpc(npc, _)
local projectile = self.projectile
if projectile.modData.flameLevel > 0 then
npc:AddBuff(Reg.BuffID("fire"), 60 * (projectile.modData.flameLevel + 1))
end
if projectile.modData.piercingCount > 0 then
projectile.modData.piercingCount = projectile.modData.piercingCount - 1
else
projectile:Kill()
end
end
function Arrow:OnHitPlayer(player, _)
local projectile = self.projectile
if projectile.modData.flameLevel > 0 then
player:AddBuff(Reg.BuffID("fire"), 60 * (projectile.modData.flameLevel + 1))
end
projectile:Kill()
end
function Arrow:OnTileCollide(_, _)
local projectile = self.projectile
if self.attachItemID ~= nil and self.attachItemID > 0 then
ItemUtils.CreateDrop(self.attachItemID, 1, projectile.centerX, projectile.centerY,
-1.5 * math.cos(projectile.rotateAngle), -4 * math.sin(projectile.rotateAngle))
end
projectile:Kill()
end
return Arrow
================================================
FILE: projectile_ai/BlackHole.json
================================================
{
"BlackHole": {
"script": {
"path": "BlackHole.lua"
}
}
}
================================================
FILE: projectile_ai/BlackHole.lua
================================================
---@class TC.BlackHole:ModProjectile
local BlackHole = class("BlackHole", ModProjectile)
function BlackHole:Update()
local projectile = self.projectile
local angle = projectile.speedAngle
local speed = Vector2.new(projectile.speedX, projectile.speedY).length
if speed < 0.2 then
projectile:Kill()
return
end
speed = speed * 0.98
projectile.speedX = speed * math.cos(angle)
projectile.speedY = speed * math.sin(angle)
if projectile.isCheckNpc then
local npcTarget = NpcUtils.SearchNearestEnemy(projectile.centerX, projectile.centerY, 128)
if npcTarget ~= nil then
npcTarget.speedX, npcTarget.speedY = Utils.ForceSpeed2D(npcTarget.speedX, npcTarget.speedY, 0.5,
npcTarget:GetAngleTo(projectile.centerX, projectile.centerY), 4.0)
if npcTarget.stand then
npcTarget.speedY = -6
end
end
end
if projectile.tickTime % 1 == 0 then
local effectAngle = Utils.RandSym(math.pi)
local d = 96
local effectX = projectile.centerX + math.cos(effectAngle) * d
local effectY = projectile.centerY + math.sin(effectAngle) * d
local effectSpeed = 6
local effectSpeedAngle = Utils.FixAngle(effectAngle + math.pi)
local spx = projectile.speedX + math.cos(effectSpeedAngle) * effectSpeed
local spy = projectile.speedY + math.sin(effectSpeedAngle) * effectSpeed
local colorChannel = Utils.RandIntArea(64, 140)
EffectUtils.Create(
Reg.EffectID("flash2"),
effectX,
effectY,
spx,
spy,
Utils.RandSym(0.5),
Utils.RandDoubleArea(0.5,0.7),
1,
Color.new(colorChannel, colorChannel, colorChannel)
)
end
LightingUtils.AddDelay(projectile.centerXi, projectile.centerYi, 32, 30)
end
function BlackHole:OnKilled()
local projectile = self.projectile
local flash2 = Reg.EffectID("flash2")
for _ = 1, 12 do
local colorChannel = Utils.RandIntArea(100, 140)
EffectUtils.Create(flash2,
projectile.centerX,
projectile.centerY,
Utils.RandSym(6),
Utils.RandSym(6),
0,
Utils.RandDoubleArea(1, 1),
1.0,
Color.new(colorChannel, colorChannel, colorChannel)
)
end
end
function BlackHole:OnHitNpc(npc, hitAttack)
--self.projectile:Kill()
end
function BlackHole:OnHitPlayer(player, hitAttack)
--self.projectile:Kill()
end
function BlackHole:OnTileCollide(oldSpeedX, oldSpeedY)
--self.projectile:Kill()
end
return BlackHole
================================================
FILE: projectile_ai/BlazeRod.json
================================================
{
"BlazeRod": {
"script": {
"path": "BlazeRod.lua"
},
"modData": [
[ "int", "beginDir" ]
]
}
}
================================================
FILE: projectile_ai/BlazeRod.lua
================================================
---@type ModProjectile
local BlazeRod = class("BlazeRod", ModProjectile)
function BlazeRod:Update()
local projectile = self.projectile
local ownerNpc = NpcUtils.Get(projectile.npcOwnerIndex)
if ownerNpc ~= nil then
local angle = projectile.modData.beginDir * math.pi / 2 + projectile.tickTime / 32
local d = Utils.SinValue(projectile.tickTime, 128) * 8 + 56
projectile.x = ownerNpc.centerX + math.cos(angle) * d - projectile.width / 2
projectile.y = ownerNpc.centerY + math.sin(angle) * d - projectile.height / 2
projectile.rotateAngle = angle + math.pi / 2
if projectile.tickTime % 8 == 0 then
EffectUtils.Create(
Reg.EffectID("fire_flame"),
projectile.centerX,
projectile.centerY,
0,
0,
Utils.RandSym(1),
Utils.RandDoubleArea(0.5, 0.5),
1
)
end
else
projectile:Kill()
end
end
return BlazeRod
================================================
FILE: projectile_ai/BloodArrow.json
================================================
{
"BloodArrow": {
"defaultAI": "Arrow",
"script": {
"path": "BloodArrow.lua"
}
}
}
================================================
FILE: projectile_ai/BloodArrow.lua
================================================
---@type ModProjectile
local BloodArrow = class("BloodArrow", require("Arrow"))
function BloodArrow:PostUpdate()
local projectile = self.projectile
if projectile.modData.flameLevel == 0 then
if projectile.tickTime % 2 == 0 then
EffectUtils.Create(
Reg.EffectID("arrow_paticular"),
projectile.hots[1].x,
projectile.hots[1].y,
projectile.speedX / 8 + Utils.RandSym(2),
projectile.speedY / 8 + Utils.RandSym(2),
0,
Utils.RandDoubleArea(1, 1),
0,
Color.Red
)
end
end
LightingUtils.AddDelay(projectile.centerXi, projectile.centerYi, 16, 20, 12)
end
---OnHitNpc
---@param npc Npc
---@param hitAttack Attack
function BloodArrow:OnHitNpc(npc, hitAttack)
local projectile = self.projectile
npc:AddBuff(Reg.BuffID("hurt"), 120)
if projectile.modData.flameLevel > 0 then
npc:AddBuff(Reg.BuffID("fire"), 60 * (projectile.modData.flameLevel + 1))
end
if projectile.modData.piercingCount > 0 then
projectile.modData.piercingCount = projectile.modData.piercingCount - 1
else
projectile:Kill()
end
end
---OnHitPlayer
---@param player Player
---@param hitAttack Attack
function BloodArrow:OnHitPlayer(player, hitAttack)
local projectile = self.projectile
player:AddBuff(Reg.BuffID("hurt"), 120)
if projectile.modData.flameLevel > 0 then
player:AddBuff(Reg.BuffID("fire"), 60 * (projectile.modData.flameLevel + 1))
end
projectile:Kill()
end
return BloodArrow
================================================
FILE: projectile_ai/BlueArrow.json
================================================
{
"BlueArrow": {
"script": {
"path": "BlueArrow.lua"
}
}
}
================================================
FILE: projectile_ai/BlueArrow.lua
================================================
---@class TC.BlueArrow:ModProjectile
local BlueArrow = class("BlueArrow", ModProjectile)
function BlueArrow:Update()
local projectile = self.projectile
projectile.rotateAngle = projectile.speedAngle
if projectile.tickTime % 2 == 0 then
local spx = projectile.speedX / 4 + Utils.RandSym(1)
local spy = projectile.speedY / 4 + Utils.RandSym(1)
local effect = EffectUtils.Create(
Reg.EffectID("chip_fast"),
projectile.hots[1].x,
projectile.hots[1].y,
spx,
spy,
Utils.RandSym(0.1),
Utils.RandDoubleArea(1.0, 1.0)
)
effect.lightAlpha = 24
effect.color = Color.new(255, 100, 255)
effect.gravity = false
end
projectile.gravity = 0
end
function BlueArrow:OnKilled()
local projectile = self.projectile
local effectId = Reg.EffectID("chip_fast")
for _ = 1, 8 do
local spx = -projectile.speedX / 8 + Utils.RandSym(1)
local spy = -projectile.speedY / 8 + Utils.RandSym(1)
local effect = EffectUtils.Create(
effectId,
projectile.centerX,
projectile.centerY,
spx,
spy,
Utils.RandSym(1),
Utils.RandDoubleArea(1, 1.0),
1.0,
Color.new(255, 100, 255)
)
effect.lightAlpha = 24
effect.gravity = false
end
SoundUtils.PlaySound(Reg.SoundID("bowhit"), projectile.centerXi, projectile.centerYi)
end
function BlueArrow:OnHitNpc(npc, _)
self.projectile:Kill()
end
function BlueArrow:OnHitPlayer(player, _)
self.projectile:Kill()
end
function BlueArrow:OnTileCollide(_, _)
self.projectile:Kill()
end
return BlueArrow
================================================
FILE: projectile_ai/BlueBullet.json
================================================
{
"BlueBullet": {
"script": {
"path": "BlueBullet.lua"
}
}
}
================================================
FILE: projectile_ai/BlueBullet.lua
================================================
---@class TC.BlueBullet:ModProjectile
local BlueBullet = class("BlueBullet", ModProjectile)
function BlueBullet:TouchEffect()
local projectile = self.projectile
for _ = 1, 12 do
EffectUtils.Create(
Reg.EffectID("circle"),
projectile.centerX,
projectile.centerY,
Utils.RandSym(3),
Utils.RandSym(3),
0,
Utils.RandDoubleArea(0.25, 0.25),
Utils.RandDoubleArea(0.5, 0.5),
Color.new(200, 200, 255)
)
end
end
function BlueBullet:Update()
local projectile = self.projectile
local effect = EffectUtils.Create(
Reg.EffectID("circle"),
projectile.hots[1].x + Utils.RandSym(10),
projectile.hots[1].y + Utils.RandSym(10),
projectile.speedX / 4 + Utils.RandSym(0.25),
projectile.speedY / 4 + Utils.RandSym(0.25),
Utils.RandSym(1),
Utils.RandDoubleArea(0.15, 0.35),
1.0,
Color.new(200, 200, 255)
)
effect:SetDisappearTime(30)
end
function BlueBullet:OnHitNpc(_, _)
self:TouchEffect()
self.projectile:Kill()
end
function BlueBullet:OnHitPlayer(_, _)
self:TouchEffect()
self.projectile:Kill()
end
function BlueBullet:OnTileCollide(_, _)
self:TouchEffect()
self.projectile:Kill()
end
return BlueBullet
================================================
FILE: projectile_ai/BlueWave.json
================================================
{
"BlueWave": {
"script": {
"path": "BlueWave.lua"
}
}
}
================================================
FILE: projectile_ai/BlueWave.lua
================================================
---@class TC.BlueWave:ModProjectile
local BlueWave = class("BlueWave", ModProjectile)
function BlueWave:TouchEffect()
local projectile = self.projectile
for _ = 1, 4 do
EffectUtils.Create(
Reg.EffectID("circle"),
projectile.centerX,
projectile.centerY,
Utils.RandSym(1),
Utils.RandSym(1),
0,
Utils.RandDoubleArea(1, 1),
Utils.RandDoubleArea(0.5, 0.5),
Color.new(177, 177, 255)
)
end
end
function BlueWave:Update()
local projectile = self.projectile
projectile.rotateAngle = projectile.speedAngle
local effect = EffectUtils.Create(
Reg.EffectID("circle"),
projectile.hots[1].x + Utils.RandSym(10),
projectile.hots[1].y + Utils.RandSym(10),
projectile.speedX / 4 + Utils.RandSym(0.25),
projectile.speedY / 4 + Utils.RandSym(0.25),
Utils.RandSym(1),
Utils.RandDoubleArea(0.15, 0.35),
1.0,
Color.new(177, 177, 255)
)
effect:SetDisappearTime(30)
end
function BlueWave:OnHitNpc(_, _)
self:TouchEffect()
self.projectile:Kill()
end
function BlueWave:OnHitPlayer(_, _)
self:TouchEffect()
self.projectile:Kill()
end
function BlueWave:OnTileCollide(_, _)
self:TouchEffect()
self.projectile:Kill()
end
return BlueWave
================================================
FILE: projectile_ai/Bomb.json
================================================
{
"Bomb": {
"script": {
"path": "Bomb.lua"
}
}
}
================================================
FILE: projectile_ai/Bomb.lua
================================================
---@type ModProjectile
local Bomb = class("Bomb", ModProjectile)
function Bomb:Update()
local projectile = self.projectile
-- slow speed
if projectile.stand then
projectile.speedX = Utils.SlowSpeed1D(projectile.speedX, 0.025)
end
-- rotate
if projectile.speedX ~= 0 then
projectile:Rotate(projectile.speedX / (projectile.height / 2))
end
-- make fire effect every 4 ticks
if projectile.tickTime % 4 == 0 then
EffectUtils.Create(
Reg.EffectID("flame_star"),
projectile.hots[1].x,
projectile.hots[1].y,
Utils.RandSym(0.3),
Utils.RandSym(0.2),
0,
Utils.RandDoubleArea(1, 1)
)
end
-- make explosion after the bomb survives target time
if projectile.tickTime > projectile.targetTime then
projectile:Kill()
end
end
function Bomb:OnKilled()
local projectile = self.projectile
EffectUtils.CreateExplosion(projectile.centerX, projectile.centerY)
MiscUtils.CreateExplosion(projectile.centerXi, projectile.centerYi, projectile.baseAttack.attack,
true, true, -- hurt npc / player
true, true, -- kill tiles / walls
true) -- play explosion sound
end
function Bomb:OnHitNpc(npc, hitAttack)
self.projectile:Kill()
end
function Bomb:OnHitPlayer(player, hitAttack)
self.projectile:Kill()
end
function Bomb:OnTileCollide(oldSpeedX, oldSpeedY)
local projectile = self.projectile
--bounce
if projectile.stand then
if oldSpeedY > 0.5 then
projectile.speedY = -oldSpeedY / 3
end
end
end
return Bomb
================================================
FILE: projectile_ai/Boomerang.json
================================================
{
"Boomerang": {
"script": {
"path": "Boomerang.lua"
},
"netUpdate": false
}
}
================================================
FILE: projectile_ai/Boomerang.lua
================================================
---@class Boomerang:ModProjectile
local Boomerang = class("Boomerang", ModProjectile)
local GPlayer = require("player.GPlayer")
local STATE_NORMAL = 0
local STATE_FLYING_BACK = 1
function Boomerang:Update()
local alive = false
local proj = self.projectile
local slot = self:TryGetHookSlot()
if slot ~= nil then
alive = true
end
if alive then
if proj.state == STATE_NORMAL then
if proj.tickTime > proj.targetTime then
proj.state = STATE_FLYING_BACK
end
elseif proj.state == STATE_FLYING_BACK then
local player = self:TryGetHookPlayer()
if player then
local backX = player.centerX
local backY = player.centerY
if Utils.GetDistance(proj.centerX - backX, proj.centerY - backY) < 32 then
proj:Kill()
return
end
proj.speedX, proj.speedY = Utils.ForceSpeed2D(
proj.speedX, proj.speedY, 0.5, Utils.GetAngle(backX - proj.centerX, backY - proj.centerY), 8)
end
end
end
proj.rotateAngle = proj.rotateAngle + 0.4
if proj.special == 1 and proj.tickTime % 4 == 0 then
EffectUtils.Create(Reg.EffectID("flame_star"),
proj.randX,
proj.randY,
Utils.RandSym(1),
Utils.RandSym(1),
0,
Utils.RandDoubleArea(1, 1)
)
end
end
function Boomerang:TryGetHookPlayer()
if self.playerOwnerIndex ~= nil then
if PlayerUtils.IsAlive(self.playerOwnerIndex) then
local player = PlayerUtils.Get(self.playerOwnerIndex)
return player
end
end
return nil
end
function Boomerang:TryGetHookSlot()
local player = self:TryGetHookPlayer()
if player == nil then
return
end
local gp = GPlayer.GetInstance(player)
local slot = gp:GetHeldSlot()
if slot.hasStack then
local stack = slot:GetStack()
local item = stack:GetItem()
if item.projectileID == self.projectile.id then
return slot
end
end
return nil
end
function Boomerang:TryReleasePlayerHook()
local player = self:TryGetHookPlayer()
if player ~= nil then
local gp = GPlayer.GetInstance(player)
gp.throwingBoomerang = false
gp.throwingBoomerangTime = 0
end
end
function Boomerang:TryLossDurable()
local slot = self:TryGetHookSlot()
if slot == nil then
return
end
slot:GetStack():LoseDurable(1)
if slot:GetStack().durable == 0 then
slot:DecrStackSize(1)
end
end
function Boomerang:PostUpdate()
end
function Boomerang:OnKilled()
self:TryReleasePlayerHook()
end
function Boomerang:DoFlyBack()
local proj = self.projectile
if proj.state == STATE_NORMAL then
proj.speedX = -proj.speedX
proj.speedY = -proj.speedY
proj.state = STATE_FLYING_BACK
end
end
---OnHitNpc
---@param npc Npc
function Boomerang:OnHitNpc(npc, _)
self:TryLossDurable()
self:DoFlyBack()
if self.projectile.special == 1 then
npc:AddBuff(Reg.BuffID("fire"), 180)
end
end
---@param player Player
function Boomerang:OnHitPlayer(player, _)
self:TryLossDurable()
self:DoFlyBack()
end
function Boomerang:OnTileCollide(_, _)
local proj = self.projectile
if proj.state == STATE_NORMAL then
self:DoFlyBack()
else
proj.speedX = -proj.speedX
proj.speedY = -proj.speedY
end
end
return Boomerang
================================================
FILE: projectile_ai/Bullet.json
================================================
{
"Bullet": {
"script": {
"path": "Bullet.lua"
}
}
}
================================================
FILE: projectile_ai/Bullet.lua
================================================
---@type ModProjectile
local Bullet = class("Bullet", ModProjectile)
function Bullet:Update()
local projectile = self.projectile
projectile.rotateAngle = projectile.speedAngle
LightingUtils.AddDelay(projectile.centerXi, projectile.centerYi, 8, 24)
end
function Bullet:OnKilled()
local projectile = self.projectile
local spx = math.min(math.max(projectile.speedX, -24), 24)
local spy = math.min(math.max(projectile.speedY, -24), 24)
EffectUtils.Create(
Reg.EffectID("liquid_paticular"),
projectile.centerX,
projectile.centerY,
-spx / 16 + Utils.RandSym(1),
-spy / 16 - Utils.RandDouble(2),
0,
0.5,
0,
Color.Yellow
)
end
function Bullet:OnHitNpc(_, _)
self.projectile:Kill()
end
function Bullet:OnHitPlayer(_, _)
self.projectile:Kill()
end
function Bullet:OnTileCollide(_, _)
self.projectile:Kill()
end
return Bullet
================================================
FILE: projectile_ai/CrystalMagic.json
================================================
{
"CrystalMagic": {
"script": {
"path": "CrystalMagic.lua"
}
}
}
================================================
FILE: projectile_ai/CrystalMagic.lua
================================================
---@type ModProjectile
local CrystalMagic = class("CrystalMagic", ModProjectile)
function CrystalMagic:Update()
local projectile = self.projectile
local chasing = false
if projectile.isCheckNpc then
local npcTarget = NpcUtils.SearchNearestEnemy(projectile.centerX, projectile.centerY, 300)
if npcTarget ~= nil then
projectile.speedX, projectile.speedY = Utils.ForceSpeed2D(projectile.speedX, projectile.speedY, 0.1,
projectile:GetAngleTo(npcTarget.centerX, npcTarget.centerY), projectile.maxSpeed)
chasing = true
end
end
if not chasing then
-- random move
projectile.speedX = projectile.speedX + Utils.RandSym(0.2)
projectile.speedY = projectile.speedY + Utils.RandSym(0.2)
if projectile.tickTime % 4 == 0 then
EffectUtils.Create(
Reg.EffectID("flash2"),
projectile.randX,
projectile.randY,
Utils.RandSym(1),
Utils.RandSym(1),
0, 1,
1
)
end
else
if projectile.tickTime % 2 == 0 then
EffectUtils.Create(
Reg.EffectID("flash2"),
projectile.randX,
projectile.randY,
-projectile.speedX / 4 + Utils.RandSym(2),
-projectile.speedY / 4 + Utils.RandSym(2),
0,
1,
1
)
end
end
LightingUtils.AddDelay(projectile.centerXi, projectile.centerYi, 32, 30)
end
function CrystalMagic:OnKilled()
local projectile = self.projectile
local flash2 = Reg.EffectID("flash2")
for _ = 1, 12 do
EffectUtils.Create(flash2,
projectile.centerX,
projectile.centerY,
Utils.RandSym(6),
Utils.RandSym(6),
0,
Utils.RandDoubleArea(1, 1)
)
end
end
function CrystalMagic:OnHitNpc(npc, hitAttack)
self.projectile:Kill()
end
function CrystalMagic:OnHitPlayer(player, hitAttack)
self.projectile:Kill()
end
function CrystalMagic:OnTileCollide(oldSpeedX, oldSpeedY)
self.projectile:Kill()
end
return CrystalMagic
================================================
FILE: projectile_ai/CursedArrow.json
================================================
{
"CursedArrow": {
"script": {
"path": "CursedArrow.lua"
}
}
}
================================================
FILE: projectile_ai/CursedArrow.lua
================================================
---@class TC.CursedArrow:ModProjectile
local CursedArrow = class("CursedArrow", ModProjectile)
function CursedArrow:Update()
local projectile = self.projectile
projectile.rotateAngle = projectile.speedAngle
if projectile.tickTime % 1 == 0 then
local spx = projectile.speedX / 4 + Utils.RandSym(1)
local spy = projectile.speedY / 4 + Utils.RandSym(1)
local effect = EffectUtils.Create(
Reg.EffectID("chip_fast"),
projectile.hots[1].x,
projectile.hots[1].y,
spx,
spy,
Utils.RandSym(0.1),
Utils.RandDoubleArea(0.7, 0.4)
)
effect.lightAlpha = 24
effect.color = Color.new(255, 100, 255)
effect.gravity = false
effect:SetDisappearTime(20)
end
projectile.gravity = 0
projectile.speedX, projectile.speedY = Utils.ForceSpeed2D(projectile.speedX, projectile.speedY,
0.4, projectile.speedAngle, 24)
end
function CursedArrow:OnKilled()
local projectile = self.projectile
local effectId = Reg.EffectID("chip_fast")
for _ = 1, 8 do
local spx = projectile.speedX / 8 + Utils.RandSym(1)
local spy = projectile.speedY / 8 + Utils.RandSym(1)
local effect = EffectUtils.Create(
effectId,
projectile.centerX,
projectile.centerY,
spx,
spy,
Utils.RandSym(1),
Utils.RandDoubleArea(1.0, 2.0),
1.0,
Color.new(255, 100, 255)
)
effect.lightAlpha = 24
effect.gravity = false
end
SoundUtils.PlaySound(Reg.SoundID("bowhit"), projectile.centerXi, projectile.centerYi)
end
function CursedArrow:OnHitNpc(npc, _)
self.projectile:Kill()
end
function CursedArrow:OnHitPlayer(player, _)
self.projectile:Kill()
end
function CursedArrow:OnTileCollide(_, _)
self.projectile:Kill()
end
return CursedArrow
================================================
FILE: projectile_ai/Fire.json
================================================
{
"Fire": {
"script": {
"path": "Fire.lua"
}
}
}
================================================
FILE: projectile_ai/Fire.lua
================================================
---@type ModProjectile
local Fire = class("Fire", ModProjectile)
function Fire:GetFireScale()
local projectile = self.projectile
local scale = 1.0
if projectile.tickTime < 30 then
scale = 0.25 + 1.75 * projectile.tickTime / 30
elseif projectile.tickTime < 60 then
scale = 2 - (projectile.tickTime - 30) / 10
end
scale = scale * 1.25
return scale
end
function Fire:Update()
local projectile = self.projectile
projectile.speedX, projectile.speedY = Utils.SlowSpeed2D(projectile.speedX, projectile.speedY, 0.14)
projectile:Rotate(0.2)
local scale = self:GetFireScale()
if scale <= 0 or scale >= 60 then
projectile:Kill()
else
local lighting = math.floor((1 - projectile.tickTime / 60) * 32)
LightingUtils.Add(projectile.centerXi, projectile.centerYi, lighting, 8, 6, 0)
if Utils.RandTry(32) then
EffectUtils.Create(
Reg.EffectID("liquid_paticular"),
projectile.centerX,
projectile.centerY,
projectile.speedX / 2 + Utils.RandSym(0.25),
projectile.speedY - Utils.RandDouble(0.75),
Utils.RandSym(0.05),
0.5,
0,
Color.new(255, 128, 0)
)
end
end
end
function Fire:OnDraw()
local projectile = self.projectile
projectile.color = Color.new(255, 255, 255, math.floor((1 - projectile.tickTime / 60) * 255))
local scale = math.max(self:GetFireScale(), 0.1)
projectile.spriteEx.angle = projectile.rotateAngle
projectile.spriteEx.scaleRateX = scale
projectile.spriteEx.scaleRateY = scale
projectile.spriteOffsetX = math.floor((1 - projectile.spriteEx.scaleRateX) * projectile.spriteDefaultWidth / 2);
projectile.spriteOffsetY = math.floor((1 - projectile.spriteEx.scaleRateY) * projectile.spriteDefaultHeight / 2);
end
---OnHitNpc
---@param npc Npc
---@param _ Attack
function Fire:OnHitNpc(npc, _)
npc:AddBuff(Reg.BuffID("fire"), 100)
end
---OnHitPlayer
---@param player Player
---@param _ Attack
function Fire:OnHitPlayer(player, _)
player:AddBuff(Reg.BuffID("fire"), 100)
end
function Fire:OnTileCollide(oldSpeedX, oldSpeedY)
local projectile = self.projectile
for _ = 1, 4 do
local effect = EffectUtils.Create(
Reg.EffectID("liquid_paticular"),
projectile.centerX,
projectile.centerY,
-oldSpeedX / 4 + Utils.RandSym(1),
-oldSpeedY / 4 - Utils.RandDouble(2),
Utils.RandSym(0.05),
0.5,
0,
Color.new(255, 128, 0)
)
end
projectile:Kill()
end
return Fire
================================================
FILE: projectile_ai/FireArrow.json
================================================
{
"FireArrow": {
"script": {
"path": "FireArrow.lua"
},
"modData": [
[ "int", "attachItemID" ],
[ "int", "flameLevel" ],
[ "int", "piercingCount" ]
]
}
}
================================================
FILE: projectile_ai/FireArrow.lua
================================================
---@class TC.FireArrow:ModProjectile
local FireArrow = class("AmethystMagic", ModProjectile)
function FireArrow:Update()
local projectile = self.projectile
projectile.rotateAngle = projectile.speedAngle
if projectile.tickTime % 2 == 0 then
EffectUtils.Create(
Reg.EffectID("smoke"),
projectile.hots[1].x,
projectile.hots[1].y,
Utils.RandSym(2),
Utils.RandSym(2),
Utils.RandSym(0.1),
Utils.RandDoubleArea(0.25, 0.5),
0.6,
Color.new(64, 64, 64)
)
end
if projectile.tickTime % 1 == 0 then
local effect = EffectUtils.Create(
Reg.EffectID("fire_flame"),
projectile.hots[1].x,
projectile.hots[1].y,
Utils.RandSym(0.3),
Utils.RandSym(0.3),
Utils.RandSym(0.1),
Utils.RandDoubleArea(0.5, 1.0)
)
effect:SetDisappearTime(20)
end
end
function FireArrow:OnKilled()
local projectile = self.projectile
local effectId = Reg.EffectID("fire_flame")
for _ = 1, 8 do
EffectUtils.Create(
effectId,
projectile.centerX,
projectile.centerY,
Utils.RandSym(2) + projectile.speedX / 4,
Utils.RandDoubleArea(-2, 3) + projectile.speedY / 4,
Utils.RandSym(1),
Utils.RandDoubleArea(1, 0.5),
1.0,
Color.new(200, 200, 200)
)
EffectUtils.Create(
Reg.EffectID("smoke"),
projectile.hots[1].x,
projectile.hots[1].y,
Utils.RandSym(2) + projectile.speedX / 3,
Utils.RandSym(2) + projectile.speedY / 3,
Utils.RandSym(0.1),
Utils.RandDoubleArea(0.25, 0.5),
0.9,
Color.new(200, 200, 100)
)
end
local explosionEffect = EffectUtils.Create(
Reg.EffectID("explosion"),
projectile.centerX,
projectile.centerY,
0,
0,
0,
1,
1.0,
Color.new(200, 200, 0)
)
end
function FireArrow:OnHitNpc(npc, _)
local projectile = self.projectile
projectile:Kill()
end
function FireArrow:OnHitPlayer(player, _)
local projectile = self.projectile
projectile:Kill()
end
function FireArrow:OnTileCollide(_, _)
local projectile = self.projectile
projectile:Kill()
end
return FireArrow
================================================
FILE: projectile_ai/FireElement.json
================================================
{
"FireElement": {
"script": {
"path": "FireElement.lua"
},
"modData": [
[ "int", "bounceTimes" ]
]
}
}
================================================
FILE: projectile_ai/FireElement.lua
================================================
---@type ModProjectile
local FireElement = class("FireElement", ModProjectile)
function FireElement:Update()
local projectile = self.projectile
projectile.speedY = projectile.speedY + 0.1
projectile.rotateAngle = projectile.speedAngle
if projectile.tickTime % 2 == 0 then
local effect = EffectUtils.Create(
Reg.EffectID("fire_flame"),
projectile.hots[1].x,
projectile.hots[1].y,
projectile.speedX / 4 + Utils.RandSym(1),
projectile.speedY / 4 + Utils.RandSym(1),
Utils.RandSym(0.1),
Utils.RandDoubleArea(0.5, 0.55),
1.0
)
effect:SetDisappearTime(30)
end
LightingUtils.AddDelay(projectile.centerXi, projectile.centerYi, 32, 24, 0, 0, 16)
end
function FireElement:OnKilled()
local projectile = self.projectile
local flash2 = Reg.EffectID("fire_flame")
for _ = 1, 8 do
EffectUtils.Create(
flash2,
projectile.centerX,
projectile.centerY,
Utils.RandSym(2),
Utils.RandSym(2),
0,
1.0,
1.0
)
end
end
function FireElement:OnHitNpc(_, _)
local projectile = self.projectile
SoundUtils.PlaySoundGroup(Reg.SoundGroupID("glass"), projectile.centerXi, projectile.centerYi)
projectile:Kill()
end
function FireElement:OnHitPlayer(_, _)
local projectile = self.projectile
SoundUtils.PlaySoundGroup(Reg.SoundGroupID("glass"), projectile.centerXi, projectile.centerYi)
projectile:Kill()
end
function FireElement:OnTileCollide(oldSpeedX, oldSpeedY)
local projectile = self.projectile
if projectile.modData.bounceTimes >= 2 then
projectile:Kill()
else
local star = Reg.EffectID("star")
for _ = 1, 3 do
EffectUtils.Create(
star,
projectile.centerX,
projectile.centerY,
Utils.RandSym(2),
Utils.RandSym(2),
0,
1.0,
1.0,
Color.new(255, 220, 0)
)
end
end
if projectile.stand or projectile.isCollisionTop then
projectile.speedY = -oldSpeedY * 0.8
elseif projectile.isCollisionLeft or projectile.isCollisionRight then
projectile.speedX = -oldSpeedX * 0.8
end
SoundUtils.PlaySoundGroup(Reg.SoundGroupID("glass"), projectile.centerXi, projectile.centerYi)
projectile.modData.bounceTimes = projectile.modData.bounceTimes + 1
end
return FireElement
================================================
FILE: projectile_ai/FireFlow.json
================================================
{
"FireFlow": {
"script": {
"path": "FireFlow.lua"
}
}
}
================================================
FILE: projectile_ai/FireFlow.lua
================================================
---@class TC.FireFlow:ModProjectile
local FireFlow = class("FireFlow", ModProjectile)
function FireFlow:TouchEffect()
local projectile = self.projectile
for _ = 1, 4 do
EffectUtils.Create(
Reg.EffectID("fire_flame"),
projectile.centerX,
projectile.centerY,
Utils.RandSym(1),
Utils.RandSym(1),
0,
Utils.RandDoubleArea(1, 1),
Utils.RandDoubleArea(0.5, 0.5),
Color.new(150, 150, 40)
)
end
end
function FireFlow:Update()
local projectile = self.projectile
projectile.color = Color.new(0, 0, 0, 0)
if projectile.tickTime == 0 then
for _ = 1, 8 do
EffectUtils.Create(
Reg.EffectID("fire_flame"),
projectile.centerX,
projectile.centerY,
projectile.speedX / 6 + Utils.RandSym(1),
projectile.speedY / 6 + Utils.RandSym(1),
0,
Utils.RandDoubleArea(0.5, 0.5),
Utils.RandDoubleArea(0.5, 0.5),
Color.new(150, 150, 40)
)
end
end
local effect = EffectUtils.Create(
Reg.EffectID("fire_flame"),
projectile.hots[1].x,
projectile.hots[1].y,
projectile.speedX / 4 + Utils.RandSym(0.25),
projectile.speedY / 4 + Utils.RandSym(0.25),
Utils.RandSym(1),
Utils.RandDoubleArea(0.5, 0.5),
1.0,
Color.new(255, 180, 130)
)
effect:SetDisappearTime(30)
if projectile.tickTime > 32 then
projectile:Kill()
end
end
function FireFlow:OnHitNpc(_, _)
self:TouchEffect()
self.projectile:Kill()
end
function FireFlow:OnHitPlayer(_, _)
self:TouchEffect()
self.projectile:Kill()
end
function FireFlow:OnTileCollide(_, _)
self:TouchEffect()
self.projectile:Kill()
end
return FireFlow
================================================
FILE: projectile_ai/FireFlowLarge.json
================================================
{
"FireFlowLarge": {
"script": {
"path": "FireFlowLarge.lua"
}
}
}
================================================
FILE: projectile_ai/FireFlowLarge.lua
================================================
---@class TC.FireFlowLarge:ModProjectile
local FireFlowLarge = class("FireFlowLarge", ModProjectile)
function FireFlowLarge:TouchEffect()
local projectile = self.projectile
for _ = 1, 8 do
EffectUtils.Create(
Reg.EffectID("fire_flame"),
projectile.centerX,
projectile.centerY,
-projectile.speedX / 4 + Utils.RandSym(3),
-projectile.speedY / 4 + Utils.RandSym(3),
0,
Utils.RandDoubleArea(1, 1),
1.0,
Color.new(255, 200, 0)
)
end
end
function FireFlowLarge:Update()
local projectile = self.projectile
projectile.color = Color.new(0, 0, 0, 0)
projectile.speedY = projectile.speedY + 0.2
if projectile.tickTime == 0 then
for _ = 1, 2 do
EffectUtils.Create(
Reg.EffectID("fire_flame"),
projectile.centerX,
projectile.centerY,
projectile.speedX / 6 + Utils.RandSym(1),
projectile.speedY / 6 + Utils.RandSym(1),
0,
1.0,
Utils.RandDoubleArea(0.5, 0.5),
Color.new(255, 200, 0)
)
end
end
local effect = EffectUtils.Create(
Reg.EffectID("fire_flame"),
projectile.hots[1].x,
projectile.hots[1].y,
projectile.speedX / 4 + Utils.RandSym(0.25),
projectile.speedY / 4 + Utils.RandSym(0.25),
Utils.RandSym(1),
Utils.RandDoubleArea(1.5, 0.5),
1.0,
Color.new(255, 180, 130)
)
effect:SetDisappearTime(60)
if projectile.tickTime > 100 then
projectile:Kill()
end
local npcTarget = NpcUtils.SearchNearestEnemy(projectile.centerX, projectile.centerY, 30)
if npcTarget ~= nil then
npcTarget:AddBuff(Reg.BuffID("fire"), 100)
end
end
function FireFlowLarge:OnHitNpc(npc, _)
self:TouchEffect()
self.projectile:Kill()
end
function FireFlowLarge:OnHitPlayer(_, _)
self:TouchEffect()
self.projectile:Kill()
end
function FireFlowLarge:OnTileCollide(_, _)
self:TouchEffect()
self.projectile:Kill()
end
return FireFlowLarge
================================================
FILE: projectile_ai/FireMagic.json
================================================
{
"FireMagic": {
"script": {
"path": "FireMagic.lua"
}
}
}
================================================
FILE: projectile_ai/FireMagic.lua
================================================
---@type ModProjectile
local FireMagic = class("FireMagic", ModProjectile)
function FireMagic:Update()
local projectile = self.projectile
if projectile.isCheckNpc then
local npcTarget = NpcUtils.SearchNearestEnemy(projectile.centerX, projectile.centerY, 120)
if npcTarget ~= nil then
projectile.speedX, projectile.speedY = Utils.ForceSpeed2D(projectile.speedX, projectile.speedY, 0.4,
projectile:GetAngleTo(npcTarget.centerX, npcTarget.centerY), projectile.maxSpeed)
end
end
EffectUtils.Create(
Reg.EffectID("circle"),
projectile.hots[1].x,
projectile.hots[1].y,
0,
0,
0,
0.75,
0.8,
Color.Yellow
)
LightingUtils.AddDelay(projectile.centerXi, projectile.centerYi, 32, 30)
end
function FireMagic:OnKilled()
local projectile = self.projectile
local flash2 = Reg.EffectID("flash2")
for _ = 1, 8 do
EffectUtils.Create(flash2,
projectile.centerX,
projectile.centerY,
-projectile.speedX / 8 + Utils.RandSym(2),
-projectile.speedY / 8 - Utils.RandSym(2),
0,
Utils.RandDoubleArea(1, 1),
0,
Color.Yellow
)
end
end
---OnHitNpc
---@param npc Npc
---@param _ Attack
function FireMagic:OnHitNpc(npc, _)
npc:AddBuff(Reg.BuffID("fire"), 240)
self.projectile:Kill()
end
---OnHitPlayer
---@param player Player
---@param _ Attack
function FireMagic:OnHitPlayer(player, _)
player:AddBuff(Reg.BuffID("fire"), 240)
self.projectile:Kill()
end
function FireMagic:OnTileCollide(_, _)
self.projectile:Kill()
end
return FireMagic
================================================
FILE: projectile_ai/Fireball.json
================================================
{
"Fireball": {
"script": {
"path": "Fireball.lua"
},
"modData": [
[ "bool", "boom" ]
]
}
}
================================================
FILE: projectile_ai/Fireball.lua
================================================
---@type ModProjectile
local Fireball = class("Fireball", ModProjectile)
function Fireball:Update()
local projectile = self.projectile
projectile:Rotate(0.1)
if projectile.tickTime % 8 == 0 then
local fire_flame = Reg.EffectID("fire_flame")
local flame_star = Reg.EffectID("flame_star")
EffectUtils.Create(
fire_flame,
projectile.randX,
projectile.randY,
Utils.RandSym(4),
Utils.RandSym(4),
Utils.RandSym(0.1),
Utils.RandDoubleArea(0.5, 0.5)
)
EffectUtils.Create(
flame_star,
projectile.randX,
projectile.randY,
Utils.RandSym(3),
Utils.RandSym(3),
Utils.RandSym(0.1),
Utils.RandDoubleArea(0.5, 0.5)
)
end
end
function Fireball:OnKilled()
local projectile = self.projectile
-- explode
if projectile.modData.boom then
MiscUtils.CreateExplosion(projectile.centerXi, projectile.centerYi, 5, -- attack
projectile.isCheckNpc, projectile.isCheckPlayer, -- hurt npc / player
true, false, -- kill tiles but not walls
true, -- play sound
100) -- max hardness
EffectUtils.CreateExplosion(projectile.centerX, projectile.centerY)
else
local fire_flame = Reg.EffectID("fire_flame")
local flame_star = Reg.EffectID("flame_star")
for _ = 1, 8 do
EffectUtils.Create(
fire_flame,
projectile.randX,
projectile.randY,
Utils.RandSym(3),
Utils.RandSym(3),
Utils.RandSym(0.1),
Utils.RandDoubleArea(0.5, 0.5)
)
EffectUtils.Create(
flame_star,
projectile.randX,
projectile.randY,
Utils.RandSym(5),
Utils.RandSym(5),
Utils.RandSym(0.1),
Utils.RandDoubleArea(0.5, 0.5)
)
end
SoundUtils.PlaySoundGroup(Reg.SoundGroupID("explode"), projectile.centerXi, projectile.centerYi)
end
end
function Fireball:OnHitNpc(npc, hitAttack)
self.projectile:Kill()
end
function Fireball:OnHitPlayer(player, hitAttack)
self.projectile:Kill()
end
function Fireball:OnTileCollide(oldSpeedX, oldSpeedY)
self.projectile:Kill()
end
return Fireball
================================================
FILE: projectile_ai/GlowBomb.json
================================================
{
"GlowBomb": {
"defaultAI": "Bomb",
"script": {
"path": "GlowBomb.lua",
"requires": [ [ "mycode", "modules\\mycode.lua" ] ]
}
}
}
================================================
FILE: projectile_ai/GlowBomb.lua
================================================
---@type ModProjectile
local GlowBomb = class("GlowBomb", require("Bomb"))
---MakeGlowingBombEffect
---@param centerX double
---@param centerY double
function MakeGlowingBombEffect(centerX, centerY)
local loops = 32
local flowEffectID = Reg.EffectID("flow_particular")
for i = 1, loops do
local rate = Utils.RandSym(1)
local speed = 1 + 20 * math.abs(rate)
local spx = speed * math.cos(i / loops * 2 * math.pi)
local spy = speed * math.sin(i / loops * 2 * math.pi)
local rotateSpeed = 0.1 * (1 - math.abs(rate))
if rate < 0 then
rotateSpeed = -rotateSpeed
end
EffectUtils.Create(
flowEffectID,
centerX,
centerY,
spx,
spy,
rotateSpeed,
0,
0,
Color.Yellow
)
end
end
function GlowBomb:PostUpdate()
local projectile = self.projectile
LightingUtils.Add(projectile.centerXi, projectile.centerYi, 30)
end
function GlowBomb:OnKilled()
local projectile = self.projectile
MakeGlowingBombEffect(projectile.centerX, projectile.centerY)
EffectUtils.CreateExplosion(projectile.centerX, projectile.centerY)
MiscUtils.CreateExplosion(projectile.centerXi, projectile.centerYi, projectile.baseAttack.attack,
true, true, -- hurt npc / player
true, true, -- kill tiles / walls
true) -- play explosion sound
end
return GlowBomb
================================================
FILE: projectile_ai/Glowball.json
================================================
{
"Glowball": {
"script": {
"path": "Glowball.lua"
}
}
}
================================================
FILE: projectile_ai/Glowball.lua
================================================
---@type ModProjectile
local Glowball = class("Glowball", ModProjectile)
function Glowball:Update()
local projectile = self.projectile
-- slow speed
if projectile.stand then
projectile.speedX = Utils.SlowSpeed1D(projectile.speedX, 0.025)
end
-- rotate
if projectile.speedX ~= 0 then
projectile:Rotate(projectile.speedX / (projectile.height / 2))
end
LightingUtils.Add(projectile.centerXi, projectile.centerYi, 28)
-- make fire effect every 4 ticks
if projectile.tickTime % 4 == 0 then
EffectUtils.Create(
Reg.EffectID("flame_star"),
projectile.randX,
projectile.randY,
Utils.RandSym(1),
Utils.RandSym(1),
0,
Utils.RandDoubleArea(1, 1)
)
end
-- make explosion after the bomb survives target time
if projectile.tickTime > projectile.targetTime then
projectile:Kill()
end
end
function Glowball:OnKilled()
local projectile = self.projectile
local flame_star = Reg.EffectID("flame_star")
for i = 1, 32 do
EffectUtils.Create(
flame_star,
projectile.randX,
projectile.randY,
Utils.RandSym(3),
Utils.RandSym(3),
0,
Utils.RandDoubleArea(1, 1)
)
end
end
---OnHitNpc
---@param npc Npc
---@param hitAttack Attack
function Glowball:OnHitNpc(npc, hitAttack)
npc:AddBuff(Reg.BuffID("glowing"), 120)
end
function Glowball:OnTileCollide(oldSpeedX, oldSpeedY)
local projectile = self.projectile
-- bounce
if projectile.stand then
if oldSpeedY > 0.5 then
projectile.speedY = -oldSpeedY / 1.5
end
end
end
return Glowball
================================================
FILE: projectile_ai/Grenade.json
================================================
{
"Grenade": {
"defaultAI": "Bomb",
"script": {
"path": "Grenade.lua"
}
}
}
================================================
FILE: projectile_ai/Grenade.lua
================================================
---@type ModProjectile
local Grenade = class("Grenade", require("Bomb"))
function Grenade:OnKilled()
local projectile = self.projectile
EffectUtils.CreateExplosion(projectile.centerX, projectile.centerY)
MiscUtils.CreateExplosion(projectile.centerXi, projectile.centerYi, projectile.baseAttack.attack,
true, false, -- hurt npc / player
false, false, -- kill tiles / walls
false) -- play explosion sound
SoundUtils.PlaySound(Reg.SoundID("grenade_fire"), projectile.centerXi, projectile.centerYi)
end
return Grenade
================================================
FILE: projectile_ai/IceArrow.json
================================================
{
"IceArrow": {
"defaultAI": "Arrow",
"script": {
"path": "IceArrow.lua"
},
"modData": [
[ "bool", "bounceOnce" ]
]
}
}
================================================
FILE: projectile_ai/IceArrow.lua
================================================
---@type ModProjectile
local IceArrow = class("Grenade", require("Arrow"))
function IceArrow:Update()
local projectile = self.projectile
projectile.rotateAngle = projectile.speedAngle
if projectile.modData.flameLevel == 0 then
if projectile.tickTime % 2 == 0 then
EffectUtils.Create(
Reg.EffectID("arrow_paticular"),
projectile.hots[1].x,
projectile.hots[1].y,
Utils.RandSym(2),
Utils.RandSym(2),
Utils.RandSym(0.25),
0,
0,
Color.new(0, 200, 255)
)
end
end
end
function IceArrow:OnKilled()
local projectile = self.projectile
local flash2 = Reg.EffectID("flash2")
for _ = 1, 8 do
EffectUtils.Create(
flash2,
projectile.centerX,
projectile.centerY,
Utils.RandSym(4),
Utils.RandSym(4)
)
end
SoundUtils.PlaySound(Reg.SoundID("bowhit"), projectile.centerXi, projectile.centerYi)
end
function IceArrow:OnHitNpc(_, _)
local projectile = self.projectile
if projectile.modData.piercingCount > 0 then
projectile.modData.piercingCount = projectile.modData.piercingCount - 1
else
projectile:Kill()
end
end
function IceArrow:OnHitPlayer(_, _)
self.projectile:Kill()
end
---OnTileCollide
---@param oldSpeedX double
---@param oldSpeedY double
function IceArrow:OnTileCollide(oldSpeedX, oldSpeedY)
local projectile = self.projectile
if not projectile.modData.bounceOnce then
if projectile.stand or projectile.isCollisionTop then
projectile.speedY = -oldSpeedY / 2
projectile.speedX = oldSpeedX / 2
elseif projectile.isCollisionLeft or projectile.isCollisionRight then
projectile.speedX = -oldSpeedX / 2
end
projectile.modData.bounceOnce = true
SoundUtils.PlaySound(Reg.SoundID("bowhit"), projectile.centerXi, projectile.centerYi)
else
if projectile.modData.attachItemID > 0 then
ItemUtils.CreateDrop(projectile.modData.attachItemID, 1, projectile.centerX, projectile.centerY,
-1.5 * math.cos(projectile.rotateAngle), -4 * math.sin(projectile.rotateAngle))
end
projectile:Kill()
end
end
return IceArrow
================================================
FILE: projectile_ai/IceBullet.json
================================================
{
"IceBullet": {
"script": {
"path": "IceBullet.lua"
}
}
}
================================================
FILE: projectile_ai/IceBullet.lua
================================================
---@type ModProjectile
local IceBullet = class("IceBullet", ModProjectile)
function IceBullet:Update()
local projectile = self.projectile
if projectile.tickTime % 8 == 0 then
EffectUtils.Create(
Reg.EffectID("flash2"),
projectile.randX,
projectile.randY,
Utils.RandSym(1),
Utils.RandSym(1)
)
end
LightingUtils.AddDelay(projectile.centerXi, projectile.centerYi, 32, 30)
end
function IceBullet:OnKilled()
local projectile = self.projectile
local flash2 = Reg.EffectID("flash2")
for _ = 1, 8 do
EffectUtils.Create(
flash2,
projectile.centerX,
projectile.centerY,
Utils.RandSym(4),
Utils.RandSym(4)
)
end
end
function IceBullet:OnHitNpc(npc, hitAttack)
self.projectile:Kill()
end
function IceBullet:OnHitPlayer(player, hitAttack)
self.projectile:Kill()
end
function IceBullet:OnTileCollide(oldSpeedX, oldSpeedY)
self.projectile:Kill()
end
return IceBullet
================================================
FILE: projectile_ai/IceMagic.json
================================================
{
"IceMagic": {
"script": {
"path": "IceMagic.lua"
},
"modData": [
[ "int", "bounceTimes" ]
]
}
}
================================================
FILE: projectile_ai/IceMagic.lua
================================================
---@type ModProjectile
local IceMagic = class("IceMagic", ModProjectile)
function IceMagic:Update()
local projectile = self.projectile
projectile.speedY = projectile.speedY + 0.2
projectile.rotateAngle = projectile.speedAngle
if projectile.tickTime % 4 == 0 then
EffectUtils.Create(
Reg.EffectID("flash2"),
projectile.hots[1].x,
projectile.hots[1].y,
projectile.speedX / 4 + Utils.RandSym(3),
projectile.speedY / 4 + Utils.RandSym(3),
Utils.RandSym(0.1),
Utils.RandDoubleArea(1, 0.25),
1.0,
Color.new(240, 160, 255)
)
end
LightingUtils.AddDelay(projectile.centerXi, projectile.centerYi, 32, 24, 0, 0, 16)
end
function IceMagic:OnKilled()
local projectile = self.projectile
local flash2 = Reg.EffectID("flash2")
for _ = 1, 8 do
EffectUtils.Create(
flash2,
projectile.centerX,
projectile.centerY,
Utils.RandSym(4),
Utils.RandSym(4),
0,
2.0,
1.0,
Color.new(240, 160, 255)
)
end
end
function IceMagic:OnHitNpc(_, _)
local projectile = self.projectile
SoundUtils.PlaySoundGroup(Reg.SoundGroupID("glass"), projectile.centerXi, projectile.centerYi)
projectile:Kill()
end
function IceMagic:OnHitPlayer(_, _)
local projectile = self.projectile
SoundUtils.PlaySoundGroup(Reg.SoundGroupID("glass"), projectile.centerXi, projectile.centerYi)
projectile:Kill()
end
function IceMagic:OnTileCollide(oldSpeedX, oldSpeedY)
local projectile = self.projectile
if projectile.modData.bounceTimes >= 4 then
projectile:Kill()
else
local star = Reg.EffectID("star")
for _ = 1, 3 do
EffectUtils.Create(
star,
projectile.centerX,
projectile.centerY,
Utils.RandSym(2),
Utils.RandSym(2),
0,
1.0,
1.0,
Color.new(240, 160, 255)
)
end
end
if projectile.stand or projectile.isCollisionTop then
projectile.speedY = -oldSpeedY * 0.8
elseif projectile.isCollisionLeft or projectile.isCollisionRight then
projectile.speedX = -oldSpeedX * 0.8
end
SoundUtils.PlaySoundGroup(Reg.SoundGroupID("glass"), projectile.centerXi, projectile.centerYi)
projectile.modData.bounceTimes = projectile.modData.bounceTimes + 1
end
return IceMagic
================================================
FILE: projectile_ai/LaserBullet.json
================================================
{
"LaserBullet": {
"defaultAI": "Bullet",
"script": {
"path": "LaserBullet.lua"
}
}
}
================================================
FILE: projectile_ai/LaserBullet.lua
================================================
---@type ModProjectile
local LaserBullet = class("LaserBullet", require("Bullet"))
function LaserBullet:Update()
local projectile = self.projectile
projectile.rotateAngle = projectile.speedAngle
LightingUtils.AddDelay(projectile.centerXi, projectile.centerYi, 32, 24, 0, 0, 24)
end
function LaserBullet:OnKilled()
local projectile = self.projectile
EffectUtils.Create(
Reg.EffectID("liquid_paticular"),
projectile.centerX,
projectile.centerY,
Utils.RandSym(2),
Utils.RandSym(2),
0,
0.5,
0.5,
Color.new(100, 100, 255)
)
end
return LaserBullet
================================================
FILE: projectile_ai/LightingArrow.json
================================================
{
"LightingArrow": {
"defaultAI": "Arrow",
"script": {
"path": "LightingArrow.lua"
}
}
}
================================================
FILE: projectile_ai/LightingArrow.lua
================================================
---@type ModProjectile
local LightingArrow = class("LightingArrow", require("Arrow"))
function LightingArrow:PreUpdate()
local projectile = self.projectile
LightingUtils.AddDelay(projectile.centerXi, projectile.centerYi, 32, 32)
end
function LightingArrow:OnKilled()
local projectile = self.projectile
if projectile.modData.flameLevel > 0 then
local fire_flame = Reg.EffectID("fire_flame")
for _ = 1, 4 do
EffectUtils.Create(
fire_flame,
projectile.centerX,
projectile.centerY,
Utils.RandSym(2),
Utils.RandDoubleArea(-2, 3),
Utils.RandSym(1),
Utils.RandDoubleArea(1, 0.5),
1.0,
Color.new(200,200,200)
)
end
else
local flame_star = Reg.EffectID("flame_star")
for _ = 1, 8 do
EffectUtils.Create(
flame_star,
projectile.centerX,
projectile.centerY,
Utils.RandSym(2),
Utils.RandDoubleArea(-2, 3),
Utils.RandSym(1),
Utils.RandDoubleArea(1, 0.5),
1.0,
Color.new(200,200,200)
)
end
end
EffectUtils.Create(
Reg.EffectID("flame_star"),
projectile.centerX,
projectile.centerY,
-projectile.speedX / 4 + Utils.RandSym(2),
-projectile.speedY / 4 + Utils.RandSym(2),
Utils.RandSym(0.25),
Utils.RandDoubleArea(1, 0.5),
1.0,
Color.Yellow
)
SoundUtils.PlaySound(Reg.SoundID("bowhit"), projectile.centerXi, projectile.centerYi)
end
---OnHitNpc
---@param npc Npc
---@param hitAttack Attack
function LightingArrow:OnHitNpc(npc, hitAttack)
local projectile = self.projectile
npc:AddBuff(Reg.BuffID("glowing"), 300)
if projectile.modData.flameLevel > 0 then
npc:AddBuff(Reg.BuffID("fire"), 60 * (projectile.modData.flameLevel + 1))
end
if projectile.modData.piercingCount > 0 then
projectile.modData.piercingCount = projectile.modData.piercingCount - 1
else
projectile:Kill()
end
end
---OnHitPlayer
---@param player Player
---@param hitAttack Attack
function LightingArrow:OnHitPlayer(player, hitAttack)
local projectile = self.projectile
player:AddBuff(Reg.BuffID("glowing"), 300)
if projectile.modData.flameLevel > 0 then
player:AddBuff(Reg.BuffID("fire"), 60 * (projectile.modData.flameLevel + 1))
end
projectile:Kill()
end
return LightingArrow
================================================
FILE: projectile_ai/LightingBulletYellow.json
================================================
{
"LightingBulletYellow": {
"script": {
"path": "LightingBulletYellow.lua"
}
}
}
================================================
FILE: projectile_ai/LightingBulletYellow.lua
================================================
---@class TC.LightingBulletYellow:ModProjectile
local LightingBulletYellow = class("LightingBulletYellow", ModProjectile)
function LightingBulletYellow:TouchEffect()
local projectile = self.projectile
for _ = 1, 4 do
EffectUtils.Create(
Reg.EffectID("fire_flame"),
projectile.centerX,
projectile.centerY,
Utils.RandSym(1),
Utils.RandSym(1),
0,
Utils.RandDoubleArea(1, 1),
Utils.RandDoubleArea(0.5, 0.5),
Color.new(150, 150, 40)
)
end
end
function LightingBulletYellow:Update()
local projectile = self.projectile
end
function LightingBulletYellow:OnHitNpc(_, _)
self:TouchEffect()
self.projectile:Kill()
end
function LightingBulletYellow:OnHitPlayer(_, _)
self:TouchEffect()
self.projectile:Kill()
end
function LightingBulletYellow:OnTileCollide(_, _)
self:TouchEffect()
self.projectile:Kill()
end
return LightingBulletYellow
================================================
FILE: projectile_ai/LightingWheel.json
================================================
{
"LightingWheel": {
"script": {
"path": "LightingWheel.lua"
}
}
}
================================================
FILE: projectile_ai/LightingWheel.lua
================================================
---@class TC.LightingWheel:ModProjectile
local LightingWheel = class("LightingWheel", ModProjectile)
function LightingWheel:TouchEffect()
local projectile = self.projectile
for _ = 1, 4 do
EffectUtils.Create(
Reg.EffectID("fire_flame"),
projectile.centerX,
projectile.centerY,
Utils.RandSym(1),
Utils.RandSym(1),
0,
Utils.RandDoubleArea(1, 1),
Utils.RandDoubleArea(0.5, 0.5),
Color.new(150, 150, 40)
)
end
end
function LightingWheel:Update()
local projectile = self.projectile
projectile.rotateAngle = projectile.rotateAngle + 0.2
local effect = EffectUtils.Create(
Reg.EffectID("circle"),
projectile.hots[1].x,
projectile.hots[1].y,
projectile.speedX / 4 + Utils.RandSym(0.25),
projectile.speedY / 4 + Utils.RandSym(0.25),
Utils.RandSym(1),
Utils.RandDoubleArea(0.5, 0.5),
1.0,
Color.new(255, 255, 130)
)
effect:SetDisappearTime(30)
if projectile.tickTime > 0 and projectile.tickTime % 32 == 0 then
local angle = -projectile.tickTime / 32 - math.pi / 2
local proj = ProjectileUtils.Create(Reg.ProjectileID("lighting_bullet_yellow"),
projectile.centerX, projectile.centerY,
2 * math.cos(angle), 2 * math.sin(angle),
projectile.baseAttack)
proj.isCheckPlayer = true
end
end
function LightingWheel:OnHitNpc(_, _)
self:TouchEffect()
self.projectile:Kill()
end
function LightingWheel:OnHitPlayer(_, _)
self:TouchEffect()
self.projectile:Kill()
end
function LightingWheel:OnTileCollide(_, _)
self:TouchEffect()
self.projectile:Kill()
end
return LightingWheel
================================================
FILE: projectile_ai/MagicWave.json
================================================
{
"MagicWave": {
"script": {
"path": "MagicWave.lua"
}
}
}
================================================
FILE: projectile_ai/MagicWave.lua
================================================
---@class TC.MagicWave:ModProjectile
local MagicWave = class("MagicWave", ModProjectile)
function MagicWave:TouchEffect()
local projectile = self.projectile
for _ = 1, 12 do
EffectUtils.Create(
Reg.EffectID("circle"),
projectile.centerX,
projectile.centerY,
Utils.RandSym(3),
Utils.RandSym(3),
0,
Utils.RandDoubleArea(0.25, 0.25),
Utils.RandDoubleArea(0.5, 0.5),
Color.new(200, 200, 255)
)
end
end
function MagicWave:Update()
local projectile = self.projectile
projectile.rotateAngle = projectile.speedAngle
local effect = EffectUtils.Create(
Reg.EffectID("circle"),
projectile.hots[1].x + Utils.RandSym(10),
projectile.hots[1].y + Utils.RandSym(10),
projectile.speedX / 4 + Utils.RandSym(0.25),
projectile.speedY / 4 + Utils.RandSym(0.25),
Utils.RandSym(1),
Utils.RandDoubleArea(0.15, 0.35),
1.0,
Color.new(200, 200, 255)
)
effect:SetDisappearTime(30)
end
function MagicWave:OnHitNpc(_, _)
self:TouchEffect()
self.projectile:Kill()
end
function MagicWave:OnHitPlayer(_, _)
self:TouchEffect()
self.projectile:Kill()
end
function MagicWave:OnTileCollide(_, _)
self:TouchEffect()
self.projectile:Kill()
end
return MagicWave
================================================
FILE: projectile_ai/MiniRocket.json
================================================
{
"MiniRocket": {
"script": {
"path": "MiniRocket.lua"
}
}
}
================================================
FILE: projectile_ai/MiniRocket.lua
================================================
---@class TC.MiniRocket:ModProjectile
local MiniRocket = class("MiniRocket", ModProjectile)
function MiniRocket:Update()
local projectile = self.projectile
projectile.rotateAngle = projectile.speedAngle
if projectile.tickTime == 0 then
for i = 1, 5 do
EffectUtils.Create(
Reg.EffectID("smoke"),
projectile.hots[1].x,
projectile.hots[1].y,
projectile.speedX / 4 + Utils.RandSym(2),
projectile.speedY / 4 + Utils.RandSym(2),
Utils.RandSym(0.1),
Utils.RandDoubleArea(0.25, 0.75),
0.9,
Color.new(255, 255, 200)
)
end
local s = Vector2.new(projectile.speedX, projectile.speedY).length
s = s * Utils.RandDoubleArea(0.7, 0.3)
local angle = projectile.speedAngle
projectile.speedX = s * math.cos(angle)
projectile.speedY = s * math.sin(angle)
end
if projectile.tickTime % 4 == 0 then
EffectUtils.Create(
Reg.EffectID("smoke"),
projectile.hots[1].x,
projectile.hots[1].y,
Utils.RandSym(1),
Utils.RandSym(1),
Utils.RandSym(0.1),
Utils.RandDoubleArea(0.25, 0.5),
0.9,
Color.new(164, 164, 64)
)
end
if projectile.tickTime % 1 == 0 then
EffectUtils.Create(
Reg.EffectID("fire_flame"),
projectile.hots[1].x,
projectile.hots[1].y,
Utils.RandSym(0.2),
Utils.RandSym(0.2),
Utils.RandSym(0.1),
Utils.RandDoubleArea(0.5, 0.25)
)
end
local chasing = false
if projectile.isCheckNpc then
local npcTarget = NpcUtils.SearchNearestEnemy(projectile.centerX, projectile.centerY, 128)
if npcTarget ~= nil then
projectile.speedX, projectile.speedY = Utils.ForceSpeed2D(projectile.speedX, projectile.speedY, 0.63,
projectile:GetAngleTo(npcTarget.centerX, npcTarget.centerY), projectile.maxSpeed)
chasing = true
end
end
projectile.speedX = projectile.speedX + Utils.RandSym(0.52)
projectile.speedY = projectile.speedY + Utils.RandSym(0.52)
end
function MiniRocket:OnKilled()
local projectile = self.projectile
--MiscUtils.CreateExplosion(projectile.centerXi, projectile.centerYi, 11, projectile.isCheckNpc, projectile.isCheckPlayer)
--EffectUtils.CreateExplosion(projectile.centerX, projectile.centerY)
local explosionEffect = EffectUtils.Create(
Reg.EffectID("explosion"),
projectile.centerX,
projectile.centerY,
0,
0,
0,
1,
1.0,
Color.new(255, 255, 200)
)
end
function MiniRocket:OnHitNpc(_, _)
self.projectile:Kill()
end
function MiniRocket:OnHitPlayer(_, _)
self.projectile:Kill()
end
function MiniRocket:OnTileCollide(_, _)
self.projectile:Kill()
end
return MiniRocket
================================================
FILE: projectile_ai/RedSpeedUp.json
================================================
{
"RedSpeedUp": {
"script": {
"path": "RedSpeedUp.lua"
}
}
}
================================================
FILE: projectile_ai/RedSpeedUp.lua
================================================
---@class TC.RedSpeedUp:ModProjectile
local RedSpeedUp = class("RedSpeedUp", ModProjectile)
function RedSpeedUp:TouchEffect()
local projectile = self.projectile
for _ = 1, 12 do
EffectUtils.Create(
Reg.EffectID("circle"),
projectile.centerX,
projectile.centerY,
Utils.RandSym(3),
Utils.RandSym(3),
0,
Utils.RandDoubleArea(0.25, 0.25),
Utils.RandDoubleArea(0.5, 0.5),
Color.new(200, 0, 0)
)
end
end
function RedSpeedUp:Update()
local projectile = self.projectile
local angle = projectile.speedAngle
local speed = Vector2.new(projectile.speedX, projectile.speedY).length
speed = speed + 0.1
projectile.speedX = speed * math.cos(angle)
projectile.speedY = speed * math.sin(angle)
local effect = EffectUtils.Create(
Reg.EffectID("circle"),
projectile.hots[1].x + Utils.RandSym(10),
projectile.hots[1].y + Utils.RandSym(10),
projectile.speedX / 4 + Utils.RandSym(0.25),
projectile.speedY / 4 + Utils.RandSym(0.25),
Utils.RandSym(1),
Utils.RandDoubleArea(0.15, 0.35),
1.0,
Color.new(200, 0, 0)
)
effect:SetDisappearTime(30)
end
function RedSpeedUp:OnHitNpc(_, _)
self:TouchEffect()
self.projectile:Kill()
end
function RedSpeedUp:OnHitPlayer(_, _)
self:TouchEffect()
self.projectile:Kill()
end
function RedSpeedUp:OnTileCollide(_, _)
self:TouchEffect()
self.projectile:Kill()
end
return RedSpeedUp
================================================
FILE: projectile_ai/Rocket.json
================================================
{
"Rocket": {
"script": {
"path": "Rocket.lua"
}
}
}
================================================
FILE: projectile_ai/Rocket.lua
================================================
---@type ModProjectile
local Rocket = class("Rocket", ModProjectile)
function Rocket:Update()
local projectile = self.projectile
projectile.rotateAngle = projectile.speedAngle
if projectile.tickTime % 4 == 0 then
EffectUtils.Create(
Reg.EffectID("smoke"),
projectile.hots[1].x,
projectile.hots[1].y,
Utils.RandSym(2),
Utils.RandSym(2),
Utils.RandSym(0.1),
Utils.RandDoubleArea(0.25, 0.5),
0.6,
Color.new(64, 64, 64)
)
end
if projectile.tickTime % 2 == 0 then
EffectUtils.Create(
Reg.EffectID("fire_flame"),
projectile.hots[1].x,
projectile.hots[1].y,
Utils.RandSym(0.1),
Utils.RandSym(0.1),
Utils.RandSym(0.1),
Utils.RandDoubleArea(1, 2)
)
end
end
function Rocket:OnKilled()
local projectile = self.projectile
MiscUtils.CreateExplosion(projectile.centerXi, projectile.centerYi, 11, projectile.isCheckNpc, projectile.isCheckPlayer,
true,true)
EffectUtils.CreateExplosion(projectile.centerX, projectile.centerY)
end
function Rocket:OnHitNpc(_, _)
self.projectile:Kill()
end
function Rocket:OnHitPlayer(_, _)
self.projectile:Kill()
end
function Rocket:OnTileCollide(_, _)
self.projectile:Kill()
end
return Rocket
================================================
FILE: projectile_ai/ShadowMagic.json
================================================
{
"ShadowMagic": {
"script": {
"path": "ShadowMagic.lua"
}
}
}
================================================
FILE: projectile_ai/ShadowMagic.lua
================================================
---@type ModProjectile
local ShadowMagic = class("ShadowMagic", ModProjectile)
function ShadowMagic:Update()
local projectile = self.projectile
local chasing = false
if projectile.isCheckNpc then
local npcTarget = NpcUtils.SearchNearestEnemy(projectile.centerX, projectile.centerY, 120)
if npcTarget ~= nil then
projectile.speedX, projectile.speedY = Utils.ForceSpeed2D(projectile.speedX, projectile.speedY, 0.8,
projectile:GetAngleTo(npcTarget.centerX, npcTarget.centerY), projectile.maxSpeed)
chasing = true
end
end
if not chasing then
EffectUtils.Create(
Reg.EffectID("circle"),
projectile.hots[1].x,
projectile.hots[1].y,
0,
0,
0,
0.75,
0.25
)
else
EffectUtils.Create(
Reg.EffectID("circle"),
projectile.hots[1].x,
projectile.hots[1].y,
Utils.RandSym(2),
Utils.RandSym(2),
0,
0.75,
0.25
)
end
if projectile.tickTime % 2 == 0 then
if not chasing then
EffectUtils.Create(
Reg.EffectID("flash2"),
projectile.hots[1].x,
projectile.hots[1].y,
Utils.RandSym(2),
Utils.RandSym(2),
Utils.RandSym(0.1),
Utils.RandDoubleArea(1, 0.25)
)
else
EffectUtils.Create(
Reg.EffectID("flash2"),
projectile.hots[1].x,
projectile.hots[1].y,
Utils.RandSym(8),
Utils.RandSym(8),
Utils.RandSym(0.1),
Utils.RandDoubleArea(1, 0.25)
)
end
end
LightingUtils.AddDelay(projectile.centerXi, projectile.centerYi, 32, 24, 0, 0, 16)
end
function ShadowMagic:OnKilled()
local projectile = self.projectile
local flash2 = Reg.EffectID("flash2")
for _ = 1, 8 do
EffectUtils.Create(
flash2,
projectile.centerX,
projectile.centerY,
Utils.RandSym(4),
Utils.RandSym(4),
0,
Utils.RandDoubleArea(1, 1)
)
end
end
function ShadowMagic:OnHitNpc(_, _)
self.projectile:Kill()
end
function ShadowMagic:OnHitPlayer(_, _)
self.projectile:Kill()
end
function ShadowMagic:OnTileCollide(_, _)
self.projectile:Kill()
end
return ShadowMagic
================================================
FILE: projectile_ai/ShulkerBullet.json
================================================
{
"ShulkerBullet": {
"script": {
"path": "ShulkerBullet.lua"
}
}
}
================================================
FILE: projectile_ai/ShulkerBullet.lua
================================================
---@type ModProjectile
local ShulkerBullet = class("ShulkerBullet", ModProjectile)
function ShulkerBullet:Update()
local projectile = self.projectile
if projectile.isCheckPlayer then
local playerTarget = PlayerUtils.SearchNearestPlayer(projectile.centerX, projectile.centerY, 360)
if playerTarget ~= nil then
projectile.speedX, projectile.speedY = Utils.ForceSpeed2D(projectile.speedX, projectile.speedY, 0.3,
projectile:GetAngleTo(playerTarget.centerX, playerTarget.centerY), projectile.maxSpeed)
end
end
projectile:Rotate(0.1)
if projectile.tickTime % 4 == 0 then
EffectUtils.Create(
Reg.EffectID("laser_flash"),
projectile.hots[1].x,
projectile.hots[1].y,
Utils.RandSym(1),
Utils.RandSym(1),
Utils.RandSym(0.1)
)
end
if projectile.tickTime > 200 then
projectile:Kill()
end
end
function ShulkerBullet:OnKilled()
local projectile = self.projectile
local laser_flash = Reg.EffectID("laser_flash")
for i = 0, 15 do
local angle = i * math.pi * 2 / 16
EffectUtils.Create(
laser_flash,
projectile.hots[1].x,
projectile.hots[1].y,
math.cos(angle) * 2,
math.sin(angle) * 2,
Utils.RandSym(0.1),
2
)
end
end
function ShulkerBullet:OnHitPlayer(player, _)
player:AddBuff(Reg.BuffID("levitation"), 120)
self.projectile:Kill()
end
function ShulkerBullet:OnTileCollide(_, _)
self.projectile:Kill()
end
return ShulkerBullet
================================================
FILE: projectile_ai/SnowFlake.json
================================================
{
"SnowFlake": {
"script": {
"path": "SnowFlake.lua"
}
}
}
================================================
FILE: projectile_ai/SnowFlake.lua
================================================
---@type ModProjectile
local SnowFlake = class("SnowFlake", ModProjectile)
function SnowFlake:Update()
local projectile = self.projectile
if projectile.speedX == 0 and projectile.speedY == 0 then
projectile:Kill()
else
projectile.speedX, projectile.speedY = Utils.ForceSpeed2D(projectile.speedX, projectile.speedY, 0.05, projectile.speedAngle, 14.0)
end
if projectile.tickTime >= 600 then
projectile:Kill()
end
projectile:Rotate(0.03)
if projectile.tickTime % 4 == 0 then
EffectUtils.Create(
Reg.EffectID("flash2"),
projectile.hots[1].x + Utils.RandSym(20),
projectile.hots[1].y + Utils.RandSym(20),
Utils.RandSym(2),
Utils.RandSym(2),
0,
Utils.RandDoubleArea(1.5, 1)
)
end
end
function SnowFlake:OnKilled()
local projectile = self.projectile
local flash2 = Reg.EffectID("flash2")
for _ = 1, 12 do
EffectUtils.Create(
flash2,
projectile.hots[1].x,
projectile.hots[1].y,
Utils.RandSym(5),
Utils.RandSym(5),
0,
Utils.RandDoubleArea(1, 1)
)
end
end
function SnowFlake:OnHitNpc(_, _)
self.projectile:Kill()
end
function SnowFlake:OnHitPlayer(_, _)
self.projectile:Kill()
end
function SnowFlake:OnTileCollide(_, _)
self.projectile:Kill()
end
return SnowFlake
================================================
FILE: projectile_ai/Spike.json
================================================
{
"Spike": {
"script": {
"path": "Spike.lua"
},
"modData": [
[ "int", "crossCount" ]
]
}
}
================================================
FILE: projectile_ai/Spike.lua
================================================
---@class TC.Spike:ModProjectile
local Spike = class("Spike", ModProjectile)
function Spike:Update()
local projectile = self.projectile
if projectile.modData.crossCount == 0 then
projectile.rotateAngle = projectile.speedAngle
local effect = EffectUtils.Create(
Reg.EffectID("chip"),
projectile.centerX,
projectile.centerY,
projectile.speedX / 2 + Utils.RandSym(2),
projectile.speedY / 2 + Utils.RandSym(2),
Utils.RandSym(1),
Utils.RandDoubleArea(0.5, 0.5),
1.0,
Color.new(200, 200, 200)
)
effect.gravity = false
effect:SetDisappearTime(20)
else
projectile.rotateAngle = projectile.rotateAngle + 0.1
end
end
function Spike:OnKilled()
local projectile = self.projectile
local effectId = Reg.EffectID("chip")
for _ = 1, 8 do
local effect = EffectUtils.Create(
effectId,
projectile.centerX,
projectile.centerY,
projectile.speedX + Utils.RandSym(2),
-projectile.speedY + Utils.RandSym(2),
Utils.RandSym(1),
Utils.RandDoubleArea(1, 1.5),
1.0,
Color.new(200, 200, 200)
)
effect:SetDisappearTime(40)
end
end
function Spike:OnHitNpc(npc, _)
local projectile = self.projectile
if projectile.modData.crossCount >= 6 then
projectile:Kill()
end
projectile.modData.crossCount = projectile.modData.crossCount + 1
end
function Spike:OnHitPlayer(player, _)
local projectile = self.projectile
if projectile.modData.crossCount >= 6 then
projectile:Kill()
end
projectile.modData.crossCount = projectile.modData.crossCount + 1
end
function Spike:OnTileCollide(_, _)
local projectile = self.projectile
if projectile.modData.crossCount >= 2 then
projectile:Kill()
end
projectile.modData.crossCount = projectile.modData.crossCount + 1
projectile.speedX = -projectile.speedX / 2
end
return Spike
================================================
FILE: projectile_ai/StarArrow.json
================================================
{
"StarArrow": {
"defaultAI": "Arrow",
"script": {
"path": "StarArrow.lua"
}
}
}
================================================
FILE: projectile_ai/StarArrow.lua
================================================
---@type ModProjectile
local StarArrow = class("StarArrow", require("Arrow"))
function StarArrow:CheckFallStarArrow()
local projectile = self.projectile
if projectile.modData.attachItemID > 0 then
local height = 256
local width = 1024
local offsetX = 0
if projectile.speedX < 0 then
offsetX = Utils.RandInt(256)
else
offsetX = width - Utils.RandInt(256)
end
local shootX = projectile.centerX - width / 2 + offsetX
local shootY = projectile.centerY - height
local angle = projectile:GetAngleFrom(shootX, shootY)
local speed = 10
local proj = ProjectileUtils.Create(
projectile.id,
shootX,
shootY,
speed * math.cos(angle),
speed * math.sin(angle),
projectile.baseAttack
)
proj.isCheckPlayer = projectile.isCheckPlayer
proj.isCheckNpc = projectile.isCheckNpc
local star = Reg.EffectID("star")
for _ = 1, 12 do
EffectUtils.Create(
star,
shootX,
shootY,
Utils.RandSym(4),
Utils.RandSym(4),
Utils.RandSym(1),
Utils.RandDoubleArea(1, 0.5),
0,
Color.Yellow
)
end
end
end
function StarArrow:Update()
local projectile = self.projectile
projectile.rotateAngle = projectile.speedAngle
if projectile.tickTime % 8 == 0 then
EffectUtils.Create(
Reg.EffectID("star"),
projectile.hots[1].x,
projectile.hots[1].y,
projectile.speedX / 4 + Utils.RandSym(2),
projectile.speedY / 4 + Utils.RandSym(2),
Utils.RandSym(0.25),
0,
0,
Color.Yellow
)
end
LightingUtils.AddDelay(projectile.centerXi, projectile.centerYi, 32, 32)
end
function StarArrow:OnKilled()
local projectile = self.projectile
local flame_star = Reg.EffectID("flame_star")
for _ = 1, 8 do
EffectUtils.Create(
flame_star,
projectile.centerX,
projectile.centerY,
Utils.RandSym(2),
Utils.RandDoubleArea(-2, 3),
Utils.RandSym(1),
Utils.RandDoubleArea(1, 0.5),
0,
Color.new(200,200,200)
)
end
EffectUtils.Create(
Reg.EffectID("star"),
projectile.centerX,
projectile.centerY,
-projectile.speedX / 4 + Utils.RandSym(2),
-projectile.speedY / 4 + Utils.RandSym(2),
Utils.RandSym(0.25),
Utils.RandDoubleArea(1, 0.5),
0,
Color.Yellow
)
SoundUtils.PlaySound(Reg.SoundID("bowhit"), projectile.centerXi, projectile.centerYi)
end
function StarArrow:OnHitNpc(_, _)
self:CheckFallStarArrow()
self.projectile:Kill()
end
function StarArrow:OnHitPlayer(_, _)
self:CheckFallStarArrow()
self.projectile:Kill()
end
function StarArrow:OnTileCollide(_, _)
local projectile = self.projectile
if projectile.modData.attachItemID > 0 then
ItemUtils.CreateDrop(projectile.modData.attachItemID, 1, projectile.centerX, projectile.centerY,
-1.5 * math.cos(projectile.rotateAngle), -4 * math.sin(projectile.rotateAngle))
end
self:CheckFallStarArrow()
projectile:Kill()
end
return StarArrow
================================================
FILE: projectile_ai/StarMagic.json
================================================
{
"StarMagic": {
"script": {
"path": "StarMagic.lua"
},
"modData": [
[ "int", "crossCount" ]
]
}
}
================================================
FILE: projectile_ai/StarMagic.lua
================================================
---@type ModProjectile
local StarMagic = class("StarMagic", ModProjectile)
function StarMagic:Update()
local projectile = self.projectile
projectile:Rotate(0.2)
if projectile.tickTime % 8 == 0 then
EffectUtils.Create(
Reg.EffectID("star"),
projectile.hots[1].x,
projectile.hots[1].y,
projectile.speedX / 4 + Utils.RandSym(2),
projectile.speedY / 4 + Utils.RandSym(2),
Utils.RandSym(0.1),
Utils.RandDoubleArea(0.5, 0.5),
0,
Color.new(255, 220, 0)
)
end
if projectile.tickTime % 4 == 0 then
EffectUtils.Create(
Reg.EffectID("flash2"),
projectile.hots[1].x,
projectile.hots[1].y,
projectile.speedX / 4 + Utils.RandSym(2),
projectile.speedY / 4 + Utils.RandSym(2),
0,
Utils.RandDoubleArea(0.75, 0.4),
0,
Color.Yellow
)
end
LightingUtils.AddDelay(projectile.centerXi, projectile.centerYi, 32, 24, 16, 16, 0)
end
function StarMagic:OnKilled()
local projectile = self.projectile
for _ = 1, 8 do
EffectUtils.Create(
Reg.EffectID("star"),
projectile.centerX,
projectile.centerY,
Utils.RandSym(2),
Utils.RandSym(2),
0,
Utils.RandDoubleArea(0.5, 0.25),
0,
Color.Yellow
)
end
end
function StarMagic:OnHitNpc(npc, _)
local projectile = self.projectile
if projectile.modData.crossCount >= 3 then
projectile:Kill()
end
projectile.modData.crossCount = projectile.modData.crossCount + 1
npc:AddBuff(Reg.BuffID("glowing"), 120)
end
function StarMagic:OnHitPlayer(player, _)
local projectile = self.projectile
if projectile.modData.crossCount >= 2 then
projectile:Kill()
end
projectile.modData.crossCount = projectile.modData.crossCount + 1
player:AddBuff(Reg.BuffID("glowing"), 120)
end
function StarMagic:OnTileCollide(_, _)
self.projectile:Kill()
end
return StarMagic
================================================
FILE: projectile_ai/SuperBullet.json
================================================
{
"SuperBullet": {
"defaultAI": "Bullet",
"script": {
"path": "SuperBullet.lua"
}
}
}
================================================
FILE: projectile_ai/SuperBullet.lua
================================================
---@type ModProjectile
local SuperBullet = class("SuperBullet", require("Bullet"))
function SuperBullet:PostUpdate()
local projectile = self.projectile
for i = 1, 2 do
EffectUtils.Create(
Reg.EffectID("liquid_paticular"),
projectile.centerX - projectile.speedX * i / 2,
projectile.centerY - projectile.speedY * i / 2,
Utils.RandSym(1),
-1 - Utils.RandDouble(1), -- speed
Utils.RandSym(0.05),
Utils.RandDoubleArea(0.5, 0.5),
1,
Color.Yellow
) -- rotate, scale, alpha
end
EffectUtils.Create(
Reg.EffectID("fire_flame"),
projectile.centerX - Utils.RandDouble(projectile.speedX),
projectile.centerY - Utils.RandDouble(projectile.speedY),
Utils.RandSym(0.6),
-Utils.RandDouble(1),
Utils.RandSym(0.05),
Utils.RandDoubleArea(0.5, 0.5),
Utils.RandDoubleArea(0.5, 0.5)
)
end
function SuperBullet:OnKilled()
local projectile = self.projectile
EffectUtils.Create(
Reg.EffectID("liquid_paticular"),
projectile.centerX,
projectile.centerY,
projectile.speedX / 16 + Utils.RandSym(0.6),
projectile.speedY / 16 - Utils.RandDouble(1), -- speed
Utils.RandSym(0.05),
Utils.RandDoubleArea(0.5, 0.5),
1,
Color.Yellow
) -- rotate, scale, alpha
end
return SuperBullet
================================================
FILE: projectile_ai/SuperFire.json
================================================
{
"SuperFire": {
"script": {
"path": "SuperFire.lua"
}
}
}
================================================
FILE: projectile_ai/SuperFire.lua
================================================
---@class TC.SuperFire:ModProjectile
local SuperFire = class("SuperFire", ModProjectile)
function SuperFire:GetFireScale()
local projectile = self.projectile
local scale = 1.0
if projectile.tickTime < 45 then
scale = 0.25 + 1.75 * projectile.tickTime / 45
elseif projectile.tickTime < 90 then
scale = 2 - (projectile.tickTime - 45) / 10
end
scale = scale * 1.25
return scale
end
function SuperFire:Update()
local projectile = self.projectile
projectile.speedX, projectile.speedY = Utils.SlowSpeed2D(projectile.speedX, projectile.speedY, 0.14)
projectile:Rotate(0.1)
local scale = self:GetFireScale()
if scale <= 0 or scale >= 90 then
projectile:Kill()
else
local lighting = math.floor((1 - projectile.tickTime / 90) * 32)
LightingUtils.Add(projectile.centerXi, projectile.centerYi, 32, 8, 6, 0)
if Utils.RandTry(32) then
EffectUtils.Create(
Reg.EffectID("liquid_paticular"),
projectile.centerX,
projectile.centerY,
projectile.speedX / 2 + Utils.RandSym(0.25),
projectile.speedY - Utils.RandDouble(0.75),
Utils.RandSym(0.05),
0.5,
0,
Color.new(255, 128, 0)
)
end
if Utils.RandTry(8) then
local effect = EffectUtils.Create(
Reg.EffectID("liquid_paticular"),
projectile.centerX,
projectile.centerY,
projectile.speedX / 4 + Utils.RandSym(1),
projectile.speedY / 4 + Utils.RandSym(1),
Utils.RandSym(0.05),
0.5,
1.0,
Color.new(255, 128, 0)
)
effect.gravity = false
effect:SetDisappearTime(40)
end
if projectile.tickTime == 0 then
local effect = EffectUtils.Create(
Reg.EffectID("liquid_paticular"),
projectile.centerX,
projectile.centerY,
projectile.speedX / 8 + Utils.RandSym(1),
projectile.speedY / 8 + Utils.RandSym(1),
Utils.RandSym(0.05),
1.0,
1.0,
Color.new(255, 128, 0)
)
effect.gravity = false
effect:SetDisappearTime(60)
end
end
end
function SuperFire:OnDraw()
local projectile = self.projectile
projectile.color = Color.new(255, 255, 255, math.floor((1 - projectile.tickTime / 60) * 255))
local scale = math.max(self:GetFireScale(), 0.1)
projectile.spriteEx.angle = projectile.rotateAngle
projectile.spriteEx.scaleRateX = scale
projectile.spriteEx.scaleRateY = scale
projectile.spriteOffsetX = math.floor((1 - projectile.spriteEx.scaleRateX) * projectile.spriteDefaultWidth / 2);
projectile.spriteOffsetY = math.floor((1 - projectile.spriteEx.scaleRateY) * projectile.spriteDefaultHeight / 2);
end
---OnHitNpc
---@param npc Npc
---@param _ Attack
function SuperFire:OnHitNpc(npc, _)
npc:AddBuff(Reg.BuffID("fire"), 100)
end
---OnHitPlayer
---@param player Player
---@param _ Attack
function SuperFire:OnHitPlayer(player, _)
player:AddBuff(Reg.BuffID("fire"), 100)
end
function SuperFire:OnTileCollide(oldSpeedX, oldSpeedY)
local projectile = self.projectile
for _ = 1, 4 do
local effect = EffectUtils.Create(
Reg.EffectID("liquid_paticular"),
projectile.centerX,
projectile.centerY,
-oldSpeedX / 4 + Utils.RandSym(2),
-oldSpeedY / 4 + Utils.RandSym(2),
Utils.RandSym(0.05),
0.85,
1.0,
Color.new(255, 128, 0)
)
effect:SetDisappearTime(20)
end
projectile:Kill()
end
return SuperFire
================================================
FILE: projectile_ai/SwordArrow.json
================================================
{
"SwordArrow": {
"defaultAI": "Arrow",
"script": {
"path": "SwordArrow.lua"
}
}
}
================================================
FILE: projectile_ai/SwordArrow.lua
================================================
---@type ModProjectile
local SwordArrow = class("SwordArrow", require("Arrow"))
function SwordArrow:Update()
local projectile = self.projectile
local chasing = false
if projectile.isCheckNpc then
local npcTarget = NpcUtils.SearchNearestEnemy(projectile.centerX, projectile.centerY, 120)
if npcTarget ~= nil then
projectile.speedX, projectile.speedY = Utils.ForceSpeed2D(projectile.speedX, projectile.speedY, 1.0,
projectile:GetAngleTo(npcTarget.centerX, npcTarget.centerY), projectile.maxSpeed)
chasing = true
end
end
if not chasing then
projectile.gravity = 0.2
EffectUtils.Create(
Reg.EffectID("circle"),
projectile.hots[1].x,
projectile.hots[1].y,
0,
0,
0,
0.5
)
else
projectile.gravity = 0.0
EffectUtils.Create(
Reg.EffectID("circle"),
projectile.hots[1].x,
projectile.hots[1].y,
Utils.RandSym(2),
Utils.RandSym(2),
0,
0.75,
0.25
)
end
projectile.rotateAngle = projectile.speedAngle
LightingUtils.AddDelay(projectile.centerXi, projectile.centerYi, 24, 24)
end
function SwordArrow:OnKilled()
local projectile = self.projectile
local circle = Reg.EffectID("circle")
for _ = 1, 8 do
EffectUtils.Create(
circle,
projectile.centerX,
projectile.centerY,
Utils.RandSym(4),
Utils.RandSym(4)
)
end
SoundUtils.PlaySound(Reg.SoundID("bowhit"), projectile.centerXi, projectile.centerYi)
end
function SwordArrow:OnHitNpc(npc, hitAttack)
self.projectile:Kill()
end
function SwordArrow:OnHitPlayer(player, hitAttack)
self.projectile:Kill()
end
return SwordArrow
================================================
FILE: projectile_ai/WaterFlow.json
================================================
{
"WaterFlow": {
"script": {
"path": "WaterFlow.lua"
}
}
}
================================================
FILE: projectile_ai/WaterFlow.lua
================================================
---@class TC.WaterFlow:ModProjectile
local WaterFlow = class("WaterFlow", ModProjectile)
function WaterFlow:TouchEffect()
local projectile = self.projectile
for _ = 1, 4 do
EffectUtils.Create(
Reg.EffectID("liquid_paticular"),
projectile.centerX,
projectile.centerY,
Utils.RandSym(1),
Utils.RandSym(1) - 2,
0,
Utils.RandDoubleArea(1, 1),
Utils.RandDoubleArea(1.5, 1.5),
Color.new(30, 80, 255)
)
end
end
function WaterFlow:Update()
local projectile = self.projectile
projectile.color = Color.new(0, 0, 0, 0)
projectile.gravity = 0
if projectile.tickTime == 0 then
for _ = 1, 2 do
local effect = EffectUtils.Create(
Reg.EffectID("liquid_paticular"),
projectile.centerX,
projectile.centerY,
projectile.speedX / 12 + Utils.RandSym(1),
projectile.speedY / 12 + Utils.RandSym(1),
0,
Utils.RandDoubleArea(1.0, 1.5),
1.0,
Color.new(30, 80, 255)
)
effect.gravity = false
end
end
local effect = EffectUtils.Create(
Reg.EffectID("liquid_paticular"),
projectile.hots[1].x,
projectile.hots[1].y,
projectile.speedX / 4 + Utils.RandSym(0.25),
projectile.speedY / 4 + Utils.RandSym(0.25),
Utils.RandSym(1),
Utils.RandDoubleArea(1.0, 1.5),
1.0,
Color.new(30, 80, 255)
)
effect.gravity = false
effect:SetDisappearTime(50)
LightingUtils.AddDelay(projectile.centerXi, projectile.centerYi, 32, 32)
if projectile.tickTime > 160 then
projectile:Kill()
end
end
function WaterFlow:OnHitNpc(_, _)
self:TouchEffect()
self.projectile:Kill()
end
function WaterFlow:OnHitPlayer(_, _)
self:TouchEffect()
self.projectile:Kill()
end
function WaterFlow:OnTileCollide(_, _)
self:TouchEffect()
local projectile = self.projectile
if projectile.stand then
projectile.speedY = -math.abs(projectile.speedY)
elseif projectile.isCollisionTop then
projectile.speedY = math.abs(projectile.speedY)
end
if projectile.isCollisionLeft then
projectile.speedX = math.abs(projectile.speedX)
elseif projectile.isCollisionRight then
projectile.speedX = -math.abs(projectile.speedX)
end
end
return WaterFlow
================================================
FILE: projectile_ai/WaterMagic.json
================================================
{
"WaterMagic": {
"script": {
"path": "WaterMagic.lua"
}
}
}
================================================
FILE: projectile_ai/WaterMagic.lua
================================================
---@type ModProjectile
local WaterMagic = class("WaterMagic", ModProjectile)
function WaterMagic:TouchEffect()
local projectile = self.projectile
for _ = 1, 2 do
EffectUtils.Create(
Reg.EffectID("flash2"),
projectile.centerX,
projectile.centerY,
Utils.RandSym(2),
Utils.RandSym(2),
0,
Utils.RandDoubleArea(1, 1),
0,
Color.new(66, 66, 255)
)
end
end
function WaterMagic:Update()
local projectile = self.projectile
if projectile.tickTime % 2 == 0 then
EffectUtils.Create(
Reg.EffectID("chip"),
projectile.hots[1].x,
projectile.hots[1].y,
projectile.speedX / 4 + Utils.RandSym(0.25),
projectile.speedY / 4 + Utils.RandSym(0.25),
Utils.RandSym(1),
Utils.RandDoubleArea(1, 1),
0.5,
Color.new(66, 66, 255)
)
end
LightingUtils.AddDelay(projectile.centerXi, projectile.centerYi, 32, 24, 0, 0, 16)
if projectile.tickTime > 32 then
projectile:Kill()
end
end
function WaterMagic:OnHitNpc(_, _)
self:TouchEffect()
self.projectile:Kill()
end
function WaterMagic:OnHitPlayer(_, _)
self:TouchEffect()
self.projectile:Kill()
end
function WaterMagic:OnTileCollide(_, _)
self:TouchEffect()
self.projectile:Kill()
end
return WaterMagic
================================================
FILE: projectile_ai_global/GProjectile.lua
================================================
---@type GlobalProjectile
local GProjectile = class("GProjectile", GlobalProjectile)
function GProjectile:Update()
end
return GProjectile
================================================
FILE: projectile_ai_global/GlobalProjectile.json
================================================
{
"GlobalClass": [
"GProjectile"
]
}
================================================
FILE: projectiles/air_bullet.json
================================================
{
"air_bullet": {
"ai": "AirBullet",
"textureData": "air_bullet.png",
"width": 28,
"height": 20,
"gfxWidth": 28,
"gfxHeight": 20,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"hots": [[0, 10]],
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 12.0,
"gravity": false,
"foreground": false,
"fixByBlocks": false,
"througthBlock": false,
"keepStrick": true
}
}
================================================
FILE: projectiles/air_wave.json
================================================
{
"air_wave": {
"ai": "AirWave",
"textureData": "air_wave.png",
"width": 48,
"height": 16,
"gfxWidth": 48,
"gfxHeight": 16,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"hots": [[0, 8]],
"frameStyle": 1,
"frames": 4,
"frameSpeed": 4,
"shape": "ROTATED_BOX",
"maxSpeed": 12.0,
"gravity": false,
"foreground": true,
"fixByBlocks": false,
"througthBlock": false,
"keepStrick": true
}
}
================================================
FILE: projectiles/amethyst_magic.json
================================================
{
"amethyst_magic": {
"ai": "AmethystMagic",
"textureData": "amethyst_magic.png",
"width": 20,
"height": 24,
"gfxWidth": 20,
"gfxHeight": 24,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"hots": [[10, 12]],
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 8.0,
"gravity": false,
"foreground": true,
"fixByBlocks": false,
"througthBlock": false,
"keepStrick": true
}
}
================================================
FILE: projectiles/black_hole.json
================================================
{
"black_hole": {
"ai": "BlackHole",
"textureData": "black_hole.png",
"width": 64,
"height": 64,
"gfxWidth": 64,
"gfxHeight": 64,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"hots": [[16, 16]],
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 6.0,
"gravity": false,
"foreground": true,
"fixByBlocks": false,
"througthBlock": false,
"keepStrick": true
}
}
================================================
FILE: projectiles/blaze_rod.json
================================================
{
"blaze_rod": {
"ai": "BlazeRod",
"textureData": "blaze_rod.png",
"width": 48,
"height": 16,
"gfxWidth": 48,
"gfxHeight": 16,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"hots": [[24, 8]],
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "ROTATED_BOX",
"maxSpeed": 6.0,
"gravity": false,
"foreground": true,
"fixByBlocks": false,
"througthBlock": true,
"keepStrick": false
}
}
================================================
FILE: projectiles/blood_arrow.json
================================================
{
"blood_arrow": {
"ai": "BloodArrow",
"textureData": "blood_arrow.png",
"width": 32,
"height": 14,
"gfxWidth": 32,
"gfxHeight": 14,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"hots": [[0, 7]],
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "ROTATED_BOX",
"maxSpeed": 6.0,
"gravity": true,
"foreground": false,
"fixByBlocks": false,
"througthBlock": false,
"keepStrick": true
}
}
================================================
FILE: projectiles/blue_arrow.json
================================================
{
"blue_arrow": {
"ai": "BlueArrow",
"textureData": "blue_arrow.png",
"width": 32,
"height": 14,
"gfxWidth": 32,
"gfxHeight": 14,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"hots": [[0, 7]],
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "ROTATED_BOX",
"maxSpeed": 6.0,
"gravity": true,
"foreground": false,
"fixByBlocks": false,
"througthBlock": false,
"keepStrick": false
}
}
================================================
FILE: projectiles/bomb.json
================================================
{
"bomb": {
"ai": "Bomb",
"textureData": "bomb.png",
"width": 20,
"height": 20,
"gfxWidth": 36,
"gfxHeight": 36,
"gfxOffsetX": -8,
"gfxOffsetY": -8,
"hots": [[18, 4]],
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 8.0,
"gravity": true,
"foreground": false,
"fixByBlocks": true,
"througthBlock": false,
"keepStrick": true
}
}
================================================
FILE: projectiles/bone.json
================================================
{
"bone": {
"ai": "Spike",
"textureData": "bone.png",
"width": 24,
"height": 20,
"gfxWidth": 24,
"gfxHeight": 20,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"hots": [[0, 10]],
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "ROTATED_BOX",
"maxSpeed": 6.0,
"gravity": true,
"foreground": false,
"fixByBlocks": false,
"througthBlock": false,
"keepStrick": false
}
}
================================================
FILE: projectiles/boomerang.json
================================================
{
"boomerang": {
"ai": "Boomerang",
"textureData": "boomerang.png",
"width": 18,
"height": 32,
"gfxWidth": 18,
"gfxHeight": 32,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"hots": [[8, 16]],
"frameStyle": 1,
"frames": 1,
"frameSpeed": 16,
"shape": "BOX",
"maxSpeed": 8.0,
"gravity": false,
"foreground": false,
"fixByBlocks": false,
"througthBlock": false,
"special": 0,
"keepStrick": false,
"trajectoryPrediction": false,
"killWhenHitTile": false
}
}
================================================
FILE: projectiles/bullet.json
================================================
{
"bullet": {
"ai": "Bullet",
"textureData": "bullet.png",
"width": 24,
"height": 2,
"gfxWidth": 24,
"gfxHeight": 2,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"hots": [[0, 0]],
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "ROTATED_BOX",
"maxSpeed": 32.0,
"gravity": false,
"foreground": false,
"fixByBlocks": false,
"througthBlock": false,
"keepStrick": true
}
}
================================================
FILE: projectiles/bullet_laser.json
================================================
{
"bullet_laser": {
"ai": "LaserBullet",
"textureData": "bullet_laser.png",
"width": 64,
"height": 2,
"gfxWidth": 64,
"gfxHeight": 2,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"hots": [[0, 0]],
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "ROTATED_BOX",
"maxSpeed": 32.0,
"gravity": false,
"foreground": false,
"fixByBlocks": false,
"througthBlock": false,
"keepStrick": true
}
}
================================================
FILE: projectiles/bullet_super.json
================================================
{
"bullet_super": {
"ai": "SuperBullet",
"textureData": "bullet_super.png",
"width": 64,
"height": 2,
"gfxWidth": 64,
"gfxHeight": 2,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"hots": [ [ 0, 0 ] ],
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "ROTATED_BOX",
"maxSpeed": 32.0,
"gravity": false,
"foreground": false,
"fixByBlocks": false,
"througthBlock": false,
"keepStrick": true
}
}
================================================
FILE: projectiles/crystal_magic.json
================================================
{
"crystal_magic": {
"ai": "CrystalMagic",
"textureData": "crystal_magic.png",
"width": 32,
"height": 32,
"gfxWidth": 32,
"gfxHeight": 32,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"hots": [[16, 16]],
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 6.0,
"gravity": false,
"foreground": true,
"fixByBlocks": false,
"througthBlock": false,
"keepStrick": true
}
}
================================================
FILE: projectiles/cursed_arrow.json
================================================
{
"cursed_arrow": {
"ai": "CursedArrow",
"textureData": "cursed_arrow.png",
"width": 32,
"height": 14,
"gfxWidth": 32,
"gfxHeight": 14,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"hots": [[0, 7]],
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "ROTATED_BOX",
"maxSpeed": 6.0,
"gravity": true,
"foreground": false,
"fixByBlocks": false,
"througthBlock": false,
"keepStrick": false
}
}
================================================
FILE: projectiles/fire_arrow.json
================================================
{
"fire_arrow": {
"ai": "FireArrow",
"textureData": "fire_arrow.png",
"width": 32,
"height": 14,
"gfxWidth": 32,
"gfxHeight": 14,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"hots": [[0, 7]],
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "ROTATED_BOX",
"maxSpeed": 6.0,
"gravity": true,
"foreground": false,
"fixByBlocks": false,
"througthBlock": false,
"keepStrick": true
}
}
================================================
FILE: projectiles/fire_boomerang.json
================================================
{
"fire_boomerang": {
"ai": "Boomerang",
"textureData": "fire_boomerang.png",
"width": 18,
"height": 32,
"gfxWidth": 18,
"gfxHeight": 32,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"hots": [[8, 16]],
"frameStyle": 1,
"frames": 1,
"frameSpeed": 16,
"shape": "BOX",
"maxSpeed": 16.0,
"gravity": false,
"foreground": false,
"fixByBlocks": false,
"througthBlock": false,
"special": 1,
"keepStrick": false,
"trajectoryPrediction": false,
"killWhenHitTile": false
}
}
================================================
FILE: projectiles/fire_charge.json
================================================
{
"fire_charge": {
"ai": "Fireball",
"textureData": "fire_charge.png",
"width": 24,
"height": 24,
"gfxWidth": 24,
"gfxHeight": 24,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"hots": [ [ 12, 12 ] ],
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 6.0,
"gravity": false,
"foreground": true,
"fixByBlocks": false,
"througthBlock": false,
"keepStrick": true
}
}
================================================
FILE: projectiles/fire_element.json
================================================
{
"fire_element": {
"ai": "FireElement",
"textureData": "fire_element.png",
"width": 24,
"height": 16,
"gfxWidth": 24,
"gfxHeight": 16,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"hots": [[0, 8]],
"frameStyle": 1,
"frames": 2,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 12.0,
"gravity": false,
"foreground": false,
"fixByBlocks": false,
"througthBlock": false,
"keepStrick": true
}
}
================================================
FILE: projectiles/fire_flow.json
================================================
{
"fire_flow": {
"ai": "FireFlow",
"textureData": "super_fire.png",
"width": 16,
"height": 16,
"gfxWidth": 16,
"gfxHeight": 16,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"hots": [ [ 8, 8 ] ],
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 14.0,
"gravity": true,
"foreground": true,
"fixByBlocks": false,
"througthBlock": false,
"keepStrick": true
}
}
================================================
FILE: projectiles/fire_flow_large.json
================================================
{
"fire_flow_large": {
"ai": "FireFlowLarge",
"textureData": "super_fire.png",
"width": 24,
"height": 24,
"gfxWidth": 16,
"gfxHeight": 16,
"gfxOffsetX": 4,
"gfxOffsetY": 4,
"hots": [ [ 8, 8 ] ],
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 14.0,
"gravity": true,
"foreground": true,
"fixByBlocks": false,
"througthBlock": false,
"keepStrick": true
}
}
================================================
FILE: projectiles/fire_magic.json
================================================
{
"fire_magic": {
"ai": "FireMagic",
"textureData": "fire_magic.png",
"width": 20,
"height": 20,
"gfxWidth": 20,
"gfxHeight": 20,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"hots": [ [ 10, 10 ] ],
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 8.0,
"gravity": true,
"foreground": true,
"fixByBlocks": false,
"througthBlock": false,
"keepStrick": true
}
}
================================================
FILE: projectiles/fire_wave.json
================================================
{
"fire_wave": {
"ai": "FireElement",
"textureData": "fire_wave.png",
"width": 48,
"height": 32,
"gfxWidth": 48,
"gfxHeight": 32,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"hots": [[0, 16]],
"frameStyle": 1,
"frames": 4,
"frameSpeed": 4,
"shape": "ROTATED_BOX",
"maxSpeed": 12.0,
"gravity": false,
"foreground": false,
"fixByBlocks": false,
"througthBlock": false,
"keepStrick": true
}
}
================================================
FILE: projectiles/glow_ball.json
================================================
{
"glow_ball": {
"ai": "Glowball",
"textureData": "glow_ball.png",
"width": 16,
"height": 16,
"gfxWidth": 16,
"gfxHeight": 16,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"hots": [[8, 8]],
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 8.0,
"gravity": true,
"foreground": false,
"fixByBlocks": true,
"througthBlock": false,
"keepStrick": false
}
}
================================================
FILE: projectiles/glow_bomb.json
================================================
{
"glow_bomb": {
"ai": "GlowBomb",
"textureData": "glow_bomb.png",
"width": 20,
"height": 20,
"gfxWidth": 36,
"gfxHeight": 36,
"gfxOffsetX": -4,
"gfxOffsetY": -4,
"hots": [[14, 4]],
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 8.0,
"gravity": true,
"foreground": false,
"fixByBlocks": true,
"througthBlock": false,
"keepStrick": true
}
}
================================================
FILE: projectiles/grenade.json
================================================
{
"grenade": {
"ai": "Grenade",
"textureData": "grenade.png",
"width": 20,
"height": 20,
"gfxWidth": 28,
"gfxHeight": 28,
"gfxOffsetX": -4,
"gfxOffsetY": -4,
"hots": [[14, 4]],
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 8.0,
"gravity": true,
"foreground": false,
"fixByBlocks": true,
"througthBlock": false,
"keepStrick": true
}
}
================================================
FILE: projectiles/gun_fire.json
================================================
{
"gun_fire": {
"ai": "Fire",
"textureData": "gun_fire.png",
"width": 16,
"height": 16,
"gfxWidth": 16,
"gfxHeight": 16,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"hots": [[8, 8]],
"frameStyle": 1,
"frames": 3,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 32.0,
"gravity": false,
"foreground": false,
"fixByBlocks": false,
"througthBlock": false,
"keepStrick": false
}
}
================================================
FILE: projectiles/ice_arrow.json
================================================
{
"ice_arrow": {
"ai": "IceArrow",
"textureData": "ice_arrow.png",
"width": 32,
"height": 14,
"gfxWidth": 32,
"gfxHeight": 14,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"hots": [[0, 7]],
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 6.0,
"gravity": true,
"foreground": false,
"fixByBlocks": true,
"througthBlock": false,
"keepStrick": true
}
}
================================================
FILE: projectiles/ice_bullet.json
================================================
{
"ice_bullet": {
"ai": "IceBullet",
"textureData": "ice_bullet.png",
"width": 12,
"height": 12,
"gfxWidth": 24,
"gfxHeight": 24,
"gfxOffsetX": -6,
"gfxOffsetY": -6,
"hots": [[12, 12]],
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 12.0,
"gravity": false,
"foreground": true,
"fixByBlocks": false,
"througthBlock": false,
"keepStrick": true
}
}
================================================
FILE: projectiles/ice_magic.json
================================================
{
"ice_magic": {
"ai": "IceMagic",
"textureData": "ice_magic.png",
"width": 12,
"height": 12,
"gfxWidth": 24,
"gfxHeight": 12,
"gfxOffsetX": -6,
"gfxOffsetY": 0,
"hots": [ [ 6, 6 ] ],
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 12.0,
"gravity": false,
"foreground": true,
"fixByBlocks": true,
"througthBlock": false,
"keepStrick": true
}
}
================================================
FILE: projectiles/light_bullet_laser.json
================================================
{
"light_bullet_laser": {
"ai": "LaserBullet",
"textureData": "light_bullet_laser.png",
"width": 64,
"height": 2,
"gfxWidth": 64,
"gfxHeight": 2,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"hots": [[0, 0]],
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "ROTATED_BOX",
"maxSpeed": 32.0,
"gravity": false,
"foreground": false,
"fixByBlocks": false,
"througthBlock": false,
"keepStrick": true
}
}
================================================
FILE: projectiles/lighting_arrow.json
================================================
{
"lighting_arrow": {
"ai": "LightingArrow",
"textureData": "lighting_arrow.png",
"width": 32,
"height": 14,
"gfxWidth": 32,
"gfxHeight": 14,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"hots": [[0, 7]],
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "ROTATED_BOX",
"maxSpeed": 6.0,
"gravity": true,
"foreground": false,
"fixByBlocks": false,
"througthBlock": false,
"keepStrick": true
}
}
================================================
FILE: projectiles/lighting_bullet_blue.json
================================================
{
"lighting_bullet_blue": {
"ai": "BlueBullet",
"textureData": "lighting_bullet_blue.png",
"width": 32,
"height": 32,
"gfxWidth": 32,
"gfxHeight": 32,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"hots": [[16, 16]],
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 6.0,
"gravity": false,
"foreground": true,
"fixByBlocks": false,
"througthBlock": false,
"keepStrick": true
}
}
================================================
FILE: projectiles/lighting_bullet_red_invert2.json
================================================
{
"lighting_bullet_red_invert2": {
"ai": "RedSpeedUp",
"textureData": "lighting_bullet_red_invert2.png",
"width": 32,
"height": 32,
"gfxWidth": 32,
"gfxHeight": 32,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"hots": [[16, 16]],
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 6.0,
"gravity": false,
"foreground": true,
"fixByBlocks": false,
"througthBlock": false,
"keepStrick": true
}
}
================================================
FILE: projectiles/lighting_bullet_yellow.json
================================================
{
"lighting_bullet_yellow": {
"ai": "LightingBulletYellow",
"textureData": "lighting_bullet_yellow.png",
"width": 32,
"height": 32,
"gfxWidth": 32,
"gfxHeight": 32,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"hots": [[16, 16]],
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 6.0,
"gravity": false,
"foreground": true,
"fixByBlocks": false,
"througthBlock": false,
"keepStrick": true
}
}
================================================
FILE: projectiles/lighting_wheel.json
================================================
{
"lighting_wheel": {
"ai": "LightingWheel",
"textureData": "lighting_wheel.png",
"width": 32,
"height": 32,
"gfxWidth": 32,
"gfxHeight": 32,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"hots": [[16, 16]],
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 6.0,
"gravity": false,
"foreground": true,
"fixByBlocks": false,
"througthBlock": false,
"keepStrick": true
}
}
================================================
FILE: projectiles/magic_wave.json
================================================
{
"magic_wave": {
"ai": "MagicWave",
"textureData": "magic_wave.png",
"width": 48,
"height": 32,
"gfxWidth": 48,
"gfxHeight": 32,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"hots": [[0, 16]],
"frameStyle": 1,
"frames": 2,
"frameSpeed": 4,
"shape": "ROTATED_BOX",
"maxSpeed": 12.0,
"gravity": false,
"foreground": true,
"fixByBlocks": false,
"througthBlock": false,
"keepStrick": true
}
}
================================================
FILE: projectiles/magic_wave3.json
================================================
{
"magic_wave3": {
"ai": "BlueWave",
"textureData": "magic_wave3.png",
"width": 48,
"height": 32,
"gfxWidth": 48,
"gfxHeight": 32,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"hots": [[0, 16]],
"frameStyle": 1,
"frames": 4,
"frameSpeed": 4,
"shape": "ROTATED_BOX",
"maxSpeed": 12.0,
"gravity": false,
"foreground": true,
"fixByBlocks": false,
"througthBlock": false,
"keepStrick": true
}
}
================================================
FILE: projectiles/mini_rocket.json
================================================
{
"mini_rocket": {
"ai": "MiniRocket",
"textureData": "mini_rocket.png",
"width": 24,
"height": 16,
"gfxWidth": 24,
"gfxHeight": 16,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"hots": [ [ 0, 8 ] ],
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "ROTATED_BOX",
"maxSpeed": 6.0,
"gravity": false,
"foreground": false,
"fixByBlocks": false,
"througthBlock": false,
"keepStrick": true
}
}
================================================
FILE: projectiles/rocket.json
================================================
{
"rocket": {
"ai": "Rocket",
"textureData": "rocket.png",
"width": 28,
"height": 20,
"gfxWidth": 28,
"gfxHeight": 20,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"hots": [ [ 0, 10 ] ],
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "ROTATED_BOX",
"maxSpeed": 6.0,
"gravity": true,
"foreground": false,
"fixByBlocks": false,
"througthBlock": false,
"keepStrick": true
}
}
================================================
FILE: projectiles/shadow_magic.json
================================================
{
"shadow_magic": {
"ai": "ShadowMagic",
"textureData": "shadow_magic.png",
"width": 20,
"height": 20,
"gfxWidth": 20,
"gfxHeight": 20,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"hots": [[10, 10]],
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 8.0,
"gravity": false,
"foreground": true,
"fixByBlocks": false,
"througthBlock": false,
"keepStrick": true
}
}
================================================
FILE: projectiles/shulker_bullet.json
================================================
{
"shulker_bullet": {
"ai": "ShulkerBullet",
"textureData": "shulker_bullet.png",
"width": 16,
"height": 16,
"gfxWidth": 16,
"gfxHeight": 16,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"hots": [[8, 8]],
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 3.0,
"gravity": false,
"foreground": false,
"fixByBlocks": false,
"througthBlock": false,
"keepStrick": true
}
}
================================================
FILE: projectiles/small_air_bullet.json
================================================
{
"small_air_bullet": {
"ai": "AirBullet",
"textureData": "small_air_bullet.png",
"width": 28,
"height": 12,
"gfxWidth": 28,
"gfxHeight": 12,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"hots": [[0, 6]],
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 12.0,
"gravity": false,
"foreground": false,
"fixByBlocks": false,
"througthBlock": false,
"keepStrick": true
}
}
================================================
FILE: projectiles/snow_flake.json
================================================
{
"snow_flake": {
"ai": "SnowFlake",
"textureData": "snow_flake.png",
"width": 32,
"height": 32,
"gfxWidth": 40,
"gfxHeight": 40,
"gfxOffsetX": -4,
"gfxOffsetY": -4,
"hots": [[16, 16]],
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 3.0,
"gravity": false,
"foreground": false,
"fixByBlocks": false,
"througthBlock": false,
"keepStrick": true
}
}
================================================
FILE: projectiles/spike.json
================================================
{
"spike": {
"ai": "Spike",
"textureData": "spike.png",
"width": 28,
"height": 16,
"gfxWidth": 28,
"gfxHeight": 16,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"hots": [[0, 7]],
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 6.0,
"gravity": true,
"foreground": false,
"fixByBlocks": false,
"througthBlock": false,
"keepStrick": true
}
}
================================================
FILE: projectiles/star.json
================================================
{
"star": {
"ai": "StarMagic",
"textureData": "star.png",
"width": 22,
"height": 24,
"gfxWidth": 22,
"gfxHeight": 24,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"hots": [ [ 11, 12 ] ],
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 8.0,
"gravity": false,
"foreground": true,
"fixByBlocks": false,
"througthBlock": true,
"keepStrick": false
}
}
================================================
FILE: projectiles/star_arrow.json
================================================
{
"star_arrow": {
"ai": "StarArrow",
"textureData": "star_arrow.png",
"width": 32,
"height": 14,
"gfxWidth": 32,
"gfxHeight": 14,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"hots": [[0, 7]],
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "ROTATED_BOX",
"maxSpeed": 6.0,
"gravity": true,
"foreground": false,
"fixByBlocks": false,
"througthBlock": false,
"keepStrick": true
}
}
================================================
FILE: projectiles/super_fire.json
================================================
{
"super_fire": {
"ai": "SuperFire",
"textureData": "super_fire.png",
"width": 16,
"height": 16,
"gfxWidth": 16,
"gfxHeight": 16,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"hots": [[8, 8]],
"frameStyle": 1,
"frames": 3,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 32.0,
"gravity": false,
"foreground": false,
"fixByBlocks": false,
"througthBlock": false,
"keepStrick": false
}
}
================================================
FILE: projectiles/sword_arrow.json
================================================
{
"sword_arrow": {
"ai": "SwordArrow",
"textureData": "sword_arrow.png",
"width": 32,
"height": 20,
"gfxWidth": 32,
"gfxHeight": 20,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"hots": [[0, 10]],
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "ROTATED_BOX",
"maxSpeed": 10.0,
"gravity": true,
"foreground": false,
"fixByBlocks": false,
"througthBlock": false,
"keepStrick": true
}
}
================================================
FILE: projectiles/tnt.json
================================================
{
"tnt": {
"ai": "Bomb",
"textureData": "tnt.png",
"width": 16,
"height": 16,
"gfxWidth": 16,
"gfxHeight": 16,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"hots": [[8, 0]],
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 8.0,
"gravity": true,
"foreground": false,
"fixByBlocks": true,
"througthBlock": false,
"keepStrick": true
}
}
================================================
FILE: projectiles/water_flow.json
================================================
{
"water_flow": {
"ai": "WaterFlow",
"textureData": "super_fire.png",
"width": 16,
"height": 16,
"gfxWidth": 16,
"gfxHeight": 16,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"hots": [ [ 8, 8 ] ],
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 14.0,
"gravity": true,
"foreground": true,
"fixByBlocks": false,
"througthBlock": false,
"keepStrick": true
}
}
================================================
FILE: projectiles/water_magic.json
================================================
{
"water_magic": {
"ai": "WaterMagic",
"textureData": "water_magic.png",
"width": 16,
"height": 16,
"gfxWidth": 16,
"gfxHeight": 16,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"hots": [ [ 8, 8 ] ],
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "BOX",
"maxSpeed": 14.0,
"gravity": true,
"foreground": true,
"fixByBlocks": false,
"througthBlock": false,
"keepStrick": true
}
}
================================================
FILE: projectiles/wooden_arrow.json
================================================
{
"wooden_arrow": {
"ai": "Arrow",
"textureData": "wooden_arrow.png",
"width": 32,
"height": 14,
"gfxWidth": 32,
"gfxHeight": 14,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"hots": [[0, 7]],
"frameStyle": 1,
"frames": 1,
"frameSpeed": 8,
"shape": "ROTATED_BOX",
"maxSpeed": 6.0,
"gravity": true,
"foreground": false,
"fixByBlocks": false,
"througthBlock": false,
"keepStrick": true
}
}
================================================
FILE: projectiles/wooden_boomerang.json
================================================
{
"wooden_boomerang": {
"ai": "Boomerang",
"textureData": "wooden_boomerang.png",
"width": 18,
"height": 32,
"gfxWidth": 18,
"gfxHeight": 32,
"gfxOffsetX": 0,
"gfxOffsetY": 0,
"hots": [[8, 16]],
"frameStyle": 1,
"frames": 1,
"frameSpeed": 16,
"shape": "BOX",
"maxSpeed": 8.0,
"gravity": false,
"foreground": false,
"fixByBlocks": false,
"througthBlock": false,
"special": 0,
"keepStrick": false,
"trajectoryPrediction": false,
"killWhenHitTile": false
}
}
================================================
FILE: recipe_config/Brew.json
================================================
{
"Brew": {
"iconItem": "brewing_stand",
"sourceGroups": [
{
"slotCount": 2,
"searchAction": "SA_FIX"
}
],
"resultSlotCount": 1,
"exData": [
["int", "time"]
]
}
}
================================================
FILE: recipe_config/Craft3x.json
================================================
{
"Craft3x": {
"iconItem": "crafting_table",
"sourceGroups": [
{
"slotCount": 9,
"align": true,
"alignWidth": 3,
"alignHeight": 3,
"searchAction": "SA_NORMAL"
}
],
"resultSlotCount": 2,
"exData": []
}
}
================================================
FILE: recipe_config/Repair.json
================================================
{
"Repair": {
"iconItem": "anvil",
"sourceGroups": [
{
"slotCount": 2,
"searchAction": "SA_FIX"
}
],
"resultSlotCount": 1,
"exData": [
["double", "repairRate"]
]
}
}
================================================
FILE: recipe_config/Smelt.json
================================================
{
"Smelt": {
"iconItem": "furnace",
"sourceGroups": [
{
"slotCount": 1,
"searchAction": "SA_FIX"
}
],
"resultSlotCount": 1,
"exData": [
["int", "time"]
]
}
}
================================================
FILE: recipes/brew/potion_awkward.json
================================================
{
"config": "Brew",
"results": [
{
"id": "potion_awkward",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "potion_water" ],
[ "B", "nether_wart" ]
],
"exData": { "time": 400 }
}
================================================
FILE: recipes/brew/potion_fire_resistance.json
================================================
{
"config": "Brew",
"results": [
{
"id": "potion_fire_resistance",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "potion_awkward" ],
[ "B", "magma_cream" ]
],
"exData": { "time": 400 }
}
================================================
FILE: recipes/brew/potion_fire_resistance_long.json
================================================
{
"config": "Brew",
"results": [
{
"id": "potion_fire_resistance_long",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "potion_fire_resistance" ],
[ "B", "redstone" ]
],
"exData": { "time": 400 }
}
================================================
FILE: recipes/brew/potion_glowing.json
================================================
{
"config": "Brew",
"results": [
{
"id": "potion_glowing",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "potion_awkward" ],
[ "B", "glowing_mushroom" ]
],
"exData": { "time": 400 }
}
================================================
FILE: recipes/brew/potion_harming.json
================================================
{
"config": "Brew",
"results": [
{
"id": "potion_harming",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "potion_healing" ],
[ "B", "fermented_spider_eye" ]
],
"exData": { "time": 400 }
}
================================================
FILE: recipes/brew/potion_harming_2.json
================================================
{
"config": "Brew",
"results": [
{
"id": "potion_harming",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "potion_poison" ],
[ "B", "fermented_spider_eye" ]
],
"exData": { "time": 400 }
}
================================================
FILE: recipes/brew/potion_harming_super.json
================================================
{
"config": "Brew",
"results": [
{
"id": "potion_harming_super",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "potion_harming" ],
[ "B", "glowstone_dust" ]
],
"exData": { "time": 400 }
}
================================================
FILE: recipes/brew/potion_healing.json
================================================
{
"config": "Brew",
"results": [
{
"id": "potion_healing",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "potion_awkward" ],
[ "B", "glistering_melon_slice" ]
],
"exData": { "time": 400 }
}
================================================
FILE: recipes/brew/potion_healing_super.json
================================================
{
"config": "Brew",
"results": [
{
"id": "potion_healing_super",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "potion_healing" ],
[ "B", "glowstone_dust" ]
],
"exData": { "time": 400 }
}
================================================
FILE: recipes/brew/potion_invisibility.json
================================================
{
"config": "Brew",
"results": [
{
"id": "potion_invisibility",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "potion_night_vision" ],
[ "B", "fermented_spider_eye" ]
],
"exData": { "time": 400 }
}
================================================
FILE: recipes/brew/potion_invisibility_long.json
================================================
{
"config": "Brew",
"results": [
{
"id": "potion_invisibility_long",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "potion_invisibility" ],
[ "B", "redstone" ]
],
"exData": { "time": 400 }
}
================================================
FILE: recipes/brew/potion_leaping.json
================================================
{
"config": "Brew",
"results": [
{
"id": "potion_leaping",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "potion_awkward" ],
[ "B", "rabbit_foot" ]
],
"exData": { "time": 400 }
}
================================================
FILE: recipes/brew/potion_leaping_long.json
================================================
{
"config": "Brew",
"results": [
{
"id": "potion_leaping_long",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "potion_leaping" ],
[ "B", "redstone" ]
],
"exData": { "time": 400 }
}
================================================
FILE: recipes/brew/potion_night_vision.json
================================================
{
"config": "Brew",
"results": [
{
"id": "potion_night_vision",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "potion_awkward" ],
[ "B", "golden_carrot" ]
],
"exData": { "time": 400 }
}
================================================
FILE: recipes/brew/potion_night_vision_long.json
================================================
{
"config": "Brew",
"results": [
{
"id": "potion_night_vision_long",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "potion_night_vision" ],
[ "B", "redstone" ]
],
"exData": { "time": 400 }
}
================================================
FILE: recipes/brew/potion_poison.json
================================================
{
"config": "Brew",
"results": [
{
"id": "potion_poison",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "potion_awkward" ],
[ "B", "poison_mushroom" ]
],
"exData": { "time": 400 }
}
================================================
FILE: recipes/brew/potion_poison_2.json
================================================
{
"config": "Brew",
"results": [
{
"id": "potion_poison",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "potion_awkward" ],
[ "B", "spider_eye" ]
],
"exData": { "time": 400 }
}
================================================
FILE: recipes/brew/potion_poison_long.json
================================================
{
"config": "Brew",
"results": [
{
"id": "potion_poison_long",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "potion_poison" ],
[ "B", "redstone" ]
],
"exData": { "time": 400 }
}
================================================
FILE: recipes/brew/potion_regeneration.json
================================================
{
"config": "Brew",
"results": [
{
"id": "potion_regeneration",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "potion_awkward" ],
[ "B", "ghast_tear" ]
],
"exData": { "time": 400 }
}
================================================
FILE: recipes/brew/potion_regeneration_long.json
================================================
{
"config": "Brew",
"results": [
{
"id": "potion_regeneration_long",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "potion_regeneration" ],
[ "B", "redstone" ]
],
"exData": { "time": 400 }
}
================================================
FILE: recipes/brew/potion_slow_falling.json
================================================
{
"config": "Brew",
"results": [
{
"id": "potion_slow_falling",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "potion_awkward" ],
[ "B", "phantom_membrane" ]
],
"exData": { "time": 400 }
}
================================================
FILE: recipes/brew/potion_slow_falling_long.json
================================================
{
"config": "Brew",
"results": [
{
"id": "potion_slow_falling_long",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "potion_slow_falling" ],
[ "B", "redstone" ]
],
"exData": { "time": 400 }
}
================================================
FILE: recipes/brew/potion_slowness.json
================================================
{
"config": "Brew",
"results": [
{
"id": "potion_slowness",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "potion_swiftness" ],
[ "B", "fermented_spider_eye" ]
],
"exData": { "time": 400 }
}
================================================
FILE: recipes/brew/potion_slowness_2.json
================================================
{
"config": "Brew",
"results": [
{
"id": "potion_slowness",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "potion_leaping" ],
[ "B", "fermented_spider_eye" ]
],
"exData": { "time": 400 }
}
================================================
FILE: recipes/brew/potion_slowness_long.json
================================================
{
"config": "Brew",
"results": [
{
"id": "potion_slowness_long",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "potion_slowness" ],
[ "B", "redstone" ]
],
"exData": { "time": 400 }
}
================================================
FILE: recipes/brew/potion_strength.json
================================================
{
"config": "Brew",
"results": [
{
"id": "potion_strength",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "potion_awkward" ],
[ "B", "blaze_powder" ]
],
"exData": { "time": 400 }
}
================================================
FILE: recipes/brew/potion_strength_long.json
================================================
{
"config": "Brew",
"results": [
{
"id": "potion_strength_long",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "potion_strength" ],
[ "B", "redstone" ]
],
"exData": { "time": 400 }
}
================================================
FILE: recipes/brew/potion_swiftness.json
================================================
{
"config": "Brew",
"results": [
{
"id": "potion_swiftness",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "potion_awkward" ],
[ "B", "suger" ]
],
"exData": { "time": 400 }
}
================================================
FILE: recipes/brew/potion_swiftness_long.json
================================================
{
"config": "Brew",
"results": [
{
"id": "potion_swiftness_long",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "potion_swiftness" ],
[ "B", "redstone" ]
],
"exData": { "time": 400 }
}
================================================
FILE: recipes/brew/potion_water_breathing.json
================================================
{
"config": "Brew",
"results": [
{
"id": "potion_water_breathing",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "potion_awkward" ],
[ "B", "pufferfish" ]
],
"exData": { "time": 400 }
}
================================================
FILE: recipes/brew/potion_water_breathing_long.json
================================================
{
"config": "Brew",
"results": [
{
"id": "potion_water_breathing_long",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "potion_water_breathing" ],
[ "B", "redstone" ]
],
"exData": { "time": 400 }
}
================================================
FILE: recipes/brew/potion_weakness.json
================================================
{
"config": "Brew",
"results": [
{
"id": "potion_weakness",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "potion_strength" ],
[ "B", "fermented_spider_eye" ]
],
"exData": { "time": 400 }
}
================================================
FILE: recipes/brew/potion_weakness_2.json
================================================
{
"config": "Brew",
"results": [
{
"id": "potion_weakness",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "potion_regeneration" ],
[ "B", "fermented_spider_eye" ]
],
"exData": { "time": 400 }
}
================================================
FILE: recipes/brew/potion_weakness_long.json
================================================
{
"config": "Brew",
"results": [
{
"id": "potion_weakness_long",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "potion_weakness" ],
[ "B", "redstone" ]
],
"exData": { "time": 400 }
}
================================================
FILE: recipes/craft3x/acacia_plank.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "acacia_plank",
"stackSize": 4
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "wood_acacia" ] ]
}
================================================
FILE: recipes/craft3x/amethyst_staff.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "amethyst_staff",
"stackSize": 1
}
],
"pattern": [
"OAB",
"OCA",
"COO"
],
"elements": [
[ "A", "lapis_lazuli" ],
[ "B", "gold_ingot" ],
[ "C", "OD_IRON_INGOT" ]
]
}
================================================
FILE: recipes/craft3x/amethyst_staff_2.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "amethyst_staff",
"stackSize": 1
}
],
"pattern": [
"OAB",
"OCA",
"COO"
],
"elements": [
[ "A", "lapis_lazuli" ],
[ "B", "gold_ingot" ],
[ "C", "lead_ingot" ]
]
}
================================================
FILE: recipes/craft3x/ancient_ingot.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "ancient_ingot",
"stackSize": 1
}
],
"pattern": [
"ABO",
"OOO",
"OOO"
],
"elements": [
[ "A", "netherite_ingot" ],
[ "B", "ancient_sample" ]
]
}
================================================
FILE: recipes/craft3x/andesite.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "andesite",
"stackSize": 2
}
],
"pattern": [
"ABO",
"OOO",
"OOO"
],
"elements": [
[ "A", "cobblestone" ],
[ "B", "diorite" ]
]
}
================================================
FILE: recipes/craft3x/andesite_polished.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "andesite_polished",
"stackSize": 4
}
],
"pattern": [
"AAO",
"AAO",
"OOO"
],
"elements": [ [ "A", "andesite" ] ]
}
================================================
FILE: recipes/craft3x/anvil.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "anvil",
"stackSize": 1
}
],
"pattern": [
"AAA",
"OBO",
"BBB"
],
"elements": [
[ "A", "block_iron" ],
[ "B", "OD_IRON_INGOT" ]
]
}
================================================
FILE: recipes/craft3x/barrel.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "barrel",
"stackSize": 1
}
],
"pattern": [
"BAB",
"BOB",
"BAB"
],
"elements": [
[ "A", "OD_WOODEN_PLATFORM" ],
[ "B", "OD_WOODEN_PLANK" ]
]
}
================================================
FILE: recipes/craft3x/bench_acacia.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "bench_acacia",
"stackSize": 1
}
],
"pattern": [
"AAA",
"BOB",
"OOO"
],
"elements": [
[ "A", "acacia_plank" ],
[ "B", "platform_acacia" ]
]
}
================================================
FILE: recipes/craft3x/bench_birch.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "bench_birch",
"stackSize": 1
}
],
"pattern": [
"AAA",
"BOB",
"OOO"
],
"elements": [
[ "A", "birch_plank" ],
[ "B", "platform_birch" ]
]
}
================================================
FILE: recipes/craft3x/bench_dark_oak.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "bench_dark_oak",
"stackSize": 1
}
],
"pattern": [
"AAA",
"BOB",
"OOO"
],
"elements": [
[ "A", "dark_oak_plank" ],
[ "B", "platform_dark_oak" ]
]
}
================================================
FILE: recipes/craft3x/bench_jungle.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "bench_jungle",
"stackSize": 1
}
],
"pattern": [
"AAA",
"BOB",
"OOO"
],
"elements": [
[ "A", "jungle_plank" ],
[ "B", "platform_jungle" ]
]
}
================================================
FILE: recipes/craft3x/bench_nether.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "bench_nether",
"stackSize": 1
}
],
"pattern": [
"AAA",
"BOB",
"OOO"
],
"elements": [
[ "A", "nether_brick" ],
[ "B", "platform_nether_brick" ]
]
}
================================================
FILE: recipes/craft3x/bench_oak.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "bench_oak",
"stackSize": 1
}
],
"pattern": [
"AAA",
"BOB",
"OOO"
],
"elements": [
[ "A", "oak_plank" ],
[ "B", "platform_oak" ]
]
}
================================================
FILE: recipes/craft3x/bench_palm.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "bench_palm",
"stackSize": 1
}
],
"pattern": [
"AAA",
"BOB",
"OOO"
],
"elements": [
[ "A", "palm_plank" ],
[ "B", "platform_palm" ]
]
}
================================================
FILE: recipes/craft3x/bench_spruce.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "bench_spruce",
"stackSize": 1
}
],
"pattern": [
"AAA",
"BOB",
"OOO"
],
"elements": [
[ "A", "spruce_plank" ],
[ "B", "platform_spruce" ]
]
}
================================================
FILE: recipes/craft3x/bench_tainted.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "bench_tainted",
"stackSize": 1
}
],
"pattern": [
"AAA",
"BOB",
"OOO"
],
"elements": [
[ "A", "tainted_plank" ],
[ "B", "platform_tainted" ]
]
}
================================================
FILE: recipes/craft3x/bench_volcano.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "bench_volcano",
"stackSize": 1
}
],
"pattern": [
"AAA",
"BOB",
"OOO"
],
"elements": [
[ "A", "volcano_plank" ],
[ "B", "platform_volcano" ]
]
}
================================================
FILE: recipes/craft3x/birch_plank.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "birch_plank",
"stackSize": 4
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "wood_birch" ] ]
}
================================================
FILE: recipes/craft3x/blaze_powder.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "blaze_powder",
"stackSize": 2
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "blaze_rod" ] ]
}
================================================
FILE: recipes/craft3x/block_coal.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "block_coal",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AAA",
"AAA"
],
"elements": [ [ "A", "coal" ] ]
}
================================================
FILE: recipes/craft3x/block_diamond.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "block_diamond",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AAA",
"AAA"
],
"elements": [ [ "A", "diamond" ] ]
}
================================================
FILE: recipes/craft3x/block_emerald.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "block_emerald",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AAA",
"AAA"
],
"elements": [ [ "A", "emerald" ] ]
}
================================================
FILE: recipes/craft3x/block_gold.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "block_gold",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AAA",
"AAA"
],
"elements": [ [ "A", "gold_ingot" ] ]
}
================================================
FILE: recipes/craft3x/block_iron.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "block_iron",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AAA",
"AAA"
],
"elements": [ [ "A", "iron_ingot" ] ]
}
================================================
FILE: recipes/craft3x/block_lapis.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "block_lapis",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AAA",
"AAA"
],
"elements": [ [ "A", "lapis_lazuli" ] ]
}
================================================
FILE: recipes/craft3x/block_netherite.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "block_netherite",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AAA",
"AAA"
],
"elements": [ [ "A", "netherite_ingot" ] ]
}
================================================
FILE: recipes/craft3x/block_quartz.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "block_quartz",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AAA",
"AAA"
],
"elements": [ [ "A", "quartz" ] ]
}
================================================
FILE: recipes/craft3x/block_redstone.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "block_redstone",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AAA",
"AAA"
],
"elements": [ [ "A", "redstone" ] ]
}
================================================
FILE: recipes/craft3x/blood_arrow.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "blood_arrow",
"stackSize": 1
}
],
"pattern": [
"BOO",
"AOO",
"BOO"
],
"elements": [
[ "A", "wooden_arrow" ],
[ "B", "rotten_flesh" ]
]
}
================================================
FILE: recipes/craft3x/blood_arrow_2.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "blood_arrow",
"stackSize": 1
}
],
"pattern": [
"OBO",
"BAB",
"OBO"
],
"elements": [
[ "A", "wooden_arrow" ],
[ "B", "spider_eye" ]
]
}
================================================
FILE: recipes/craft3x/blood_bow.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "blood_bow",
"stackSize": 1
}
],
"pattern": [
"BAC",
"AOC",
"BAC"
],
"elements": [
[ "A", "copper_ingot" ],
[ "B", "rotten_flesh" ],
[ "C", "string" ]
]
}
================================================
FILE: recipes/craft3x/blue_ice.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "blue_ice",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AAA",
"AAA"
],
"elements": [ [ "A", "ice_packed" ] ]
}
================================================
FILE: recipes/craft3x/blue_stone_bow.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "blue_stone_bow",
"stackSize": 1
}
],
"pattern": [
"BAC",
"AOC",
"BAC"
],
"elements": [
[ "A", "diamond" ],
[ "B", "lapis_lazuli" ],
[ "C", "string" ]
]
}
================================================
FILE: recipes/craft3x/blue_torch.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "blue_torch",
"stackSize": 1
}
],
"pattern": [
"ABO",
"OOO",
"OOO"
],
"elements": [
[ "A", "torch" ],
[ "B", "dye_blue" ]
]
}
================================================
FILE: recipes/craft3x/blue_wire.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "blue_wire",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "red_wire" ],
[ "B", "dye_blue" ]
]
}
================================================
FILE: recipes/craft3x/bomb.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "bomb",
"stackSize": 1
}
],
"pattern": [
"CBC",
"BAB",
"CBC"
],
"elements": [
[ "A", "fire_charge" ],
[ "B", "gunpowder" ],
[ "C", "sand" ]
]
}
================================================
FILE: recipes/craft3x/bomb_2.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "bomb",
"stackSize": 1
}
],
"pattern": [
"CBC",
"BAB",
"CBC"
],
"elements": [
[ "A", "fire_charge" ],
[ "B", "gunpowder" ],
[ "C", "red_sand" ]
]
}
================================================
FILE: recipes/craft3x/bone_block.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "bone_block",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AAA",
"AAA"
],
"elements": [ [ "A", "bone_meal" ] ]
}
================================================
FILE: recipes/craft3x/bone_meal.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "bone_meal",
"stackSize": 3
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "bone" ] ]
}
================================================
FILE: recipes/craft3x/bone_meal_2.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "bone_meal",
"stackSize": 9
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "bone_block" ] ]
}
================================================
FILE: recipes/craft3x/book.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "book",
"stackSize": 1
}
],
"pattern": [
"AAA",
"BOO",
"OOO"
],
"elements": [
[ "A", "paper" ],
[ "B", "leather" ]
]
}
================================================
FILE: recipes/craft3x/book_block.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "book_block",
"stackSize": 1
}
],
"pattern": [
"AAO",
"AAO",
"OOO"
],
"elements": [ [ "A", "book" ] ]
}
================================================
FILE: recipes/craft3x/bookcase_acacia.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "bookcase_acacia",
"stackSize": 1
}
],
"pattern": [
"AAA",
"BBB",
"AAA"
],
"elements": [
[ "A", "acacia_plank" ],
[ "B", "book_block" ]
]
}
================================================
FILE: recipes/craft3x/bookcase_birch.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "bookcase_birch",
"stackSize": 1
}
],
"pattern": [
"AAA",
"BBB",
"AAA"
],
"elements": [
[ "A", "birch_plank" ],
[ "B", "book_block" ]
]
}
================================================
FILE: recipes/craft3x/bookcase_dark_oak.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "bookcase_dark_oak",
"stackSize": 1
}
],
"pattern": [
"AAA",
"BBB",
"AAA"
],
"elements": [
[ "A", "dark_oak_plank" ],
[ "B", "book_block" ]
]
}
================================================
FILE: recipes/craft3x/bookcase_jungle.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "bookcase_jungle",
"stackSize": 1
}
],
"pattern": [
"AAA",
"BBB",
"AAA"
],
"elements": [
[ "A", "jungle_plank" ],
[ "B", "book_block" ]
]
}
================================================
FILE: recipes/craft3x/bookcase_nether.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "bookcase_nether",
"stackSize": 1
}
],
"pattern": [
"AAA",
"BBB",
"AAA"
],
"elements": [
[ "A", "nether_brick" ],
[ "B", "book_block" ]
]
}
================================================
FILE: recipes/craft3x/bookcase_oak.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "bookcase_oak",
"stackSize": 1
}
],
"pattern": [
"AAA",
"BBB",
"AAA"
],
"elements": [
[ "A", "oak_plank" ],
[ "B", "book_block" ]
]
}
================================================
FILE: recipes/craft3x/bookcase_palm.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "bookcase_palm",
"stackSize": 1
}
],
"pattern": [
"AAA",
"BBB",
"AAA"
],
"elements": [
[ "A", "palm_plank" ],
[ "B", "book_block" ]
]
}
================================================
FILE: recipes/craft3x/bookcase_spruce.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "bookcase_spruce",
"stackSize": 1
}
],
"pattern": [
"AAA",
"BBB",
"AAA"
],
"elements": [
[ "A", "spruce_plank" ],
[ "B", "book_block" ]
]
}
================================================
FILE: recipes/craft3x/bookcase_tainted.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "bookcase_tainted",
"stackSize": 1
}
],
"pattern": [
"AAA",
"BBB",
"AAA"
],
"elements": [
[ "A", "tainted_plank" ],
[ "B", "book_block" ]
]
}
================================================
FILE: recipes/craft3x/bookcase_volcano.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "bookcase_volcano",
"stackSize": 1
}
],
"pattern": [
"AAA",
"BBB",
"AAA"
],
"elements": [
[ "A", "volcano_plank" ],
[ "B", "book_block" ]
]
}
================================================
FILE: recipes/craft3x/boomerang.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "boomerang",
"stackSize": 1
}
],
"pattern": [
"OAO",
"AOO",
"OAO"
],
"elements": [ [ "A", "copper_ingot" ] ]
}
================================================
FILE: recipes/craft3x/boomerang_2.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "boomerang",
"stackSize": 1
}
],
"pattern": [
"OAO",
"AOO",
"OAO"
],
"elements": [ [ "A", "tin_ingot" ] ]
}
================================================
FILE: recipes/craft3x/bowl.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "bowl",
"stackSize": 4
}
],
"pattern": [
"AOA",
"OAO",
"OOO"
],
"elements": [ [ "A", "OD_WOODEN_PLANK" ] ]
}
================================================
FILE: recipes/craft3x/bread.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "bread",
"stackSize": 1
}
],
"pattern": [
"AAA",
"OOO",
"OOO"
],
"elements": [ [ "A", "wheat" ] ]
}
================================================
FILE: recipes/craft3x/brewing_stand.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "brewing_stand",
"stackSize": 1
}
],
"pattern": [
"OAO",
"BBB",
"OOO"
],
"elements": [
[ "A", "blaze_rod" ],
[ "B", "cobblestone" ]
]
}
================================================
FILE: recipes/craft3x/brick.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "brick",
"stackSize": 1
}
],
"pattern": [
"AAO",
"AAO",
"OOO"
],
"elements": [ [ "A", "red_brick" ] ]
}
================================================
FILE: recipes/craft3x/bronze_axe.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "bronze_axe",
"stackSize": 1
}
],
"pattern": [
"AAO",
"ABO",
"OBO"
],
"elements": [
[ "A", "bronze_ingot" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/bronze_chestplate.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "bronze_chestplate",
"stackSize": 1
}
],
"pattern": [
"AOA",
"AAA",
"AAA"
],
"elements": [ [ "A", "bronze_ingot" ] ]
}
================================================
FILE: recipes/craft3x/bronze_helmet.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "bronze_helmet",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AOA",
"OOO"
],
"elements": [ [ "A", "bronze_ingot" ] ]
}
================================================
FILE: recipes/craft3x/bronze_ingot.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "bronze_ingot",
"stackSize": 2
}
],
"pattern": [
"ABB",
"BOO",
"OOO"
],
"elements": [
[ "A", "tin_ingot" ],
[ "B", "copper_ingot" ]
]
}
================================================
FILE: recipes/craft3x/bronze_leggings.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "bronze_leggings",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AOA",
"AOA"
],
"elements": [ [ "A", "bronze_ingot" ] ]
}
================================================
FILE: recipes/craft3x/bronze_pickaxe.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "bronze_pickaxe",
"stackSize": 1
}
],
"pattern": [
"AAA",
"OBO",
"OBO"
],
"elements": [
[ "A", "bronze_ingot" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/bronze_sword.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "bronze_sword",
"stackSize": 1
}
],
"pattern": [
"AOO",
"AOO",
"BOO"
],
"elements": [
[ "A", "bronze_ingot" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/brown_mushroom.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "brown_mushroom",
"stackSize": 2
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "large_brown_mushroom" ] ]
}
================================================
FILE: recipes/craft3x/brown_mushroom_2.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "brown_mushroom",
"stackSize": 2
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "brown_mushroom_block" ] ]
}
================================================
FILE: recipes/craft3x/bucket_empty.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "bucket_empty",
"stackSize": 3
}
],
"pattern": [
"AOA",
"OAO",
"OOO"
],
"elements": [ [ "A", "OD_IRON_INGOT" ] ]
}
================================================
FILE: recipes/craft3x/cabinet_acacia.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "cabinet_acacia",
"stackSize": 1
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "acacia_plank" ],
[ "B", "chest" ]
]
}
================================================
FILE: recipes/craft3x/cabinet_birch.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "cabinet_birch",
"stackSize": 1
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "birch_plank" ],
[ "B", "chest" ]
]
}
================================================
FILE: recipes/craft3x/cabinet_dark_oak.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "cabinet_dark_oak",
"stackSize": 1
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "dark_oak_plank" ],
[ "B", "chest" ]
]
}
================================================
FILE: recipes/craft3x/cabinet_jungle.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "cabinet_jungle",
"stackSize": 1
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "jungle_plank" ],
[ "B", "chest" ]
]
}
================================================
FILE: recipes/craft3x/cabinet_nether.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "cabinet_nether",
"stackSize": 1
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "nether_brick" ],
[ "B", "chest" ]
]
}
================================================
FILE: recipes/craft3x/cabinet_oak.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "cabinet_oak",
"stackSize": 1
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "oak_plank" ],
[ "B", "chest" ]
]
}
================================================
FILE: recipes/craft3x/cabinet_palm.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "cabinet_palm",
"stackSize": 1
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "palm_plank" ],
[ "B", "chest" ]
]
}
================================================
FILE: recipes/craft3x/cabinet_spruce.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "cabinet_spruce",
"stackSize": 1
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "spruce_plank" ],
[ "B", "chest" ]
]
}
================================================
FILE: recipes/craft3x/cabinet_tainted.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "cabinet_tainted",
"stackSize": 1
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "tainted_plank" ],
[ "B", "chest" ]
]
}
================================================
FILE: recipes/craft3x/cabinet_volcano.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "cabinet_volcano",
"stackSize": 1
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "volcano_plank" ],
[ "B", "chest" ]
]
}
================================================
FILE: recipes/craft3x/cake.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "cake",
"stackSize": 1
},
{
"id": "bucket_empty",
"stackSize": 3
}
],
"pattern": [
"BBB",
"CAC",
"DDD"
],
"elements": [
[ "A", "egg" ],
[ "B", "bucket_milk" ],
[ "C", "suger" ],
[ "D", "wheat" ]
]
}
================================================
FILE: recipes/craft3x/cake_piece.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "cake_piece",
"stackSize": 8
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "cake" ] ]
}
================================================
FILE: recipes/craft3x/campfire.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "campfire",
"stackSize": 1
}
],
"pattern": [
"OBO",
"BAB",
"CCC"
],
"elements": [
[ "A", "coal" ],
[ "B", "stick" ],
[ "C", "OD_WOOD" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/campfire_2.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "campfire",
"stackSize": 1
}
],
"pattern": [
"OBO",
"BAB",
"CCC"
],
"elements": [
[ "A", "charcoal" ],
[ "B", "stick" ]
],
"group3": "OD_WOOD",
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/campfire_3.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "campfire",
"stackSize": 1
}
],
"pattern": [
"OBO",
"BAB",
"CCC"
],
"elements": [
[ "A", "coal" ],
[ "B", "stick" ]
],
"group3": "OD_WOOD_STRIPPED",
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/campfire_4.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "campfire",
"stackSize": 1
}
],
"pattern": [
"OBO",
"BAB",
"CCC"
],
"elements": [
[ "A", "charcoal" ],
[ "B", "stick" ]
],
"group3": "OD_WOOD_STRIPPED",
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/candle.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "candle",
"stackSize": 1
}
],
"pattern": [
"AOO",
"BOO",
"OOO"
],
"elements": [
[ "A", "torch" ],
[ "B", "OD_IRON_INGOT" ]
]
}
================================================
FILE: recipes/craft3x/candle_holder.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "candle_holder",
"stackSize": 1
}
],
"pattern": [
"AAA",
"OBO",
"BBB"
],
"elements": [
[ "A", "candle" ],
[ "B", "OD_IRON_INGOT" ]
]
}
================================================
FILE: recipes/craft3x/cauldron.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "cauldron",
"stackSize": 1
}
],
"pattern": [
"AOA",
"AOA",
"AAA"
],
"elements": [ [ "A", "OD_IRON_INGOT" ] ]
}
================================================
FILE: recipes/craft3x/chair_acacia.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "chair_acacia",
"stackSize": 2
}
],
"pattern": [
"AOO",
"AAA",
"AOA"
],
"elements": [ [ "A", "acacia_plank" ] ]
}
================================================
FILE: recipes/craft3x/chair_birch.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "chair_birch",
"stackSize": 2
}
],
"pattern": [
"AOO",
"AAA",
"AOA"
],
"elements": [ [ "A", "birch_plank" ] ]
}
================================================
FILE: recipes/craft3x/chair_dark_oak.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "chair_dark_oak",
"stackSize": 2
}
],
"pattern": [
"AOO",
"AAA",
"AOA"
],
"elements": [ [ "A", "dark_oak_plank" ] ]
}
================================================
FILE: recipes/craft3x/chair_jungle.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "chair_jungle",
"stackSize": 2
}
],
"pattern": [
"AOO",
"AAA",
"AOA"
],
"elements": [ [ "A", "jungle_plank" ] ]
}
================================================
FILE: recipes/craft3x/chair_nether.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "chair_nether",
"stackSize": 2
}
],
"pattern": [
"AOO",
"AAA",
"AOA"
],
"elements": [ [ "A", "nether_brick" ] ]
}
================================================
FILE: recipes/craft3x/chair_oak.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "chair_oak",
"stackSize": 2
}
],
"pattern": [
"AOO",
"AAA",
"AOA"
],
"elements": [ [ "A", "oak_plank" ] ]
}
================================================
FILE: recipes/craft3x/chair_palm.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "chair_palm",
"stackSize": 2
}
],
"pattern": [
"AOO",
"AAA",
"AOA"
],
"elements": [ [ "A", "palm_plank" ] ]
}
================================================
FILE: recipes/craft3x/chair_spruce.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "chair_spruce",
"stackSize": 2
}
],
"pattern": [
"AOO",
"AAA",
"AOA"
],
"elements": [ [ "A", "spruce_plank" ] ]
}
================================================
FILE: recipes/craft3x/chair_tainted.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "chair_tainted",
"stackSize": 2
}
],
"pattern": [
"AOO",
"AAA",
"AOA"
],
"elements": [ [ "A", "tainted_plank" ] ]
}
================================================
FILE: recipes/craft3x/chair_volcano.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "chair_volcano",
"stackSize": 2
}
],
"pattern": [
"AOO",
"AAA",
"AOA"
],
"elements": [ [ "A", "volcano_plank" ] ]
}
================================================
FILE: recipes/craft3x/chandeliers.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "chandeliers",
"stackSize": 1
}
],
"pattern": [
"OCO",
"BAB",
"CCC"
],
"elements": [
[ "A", "diamond" ],
[ "B", "glowstone_dust" ],
[ "C", "glass" ]
]
}
================================================
FILE: recipes/craft3x/chest.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "chest",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AOA",
"AAA"
],
"elements": [ [ "A", "OD_WOODEN_PLANK" ] ]
}
================================================
FILE: recipes/craft3x/clay.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "clay",
"stackSize": 4
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "clay_block" ] ]
}
================================================
FILE: recipes/craft3x/clay_block.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "clay_block",
"stackSize": 1
}
],
"pattern": [
"AAO",
"AAO",
"OOO"
],
"elements": [ [ "A", "clay" ] ]
}
================================================
FILE: recipes/craft3x/coal.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "coal",
"stackSize": 9
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "block_coal" ] ]
}
================================================
FILE: recipes/craft3x/coarse_dirt.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "coarse_dirt",
"stackSize": 4
}
],
"pattern": [
"ABO",
"BAO",
"OOO"
],
"elements": [
[ "A", "dirt" ],
[ "B", "gravel" ]
]
}
================================================
FILE: recipes/craft3x/cobblestone_fence.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "cobblestone_fence",
"stackSize": 6
}
],
"pattern": [
"AAA",
"AAA",
"OOO"
],
"elements": [ [ "A", "cobblestone" ] ]
}
================================================
FILE: recipes/craft3x/cobblestone_mossy.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "cobblestone_mossy",
"stackSize": 1
}
],
"pattern": [
"ABO",
"OOO",
"OOO"
],
"elements": [
[ "A", "cobblestone" ],
[ "B", "vine" ]
]
}
================================================
FILE: recipes/craft3x/cobweb.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "cobweb",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AAA",
"AAA"
],
"elements": [ [ "A", "string" ] ]
}
================================================
FILE: recipes/craft3x/cookie.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "cookie",
"stackSize": 8
}
],
"pattern": [
"ABA",
"OOO",
"OOO"
],
"elements": [
[ "A", "wheat" ],
[ "B", "cocoa_bean" ]
]
}
================================================
FILE: recipes/craft3x/copper_axe.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "copper_axe",
"stackSize": 1
}
],
"pattern": [
"AAO",
"ABO",
"OBO"
],
"elements": [
[ "A", "copper_ingot" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/copper_chestplate.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "copper_chestplate",
"stackSize": 1
}
],
"pattern": [
"AOA",
"AAA",
"AAA"
],
"elements": [ [ "A", "copper_ingot" ] ]
}
================================================
FILE: recipes/craft3x/copper_helmet.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "copper_helmet",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AOA",
"OOO"
],
"elements": [ [ "A", "copper_ingot" ] ]
}
================================================
FILE: recipes/craft3x/copper_leggings.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "copper_leggings",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AOA",
"AOA"
],
"elements": [ [ "A", "copper_ingot" ] ]
}
================================================
FILE: recipes/craft3x/copper_pickaxe.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "copper_pickaxe",
"stackSize": 1
}
],
"pattern": [
"AAA",
"OBO",
"OBO"
],
"elements": [
[ "A", "copper_ingot" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/copper_sword.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "copper_sword",
"stackSize": 1
}
],
"pattern": [
"AOO",
"AOO",
"BOO"
],
"elements": [
[ "A", "copper_ingot" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/crafting_table.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "crafting_table",
"stackSize": 1
}
],
"pattern": [
"AAO",
"AAO",
"OOO"
],
"elements": [ [ "A", "OD_WOODEN_PLANK" ] ]
}
================================================
FILE: recipes/craft3x/cross_bow.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "cross_bow",
"stackSize": 1
}
],
"pattern": [
"BAB",
"CAC",
"OBO"
],
"elements": [
[ "A", "OD_IRON_INGOT" ],
[ "B", "stick" ],
[ "C", "string" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/dark_oak_plank.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "dark_oak_plank",
"stackSize": 4
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "wood_dark_oak" ] ]
}
================================================
FILE: recipes/craft3x/dark_shadow_ingot.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "dark_shadow_ingot",
"stackSize": 1
}
],
"pattern": [
"ABC",
"OOO",
"OOO"
],
"elements": [
[ "A", "dark_shadow_part" ],
[ "B", "gold_ingot" ],
[ "C", "silver_ingot" ]
]
}
================================================
FILE: recipes/craft3x/daylight_sensor.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "daylight_sensor",
"stackSize": 1
}
],
"pattern": [
"AAA",
"BBB",
"CCC"
],
"elements": [
[ "A", "glass" ],
[ "B", "quartz" ]
],
"group3": "OD_WOODEN_PLANK"
}
================================================
FILE: recipes/craft3x/daylight_sensor_inverted.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "daylight_sensor_inverted",
"stackSize": 1
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "daylight_sensor" ] ]
}
================================================
FILE: recipes/craft3x/diamond.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "diamond",
"stackSize": 9
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "block_diamond" ] ]
}
================================================
FILE: recipes/craft3x/diamond_axe.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "diamond_axe",
"stackSize": 1
}
],
"pattern": [
"AAO",
"ABO",
"OBO"
],
"elements": [
[ "A", "diamond" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/diamond_chestplate.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "diamond_chestplate",
"stackSize": 1
}
],
"pattern": [
"AOA",
"AAA",
"AAA"
],
"elements": [ [ "A", "diamond" ] ]
}
================================================
FILE: recipes/craft3x/diamond_helmet.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "diamond_helmet",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AOA",
"OOO"
],
"elements": [ [ "A", "diamond" ] ]
}
================================================
FILE: recipes/craft3x/diamond_ingot.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "diamond_ingot",
"stackSize": 1
}
],
"pattern": [
"ABC",
"DEO",
"OOO"
],
"elements": [
[ "A", "diamond" ],
[ "B", "blue_crystal" ],
[ "C", "red_crystal" ],
[ "D", "yellow_crystal" ],
[ "E", "white_crystal" ]
]
}
================================================
FILE: recipes/craft3x/diamond_leggings.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "diamond_leggings",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AOA",
"AOA"
],
"elements": [ [ "A", "diamond" ] ]
}
================================================
FILE: recipes/craft3x/diamond_pickaxe.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "diamond_pickaxe",
"stackSize": 1
}
],
"pattern": [
"AAA",
"OBO",
"OBO"
],
"elements": [
[ "A", "diamond" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/diamond_sword.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "diamond_sword",
"stackSize": 1
}
],
"pattern": [
"AOO",
"AOO",
"BOO"
],
"elements": [
[ "A", "diamond" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/diorite.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "diorite",
"stackSize": 2
}
],
"pattern": [
"ABO",
"BAO",
"OOO"
],
"elements": [
[ "A", "cobblestone" ],
[ "B", "quartz" ]
]
}
================================================
FILE: recipes/craft3x/diorite_polished.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "diorite_polished",
"stackSize": 4
}
],
"pattern": [
"AAO",
"AAO",
"OOO"
],
"elements": [ [ "A", "diorite" ] ]
}
================================================
FILE: recipes/craft3x/dirt.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "dirt",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "flesh_dirt" ],
[ "B", "bone_meal" ]
]
}
================================================
FILE: recipes/craft3x/door_nether.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "door_nether",
"stackSize": 3
}
],
"pattern": [
"AAO",
"AAO",
"AAO"
],
"elements": [ [ "A", "nether_brick" ] ]
}
================================================
FILE: recipes/craft3x/dried_kelp.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "dried_kelp",
"stackSize": 9
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "dried_kelp_block" ] ]
}
================================================
FILE: recipes/craft3x/dried_kelp_block.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "dried_kelp_block",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AAA",
"AAA"
],
"elements": [ [ "A", "dried_kelp" ] ]
}
================================================
FILE: recipes/craft3x/dungeon_eater.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "dungeon_eater",
"stackSize": 1
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [ [ "A", "evil_part" ], [ "B", "blood" ] ]
}
================================================
FILE: recipes/craft3x/dye_black.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "dye_black",
"stackSize": 1
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "ink_sac" ] ]
}
================================================
FILE: recipes/craft3x/dye_blue.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "dye_blue",
"stackSize": 1
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "lapis_lazuli" ] ]
}
================================================
FILE: recipes/craft3x/dye_brown.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "dye_brown",
"stackSize": 1
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "cocoa_bean" ] ]
}
================================================
FILE: recipes/craft3x/dye_cyan.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "dye_cyan",
"stackSize": 2
}
],
"pattern": [
"ABO",
"OOO",
"OOO"
],
"elements": [
[ "A", "dye_blue" ],
[ "B", "dye_green" ]
]
}
================================================
FILE: recipes/craft3x/dye_cyan_2.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "dye_cyan",
"stackSize": 2
}
],
"pattern": [
"ABO",
"OOO",
"OOO"
],
"elements": [
[ "A", "lapis_lazuli" ],
[ "B", "dye_green" ]
]
}
================================================
FILE: recipes/craft3x/dye_gray.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "dye_gray",
"stackSize": 2
}
],
"pattern": [
"ABO",
"OOO",
"OOO"
],
"elements": [
[ "A", "dye_black" ],
[ "B", "dye_white" ]
]
}
================================================
FILE: recipes/craft3x/dye_light_blue.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "dye_light_blue",
"stackSize": 1
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "blue_orchid" ] ]
}
================================================
FILE: recipes/craft3x/dye_light_blue_2.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "dye_light_blue",
"stackSize": 2
}
],
"pattern": [
"ABO",
"OOO",
"OOO"
],
"elements": [
[ "A", "dye_blue" ],
[ "B", "dye_white" ]
]
}
================================================
FILE: recipes/craft3x/dye_light_blue_3.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "dye_light_blue",
"stackSize": 2
}
],
"pattern": [
"ABO",
"OOO",
"OOO"
],
"elements": [
[ "A", "lapis_lazuli" ],
[ "B", "dye_white" ]
]
}
================================================
FILE: recipes/craft3x/dye_light_gray.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "dye_light_gray",
"stackSize": 1
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "azure_bluet" ] ]
}
================================================
FILE: recipes/craft3x/dye_light_gray_2.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "dye_light_gray",
"stackSize": 1
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "white_tulip" ] ]
}
================================================
FILE: recipes/craft3x/dye_light_gray_3.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "dye_light_gray",
"stackSize": 3
}
],
"pattern": [
"ABB",
"OOO",
"OOO"
],
"elements": [
[ "A", "dye_black" ],
[ "B", "dye_white" ]
]
}
================================================
FILE: recipes/craft3x/dye_light_gray_4.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "dye_light_gray",
"stackSize": 2
}
],
"pattern": [
"ABO",
"OOO",
"OOO"
],
"elements": [
[ "A", "dye_gray" ],
[ "B", "dye_white" ]
]
}
================================================
FILE: recipes/craft3x/dye_lime.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "dye_lime",
"stackSize": 2
}
],
"pattern": [
"ABO",
"OOO",
"OOO"
],
"elements": [
[ "A", "dye_green" ],
[ "B", "dye_white" ]
]
}
================================================
FILE: recipes/craft3x/dye_lime_2.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "dye_lime",
"stackSize": 2
}
],
"pattern": [
"ABO",
"OOO",
"OOO"
],
"elements": [
[ "A", "dye_green" ],
[ "B", "bone_meal" ]
]
}
================================================
FILE: recipes/craft3x/dye_magenta.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "dye_magenta",
"stackSize": 1
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "allium" ] ]
}
================================================
FILE: recipes/craft3x/dye_magenta_2.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "dye_magenta",
"stackSize": 2
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "lilac" ] ]
}
================================================
FILE: recipes/craft3x/dye_magenta_3.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "dye_magenta",
"stackSize": 2
}
],
"pattern": [
"ABO",
"OOO",
"OOO"
],
"elements": [
[ "A", "dye_purple" ],
[ "B", "dye_pink" ]
]
}
================================================
FILE: recipes/craft3x/dye_magenta_4.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "dye_magenta",
"stackSize": 3
}
],
"pattern": [
"ABC",
"OOO",
"OOO"
],
"elements": [
[ "A", "dye_blue" ],
[ "B", "dye_red" ],
[ "C", "dye_pink" ]
]
}
================================================
FILE: recipes/craft3x/dye_magenta_5.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "dye_magenta",
"stackSize": 4
}
],
"pattern": [
"ABB",
"COO",
"OOO"
],
"elements": [
[ "A", "dye_blue" ],
[ "B", "dye_red" ],
[ "C", "dye_white" ]
]
}
================================================
FILE: recipes/craft3x/dye_orange.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "dye_orange",
"stackSize": 1
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "orange_tulip" ] ]
}
================================================
FILE: recipes/craft3x/dye_orange_2.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "dye_orange",
"stackSize": 2
}
],
"pattern": [
"ABO",
"OOO",
"OOO"
],
"elements": [
[ "A", "dye_red" ],
[ "B", "dye_yellow" ]
]
}
================================================
FILE: recipes/craft3x/dye_pink.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "dye_pink",
"stackSize": 1
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "pink_tulip" ] ]
}
================================================
FILE: recipes/craft3x/dye_pink_2.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "dye_pink",
"stackSize": 2
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "peony" ] ]
}
================================================
FILE: recipes/craft3x/dye_pink_3.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "dye_pink",
"stackSize": 2
}
],
"pattern": [
"ABO",
"OOO",
"OOO"
],
"elements": [
[ "A", "dye_red" ],
[ "B", "dye_white" ]
]
}
================================================
FILE: recipes/craft3x/dye_pink_4.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "dye_pink",
"stackSize": 2
}
],
"pattern": [
"ABO",
"OOO",
"OOO"
],
"elements": [
[ "A", "dye_red" ],
[ "B", "bone_meal" ]
]
}
================================================
FILE: recipes/craft3x/dye_purple.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "dye_purple",
"stackSize": 2
}
],
"pattern": [
"ABO",
"OOO",
"OOO"
],
"elements": [
[ "A", "dye_blue" ],
[ "B", "dye_red" ]
]
}
================================================
FILE: recipes/craft3x/dye_purple_2.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "dye_purple",
"stackSize": 2
}
],
"pattern": [
"ABO",
"OOO",
"OOO"
],
"elements": [
[ "A", "lapis_lazuli" ],
[ "B", "dye_red" ]
]
}
================================================
FILE: recipes/craft3x/dye_red.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "dye_red",
"stackSize": 1
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "poppy" ] ]
}
================================================
FILE: recipes/craft3x/dye_red_2.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "dye_red",
"stackSize": 1
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "red_tulip" ] ]
}
================================================
FILE: recipes/craft3x/dye_red_3.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "dye_red",
"stackSize": 2
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "rose_bush" ] ]
}
================================================
FILE: recipes/craft3x/dye_white.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "dye_white",
"stackSize": 1
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "bone_meal" ] ]
}
================================================
FILE: recipes/craft3x/dye_yellow.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "dye_yellow",
"stackSize": 1
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "dandelion" ] ]
}
================================================
FILE: recipes/craft3x/dye_yellow_2.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "dye_yellow",
"stackSize": 2
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "sunflower" ] ]
}
================================================
FILE: recipes/craft3x/emerald.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "emerald",
"stackSize": 9
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "block_emerald" ] ]
}
================================================
FILE: recipes/craft3x/enchantment_table.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "enchantment_table",
"stackSize": 1
}
],
"pattern": [
"OAO",
"BCB",
"CCC"
],
"elements": [
[ "A", "book" ],
[ "B", "diamond" ],
[ "C", "obsidian" ]
]
}
================================================
FILE: recipes/craft3x/end_rod.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "end_rod",
"stackSize": 4
}
],
"pattern": [
"AOO",
"BOO",
"OOO"
],
"elements": [
[ "A", "blaze_rod" ],
[ "B", "popped_chorus_fruits" ]
]
}
================================================
FILE: recipes/craft3x/end_stone_brick.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "end_stone_brick",
"stackSize": 4
}
],
"pattern": [
"AAO",
"AAO",
"OOO"
],
"elements": [ [ "A", "end_stone" ] ]
}
================================================
FILE: recipes/craft3x/ender_chest.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "ender_chest",
"stackSize": 1
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "obsidian" ],
[ "B", "ender_eye" ]
]
}
================================================
FILE: recipes/craft3x/ender_eye.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "ender_eye",
"stackSize": 1
}
],
"pattern": [
"ABO",
"OOO",
"OOO"
],
"elements": [
[ "A", "blaze_powder" ],
[ "B", "ender_pearl" ]
]
}
================================================
FILE: recipes/craft3x/ender_mirror.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "ender_mirror",
"stackSize": 1
}
],
"pattern": [
"OAO",
"ABA",
"OAO"
],
"elements": [
[ "A", "glass" ],
[ "B", "ender_pearl" ]
]
}
================================================
FILE: recipes/craft3x/farmland.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "farmland",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "flesh_gut" ],
[ "B", "bone_meal" ]
]
}
================================================
FILE: recipes/craft3x/farmland_2.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "farmland",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "tainted_dirt" ],
[ "B", "bone_meal" ]
]
}
================================================
FILE: recipes/craft3x/fence_acacia.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "fence_acacia",
"stackSize": 3
}
],
"pattern": [
"ABA",
"ABA",
"OOO"
],
"elements": [
[ "A", "acacia_plank" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/fence_birch.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "fence_birch",
"stackSize": 3
}
],
"pattern": [
"ABA",
"ABA",
"OOO"
],
"elements": [
[ "A", "birch_plank" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/fence_dark_oak.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "fence_dark_oak",
"stackSize": 3
}
],
"pattern": [
"ABA",
"ABA",
"OOO"
],
"elements": [
[ "A", "dark_oak_plank" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/fence_jungle.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "fence_jungle",
"stackSize": 3
}
],
"pattern": [
"ABA",
"ABA",
"OOO"
],
"elements": [
[ "A", "jungle_plank" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/fence_nether.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "fence_nether",
"stackSize": 6
}
],
"pattern": [
"AAA",
"AAA",
"OOO"
],
"elements": [ [ "A", "nether_brick_block" ] ]
}
================================================
FILE: recipes/craft3x/fence_oak.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "fence_oak",
"stackSize": 3
}
],
"pattern": [
"ABA",
"ABA",
"OOO"
],
"elements": [
[ "A", "oak_plank" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/fence_palm.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "fence_palm",
"stackSize": 3
}
],
"pattern": [
"ABA",
"ABA",
"OOO"
],
"elements": [
[ "A", "palm_plank" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/fence_spruce.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "fence_spruce",
"stackSize": 3
}
],
"pattern": [
"ABA",
"ABA",
"OOO"
],
"elements": [
[ "A", "spruce_plank" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/fence_tainted.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "fence_tainted",
"stackSize": 3
}
],
"pattern": [
"ABA",
"ABA",
"OOO"
],
"elements": [
[ "A", "tainted_plank" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/fence_volcano.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "fence_volcano",
"stackSize": 3
}
],
"pattern": [
"ABA",
"ABA",
"OOO"
],
"elements": [
[ "A", "volcano_plank" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/fermented_spider_eye.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "fermented_spider_eye",
"stackSize": 1
}
],
"pattern": [
"ABC",
"OOO",
"OOO"
],
"elements": [
[ "A", "spider_eye" ],
[ "B", "brown_mushroom" ],
[ "C", "suger" ]
]
}
================================================
FILE: recipes/craft3x/fire_boomerang.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "fire_boomerang",
"stackSize": 1
}
],
"pattern": [
"OAB",
"AOO",
"OAB"
],
"elements": [
[ "A", "copper_ingot" ],
[ "B", "blaze_rod" ]
]
}
================================================
FILE: recipes/craft3x/fire_boomerang_2.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "fire_boomerang",
"stackSize": 1
}
],
"pattern": [
"OAB",
"AOO",
"OAB"
],
"elements": [
[ "A", "tin_ingot" ],
[ "B", "blaze_rod" ]
]
}
================================================
FILE: recipes/craft3x/fire_bullet.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "fire_bullet",
"stackSize": 16
}
],
"pattern": [
"ABO",
"OOO",
"OOO"
],
"elements": [
[ "A", "fire_charge" ],
[ "B", "copper_ingot" ]
]
}
================================================
FILE: recipes/craft3x/fire_bullet_2.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "fire_bullet",
"stackSize": 16
}
],
"pattern": [
"ABO",
"OOO",
"OOO"
],
"elements": [
[ "A", "fire_charge" ],
[ "B", "tin_ingot" ]
]
}
================================================
FILE: recipes/craft3x/fire_charge.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "fire_charge",
"stackSize": 3
}
],
"pattern": [
"ABC",
"OOO",
"OOO"
],
"elements": [
[ "A", "blaze_powder" ],
[ "B", "coal" ],
[ "C", "gunpowder" ]
]
}
================================================
FILE: recipes/craft3x/fire_charge_2.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "fire_charge",
"stackSize": 3
}
],
"pattern": [
"ABC",
"OOO",
"OOO"
],
"elements": [
[ "A", "blaze_powder" ],
[ "B", "charcoal" ],
[ "C", "gunpowder" ]
]
}
================================================
FILE: recipes/craft3x/fire_lamp.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "fire_lamp",
"stackSize": 1
}
],
"pattern": [
"OAO",
"BAB",
"CCC"
],
"elements": [
[ "A", "OD_IRON_INGOT" ],
[ "B", "torch" ]
],
"group3": "OD_WOODEN_PLANK"
}
================================================
FILE: recipes/craft3x/flesh_chestplate.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "flesh_chestplate",
"stackSize": 1
}
],
"pattern": [
"AOA",
"AAA",
"AAA"
],
"elements": [ [ "A", "flesh_ingot" ] ]
}
================================================
FILE: recipes/craft3x/flesh_helmet.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "flesh_helmet",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AOA",
"OOO"
],
"elements": [ [ "A", "flesh_ingot" ] ]
}
================================================
FILE: recipes/craft3x/flesh_ingot.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "flesh_ingot",
"stackSize": 1
}
],
"pattern": [
"ABC",
"COO",
"OOO"
],
"elements": [
[ "A", "gold_ingot" ],
[ "B", "silver_ingot" ],
[ "B", "flesh_part" ]
]
}
================================================
FILE: recipes/craft3x/flesh_leggings.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "flesh_leggings",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AOA",
"AOA"
],
"elements": [ [ "A", "flesh_ingot" ] ]
}
================================================
FILE: recipes/craft3x/flesh_machine_part.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "flesh_machine_part",
"stackSize": 1
}
],
"pattern": [
"ABO",
"OOO",
"OOO"
],
"elements": [
[ "A", "machine_part" ],
[ "B", "magic_cell" ]
]
}
================================================
FILE: recipes/craft3x/flower_pot.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "flower_pot",
"stackSize": 1
}
],
"pattern": [
"AOA",
"OAO",
"OOO"
],
"elements": [ [ "A", "red_brick" ] ]
}
================================================
FILE: recipes/craft3x/flower_pot_large.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "flower_pot_large",
"stackSize": 1
}
],
"pattern": [
"AOA",
"AOA",
"OAO"
],
"elements": [ [ "A", "red_brick" ] ]
}
================================================
FILE: recipes/craft3x/furnace.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "furnace",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AOA",
"AAA"
],
"elements": [ [ "A", "cobblestone" ] ]
}
================================================
FILE: recipes/craft3x/ghost.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "ghost",
"stackSize": 1
}
],
"pattern": [
"AAA",
"BAB",
"AAA"
],
"elements": [ [ "A", "ghost_crystal"], [ "B", "ghost_element" ] ]
}
================================================
FILE: recipes/craft3x/glass_bottle.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "glass_bottle",
"stackSize": 6
}
],
"pattern": [
"AOA",
"OAO",
"OOO"
],
"elements": [ [ "A", "glass" ] ]
}
================================================
FILE: recipes/craft3x/glistering_melon_slice.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "glistering_melon_slice",
"stackSize": 1
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "gold_nugget" ],
[ "B", "melon_slice" ]
]
}
================================================
FILE: recipes/craft3x/glow_ball.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "glow_ball",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "glowstone_dust" ],
[ "B", "cobblestone" ]
]
}
================================================
FILE: recipes/craft3x/glow_bomb.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "glow_bomb",
"stackSize": 2
}
],
"pattern": [
"OBO",
"BAB",
"OBO"
],
"elements": [
[ "A", "bomb" ],
[ "B", "glowstone_dust" ]
]
}
================================================
FILE: recipes/craft3x/glowing_mushroom.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "glowing_mushroom",
"stackSize": 1
}
],
"pattern": [
"OAO",
"ABA",
"OAO"
],
"elements": [
[ "A", "glowstone_dust" ],
[ "B", "red_mushroom" ]
]
}
================================================
FILE: recipes/craft3x/glowing_mushroom_2.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "glowing_mushroom",
"stackSize": 1
}
],
"pattern": [
"OAO",
"ABA",
"OAO"
],
"elements": [
[ "A", "glowstone_dust" ],
[ "B", "brown_mushroom" ]
]
}
================================================
FILE: recipes/craft3x/glowstone.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "glowstone",
"stackSize": 1
}
],
"pattern": [
"AAO",
"AAO",
"OOO"
],
"elements": [ [ "A", "glowstone_dust" ] ]
}
================================================
FILE: recipes/craft3x/gold_ingot.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "gold_ingot",
"stackSize": 9
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "block_gold" ] ]
}
================================================
FILE: recipes/craft3x/gold_ingot_2.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "gold_ingot",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AAA",
"AAA"
],
"elements": [ [ "A", "gold_nugget" ] ]
}
================================================
FILE: recipes/craft3x/gold_nugget.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "gold_nugget",
"stackSize": 9
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "gold_ingot" ] ]
}
================================================
FILE: recipes/craft3x/golden_apple.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "golden_apple",
"stackSize": 1
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "gold_ingot" ],
[ "B", "apple" ]
]
}
================================================
FILE: recipes/craft3x/golden_axe.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "golden_axe",
"stackSize": 1
}
],
"pattern": [
"AAO",
"ABO",
"OBO"
],
"elements": [
[ "A", "gold_ingot" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/golden_carrot.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "golden_carrot",
"stackSize": 1
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "gold_nugget" ],
[ "B", "carrot" ]
]
}
================================================
FILE: recipes/craft3x/golden_chestplate.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "golden_chestplate",
"stackSize": 1
}
],
"pattern": [
"AOA",
"AAA",
"AAA"
],
"elements": [ [ "A", "gold_ingot" ] ]
}
================================================
FILE: recipes/craft3x/golden_helmet.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "golden_helmet",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AOA",
"OOO"
],
"elements": [ [ "A", "gold_ingot" ] ]
}
================================================
FILE: recipes/craft3x/golden_leggings.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "golden_leggings",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AOA",
"AOA"
],
"elements": [ [ "A", "gold_ingot" ] ]
}
================================================
FILE: recipes/craft3x/golden_pickaxe.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "golden_pickaxe",
"stackSize": 1
}
],
"pattern": [
"AAA",
"OBO",
"OBO"
],
"elements": [
[ "A", "gold_ingot" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/golden_pressure_plate.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "golden_pressure_plate",
"stackSize": 1
}
],
"pattern": [
"AAO",
"OOO",
"OOO"
],
"elements": [ [ "A", "gold_ingot" ] ]
}
================================================
FILE: recipes/craft3x/golden_sword.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "golden_sword",
"stackSize": 1
}
],
"pattern": [
"AOO",
"AOO",
"BOO"
],
"elements": [
[ "A", "gold_ingot" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/granite.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "granite",
"stackSize": 1
}
],
"pattern": [
"ABO",
"OOO",
"OOO"
],
"elements": [
[ "A", "diorite" ],
[ "B", "quartz" ]
]
}
================================================
FILE: recipes/craft3x/granite_polished.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "granite_polished",
"stackSize": 4
}
],
"pattern": [
"AAO",
"AAO",
"OOO"
],
"elements": [ [ "A", "granite" ] ]
}
================================================
FILE: recipes/craft3x/grass_axe.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "grass_axe",
"stackSize": 1
}
],
"pattern": [
"AAO",
"ABO",
"OBO"
],
"elements": [
[ "A", "grass" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/grass_pickaxe.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "grass_pickaxe",
"stackSize": 1
}
],
"pattern": [
"AAA",
"OBO",
"OBO"
],
"elements": [
[ "A", "grass" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/grass_sword.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "grass_sword",
"stackSize": 1
}
],
"pattern": [
"AOO",
"AOO",
"BOO"
],
"elements": [
[ "A", "grass" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/green_torch.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "green_torch",
"stackSize": 1
}
],
"pattern": [
"ABO",
"OOO",
"OOO"
],
"elements": [
[ "A", "torch" ],
[ "B", "dye_green" ]
],
"importantElements": [ "B" ]
}
================================================
FILE: recipes/craft3x/green_wire.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "green_wire",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "red_wire" ],
[ "B", "dye_green" ]
]
}
================================================
FILE: recipes/craft3x/grenade.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "grenade",
"stackSize": 3
}
],
"pattern": [
"OBO",
"BAB",
"OBO"
],
"elements": [
[ "A", "bomb" ],
[ "B", "sand" ]
]
}
================================================
FILE: recipes/craft3x/grenade_2.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "grenade",
"stackSize": 3
}
],
"pattern": [
"OBO",
"BAB",
"OBO"
],
"elements": [
[ "A", "bomb" ],
[ "B", "red_sand" ]
]
}
================================================
FILE: recipes/craft3x/hay_bale.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "hay_bale",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AAA",
"AAA"
],
"elements": [ [ "A", "wheat" ] ]
}
================================================
FILE: recipes/craft3x/ice_arrow.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "ice_arrow",
"stackSize": 4
}
],
"pattern": [
"OAO",
"ABA",
"OAO"
],
"elements": [
[ "A", "wooden_arrow" ],
[ "B", "ice_packed" ]
]
}
================================================
FILE: recipes/craft3x/ice_bow.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "ice_bow",
"stackSize": 1
}
],
"pattern": [
"BDC",
"AOC",
"BDC"
],
"elements": [
[ "A", "diamond" ],
[ "B", "blue_ice" ],
[ "C", "string" ],
[ "D", "OD_IRON_INGOT" ]
]
}
================================================
FILE: recipes/craft3x/ice_brick.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "ice_brick",
"stackSize": 4
}
],
"pattern": [
"AAO",
"AAO",
"OOO"
],
"elements": [ [ "A", "ice_cobblestone" ] ]
}
================================================
FILE: recipes/craft3x/ice_element_ball.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "ice_element_ball",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AAA",
"AAA"
],
"elements": [ [ "A", "ice_element" ] ]
}
================================================
FILE: recipes/craft3x/ice_packed.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "ice_packed",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AAA",
"AAA"
],
"elements": [ [ "A", "ice" ] ]
}
================================================
FILE: recipes/craft3x/ice_staff.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "ice_staff",
"stackSize": 1
}
],
"pattern": [
"OAB",
"OCA",
"COO"
],
"elements": [
[ "A", "blue_ice" ],
[ "B", "diamond" ],
[ "C", "OD_IRON_INGOT" ]
]
}
================================================
FILE: recipes/craft3x/iron_axe.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "iron_axe",
"stackSize": 1
}
],
"pattern": [
"AAO",
"ABO",
"OBO"
],
"elements": [
[ "A", "OD_IRON_INGOT" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/iron_bar.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "iron_bar",
"stackSize": 32
}
],
"pattern": [
"AAA",
"AAA",
"OOO"
],
"elements": [ [ "A", "OD_IRON_INGOT" ] ]
}
================================================
FILE: recipes/craft3x/iron_bullet.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "iron_bullet",
"stackSize": 16
}
],
"pattern": [
"ABO",
"OOO",
"OOO"
],
"elements": [
[ "A", "fire_charge" ],
[ "B", "OD_IRON_INGOT" ]
]
}
================================================
FILE: recipes/craft3x/iron_bullet_2.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "iron_bullet",
"stackSize": 32
}
],
"pattern": [
"ABO",
"OOO",
"OOO"
],
"elements": [
[ "A", "fire_charge" ],
[ "B", "steel_ingot" ]
]
}
================================================
FILE: recipes/craft3x/iron_chestplate.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "iron_chestplate",
"stackSize": 1
}
],
"pattern": [
"AOA",
"AAA",
"AAA"
],
"elements": [ [ "A", "OD_IRON_INGOT" ] ]
}
================================================
FILE: recipes/craft3x/iron_door.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "iron_door",
"stackSize": 3
}
],
"pattern": [
"AAO",
"AAO",
"AAO"
],
"elements": [ [ "A", "OD_IRON_INGOT" ] ]
}
================================================
FILE: recipes/craft3x/iron_helmet.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "iron_helmet",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AOA",
"OOO"
],
"elements": [ [ "A", "OD_IRON_INGOT" ] ]
}
================================================
FILE: recipes/craft3x/iron_ingot.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "iron_ingot",
"stackSize": 9
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "block_iron" ] ]
}
================================================
FILE: recipes/craft3x/iron_ingot_2.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "iron_ingot",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AAA",
"AAA"
],
"elements": [ [ "A", "iron_nugget" ] ]
}
================================================
FILE: recipes/craft3x/iron_leggings.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "iron_leggings",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AOA",
"AOA"
],
"elements": [ [ "A", "OD_IRON_INGOT" ] ]
}
================================================
FILE: recipes/craft3x/iron_nugget.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "iron_nugget",
"stackSize": 9
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "OD_IRON_INGOT" ] ]
}
================================================
FILE: recipes/craft3x/iron_pickaxe.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "iron_pickaxe",
"stackSize": 1
}
],
"pattern": [
"AAA",
"OBO",
"OBO"
],
"elements": [
[ "A", "OD_IRON_INGOT" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/iron_pressure_plate.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "iron_pressure_plate",
"stackSize": 1
}
],
"pattern": [
"AAO",
"OOO",
"OOO"
],
"elements": [ [ "A", "OD_IRON_INGOT" ] ]
}
================================================
FILE: recipes/craft3x/iron_sword.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "iron_sword",
"stackSize": 1
}
],
"pattern": [
"AOO",
"AOO",
"BOO"
],
"elements": [
[ "A", "OD_IRON_INGOT" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/jack_o_lantern.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "jack_o_lantern",
"stackSize": 1
}
],
"pattern": [
"AOO",
"BOO",
"OOO"
],
"elements": [
[ "A", "pumpkin_carved" ],
[ "B", "torch" ]
]
}
================================================
FILE: recipes/craft3x/jukebox.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "jukebox",
"stackSize": 1
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "OD_WOODEN_PLANK" ],
[ "B", "diamond" ]
]
}
================================================
FILE: recipes/craft3x/jungle_plank.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "jungle_plank",
"stackSize": 4
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "wood_jungle" ] ]
}
================================================
FILE: recipes/craft3x/knight_chestplate.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "knight_chestplate",
"stackSize": 1
}
],
"pattern": [
"AOA",
"AAA",
"AAA"
],
"elements": [ [ "A", "knight_ingot" ] ]
}
================================================
FILE: recipes/craft3x/knight_helmet.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "knight_helmet",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AOA",
"OOO"
],
"elements": [ [ "A", "knight_ingot" ] ]
}
================================================
FILE: recipes/craft3x/knight_leggings.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "knight_leggings",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AOA",
"AOA"
],
"elements": [ [ "A", "knight_ingot" ] ]
}
================================================
FILE: recipes/craft3x/lantern.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "lantern",
"stackSize": 1
}
],
"pattern": [
"BBB",
"BAB",
"BBB"
],
"elements": [
[ "A", "torch" ],
[ "B", "iron_nugget" ]
]
}
================================================
FILE: recipes/craft3x/lapis_lazuli.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "lapis_lazuli",
"stackSize": 9
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "block_lapis" ] ]
}
================================================
FILE: recipes/craft3x/lava_chestplate.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "lava_chestplate",
"stackSize": 1
}
],
"pattern": [
"AOA",
"AAA",
"AAA"
],
"elements": [ [ "A", "magma_gold_ingot" ] ]
}
================================================
FILE: recipes/craft3x/lava_helmet.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "lava_helmet",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AOA",
"OOO"
],
"elements": [ [ "A", "magma_gold_ingot" ] ]
}
================================================
FILE: recipes/craft3x/lava_leggings.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "lava_leggings",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AOA",
"AOA"
],
"elements": [ [ "A", "magma_gold_ingot" ] ]
}
================================================
FILE: recipes/craft3x/lead_axe.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "lead_axe",
"stackSize": 1
}
],
"pattern": [
"AAO",
"ABO",
"OBO"
],
"elements": [
[ "A", "lead_ingot" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/lead_chestplate.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "lead_chestplate",
"stackSize": 1
}
],
"pattern": [
"AOA",
"AAA",
"AAA"
],
"elements": [ [ "A", "lead_ingot" ] ]
}
================================================
FILE: recipes/craft3x/lead_helmet.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "lead_helmet",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AOA",
"OOO"
],
"elements": [ [ "A", "lead_ingot" ] ]
}
================================================
FILE: recipes/craft3x/lead_leggings.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "lead_leggings",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AOA",
"AOA"
],
"elements": [ [ "A", "lead_ingot" ] ]
}
================================================
FILE: recipes/craft3x/lead_pickaxe.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "lead_pickaxe",
"stackSize": 1
}
],
"pattern": [
"AAA",
"OBO",
"OBO"
],
"elements": [
[ "A", "lead_ingot" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/lead_sword.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "lead_sword",
"stackSize": 1
}
],
"pattern": [
"AOO",
"AOO",
"BOO"
],
"elements": [
[ "A", "lead_ingot" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/leather.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "leather",
"stackSize": 1
}
],
"pattern": [
"AAO",
"AAO",
"OOO"
],
"elements": [ [ "A", "rabbit_hide" ] ]
}
================================================
FILE: recipes/craft3x/leather_chestplate.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "leather_chestplate",
"stackSize": 1
}
],
"pattern": [
"AOA",
"AAA",
"AAA"
],
"elements": [ [ "A", "leather" ] ]
}
================================================
FILE: recipes/craft3x/leather_helmet.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "leather_helmet",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AOA",
"OOO"
],
"elements": [ [ "A", "leather" ] ]
}
================================================
FILE: recipes/craft3x/leather_leggings.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "leather_leggings",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AOA",
"AOA"
],
"elements": [ [ "A", "leather" ] ]
}
================================================
FILE: recipes/craft3x/lever.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "lever",
"stackSize": 1
}
],
"pattern": [
"AOO",
"BOO",
"OOO"
],
"elements": [
[ "A", "stick" ],
[ "B", "cobblestone" ]
],
"importantElements": [ "B" ]
}
================================================
FILE: recipes/craft3x/lighter.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "lighter",
"stackSize": 1
}
],
"pattern": [
"ABO",
"OOO",
"OOO"
],
"elements": [
[ "A", "OD_IRON_INGOT" ],
[ "B", "flint" ]
]
}
================================================
FILE: recipes/craft3x/lighting_arrow.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "lighting_arrow",
"stackSize": 1
}
],
"pattern": [
"ABO",
"OOO",
"OOO"
],
"elements": [
[ "A", "wooden_arrow" ],
[ "B", "glowstone_dust" ]
]
}
================================================
FILE: recipes/craft3x/lighting_bow.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "lighting_bow",
"stackSize": 1
}
],
"pattern": [
"BDC",
"AOC",
"BDC"
],
"elements": [
[ "A", "gold_ingot" ],
[ "B", "glowstone_dust" ],
[ "C", "string" ],
[ "D", "blaze_rod" ]
]
}
================================================
FILE: recipes/craft3x/lighting_staff.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "lighting_staff",
"stackSize": 1
}
],
"pattern": [
"OAB",
"OCA",
"COO"
],
"elements": [
[ "A", "glowstone_dust" ],
[ "B", "silver_ingot" ],
[ "C", "gold_ingot" ]
]
}
================================================
FILE: recipes/craft3x/machine_part.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "machine_part",
"stackSize": 2
}
],
"pattern": [
"AAA",
"OOO",
"OOO"
],
"elements": [
[ "A", "steel_ingot" ]
]
}
================================================
FILE: recipes/craft3x/magic_cell_group.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "magic_cell_group",
"stackSize": 1
}
],
"pattern": [
"AAO",
"AAO",
"OOO"
],
"elements": [ [ "A", "magic_cell" ] ]
}
================================================
FILE: recipes/craft3x/magic_gold_chestplate.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "magic_gold_chestplate",
"stackSize": 1
}
],
"pattern": [
"AOA",
"AAA",
"AAA"
],
"elements": [ [ "A", "red_gold_ingot" ] ]
}
================================================
FILE: recipes/craft3x/magic_gold_helmet.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "magic_gold_helmet",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AOA",
"OOO"
],
"elements": [ [ "A", "red_gold_ingot" ] ]
}
================================================
FILE: recipes/craft3x/magic_gold_leggings.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "magic_gold_leggings",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AOA",
"AOA"
],
"elements": [ [ "A", "red_gold_ingot" ] ]
}
================================================
FILE: recipes/craft3x/magic_silver_chestplate.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "magic_silver_chestplate",
"stackSize": 1
}
],
"pattern": [
"AOA",
"AAA",
"AAA"
],
"elements": [ [ "A", "magic_silver_ingot" ] ]
}
================================================
FILE: recipes/craft3x/magic_silver_helmet.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "magic_silver_helmet",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AOA",
"OOO"
],
"elements": [ [ "A", "magic_silver_ingot" ] ]
}
================================================
FILE: recipes/craft3x/magic_silver_ingot.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "magic_silver_ingot",
"stackSize": 1
}
],
"pattern": [
"OBO",
"BAB",
"OBO"
],
"elements": [ [ "A", "silver_ingot" ], [ "B", "magic_cell" ] ]
}
================================================
FILE: recipes/craft3x/magic_silver_leggings.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "magic_silver_leggings",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AOA",
"AOA"
],
"elements": [ [ "A", "magic_silver_ingot" ] ]
}
================================================
FILE: recipes/craft3x/magma_block.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "magma_block",
"stackSize": 1
}
],
"pattern": [
"AAO",
"AAO",
"OOO"
],
"elements": [ [ "A", "magma_cream" ] ]
}
================================================
FILE: recipes/craft3x/magma_cream.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "magma_cream",
"stackSize": 1
}
],
"pattern": [
"ABO",
"OOO",
"OOO"
],
"elements": [
[ "A", "blaze_powder" ],
[ "B", "slimeball" ]
]
}
================================================
FILE: recipes/craft3x/magma_gold_ingot.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "magma_gold_ingot",
"stackSize": 1
}
],
"pattern": [
"OBO",
"BAB",
"OBO"
],
"elements": [ [ "A", "gold_ingot" ], [ "B", "magma_cream" ] ]
}
================================================
FILE: recipes/craft3x/melon_seed.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "melon_seed",
"stackSize": 1
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "melon_slice" ] ]
}
================================================
FILE: recipes/craft3x/mossy_cobblestone_fence.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "mossy_cobblestone_fence",
"stackSize": 6
}
],
"pattern": [
"AAA",
"AAA",
"OOO"
],
"elements": [ [ "A", "cobblestone_mossy" ] ]
}
================================================
FILE: recipes/craft3x/mushroom_stew.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "mushroom_stew",
"stackSize": 1
}
],
"pattern": [
"ABC",
"OOO",
"OOO"
],
"elements": [
[ "A", "bowl" ],
[ "B", "brown_mushroom" ],
[ "C", "red_mushroom" ]
]
}
================================================
FILE: recipes/craft3x/nether_brick_block.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "nether_brick_block",
"stackSize": 1
}
],
"pattern": [
"AAO",
"AAO",
"OOO"
],
"elements": [ [ "A", "nether_brick" ] ]
}
================================================
FILE: recipes/craft3x/nether_chest.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "nether_chest",
"stackSize": 1
}
],
"pattern": [
"OAO",
"ABA",
"OAO"
],
"elements": [
[ "A", "nether_brick" ],
[ "B", "chest" ]
]
}
================================================
FILE: recipes/craft3x/nether_lamp.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "nether_lamp",
"stackSize": 1
}
],
"pattern": [
"OAO",
"BAB",
"CCC"
],
"elements": [
[ "A", "OD_IRON_INGOT" ],
[ "B", "red_torch" ],
[ "C", "nether_brick" ]
]
}
================================================
FILE: recipes/craft3x/netherite_ingot.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "netherite_ingot",
"stackSize": 1
}
],
"pattern": [
"AAA",
"ABB",
"BBO"
],
"elements": [
[ "A", "netherite_scrap" ],
[ "B", "gold_ingot" ]
]
}
================================================
FILE: recipes/craft3x/netherite_ingot_2.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "netherite_ingot",
"stackSize": 9
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "block_netherite" ] ]
}
================================================
FILE: recipes/craft3x/oak_plank.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "oak_plank",
"stackSize": 4
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "wood_oak" ] ]
}
================================================
FILE: recipes/craft3x/painting_2x2.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "painting_2x2",
"stackSize": 1
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "stick" ],
[ "B", "OD_WOOL" ]
],
"importantElements": [ "B" ]
}
================================================
FILE: recipes/craft3x/painting_2x2_2.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "painting_2x2",
"stackSize": 1
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "painting_8x8" ] ]
}
================================================
FILE: recipes/craft3x/painting_2x4.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "painting_2x4",
"stackSize": 1
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "painting_4x2" ] ]
}
================================================
FILE: recipes/craft3x/painting_4x2.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "painting_4x2",
"stackSize": 1
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "painting_2x2" ] ]
}
================================================
FILE: recipes/craft3x/painting_4x4.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "painting_4x4",
"stackSize": 1
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "painting_2x4" ] ]
}
================================================
FILE: recipes/craft3x/painting_8x4.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "painting_8x4",
"stackSize": 1
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "painting_4x4" ] ]
}
================================================
FILE: recipes/craft3x/painting_8x6.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "painting_8x6",
"stackSize": 1
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "painting_8x4" ] ]
}
================================================
FILE: recipes/craft3x/painting_8x8.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "painting_8x8",
"stackSize": 1
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "painting_8x6" ] ]
}
================================================
FILE: recipes/craft3x/palm_plank.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "palm_plank",
"stackSize": 5
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "wood_palm" ] ]
}
================================================
FILE: recipes/craft3x/paper.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "paper",
"stackSize": 3
}
],
"pattern": [
"AAA",
"OOO",
"OOO"
],
"elements": [ [ "A", "sugar_cane" ] ]
}
================================================
FILE: recipes/craft3x/platform_acacia.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "platform_acacia",
"stackSize": 6
}
],
"pattern": [
"AAA",
"OOO",
"OOO"
],
"elements": [ [ "A", "acacia_plank" ] ]
}
================================================
FILE: recipes/craft3x/platform_birch.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "platform_birch",
"stackSize": 6
}
],
"pattern": [
"AAA",
"OOO",
"OOO"
],
"elements": [ [ "A", "birch_plank" ] ]
}
================================================
FILE: recipes/craft3x/platform_dark_oak.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "platform_dark_oak",
"stackSize": 6
}
],
"pattern": [
"AAA",
"OOO",
"OOO"
],
"elements": [ [ "A", "dark_oak_plank" ] ]
}
================================================
FILE: recipes/craft3x/platform_end_stone.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "platform_end_stone",
"stackSize": 6
}
],
"pattern": [
"AAA",
"OOO",
"OOO"
],
"elements": [ [ "A", "end_stone" ] ]
}
================================================
FILE: recipes/craft3x/platform_jungle.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "platform_jungle",
"stackSize": 6
}
],
"pattern": [
"AAA",
"OOO",
"OOO"
],
"elements": [ [ "A", "jungle_plank" ] ]
}
================================================
FILE: recipes/craft3x/platform_nether_brick.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "platform_nether_brick",
"stackSize": 6
}
],
"pattern": [
"AAA",
"OOO",
"OOO"
],
"elements": [ [ "A", "nether_brick" ] ]
}
================================================
FILE: recipes/craft3x/platform_oak.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "platform_oak",
"stackSize": 6
}
],
"pattern": [
"AAA",
"OOO",
"OOO"
],
"elements": [ [ "A", "oak_plank" ] ]
}
================================================
FILE: recipes/craft3x/platform_palm.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "platform_palm",
"stackSize": 6
}
],
"pattern": [
"AAA",
"OOO",
"OOO"
],
"elements": [ [ "A", "palm_plank" ] ]
}
================================================
FILE: recipes/craft3x/platform_prismarine.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "platform_prismarine",
"stackSize": 6
}
],
"pattern": [
"AAA",
"OOO",
"OOO"
],
"elements": [ [ "A", "prismarine_brick" ] ]
}
================================================
FILE: recipes/craft3x/platform_prismarine_dark.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "platform_prismarine_dark",
"stackSize": 6
}
],
"pattern": [
"AAA",
"OOO",
"OOO"
],
"elements": [ [ "A", "prismarine_dark" ] ]
}
================================================
FILE: recipes/craft3x/platform_purpur.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "platform_purpur",
"stackSize": 6
}
],
"pattern": [
"AAA",
"OOO",
"OOO"
],
"elements": [ [ "A", "purpur_block" ] ]
}
================================================
FILE: recipes/craft3x/platform_quartz.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "platform_quartz",
"stackSize": 6
}
],
"pattern": [
"AAA",
"OOO",
"OOO"
],
"elements": [ [ "A", "block_quartz" ] ]
}
================================================
FILE: recipes/craft3x/platform_red_sand_stone.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "platform_red_sand_stone",
"stackSize": 6
}
],
"pattern": [
"AAA",
"OOO",
"OOO"
],
"elements": [ [ "A", "red_sand_stone" ] ]
}
================================================
FILE: recipes/craft3x/platform_sandstone.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "platform_sandstone",
"stackSize": 6
}
],
"pattern": [
"AAA",
"OOO",
"OOO"
],
"elements": [ [ "A", "sandstone" ] ]
}
================================================
FILE: recipes/craft3x/platform_spruce.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "platform_spruce",
"stackSize": 6
}
],
"pattern": [
"AAA",
"OOO",
"OOO"
],
"elements": [ [ "A", "spruce_plank" ] ]
}
================================================
FILE: recipes/craft3x/platform_stone_brick.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "platform_stone_brick",
"stackSize": 6
}
],
"pattern": [
"AAA",
"OOO",
"OOO"
],
"elements": [ [ "A", "stone_brick" ] ]
}
================================================
FILE: recipes/craft3x/platform_tainted.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "platform_tainted",
"stackSize": 6
}
],
"pattern": [
"AAA",
"OOO",
"OOO"
],
"elements": [ [ "A", "tainted_plank" ] ]
}
================================================
FILE: recipes/craft3x/platform_volcano.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "platform_volcano",
"stackSize": 6
}
],
"pattern": [
"AAA",
"OOO",
"OOO"
],
"elements": [ [ "A", "volcano_plank" ] ]
}
================================================
FILE: recipes/craft3x/poison_mushroom.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "poison_mushroom",
"stackSize": 2
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "large_poison_mushroom" ] ]
}
================================================
FILE: recipes/craft3x/prismarine.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "prismarine",
"stackSize": 1
}
],
"pattern": [
"AAO",
"AAO",
"OOO"
],
"elements": [ [ "A", "prismarine_shard" ] ]
}
================================================
FILE: recipes/craft3x/prismarine_brick.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "prismarine_brick",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AAA",
"AAA"
],
"elements": [ [ "A", "prismarine_shard" ] ]
}
================================================
FILE: recipes/craft3x/prismarine_dark.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "prismarine_dark",
"stackSize": 1
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "prismarine_shard" ],
[ "B", "ink_sac" ]
]
}
================================================
FILE: recipes/craft3x/prismarine_dark_2.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "prismarine_dark",
"stackSize": 1
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "prismarine_shard" ],
[ "B", "dye_black" ]
]
}
================================================
FILE: recipes/craft3x/pumpkin_helmet.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "pumpkin_helmet",
"stackSize": 1
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "pumpkin_carved" ] ]
}
================================================
FILE: recipes/craft3x/pumpkin_pie.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "pumpkin_pie",
"stackSize": 2
}
],
"pattern": [
"ABC",
"OOO",
"OOO"
],
"elements": [
[ "A", "pumpkin" ],
[ "B", "suger" ],
[ "C", "egg" ]
]
}
================================================
FILE: recipes/craft3x/pumpkin_seed.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "pumpkin_seed",
"stackSize": 4
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "pumpkin" ] ]
}
================================================
FILE: recipes/craft3x/purpur_block.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "purpur_block",
"stackSize": 4
}
],
"pattern": [
"AAO",
"AAO",
"OOO"
],
"elements": [ [ "A", "popped_chorus_fruits" ] ]
}
================================================
FILE: recipes/craft3x/quartz.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "quartz",
"stackSize": 9
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "block_quartz" ] ]
}
================================================
FILE: recipes/craft3x/red_gold_ingot.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "red_gold_ingot",
"stackSize": 2
}
],
"pattern": [
"OBO",
"BAB",
"OBO"
],
"elements": [ [ "A", "gold_ingot" ], [ "B", "red_crystal" ] ]
}
================================================
FILE: recipes/craft3x/red_mushroom.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "red_mushroom",
"stackSize": 2
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "large_red_mushroom" ] ]
}
================================================
FILE: recipes/craft3x/red_mushroom_2.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "red_mushroom",
"stackSize": 2
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "red_mushroom_block" ] ]
}
================================================
FILE: recipes/craft3x/red_nether_brick.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "red_nether_brick",
"stackSize": 1
}
],
"pattern": [
"BAO",
"ABO",
"OOO"
],
"elements": [
[ "A", "nether_brick" ],
[ "B", "nether_wart" ]
]
}
================================================
FILE: recipes/craft3x/red_sand_carved.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "red_sand_carved",
"stackSize": 4
}
],
"pattern": [
"AAO",
"AAO",
"OOO"
],
"elements": [ [ "A", "red_sand_stone" ] ]
}
================================================
FILE: recipes/craft3x/red_sand_stone.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "red_sand_stone",
"stackSize": 1
}
],
"pattern": [
"AAO",
"AAO",
"OOO"
],
"elements": [ [ "A", "red_sand" ] ]
}
================================================
FILE: recipes/craft3x/red_torch.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "red_torch",
"stackSize": 1
}
],
"pattern": [
"ABO",
"OOO",
"OOO"
],
"elements": [
[ "A", "torch" ],
[ "B", "dye_red" ]
],
"importantElements": [ "B" ]
}
================================================
FILE: recipes/craft3x/red_wire.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "red_wire",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "redstone" ],
[ "B", "string" ]
]
}
================================================
FILE: recipes/craft3x/redstone.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "redstone",
"stackSize": 9
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "block_redstone" ] ]
}
================================================
FILE: recipes/craft3x/redstone_lamp.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "redstone_lamp",
"stackSize": 1
}
],
"pattern": [
"OAO",
"ABA",
"OAO"
],
"elements": [
[ "A", "redstone" ],
[ "B", "glowstone" ]
]
}
================================================
FILE: recipes/craft3x/redstone_torch.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "redstone_torch",
"stackSize": 1
}
],
"pattern": [
"AOO",
"BOO",
"OOO"
],
"elements": [
[ "A", "redstone" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/rocket.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "rocket",
"stackSize": 1
}
],
"pattern": [
"OBO",
"BAB",
"OOO"
],
"elements": [
[ "A", "tnt" ],
[ "B", "OD_IRON_INGOT" ]
]
}
================================================
FILE: recipes/craft3x/rocket_boost.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "rocket_boost",
"stackSize": 1
}
],
"pattern": [
"OBB",
"BAB",
"OOO"
],
"elements": [
[ "A", "rocket" ],
[ "B", "OD_IRON_INGOT" ]
]
}
================================================
FILE: recipes/craft3x/rotten_flesh.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "rotten_flesh",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AAA",
"AAA"
],
"elements": [ [ "A", "flesh_stone" ] ]
}
================================================
FILE: recipes/craft3x/sandstone.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "sandstone",
"stackSize": 1
}
],
"pattern": [
"AAO",
"AAO",
"OOO"
],
"elements": [ [ "A", "sand" ] ]
}
================================================
FILE: recipes/craft3x/sandstone_carved.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "sandstone_carved",
"stackSize": 4
}
],
"pattern": [
"AAO",
"AAO",
"OOO"
],
"elements": [ [ "A", "sandstone" ] ]
}
================================================
FILE: recipes/craft3x/sea_lantern.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "sea_lantern",
"stackSize": 1
}
],
"pattern": [
"BAB",
"AAA",
"BAB"
],
"elements": [
[ "A", "prismarine_crystals" ],
[ "B", "prismarine_shard" ]
]
}
================================================
FILE: recipes/craft3x/shadow_staff.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "shadow_staff",
"stackSize": 1
}
],
"pattern": [
"OAB",
"OCA",
"COO"
],
"elements": [
[ "A", "ender_pearl" ],
[ "B", "diamond" ],
[ "C", "silver_ingot" ]
]
}
================================================
FILE: recipes/craft3x/shears.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "shears",
"stackSize": 1
}
],
"pattern": [
"OAO",
"AOO",
"OOO"
],
"elements": [ [ "A", "OD_IRON_INGOT" ] ]
}
================================================
FILE: recipes/craft3x/shot_bow.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "shot_bow",
"stackSize": 1
}
],
"pattern": [
"AAA",
"CDC",
"OBO"
],
"elements": [
[ "A", "gold_ingot" ],
[ "B", "stick" ],
[ "C", "string" ],
[ "D", "cross_bow" ]
],
"importantElements": [ "A", "D" ]
}
================================================
FILE: recipes/craft3x/shot_bow_2.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "shot_bow",
"stackSize": 1
}
],
"pattern": [
"AAA",
"CDC",
"OBO"
],
"elements": [
[ "A", "silver_ingot" ],
[ "B", "stick" ],
[ "C", "string" ],
[ "D", "cross_bow" ]
],
"importantElements": [ "A", "B" ]
}
================================================
FILE: recipes/craft3x/shulker_box.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "shulker_box",
"stackSize": 1
}
],
"pattern": [
"AOO",
"BOO",
"AOO"
],
"elements": [
[ "A", "shulker_shell" ],
[ "B", "chest" ]
]
}
================================================
FILE: recipes/craft3x/sign.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "sign",
"stackSize": 3
}
],
"pattern": [
"AAA",
"AAA",
"OBO"
],
"elements": [
[ "A", "OD_WOODEN_PLANK" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/silver_axe.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "silver_axe",
"stackSize": 1
}
],
"pattern": [
"AAO",
"ABO",
"OBO"
],
"elements": [
[ "A", "silver_ingot" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/silver_bullet.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "silver_bullet",
"stackSize": 16
}
],
"pattern": [
"ABO",
"OOO",
"OOO"
],
"elements": [
[ "A", "fire_charge" ],
[ "B", "silver_ingot" ]
]
}
================================================
FILE: recipes/craft3x/silver_chestplate.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "silver_chestplate",
"stackSize": 1
}
],
"pattern": [
"AOA",
"AAA",
"AAA"
],
"elements": [ [ "A", "silver_ingot" ] ]
}
================================================
FILE: recipes/craft3x/silver_helmet.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "silver_helmet",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AOA",
"OOO"
],
"elements": [ [ "A", "silver_ingot" ] ]
}
================================================
FILE: recipes/craft3x/silver_leggings.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "silver_leggings",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AOA",
"AOA"
],
"elements": [ [ "A", "silver_ingot" ] ]
}
================================================
FILE: recipes/craft3x/silver_pickaxe.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "silver_pickaxe",
"stackSize": 1
}
],
"pattern": [
"AAA",
"OBO",
"OBO"
],
"elements": [
[ "A", "silver_ingot" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/silver_sword.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "silver_sword",
"stackSize": 1
}
],
"pattern": [
"AOO",
"AOO",
"BOO"
],
"elements": [
[ "A", "silver_ingot" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/slime_block.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "slime_block",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AAA",
"AAA"
],
"elements": [ [ "A", "slimeball" ] ]
}
================================================
FILE: recipes/craft3x/slimeball.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "slimeball",
"stackSize": 9
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "slime_block" ] ]
}
================================================
FILE: recipes/craft3x/snow.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "snow",
"stackSize": 1
}
],
"pattern": [
"AAO",
"AAO",
"OOO"
],
"elements": [ [ "A", "snowball" ] ]
}
================================================
FILE: recipes/craft3x/snow_brick.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "snow_brick",
"stackSize": 4
}
],
"pattern": [
"AAO",
"AAO",
"OOO"
],
"elements": [ [ "A", "snow" ] ]
}
================================================
FILE: recipes/craft3x/snowball.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "snowball",
"stackSize": 2
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "snow" ] ]
}
================================================
FILE: recipes/craft3x/spruce_plank.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "spruce_plank",
"stackSize": 4
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "wood_spruce" ] ]
}
================================================
FILE: recipes/craft3x/stained_glass_black.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "stained_glass_black",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "OD_GLASS" ],
[ "B", "dye_black" ]
]
}
================================================
FILE: recipes/craft3x/stained_glass_blue.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "stained_glass_blue",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "OD_GLASS" ],
[ "B", "dye_blue" ]
]
}
================================================
FILE: recipes/craft3x/stained_glass_brown.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "stained_glass_brown",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "OD_GLASS" ],
[ "B", "dye_brown" ]
]
}
================================================
FILE: recipes/craft3x/stained_glass_cyan.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "stained_glass_cyan",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "OD_GLASS" ],
[ "B", "dye_cyan" ]
]
}
================================================
FILE: recipes/craft3x/stained_glass_gray.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "stained_glass_gray",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "OD_GLASS" ],
[ "B", "dye_gray" ]
]
}
================================================
FILE: recipes/craft3x/stained_glass_green.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "stained_glass_green",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "OD_GLASS" ],
[ "B", "dye_green" ]
]
}
================================================
FILE: recipes/craft3x/stained_glass_light_blue.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "stained_glass_light_blue",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "OD_GLASS" ],
[ "B", "dye_light_blue" ]
]
}
================================================
FILE: recipes/craft3x/stained_glass_light_gray.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "stained_glass_light_gray",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "OD_GLASS" ],
[ "B", "dye_light_gray" ]
]
}
================================================
FILE: recipes/craft3x/stained_glass_lime.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "stained_glass_lime",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "OD_GLASS" ],
[ "B", "dye_lime" ]
]
}
================================================
FILE: recipes/craft3x/stained_glass_magenta.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "stained_glass_magenta",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "OD_GLASS" ],
[ "B", "dye_magenta" ]
]
}
================================================
FILE: recipes/craft3x/stained_glass_orange.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "stained_glass_orange",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "OD_GLASS" ],
[ "B", "dye_orange" ]
]
}
================================================
FILE: recipes/craft3x/stained_glass_pink.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "stained_glass_pink",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "OD_GLASS" ],
[ "B", "dye_pink" ]
]
}
================================================
FILE: recipes/craft3x/stained_glass_purple.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "stained_glass_purple",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "OD_GLASS" ],
[ "B", "dye_purple" ]
]
}
================================================
FILE: recipes/craft3x/stained_glass_red.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "stained_glass_red",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "OD_GLASS" ],
[ "B", "dye_red" ]
]
}
================================================
FILE: recipes/craft3x/stained_glass_white.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "stained_glass_white",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "OD_GLASS" ],
[ "B", "dye_white" ]
]
}
================================================
FILE: recipes/craft3x/stained_glass_yellow.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "stained_glass_yellow",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "OD_GLASS" ],
[ "B", "dye_yellow" ]
]
}
================================================
FILE: recipes/craft3x/star_arrow.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "star_arrow",
"stackSize": 4
}
],
"pattern": [
"OAO",
"ABA",
"OAO"
],
"elements": [
[ "A", "lighting_arrow" ],
[ "B", "gold_nugget" ]
]
}
================================================
FILE: recipes/craft3x/star_chestplate.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "star_chestplate",
"stackSize": 1
}
],
"pattern": [
"AOA",
"AAA",
"AAA"
],
"elements": [ [ "A", "star_ingot" ] ]
}
================================================
FILE: recipes/craft3x/star_helmet.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "star_helmet",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AOA",
"OOO"
],
"elements": [ [ "A", "star_ingot" ] ]
}
================================================
FILE: recipes/craft3x/star_leggings.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "star_leggings",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AOA",
"AOA"
],
"elements": [ [ "A", "star_ingot" ] ]
}
================================================
FILE: recipes/craft3x/steel_axe.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "steel_axe",
"stackSize": 1
}
],
"pattern": [
"AAO",
"ABO",
"OBO"
],
"elements": [
[ "A", "steel_ingot" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/steel_chestplate.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "steel_chestplate",
"stackSize": 1
}
],
"pattern": [
"AOA",
"AAA",
"AAA"
],
"elements": [ [ "A", "steel_ingot" ] ]
}
================================================
FILE: recipes/craft3x/steel_helmet.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "steel_helmet",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AOA",
"OOO"
],
"elements": [ [ "A", "steel_ingot" ] ]
}
================================================
FILE: recipes/craft3x/steel_leggings.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "steel_leggings",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AOA",
"AOA"
],
"elements": [ [ "A", "steel_ingot" ] ]
}
================================================
FILE: recipes/craft3x/steel_pickaxe.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "steel_pickaxe",
"stackSize": 1
}
],
"pattern": [
"AAA",
"OBO",
"OBO"
],
"elements": [
[ "A", "steel_ingot" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/steel_sword.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "steel_sword",
"stackSize": 1
}
],
"pattern": [
"AOO",
"AOO",
"BOO"
],
"elements": [
[ "A", "steel_ingot" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/stick.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "stick",
"stackSize": 4
}
],
"pattern": [
"AOO",
"AOO",
"OOO"
],
"elements": [ [ "A", "OD_WOODEN_PLANK" ] ]
}
================================================
FILE: recipes/craft3x/stone.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "stone",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "flesh_dirt" ],
[ "B", "flesh_stone" ]
]
}
================================================
FILE: recipes/craft3x/stone_2.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "stone",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "tainted_stone" ],
[ "B", "bone_meal" ]
]
}
================================================
FILE: recipes/craft3x/stone_axe.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "stone_axe",
"stackSize": 1
}
],
"pattern": [
"AAO",
"ABO",
"OBO"
],
"elements": [
[ "A", "cobblestone" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/stone_brick.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "stone_brick",
"stackSize": 4
}
],
"pattern": [
"AAO",
"AAO",
"OOO"
],
"elements": [ [ "A", "stone" ] ]
}
================================================
FILE: recipes/craft3x/stone_brick_carved.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "stone_brick_carved",
"stackSize": 4
}
],
"pattern": [
"AAO",
"AAO",
"OOO"
],
"elements": [ [ "A", "stone_brick" ] ]
}
================================================
FILE: recipes/craft3x/stone_brick_mossy.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "stone_brick_mossy",
"stackSize": 1
}
],
"pattern": [
"ABO",
"OOO",
"OOO"
],
"elements": [
[ "A", "stone_brick" ],
[ "B", "vine" ]
]
}
================================================
FILE: recipes/craft3x/stone_button.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "stone_button",
"stackSize": 1
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "stone" ] ]
}
================================================
FILE: recipes/craft3x/stone_chest.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "stone_chest",
"stackSize": 1
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "cobblestone" ],
[ "B", "chest" ]
]
}
================================================
FILE: recipes/craft3x/stone_hoe.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "stone_hoe",
"stackSize": 1
}
],
"pattern": [
"AAO",
"OBO",
"OBO"
],
"elements": [
[ "A", "cobblestone" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/stone_pickaxe.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "stone_pickaxe",
"stackSize": 1
}
],
"pattern": [
"AAA",
"OBO",
"OBO"
],
"elements": [
[ "A", "cobblestone" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/stone_pressure_plate.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "stone_pressure_plate",
"stackSize": 1
}
],
"pattern": [
"AAO",
"OOO",
"OOO"
],
"elements": [ [ "A", "stone" ] ]
}
================================================
FILE: recipes/craft3x/stone_sword.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "stone_sword",
"stackSize": 1
}
],
"pattern": [
"AOO",
"AOO",
"BOO"
],
"elements": [
[ "A", "cobblestone" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/strange_eye.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "strange_eye",
"stackSize": 1
}
],
"pattern": [
"OAO",
"AAA",
"OAO"
],
"elements": [ [ "A", "strange_len" ] ]
}
================================================
FILE: recipes/craft3x/string.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "string",
"stackSize": 2
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "cobweb" ] ]
}
================================================
FILE: recipes/craft3x/suger.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "suger",
"stackSize": 1
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "sugar_cane" ] ]
}
================================================
FILE: recipes/craft3x/super_bronze_sword.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "super_bronze_sword",
"stackSize": 1
}
],
"pattern": [
"AAO",
"AAO",
"BBO"
],
"elements": [
[ "A", "bronze_ingot" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/super_copper_sword.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "super_copper_sword",
"stackSize": 1
}
],
"pattern": [
"AAO",
"AAO",
"BBO"
],
"elements": [
[ "A", "copper_ingot" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/super_cross_bow.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "super_cross_bow",
"stackSize": 1
}
],
"pattern": [
"EAE",
"CDC",
"OBO"
],
"elements": [
[ "A", "diamond" ],
[ "B", "stick" ],
[ "C", "string" ],
[ "D", "cross_bow" ],
[ "E", "OD_IRON_INGOT" ]
],
"importantElements": [ "A", "D", "E" ]
}
================================================
FILE: recipes/craft3x/super_diamond_chestplate.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "super_diamond_chestplate",
"stackSize": 1
}
],
"pattern": [
"AOA",
"AAA",
"AAA"
],
"elements": [ [ "A", "diamond_ingot" ] ]
}
================================================
FILE: recipes/craft3x/super_diamond_helmet.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "super_diamond_helmet",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AOA",
"OOO"
],
"elements": [ [ "A", "diamond_ingot" ] ]
}
================================================
FILE: recipes/craft3x/super_diamond_leggings.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "super_diamond_leggings",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AOA",
"AOA"
],
"elements": [ [ "A", "diamond_ingot" ] ]
}
================================================
FILE: recipes/craft3x/super_diamond_sword.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "super_diamond_sword",
"stackSize": 1
}
],
"pattern": [
"AAO",
"AAO",
"BBO"
],
"elements": [
[ "A", "diamond" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/super_golden_sword.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "super_golden_sword",
"stackSize": 1
}
],
"pattern": [
"AAO",
"AAO",
"BBO"
],
"elements": [
[ "A", "gold_ingot" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/super_iron_sword.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "super_iron_sword",
"stackSize": 1
}
],
"pattern": [
"AAO",
"AAO",
"BBO"
],
"elements": [
[ "A", "OD_IRON_INGOT" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/super_lead_sword.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "super_lead_sword",
"stackSize": 1
}
],
"pattern": [
"AAO",
"AAO",
"BBO"
],
"elements": [
[ "A", "lead_ingot" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/super_silver_sword.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "super_silver_sword",
"stackSize": 1
}
],
"pattern": [
"AAO",
"AAO",
"BBO"
],
"elements": [
[ "A", "silver_ingot" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/super_steel_sword.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "super_steel_sword",
"stackSize": 1
}
],
"pattern": [
"AAO",
"AAO",
"BBO"
],
"elements": [
[ "A", "steel_ingot" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/super_tin_sword.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "super_tin_sword",
"stackSize": 1
}
],
"pattern": [
"AAO",
"AAO",
"BBO"
],
"elements": [
[ "A", "tin_ingot" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/sword_arrow.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "sword_arrow",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "wooden_arrow" ],
[ "B", "shulker_shell" ]
]
}
================================================
FILE: recipes/craft3x/sword_arrow_2.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "sword_arrow",
"stackSize": 16
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "wooden_arrow" ],
[ "B", "ender_pearl" ]
]
}
================================================
FILE: recipes/craft3x/sword_arrow_3.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "sword_arrow",
"stackSize": 24
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "wooden_arrow" ],
[ "B", "ender_eye" ]
]
}
================================================
FILE: recipes/craft3x/table_acacia.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "table_acacia",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AOA",
"OOO"
],
"elements": [ [ "A", "acacia_plank" ] ]
}
================================================
FILE: recipes/craft3x/table_birch.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "table_birch",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AOA",
"OOO"
],
"elements": [ [ "A", "birch_plank" ] ]
}
================================================
FILE: recipes/craft3x/table_dark_oak.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "table_dark_oak",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AOA",
"OOO"
],
"elements": [ [ "A", "dark_oak_plank" ] ]
}
================================================
FILE: recipes/craft3x/table_jungle.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "table_jungle",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AOA",
"OOO"
],
"elements": [ [ "A", "jungle_plank" ] ]
}
================================================
FILE: recipes/craft3x/table_nether.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "table_nether",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AOA",
"OOO"
],
"elements": [ [ "A", "nether_brick" ] ]
}
================================================
FILE: recipes/craft3x/table_oak.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "table_oak",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AOA",
"OOO"
],
"elements": [ [ "A", "oak_plank" ] ]
}
================================================
FILE: recipes/craft3x/table_palm.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "table_palm",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AOA",
"OOO"
],
"elements": [ [ "A", "palm_plank" ] ]
}
================================================
FILE: recipes/craft3x/table_spruce.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "table_spruce",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AOA",
"OOO"
],
"elements": [ [ "A", "spruce_plank" ] ]
}
================================================
FILE: recipes/craft3x/table_tainted.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "table_tainted",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AOA",
"OOO"
],
"elements": [ [ "A", "tainted_plank" ] ]
}
================================================
FILE: recipes/craft3x/table_volcano.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "table_volcano",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AOA",
"OOO"
],
"elements": [ [ "A", "volcano_plank" ] ]
}
================================================
FILE: recipes/craft3x/tainted_plank.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "tainted_plank",
"stackSize": 5
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "wood_tainted" ] ]
}
================================================
FILE: recipes/craft3x/terracotta_black.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "terracotta_black",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "OD_TERRACOTTA" ],
[ "B", "dye_black" ]
]
}
================================================
FILE: recipes/craft3x/terracotta_black_2.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "terracotta_black",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "OD_TERRACOTTA" ],
[ "B", "ink_sac" ]
]
}
================================================
FILE: recipes/craft3x/terracotta_blue.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "terracotta_blue",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "OD_TERRACOTTA" ],
[ "B", "dye_blue" ]
]
}
================================================
FILE: recipes/craft3x/terracotta_blue_2.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "terracotta_blue",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "OD_TERRACOTTA" ],
[ "B", "lapis_lazuli" ]
]
}
================================================
FILE: recipes/craft3x/terracotta_brown.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "terracotta_brown",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "OD_TERRACOTTA" ],
[ "B", "dye_brown" ]
]
}
================================================
FILE: recipes/craft3x/terracotta_cyan.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "terracotta_cyan",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "OD_TERRACOTTA" ],
[ "B", "dye_cyan" ]
]
}
================================================
FILE: recipes/craft3x/terracotta_gray.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "terracotta_gray",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "OD_TERRACOTTA" ],
[ "B", "dye_gray" ]
]
}
================================================
FILE: recipes/craft3x/terracotta_green.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "terracotta_green",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "OD_TERRACOTTA" ],
[ "B", "dye_green" ]
]
}
================================================
FILE: recipes/craft3x/terracotta_light_blue.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "terracotta_light_blue",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "OD_TERRACOTTA" ],
[ "B", "dye_light_blue" ]
]
}
================================================
FILE: recipes/craft3x/terracotta_light_gray.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "terracotta_light_gray",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "OD_TERRACOTTA" ],
[ "B", "dye_light_gray" ]
]
}
================================================
FILE: recipes/craft3x/terracotta_lime.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "terracotta_lime",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "OD_TERRACOTTA" ],
[ "B", "dye_lime" ]
]
}
================================================
FILE: recipes/craft3x/terracotta_magenta.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "terracotta_magenta",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "OD_TERRACOTTA" ],
[ "B", "dye_magenta" ]
]
}
================================================
FILE: recipes/craft3x/terracotta_orange.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "terracotta_orange",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "OD_TERRACOTTA" ],
[ "B", "dye_orange" ]
]
}
================================================
FILE: recipes/craft3x/terracotta_pink.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "terracotta_pink",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "OD_TERRACOTTA" ],
[ "B", "dye_pink" ]
]
}
================================================
FILE: recipes/craft3x/terracotta_purple.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "terracotta_purple",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "OD_TERRACOTTA" ],
[ "B", "dye_purple" ]
]
}
================================================
FILE: recipes/craft3x/terracotta_red.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "terracotta_red",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "OD_TERRACOTTA" ],
[ "B", "dye_red" ]
]
}
================================================
FILE: recipes/craft3x/terracotta_white.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "terracotta_white",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "OD_TERRACOTTA" ],
[ "B", "dye_white" ]
]
}
================================================
FILE: recipes/craft3x/terracotta_white_2.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "terracotta_white",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "OD_TERRACOTTA" ],
[ "B", "bone_meal" ]
]
}
================================================
FILE: recipes/craft3x/terracotta_yellow.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "terracotta_yellow",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "OD_TERRACOTTA" ],
[ "B", "dye_yellow" ]
]
}
================================================
FILE: recipes/craft3x/tin_axe.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "tin_axe",
"stackSize": 1
}
],
"pattern": [
"AAO",
"ABO",
"OBO"
],
"elements": [
[ "A", "tin_ingot" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/tin_chestplate.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "tin_chestplate",
"stackSize": 1
}
],
"pattern": [
"AOA",
"AAA",
"AAA"
],
"elements": [ [ "A", "tin_ingot" ] ]
}
================================================
FILE: recipes/craft3x/tin_helmet.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "tin_helmet",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AOA",
"OOO"
],
"elements": [ [ "A", "tin_ingot" ] ]
}
================================================
FILE: recipes/craft3x/tin_leggings.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "tin_leggings",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AOA",
"AOA"
],
"elements": [ [ "A", "tin_ingot" ] ]
}
================================================
FILE: recipes/craft3x/tin_pickaxe.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "tin_pickaxe",
"stackSize": 1
}
],
"pattern": [
"AAA",
"OBO",
"OBO"
],
"elements": [
[ "A", "tin_ingot" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/tin_sword.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "tin_sword",
"stackSize": 1
}
],
"pattern": [
"AOO",
"AOO",
"BOO"
],
"elements": [
[ "A", "tin_ingot" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/tnt.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "tnt",
"stackSize": 1
}
],
"pattern": [
"BAB",
"ABA",
"BAB"
],
"elements": [
[ "A", "sand" ],
[ "B", "gunpowder" ]
]
}
================================================
FILE: recipes/craft3x/tnt_2.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "tnt",
"stackSize": 1
}
],
"pattern": [
"BAB",
"ABA",
"BAB"
],
"elements": [
[ "A", "red_sand" ],
[ "B", "gunpowder" ]
]
}
================================================
FILE: recipes/craft3x/torch.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "torch",
"stackSize": 4
}
],
"pattern": [
"AOO",
"BOO",
"OOO"
],
"elements": [
[ "A", "slimeball" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/torch_2.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "torch",
"stackSize": 6
}
],
"pattern": [
"AOO",
"BOO",
"OOO"
],
"elements": [
[ "A", "coal" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/torch_3.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "torch",
"stackSize": 6
}
],
"pattern": [
"AOO",
"BOO",
"OOO"
],
"elements": [
[ "A", "charcoal" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/tower_core.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "tower_core",
"stackSize": 1
}
],
"pattern": [
"OBO",
"BAB",
"OBO"
],
"elements": [ [ "A", "ice_element_ball"], [ "B", "ghost" ] ]
}
================================================
FILE: recipes/craft3x/trapped_chest.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "trapped_chest",
"stackSize": 1
}
],
"pattern": [
"OBO",
"BAB",
"OBO"
],
"elements": [
[ "A", "chest" ],
[ "B", "redstone" ]
]
}
================================================
FILE: recipes/craft3x/volcano_plank.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "volcano_plank",
"stackSize": 6
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "wood_volcano" ] ]
}
================================================
FILE: recipes/craft3x/water_staff.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "water_staff",
"stackSize": 1
}
],
"pattern": [
"OAB",
"OCA",
"COO"
],
"elements": [
[ "A", "copper_ingot" ],
[ "B", "bucket_water" ],
[ "C", "OD_IRON_INGOT" ]
]
}
================================================
FILE: recipes/craft3x/watermelon.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "watermelon",
"stackSize": 1
}
],
"pattern": [
"AAA",
"AAA",
"AAA"
],
"elements": [ [ "A", "melon_slice" ] ]
}
================================================
FILE: recipes/craft3x/wheat.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wheat",
"stackSize": 9
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "hay_bale" ] ]
}
================================================
FILE: recipes/craft3x/white_torch.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "white_torch",
"stackSize": 1
}
],
"pattern": [
"ABO",
"OOO",
"OOO"
],
"elements": [
[ "A", "torch" ],
[ "B", "dye_white" ]
],
"importantElements": [ "B" ]
}
================================================
FILE: recipes/craft3x/wire_cutter.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wire_cutter",
"stackSize": 1
}
],
"pattern": [
"AOA",
"AAA",
"BOB"
],
"elements": [
[ "A", "OD_IRON_INGOT" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/wooden_arrow.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wooden_arrow",
"stackSize": 6
}
],
"pattern": [
"AOO",
"BOO",
"COO"
],
"elements": [
[ "A", "flint" ],
[ "B", "stick" ],
[ "C", "feather" ]
],
"importantElements": [ "A", "C" ]
}
================================================
FILE: recipes/craft3x/wooden_arrow_2.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wooden_arrow",
"stackSize": 6
}
],
"pattern": [
"AOO",
"BOO",
"COO"
],
"elements": [
[ "A", "flint" ],
[ "B", "stick" ],
[ "C", "gray_feather" ]
],
"importantElements": [ "A", "C" ]
}
================================================
FILE: recipes/craft3x/wooden_arrow_3.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wooden_arrow",
"stackSize": 16
}
],
"pattern": [
"AOO",
"BOO",
"COO"
],
"elements": [
[ "A", "OD_IRON_INGOT" ],
[ "B", "stick" ],
[ "C", "feather" ]
],
"importantElements": [ "A", "C" ]
}
================================================
FILE: recipes/craft3x/wooden_arrow_4.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wooden_arrow",
"stackSize": 16
}
],
"pattern": [
"AOO",
"BOO",
"COO"
],
"elements": [
[ "A", "OD_IRON_INGOT" ],
[ "B", "stick" ],
[ "C", "gray_feather" ]
],
"importantElements": [ "A", "C" ]
}
================================================
FILE: recipes/craft3x/wooden_axe.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wooden_axe",
"stackSize": 1
}
],
"pattern": [
"AAO",
"ABO",
"OBO"
],
"elements": [
[ "A", "OD_WOODEN_PLANK" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/wooden_bed_black.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "wooden_bed_black",
"stackSize": 1
}
],
"pattern": [
"ABO",
"OOO",
"OOO"
],
"elements": [
[ "A", "wooden_bed_white" ],
[ "B", "dye_black" ]
],
"importantElements": [ "B" ]
}
================================================
FILE: recipes/craft3x/wooden_bed_black_2.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wooden_bed_black",
"stackSize": 1
}
],
"pattern": [
"BBB",
"AAA",
"OOO"
],
"elements": [
[ "A", "OD_WOODEN_PLANK" ],
[ "B", "wool_black" ]
],
"importantElements": [ "B" ]
}
================================================
FILE: recipes/craft3x/wooden_bed_blue.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "wooden_bed_blue",
"stackSize": 1
}
],
"pattern": [
"ABO",
"OOO",
"OOO"
],
"elements": [
[ "A", "wooden_bed_white" ],
[ "B", "dye_blue" ]
],
"importantElements": [ "B" ]
}
================================================
FILE: recipes/craft3x/wooden_bed_blue_2.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wooden_bed_blue",
"stackSize": 1
}
],
"pattern": [
"BBB",
"AAA",
"OOO"
],
"elements": [
[ "A", "OD_WOODEN_PLANK" ],
[ "B", "wool_blue" ]
],
"importantElements": [ "B" ]
}
================================================
FILE: recipes/craft3x/wooden_bed_brown.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "wooden_bed_brown",
"stackSize": 1
}
],
"pattern": [
"ABO",
"OOO",
"OOO"
],
"elements": [
[ "A", "wooden_bed_white" ],
[ "B", "dye_brown" ]
],
"importantElements": [ "B" ]
}
================================================
FILE: recipes/craft3x/wooden_bed_brown_2.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wooden_bed_brown",
"stackSize": 1
}
],
"pattern": [
"BBB",
"AAA",
"OOO"
],
"elements": [
[ "A", "OD_WOODEN_PLANK" ],
[ "B", "wool_brown" ]
],
"importantElements": [ "B" ]
}
================================================
FILE: recipes/craft3x/wooden_bed_cyan.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "wooden_bed_cyan",
"stackSize": 1
}
],
"pattern": [
"ABO",
"OOO",
"OOO"
],
"elements": [
[ "A", "wooden_bed_white" ],
[ "B", "dye_cyan" ]
],
"importantElements": [ "B" ]
}
================================================
FILE: recipes/craft3x/wooden_bed_cyan_2.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wooden_bed_cyan",
"stackSize": 1
}
],
"pattern": [
"BBB",
"AAA",
"OOO"
],
"elements": [
[ "A", "OD_WOODEN_PLANK" ],
[ "B", "wool_cyan" ]
],
"importantElements": [ "B" ]
}
================================================
FILE: recipes/craft3x/wooden_bed_gray.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "wooden_bed_gray",
"stackSize": 1
}
],
"pattern": [
"ABO",
"OOO",
"OOO"
],
"elements": [
[ "A", "wooden_bed_white" ],
[ "B", "dye_gray" ]
],
"importantElements": [ "B" ]
}
================================================
FILE: recipes/craft3x/wooden_bed_gray_2.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wooden_bed_gray",
"stackSize": 1
}
],
"pattern": [
"BBB",
"AAA",
"OOO"
],
"elements": [
[ "A", "OD_WOODEN_PLANK" ],
[ "B", "wool_gray" ]
],
"importantElements": [ "B" ]
}
================================================
FILE: recipes/craft3x/wooden_bed_green.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "wooden_bed_green",
"stackSize": 1
}
],
"pattern": [
"ABO",
"OOO",
"OOO"
],
"elements": [
[ "A", "wooden_bed_white" ],
[ "B", "dye_green" ]
],
"importantElements": [ "B" ]
}
================================================
FILE: recipes/craft3x/wooden_bed_green_2.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wooden_bed_green",
"stackSize": 1
}
],
"pattern": [
"BBB",
"AAA",
"OOO"
],
"elements": [
[ "A", "OD_WOODEN_PLANK" ],
[ "B", "wool_green" ]
],
"importantElements": [ "B" ]
}
================================================
FILE: recipes/craft3x/wooden_bed_light_blue.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "wooden_bed_light_blue",
"stackSize": 1
}
],
"pattern": [
"ABO",
"OOO",
"OOO"
],
"elements": [
[ "A", "wooden_bed_white" ],
[ "B", "dye_light_blue" ]
],
"importantElements": [ "B" ]
}
================================================
FILE: recipes/craft3x/wooden_bed_light_blue_2.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wooden_bed_light_blue",
"stackSize": 1
}
],
"pattern": [
"BBB",
"AAA",
"OOO"
],
"elements": [
[ "A", "OD_WOODEN_PLANK" ],
[ "B", "wool_light_blue" ]
],
"importantElements": [ "B" ]
}
================================================
FILE: recipes/craft3x/wooden_bed_light_gray.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "wooden_bed_light_gray",
"stackSize": 1
}
],
"pattern": [
"ABO",
"OOO",
"OOO"
],
"elements": [
[ "A", "wooden_bed_white" ],
[ "B", "dye_light_gray" ]
],
"importantElements": [ "B" ]
}
================================================
FILE: recipes/craft3x/wooden_bed_light_gray_2.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wooden_bed_light_gray",
"stackSize": 1
}
],
"pattern": [
"BBB",
"AAA",
"OOO"
],
"elements": [
[ "A", "OD_WOODEN_PLANK" ],
[ "B", "wool_light_gray" ]
],
"importantElements": [ "B" ]
}
================================================
FILE: recipes/craft3x/wooden_bed_lime.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "wooden_bed_lime",
"stackSize": 1
}
],
"pattern": [
"ABO",
"OOO",
"OOO"
],
"elements": [
[ "A", "wooden_bed_white" ],
[ "B", "dye_lime" ]
],
"importantElements": [ "B" ]
}
================================================
FILE: recipes/craft3x/wooden_bed_lime_2.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wooden_bed_lime",
"stackSize": 1
}
],
"pattern": [
"BBB",
"AAA",
"OOO"
],
"elements": [
[ "A", "OD_WOODEN_PLANK" ],
[ "B", "wool_lime" ]
],
"importantElements": [ "B" ]
}
================================================
FILE: recipes/craft3x/wooden_bed_magenta.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "wooden_bed_magenta",
"stackSize": 1
}
],
"pattern": [
"ABO",
"OOO",
"OOO"
],
"elements": [
[ "A", "wooden_bed_white" ],
[ "B", "dye_magenta" ]
],
"importantElements": [ "B" ]
}
================================================
FILE: recipes/craft3x/wooden_bed_magenta_2.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wooden_bed_magenta",
"stackSize": 1
}
],
"pattern": [
"BBB",
"AAA",
"OOO"
],
"elements": [
[ "A", "OD_WOODEN_PLANK" ],
[ "B", "wool_magenta" ]
],
"importantElements": [ "B" ]
}
================================================
FILE: recipes/craft3x/wooden_bed_orange.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "wooden_bed_orange",
"stackSize": 1
}
],
"pattern": [
"ABO",
"OOO",
"OOO"
],
"elements": [
[ "A", "wooden_bed_white" ],
[ "B", "dye_orange" ]
],
"importantElements": [ "B" ]
}
================================================
FILE: recipes/craft3x/wooden_bed_orange_2.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wooden_bed_orange",
"stackSize": 1
}
],
"pattern": [
"BBB",
"AAA",
"OOO"
],
"elements": [
[ "A", "OD_WOODEN_PLANK" ],
[ "B", "wool_orange" ]
],
"importantElements": [ "B" ]
}
================================================
FILE: recipes/craft3x/wooden_bed_pink.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "wooden_bed_pink",
"stackSize": 1
}
],
"pattern": [
"ABO",
"OOO",
"OOO"
],
"elements": [
[ "A", "wooden_bed_white" ],
[ "B", "dye_pink" ]
],
"importantElements": [ "B" ]
}
================================================
FILE: recipes/craft3x/wooden_bed_pink_2.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wooden_bed_pink",
"stackSize": 1
}
],
"pattern": [
"BBB",
"AAA",
"OOO"
],
"elements": [
[ "A", "OD_WOODEN_PLANK" ],
[ "B", "wool_pink" ]
],
"importantElements": [ "B" ]
}
================================================
FILE: recipes/craft3x/wooden_bed_purple.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "wooden_bed_purple",
"stackSize": 1
}
],
"pattern": [
"ABO",
"OOO",
"OOO"
],
"elements": [
[ "A", "wooden_bed_white" ],
[ "B", "dye_purple" ]
],
"importantElements": [ "B" ]
}
================================================
FILE: recipes/craft3x/wooden_bed_purple_2.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wooden_bed_purple",
"stackSize": 1
}
],
"pattern": [
"BBB",
"AAA",
"OOO"
],
"elements": [
[ "A", "OD_WOODEN_PLANK" ],
[ "B", "wool_purple" ]
],
"importantElements": [ "B" ]
}
================================================
FILE: recipes/craft3x/wooden_bed_red.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "wooden_bed_red",
"stackSize": 1
}
],
"pattern": [
"ABO",
"OOO",
"OOO"
],
"elements": [
[ "A", "wooden_bed_white" ],
[ "B", "dye_red" ]
],
"importantElements": [ "B" ]
}
================================================
FILE: recipes/craft3x/wooden_bed_red_2.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wooden_bed_red",
"stackSize": 1
}
],
"pattern": [
"BBB",
"AAA",
"OOO"
],
"elements": [
[ "A", "OD_WOODEN_PLANK" ],
[ "B", "wool_red" ]
],
"importantElements": [ "B" ]
}
================================================
FILE: recipes/craft3x/wooden_bed_white.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wooden_bed_white",
"stackSize": 1
}
],
"pattern": [
"BBB",
"AAA",
"OOO"
],
"elements": [
[ "A", "OD_WOODEN_PLANK" ],
[ "B", "wool_white" ]
]
}
================================================
FILE: recipes/craft3x/wooden_bed_yellow.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "wooden_bed_yellow",
"stackSize": 1
}
],
"pattern": [
"ABO",
"OOO",
"OOO"
],
"elements": [
[ "A", "wooden_bed_white" ],
[ "B", "dye_yellow" ]
],
"importantElements": [ "B" ]
}
================================================
FILE: recipes/craft3x/wooden_bed_yellow_2.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wooden_bed_yellow",
"stackSize": 1
}
],
"pattern": [
"BBB",
"AAA",
"OOO"
],
"elements": [
[ "A", "OD_WOODEN_PLANK" ],
[ "B", "wool_yellow" ]
],
"importantElements": [ "B" ]
}
================================================
FILE: recipes/craft3x/wooden_boomerang.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wooden_boomerang",
"stackSize": 1
}
],
"pattern": [
"OAO",
"AOO",
"OAO"
],
"elements": [ [ "A", "OD_WOODEN_PLANK" ] ]
}
================================================
FILE: recipes/craft3x/wooden_bow.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wooden_bow",
"stackSize": 1
}
],
"pattern": [
"OAB",
"AOB",
"OAB"
],
"elements": [
[ "A", "stick" ],
[ "B", "string" ]
],
"importantElements": [ "B" ]
}
================================================
FILE: recipes/craft3x/wooden_button.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wooden_button",
"stackSize": 1
}
],
"pattern": [
"AOO",
"OOO",
"OOO"
],
"elements": [ [ "A", "OD_WOODEN_PLANK" ] ]
}
================================================
FILE: recipes/craft3x/wooden_door_acacia.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wooden_door_acacia",
"stackSize": 3
}
],
"pattern": [
"AAO",
"AAO",
"AAO"
],
"elements": [ [ "A", "acacia_plank" ] ]
}
================================================
FILE: recipes/craft3x/wooden_door_birch.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wooden_door_birch",
"stackSize": 3
}
],
"pattern": [
"AAO",
"AAO",
"AAO"
],
"elements": [ [ "A", "birch_plank" ] ]
}
================================================
FILE: recipes/craft3x/wooden_door_dark_oak.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wooden_door_dark_oak",
"stackSize": 3
}
],
"pattern": [
"AAO",
"AAO",
"AAO"
],
"elements": [ [ "A", "dark_oak_plank" ] ]
}
================================================
FILE: recipes/craft3x/wooden_door_jungle.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wooden_door_jungle",
"stackSize": 3
}
],
"pattern": [
"AAO",
"AAO",
"AAO"
],
"elements": [ [ "A", "jungle_plank" ] ]
}
================================================
FILE: recipes/craft3x/wooden_door_oak.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wooden_door_oak",
"stackSize": 3
}
],
"pattern": [
"AAO",
"AAO",
"AAO"
],
"elements": [ [ "A", "oak_plank" ] ]
}
================================================
FILE: recipes/craft3x/wooden_door_palm.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wooden_door_palm",
"stackSize": 3
}
],
"pattern": [
"AAO",
"AAO",
"AAO"
],
"elements": [ [ "A", "palm_plank" ] ]
}
================================================
FILE: recipes/craft3x/wooden_door_spruce.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wooden_door_spruce",
"stackSize": 3
}
],
"pattern": [
"AAO",
"AAO",
"AAO"
],
"elements": [ [ "A", "spruce_plank" ] ]
}
================================================
FILE: recipes/craft3x/wooden_door_tainted.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wooden_door_tainted",
"stackSize": 3
}
],
"pattern": [
"AAO",
"AAO",
"AAO"
],
"elements": [ [ "A", "tainted_plank" ] ]
}
================================================
FILE: recipes/craft3x/wooden_door_volcano.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wooden_door_volcano",
"stackSize": 3
}
],
"pattern": [
"AAO",
"AAO",
"AAO"
],
"elements": [ [ "A", "volcano_plank" ] ]
}
================================================
FILE: recipes/craft3x/wooden_hoe.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wooden_hoe",
"stackSize": 1
}
],
"pattern": [
"AAO",
"OBO",
"OBO"
],
"elements": [
[ "A", "OD_WOODEN_PLANK" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/wooden_pickaxe.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wooden_pickaxe",
"stackSize": 1
}
],
"pattern": [
"AAA",
"OBO",
"OBO"
],
"elements": [
[ "A", "OD_WOODEN_PLANK" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/wooden_pressure_plate.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wooden_pressure_plate",
"stackSize": 1
}
],
"pattern": [
"AAO",
"OOO",
"OOO"
],
"elements": [ [ "A", "OD_WOODEN_PLANK" ] ]
}
================================================
FILE: recipes/craft3x/wooden_sword.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wooden_sword",
"stackSize": 1
}
],
"pattern": [
"AOO",
"AOO",
"BOO"
],
"elements": [
[ "A", "OD_WOODEN_PLANK" ],
[ "B", "stick" ]
],
"importantElements": [ "A" ]
}
================================================
FILE: recipes/craft3x/wool_black.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wool_black",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "wool_white" ],
[ "B", "dye_black" ]
]
}
================================================
FILE: recipes/craft3x/wool_black_2.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wool_black",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "wool_white" ],
[ "B", "ink_sac" ]
]
}
================================================
FILE: recipes/craft3x/wool_blue.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wool_blue",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "wool_white" ],
[ "B", "dye_blue" ]
]
}
================================================
FILE: recipes/craft3x/wool_blue_2.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wool_blue",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "wool_white" ],
[ "B", "lapis_lazuli" ]
]
}
================================================
FILE: recipes/craft3x/wool_brown.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wool_brown",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "wool_white" ],
[ "B", "dye_brown" ]
]
}
================================================
FILE: recipes/craft3x/wool_cyan.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wool_cyan",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "wool_white" ],
[ "B", "dye_cyan" ]
]
}
================================================
FILE: recipes/craft3x/wool_gray.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wool_gray",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "wool_white" ],
[ "B", "dye_gray" ]
]
}
================================================
FILE: recipes/craft3x/wool_green.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wool_green",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "wool_white" ],
[ "B", "dye_green" ]
]
}
================================================
FILE: recipes/craft3x/wool_light_blue.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wool_light_blue",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "wool_white" ],
[ "B", "dye_light_blue" ]
]
}
================================================
FILE: recipes/craft3x/wool_light_gray.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wool_light_gray",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "wool_white" ],
[ "B", "dye_light_gray" ]
]
}
================================================
FILE: recipes/craft3x/wool_lime.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wool_lime",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "wool_white" ],
[ "B", "dye_lime" ]
]
}
================================================
FILE: recipes/craft3x/wool_magenta.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wool_magenta",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "wool_white" ],
[ "B", "dye_magenta" ]
]
}
================================================
FILE: recipes/craft3x/wool_orange.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wool_orange",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "wool_white" ],
[ "B", "dye_orange" ]
]
}
================================================
FILE: recipes/craft3x/wool_pink.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wool_pink",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "wool_white" ],
[ "B", "dye_pink" ]
]
}
================================================
FILE: recipes/craft3x/wool_purple.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wool_purple",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "wool_white" ],
[ "B", "dye_purple" ]
]
}
================================================
FILE: recipes/craft3x/wool_red.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wool_red",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "wool_white" ],
[ "B", "dye_red" ]
]
}
================================================
FILE: recipes/craft3x/wool_white.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wool_white",
"stackSize": 1
}
],
"pattern": [
"AAO",
"AAO",
"OOO"
],
"elements": [ [ "A", "string" ] ]
}
================================================
FILE: recipes/craft3x/wool_yellow.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "wool_yellow",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "wool_white" ],
[ "B", "dye_yellow" ]
]
}
================================================
FILE: recipes/craft3x/yellow_torch.json
================================================
{
"config": "Craft3x",
"searchActions": [ [ 0, "SA_UNORDER" ] ],
"results": [
{
"id": "yellow_torch",
"stackSize": 1
}
],
"pattern": [
"ABO",
"OOO",
"OOO"
],
"elements": [
[ "A", "torch" ],
[ "B", "dye_yellow" ]
],
"importantElements": [ "B" ]
}
================================================
FILE: recipes/craft3x/yellow_wire.json
================================================
{
"config": "Craft3x",
"results": [
{
"id": "yellow_wire",
"stackSize": 8
}
],
"pattern": [
"AAA",
"ABA",
"AAA"
],
"elements": [
[ "A", "red_wire" ],
[ "B", "dye_yellow" ]
]
}
================================================
FILE: recipes/repair/ancient_chestplate.json
================================================
{
"config": "Repair",
"results": [
{
"id": "ancient_chestplate",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "ancient_chestplate" ],
[ "B", "ancient_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/ancient_chestplate_2.json
================================================
{
"config": "Repair",
"results": [
{
"id": "ancient_chestplate",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "super_diamond_chestplate" ],
[ "B", "ancient_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/ancient_helmet.json
================================================
{
"config": "Repair",
"results": [
{
"id": "ancient_helmet",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "ancient_helmet" ],
[ "B", "ancient_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/ancient_helmet_2.json
================================================
{
"config": "Repair",
"results": [
{
"id": "ancient_helmet",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "super_diamond_helmet" ],
[ "B", "ancient_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/ancient_leggings.json
================================================
{
"config": "Repair",
"results": [
{
"id": "ancient_leggings",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "ancient_leggings" ],
[ "B", "ancient_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/ancient_leggings_2.json
================================================
{
"config": "Repair",
"results": [
{
"id": "ancient_leggings",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "super_diamond_leggings" ],
[ "B", "ancient_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/bronze_axe.json
================================================
{
"config": "Repair",
"results": [
{
"id": "bronze_axe",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "bronze_axe" ],
[ "B", "bronze_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/bronze_chestplate.json
================================================
{
"config": "Repair",
"results": [
{
"id": "bronze_chestplate",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "bronze_chestplate" ],
[ "B", "bronze_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/bronze_helmet.json
================================================
{
"config": "Repair",
"results": [
{
"id": "bronze_helmet",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "bronze_helmet" ],
[ "B", "bronze_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/bronze_leggings.json
================================================
{
"config": "Repair",
"results": [
{
"id": "bronze_leggings",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "bronze_leggings" ],
[ "B", "bronze_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/bronze_pickaxe.json
================================================
{
"config": "Repair",
"results": [
{
"id": "bronze_pickaxe",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "bronze_pickaxe" ],
[ "B", "bronze_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/bronze_sword.json
================================================
{
"config": "Repair",
"results": [
{
"id": "bronze_sword",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "bronze_sword" ],
[ "B", "bronze_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/copper_axe.json
================================================
{
"config": "Repair",
"results": [
{
"id": "copper_axe",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "copper_axe" ],
[ "B", "copper_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/copper_chestplate.json
================================================
{
"config": "Repair",
"results": [
{
"id": "copper_chestplate",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "copper_chestplate" ],
[ "B", "copper_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/copper_helmet.json
================================================
{
"config": "Repair",
"results": [
{
"id": "copper_helmet",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "copper_helmet" ],
[ "B", "copper_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/copper_leggings.json
================================================
{
"config": "Repair",
"results": [
{
"id": "copper_leggings",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "copper_leggings" ],
[ "B", "copper_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/copper_pickaxe.json
================================================
{
"config": "Repair",
"results": [
{
"id": "copper_pickaxe",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "copper_pickaxe" ],
[ "B", "copper_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/copper_sword.json
================================================
{
"config": "Repair",
"results": [
{
"id": "copper_sword",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "copper_sword" ],
[ "B", "copper_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/diamond_axe.json
================================================
{
"config": "Repair",
"results": [
{
"id": "diamond_axe",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "diamond_axe" ],
[ "B", "diamond" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/diamond_chestplate.json
================================================
{
"config": "Repair",
"results": [
{
"id": "diamond_chestplate",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "diamond_chestplate" ],
[ "B", "diamond" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/diamond_helmet.json
================================================
{
"config": "Repair",
"results": [
{
"id": "diamond_helmet",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "diamond_helmet" ],
[ "B", "diamond" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/diamond_leggings.json
================================================
{
"config": "Repair",
"results": [
{
"id": "diamond_leggings",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "diamond_leggings" ],
[ "B", "diamond" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/diamond_pickaxe.json
================================================
{
"config": "Repair",
"results": [
{
"id": "diamond_pickaxe",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "diamond_pickaxe" ],
[ "B", "diamond" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/diamond_sword.json
================================================
{
"config": "Repair",
"results": [
{
"id": "diamond_sword",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "diamond_sword" ],
[ "B", "diamond" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/golden_axe.json
================================================
{
"config": "Repair",
"results": [
{
"id": "golden_axe",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "golden_axe" ],
[ "B", "gold_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/golden_chestplate.json
================================================
{
"config": "Repair",
"results": [
{
"id": "golden_chestplate",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "golden_chestplate" ],
[ "B", "gold_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/golden_helmet.json
================================================
{
"config": "Repair",
"results": [
{
"id": "golden_helmet",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "golden_helmet" ],
[ "B", "gold_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/golden_leggings.json
================================================
{
"config": "Repair",
"results": [
{
"id": "golden_leggings",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "golden_leggings" ],
[ "B", "gold_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/golden_pickaxe.json
================================================
{
"config": "Repair",
"results": [
{
"id": "golden_pickaxe",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "golden_pickaxe" ],
[ "B", "gold_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/golden_sword.json
================================================
{
"config": "Repair",
"results": [
{
"id": "golden_sword",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "golden_sword" ],
[ "B", "gold_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/iron_axe.json
================================================
{
"config": "Repair",
"results": [
{
"id": "iron_axe",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "iron_axe" ],
[ "B", "iron_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/iron_chestplate.json
================================================
{
"config": "Repair",
"results": [
{
"id": "iron_chestplate",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "iron_chestplate" ],
[ "B", "iron_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/iron_helmet.json
================================================
{
"config": "Repair",
"results": [
{
"id": "iron_helmet",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "iron_helmet" ],
[ "B", "iron_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/iron_leggings.json
================================================
{
"config": "Repair",
"results": [
{
"id": "iron_leggings",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "iron_leggings" ],
[ "B", "iron_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/iron_pickaxe.json
================================================
{
"config": "Repair",
"results": [
{
"id": "iron_pickaxe",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "iron_pickaxe" ],
[ "B", "iron_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/iron_sword.json
================================================
{
"config": "Repair",
"results": [
{
"id": "iron_sword",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "iron_sword" ],
[ "B", "iron_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/lead_axe.json
================================================
{
"config": "Repair",
"results": [
{
"id": "lead_axe",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "lead_axe" ],
[ "B", "lead_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/lead_chestplate.json
================================================
{
"config": "Repair",
"results": [
{
"id": "lead_chestplate",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "lead_chestplate" ],
[ "B", "lead_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/lead_helmet.json
================================================
{
"config": "Repair",
"results": [
{
"id": "lead_helmet",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "lead_helmet" ],
[ "B", "lead_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/lead_leggings.json
================================================
{
"config": "Repair",
"results": [
{
"id": "lead_leggings",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "lead_leggings" ],
[ "B", "lead_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/lead_pickaxe.json
================================================
{
"config": "Repair",
"results": [
{
"id": "lead_pickaxe",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "lead_pickaxe" ],
[ "B", "lead_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/lead_sword.json
================================================
{
"config": "Repair",
"results": [
{
"id": "lead_sword",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "lead_sword" ],
[ "B", "lead_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/leather_chestplate.json
================================================
{
"config": "Repair",
"results": [
{
"id": "leather_chestplate",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "leather_chestplate" ],
[ "B", "leather" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/leather_helmet.json
================================================
{
"config": "Repair",
"results": [
{
"id": "leather_helmet",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "leather_helmet" ],
[ "B", "leather" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/leather_leggings.json
================================================
{
"config": "Repair",
"results": [
{
"id": "leather_leggings",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "leather_leggings" ],
[ "B", "leather" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/nether_axe.json
================================================
{
"config": "Repair",
"results": [
{
"id": "nether_axe",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "nether_axe" ],
[ "B", "netherite_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/nether_axe_2.json
================================================
{
"config": "Repair",
"results": [
{
"id": "nether_axe",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "diamond_axe" ],
[ "B", "netherite_ingot" ]
],
"exData": { "repairRate": 0.15 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/nether_chestplate.json
================================================
{
"config": "Repair",
"results": [
{
"id": "nether_chestplate",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "nether_chestplate" ],
[ "B", "netherite_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/nether_chestplate_2.json
================================================
{
"config": "Repair",
"results": [
{
"id": "nether_chestplate",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "diamond_chestplate" ],
[ "B", "netherite_ingot" ]
],
"exData": { "repairRate": 0.15 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/nether_helmet.json
================================================
{
"config": "Repair",
"results": [
{
"id": "nether_helmet",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "nether_helmet" ],
[ "B", "netherite_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/nether_helmet_2.json
================================================
{
"config": "Repair",
"results": [
{
"id": "nether_helmet",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "diamond_helmet" ],
[ "B", "netherite_ingot" ]
],
"exData": { "repairRate": 0.15 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/nether_helmet_3.json
================================================
{
"config": "Repair",
"results": [
{
"id": "nether_helmet",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "diamond_helmet" ],
[ "B", "netherite_ingot" ]
],
"exData": { "repairRate": 0.15 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/nether_leggings.json
================================================
{
"config": "Repair",
"results": [
{
"id": "nether_leggings",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "nether_leggings" ],
[ "B", "netherite_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/nether_leggings_2.json
================================================
{
"config": "Repair",
"results": [
{
"id": "nether_leggings",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "diamond_leggings" ],
[ "B", "netherite_ingot" ]
],
"exData": { "repairRate": 0.15 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/nether_pickaxe.json
================================================
{
"config": "Repair",
"results": [
{
"id": "nether_pickaxe",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "nether_pickaxe" ],
[ "B", "netherite_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/nether_pickaxe_2.json
================================================
{
"config": "Repair",
"results": [
{
"id": "nether_pickaxe",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "diamond_pickaxe" ],
[ "B", "netherite_ingot" ]
],
"exData": { "repairRate": 0.15 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/nether_sword.json
================================================
{
"config": "Repair",
"results": [
{
"id": "nether_sword",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "nether_sword" ],
[ "B", "netherite_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/nether_sword_2.json
================================================
{
"config": "Repair",
"results": [
{
"id": "nether_sword",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "diamond_sword" ],
[ "B", "netherite_ingot" ]
],
"exData": { "repairRate": 0.15 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/silver_axe.json
================================================
{
"config": "Repair",
"results": [
{
"id": "silver_axe",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "silver_axe" ],
[ "B", "silver_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/silver_chestplate.json
================================================
{
"config": "Repair",
"results": [
{
"id": "silver_chestplate",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "silver_chestplate" ],
[ "B", "silver_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/silver_helmet.json
================================================
{
"config": "Repair",
"results": [
{
"id": "silver_helmet",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "silver_helmet" ],
[ "B", "silver_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/silver_leggings.json
================================================
{
"config": "Repair",
"results": [
{
"id": "silver_leggings",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "silver_leggings" ],
[ "B", "silver_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/silver_pickaxe.json
================================================
{
"config": "Repair",
"results": [
{
"id": "silver_pickaxe",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "silver_pickaxe" ],
[ "B", "silver_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/silver_sword.json
================================================
{
"config": "Repair",
"results": [
{
"id": "silver_sword",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "silver_sword" ],
[ "B", "silver_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/steel_axe.json
================================================
{
"config": "Repair",
"results": [
{
"id": "steel_axe",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "steel_axe" ],
[ "B", "steel_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/steel_chestplate.json
================================================
{
"config": "Repair",
"results": [
{
"id": "steel_chestplate",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "steel_chestplate" ],
[ "B", "steel_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/steel_helmet.json
================================================
{
"config": "Repair",
"results": [
{
"id": "steel_helmet",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "steel_helmet" ],
[ "B", "steel_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/steel_leggings.json
================================================
{
"config": "Repair",
"results": [
{
"id": "steel_leggings",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "steel_leggings" ],
[ "B", "steel_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/steel_pickaxe.json
================================================
{
"config": "Repair",
"results": [
{
"id": "steel_pickaxe",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "steel_pickaxe" ],
[ "B", "steel_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/steel_sword.json
================================================
{
"config": "Repair",
"results": [
{
"id": "steel_sword",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "steel_sword" ],
[ "B", "steel_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/stone_axe.json
================================================
{
"config": "Repair",
"results": [
{
"id": "stone_axe",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "stone_axe" ],
[ "B", "cobblestone" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/stone_hoe.json
================================================
{
"config": "Repair",
"results": [
{
"id": "stone_hoe",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "stone_hoe" ],
[ "B", "cobblestone" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/stone_pickaxe.json
================================================
{
"config": "Repair",
"results": [
{
"id": "stone_pickaxe",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "stone_pickaxe" ],
[ "B", "cobblestone" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/stone_sword.json
================================================
{
"config": "Repair",
"results": [
{
"id": "stone_sword",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "stone_sword" ],
[ "B", "cobblestone" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/super_bronze_sword.json
================================================
{
"config": "Repair",
"results": [
{
"id": "super_bronze_sword",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "super_bronze_sword" ],
[ "B", "bronze_ingot" ]
],
"exData": { "repairRate": 0.15 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/super_copper_sword.json
================================================
{
"config": "Repair",
"results": [
{
"id": "super_copper_sword",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "super_copper_sword" ],
[ "B", "copper_ingot" ]
],
"exData": { "repairRate": 0.15 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/super_diamond_sword.json
================================================
{
"config": "Repair",
"results": [
{
"id": "super_diamond_sword",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "super_diamond_sword" ],
[ "B", "diamond" ]
],
"exData": { "repairRate": 0.15 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/super_golden_sword.json
================================================
{
"config": "Repair",
"results": [
{
"id": "super_golden_sword",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "super_golden_sword" ],
[ "B", "gold_ingot" ]
],
"exData": { "repairRate": 0.15 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/super_iron_sword.json
================================================
{
"config": "Repair",
"results": [
{
"id": "super_iron_sword",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "super_iron_sword" ],
[ "B", "iron_ingot" ]
],
"exData": { "repairRate": 0.15 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/super_lead_sword.json
================================================
{
"config": "Repair",
"results": [
{
"id": "super_lead_sword",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "super_lead_sword" ],
[ "B", "lead_ingot" ]
],
"exData": { "repairRate": 0.15 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/super_nether_sword.json
================================================
{
"config": "Repair",
"results": [
{
"id": "super_nether_sword",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "super_nether_sword" ],
[ "B", "netherite_ingot" ]
],
"exData": { "repairRate": 0.15 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/super_nether_sword_2.json
================================================
{
"config": "Repair",
"results": [
{
"id": "super_nether_sword",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "super_diamond_sword" ],
[ "B", "netherite_ingot" ]
],
"exData": { "repairRate": 0.15 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/super_silver_sword.json
================================================
{
"config": "Repair",
"results": [
{
"id": "super_silver_sword",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "super_silver_sword" ],
[ "B", "silver_ingot" ]
],
"exData": { "repairRate": 0.15 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/super_steel_sword.json
================================================
{
"config": "Repair",
"results": [
{
"id": "super_steel_sword",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "super_steel_sword" ],
[ "B", "steel_ingot" ]
],
"exData": { "repairRate": 0.15 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/super_tin_sword.json
================================================
{
"config": "Repair",
"results": [
{
"id": "super_tin_sword",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "super_tin_sword" ],
[ "B", "tin_ingot" ]
],
"exData": { "repairRate": 0.15 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/tin_axe.json
================================================
{
"config": "Repair",
"results": [
{
"id": "tin_axe",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "tin_axe" ],
[ "B", "tin_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/tin_chestplate.json
================================================
{
"config": "Repair",
"results": [
{
"id": "tin_chestplate",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "tin_chestplate" ],
[ "B", "tin_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/tin_helmet.json
================================================
{
"config": "Repair",
"results": [
{
"id": "tin_helmet",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "tin_helmet" ],
[ "B", "tin_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/tin_leggings.json
================================================
{
"config": "Repair",
"results": [
{
"id": "tin_leggings",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "tin_leggings" ],
[ "B", "tin_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/tin_pickaxe.json
================================================
{
"config": "Repair",
"results": [
{
"id": "tin_pickaxe",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "tin_pickaxe" ],
[ "B", "tin_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/repair/tin_sword.json
================================================
{
"config": "Repair",
"results": [
{
"id": "tin_sword",
"stackSize": 1
}
],
"pattern": [ "AB" ],
"elements": [
[ "A", "tin_sword" ],
[ "B", "tin_ingot" ]
],
"exData": { "repairRate": 0.25 },
"importantElements": [ "A" ]
}
================================================
FILE: recipes/smelt/baked_potato.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "baked_potato",
"stackSize": 1
}
],
"elements": [ [ "A", "potato" ] ],
"exData": { "time": 40 }
}
================================================
FILE: recipes/smelt/charcoal.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "charcoal",
"stackSize": 1
}
],
"elements": [ [ "A", "wood_oak" ] ],
"exData": { "time": 40 }
}
================================================
FILE: recipes/smelt/charcoal_10.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "charcoal",
"stackSize": 1
}
],
"elements": [ [ "A", "wood_stripped_oak" ] ],
"exData": { "time": 40 }
}
================================================
FILE: recipes/smelt/charcoal_11.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "charcoal",
"stackSize": 1
}
],
"elements": [ [ "A", "wood_stripped_spruce" ] ],
"exData": { "time": 40 }
}
================================================
FILE: recipes/smelt/charcoal_12.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "charcoal",
"stackSize": 1
}
],
"elements": [ [ "A", "wood_stripped_birch" ] ],
"exData": { "time": 40 }
}
================================================
FILE: recipes/smelt/charcoal_13.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "charcoal",
"stackSize": 1
}
],
"elements": [ [ "A", "wood_stripped_jungle" ] ],
"exData": { "time": 40 }
}
================================================
FILE: recipes/smelt/charcoal_14.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "charcoal",
"stackSize": 1
}
],
"elements": [ [ "A", "wood_stripped_acacia" ] ],
"exData": { "time": 40 }
}
================================================
FILE: recipes/smelt/charcoal_15.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "charcoal",
"stackSize": 1
}
],
"elements": [ [ "A", "wood_stripped_dark_oak" ] ],
"exData": { "time": 40 }
}
================================================
FILE: recipes/smelt/charcoal_16.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "charcoal",
"stackSize": 1
}
],
"elements": [ [ "A", "wood_stripped_palm" ] ],
"exData": { "time": 40 }
}
================================================
FILE: recipes/smelt/charcoal_17.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "charcoal",
"stackSize": 1
}
],
"elements": [ [ "A", "wood_stripped_volcano" ] ],
"exData": { "time": 40 }
}
================================================
FILE: recipes/smelt/charcoal_18.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "charcoal",
"stackSize": 1
}
],
"elements": [ [ "A", "wood_stripped_tainted" ] ],
"exData": { "time": 40 }
}
================================================
FILE: recipes/smelt/charcoal_2.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "charcoal",
"stackSize": 1
}
],
"elements": [ [ "A", "wood_spruce" ] ],
"exData": { "time": 40 }
}
================================================
FILE: recipes/smelt/charcoal_3.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "charcoal",
"stackSize": 1
}
],
"elements": [ [ "A", "wood_birch" ] ],
"exData": { "time": 40 }
}
================================================
FILE: recipes/smelt/charcoal_4.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "charcoal",
"stackSize": 1
}
],
"elements": [ [ "A", "wood_jungle" ] ],
"exData": { "time": 40 }
}
================================================
FILE: recipes/smelt/charcoal_5.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "charcoal",
"stackSize": 1
}
],
"elements": [ [ "A", "wood_acacia" ] ],
"exData": { "time": 40 }
}
================================================
FILE: recipes/smelt/charcoal_6.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "charcoal",
"stackSize": 1
}
],
"elements": [ [ "A", "wood_palm" ] ],
"exData": { "time": 40 }
}
================================================
FILE: recipes/smelt/charcoal_7.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "charcoal",
"stackSize": 1
}
],
"elements": [ [ "A", "wood_volcano" ] ],
"exData": { "time": 40 }
}
================================================
FILE: recipes/smelt/charcoal_8.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "charcoal",
"stackSize": 1
}
],
"elements": [ [ "A", "wood_tainted" ] ],
"exData": { "time": 40 }
}
================================================
FILE: recipes/smelt/charcoal_9.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "charcoal",
"stackSize": 1
}
],
"elements": [ [ "A", "wood_dark_oak" ] ],
"exData": { "time": 40 }
}
================================================
FILE: recipes/smelt/coal.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "coal",
"stackSize": 1
}
],
"elements": [ [ "A", "ore_coal" ] ],
"exData": { "time": 40 }
}
================================================
FILE: recipes/smelt/cooked_chicken.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "cooked_chicken",
"stackSize": 1
}
],
"elements": [ [ "A", "raw_chicken" ] ],
"exData": { "time": 40 }
}
================================================
FILE: recipes/smelt/cooked_cod.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "cooked_cod",
"stackSize": 1
}
],
"elements": [ [ "A", "raw_cod" ] ],
"exData": { "time": 40 }
}
================================================
FILE: recipes/smelt/cooked_mutton.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "cooked_mutton",
"stackSize": 1
}
],
"elements": [ [ "A", "raw_mutton" ] ],
"exData": { "time": 40 }
}
================================================
FILE: recipes/smelt/cooked_porkchop.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "cooked_porkchop",
"stackSize": 1
}
],
"elements": [ [ "A", "raw_porkchop" ] ],
"exData": { "time": 40 }
}
================================================
FILE: recipes/smelt/cooked_rabbit.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "cooked_rabbit",
"stackSize": 1
}
],
"elements": [ [ "A", "raw_rabbit" ] ],
"exData": { "time": 40 }
}
================================================
FILE: recipes/smelt/cooked_salmon.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "cooked_salmon",
"stackSize": 1
}
],
"elements": [ [ "A", "raw_salmon" ] ],
"exData": { "time": 40 }
}
================================================
FILE: recipes/smelt/copper_ingot.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "copper_ingot",
"stackSize": 1
}
],
"elements": [ [ "A", "ore_copper", 3 ] ],
"exData": { "time": 40 }
}
================================================
FILE: recipes/smelt/diamond.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "diamond",
"stackSize": 1
}
],
"elements": [ [ "A", "ore_diamond" ] ],
"exData": { "time": 40 }
}
================================================
FILE: recipes/smelt/dried_kelp.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "dried_kelp",
"stackSize": 1
}
],
"elements": [ [ "A", "kelp" ] ],
"exData": { "time": 20 }
}
================================================
FILE: recipes/smelt/dye_green.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "dye_green",
"stackSize": 1
}
],
"elements": [ [ "A", "sapling_cactus" ] ],
"exData": { "time": 40 }
}
================================================
FILE: recipes/smelt/emerald.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "emerald",
"stackSize": 1
}
],
"elements": [ [ "A", "ore_emerald" ] ],
"exData": { "time": 40 }
}
================================================
FILE: recipes/smelt/glass.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "glass",
"stackSize": 1
}
],
"elements": [ [ "A", "sand" ] ],
"exData": { "time": 10 }
}
================================================
FILE: recipes/smelt/glass_2.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "glass",
"stackSize": 1
}
],
"elements": [ [ "A", "red_sand" ] ],
"exData": { "time": 10 }
}
================================================
FILE: recipes/smelt/glass_3.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "glass",
"stackSize": 1
}
],
"elements": [ [ "A", "prismarine_mud" ] ],
"exData": { "time": 160 }
}
================================================
FILE: recipes/smelt/gold_ingot.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "gold_ingot",
"stackSize": 1
}
],
"elements": [ [ "A", "ore_gold", 3 ] ],
"exData": { "time": 40 }
}
================================================
FILE: recipes/smelt/iron_ingot.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "iron_ingot",
"stackSize": 1
}
],
"elements": [ [ "A", "ore_iron", 3 ] ],
"exData": { "time": 40 }
}
================================================
FILE: recipes/smelt/lapis_lazuli.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "lapis_lazuli",
"stackSize": 1
}
],
"elements": [ [ "A", "ore_lapis" ] ],
"exData": { "time": 40 }
}
================================================
FILE: recipes/smelt/lead_ingot.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "lead_ingot",
"stackSize": 1
}
],
"elements": [ [ "A", "ore_lead", 3 ] ],
"exData": { "time": 40 }
}
================================================
FILE: recipes/smelt/nether_brick.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "nether_brick",
"stackSize": 1
}
],
"elements": [ [ "A", "netherrack" ] ],
"exData": { "time": 20 }
}
================================================
FILE: recipes/smelt/netherite_scrap.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "netherite_scrap",
"stackSize": 1
}
],
"elements": [ [ "A", "ore_ancient_debris", 3 ] ],
"exData": { "time": 40 }
}
================================================
FILE: recipes/smelt/popped_chorus_fruits.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "popped_chorus_fruits",
"stackSize": 1
}
],
"elements": [ [ "A", "chorus_fruit" ] ],
"exData": { "time": 40 }
}
================================================
FILE: recipes/smelt/quartz.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "quartz",
"stackSize": 1
}
],
"elements": [ [ "A", "ore_nether_quartz" ] ],
"exData": { "time": 20 }
}
================================================
FILE: recipes/smelt/red_brick.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "red_brick",
"stackSize": 1
}
],
"elements": [ [ "A", "clay" ] ],
"exData": { "time": 10 }
}
================================================
FILE: recipes/smelt/red_sand_smooth.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "red_sand_smooth",
"stackSize": 1
}
],
"elements": [ [ "A", "red_sand_stone" ] ],
"exData": { "time": 10 }
}
================================================
FILE: recipes/smelt/redstone.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "redstone",
"stackSize": 1
}
],
"elements": [ [ "A", "ore_redstone" ] ],
"exData": { "time": 40 }
}
================================================
FILE: recipes/smelt/sandstone_smooth.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "sandstone_smooth",
"stackSize": 1
}
],
"elements": [ [ "A", "sandstone" ] ],
"exData": { "time": 10 }
}
================================================
FILE: recipes/smelt/silver_ingot.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "silver_ingot",
"stackSize": 1
}
],
"elements": [ [ "A", "ore_silver", 3 ] ],
"exData": { "time": 40 }
}
================================================
FILE: recipes/smelt/sponge.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "sponge",
"stackSize": 1
}
],
"elements": [ [ "A", "wet_sponge" ] ],
"exData": { "time": 40 }
}
================================================
FILE: recipes/smelt/steak.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "steak",
"stackSize": 1
}
],
"elements": [ [ "A", "raw_beef" ] ],
"exData": { "time": 40 }
}
================================================
FILE: recipes/smelt/steel_ingot.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "steel_ingot",
"stackSize": 1
}
],
"elements": [ [ "A", "iron_ingot", 2 ] ],
"exData": { "time": 80 }
}
================================================
FILE: recipes/smelt/stone.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "stone",
"stackSize": 1
}
],
"elements": [ [ "A", "cobblestone" ] ],
"exData": { "time": 10 }
}
================================================
FILE: recipes/smelt/stone_brick_cracked.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "stone_brick_cracked",
"stackSize": 1
}
],
"elements": [ [ "A", "stone_brick" ] ],
"exData": { "time": 20 }
}
================================================
FILE: recipes/smelt/terracotta_pink.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "terracotta_pink",
"stackSize": 1
}
],
"elements": [ [ "A", "clay_block" ] ],
"exData": { "time": 20 }
}
================================================
FILE: recipes/smelt/tin_ingot.json
================================================
{
"config": "Smelt",
"pattern": [ "A" ],
"results": [
{
"id": "tin_ingot",
"stackSize": 1
}
],
"elements": [ [ "A", "ore_tin", 3 ] ],
"exData": { "time": 40 }
}
================================================
FILE: record/RecordData.lua
================================================
---@class TC.RecordData
local RecordData = class("RecordData")
local SNOW_QUEEN_ID = Reg.NpcID("snow_queen")
local HELL_DESTROYER_ID = Reg.NpcID("worm_head")
local CRISON_EYE_ID = Reg.NpcID("crison_eye")
local DUNGEON_EATER_ID = Reg.NpcID("dungeon_eater_head")
local s_RecordData = nil
---@return TC.RecordData
function RecordData.getInstance()
if s_RecordData == nil then
s_RecordData = RecordData.new()
end
return s_RecordData
end
function RecordData:__init()
self.hasSnowQueen = false
self.hasNetherDestroyer = false
self.hasCrisonEye = false
self.hasDungeonEater = false
self.curBossID = -1
end
function RecordData:_updateNpc()
self.hasSnowQueen = false
self.hasNetherDestroyer = false
self.hasCrisonEye = false
self.hasDungeonEater = false
self.curBossID = -1
local npcs = NpcUtils.GetAllEntities()
---@param npc Npc
for _, npc in each(npcs) do
local id = npc.id
if id == SNOW_QUEEN_ID then
self.hasSnowQueen = true
self.curBossID = id
elseif id == HELL_DESTROYER_ID then
self.hasNetherDestroyer = true
self.curBossID = id
elseif id == CRISON_EYE_ID then
self.hasCrisonEye = true
self.curBossID = id
elseif id == DUNGEON_EATER_ID then
self.hasDungeonEater = true
self.curBossID = id
end
end
end
function RecordData:update()
self:_updateNpc()
end
return RecordData
================================================
FILE: settings/Settings.lua
================================================
---@class TC.Settings
local Settings = class("Settings")
local SettingsData = require("SettingsData")
local SETTING_FILE = "tc_settings.json"
local s_instance
---@return TC.Settings
function Settings.getInstance()
if s_instance == nil then
s_instance = Settings.new()
end
return s_instance
end
function Settings:__init()
self.uiConfig = {
{
name = "常规",
elements = {
-- TODO:有BUG,后面再搞
--{
-- name = "地图显示比例", type = "Slider",
-- maxValue = 15, minValue = 0,
-- valueStep = 1,
-- getter = function() return (MiscUtils.GetMapDisplayScale() - 0.5) * 10 end,
-- setter = function(value) MiscUtils.SetMapDisplayScale(value * 0.1 + 0.5) end,
--},
{
name = "音乐音量", type = "Slider",
maxValue = 100, minValue = 0,
getter = function() return SettingsData.musicVolume end,
setter = function(value) SettingsData.musicVolume = value end,
},
{
name = "音效音量", type = "Slider",
maxValue = 100, minValue = 0,
getter = function() return SettingsData.soundVolume end,
setter = function(value) SettingsData.soundVolume = value end,
},
{
name = "显示音乐信息", type = "Boolean",
getter = function() return SettingsData.showMusicInfo end,
setter = function(value) SettingsData.showMusicInfo = value end,
},
}
},
{
name = "开发者调试",
elements = {
{
name = "移动端操作模拟", type = "Boolean",
getter = function() return SettingsData.isMobileOperation end,
setter = function(value)
if App.isPC then
SettingsData.isMobileOperation = value
end
end,
},
{
name = "显示调试信息", type = "Boolean",
getter = function() return SettingsData.isShowDebugInfo end,
setter = function(value) SettingsData.isShowDebugInfo = value end,
},
{
name = "显示GUI布局", type = "Boolean",
getter = function() return SettingsData.isShowUIDebug end,
setter = function(value) SettingsData.isShowUIDebug = value end,
},
--{
-- name = "TEST VALUE", type = "Slider",
-- maxValue = 100, minValue = 0,
-- getter = nil,
-- setter = nil,
--},
--{
-- name = "TEST BOOL 3", type = "Boolean",
-- getter = nil,
-- setter = nil,
--},
--{
-- name = "TEST BOOL 4", type = "Boolean",
-- getter = nil,
-- setter = nil,
--},
--{
-- name = "TEST VALUE 2", type = "Slider",
-- maxValue = 100, minValue = 0,
-- getter = nil,
-- setter = nil,
--},
--{
-- name = "TEST BOOL 5", type = "Boolean",
-- getter = nil,
-- setter = nil,
--},
--{
-- name = "TEST BOOL 6", type = "Boolean",
-- getter = nil,
-- setter = nil,
--},
--{
-- name = "TEST BOOL 7", type = "Boolean",
-- getter = nil,
-- setter = nil,
--},
}
}
}
end
function Settings.loadData()
local path = Path.join(App.persistentDataPath, SETTING_FILE)
if File.isPathExist(path) then
local jsonStr = File.readAsString(path)
local data = JsonUtil.fromJson(jsonStr)
local function _readProperty(name)
if data[name] ~= nil then
SettingsData[name] = data[name]
end
end
for k, _ in pairs(SettingsData) do
_readProperty(k)
end
else
-- 默认值
SettingsData.isMobileOperation = App.isMobile and true or false
end
print("Current Settings Data:", SettingsData)
end
function Settings.saveData()
local path = Path.join(App.persistentDataPath, SETTING_FILE)
local jsonStr = JsonUtil.toJson(SettingsData)
File.saveString(path, jsonStr)
print("Save Settings Data:", SettingsData)
end
return Settings
================================================
FILE: settings/SettingsData.lua
================================================
local SettingsData = {
isMobileOperation = false,
isShowDebugInfo = false,
isShowUIDebug = false,
soundVolume = 100,
musicVolume = 100,
showMusicInfo = true,
}
return SettingsData
================================================
FILE: skins/skin_22.json
================================================
{
"skin_22": {
"isFemale": true,
"name": "22",
"headTexture": "base/head.png",
"bodyTexture": "base/body.png",
"legTexture": "base/leg.png",
"hairTexture": "22/hair.png",
"clothTexture": "22/cloth.png",
"pantTexture": "22/pant.png",
"authors": [ "BlueYoshi" ]
}
}
================================================
FILE: skins/skin_33.json
================================================
{
"skin_33": {
"isFemale": true,
"name": "33",
"headTexture": "base\\head.png",
"bodyTexture": "base\\body.png",
"legTexture": "base\\leg.png",
"hairTexture": "33\\hair.png",
"clothTexture": "33\\cloth.png",
"pantTexture": "33\\pant.png",
"authors": [ "BlueYoshi" ]
}
}
================================================
FILE: skins/skin_my.json
================================================
{
"skin_my": {
"isFemale": true,
"headTexture": "base\\head.png",
"bodyTexture": "base\\body.png",
"legTexture": "base\\leg.png",
"hairTexture": "my\\hair.png",
"clothTexture": "my\\cloth.png",
"pantTexture": "my\\pant.png",
"authors": [ "BlueYoshi" ]
}
}
================================================
FILE: skins/skin_plin.json
================================================
{
"skin_plin": {
"isFemale": true,
"name": "Piglin",
"headTexture": "base\\head.png",
"bodyTexture": "base\\body.png",
"legTexture": "base\\leg.png",
"hairTexture": "plin\\hair.png",
"clothTexture": "plin\\cloth.png",
"pantTexture": "plin\\pant.png",
"authors": [ "BlueYoshi" ]
}
}
================================================
FILE: skins/skin_redust.json
================================================
{
"skin_redust": {
"isFemale": true,
"name": "Redust",
"headTexture": "base\\head.png",
"bodyTexture": "base\\body.png",
"legTexture": "base\\leg.png",
"hairTexture": "redust\\hair.png",
"clothTexture": "redust\\cloth.png",
"pantTexture": "redust\\pant.png",
"authors": [ "Redust" ]
}
}
================================================
FILE: skins/skin_steve.json
================================================
{
"skin_steve": {
"isFemale": false,
"name": "Steve",
"headTexture": "base2\\head.png",
"bodyTexture": "base2\\body.png",
"legTexture": "base2\\leg.png",
"hairTexture": "steve\\hair.png",
"clothTexture": "steve\\cloth.png",
"pantTexture": "steve\\pant.png",
"authors": [ "BlueYoshi" ]
}
}
================================================
FILE: skins/skin_ym.json
================================================
{
"skin_ym": {
"isFemale": true,
"name": "Red Hair",
"headTexture": "base\\head.png",
"bodyTexture": "base\\body.png",
"legTexture": "base\\leg.png",
"hairTexture": "ym\\hair.png",
"clothTexture": "ym\\cloth.png",
"pantTexture": "ym\\pant.png",
"authors": [ "BlueYoshi" ]
}
}
================================================
FILE: skins/skin_yy.json
================================================
{
"skin_yy": {
"isFemale": true,
"name": "White Hair",
"headTexture": "base\\head.png",
"bodyTexture": "base\\body.png",
"legTexture": "base\\leg.png",
"hairTexture": "yy\\hair.png",
"clothTexture": "yy\\cloth.png",
"pantTexture": "yy\\pant.png",
"authors": [ "BlueYoshi" ]
}
}
================================================
FILE: skins/skin_zk.json
================================================
{
"skin_zk": {
"isFemale": true,
"headTexture": "base\\head.png",
"bodyTexture": "base\\body.png",
"legTexture": "base\\leg.png",
"hairTexture": "zk\\hair.png",
"clothTexture": "zk\\cloth.png",
"pantTexture": "zk\\pant.png",
"authors": [ "BlueYoshi" ]
}
}
================================================
FILE: skins/xqz.json
================================================
{
"xqz": {
"isFemale": true,
"name": "Mr. Skirt",
"headTexture": "xqz\\head.png",
"bodyTexture": "xqz\\body.png",
"legTexture": "xqz\\leg.png",
"hairTexture": "xqz\\hair.png",
"clothTexture": "xqz\\cloth.png",
"pantTexture": "xqz\\pant.png",
"authors": [ "BlueYoshi" ]
}
}
================================================
FILE: sounds/README.txt
================================================
All sound comes from Minecraft, RPG Maker XP and Minecraft Working Gun Mod 1.12.2.
If you like Minecraft you can get more Minecraft sounds here:
https://o.xbottle.top/mcsounds/
================================================
FILE: spawns/aurora_palace.json
================================================
{
"walls": [
{
"id": "aurora_block"
}
],
"spawn": {
"mobSpeed": 150,
"maxMobSpawn": 6,
"mobs": [
{
"id": "snow_guardian",
"weight": 5
},
{
"id": "snow_guardian_archer",
"weight": 5
}
]
}
}
================================================
FILE: spawns/end_outpost.json
================================================
{
"walls": [
{
"id": "end_stone_brick"
},
{
"id": "purpur_block"
}
],
"spawn": {
"mobSpeed": 150,
"maxMobSpawn": 4,
"mobs": [
{
"id": "shulker",
"weight": 5
}
]
}
}
================================================
FILE: spawns/monument_ocean.json
================================================
{
"walls": [
{
"id": "prismarine"
}
],
"spawn": {
"mobSpeed": 20,
"maxMobSpawn": 10,
"mobs": [
{
"id": "guardian",
"weight": 5
}
]
}
}
================================================
FILE: textures/backgrounds/atlas_config.json
================================================
[
{
"name": "sky",
"path": "sky",
"size": 512
},
{
"name": "backgrounds",
"path": "layers",
"size": 2048
},
{
"name": "cave_backgrounds",
"path": "walls",
"size": 2048
}
]
================================================
FILE: trees/acacia/acacia.json
================================================
{
"tree": {
"acacia": {
"length": 6,
"baseTiles": [ "dirt", "coarse_dirt" ],
"leafs": [
"leaf.png",
"leaf_2.png",
"leaf_3.png",
"leaf_4.png",
"leaf_5.png",
"leaf_6.png"
],
"branches": [
[
"branch.png",
[ 68, 136 ],
[ 88, 118 ],
[ 211, 112 ]
],
[
"branch_2.png",
[ 51, 101 ],
[ 104, 113 ],
[ 226, 131 ],
[ 180, 80 ]
],
[
"branch_3.png",
[ 59, 118 ],
[ 84, 100 ],
[ 228, 112 ],
[ 206, 83 ]
]
],
"crowns": [
[
"crown.png",
[ 74, 146 ],
[ 80, 130 ],
[ 100, 100 ],
[ 193, 84 ],
[ 156, 146 ]
],
[
"crown_2.png",
[ 120, 138 ],
[ 188, 116 ],
[ 68, 96 ],
[ 216, 80 ],
[ 136, 58 ]
],
[
"crown_3.png",
[ 140, 140 ],
[ 60, 112 ],
[ 228, 113 ],
[ 183, 72 ],
[ 103, 40 ]
]
],
"woodId": "wood_acacia",
"saplingId": "sapling_acacia",
"fruits": []
}
},
"block": {
"log_acacia": {
"textureData": "stem.png",
"color": [ 85, 80, 72 ],
"subGroup": "LOG",
"placeCheck": "PLACE_TREE_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 620,
"treeId": "acacia",
"soundGroupId": "wood",
"particleColor": [ 255, 80, 76, 70 ]
}
}
}
================================================
FILE: trees/bare_oak/bare_oak.json
================================================
{
"tree": {
"bare_oak": {
"length": 2,
"baseTiles": [ "red_sand", "red_sand_stone" ],
"leafs": [],
"branches": [
[
"branch.png"
],
[
"branch_2.png"
],
[
"branch_3.png"
]
],
"crowns": [
[
"crown.png"
],
[
"crown_2.png"
],
[
"crown_3.png"
]
],
"woodId": "wood_oak",
"saplingId": "sapling_bare_oak",
"fruits": []
}
},
"block": {
"log_bare_oak": {
"textureData": "stem.png",
"color": [ 98, 78, 35 ],
"subGroup": "LOG",
"placeCheck": "PLACE_TREE_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 600,
"treeId": "bare_oak",
"soundGroupId": "wood",
"particleColor": [ 255, 98, 78, 35 ]
}
}
}
================================================
FILE: trees/birch/birch.json
================================================
{
"tree": {
"birch": {
"length": 7,
"baseTiles": [ "dirt", "coarse_dirt" ],
"leafs": [
"leaf.png",
"leaf_2.png",
"leaf_3.png",
"leaf_4.png",
"leaf_5.png",
"leaf_6.png"
],
"branches": [
[
"branch.png",
[ 68, 136 ],
[ 88, 118 ],
[ 211, 112 ]
],
[
"branch_2.png",
[ 51, 101 ],
[ 104, 113 ],
[ 226, 131 ],
[ 180, 80 ]
],
[
"branch_3.png",
[ 59, 118 ],
[ 84, 100 ],
[ 228, 112 ],
[ 206, 83 ]
]
],
"crowns": [
[
"crown.png",
[ 74, 146 ],
[ 80, 130 ],
[ 100, 100 ],
[ 193, 84 ],
[ 156, 146 ]
],
[
"crown_2.png",
[ 120, 138 ],
[ 188, 116 ],
[ 68, 96 ],
[ 216, 80 ],
[ 136, 58 ]
],
[
"crown_3.png",
[ 140, 140 ],
[ 60, 112 ],
[ 228, 113 ],
[ 183, 72 ],
[ 103, 40 ]
]
],
"woodId": "wood_birch",
"saplingId": "sapling_birch",
"fruits": []
}
},
"block": {
"log_birch": {
"textureData": "stem.png",
"color": [ 225, 225, 220 ],
"subGroup": "LOG",
"placeCheck": "PLACE_TREE_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 550,
"treeId": "birch",
"soundGroupId": "wood",
"particleColor": [ 255, 233, 233, 233 ]
}
}
}
================================================
FILE: trees/blue_mushroom/blue_mushroom.json
================================================
{
"tree": {
"blue_mushroom": {
"length": 3,
"baseTiles": [ "blue_mushroom_stem", "blue_mushroom_dirt" ],
"leafs": [],
"branches": [],
"crowns": [
[
"crown.png"
],
[
"crown.png"
],
[
"crown.png"
]
],
"saplingId": "blue_mushroom",
"fruits": [ "glowstone_dust" ]
}
},
"block": {
"log_blue_mushroom": {
"textureData": "stem.png",
"color": [ 150, 130, 77 ],
"subGroup": "LOG",
"placeCheck": "PLACE_TREE_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 600,
"treeId": "blue_mushroom",
"soundGroupId": "wood",
"particleColor": [ 255, 100, 120, 40 ],
"isLighting": true,
"lightColor": [ 16, 0, 0, 8 ],
"lightX": 0,
"lightY": 0,
"lightWi": 2,
"lightHi": 2
}
}
}
================================================
FILE: trees/cactus/cactus.json
================================================
{
"tree": {
"cactus": {
"length": 4,
"baseTiles": [ "sand", "sandstone" ],
"leafs": [],
"branches": [
[
"branch.png"
],
[
"branch_2.png"
],
[
"branch_3.png"
]
],
"crowns": [
[
"crown.png"
],
[
"crown_2.png"
],
[
"crown_3.png"
]
],
"woodId": "sapling_cactus",
"saplingId": "sapling_cactus",
"fruits": []
}
},
"block": {
"log_cactus": {
"textureData": "stem.png",
"color": [ 150, 120, 40 ],
"subGroup": "LOG",
"placeCheck": "PLACE_TREE_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 650,
"treeId": "cactus",
"soundGroupId": "wood",
"particleColor": [ 255, 166, 233, 166 ]
}
}
}
================================================
FILE: trees/dark_oak/dark_oak.json
================================================
{
"tree": {
"dark_oak": {
"length": 5,
"baseTiles": [ "dirt", "coarse_dirt", "flesh_dirt" ],
"leafs": [
"leaf.png",
"leaf_2.png",
"leaf_3.png",
"leaf_4.png",
"leaf_5.png",
"leaf_6.png"
],
"branches": [
[
"branch.png",
[ 68, 136 ],
[ 88, 118 ],
[ 211, 112 ]
],
[
"branch_2.png",
[ 51, 101 ],
[ 104, 113 ],
[ 226, 131 ],
[ 180, 80 ]
],
[
"branch_3.png",
[ 59, 118 ],
[ 84, 100 ],
[ 228, 112 ],
[ 206, 83 ]
]
],
"crowns": [
[
"crown.png",
[ 74, 146 ],
[ 80, 130 ],
[ 100, 100 ],
[ 193, 84 ],
[ 156, 146 ]
],
[
"crown_2.png",
[ 120, 138 ],
[ 188, 116 ],
[ 68, 96 ],
[ 216, 80 ],
[ 136, 58 ]
],
[
"crown_3.png",
[ 140, 140 ],
[ 60, 112 ],
[ 228, 113 ],
[ 183, 72 ],
[ 103, 40 ]
]
],
"woodId": "wood_dark_oak",
"saplingId": "sapling_dark_oak",
"fruits": [ "apple" ]
}
},
"block": {
"log_dark_oak": {
"textureData": "stem.png",
"color": [ 78, 61, 33 ],
"subGroup": "LOG",
"placeCheck": "PLACE_TREE_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 700,
"treeId": "dark_oak",
"soundGroupId": "wood",
"particleColor": [ 255, 50, 40, 20 ]
}
}
}
================================================
FILE: trees/jungle/jungle.json
================================================
{
"tree": {
"jungle": {
"length": 13,
"baseTiles": [ "dirt", "coarse_dirt" ],
"leafs": [
"leaf.png",
"leaf_2.png",
"leaf_3.png",
"leaf_4.png",
"leaf_5.png",
"leaf_6.png"
],
"branches": [
[
"branch.png",
[ 68, 136 ],
[ 88, 118 ],
[ 211, 112 ]
],
[
"branch_2.png",
[ 51, 101 ],
[ 104, 113 ],
[ 226, 131 ],
[ 180, 80 ]
],
[
"branch_3.png",
[ 59, 118 ],
[ 84, 100 ],
[ 228, 112 ],
[ 206, 83 ]
]
],
"crowns": [
[
"crown.png",
[ 74, 146 ],
[ 80, 130 ],
[ 100, 100 ],
[ 193, 84 ],
[ 156, 146 ]
],
[
"crown_2.png",
[ 120, 138 ],
[ 188, 116 ],
[ 68, 96 ],
[ 216, 80 ],
[ 136, 58 ]
],
[
"crown_3.png",
[ 140, 140 ],
[ 60, 112 ],
[ 228, 113 ],
[ 183, 72 ],
[ 103, 40 ]
]
],
"woodId": "wood_jungle",
"saplingId": "sapling_jungle",
"fruits": [ "cocoa_bean" ]
}
},
"block": {
"log_jungle": {
"textureData": "stem.png",
"color": [ 102, 66, 55 ],
"subGroup": "LOG",
"placeCheck": "PLACE_TREE_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 660,
"treeId": "jungle",
"soundGroupId": "wood",
"particleColor": [ 255, 130, 100, 80 ]
}
}
}
================================================
FILE: trees/oak/oak.json
================================================
{
"tree": {
"oak": {
"length": 7,
"baseTiles": [ "dirt", "coarse_dirt" ],
"leafs": [
"leaf.png",
"leaf_2.png",
"leaf_3.png",
"leaf_4.png",
"leaf_5.png",
"leaf_6.png"
],
"branches": [
[
"branch.png",
[ 68, 136 ],
[ 88, 118 ],
[ 211, 112 ]
],
[
"branch_2.png",
[ 51, 101 ],
[ 104, 113 ],
[ 226, 131 ],
[ 180, 80 ]
],
[
"branch_3.png",
[ 59, 118 ],
[ 84, 100 ],
[ 228, 112 ],
[ 206, 83 ]
]
],
"crowns": [
[
"crown.png",
[ 74, 146 ],
[ 80, 130 ],
[ 100, 100 ],
[ 193, 84 ],
[ 156, 146 ]
],
[
"crown_2.png",
[ 120, 138 ],
[ 188, 116 ],
[ 68, 96 ],
[ 216, 80 ],
[ 136, 58 ]
],
[
"crown_3.png",
[ 140, 140 ],
[ 60, 112 ],
[ 228, 113 ],
[ 183, 72 ],
[ 103, 40 ]
]
],
"woodId": "wood_oak",
"saplingId": "sapling_oak",
"fruits": [ "apple" ]
}
},
"block": {
"log_oak": {
"textureData": "stem.png",
"color": [ 110, 100, 48 ],
"subGroup": "LOG",
"placeCheck": "PLACE_TREE_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 600,
"treeId": "oak",
"soundGroupId": "wood",
"particleColor": [ 255, 100, 100, 40 ]
}
}
}
================================================
FILE: trees/palm/palm.json
================================================
{
"tree": {
"palm": {
"length": 10,
"baseTiles": [ "sand" ],
"leafs": [],
"branches": [],
"crowns": [
[
"crown.png"
],
[
"crown_2.png"
],
[
"crown_3.png"
]
],
"woodId": "wood_palm",
"saplingId": "sapling_palm",
"fruits": []
}
},
"block": {
"log_palm": {
"textureData": "stem.png",
"color": [ 150, 130, 77 ],
"subGroup": "LOG",
"placeCheck": "PLACE_TREE_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 600,
"treeId": "palm",
"soundGroupId": "wood",
"particleColor": [ 255, 100, 120, 40 ]
}
}
}
================================================
FILE: trees/spruce/spruce.json
================================================
{
"tree": {
"spruce": {
"length": 10,
"baseTiles": [ "dirt", "coarse_dirt", "snow", "snow_soft" ],
"leafs": [
"leaf.png",
"leaf_2.png",
"leaf_3.png",
"leaf_4.png",
"leaf_5.png",
"leaf_6.png"
],
"branches": [
[
"branch.png",
[ 68, 136 ],
[ 88, 118 ],
[ 211, 112 ]
],
[
"branch_2.png",
[ 51, 101 ],
[ 104, 113 ],
[ 226, 131 ],
[ 180, 80 ]
],
[
"branch_3.png",
[ 59, 118 ],
[ 84, 100 ],
[ 228, 112 ],
[ 206, 83 ]
]
],
"crowns": [
[
"crown.png",
[ 74, 146 ],
[ 80, 130 ],
[ 100, 100 ],
[ 193, 84 ],
[ 156, 146 ]
],
[
"crown_2.png",
[ 120, 138 ],
[ 188, 116 ],
[ 68, 96 ],
[ 216, 80 ],
[ 136, 58 ]
],
[
"crown_3.png",
[ 140, 140 ],
[ 60, 112 ],
[ 228, 113 ],
[ 183, 72 ],
[ 103, 40 ]
]
],
"woodId": "wood_spruce",
"saplingId": "sapling_spruce",
"fruits": []
}
},
"block": {
"log_spruce": {
"textureData": "stem.png",
"color": [ 80, 60, 40 ],
"subGroup": "LOG",
"placeCheck": "PLACE_TREE_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 630,
"treeId": "spruce",
"soundGroupId": "wood",
"particleColor": [ 255, 80, 60, 40 ]
}
}
}
================================================
FILE: trees/tainted/tainted.json
================================================
{
"tree": {
"tainted": {
"length": 6,
"baseTiles": [ "tainted_dirt" ],
"leafs": [
"leaf.png",
"leaf_2.png",
"leaf_3.png",
"leaf_4.png",
"leaf_5.png",
"leaf_6.png"
],
"branches": [
[
"branch.png",
[ 68, 136 ],
[ 88, 118 ],
[ 211, 112 ]
],
[
"branch_2.png",
[ 51, 101 ],
[ 104, 113 ],
[ 226, 131 ],
[ 180, 80 ]
],
[
"branch_3.png",
[ 59, 118 ],
[ 84, 100 ],
[ 228, 112 ],
[ 206, 83 ]
]
],
"crowns": [
[
"crown.png",
[ 74, 146 ],
[ 80, 130 ],
[ 100, 100 ],
[ 193, 84 ],
[ 156, 146 ]
],
[
"crown_2.png",
[ 120, 138 ],
[ 188, 116 ],
[ 68, 96 ],
[ 216, 80 ],
[ 136, 58 ]
],
[
"crown_3.png",
[ 140, 140 ],
[ 60, 112 ],
[ 228, 113 ],
[ 183, 72 ],
[ 103, 40 ]
]
],
"woodId": "wood_tainted",
"saplingId": "sapling_tainted",
"fruits": []
}
},
"block": {
"log_tainted": {
"textureData": "stem.png",
"color": [ 74, 41, 107 ],
"subGroup": "LOG",
"placeCheck": "PLACE_TREE_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 600,
"treeId": "tainted",
"soundGroupId": "wood",
"particleColor": [ 255, 100, 50, 130 ]
}
}
}
================================================
FILE: trees/volcano_oak/volcano_oak.json
================================================
{
"tree": {
"volcano_oak": {
"length": 2,
"baseTiles": [ "volcano_dirt", "volcano_stone", "netherrack", "soul_sand", "volcano_burn_stone" ],
"leafs": [],
"branches": [
[
"branch.png"
],
[
"branch_2.png"
],
[
"branch_3.png"
]
],
"crowns": [
[
"crown.png"
],
[
"crown_2.png"
],
[
"crown_3.png"
]
],
"woodId": "wood_volcano",
"saplingId": "sapling_volcano",
"fruits": []
}
},
"block": {
"log_volcano_oak": {
"textureData": "stem.png",
"color": [ 200, 0, 0 ],
"subGroup": "LOG",
"placeCheck": "PLACE_TREE_CHECK",
"toolType": "AXE",
"mineGrade": "GRASS",
"hardness": 600,
"isLighting": true,
"lightColor": [ 16, 12, 0, 0 ],
"lightX": 0,
"lightY": 0,
"lightWi": 2,
"lightHi": 2,
"treeId": "volcano_oak",
"soundGroupId": "wood",
"particleColor": [ 255, 200, 0, 0 ]
}
}
}
================================================
FILE: ui/ContainerHelper.lua
================================================
local ContainerHelper = class("ContainerHelper")
---ContainerServerAddBackpack
---@param player Player
---@param container Container
function ContainerHelper.ContainerServerAddBackpack(player, container)
for i = 1, 50 do
-- 0-49 inventory
container:AddSlotToContainer(player.backpackInventory, i - 1)
end
end
---InInteractDistance
---@param player Player
---@param xi int
---@param yi int
function ContainerHelper.InInteractDistance(player, xi, yi)
return player:GetDistance(xi * 16 + 8, yi * 16 + 8) < 200
end
---ContainerClientInitSlots
---@param container Container
---@param tempSlots Inventory
function ContainerHelper.ContainerClientInitSlots(container, tempSlots)
local maxSlots = tempSlots.slotCount
for i = 1, maxSlots do
container:AddSlotToContainer(tempSlots, i - 1, true)
end
end
---CloseSendBackItems
---@param playerIndex int
---@param xi int
---@param yi int
---@param tempSlots Inventory
---@param slotIndices int[]
function ContainerHelper.CloseSendBackItems(playerIndex, xi, yi, tempSlots, slotIndices)
if PlayerUtils.IsAlive(playerIndex) then
local player = PlayerUtils.Get(playerIndex)
local inventory = player.backpackInventory
for _, i in ipairs(slotIndices) do
local slot = tempSlots:GetSlot(i)
if slot.hasStack then
-- the input item is exist, send back to player's inventory
local outStack = inventory:AddItemStack(slot:GetStack())
if outStack:Valid() then
player:DropItem(outStack)
end
slot:ClearStack()
end
end
else
-- the player is offline or unavailable, drop directly
for _, i in ipairs(slotIndices) do
local slot = tempSlots:GetSlot(i)
if slot.hasStack then
ItemUtils.CreateDrop(slot:GetStack(), xi * 16 + 8, yi * 16 + 8)
slot:ClearStack()
end
end
end
end
return ContainerHelper
================================================
FILE: ui/DeathUI.lua
================================================
---@class TC.DeathUI:TC.UIWindow
local DeathUI = class("DeathUI", require("UIWindow"))
local Locale = require("languages.Locale")
function DeathUI:__init()
DeathUI.super.__init(self, require("UIDesign").getDeathUI())
self:initUpdateFunc({ self._onUpdate, self }, 60)
self._lbCountDown = UIText.cast(self.root:getChild("panel.lb_title_2"))
self._cd = 11
self:_onUpdate()
end
function DeathUI:_onUpdate()
if ClientState.current ~= ClientState.Gaming then
self:closeWindow() -- tried fix stick DeathUI by suddenly close UIWindow
end
if self._cd > 1 then
self._cd = self._cd - 1
end
self._lbCountDown.text = string.format(Locale.RESPAWNING, self._cd)
end
function DeathUI:closeWindow()
DeathUI.super.closeWindow(self)
end
return DeathUI
================================================
FILE: ui/GuiID.lua
================================================
local GuiID = {
Backpack = 1,
Smelt = 2,
Brewing = 3,
Chest30 = 4,
Shooter9 = 5,
Advancement = 6,
Enchantment = 7,
EnderChest30 = 8,
Craft3x = 9,
Repair = 10,
}
return GuiID
================================================
FILE: ui/GuiLoader.lua
================================================
local GuiLoader = class("GUILoader")
local proxiesList = require("GuiLoaderProxy")
local serverProxies, clientProxies = proxiesList[1], proxiesList[2]
function GuiLoader:GetServerGuiElement(id, player, xi, yi)
local func = serverProxies[id]
if func then
return func(player, xi, yi)
end
return nil
end
function GuiLoader:GetClientGuiElement(id, player, xi, yi)
local func = clientProxies[id]
if func then
return func(player, xi, yi)
end
return nil
end
return GuiLoader
================================================
FILE: ui/GuiLoaderProxy.lua
================================================
local GuiID = require("GuiID")
local serverProxies = {
[GuiID.Backpack] = function(player, _, _)
return require("backpack.BackpackContainerServer").new(player)
end,
[GuiID.Smelt] = function(player, xi, yi)
return require("smelt.SmeltContainerServer").new(player, xi, yi)
end,
[GuiID.Brewing] = function(player, xi, yi)
return require("brewing.BrewingContainerServer").new(player, xi, yi)
end,
[GuiID.Chest30] = function(player, xi, yi)
return require("chest.Chest30ContainerServer").new(player, xi, yi)
end,
[GuiID.Shooter9] = function(player, xi, yi)
return require("shooter.Shooter9ContainerServer").new(player, xi, yi)
end,
[GuiID.Enchantment] = function(player, xi, yi)
return require("enchant.EnchantContainerServer").new(player, xi, yi)
end,
[GuiID.EnderChest30] = function(player, xi, yi)
return require("chest.EnderChest30ContainerServer").new(player, xi, yi)
end,
[GuiID.Craft3x] = function(player, xi, yi)
return require("craft3x.Craft3xContainerServer").new(player, xi, yi)
end,
[GuiID.Repair] = function(player, xi, yi)
return require("repair.RepairContainerServer").new(player, xi, yi)
end,
}
local clientProxies = {
[GuiID.Backpack] = function(player, _, _)
local BackpackContainerClient = require("backpack.BackpackContainerClient")
local BackpackUI = require("backpack.BackpackUI")
return BackpackUI.new(BackpackContainerClient.new(player))
end,
[GuiID.Smelt] = function(player, xi, yi)
local SmeltContainerClient = require("smelt.SmeltContainerClient")
local SmeltUI = require("smelt.SmeltUI")
return SmeltUI.new(SmeltContainerClient.new(player, xi, yi))
end,
[GuiID.Brewing] = function(player, xi, yi)
local BrewingContainerClient = require("brewing.BrewingContainerClient")
local BrewingUI = require("brewing.BrewingUI")
return BrewingUI.new(BrewingContainerClient.new(player, xi, yi))
end,
[GuiID.Chest30] = function(player, xi, yi)
local Chest30ContainerClient = require("chest.Chest30ContainerClient")
local Chest30UI = require("chest.Chest30UI")
return Chest30UI.new(Chest30ContainerClient.new(player, xi, yi))
end,
[GuiID.Shooter9] = function(player, xi, yi)
local Shooter9ContainerClient = require("shooter.Shooter9ContainerClient")
local Shooter9UI = require("shooter.Shooter9UI")
return Shooter9UI.new(Shooter9ContainerClient.new(player, xi, yi))
end,
[GuiID.Advancement] = function(player, xi, yi)
local AdvancementContainerClient = require("advancement.AdvancementContainerClient")
local AdvancementUI = require("advancement.AdvancementUI")
return AdvancementUI.new(AdvancementContainerClient.new(player))
end,
[GuiID.Enchantment] = function(player, xi, yi)
local EnchantContainerClient = require("enchant.EnchantContainerClient")
local EnchantUI = require("enchant.EnchantUI")
return EnchantUI.new(EnchantContainerClient.new(player, xi, yi))
end,
[GuiID.EnderChest30] = function(player, _, _)
local Chest30ContainerClient = require("chest.Chest30ContainerClient")
local EnderChest30UI = require("chest.EnderChest30UI")
return EnderChest30UI.new(Chest30ContainerClient.new(player))
end,
[GuiID.Craft3x] = function(player, _, _)
local Craft3xContainerClient = require("craft3x.Craft3xContainerClient")
local Craft3xUI = require("craft3x.Craft3xUI")
return Craft3xUI.new(Craft3xContainerClient.new(player))
end,
[GuiID.Repair] = function(player, xi, yi)
local RepairContainerClient = require("repair.RepairContainerClient")
local RepairUI = require("repair.RepairUI")
return RepairUI.new(RepairContainerClient.new(player, xi, yi))
end,
}
return { serverProxies, clientProxies }
================================================
FILE: ui/HotkeyUIHelper.lua
================================================
---@class TC.HotkeyUIHelper
local HotkeyUIHelper = class("HotkeyUIHelper")
local InputControl = require("client.InputControl")
function HotkeyUIHelper:__init(mod, guiID, data)
self._mod = mod
self._guiID = guiID
self._closeHotkey = Input.keyboard:getHotKeys(Keys.Escape):addListener({ HotkeyUIHelper._closeMe, self })
self._bpCloseKey = InputControl.getInstance().keyMap.Backpack
self._closeHotkeyBp = Input.keyboard:getHotKeys(self._bpCloseKey):addListener({ HotkeyUIHelper._closeMe, self })
end
function HotkeyUIHelper:destroy()
if self._closeHotkey then
Input.keyboard:getHotKeys(Keys.Escape):removeListener(self._closeHotkey)
self._closeHotkey = nil
end
if self._closeHotkeyBp then
Input.keyboard:getHotKeys(self._bpCloseKey):removeListener(self._closeHotkeyBp)
self._closeHotkeyBp = nil
end
end
function HotkeyUIHelper:_closeMe()
local player = PlayerUtils.GetCurrentClientPlayer()
if player then
player:CloseGui(self._mod, self._guiID)
end
end
return HotkeyUIHelper
================================================
FILE: ui/InfoPopupUI.lua
================================================
---@class TC.InfoPopupUI:TC.UIWindow
local InfoPopupUI = class("InfoPopupUI", require("UIWindow"))
function InfoPopupUI:__init(content, okCallback, cancelCallback, largeWindow)
InfoPopupUI.super.__init(self, require("UIDesign").getInfoPopupUI())
self._okCallback = okCallback
self._cancelCallback = cancelCallback
self._content = content
self._largeWindow = largeWindow
self:initContent()
end
function InfoPopupUI:setInfo(info)
UIText.cast(self.root:getChild("layer.panel_info.lb_info")).text = info
end
function InfoPopupUI:initContent()
local layer = self.root:getChild("layer")
if self._largeWindow then
layer.size = Size.new(1000, 500)
layer:applyMargin()
end
layer:getChild("btn_back"):addTouchUpListener({ self._onBackClicked, self })
layer:getChild("btn_ok"):addTouchUpListener({ self._onOkClicked, self })
self:setInfo(self._content)
end
function InfoPopupUI:_onBackClicked()
self.manager:playClickSound()
self:closeWindow()
if self._cancelCallback then
self._cancelCallback()
end
end
function InfoPopupUI:_onOkClicked()
if self._okCallback then
self._okCallback()
end
self:_onBackClicked()
end
function InfoPopupUI:closeWindow()
InfoPopupUI.super.closeWindow(self)
end
return InfoPopupUI
================================================
FILE: ui/LanguageUI.lua
================================================
---@class TC.LanguageUI:TC.UIWindow
local LanguageUI = class("LanguageUI", require("UIWindow"))
local UIUtil = require("UIUtil")
function LanguageUI:__init()
LanguageUI.super.__init(self, require("UIDesign").getLanguageUI())
self.indexSelected = 1
self.itemNodes = {}
self:initContent()
end
function LanguageUI:initContent()
local panel_list = self.root:getChild("layer.panel_list")
local panel_item = panel_list:getChild("panel_item")
self.itemSize = Size.new(panel_item.width / 1, panel_item.height)
UIUtil.setTable(panel_list, self, true, 1)
self:updateSelection()
self.root:getChild("layer.btn_ok"):addTouchUpListener({
function(self)
local StartUI = require("StartUI")
self:closeWindow()
StartUI.new()
end, self }
)
end
function LanguageUI:_getTableElementCount()
return 5
end
function LanguageUI:_getTableElementSize()
return self.itemSize
end
---_setTableElement
---@param node UINode
---@param index number
function LanguageUI:_setTableElement(node, index)
node.tag = index
local lb_text = UIText.cast(node:getChild("lb_locale"))
lb_text.text = lb_text.text .. tostring(index)
node:addTouchUpListener({ self._onElementClicked, self })
if index == 1 then
lb_text.text = "简体中文"
end
table.insert(self.itemNodes, node)
end
---_onElementClicked
---@param node UINode
function LanguageUI:_onElementClicked(node)
local index = node.tag
self.indexSelected = index
self:updateSelection()
end
function LanguageUI:updateSelection()
---@param node UINode
for _, node in pairs(self.itemNodes) do
if node.tag == self.indexSelected then
node:getChild("img_selected").visible = true
else
node:getChild("img_selected").visible = false
end
end
end
function LanguageUI:closeWindow()
LanguageUI.super.closeWindow(self)
end
return LanguageUI
================================================
FILE: ui/ModListUI.lua
================================================
---@class TC.ModListUI:TC.UIWindow
local ModListUI = class("ModListUI", require("UIWindow"))
local UIUtil = require("UIUtil")
local Locale = require("languages.Locale")
function ModListUI:__init()
ModListUI.super.__init(self, require("UIDesign").getModListUI())
self.indexSelected = 1
self.itemNodes = {}
self.modInfoList = {}
self._panelList = self.root:getChild("layer.panel_list")
self._panelItem = self._panelList:getChild("panel_item")
self._svInfo = UIScrollView.cast(self.root:getChild("layer.info_list"))
self._panelInfo1 = self._svInfo:getChild("panel_info_1")
self._panelInfo2 = self._svInfo:getChild("panel_info_2")
self._panelInfoWeb = self._svInfo:getChild("panel_info_web")
self._btnWeb1 = self._panelInfoWeb:getChild("btn_web_1")
self._btnWeb2 = self._panelInfoWeb:getChild("btn_web_2")
self._lbVersion = UIText.cast(self._panelInfo1:getChild("panel_version.lb_version"))
self._lbAuthors = UIText.cast(self._panelInfo1:getChild("panel_author.lb_author"))
self._lbDesc = UIText.cast(self._panelInfo2:getChild("lb_des"))
self._lbListTitle = UIText.cast(self.root:getChild("layer.lb_list_title"))
self:initContent()
end
function ModListUI:initContent()
self:_initInfo()
self.root:getChild("layer.btn_back"):addTouchUpListener({
function(self)
self.manager:playClickSound()
local StartUI = require("StartUI")
self:closeWindow()
StartUI.new()
end, self }
)
self.root:getChild("layer.btn_mod_folder"):addTouchUpListener({
self._onOpenModsFolderClicked, self }
)
self._btnWeb1:addTouchUpListener({ self._onURLClicked, self, 1 })
self._btnWeb2:addTouchUpListener({ self._onURLClicked, self, 2 })
self.itemSize = Size.new(self._panelItem.width, self._panelItem.height)
UIUtil.setTable(self._panelList, self, true, 1)
self._lbListTitle.text = string.format(Locale.ALL_MOD_LOADED, #self.modInfoList)
self:postInitContent()
self:updateSelection()
end
function ModListUI:_onOpenModsFolderClicked()
self.manager:playClickSound()
if App.isPC then
File.openFolderWindow(Path.join(App.persistentDataPath, "mods"))
else
require("ui.InfoPopupUI").new(Locale.MOD_FOLDER_UNSUPPORTED)
end
end
function ModListUI:_initInfo()
-- load all mod info from package.json
local UISpritePool = require("UISpritePool")
---@param mod Mod
for _, mod in each(Mod.modList) do
local packageJsonPath = Path.join(mod.assetRootPath, "package.json")
local jsonStr = AssetManager.readAsString(packageJsonPath)
local info = JsonUtil.fromJson(jsonStr)
if UISpritePool.getInstance():has(mod.modId .. ":__icon") then
info._texName = mod.modId .. ":__icon"
end
table.insert(self.modInfoList, info)
end
end
function ModListUI:_getTableElementCount()
return #self.modInfoList
end
function ModListUI:_getTableElementSize()
return self.itemSize
end
---_setTableElement
---@param node UINode
---@param index number
function ModListUI:_setTableElement(node, index)
node.tag = index
local info = self.modInfoList[index]
local lbCaption = UIText.cast(node:getChild("lb_mod_name"))
local lbTips = UIText.cast(node:getChild("lb_mod_tip"))
local iconImg = UIImage.cast(node:getChild("img_mod_pic"))
if info.displayName then
lbCaption.text = info.displayName
else
lbCaption.text = "Untitled"
end
if info.tips then
lbTips.text = info.tips
else
lbTips.text = ""
end
if info._texName ~= nil then
local UISpritePool = require("UISpritePool")
iconImg.sprite = UISpritePool.getInstance():get(info._texName)
end
node:addTouchUpListener({ self._onElementClicked, self })
table.insert(self.itemNodes, node)
end
---_onElementClicked
---@param node UINode
---@param _ Touch
function ModListUI:_onElementClicked(node)
local index = node.tag
if self.indexSelected ~= index then
self.indexSelected = index
self:updateSelection()
self.manager:playClickSound()
end
end
function ModListUI:updateSelection()
---@param node UINode
for _, node in pairs(self.itemNodes) do
if node.tag == self.indexSelected then
node:getChild("img_selected").visible = true
else
node:getChild("img_selected").visible = false
end
end
local info = self.modInfoList[self.indexSelected]
if info.version then
self._lbVersion.text = info.version
else
self._lbVersion.text = "0.0.0.0"
end
if info.authors then
local str = ""
local flag = false
for _, authorName in ipairs(info.authors) do
if flag then
str = str .. ", "
end
flag = true
str = str .. authorName
end
self._lbAuthors.text = str
else
self._lbAuthors.text = "..."
end
self._panelInfoWeb.visible = false
if info.websites then
self._panelInfoWeb.visible = true
self._btnWeb1.visible = false
self._btnWeb2.visible = false
for i, wbData in ipairs(info.websites) do
local btn
if i == 1 then
btn = self._btnWeb1
elseif i == 2 then
btn = self._btnWeb2
else
break
end
btn.visible = true
local originalText = wbData.title
if originalText == "Github" then
originalText = Locale.WEB_SOURCE_GITHUB
elseif originalText == "Homepage" then
originalText = Locale.WEB_HOME
end
UIText.cast(btn:getChild("lb_caption")).text = originalText
end
end
self._lbDesc.autoAdaptSize = true
self._lbDesc.preferredWidth = self._panelInfo2.width - 32
if info.description then
self._lbDesc.text = info.description
else
self._lbDesc.text = ""
end
self._panelInfo2.height = self._lbDesc.positionY + self._lbDesc.height + 16
local posY = self._panelInfo1.positionY + self._panelInfo1.height + 16
if self._panelInfoWeb.visible then
self._panelInfoWeb.positionY = posY
posY = posY + self._panelInfoWeb.height + 16
end
self._panelInfo2.positionY = posY
self._svInfo:ScrollToTop()
local tmpSize = Size.new(self._svInfo.viewSize.width,
self._panelInfo2.positionY + self._panelInfo2.height)
tmpSize.height = math.max(tmpSize.height, self._svInfo.height)
self._svInfo.viewSize = tmpSize
self._svInfo:ScrollToTop()
end
function ModListUI:_onURLClicked(index)
self.manager:playClickSound()
local info = self.modInfoList[self.indexSelected]
if info.websites then
if index <= #info.websites then
local url = info.websites[index].url
local MiscHelper = require("util.MiscHelper")
MiscHelper.OpenURL(url)
end
end
end
function ModListUI:closeWindow()
ModListUI.super.closeWindow(self)
end
return ModListUI
================================================
FILE: ui/MouseItemData.lua
================================================
---@class TC.MouseItemData
local MouseItemData = class("MouseItemData")
local SettingsData = require("settings.SettingsData")
local s_instance
---@return TC.MouseItemData
function MouseItemData.getInstance()
if s_instance == nil then
s_instance = MouseItemData.new()
end
return s_instance
end
function MouseItemData:__init()
self.inventory = Inventory.new(1)
self.slot = nil ---@type Slot
self.touchingPosition = Vector2.new()
self.originSlot = nil ---@type Slot
self.originContainer = nil ---@type Container
self.originSlotIndex = -1
self.pickingOneByOne = false
self.isPcCurrentPicking = false
self.pcSelectingSlots = {}
self.pcSelectingContainerAndSlotIndices = {}
self.pcIsAverageMode = false
self._pickingTicks = 0
self._pickingStep = 30
self._pickingSpeed = 4
self._firstPicking = false
self._ticks = 0
self._iconScale = Vector2.new(1, 1)
self._displayOffsetX = 64
self._keepingTip = false
self._itemInfoTable = {}
end
---showTip
---@param itemStack ItemStack
---@param touchingPosition Vector2
---@param keepTicks
function MouseItemData:showTip(itemStack, touchingPosition, keepTicks)
self._itemInfoTable = {}
local item = itemStack:GetItem()
local showDebugTip = true
local StringUtil = require("util.StringUtil")
local itemName = LangUtils.ItemName(item.id)
if itemName == "" then
itemName = itemStack:GetItem().idName
end
table.insert(self._itemInfoTable, itemName)
local enchantments = item.enchantments
for i = 0, itemStack.enchantmentCount - 1 do
local enchantment = itemStack:GetEnchantmentByIndex(i)
table.insert(self._itemInfoTable, string.format("%s %s",
LangUtils.EnchantmentName(enchantment.id), StringUtil.NumberToRoman(enchantment.level)))
end
if #enchantments > 0 then
table.insert(self._itemInfoTable, " ")
end
local buffs = item.buffs
for _, buff in ipairs(buffs) do
table.insert(self._itemInfoTable, string.format("%s %s",
LangUtils.BuffName(buff.id), StringUtil.TicksToTimeFormat(buff.time)))
end
local intro = LangUtils.ItemIntroduction(item.id)
if intro ~= "" then
table.insert(self._itemInfoTable, string.format("%s", intro))
end
if item.maxDurable > 0 then
table.insert(self._itemInfoTable, string.format("耐久 %d/%d", itemStack.durable, item.maxDurable))
end
if item.baseAttack.attack > 0 then
table.insert(self._itemInfoTable, string.format("攻击 +%d", item.baseAttack.attack))
end
if item.baseAttack.knockBack > 0 then
table.insert(self._itemInfoTable, string.format("击退 +%d", item.baseAttack.knockBack))
end
if item.baseAttack.crit > 0 then
table.insert(self._itemInfoTable, string.format("暴击 +%d", item.baseAttack.crit))
end
if item.defense > 0 then
table.insert(self._itemInfoTable, string.format("防御 +%d", item.defense))
end
if item.noConsumeChance > 0 then
table.insert(self._itemInfoTable, string.format("弹药节省 +%d%%", math.ceil(item.noConsumeChance * 100)))
end
if item.consumeMana > 0 then
table.insert(self._itemInfoTable, string.format("魔耗 %d", item.consumeMana))
end
if showDebugTip then
table.insert(self._itemInfoTable, string.format("%s", item.idName))
end
local modName = item.mod.displayName
if modName ~= "" then
table.insert(self._itemInfoTable, string.format("%s", modName))
end
local TipUI = require("TipUI")
if TipUI.isShowing() then
TipUI.changeNewContent(self._itemInfoTable)
TipUI.resetKeepTime()
else
TipUI.generate(self._itemInfoTable, keepTicks, 1)
end
TipUI.adaptPosition(touchingPosition)
self._keepingTip = true
end
function MouseItemData:closeTip()
local TipUI = require("TipUI")
TipUI.close()
self:stopKeepingTip()
end
function MouseItemData:stopKeepingTip()
self._keepingTip = false
end
function MouseItemData:startDragging(originContainer, originSlotIndex)
self.originSlot = originContainer:GetSlot(originSlotIndex)
self.originContainer = originContainer
self.originSlotIndex = originSlotIndex
end
function MouseItemData:stopDragging()
self.originSlot = nil
self.originContainer = nil
self.originSlotIndex = -1
end
function MouseItemData:fixDisplayOffset()
if SettingsData.isMobileOperation then
self._displayOffsetX = 64 * ((self.touchingPosition.x > GameWindow.width * 0.5) and -1.0 or 1.0)
else
self._displayOffsetX = 64
end
end
function MouseItemData:updateDisplayOffset()
if SettingsData.isMobileOperation then
local moveSpeed = 4
self._displayOffsetX = math.min(math.max(
self._displayOffsetX + moveSpeed *
((self.touchingPosition.x > GameWindow.width * 0.5) and -1 or 1), -64), 64)
else
self:fixDisplayOffset()
end
end
function MouseItemData:startPicking()
self.pickingOneByOne = true
self._pickingTicks = 0
self._pickingStep = 12
self._pickingSpeed = 2
self._firstPicking = true
self:fixDisplayOffset()
end
function MouseItemData:stopPicking()
if self.pickingOneByOne then
self.pickingOneByOne = false
end
end
function MouseItemData:update()
assert(ClientState.current == ClientState.Gaming, "current client state must be Gaming!")
if not SettingsData.isMobileOperation then
self.touchingPosition = Input.mouse.position
end
local TipUI = require("TipUI")
if TipUI.isShowing() and TipUI.getShowTag() == 1 then
TipUI.adaptPosition(self.touchingPosition)
if self._keepingTip then
TipUI.resetKeepTime()
end
end
if self.slot == nil then
local player = PlayerUtils.GetCurrentClientPlayer()
self.slot = player.mouseInventory:GetSlot(0)
---@type TC.GPlayer
local globalPlayer = player:GetGlobalPlayer("tc:GPlayer")
--print(globalPlayer.sayWord)
end
local mouseSlot = self.slot
if mouseSlot.hasStack then
if self.pickingOneByOne and self.originSlot ~= nil then
if self.originSlot.hasStack then
self._pickingTicks = self._pickingTicks + 1
local checkTime = self._pickingStep * (self._firstPicking and 2 or 1)
if self._pickingTicks >= checkTime then
self._pickingSpeed = self._pickingSpeed - 1
if self._pickingSpeed <= 0 then
self._pickingSpeed = 1
self._pickingStep = math.max(self._pickingStep - 1, 1)
end
self._pickingTicks = 0
local pickingCount = 1
local merges = mouseSlot:GetStack():GetMergeCount(self.originSlot:GetStack())
if merges > 0 then
pickingCount = math.min(merges, pickingCount)
mouseSlot:GetStack():SetStackSize(mouseSlot:GetStack().stackSize + pickingCount)
self.originSlot:DecrStackSize(pickingCount)
SoundUtils.PlaySound(Reg.SoundID("pop"))
end
end
end
end
local scaleNum = 1.5 + Utils.SinValue(self._ticks, 64) * 0.1
self._iconScale.x = scaleNum
self._iconScale.y = scaleNum
self:updateDisplayOffset()
self._ticks = self._ticks + 1
end
end
function MouseItemData:render()
assert(ClientState.current == ClientState.Gaming, "current client state must be Gaming!")
if self.slot.hasStack then
Sprite.beginBatch()
local stack = self.slot:GetStack()
local exData = SpriteExData.new()
exData.scaleRate = self._iconScale
exData.origin = Vector2.new(16, 16)
local pos = self.touchingPosition + Vector2.new(self._displayOffsetX, 48)
if self.slot.tag < 0 then
local num = require("ui.UISlotOp").getSelectedNum(self.slot)
if num > 0 then
stack:Render(pos, Color.White, exData)
stack:RenderCustomNum(num, pos, Color.Yellow, exData)
end
else
stack:Render(pos, Color.White, exData)
stack:RenderNum(pos, Color.Yellow, exData)
end
Sprite.endBatch()
end
end
return MouseItemData
================================================
FILE: ui/NewPlayerUI.lua
================================================
---@class TC.NewPlayerUI:TC.UIWindow
local NewPlayerUI = class("NewPlayerUI", require("UIWindow"))
local PlayerBoneInfo = require("bone2d.PlayerBoneInfo")
local UIUtil = require("UIUtil")
function NewPlayerUI:__init()
NewPlayerUI.super.__init(self, require("UIDesign").getNewPlayerUI())
self._playerBone = nil
self._posPanel = self.root:getChild("layer.pos_panel")
self._postureIdx = 0
self._skins = {}
self._itemSize = nil
self._indexSelected = 0
self._accountNameExists = {}
self._canGenerateAccount = false
self._validName = ""
self._validSkinID = 0
self:initContent()
end
function NewPlayerUI:initContent()
local accountNames = File.getAllFiles(Path.join(App.persistentDataPath, "accounts"),
".dat", true, false, false)
for _, name in pairs(accountNames) do
self._accountNameExists[name] = true
end
self._validSkinID = 1
self._playerBone = PlayerBoneInfo.createBySkinID(self._validSkinID)
self._playerBone.animator:setBool("Standard", false)
self._playerBone.animator:setBool("OnGround", true)
self._playerBone.joints.flip = true
self._posPanel:getPostDrawLayer(0):addListener(
{ self._onRenderPlayerBone, self })
self:_reloadListData()
UIButton.cast(self.root:getChild("layer.btn_female")).selected = true
self.root:getChild("layer.btn_ok"):addTouchUpListener({ self.onOkButtonClicked, self })
self.root:getChild("layer.btn_back"):addTouchUpListener({ self.onBackButtonClicked, self })
self.root:getChild("layer.btn_animator"):addTouchUpListener({ self.onPostureButtonClicked, self })
UIInputField.cast(self.root:getChild("layer.panel_name.edit")):addTextChangedListener({ self._onNameChanged, self })
self:initUpdateFunc({ self._onPlayerBoneUpdate, self })
self:initUpdateFunc({ self._onPlayerBoneUpdateInList, self })
self:_checkNameValid("")
end
function NewPlayerUI:onOkButtonClicked()
if self._canGenerateAccount and self._validName ~= "" and self._validSkinID > 0 then
local account = Account.new()
account.name = self._validName
account.skinID = self._validSkinID
AccountUtils.Save(account)
self.manager:playClickSound()
self:closeWindow()
require("PlayerListUI").new()
end
end
function NewPlayerUI:_onNameChanged(_, text)
self:_checkNameValid(text)
end
---_checkNameValid
---@param text string
function NewPlayerUI:_checkNameValid(text)
local checker = require("util.ValidChecker")
local tipText = ""
self._canGenerateAccount = false
local len = utf8string.len(text)
if len == 0 then
tipText = "请输入玩家名称"
elseif not (len >= 1 and len <= 20) then
tipText = "玩家名称不能超过20个字符"
elseif not checker.checkValidFileName(text) then
tipText = "玩家名称格式不正确"
elseif self._accountNameExists[text] then
tipText = "名称已存在,请换一个"
else
tipText = "玩家名称可用!"
self._canGenerateAccount = true
self._validName = text
end
UIText.cast(self.root:getChild("layer.panel_info.lb_info")).text = tipText
local btnColor = Color.Gray
if self._canGenerateAccount then
btnColor = Color.White
end
UIText.cast(self.root:getChild("layer.btn_ok.lb_caption")).color = btnColor
end
function NewPlayerUI:_reloadListData()
self._skins = {}
for skinID = 1, SkinUtils.maxID do
skin = SkinUtils.GetSkin(skinID)
local skinTable = {
id = skinID,
name = skin.name,
mod = skin.mod,
authors = "",
playerBone = PlayerBoneInfo.createBySkinID(skinID)
}
for i, author in each(skin.authors) do
if i == 1 then
skinTable.authors = "by " .. author
else
skinTable.authors = skinTable.authors .. ", " .. author
end
end
skinTable.playerBone.animator:setBool("Standard", true)
table.insert(self._skins, skinTable)
end
self._panelList = UIScrollView.cast(self.root:getChild("layer.panel_list"))
local panelItem = self._panelList:getChild("panel_item")
self._itemSize = Size.new(panelItem.width, panelItem.height)
UIUtil.setTable(self._panelList, self, true, 1)
end
function NewPlayerUI:_getTableElementCount()
return #self._skins
end
function NewPlayerUI:_getTableElementSize()
return self._itemSize
end
---_setTableElement
---@param node UINode
---@param index number
function NewPlayerUI:_setTableElement(node, index)
node.tag = index
node:getChild("img_player_icon_holder").isContainer = true
node:getChild("img_player_icon_holder.bg"):getPostDrawLayer(0):addListener(
{ self._onRenderPlayerBoneInList, self, index })
local lbName = UIText.cast(node:getChild("lb_name"))
local lbMod = UIText.cast(node:getChild("lb_mod"))
local lbAuthor = UIText.cast(node:getChild("lb_author"))
lbName.text = self._skins[index].name
lbMod.text = self._skins[index].mod.displayName
lbAuthor.text = self._skins[index].authors
if lbName.text == "Unknown" then
lbName.visible = false
lbMod.positionY = lbMod.positionY - 8
lbAuthor.positionY = lbAuthor.positionY - 8
else
lbName.visible = true
end
node:addTouchUpListener({ self._onElementClicked, self })
end
---_onElementClicked
---@param node UINode
---@param _ Touch
function NewPlayerUI:_onElementClicked(node)
local index = node.tag
if self._indexSelected ~= index then
self.manager:playClickSound()
self._indexSelected = index
self._validSkinID = self._skins[index].id
PlayerBoneInfo.setSkinByID(self._playerBone, self._validSkinID)
self:updateSelection()
end
end
function NewPlayerUI:updateSelection()
for index = 1, self:_getTableElementCount() do
local node = self._panelList:getChildByTag(index)
local show = false
if node.tag == self._indexSelected then
show = true
end
node:getChild("img_selected").visible = show
end
end
function NewPlayerUI:_onPlayerBoneUpdate()
local screenPos = self.manager:getScreenPosition(self._posPanel)
self._playerBone.joints.position = screenPos + Vector2.new(100, 200)
self._playerBone.joints.scale = Vector2.new(4, 4)
self._playerBone:update()
end
function NewPlayerUI:_onRenderPlayerBoneInList(index)
local playerBone = self._skins[index].playerBone
playerBone.joints:render()
end
function NewPlayerUI:_onPlayerBoneUpdateInList()
for index = 1, #self._skins do
local elementNode = UIUtil.getTableElement(self._panelList, index)
local screenPos = self.manager:getScreenPosition(elementNode)
---@type JointBody2D
local playerBone = self._skins[index].playerBone
playerBone.joints.position = screenPos + Vector2.new(40, 104)
playerBone.joints.scale = Vector2.new(1.5, 1.5)
playerBone:update()
end
end
function NewPlayerUI:_onRenderPlayerBone()
self._playerBone.joints:render()
end
function NewPlayerUI:onBackButtonClicked()
local PlayerListUI = require("PlayerListUI")
self.manager:playClickSound()
self:closeWindow()
PlayerListUI.new()
end
function NewPlayerUI:onPostureButtonClicked()
local animator = self._playerBone.animator
if self._postureIdx == 0 then
animator:setFloat("Speed", 0.5)
self._postureIdx = 1
elseif self._postureIdx == 1 then
animator:setFloat("Speed", 1)
self._postureIdx = 2
elseif self._postureIdx == 2 then
animator:setBool("OnGround", false)
animator:setFloat("AirSpeed", -1)
self._postureIdx = 3
elseif self._postureIdx == 3 then
animator:setFloat("AirSpeed", 1)
self._postureIdx = 4
elseif self._postureIdx == 4 then
animator:setBool("OnGround", true)
animator:setFloat("Speed", 0)
self._postureIdx = 0
end
end
function NewPlayerUI:closeWindow()
NewPlayerUI.super.closeWindow(self)
end
return NewPlayerUI
================================================
FILE: ui/NewServerUI.lua
================================================
---@class TC.NewServerUI:TC.UIWindow
local NewServerUI = class("NewServerUI", require("UIWindow"))
function NewServerUI:__init()
NewServerUI.super.__init(self, require("UIDesign").getNewServerUI())
self:initContent()
end
function NewServerUI:initContent()
self.root:getChild("layer.btn_back"):addTouchUpListener({
function(self)
local ServerListUI = require("ServerListUI")
self:closeWindow()
ServerListUI.new()
end, self }
)
end
function NewServerUI:closeWindow()
NewServerUI.super.closeWindow(self)
end
return NewServerUI
================================================
FILE: ui/NewWorldUI.lua
================================================
---@class TC.NewWorldUI:TC.UIWindow
local NewWorldUI = class("NewWorldUI", require("UIWindow"))
function NewWorldUI:__init()
NewWorldUI.super.__init(self, require("UIDesign").getNewWorldUI())
self._worldNameExists = {}
self._canGenerateWorld = false
self._isSSC = false
self._gameMode = 0
self._tipMode = 0
self._validName = ""
self:initContent()
end
function NewWorldUI:initContent()
local worldNames = File.getAllSubFolders(Path.join(App.persistentDataPath, "worlds"))
for _, name in pairs(worldNames) do
self._worldNameExists[name] = true
end
UIText.cast(self.root:getChild("layer.btn_gm.lb_caption")).color = Color.Gray
UIInputField.cast(self.root:getChild("layer.panel_name.edit")):addTextChangedListener({ self._onNameChanged, self })
self.root:getChild("layer.btn_ok"):addTouchUpListener({ self.onOkButtonClicked, self })
self.root:getChild("layer.btn_gm"):addTouchUpListener({ self._onGameModeButtonClicked, self })
self.root:getChild("layer.btn_bp"):addTouchUpListener({ self._onSideButtonClicked, self })
self.root:getChild("layer.btn_back"):addTouchUpListener({ self.onCancelClicked, self })
self:_checkNameValid("")
end
function NewWorldUI:_onNameChanged(_, text)
self:_checkNameValid(text)
end
function NewWorldUI:onCancelClicked()
self.manager:playClickSound()
self:closeWindow()
require("WorldListUI").new()
end
function NewWorldUI:onOkButtonClicked()
if self._canGenerateWorld and self._validName ~= "" then
local worldData = WorldData.new()
local seedString = UIInputField.cast(self.root:getChild("layer.panel_seed.edit")).text
worldData.worldName = self._validName
worldData.worldSeed = WorldDataUtils.GenerateSeed(seedString)
worldData.clientSideCharacters = not self._isSSC
WorldDataUtils.Save(worldData)
self.manager:playClickSound()
self:closeWindow()
require("WorldListUI").new()
end
end
function NewWorldUI:_onGameModeButtonClicked(node)
do return end
if self._tipMode == 1 then
self._gameMode = self._gameMode + 1
if self._gameMode >= 3 then
self._gameMode = 0
end
end
self._tipMode = 1
local title = ""
local tipText = ""
if self._gameMode == 0 then
title = "生存模式"
tipText = "冒险,建造,升级!"
elseif self._gameMode == 1 then
title = "创造模式"
tipText = "(非公测内容,正在开发中)"
elseif self._gameMode == 2 then
title = "冒险模式"
tipText = "(非公测内容,正在开发中)"
end
self.manager:playClickSound()
UIText.cast(node:getChild("lb_caption")).text = title
UIText.cast(self.root:getChild("layer.panel_info.lb_info")).text = tipText
end
function NewWorldUI:_onSideButtonClicked(node)
if self._tipMode == 2 then
self._isSSC = not self._isSSC
end
self._tipMode = 2
local title
local tipText
if self._isSSC then
title = "强制开荒模式"
--tipText = "[SSC Mode] Starts with new character."
tipText = "[SSC] 进入世界将强制使用新角色数据."
else
title = "背包共享模式"
tipText = "[CSC] 进入世界共享其他世界数据."
end
self.manager:playClickSound()
UIText.cast(node:getChild("lb_caption")).text = title
UIText.cast(self.root:getChild("layer.panel_info.lb_info")).text = tipText
end
---_checkNameValid
---@param text string
function NewWorldUI:_checkNameValid(text)
local checker = require("util.ValidChecker")
self._tipMode = 0
local tipText = ""
self._canGenerateWorld = false
local len = utf8string.len(text)
if len == 0 then
tipText = "请输入世界名称"
elseif not (len >= 1 and len <= 20) then
tipText = "世界名称不能超过20个字符"
elseif not checker.checkValidFileName(text) then
tipText = "世界名称格式不正确"
elseif self._worldNameExists[text] then
tipText = "名称已存在,请换一个"
else
tipText = "世界名称可用!"
self._canGenerateWorld = true
self._validName = text
end
UIText.cast(self.root:getChild("layer.panel_info.lb_info")).text = tipText
local btnColor = Color.Gray
if self._canGenerateWorld then
btnColor = Color.White
end
UIText.cast(self.root:getChild("layer.btn_ok.lb_caption")).color = btnColor
end
function NewWorldUI:closeWindow()
NewWorldUI.super.closeWindow(self)
end
return NewWorldUI
================================================
FILE: ui/OptionUI.lua
================================================
---@class TC.OptionUI:TC.UIWindow
local OptionUI = class("OptionUI", require("UIWindow"))
local Locale = require("languages.Locale")
local RawHotkeyUIHelper = require("ui.RawHotkeyUIHelper")
function OptionUI:__init()
OptionUI.super.__init(self, require("UIDesign").getOptionUI(), require("ui.UIDefault").GROUP_GAME_WINDOW)
self._hkHelper = RawHotkeyUIHelper.new(self)
self:initContent()
end
function OptionUI:initContent()
self.root:getChild("layer.btn_back"):addTouchUpListener({ OptionUI._onBtnBackClicked, self })
self.root:getChild("layer.btn_setting"):addTouchUpListener({ OptionUI._onBtnSettingClicked, self })
self.root:getChild("layer.btn_recipe"):addTouchUpListener({ OptionUI._onBtnRecipeClicked, self })
self.root:getChild("layer.btn_advancement"):addTouchUpListener({ OptionUI._onBtnAdvancementClicked, self })
self.root:getChild("layer.btn_save_and_exit"):addTouchUpListener({ OptionUI._onBtnSaveAndExitClicked, self })
end
function OptionUI:_onBtnBackClicked()
self:closeWindow()
self.manager:playClickSound()
end
function OptionUI:_onBtnSettingClicked()
self:closeWindow()
self.manager:playClickSound()
require("SettingUI").new(function()
OptionUI.new()
end)
end
function OptionUI:_onBtnRecipeClicked()
self:closeWindow()
self.manager:playClickSound()
require("ui.nei.NeiUI").new()
end
function OptionUI:_onBtnAdvancementClicked()
self:closeWindow()
self.manager:playClickSound()
local player = PlayerUtils.GetCurrentClientPlayer()
if not player then
return
end
local GuiID = require("ui.GuiID")
if player:IsGuiOpened(Mod.current, GuiID.Advancement) then
return
end
player:OpenGui(Mod.current, GuiID.Advancement, player.centerXi, player.centerYi)
end
function OptionUI:_onBtnSaveAndExitClicked()
self:closeWindow()
self.manager:playClickSound()
ClientStateManager.SaveAndExitGaming()
end
function OptionUI:closeWindow()
self._hkHelper:destroy()
OptionUI.super.closeWindow(self)
end
return OptionUI
================================================
FILE: ui/PendingUI.lua
================================================
---@class TC.PendingUI:TC.UIWindow
local PendingUI = class("PendingUI", require("UIWindow"))
local Locale = require("languages.Locale")
local UISpritePool = require("ui.UISpritePool")
local ANIMATION_SCALE = 2
function PendingUI:__init()
PendingUI.super.__init(self, require("UIDesign").getPendingUI())
self._closeBtn = UIButton.cast(self.root:getChild("layer.btn_back"))
self._aniPanel = UIPanel.cast(self.root:getChild("layer.panel_animation"))
self._lbTip = UIText.cast(self.root:getChild("layer.lb_tip"))
self._aniTexture = nil
self._ticks = 0
self._aniFrameIndex = 0
self:initContent()
end
function PendingUI:initContent()
self._aniTexture = UISpritePool.getInstance():get("tc:pending_animation").textureLocation
self._closeBtn:addTouchUpListener({
function(self)
ClientStateManager.SaveAndExitGaming()
self:_jumpTo(require("StartUI"))
end, self
})
self._closeBtn.visible = false
self._lbTip.text = ""
if ClientState.current == ClientState.Joining or ClientState.current == ClientState.LoadingWorld then
local tod = require("TipsOfTheDay").new()
self._lbTip.text = tod:getRandomText()
elseif ClientState.current == ClientState.SavingWorld then
self._lbTip.text = Locale.PENDING_SAVING
elseif ClientState.current == ClientState.LosingConnection then
self._lbTip.text = Locale.PENDING_NO_CONNECTION
self._closeBtn.visible = true
end
self._aniPanel:getPostDrawLayer(0):addListener({ PendingUI._renderAnimation, self })
self:initUpdateFunc({ self._onUpdate, self })
end
function PendingUI:_onUpdate()
self._ticks = self._ticks + 1
self._aniFrameIndex = math.floor(self._ticks / 8) % 4
end
function PendingUI:_renderAnimation(node, canvasPos)
local pos = node.positionInCanvas + canvasPos + Vector2.new(node.width * 0.5, node.height * 0.5)
local rectCut = Rect.new(32 * self._aniFrameIndex, 0, 32, 32)
local exData = SpriteExData.new()
exData.originX = 16
exData.originY = 16
exData.scaleRateX = ANIMATION_SCALE
exData.scaleRateY = ANIMATION_SCALE
Sprite.draw(self._aniTexture, pos, rectCut, Color.White, exData, 1.0)
end
function PendingUI:_jumpTo(WindowClass)
self:closeWindow()
self.manager:playClickSound()
WindowClass.new()
end
function PendingUI:closeWindow()
PendingUI.super.closeWindow(self)
end
return PendingUI
================================================
FILE: ui/PlayerListUI.lua
================================================
---@class TC.PlayerListUI:TC.UIWindow
local PlayerListUI = class("PlayerListUI", require("UIWindow"))
local UIUtil = require("UIUtil")
local PlayerBoneInfo = require("bone2d.PlayerBoneInfo")
local MenuJoinInfo = require("client.MenuJoinInfo")
local Locale = require("languages.Locale")
function PlayerListUI:__init()
PlayerListUI.super.__init(self, require("UIDesign").getPlayerListUI())
---@type UIScrollView
self._panelList = nil
self._accounts = {}
self._indexSelected = 0
self._itemSize = nil
self:initContent()
end
function PlayerListUI:initContent()
self:initAccountData()
self._panelList = UIScrollView.cast(self.root:getChild("layer.panel_list"))
local panelItem = self._panelList:getChild("panel_item")
self._itemSize = Size.new(panelItem.width, panelItem.height)
UIUtil.setTable(self._panelList, self, true, 1)
self:updateSelection()
self.root:getChild("layer.btn_back"):addTouchUpListener({ self._onBackButtonClicked, self })
self.root:getChild("layer.btn_ok"):addTouchUpListener({ self._onOkButtonClicked, self })
self.root:getChild("layer.btn_create"):addTouchUpListener({ self._onNewButtonClicked, self })
self:initUpdateFunc({ self._onPlayerBoneUpdate, self })
end
function PlayerListUI:getAccountLastModifiedTime(name)
local filePath = Path.join(App.persistentDataPath, "accounts", name .. ".dat")
if File.isPathExist(filePath) then
return File.getLastWriteTime(filePath)
end
local filePathBackup = Path.join(App.persistentDataPath, "accounts", name .. ".dat.bak")
return File.getLastWriteTime(filePathBackup)
end
function PlayerListUI:initAccountData()
local accountNames = File.getAllFiles(Path.join(App.persistentDataPath, "accounts"),
".dat", true, false, false)
for _, name in pairs(accountNames) do
local account = Account.new()
if AccountUtils.Load(name, account) then
local lastModifiedTime = self:getAccountLastModifiedTime(name)
local infoTable = {
name = name,
skinID = account.skinID,
lastModifiedTime = lastModifiedTime,
playerBone = PlayerBoneInfo.createBySkinID(account.skinID)
}
infoTable.playerBone.animator:setBool("Standard", true)
table.insert(self._accounts, infoTable)
end
end
table.sort(self._accounts, function(element1, element2)
return element1.lastModifiedTime > element2.lastModifiedTime
end)
end
function PlayerListUI:_getTableElementCount()
return #self._accounts
end
function PlayerListUI:_getTableElementSize()
return self._itemSize
end
---_setTableElement
---@param node UINode
---@param index number
function PlayerListUI:_setTableElement(node, index)
node.tag = index
node:getChild("img_player_icon_holder").isContainer = true
node:getChild("img_player_icon_holder.bg"):getPostDrawLayer(0):addListener(
{ self._onRenderPlayerBone, self, index })
local lbText = UIText.cast(node:getChild("lb_player_name"))
lbText.text = self._accounts[index].name
node.allowDoubleClick = true
node:addTouchUpListener({ self._onElementClicked, self })
node:addTouchDoubleDownListener({ self._onElementDoubleClicked, self })
node:getChild("btn_cfg"):addTouchUpListener({ self._onConfigButtonClicked, self, index })
node:getChild("btn_remove"):addTouchUpListener({ self._onRemoveButtonClicked, self, index })
end
function PlayerListUI:_onRenderPlayerBone(index)
local playerBone = self._accounts[index].playerBone
playerBone.joints:render()
--playerBone.joints:renderDebug()
end
function PlayerListUI:_onPlayerBoneUpdate()
for index = 1, #self._accounts do
local elementNode = UIUtil.getTableElement(self._panelList, index)
local screenPos = self.manager:getScreenPosition(elementNode)
---@type JointBody2D
local playerBone = self._accounts[index].playerBone
playerBone.joints.position = screenPos + Vector2.new(48, 112)
playerBone.joints.scale = Vector2.new(1.5, 1.5)
playerBone:update()
end
end
---_onElementClicked
---@param node UINode
function PlayerListUI:_onElementClicked(node)
local index = node.tag
if self._indexSelected ~= index then
self.manager:playClickSound()
self._indexSelected = index
self:updateSelection()
end
end
---_onElementClicked
---@param node UINode
function PlayerListUI:_onElementDoubleClicked(node)
self:_onElementClicked(node, nil)
self:_onOkButtonClicked()
end
function PlayerListUI:_onOkButtonClicked()
if self._indexSelected > 0 then
MenuJoinInfo.getInstance().playerInfo.name = self._accounts[self._indexSelected].name
self:closeWindow()
self.manager:playClickSound()
if not MenuJoinInfo.getInstance().serverInfo.isMultiplayer then
require("WorldListUI").new()
else
require("ServerListUI").new()
end
end
end
function PlayerListUI:_onNewButtonClicked()
self:closeWindow()
self.manager:playClickSound()
require("NewPlayerUI").new()
end
function PlayerListUI:_onConfigButtonClicked(index)
end
---@param index number
function PlayerListUI:_onRemoveButtonClicked(index)
if self._indexSelected == index then
local name = self._accounts[index].name
self.manager:playClickSound()
local InfoPopupUI = require("InfoPopupUI")
local infoUI = InfoPopupUI.new(
Locale.SURE_TO_DELETE_PLAYER_1 .. "\"" .. name .. "\"" .. Locale.SURE_TO_DELETE_PLAYER_2,
function()
if name ~= nil and name ~= "" then
print("remove player", name)
AccountUtils.Remove(name)
end
end,
function()
PlayerListUI.new()
end
)
self:closeWindow()
end
end
function PlayerListUI:_onBackButtonClicked()
MenuJoinInfo.getInstance().playerInfo.name = ""
self.manager:playClickSound()
self:closeWindow()
require("StartUI").new()
end
function PlayerListUI:updateSelection()
for index = 1, #self._accounts do
local node = self._panelList:getChildByTag(index)
local show = false
if node.tag == self._indexSelected then
show = true
end
node:getChild("img_selected").visible = show
node:getChild("btn_remove").visible = show
node:getChild("btn_cfg").visible = show
end
local btnColor = self._indexSelected and Color.White or Color.Gray
UIText.cast(self.root:getChild("layer.btn_ok.lb_caption")).color = btnColor
end
function PlayerListUI:closeWindow()
PlayerListUI.super.closeWindow(self)
end
return PlayerListUI
================================================
FILE: ui/RawHotkeyUIHelper.lua
================================================
local RawHotkeyUIHelper = class("HotkeyUIHelper")
function RawHotkeyUIHelper:__init(uiWindow)
self._uiWindow = uiWindow
self._closeHotkey = Input.keyboard:getHotKeys(Keys.Escape):addListener({ RawHotkeyUIHelper._closeMe, self })
end
function RawHotkeyUIHelper:destroy()
if self._closeHotkey then
Input.keyboard:getHotKeys(Keys.Escape):removeListener(self._closeHotkey)
self._closeHotkey = nil
end
end
function RawHotkeyUIHelper:_closeMe()
self._uiWindow:closeWindow()
end
return RawHotkeyUIHelper
================================================
FILE: ui/ServerListUI.lua
================================================
---@class TC.ServerListUI:TC.UIWindow
local ServerListUI = class("ServerListUI", require("UIWindow"))
local UIUtil = require("UIUtil")
function ServerListUI:__init()
ServerListUI.super.__init(self, require("UIDesign").getServerListUI())
self.indexSelected = 0
self.itemNodes = {}
self:initContent()
end
function ServerListUI:initContent()
local panelList = self.root:getChild("layer.panel_list")
local panelItem = panelList:getChild("panel_item")
self.itemSize = Size.new(panelItem.width / 1, panelItem.height)
UIUtil.setTable(panelList, self, true, 1)
self:updateSelection()
self.root:getChild("layer.btn_back"):addTouchUpListener({
function(self)
local PlayerListUI = require("PlayerListUI")
self:closeWindow()
PlayerListUI.new()
end, self }
)
self.root:getChild("layer.btn_create"):addTouchUpListener({
function(self)
local NewServerUI = require("NewServerUI")
self:closeWindow()
NewServerUI.new()
end, self
})
end
function ServerListUI:_getTableElementCount()
return 5
end
function ServerListUI:_getTableElementSize()
return self.itemSize
end
---_setTableElement
---@param node UINode
---@param index number
function ServerListUI:_setTableElement(node, index)
node.tag = index
node:addTouchUpListener({ self._onElementClicked, self })
node:getChild("btn_remove"):addTouchUpListener({
function(self)
local InfoPopupUI = require("InfoPopupUI")
InfoPopupUI.new()
end, self
})
table.insert(self.itemNodes, node)
end
---_onElementClicked
---@param node UINode
---@param _ Touch
function ServerListUI:_onElementClicked(node)
local index = node.tag
self.indexSelected = index
self:updateSelection()
end
function ServerListUI:updateSelection()
---@param node UINode
for _, node in pairs(self.itemNodes) do
local show = false
if node.tag == self.indexSelected then
show = true
end
node:getChild("img_selected").visible = show
node:getChild("btn_remove").visible = show
node:getChild("btn_cfg").visible = show
end
end
function ServerListUI:closeWindow()
ServerListUI.super.closeWindow(self)
end
return ServerListUI
================================================
FILE: ui/SettingUI.lua
================================================
---@class TC.SettingUI:TC.UIWindow
local SettingUI = class("SettingUI", require("UIWindow"))
local UIUtil = require("UIUtil")
local Settings = require("settings.Settings")
function SettingUI:__init(closeCallback)
SettingUI.super.__init(self, require("UIDesign").getSettingUI(), require("ui.UIDefault").GROUP_GAME_WINDOW)
self._closeCallback = closeCallback
self._settingInstance = Settings.getInstance()
self._config = self._settingInstance.uiConfig
self._infoList = UIScrollView.cast(self.root:getChild("layer.info_list"))
self._panelSlider = self._infoList:getChild("panel_slider")
self._panelBool = self._infoList:getChild("panel_bool")
self._panelHold = self._infoList:getChild("panel_hold")
self._indexSelected = 1
self._itemNodes = {}
self._sliderSoundTicks = 0
self:initContent()
end
function SettingUI:initContent()
local panelList = self.root:getChild("layer.panel_list")
local panelItem = panelList:getChild("panel_item")
self.itemSize = Size.new(panelItem.width, panelItem.height)
UIUtil.setTable(panelList, self, true, 1)
self.root:getChild("layer.btn_ok"):addTouchUpListener({ self._onBackClicked, self })
self:updateSelection()
end
function SettingUI:_getTableElementCount()
return #self._config
end
function SettingUI:_getTableElementSize()
return self.itemSize
end
---_setTableElement
---@param node UINode
---@param index number
function SettingUI:_setTableElement(node, index)
node.tag = index
local data = self._config[index]
local lbName = UIText.cast(node:getChild("lb_group_name"))
lbName.text = data.name
node:addTouchUpListener({ self._onElementClicked, self })
table.insert(self._itemNodes, node)
end
---_onElementClicked
---@param node UINode
---@param _ Touch
function SettingUI:_onElementClicked(node)
local index = node.tag
if self._indexSelected ~= index then
self.manager:playClickSound()
self._indexSelected = index
self:updateSelection()
end
end
function SettingUI:updateSelection()
---@param node UINode
for _, node in pairs(self._itemNodes) do
local show = false
if node.tag == self._indexSelected then
show = true
end
node:getChild("img_selected").visible = show
end
self:updateInfoList()
end
function SettingUI:updateInfoList()
self._panelSlider.visible = false
self._panelBool.visible = false
self._panelHold:removeAllChildren()
local elements = self._config[self._indexSelected].elements
local posY = 0
for i, element in ipairs(elements) do
local node ---@type UINode
if element.type == "Slider" then
node = self._panelSlider:clone()
local s = UISlider.cast(node:getChild("slider"))
if element.maxValue ~= nil then
s.maxValue = element.maxValue
end
if element.minValue ~= nil then
s.minValue = element.minValue
end
if element.getter ~= nil then
s.value = element.getter()
end
s.valueStep = 1
if element.valueStep ~= nil then
s.valueStep = element.valueStep
end
s:addValueChangedListener({ self._onSliderChanged, self, i })
elseif element.type == "Boolean" then
node = self._panelBool:clone()
local s = UISwitch.cast(node:getChild("sw"))
if element.getter ~= nil then
s:setSelected(element.getter(), false)
end
s:addSelectChangedListener({ self._onSwitchChanged, self, i })
end
UIText.cast(node:getChild("lb_title")).text = element.name
self._panelHold:addChild(node)
node.visible = true
node.positionY = posY
posY = posY + node.height
end
self._panelHold.height = posY
self._infoList:ScrollToTop()
local tmpSize = Size.new(self._infoList.viewSize.width, self._panelHold.height)
tmpSize.height = math.max(tmpSize.height, self._infoList.height)
self._infoList.viewSize = tmpSize
self._infoList:ScrollToTop()
end
function SettingUI:_onSwitchChanged(index, _, selected)
self.manager:playClickSound()
local elements = self._config[self._indexSelected].elements
local element = elements[index]
if element.setter ~= nil then
element.setter(selected)
end
end
function SettingUI:_onSliderChanged(index, _, value)
local elements = self._config[self._indexSelected].elements
local element = elements[index]
if element.setter ~= nil then
element.setter(value)
end
self._sliderSoundTicks = self._sliderSoundTicks + 1
if self._sliderSoundTicks > 8 then
self._sliderSoundTicks = 0
SoundUtils.PlaySoundGroup(Reg.SoundGroupID("wood"))
end
end
function SettingUI:_onBackClicked()
self.manager:playClickSound()
Settings.saveData()
self:closeWindow()
end
function SettingUI:closeWindow()
if self._closeCallback ~= nil then
self._closeCallback()
end
SettingUI.super.closeWindow(self)
end
return SettingUI
================================================
FILE: ui/StartUI.lua
================================================
---@class TC.StartUI:TC.UIWindow
local StartUI = class("StartUI", require("UIWindow"))
local Locale = require("languages.Locale")
local UISpritePool = require("ui.UISpritePool")
function StartUI:__init()
StartUI.super.__init(self, require("UIDesign").getStartUI())
self._logoTexture = nil
self._subLogoTexture = nil
self._ticks = 0
self._logoSize = 1
self._logoAngle = 0
self:initContent()
end
function StartUI:initContent()
self._logoTexture = UISpritePool.getInstance():get("tc:logo4").textureLocation
self._subLogoTexture = UISpritePool.getInstance():get("tc:sublogo").textureLocation
UIText.cast(self.root:getChild("lb_mod")).text = string.format(Locale.MOD_LOADER_INFO, Mod.modList.count)
print(App.engineVersion)
UIText.cast(self.root:getChild("lb_engine_ver")).text = string.format(Locale.ENGINE_VERSION, App.engineVersion)
UIText.cast(self.root:getChild("lb_game_ver")).text = string.format(Locale.GAME_VER, Mod.current.gameVersion .. " " .. Mod.current.version)
self.root:getChild("layer.btn_single"):addTouchUpListener({
function(self)
self:_jumpTo(require("PlayerListUI"))
end, self
})
self.root:getChild("layer.btn_mul_player"):addTouchUpListener({
function(self)
require("tc.ui.InfoPopupUI").new("功能开发中,敬请期待!")
--self:_jumpTo(require("ServerListUI"))
end, self
})
self.root:getChild("layer.btn_community"):addTouchUpListener({
function(self)
require("tc.ui.InfoPopupUI").new("欢迎加入正式论坛:https://terracraft.eu.org/")
--self:_jumpTo(require("ServerListUI"))
end, self
})
self.root:getChild("layer.btn_lang"):addTouchUpListener({
function(self)
require("tc.ui.InfoPopupUI").new("功能开发中,敬请期待!")
--self:_jumpTo(require("LanguageUI"))
end, self
})
self.root:getChild("layer.btn_mod"):addTouchUpListener({
function(self)
self:_jumpTo(require("ModListUI"))
end, self
})
self.root:getChild("layer.btn_setting"):addTouchUpListener({
function(self)
self:closeWindow()
self.manager:playClickSound()
require("SettingUI").new(function()
StartUI.new()
end)
end, self
})
self.root:getChild("layer.btn_exit"):addTouchUpListener({
function()
ClientStateManager.QuitGame()
end
})
self.root:getPreDrawLayer(0):addListener({ StartUI.renderLogo, self })
self:initUpdateFunc({ self._onUpdate, self })
end
function StartUI:_onUpdate()
self._logoSize = 1.05 + Utils.SinValue(self._ticks, 256) * 0.05
self._logoAngle = Utils.CosValue(self._ticks, 512) * 0.05
self._ticks = self._ticks + 1
end
function StartUI:renderLogo()
-- render the main logo
local texSize = TextureManager.getSourceRect(self._logoTexture)
local pos = Vector2.new(GameWindow.displayResolution.width / 2, 60)
local exLogo = SpriteExData.new()
exLogo.angle = self._logoAngle
exLogo.origin = Vector2.new(texSize.width / 2, texSize.height / 2)
exLogo.scaleRate = Vector2.new(self._logoSize, self._logoSize)
Sprite.draw(self._logoTexture, Vector2.new(GameWindow.displayResolution.width / 2, 60),
texSize, Color.White, exLogo, 0)
-- render the sub logo
local texSubLogoSize = TextureManager.getSourceRect(self._subLogoTexture)
local exSubLogo = SpriteExData.new()
exSubLogo.origin = Vector2.new(texSubLogoSize.width / 2, texSubLogoSize.height / 2)
exSubLogo.scaleRate = Vector2.new(1.3, 1.3)
Sprite.draw(self._subLogoTexture, Vector2.new(GameWindow.displayResolution.width / 2, 100),
texSubLogoSize, Color.White, exSubLogo, 0)
end
function StartUI:_jumpTo(WindowClass)
self.manager:playClickSound()
self:closeWindow()
WindowClass.new()
end
function StartUI:closeWindow()
StartUI.super.closeWindow(self)
end
return StartUI
================================================
FILE: ui/TipUI.lua
================================================
---@class TC.TipUI:TC.UIWindow
local TipUI = class("TipUI", require("UIWindow"))
---@type TC.TipUI
local s_tipUI
function TipUI.generate(contentTable, keepTicks, showTag)
keepTicks = keepTicks or 128
-- TEST CODE
contentTable = contentTable or {
"Copper Axe",
" ",
"Durability: 6666/9999",
"+3 Attack Damage",
"+6 Crit Rate",
"普通速度",
"普通攻击力",
"Can be placed",
"Debug Only"
}
TipUI.close()
s_tipUI = TipUI.new(keepTicks, contentTable, showTag)
return s_tipUI
end
function TipUI.adaptPosition(pos)
if s_tipUI ~= nil then
s_tipUI:_adaptPosition(pos.x, pos.y)
end
end
function TipUI.close()
if s_tipUI ~= nil then
s_tipUI:closeWindow()
end
end
function TipUI.isShowing()
return s_tipUI ~= nil
end
function TipUI.changeNewContent(contentTable)
if s_tipUI ~= nil then
s_tipUI:setNewContent(contentTable)
end
end
function TipUI.getShowTag()
if s_tipUI ~= nil then
return s_tipUI.showTag
end
return 0
end
function TipUI.resetKeepTime()
if s_tipUI ~= nil then
s_tipUI:_resetKeepTime()
end
end
function TipUI:__init(keepTicks, contentTable, showTag)
TipUI.super.__init(self, require("UIDesign").getTipUI())
if showTag == nil then
showTag = 0
end
self.maxKeepTicks = keepTicks
self.keepTicks = keepTicks
self.contentTable = clone(contentTable)
self.touchingPosition = Vector2.new()
self.showTag = showTag
self.baseLabel = UIText.cast(self.root:getChild("lb_tip"))
self._totalLabels = 0
self:_initContent()
end
function TipUI:_initContent()
self:_setContent()
self._schedule = IntegratedClient.main:createSchedule(0)
IntegratedClient.main:getSchedule(self._schedule):addListener({ TipUI._onTick, self })
end
function TipUI:setNewContent(contentTable)
if #self.contentTable == #contentTable then
local same = true
for i, str in ipairs(self.contentTable) do
local str2 = contentTable[i]
if str ~= str2 then
same = false
break
end
end
if same then
return
end
end
self.contentTable = contentTable
self:_setContent()
end
function TipUI:_setContent()
local label = self.baseLabel
label.visible = false
local LINE_OFFSET = 2
local maxTextWidth = 0
local offsetY = label.positionY
for i = 1, self._totalLabels do
local node = self.root:getChild(string.format("content_%d", i))
if node:valid() then
node.visible = false
self.root:removeChild(node)
end
end
self._totalLabels = #self.contentTable
-- generate all text from content table
for i, str in ipairs(self.contentTable) do
local currentLabel = self.root:getChild(string.format("content_%d", i))
if not currentLabel:valid() then
currentLabel = label:clone()
currentLabel.name = string.format("content_%d", i)
self.root:addChild(currentLabel)
end
currentLabel.visible = true
currentLabel.isRichText = true
currentLabel.text = str
currentLabel.position = Vector2(label.positionX, offsetY)
maxTextWidth = math.max(currentLabel.width, maxTextWidth)
offsetY = offsetY + currentLabel.height + LINE_OFFSET
end
self.root:setSize(maxTextWidth + 20, offsetY + 6)
end
function TipUI:_onTick()
self.keepTicks = self.keepTicks - 1
if self.keepTicks <= 0 then
self:closeWindow()
end
end
function TipUI:_resetKeepTime()
self.keepTicks = self.maxKeepTicks
end
---adaptPosition
---@param touchX double
---@param touchY double
function TipUI:_adaptPosition(touchX, touchY)
if self.touchingPosition.x ~= touchX or self.touchingPosition.y ~= touchY then
self.touchingPosition.x = touchX
self.touchingPosition.y = touchY
local size = self.root.size
local globalWidth, globalHeight = GameWindow.displayResolution.width, GameWindow.displayResolution.height
local uiWidth, uiHeight = size.width, size.height
local newX, newY = touchX, touchY
newX = touchX + 32
newY = touchY - uiHeight * 0.75
-- left boundary
newX = math.max(newX, 32)
-- right boundary
if newX + uiWidth + 32 > globalWidth then
newX = touchX - 32 - uiWidth
end
-- top boundary
newY = math.max(newY, 32)
-- bottom boundary
if newY + uiHeight + 32 > globalHeight then
newY = touchY - 32 - uiHeight
end
self.root.position = Vector2.new(newX, newY)
self.root:applyMargin()
end
end
function TipUI:closeWindow()
TipUI.super.closeWindow(self)
if self._schedule ~= nil then
IntegratedClient.main:removeSchedule(self._schedule)
self._schedule = nil
end
s_tipUI = nil
end
return TipUI
================================================
FILE: ui/TipsOfTheDay.lua
================================================
---@class TC.TipsOfTheDay
local TipsOfTheDay = class("TipsOfTheDay")
function TipsOfTheDay:__init()
self.texts = {
"你可以点击上方的\"?\"按钮查看接下来的目标。",
"使用末影传送门快速移动到世界各地。",
"拥有共享背包模式的世界可以与其他世界共享玩家背包信息。",
"你可以使用铁砧来恢复工具的耐久值。",
"要致富,先砍树!造一个庇护所来度过你的第一个晚上!",
"PC端和手机端的存档支持互通!",
"你可以通过挖掘生命水晶来增加你的生命值上限。",
"死亡会损失20%的经验值。",
"尝试制作一个红石电路系统!",
"你可以使用酿造台来制作不同的药水。",
"你可以点击上方的配方按钮来查看所有物品配方。",
"点击灯泡按钮,试试智能光标模式!",
"食用魔法碎片可以增加你的魔力值上限。",
"远程武器使用对应子弹或弓箭,将额外拥有30%伤害加成。",
}
end
function TipsOfTheDay:getRandomText()
return self.texts[math.random(1, #self.texts)]
end
return TipsOfTheDay
================================================
FILE: ui/UIDefault.lua
================================================
---@class TC.UIDefault
local UIDefault = {
FontSize = 24,
SmallFontSize = 18,
ButtonHeight = 48,
ButtonOffset = 60,
CellSize = 46,
CellLargeSize = 56,
CellOffset = 48,
CellHugeSize = 64,
CellHugeOffset = 68,
GROUP_NONE = 0,
GROUP_GAME_WINDOW = 1,
GROUP_GAME_HUD = 2,
}
return UIDefault
================================================
FILE: ui/UIDesign.lua
================================================
---@class TC.UIDesign
local UIDesign = class("UIDesign")
local UIUtil = require("UIUtil")
local UIDefault = require("UIDefault")
local Locale = require("languages.Locale")
local UISpritePool = require("UISpritePool").getInstance()
function UIDesign.getStartUI()
local UI_SIZE = Size.new(400, 400)
local root = UIPanel.new("start_ui")
root.size = GameWindow.displayResolution
root:setMarginEnabled(true, true, true, true)
root:setAutoStretch(true, true)
local panel = UIUtil.createPanel("layer", 0, 0, UI_SIZE.width, UI_SIZE.height, {
margins = { 0, 128, 0, 64, false, false }
})
root:addChild(panel)
local sy = 32
panel:addChild(UIUtil.createButton("btn_single", Locale.SINGLE_PLAYER, 0, sy, UI_SIZE.width, UIDefault.ButtonHeight, {
anchorPoint = { 0.5, 0 },
marginsLR = { 0, 0, false }
}))
sy = sy + UIDefault.ButtonOffset
panel:addChild(UIUtil.createButton("btn_mul_player", Locale.MULTI_PLAYER, 0, sy, UI_SIZE.width, UIDefault.ButtonHeight, {
anchorPoint = { 0.5, 0 },
marginsLR = { 0, 0, false }
}))
sy = sy + UIDefault.ButtonOffset
panel:addChild(UIUtil.createButton("btn_mod", Locale.MOD_LIST, 0, sy, UI_SIZE.width, UIDefault.ButtonHeight, {
anchorPoint = { 0.5, 0 },
marginsLR = { 0, 0, false }
}))
sy = sy + UIDefault.ButtonOffset
panel:addChild(UIUtil.createButton("btn_community", Locale.COMMUNITY, 0, sy, UI_SIZE.width, UIDefault.ButtonHeight, {
anchorPoint = { 0.5, 0 },
marginsLR = { 0, 0, false }
}))
sy = sy + UIDefault.ButtonOffset + 16
panel:addChild(UIUtil.createButtonWithImage("btn_lang", "tc:lang", 0, sy, UIDefault.ButtonHeight, UIDefault.ButtonHeight, {
marginsLR = { -UIDefault.ButtonHeight - 16, nil }
}))
panel:addChild(UIUtil.createButton("btn_setting", Locale.SETTING, 0, sy, UI_SIZE.width / 2 - 8, UIDefault.ButtonHeight, {
marginsLR = { 0, UI_SIZE.width / 2 + 8 }
}))
panel:addChild(UIUtil.createButton("btn_exit", Locale.EXIT_GAME,
0, sy, UI_SIZE.width / 2 - 8, UIDefault.ButtonHeight, {
marginsLR = { UI_SIZE.width / 2 + 8, 0 }
}))
root:addChild(UIUtil.createLabelNoPos("lb_copyright", Locale.COPYRIGHT,
TextAlignment.Left, TextAlignment.Bottom, {
margins = { 16, nil, nil, 0 }
}))
root:addChild(UIUtil.createLabelNoPos("lb_mod", Locale.MOD_LOADER_INFO,
TextAlignment.Left, TextAlignment.Bottom, {
margins = { 16, nil, nil, 32 }
}))
root:addChild(UIUtil.createLabelNoPos("lb_engine_ver", Locale.ENGINE_VERSION,
TextAlignment.Right, TextAlignment.Bottom, {
margins = { nil, nil, 16, 0 }
}))
root:addChild(UIUtil.createLabelNoPos("lb_game_ver", Locale.ENGINE_VERSION,
TextAlignment.Right, TextAlignment.Bottom, {
margins = { nil, nil, 16, 32 }
}))
return root
end
function UIDesign.getPendingUI()
local UI_SIZE = Size.new(400, 400)
local root = UIUtil.createBlackFullScreenLayer("pending_ui")
root.size = GameWindow.displayResolution
root:setMarginEnabled(true, true, true, true)
root:setAutoStretch(true, true)
local panel = UIUtil.createPanel("layer", 0, 0, UI_SIZE.width, UI_SIZE.height, {
margins = { 0, 0, 0, 0, false, false }
})
root:addChild(panel)
panel:addChild(UIUtil.createPanel("panel_animation", 0, 170, 32, 32, {
marginsLR = { 0, 0 }
}))
panel:addChild(UIUtil.createLabel("lb_tip", Locale.LOADING,
0, 250, UI_SIZE.width, 32, TextAlignment.HCenter, TextAlignment.VCenter, {
}))
panel:addChild(UIUtil.createButton("btn_back", Locale.BACK, 0, 0, UI_SIZE.width, UIDefault.ButtonHeight, {
anchorPoint = { 0.5, 0 },
margins = { 0, nil, 0, 50, false, false }
}))
return root
end
function UIDesign.getOptionUI()
local UI_SIZE = Size.new(400, 400)
local root = UIUtil.createBlackFullScreenLayer("option_ui")
root.size = GameWindow.displayResolution
root:setMarginEnabled(true, true, true, true)
root:setAutoStretch(true, true)
local panel = UIUtil.createPanel("layer", 0, 0, UI_SIZE.width, UI_SIZE.height, {
margins = { 0, 128, 0, 64, false, false }
})
root:addChild(panel)
local sy = 32
panel:addChild(UIUtil.createButton("btn_back", Locale.BACK_TO_GAME, 0, sy, UI_SIZE.width, UIDefault.ButtonHeight, {
anchorPoint = { 0.5, 0 },
marginsLR = { 0, 0, false }
}))
sy = sy + UIDefault.ButtonOffset
panel:addChild(UIUtil.createButton("btn_setting", Locale.SETTING, 0, sy, UI_SIZE.width, UIDefault.ButtonHeight, {
anchorPoint = { 0.5, 0 },
marginsLR = { 0, 0, false }
}))
sy = sy + UIDefault.ButtonOffset
panel:addChild(UIUtil.createButton("btn_recipe", Locale.RECIPE_SEARCH .. "(R)", 0, sy, UI_SIZE.width, UIDefault.ButtonHeight, {
anchorPoint = { 0.5, 0 },
marginsLR = { 0, 0, false }
}))
sy = sy + UIDefault.ButtonOffset
panel:addChild(UIUtil.createButton("btn_advancement", Locale.ADVANCEMENT .. "(F)", 0, sy, UI_SIZE.width, UIDefault.ButtonHeight, {
anchorPoint = { 0.5, 0 },
marginsLR = { 0, 0, false }
}))
sy = sy + UIDefault.ButtonOffset
panel:addChild(UIUtil.createButton("btn_save_and_exit", Locale.SAVE_AND_EXIT, 0, sy, UI_SIZE.width, UIDefault.ButtonHeight, {
anchorPoint = { 0.5, 0 },
marginsLR = { 0, 0, false }
}))
panel:addChild(UIUtil.createLabelNoPos("lb_caption", Locale.GAME_MENU,
TextAlignment.HCenter, TextAlignment.VCenter, {
margins = { 0, -20, 0, nil }
}))
return root
end
function UIDesign.getLanguageUI()
local UI_SIZE = Size.new(600, 450)
local root = UIPanel.new("language_ui")
root.size = GameWindow.displayResolution
root:setMarginEnabled(true, true, true, true)
root:setAutoStretch(true, true)
root.sprite = UISpritePool:get("tc:black")
root.sprite.color = Color.new(255, 255, 255, 200)
local panel = UIUtil.createPanel("layer", 0, 0, UI_SIZE.width, UI_SIZE.height, {
margins = { 0, 0, 0, 0, false, false }
})
root:addChild(panel)
panel:addChild(UIUtil.createImageNoPos("bg_frame", {
margins = { 0, 0, 0, 0 },
sprite = {
name = "tc:window_frame_01",
color = Color.new(255, 255, 255, 240)
}
}))
panel:addChild(UIUtil.createImageNoPos("bg", {
margins = { 2, 2, 2, 2 },
sprite = {
name = "tc:window_bg_01",
color = Color.new(255, 255, 255, 30),
style = UISpriteStyle.Filled
}
}))
panel:addChild(UIUtil.createButton("btn_ok", Locale.OK, 0, 200, UI_SIZE.width, UIDefault.ButtonHeight, {
anchorPoint = { 0.5, 0 },
margins = { 16, nil, 16, 16 },
targetSprite = {
color = Color.new(110, 108, 132, 255)
}
}))
panel:addChild(UIUtil.createLabelNoPos("lb_title", Locale.SELECT_LANGUAGE,
TextAlignment.HCenter, TextAlignment.VCenter, {
positionY = 12,
fontSize = UIDefault.FontSize + 8,
marginsLR = { 0, 0 }
}))
panel:addChild(UIUtil.createLabelNoPos("lb_list_title", Locale.LANGUAGE_LIST,
TextAlignment.Left, TextAlignment.Top, {
margins = { 16, 64, 16, nil },
color = Color.Gray
}))
panel:addChild(UIUtil.createImage("img_line", 0, 76, 128, 1, {
marginsLR = { 100, 16 },
sprite = {
name = "tc:white",
color = Color.Gray
}
}))
panel:addChild(UIUtil.createLabelNoPos("lb_tips",
Locale.LANGUAGE_MAY_WRONG,
TextAlignment.HCenter, TextAlignment.Top, {
margins = { 16, nil, 16, 80 },
color = Color.new(128, 128, 0)
}))
local panelList = UIUtil.createScrollViewNoPos("panel_list", {
margins = { 16, 96, 16, 128 },
})
panel:addChild(panelList)
local panelItem = UIPanel.new("panel_item", 0, 0, panelList.size.width, 64)
panelList:addChild(panelItem)
panelItem:addChild(UIUtil.createImageNoPos("img_selected", {
margins = { 0, 0, 0, 0 },
touchable = false,
visible = false,
sprite = {
name = "tc:round_rect_white",
color = Color.new(48, 48, 60, 222)
}
}))
panelItem:addChild(UIUtil.createLabelNoPos("lb_locale", "English",
TextAlignment.HCenter, TextAlignment.VCenter, {
margins = { 0, 0, 0, 0 }
}))
return root
end
function UIDesign.getPlayerListUI()
local UI_SIZE = Size.new(800, 450)
local root = UIUtil.createBlackFullScreenLayer("player_list_ui")
local panel = UIUtil.createWindowPattern(root, UI_SIZE, nil)
panel:addChild(UIUtil.createLabelNoPos("lb_title", Locale.SELECT_PLAYER,
TextAlignment.HCenter, TextAlignment.VCenter, {
positionY = 12,
marginsLR = { 0, 0 },
fontSize = UIDefault.FontSize + 8
}))
local panelList = UIUtil.createScrollViewNoPos("panel_list", {
margins = { 16, 64, 16, 80 },
sprite = {
name = "tc:round_rect_white",
color = Color.new(30, 30, 45)
}
})
panel:addChild(panelList)
local panelItem = UIPanel.new("panel_item", 0, 0, panelList.size.width, 96)
panelList:addChild(panelItem)
panelItem:addChild(UIUtil.createImageNoPos("img_selected", {
margins = { 0, 0, 0, 0 },
touchable = false,
sprite = {
name = "tc:round_rect_white",
color = Color.new(60, 60, 80, 222)
}
}))
panelItem:addChild(UIUtil.createImage("img_line", 0, 96, 100, 2, {
marginsLR = { 16, 16 },
sprite = {
name = "tc:white",
color = Color.new(60, 60, 80, 100)
}
}))
local playerIconHolder = UIUtil.createImage("img_player_icon_holder", 16, 16, 64, 64, {
touchable = false
})
panelItem:addChild(playerIconHolder)
playerIconHolder:addChild(UIUtil.createImageNoPos("bg", {
margins = { 0, 0, 0, 0 },
touchable = false,
sprite = {
name = "tc:round_rect_white",
color = Color.new(10, 10, 25)
}
}))
panelItem:addChild(UIUtil.createLabel("lb_player_name", "BlueYoshiSuperLazyJuju",
96, 32, 128, 24,
TextAlignment.Left, TextAlignment.VCenter))
--panelItem:addChild(UIUtil.createImage("img_hp", 96, 48, 32, 32, {
-- touchable = false,
-- sprite = { name = "tc:health" }
--}))
--panelItem:addChild(UIUtil.createLabel("lb_hp", "200/200",
-- 130, 48, 96, 32,
-- TextAlignment.Left, TextAlignment.VCenter, {
-- color = Color.new(200, 100, 100)
-- }))
--panelItem:addChild(UIUtil.createImage("img_mana", 226, 48, 32, 32, {
-- touchable = false,
-- sprite = { name = "tc:mana" }
--}))
--panelItem:addChild(UIUtil.createLabel("lb_mana", "100/100",
-- 260, 48, 96, 32,
-- TextAlignment.Left, TextAlignment.VCenter, {
-- color = Color.new(100, 100, 200)
-- }))
--panelItem:addChild(UIUtil.createImage("img_exp", 356, 48, 32, 32, {
-- touchable = false,
-- sprite = { name = "tc:exp" }
--}))
--panelItem:addChild(UIUtil.createLabel("lb_exp", "Lv.12",
-- 384, 48, 96, 32,
-- TextAlignment.Left, TextAlignment.VCenter, {
-- color = Color.new(150, 150, 75)
-- }))
--panelItem:addChild(UIUtil.createLabel("lb_tips", "背包共享",
-- 460, 48, 96, 32,
-- TextAlignment.Left, TextAlignment.VCenter, {
-- color = Color.FrenchGray
-- }))
panelItem:addChild(UIUtil.createButtonWithImage("btn_remove", "tc:delete",
700, 0, 48, 48, {
marginsTB = { 16, 16, false },
targetSprite = { color = Color.new(110, 108, 132, 255) }
}, {
sprite = { color = Color.new(180, 168, 232, 255) }
}))
panelItem:addChild(UIUtil.createButtonWithImage("btn_cfg", "tc:conf",
640, 0, 48, 48, {
marginsTB = { 16, 16, false },
targetSprite = { color = Color.new(110, 108, 132, 255) }
}, {
sprite = { color = Color.new(180, 168, 232, 255) }
}))
panel:addChild(UIUtil.createButton("btn_back", Locale.BACK, 0, 200, 220, UIDefault.ButtonHeight, {
anchorPoint = { 0.5, 0 },
margins = { 0, nil, UI_SIZE.width * 0.66, 16, false, false },
targetSprite = { color = Color.new(110, 108, 132, 255) },
}))
panel:addChild(UIUtil.createButton("btn_create", Locale.NEW_PLAYER_B, 0, 200, 220, UIDefault.ButtonHeight, {
anchorPoint = { 0.5, 0 },
margins = { 0, nil, 0, 16, false, false },
targetSprite = { color = Color.new(110, 108, 132, 255) },
}))
panel:addChild(UIUtil.createButton("btn_ok", Locale.SELECT_PLAYER, 0, 200, 220, UIDefault.ButtonHeight, {
anchorPoint = { 0.5, 0 },
margins = { UI_SIZE.width * 0.66, nil, 0, 16, false, false },
targetSprite = { color = Color.new(110, 108, 132, 255) },
}))
return root
end
function UIDesign.getNewPlayerUI()
local UI_SIZE = Size.new(800, 450)
local root = UIUtil.createBlackFullScreenLayer("new_player_ui")
local panel = UIUtil.createWindowPattern(root, UI_SIZE, nil)
panel:getChild("bg_frame"):setRightMargin(200, true)
root:addChild(panel)
panel:addChild(UIUtil.createLabelNoPos("lb_title", Locale.CREATE_PLAYER,
TextAlignment.HCenter, TextAlignment.VCenter, {
positionY = 12,
marginsLR = { 0, 200 },
fontSize = UIDefault.FontSize + 8
}))
panel:addChild(UIUtil.createButton("btn_back", Locale.BACK, 32, 200, 250, UIDefault.ButtonHeight, {
anchorPoint = { 0.5, 0 },
margins = { nil, nil, nil, 16, false, false },
targetSprite = { color = Color.new(110, 108, 132, 255) },
}))
panel:addChild(UIUtil.createButton("btn_ok", Locale.CREATE_PLAYER, 320, 200, 250, UIDefault.ButtonHeight, {
anchorPoint = { 0.5, 0 },
margins = { nil, nil, nil, 16, false, false },
targetSprite = { color = Color.new(110, 108, 132, 255) },
}))
local panelList = UIUtil.createScrollView("panel_list", 0, 0, 240, 100, {
margins = { 16, 64, nil, 150 },
sprite = {
name = "tc:round_rect_white",
color = Color.new(30, 30, 45)
}
})
panel:addChild(panelList)
local panelItem = UIPanel.new("panel_item", 0, 0, panelList.size.width, 80)
panelList:addChild(panelItem)
panelItem:addChild(UIUtil.createImageNoPos("img_selected", {
margins = { 0, 0, 0, 0 },
touchable = false,
sprite = {
name = "tc:round_rect_white",
color = Color.new(60, 60, 80, 222)
},
visible = false
}))
panelItem:addChild(UIUtil.createImage("img_line", 0, 80, 100, 2, {
marginsLR = { 16, 16 },
sprite = {
name = "tc:white",
color = Color.new(60, 60, 80, 100)
}
}))
local playerIconHolder = UIUtil.createImage("img_player_icon_holder", 8, 8, 64, 64, {
touchable = false
})
panelItem:addChild(playerIconHolder)
playerIconHolder:addChild(UIUtil.createImageNoPos("bg", {
margins = { 0, 0, 0, 0 },
touchable = false,
sprite = {
name = "tc:round_rect_white",
color = Color.new(10, 10, 25)
}
}))
panelItem:addChild(UIUtil.createLabel("lb_name", "xqz",
80, 8, 128, 24,
TextAlignment.Left, TextAlignment.VCenter))
panelItem:addChild(UIUtil.createLabel("lb_author", "by Blueyoshi, xxx, zzz",
80, 32, 128, 24,
TextAlignment.Left, TextAlignment.VCenter, {
fontSize = 18,
color = Color.FrenchGray
}))
panelItem:addChild(UIUtil.createLabel("lb_mod", "Mod: Terraria",
80, 52, 128, 24,
TextAlignment.Left, TextAlignment.VCenter, {
fontSize = 18,
color = Color.Gray
}))
panel:addChild(UIUtil.createLabel("lb_gender", "性别:",
280, 176, 100, 32,
TextAlignment.Left, TextAlignment.VCenter))
panel:addChild(UIUtil.createButtonWithImage("btn_male", "tc:male",
360, 160, 56, 56, {
targetSprite = { color = Color.new(80, 88, 102, 255) },
}))
panel:addChild(UIUtil.createButtonWithImage("btn_female", "tc:female",
480, 160, 56, 56, {
targetSprite = { color = Color.new(80, 88, 102, 255) },
}))
panel:getChild("lb_gender").visible = false
panel:getChild("btn_male").visible = false
panel:getChild("btn_female").visible = false
panel:addChild(UIUtil.createLabel("lb_name", Locale.NAME_Q,
280, 100, 100, 32,
TextAlignment.Left, TextAlignment.VCenter))
local panelName = UIUtil.createPanel("panel_name", 340, 90, 200, 48, {
marginsLR = { 340, 216 },
sprite = {
name = "tc:round_rect_white",
color = Color.new(60, 60, 85)
}
})
panel:addChild(panelName)
panelName:addChild(UIUtil.createPanelNoPos("bg", {
margins = { 2, 2, 2, 2 },
sprite = {
name = "tc:round_rect_white",
color = Color.new(30, 30, 45)
}
}))
local editName = UIInputField.new("edit")
UIUtil.setMargins(editName, 8, 8, 8, 8)
panelName:addChild(editName)
panel:addChild(UIUtil.createButton("btn_move", Locale.MORE_SETTINGS, 0, 250, 276, UIDefault.ButtonHeight, {
anchorPoint = { 0.5, 0 },
marginsLR = { 272, 216 },
targetSprite = { color = Color.new(110, 108, 132, 255) },
visible = false
}))
panel:addChild(UIUtil.createPanel("pos_panel", 640, 125, 200, 200))
local panelInfo = UIUtil.createPanelNoPos("panel_info", {
margins = { 16, 310, 216, 80 },
sprite = {
name = "tc:round_rect_white",
color = Color.new(28, 28, 40, 222)
},
})
panel:addChild(panelInfo)
panelInfo:addChild(UIUtil.createPanelNoPos("bg", {
margins = { 4, 4, 4, 4 },
sprite = {
name = "tc:round_rect_white",
color = Color.new(10, 10, 20, 222)
}
}))
panelInfo:addChild(UIUtil.createLabelNoPos("lb_info", "名字不能超过1000个字符!",
TextAlignment.HCenter, TextAlignment.VCenter, {
margins = { 0, 0, 0, 0 },
color = Color.Yellow
}))
panel:addChild(UIUtil.createButton("btn_animator", Locale.CHANGE_POSTURE, 660, 350, 160, UIDefault.ButtonHeight, {
anchorPoint = { 0.5, 0 },
targetSprite = { color = Color.new(80, 88, 102, 255) },
}))
return root
end
function UIDesign.getWorldListUI()
local UI_SIZE = Size.new(800, 450)
local root = UIUtil.createBlackFullScreenLayer("world_list_ui")
local panel = UIUtil.createWindowPattern(root, UI_SIZE, nil)
panel:addChild(UIUtil.createLabelNoPos("lb_title", Locale.SELECT_WORLD,
TextAlignment.HCenter, TextAlignment.VCenter, {
positionY = 12,
marginsLR = { 0, 0 },
fontSize = UIDefault.FontSize + 8
}))
local panelList = UIUtil.createScrollViewNoPos("panel_list", {
margins = { 16, 64, 16, 80 },
sprite = {
name = "tc:round_rect_white",
color = Color.new(30, 30, 45)
}
})
panel:addChild(panelList)
local panelItem = UIPanel.new("panel_item", 0, 0, panelList.size.width, 128)
panelList:addChild(panelItem)
panelItem:addChild(UIUtil.createImageNoPos("img_selected", {
margins = { 0, 0, 0, 0 },
touchable = false,
visible = false,
sprite = {
name = "tc:round_rect_white",
color = Color.new(60, 60, 80, 222)
}
}))
panelItem:addChild(UIUtil.createImage("img_line", 0, 128, 100, 2, {
marginsLR = { 16, 16 },
sprite = {
name = "tc:white",
color = Color.new(60, 60, 80, 100)
}
}))
local imgWorldPic = UIUtil.createImage("img_world_pic", 16, 16, 96, 96, {
touchable = false,
sprite = {
name = "tc:round_rect_white",
color = Color.new(10, 10, 25)
}
})
panelItem:addChild(imgWorldPic)
imgWorldPic:addChild(UIUtil.createImageNoPos("img", {
margins = { 0, 0, 0, 0 },
touchable = false,
sprite = {
name = "tc:world_icon",
}
}))
panelItem:addChild(UIUtil.createLabel("lb_world_name", "SuperJujuWorld",
128, 16, 128, 24,
TextAlignment.Left, TextAlignment.VCenter))
panelItem:addChild(UIUtil.createLabel("lb_time", "2/22/2022 2:22 PM",
128, 48, 96, 32,
TextAlignment.Left, TextAlignment.VCenter, {
color = Color.Gray
}))
panelItem:addChild(UIUtil.createLabel("lb_tips", "Hardcore Mode, Version 2022",
128, 80, 96, 32,
TextAlignment.Left, TextAlignment.VCenter, {
color = Color.FrenchGray
}))
panelItem:addChild(UIUtil.createButtonWithImage("btn_remove", "tc:delete",
700, 0, 48, 48, {
marginsTB = { 16, 16, false },
targetSprite = { color = Color.new(110, 108, 132, 255) }
}, {
sprite = { color = Color.new(180, 168, 232, 255) }
}))
panel:addChild(UIUtil.createButton("btn_back", Locale.BACK, 0, 200, 220, UIDefault.ButtonHeight, {
anchorPoint = { 0.5, 0 },
margins = { 0, nil, UI_SIZE.width * 0.66, 16, false, false },
targetSprite = { color = Color.new(110, 108, 132, 255) },
}))
panel:addChild(UIUtil.createButton("btn_create", Locale.NEW_WORLD_B, 0, 200, 220, UIDefault.ButtonHeight, {
anchorPoint = { 0.5, 0 },
margins = { 0, nil, 0, 16, false, false },
targetSprite = { color = Color.new(110, 108, 132, 255) },
}))
panel:addChild(UIUtil.createButton("btn_ok", Locale.ENTER_WORLD, 0, 200, 220, UIDefault.ButtonHeight, {
anchorPoint = { 0.5, 0 },
margins = { UI_SIZE.width * 0.66, nil, 0, 16, false, false },
targetSprite = { color = Color.new(110, 108, 132, 255) },
}))
return root
end
function UIDesign.getNewWorldUI()
local UI_SIZE = Size.new(600, 450)
local root = UIUtil.createBlackFullScreenLayer("new_list_ui")
local panel = UIUtil.createWindowPattern(root, UI_SIZE, nil)
panel:addChild(UIUtil.createLabelNoPos("lb_title", Locale.CREATE_NEW_WORLD,
TextAlignment.HCenter, TextAlignment.VCenter, {
positionY = 12,
marginsLR = { 0, 0 },
fontSize = UIDefault.FontSize + 8
}))
panel:addChild(UIUtil.createLabel("lb_name", Locale.WORLD_NAME_Q,
0, 60, 180, 48,
TextAlignment.HCenter, TextAlignment.VCenter, {}))
local panelName = UIUtil.createPanel("panel_name", 0, 60, 200, 48, {
marginsLR = { 180, 16 },
sprite = {
name = "tc:round_rect_white",
color = Color.new(60, 60, 85)
}
})
panel:addChild(panelName)
panelName:addChild(UIUtil.createPanelNoPos("bg", {
margins = { 2, 2, 2, 2 },
sprite = {
name = "tc:round_rect_white",
color = Color.new(30, 30, 45)
}
}))
local editName = UIInputField.new("edit")
UIUtil.setMargins(editName, 8, 8, 8, 8)
panelName:addChild(editName)
panel:addChild(UIUtil.createLabel("lb_seed", Locale.WORLD_SEED_Q,
0, 120, 180, 48,
TextAlignment.HCenter, TextAlignment.VCenter, {}))
local panelSeed = UIUtil.createPanel("panel_seed", 0, 120, 200, 48, {
marginsLR = { 180, 16 },
sprite = {
name = "tc:round_rect_white",
color = Color.new(60, 60, 85)
}
})
panel:addChild(panelSeed)
panelSeed:addChild(UIUtil.createPanelNoPos("bg", {
margins = { 2, 2, 2, 2 },
sprite = {
name = "tc:round_rect_white",
color = Color.new(30, 30, 45)
}
}))
local editSeed = UIInputField.new("edit")
UIUtil.setMargins(editSeed, 8, 8, 8, 8)
panelSeed:addChild(editSeed)
panel:addChild(UIUtil.createButton("btn_gm", Locale.SURVIVAL_MODE, 0, 190, 276, UIDefault.ButtonHeight, {
anchorPoint = { 0.5, 0 },
marginsLR = { 16, UI_SIZE.width * 0.5 + 8, false },
targetSprite = { color = Color.new(110, 108, 132, 255) },
}))
panel:addChild(UIUtil.createButton("btn_bp", Locale.BP_SHARED_MODE, 0, 190, 276, UIDefault.ButtonHeight, {
anchorPoint = { 0.5, 0 },
marginsLR = { UI_SIZE.width * 0.5 + 8, 16, false },
targetSprite = { color = Color.new(110, 108, 132, 255) },
}))
panel:addChild(UIUtil.createButton("btn_move", Locale.MORE_SETTINGS, 0, 250, 276, UIDefault.ButtonHeight, {
anchorPoint = { 0.5, 0 },
marginsLR = { 16, 16 },
targetSprite = { color = Color.new(110, 108, 132, 255) },
}))
panel:getChild("btn_move").visible = false
local panelInfo = UIUtil.createPanelNoPos("panel_info", {
margins = { 16, 316, 16, 80 },
sprite = {
name = "tc:round_rect_white",
color = Color.new(28, 28, 40, 222)
}
})
panel:addChild(panelInfo)
panelInfo:addChild(UIUtil.createPanelNoPos("bg", {
margins = { 4, 4, 4, 4 },
sprite = {
name = "tc:round_rect_white",
color = Color.new(10, 10, 20, 222)
}
}))
panelInfo:addChild(UIUtil.createLabelNoPos("lb_info", "Hello world! This is a Tip! 名字不能超过1000个字符!",
TextAlignment.HCenter, TextAlignment.VCenter, {
margins = { 0, 0, 0, 0 },
color = Color.Yellow
}))
panel:addChild(UIUtil.createButton("btn_back", Locale.BACK, 0, 200, 250, UIDefault.ButtonHeight, {
anchorPoint = { 0.5, 0 },
margins = { 0, nil, UI_SIZE.width * 0.5, 16, false, false },
targetSprite = { color = Color.new(110, 108, 132, 255) },
}))
panel:addChild(UIUtil.createButton("btn_ok", Locale.CREATE_WORLD, 0, 200, 250, UIDefault.ButtonHeight, {
anchorPoint = { 0.5, 0 },
margins = { UI_SIZE.width * 0.5, nil, 0, 16, false, false },
targetSprite = { color = Color.new(110, 108, 132, 255) },
}))
return root
end
function UIDesign.getServerListUI()
local UI_SIZE = Size.new(800, 450)
local root = UIUtil.createBlackFullScreenLayer("server_list_ui")
local panel = UIUtil.createWindowPattern(root, UI_SIZE, nil)
panel:addChild(UIUtil.createLabelNoPos("lb_title", "选择服务器",
TextAlignment.HCenter, TextAlignment.VCenter, {
positionY = 12,
marginsLR = { 0, 0 },
fontSize = UIDefault.FontSize + 8
}))
local panelList = UIUtil.createScrollViewNoPos("panel_list", {
margins = { 16, 64, 16, 80 },
sprite = {
name = "tc:round_rect_white",
color = Color.new(30, 30, 45)
}
})
panel:addChild(panelList)
local panelItem = UIPanel.new("panel_item", 0, 0, panelList.size.width, 96)
panelList:addChild(panelItem)
panelItem:addChild(UIUtil.createImageNoPos("img_selected", {
margins = { 0, 0, 0, 0 },
touchable = false,
visible = false,
sprite = {
name = "tc:round_rect_white",
color = Color.new(60, 60, 80, 222)
}
}))
panelItem:addChild(UIUtil.createImage("img_line", 0, 96, 100, 2, {
marginsLR = { 16, 16 },
sprite = {
name = "tc:white",
color = Color.new(60, 60, 80, 100)
}
}))
panelItem:addChild(UIUtil.createImage("img_server_pic", 16, 16, 64, 64, {
touchable = false,
sprite = {
name = "tc:round_rect_white",
color = Color.new(10, 10, 25)
}
}))
panelItem:addChild(UIUtil.createLabel("lb_server_name", "Blueyoshi Test Server",
96, 16, 128, 24,
TextAlignment.Left, TextAlignment.VCenter))
panelItem:addChild(UIUtil.createLabel("lb_tips", "这是一个服务器首页文本!",
96, 48, 96, 32,
TextAlignment.Left, TextAlignment.VCenter, {
color = Color.FrenchGray
}))
panelItem:addChild(UIUtil.createImage("img_ping_bg", 0, 0, 30, 22, {
margins = { nil, 16, 16, nil },
sprite = {
name = "tc:ping_bg"
}
}))
panelItem:addChild(UIUtil.createImage("img_ping_green", 0, 0, 30, 22, {
margins = { nil, 16, 16, nil },
sprite = {
name = "tc:ping_green"
}
}))
panelItem:addChild(UIUtil.createLabel("lb_players", "114/1000",
96, 16, 30, 24,
TextAlignment.Right, TextAlignment.VCenter, {
margins = { nil, 16, 60, nil },
color = Color.FrenchGray
}))
panelItem:addChild(UIUtil.createButtonWithImage("btn_remove", "tc:delete",
700, 0, 48, 48, {
margins = { nil, nil, 16, 8 },
targetSprite = { color = Color.new(110, 108, 132, 255) }
}, {
sprite = { color = Color.new(180, 168, 232, 255) }
}))
panelItem:addChild(UIUtil.createButtonWithImage("btn_cfg", "tc:conf",
700, 0, 48, 48, {
margins = { nil, nil, 80, 8 },
targetSprite = { color = Color.new(110, 108, 132, 255) }
}, {
sprite = { color = Color.new(180, 168, 232, 255) }
}))
panel:addChild(UIUtil.createButton("btn_back", Locale.BACK, 0, 200, 220, UIDefault.ButtonHeight, {
anchorPoint = { 0.5, 0 },
margins = { 0, nil, UI_SIZE.width * 0.66, 16, false, false },
targetSprite = { color = Color.new(110, 108, 132, 255) },
}))
panel:addChild(UIUtil.createButton("btn_create", "添加服务器..", 0, 200, 220, UIDefault.ButtonHeight, {
anchorPoint = { 0.5, 0 },
margins = { 0, nil, 0, 16, false, false },
targetSprite = { color = Color.new(110, 108, 132, 255) },
}))
panel:addChild(UIUtil.createButton("btn_ok", "进入服务器", 0, 200, 220, UIDefault.ButtonHeight, {
anchorPoint = { 0.5, 0 },
margins = { UI_SIZE.width * 0.66, nil, 0, 16, false, false },
targetSprite = { color = Color.new(110, 108, 132, 255) },
}))
return root
end
function UIDesign.getNewServerUI()
local UI_SIZE = Size.new(600, 250)
local root = UIUtil.createBlackFullScreenLayer("new_list_ui")
local panel = UIUtil.createWindowPattern(root, UI_SIZE, nil)
panel:addChild(UIUtil.createLabelNoPos("lb_title", "编辑服务器信息",
TextAlignment.HCenter, TextAlignment.VCenter, {
positionY = 12,
marginsLR = { 0, 0 },
fontSize = UIDefault.FontSize + 8
}))
panel:addChild(UIUtil.createLabel("lb_name", "Server Name:",
0, 60, 180, 48,
TextAlignment.HCenter, TextAlignment.VCenter, {}))
local panelName = UIUtil.createPanel("panel_name", 0, 60, 200, 48, {
marginsLR = { 180, 16 },
sprite = {
name = "tc:round_rect_white",
color = Color.new(60, 60, 85)
}
})
panel:addChild(panelName)
panelName:addChild(UIUtil.createPanelNoPos("bg", {
margins = { 2, 2, 2, 2 },
sprite = {
name = "tc:round_rect_white",
color = Color.new(30, 30, 45)
}
}))
local editName = UIInputField.new("edit")
UIUtil.setMargins(editName, 8, 8, 8, 8)
panelName:addChild(editName)
panel:addChild(UIUtil.createLabel("lb_addr", "Server Address:",
0, 120, 180, 48,
TextAlignment.HCenter, TextAlignment.VCenter, {}))
local panelAddr = UIUtil.createPanel("lb_addr", 0, 120, 200, 48, {
marginsLR = { 180, 16 },
sprite = {
name = "tc:round_rect_white",
color = Color.new(60, 60, 85)
}
})
panel:addChild(panelAddr)
panelAddr:addChild(UIUtil.createPanelNoPos("bg", {
margins = { 2, 2, 2, 2 },
sprite = {
name = "tc:round_rect_white",
color = Color.new(30, 30, 45)
}
}))
local editAddr = UIInputField.new("edit")
UIUtil.setMargins(editAddr, 8, 8, 8, 8)
panelAddr:addChild(editAddr)
panel:addChild(UIUtil.createButton("btn_back", "Cancel", 0, 200, 250, UIDefault.ButtonHeight, {
anchorPoint = { 0.5, 0 },
margins = { 0, nil, UI_SIZE.width * 0.5, 16, false, false },
targetSprite = { color = Color.new(110, 108, 132, 255) },
}))
panel:addChild(UIUtil.createButton("btn_ok", "Done", 0, 200, 250, UIDefault.ButtonHeight, {
anchorPoint = { 0.5, 0 },
margins = { UI_SIZE.width * 0.5, nil, 0, 16, false, false },
targetSprite = { color = Color.new(110, 108, 132, 255) },
}))
return root
end
function UIDesign.getSettingUI()
local UI_SIZE = Size.new(800, 450)
local root = UIUtil.createBlackFullScreenLayer("setting_ui")
local panel = UIUtil.createWindowPattern(root, UI_SIZE, nil)
panel:addChild(UIUtil.createLabelNoPos("lb_title", Locale.SETTING_PANEL,
TextAlignment.HCenter, TextAlignment.VCenter, {
positionY = 12,
marginsLR = { 32, 60 },
fontSize = UIDefault.FontSize + 8
}
))
local panelList = UIUtil.createScrollView("panel_list", 0, 0, 200, 32, {
margins = { 16, 64, nil, 80 }
})
panel:addChild(panelList)
local panelItem = UIPanel.new("panel_item", 0, 0, panelList.size.width, 48)
panelList:addChild(panelItem)
panelItem:addChild(UIUtil.createImageNoPos("img_selected", {
margins = { 0, 0, 0, 0 },
touchable = false,
visible = true,
sprite = {
name = "tc:round_rect_white",
color = Color.new(48, 48, 60, 222)
}
}))
panelItem:addChild(UIUtil.createImage("lb_group_pic", 8, 8, 32, 32, {
sprite = { name = "tc:conf" }
}))
panelItem:addChild(UIUtil.createLabel("lb_group_name", Locale.SOUND,
48, 16, 128, 24,
TextAlignment.HCenter, TextAlignment.VCenter, {
marginsTB = { 0, 0, false }
})
)
local infoList = UIUtil.createScrollView("info_list", 0, 0, 300, 32, {
margins = { 232, 64, 16, 80 },
sprite = {
name = "tc:round_rect_white",
color = Color.new(48, 48, 60, 160)
}
})
panel:addChild(infoList)
local panelHold = UIUtil.createPanel("panel_hold", 0, 0, 32, 300, {
marginsLR = { 0, 0 }
})
infoList:addChild(panelHold)
local panelSlider = UIUtil.createPanel("panel_slider", 0, 0, 32, 100, {
marginsLR = { 0, 0 }
})
infoList:addChild(panelSlider)
panelSlider:addChild(UIUtil.createLabel("lb_title", "Value - 50%", 16, 16, 32, 32,
TextAlignment.Left, TextAlignment.VCenter))
panelSlider:addChild(UIUtil.createSlider("slider", 0, 56, 100, 32, {
marginsLR = { 10, 10 }
}))
panelSlider:addChild(UIUtil.createImage("img_line", 0, 0, 32, 2, {
margins = { 16, nil, 16, 2, true, false },
sprite = {
name = "tc:white",
color = Color.new(20, 20, 30)
}
}))
local panelBool = UIUtil.createPanel("panel_bool", 0, 0, 32, 64, {
marginsLR = { 0, 0 }
})
infoList:addChild(panelBool)
panelBool:addChild(UIUtil.createLabel("lb_title", "Boolean Value", 16, 16, 32, 32,
TextAlignment.Left, TextAlignment.VCenter))
panelBool:addChild(UIUtil.createSwitch("sw", 20, 16, 64, 32, {
marginsLR = { nil, 16 },
selected = true
}))
panelBool:addChild(UIUtil.createImage("img_line", 0, 0, 32, 2, {
margins = { 16, nil, 16, 2, true, false },
sprite = {
name = "tc:white",
color = Color.new(20, 20, 30)
}
}))
panel:addChild(UIUtil.createButton("btn_ok", Locale.OK, 0, 200, 300, UIDefault.ButtonHeight, {
anchorPoint = { 0.5, 0 },
targetSprite = {
color = Color.new(110, 108, 132, 255)
},
margins = { 0, nil, 0, 16, false }
}))
return root
end
function UIDesign.getInfoPopupUI()
local UI_SIZE = Size.new(500, 300)
local root = UIUtil.createBlackFullScreenLayer("info_popup_ui")
local panel = UIUtil.createWindowPattern(root, UI_SIZE, nil)
panel:addChild(UIUtil.createLabelNoPos("lb_title", Locale.TIPS,
TextAlignment.HCenter, TextAlignment.VCenter, {
positionY = 12,
marginsLR = { 0, 0 },
fontSize = UIDefault.FontSize + 8
}))
local panelInfo = UIUtil.createPanelNoPos("panel_info", {
margins = { 16, 54, 16, 80 },
sprite = {
name = "tc:round_rect_white",
color = Color.new(28, 28, 40, 222)
}
})
panel:addChild(panelInfo)
panelInfo:addChild(UIUtil.createPanelNoPos("bg", {
margins = { 4, 4, 4, 4 },
sprite = {
name = "tc:round_rect_white",
color = Color.new(10, 10, 20, 222)
}
}))
panelInfo:addChild(UIUtil.createLabelNoPos("lb_info", "gGui->OnMapDeleteEvent(event, controlID, pControl, pUserContext); mapDeleteUI->GetLabel(IDC_LABEL_INFO)->SetAlignment(AL_VCENTER | AL_HCENTER);",
TextAlignment.HCenter, TextAlignment.VCenter, {
horizontalOverflow = TextHorizontalOverflow.Wrap,
margins = { 16, 16, 16, 16 },
color = Color.Yellow
}))
panel:addChild(UIUtil.createButton("btn_back", Locale.BACK, 0, 200, 200, UIDefault.ButtonHeight, {
anchorPoint = { 0.5, 0 },
margins = { 0, nil, UI_SIZE.width * 0.5, 16, false, false },
targetSprite = { color = Color.new(110, 108, 132, 255) },
}))
panel:addChild(UIUtil.createButton("btn_ok", Locale.OK, 0, 200, 200, UIDefault.ButtonHeight, {
anchorPoint = { 0.5, 0 },
margins = { UI_SIZE.width * 0.5, nil, 0, 16, false, false },
targetSprite = { color = Color.new(110, 108, 132, 255) },
}))
return root
end
function UIDesign.getModListUI()
local UI_SIZE = Size.new(800, 450)
local root = UIUtil.createBlackFullScreenLayer("mod_list_ui")
local panel = UIUtil.createWindowPattern(root, UI_SIZE, nil)
panel:addChild(UIUtil.createLabelNoPos("lb_title", Locale.MOD_LIST,
TextAlignment.HCenter, TextAlignment.VCenter, {
positionY = 12,
marginsLR = { 0, 0 },
fontSize = UIDefault.FontSize + 8
}))
panel:addChild(UIUtil.createButton("btn_back", Locale.BACK, 0, 200, 220, UIDefault.ButtonHeight, {
anchorPoint = { 0.5, 0 },
margins = { 0, nil, UI_SIZE.width * 0.66, 16, false, false },
targetSprite = { color = Color.new(110, 108, 132, 255) },
}))
panel:addChild(UIUtil.createButton("btn_mod_folder", Locale.OPEN_MOD_FOLDER, 0, 200, 220, UIDefault.ButtonHeight, {
anchorPoint = { 0.5, 0 },
margins = { 0, nil, 0, 16, false, false },
targetSprite = { color = Color.new(110, 108, 132, 255) },
}))
panel:addChild(UIUtil.createButton("btn_mod_sources", Locale.MANAGER_SOURCES, 0, 200, 220, UIDefault.ButtonHeight, {
anchorPoint = { 0.5, 0 },
margins = { UI_SIZE.width * 0.66, nil, 0, 16, false, false },
targetSprite = { color = Color.new(110, 108, 132, 255) },
}))
panel:addChild(UIUtil.createLabel("lb_list_title", string.format(Locale.ALL_MOD_LOADED, 0),
16, 64, 300, 24,
TextAlignment.Left, TextAlignment.Top, {
color = Color.Gray
}))
local panelList = UIUtil.createScrollView("panel_list", 0, 0, 300, 32, {
margins = { 16, 96, nil, 80 },
})
panel:addChild(panelList)
local panelItem = UIPanel.new("panel_item", 0, 0, panelList.size.width, 96)
panelList:addChild(panelItem)
panelItem:addChild(UIUtil.createImageNoPos("img_selected", {
margins = { 0, 0, 0, 0 },
touchable = false,
sprite = {
name = "tc:round_rect_white",
color = Color.new(48, 48, 60, 222)
},
visible = false
}))
panelItem:addChild(UIUtil.createLabel("lb_mod_name", "ModNameHere",
96, 16, 128, 24,
TextAlignment.Left, TextAlignment.VCenter))
panelItem:addChild(UIUtil.createLabel("lb_mod_tip", "the mod tip.. test for auto wrap",
96, 40, 128, 24,
TextAlignment.Left, TextAlignment.Top, {
marginsLR = { 96, 16 },
fontSize = UIDefault.SmallFontSize,
color = Color.FrenchGray,
horizontalOverflow = TextHorizontalOverflow.Wrap
}))
panelItem:addChild(UIUtil.createImage("img_mod_pic", 16, 16, 64, 64, {
sprite = { name = "tc:round_rect_white" }
}))
local infoPanelList = UIUtil.createScrollViewNoPos("info_list", {
margins = { 332, 64, 16, 80 },
})
panel:addChild(infoPanelList)
local panelInfo1 = UIUtil.createPanel("panel_info_1", 0, 0, 32, 96, {
marginsLR = { 0, 0 },
sprite = {
name = "tc:round_rect_white",
color = Color.new(48, 48, 60, 160)
}
})
infoPanelList:addChild(panelInfo1)
local panelVersion = UIPanel.new("panel_version", 0, 0, 200, 96)
panelInfo1:addChild(panelVersion)
panelVersion:addChild(UIUtil.createLabel("lb_version_title", Locale.MOD_VERSION,
0, 16, 128, 24,
TextAlignment.HCenter, TextAlignment.VCenter, {
marginsLR = { 0, 0 },
color = Color.Gray
}))
panelVersion:addChild(UIUtil.createLabel("lb_version", "1.1.1.1",
0, 48, 128, 24,
TextAlignment.HCenter, TextAlignment.VCenter, {
marginsLR = { 0, 0 },
}))
local panelAuthor = UIPanel.new("panel_author", 200, 0, 200, 96)
panelInfo1:addChild(panelAuthor)
panelAuthor:addChild(UIUtil.createLabel("lb_author_title", Locale.MOD_AUTHORS,
0, 16, 128, 24,
TextAlignment.HCenter, TextAlignment.VCenter, {
marginsLR = { 0, 0 },
color = Color.Gray
}))
panelAuthor:addChild(UIUtil.createLabel("lb_author", "Super Lazy BlueYoshi",
0, 48, 128, 24,
TextAlignment.HCenter, TextAlignment.VCenter, {
marginsLR = { 0, 0 }
}))
local panelInfoWeb = UIUtil.createPanel("panel_info_web", 0, 112, 32, 112, {
marginsLR = { 0, 0 },
sprite = {
name = "tc:round_rect_white",
color = Color.new(48, 48, 60, 160)
}
})
infoPanelList:addChild(panelInfoWeb)
panelInfoWeb:addChild(UIUtil.createLabel("lb_web", Locale.WEB,
16, 16, 300, 24))
panelInfoWeb:addChild(UIUtil.createButton("btn_web_1", Locale.WEB, 8, 56, 200, UIDefault.ButtonHeight, {
marginsLR = { 16, nil },
targetSprite = { color = Color.new(110, 108, 132, 255) },
}))
panelInfoWeb:addChild(UIUtil.createButton("btn_web_2", Locale.WEB, 200, 56, 200, UIDefault.ButtonHeight, {
marginsLR = { nil, 16 },
targetSprite = { color = Color.new(110, 108, 132, 255) },
}))
local panelInfo2 = UIUtil.createPanel("panel_info_2", 0, 188 + 64, 32, 400, {
marginsLR = { 0, 0 },
sprite = {
name = "tc:round_rect_white",
color = Color.new(48, 48, 60, 160)
}
})
infoPanelList:addChild(panelInfo2)
panelInfo2:addChild(UIUtil.createLabel("lb_des_caption", Locale.DESC,
16, 16, 300, 24))
panelInfo2:addChild(UIUtil.createLabel("lb_des", "Test Desc",
16, 48, 300, 24,
TextAlignment.Left, TextAlignment.Top, {
marginsLR = { 16, 16 },
color = Color.FrenchGray,
horizontalOverflow = TextHorizontalOverflow.Wrap
}))
return root
end
function UIDesign.getTipUI()
local UI_SIZE = Size.new(100, 100)
local root = UIUtil.createPanel("tip_ui", 0, 0, UI_SIZE.width, UI_SIZE.height, {
sprite = {
name = "tc:window_frame_01",
color = Color.new(255, 255, 255, 200)
},
touchable = false
})
root:addChild(UIUtil.createLabel("lb_tip", "This is a tip",
8, 8, 32, 32,
TextAlignment.Left, TextAlignment.Top, {
fontSize = UIDefault.SmallFontSize,
color = Color.new(224, 224, 224, 255),
isRichText = true,
autoAdaptSize = true,
}))
return root
end
function UIDesign.getHudUI()
local root = UIUtil.createPanel("hud_ui", 0, 0,
GameWindow.displayResolution.width, GameWindow.displayResolution.height, {
margins = { 0, 0, 0, 0, true, true },
touchable = false
})
local panelElementBase = UIUtil.createPanel("panel_element_base", 0, 0, 32, 32)
root:addChild(panelElementBase)
root:addChild(UIUtil.createLabel("lb_music_name", "Music:Name", 0, 0, 32, 32,
TextAlignment.Right, TextAlignment.Top, {
margins = { nil, nil, 16, 32 },
fontSize = UIDefault.SmallFontSize,
color = Color.new(155, 155, 155)
}
))
root:addChild(UIUtil.createLabel("lb_music_author", "MusicAuthor", 0, 0, 32, 32,
TextAlignment.Right, TextAlignment.Top, {
margins = { nil, nil, 16, 8 },
fontSize = UIDefault.SmallFontSize,
color = Color.new(100, 100, 100)
}
))
local joystickCenter = UIJoystick.new("joystick_center")
joystickCenter:setSize(300, 300)
--joystickCenter.backSprite = UISpritePool:get("tc:joystick_base")
--joystickCenter.frontSprite = UISpritePool:get("tc:joystick_controlled_aim")
UIUtil.setMargins(joystickCenter, 0, 0, 0, 0, false, false)
joystickCenter.controlRadius = 96
root:addChild(joystickCenter)
local joystickLeft = UIJoystick.new("joystick_left")
joystickLeft:setSize(250, 250)
joystickLeft.backSprite = UISpritePool:get("tc:joystick_base")
joystickLeft.frontSprite = UISpritePool:get("tc:joystick_controlled")
joystickLeft.leftMarginEnabled = true
joystickLeft.bottomMarginEnabled = true
joystickLeft.controlRadius = 64
joystickLeft.backSprite.color = Color.new(255, 255, 255, 128)
joystickLeft.frontSprite.color = Color.new(255, 255, 255, 128)
root:addChild(joystickLeft)
local joystickRight = UIJoystick.new("joystick_right")
joystickRight:setSize(250, 250)
joystickRight.backSprite = UISpritePool:get("tc:joystick_base")
joystickRight.frontSprite = UISpritePool:get("tc:joystick_controlled_aim")
joystickRight.rightMarginEnabled = true
joystickRight.bottomMarginEnabled = true
joystickRight.controlRadius = 96
joystickRight.backSprite.color = Color.new(255, 255, 255, 128)
joystickRight.frontSprite.color = Color.new(255, 255, 255, 128)
root:addChild(joystickRight)
local panelBtn = UIUtil.createPanel("panel_btn", 0, 0, 54 * 6, 48, {
margins = { 0, 8, 0, nil, false, false },
anchorPoint = { 0.5, 0 },
})
root:addChild(panelBtn)
---_setBtn
---@param btn UIButton
local function _setBtn(btn, spriteName)
local sprite = UISpritePool:get(spriteName)
local color = Color.new(255, 255, 255, 200)
btn.targetSprite = sprite
btn.targetSprite.color = color
btn.selectedSprite = sprite
btn.selectedSprite.color = color
btn.pressedSprite = sprite
btn.pressedSprite.color = color
btn.highlightedSprite = sprite
btn.highlightedSprite.color = color
end
local check_box_front_or_wall = UIUtil.createButton("check_box_front_or_wall", "", 0, 0, 48, 48)
_setBtn(check_box_front_or_wall, "tc:check_box_front_or_wall")
panelBtn:addChild(check_box_front_or_wall)
local check_box_smart = UIUtil.createButton("check_box_smart", "", 54 * 1, 0, 48, 48)
_setBtn(check_box_smart, "tc:check_box_smart")
panelBtn:addChild(check_box_smart)
local button_recipe = UIUtil.createButton("button_recipe", "", 54 * 2, 0, 48, 48)
_setBtn(button_recipe, "tc:button_recipe")
panelBtn:addChild(button_recipe)
local button_task = UIUtil.createButton("button_task", "", 54 * 3, 0, 48, 48)
_setBtn(button_task, "tc:button_task")
panelBtn:addChild(button_task)
local btnBackpack = UIUtil.createButton("button_backpack", "", 54 * 4, 0, 48, 48)
_setBtn(btnBackpack, "tc:button_backpack")
panelBtn:addChild(btnBackpack)
local btnOption = UIUtil.createButton("button_option", "", 54 * 5, 0, 48, 48)
_setBtn(btnOption, "tc:button_option")
panelBtn:addChild(btnOption)
root:addChild(UIUtil.createLabel("lb_debug", "FPS", 32, 200, 32, 32))
root:addChild(UIUtil.createLabel("lb_hp", "114/514", 32, 128, 32, 32))
root:addChild(UIUtil.createLabel("lb_mana", "114/514", 32, 128, 32, 32))
local panelShortcut = UIUtil.createPanel("panel_shortcut", 0, 0, 56 * 10, 56, {
margins = { 0, nil, 0, 0, false, false },
anchorPoint = { 0.5, 0 },
})
root:addChild(panelShortcut)
-- 0-9: shortcut slots
for i = 0, 9 do
panelShortcut:addChild(UIUtil.createSlotStyle("slot",
i * 56, 0, 56, 56, 2), i)
end
panelShortcut:addChild(UIUtil.createLabel("lb_exp", "114514",
0, -38, 32, 32,
TextAlignment.HCenter, TextAlignment.VCenter, {
margins = { 0, nil, 0, nil, false, false },
isRichText = true,
fontSize = UIDefault.SmallFontSize,
}
))
panelShortcut:addChild(UIUtil.createLabel("lb_item_name", "Test Item Name",
0, -68, 32, 32,
TextAlignment.HCenter, TextAlignment.VCenter, {
margins = { 0, nil, 0, nil, false, false },
}
))
-- advancement tips
local panelAdvancements = UIUtil.createPanel("panel_advancements", 0, 0, 32, 32, {
margins = { nil, 0, 0, nil },
touchable = false
})
root:addChild(panelAdvancements)
local ADVANCEMENT_TIP_SIZE = Size.new(400, 80)
local panelAdvancementTip = UIUtil.createPanel("panel_advancement_tip", 0, 0,
ADVANCEMENT_TIP_SIZE.width, ADVANCEMENT_TIP_SIZE.height, {
margins = { nil, 0, 0, nil },
sprite = {
name = "tc:advance_tip",
color = Color.new(200, 200, 200, 255)
},
touchable = false,
visible = false,
})
panelAdvancements:addChild(panelAdvancementTip)
panelAdvancementTip:addChild(UIUtil.createPanel("panel_icon",
8, 8, 64, 64))
panelAdvancementTip:addChild(UIUtil.createLabel("lb_caption", Locale.GET_ADVANCEMENT,
72, 8, 32, 32,
TextAlignment.Left, TextAlignment.VCenter, {
fontSize = UIDefault.FontSize,
color = Color.new(240, 240, 0, 255),
isRichText = true,
}))
panelAdvancementTip:addChild(UIUtil.createLabel("lb_sub_caption", "",
72, 40, 32, 32,
TextAlignment.Left, TextAlignment.VCenter, {
fontSize = UIDefault.FontSize,
color = Color.new(224, 224, 224, 255),
isRichText = true,
}))
return root
end
function UIDesign.getItemListUI()
end
function UIDesign.getAdvancementUI()
local root = UIUtil.createBlackFullScreenLayer("advancement_ui")
local panelScroll = UIUtil.createScrollViewNoPos("scroll", {
margins = { 0, 0, 0, 0, true, true }
})
root:addChild(panelScroll)
local panel = UIUtil.createPanel("panel", 0, 0, 300, 300)
panelScroll:addChild(panel)
root:addChild(UIUtil.createButton("btn_ok", Locale.BACK, 0, 0, 200, UIDefault.ButtonHeight, {
margins = { 0, nil, 0, 32, false, false }
}))
return root
end
function UIDesign.getBackpackUI()
local UI_SIZE = Size.new(512, 468)
local root = UIUtil.createBlackFullScreenLayer("backpack_ui")
local panel = UIUtil.createWindowPattern(root, UI_SIZE, {
style = "Gray",
})
-- Equipment
panel:addChild(UIUtil.createLabel("lb_equipment", Locale.EQUIPMENT,
16, 8, 32, 32,
TextAlignment.Left, TextAlignment.VCenter, {
fontSize = UIDefault.SmallFontSize,
color = Color.Gray
}))
-- Appearance
panel:addChild(UIUtil.createLabel("lb_appearance", Locale.APPEAR_ACCESSORY,
236, 8, 32, 32,
TextAlignment.Right, TextAlignment.VCenter, {
fontSize = UIDefault.SmallFontSize,
color = Color.Gray
}))
-- Crafting
panel:addChild(UIUtil.createLabel("lb_crafting", Locale.CRAFT,
286, 32, 32, 32,
TextAlignment.Left, TextAlignment.VCenter, {
fontSize = UIDefault.SmallFontSize,
color = Color.Gray
}))
local inventoryStartY = UI_SIZE.height - 268
local statusStartY = 42
panel:addChild(UIUtil.createPanel("panel_status", 68, statusStartY,
100, 142, {
sprite = {
name = "tc:base2",
color = Color.new(188, 188, 188, 200)
}
}))
panel:addChild(UIUtil.createImage("img_craft_arrow", 393, 103, 32, 24, {
sprite = {
name = "tc:arrow3",
color = Color.new(100, 100, 100, 188)
}
}))
-- 0-9: shortcut slots
for i = 0, 9 do
panel:addChild(UIUtil.createSlot("slot",
16 + i * UIDefault.CellOffset, inventoryStartY + 204), i)
end
-- 10-49: inner backpack slots
for i = 0, 39 do
panel:addChild(UIUtil.createSlot("slot",
16 + math.fmod(i, 10) * UIDefault.CellOffset,
inventoryStartY + math.floor(i / 10) * UIDefault.CellOffset), 10 + i)
end
local dressIconNames = { "tc:helmet", "tc:chestplate", "tc:leggings" }
-- 50-52: equipment slots
for i = 0, 2 do
panel:addChild(UIUtil.createSlot("slot",
16, statusStartY + i * UIDefault.CellOffset,
UIDefault.CellSize, UIDefault.CellSize, dressIconNames[i + 1]
), 50 + i)
end
-- 53-55: appearance slots
for i = 0, 2 do
panel:addChild(UIUtil.createSlot("slot",
174, statusStartY + i * UIDefault.CellOffset,
UIDefault.CellSize, UIDefault.CellSize, dressIconNames[i + 1]
), 53 + i)
end
-- 56-64: crafting input slots, only display 4 slots
local displays = { [0] = true, [1] = true, [3] = true, [4] = true }
for i = 0, 8 do
local c = UIUtil.createSlot("slot",
286 + math.fmod(i, 3) * UIDefault.CellOffset,
statusStartY + UIDefault.CellOffset / 3 + math.floor(i / 3) * UIDefault.CellOffset)
c.visible = displays[i] ~= nil and true or false
panel:addChild(c, 56 + i)
end
-- 65: crafting result slots
panel:addChild(UIUtil.createSlot("slot",
436, statusStartY + UIDefault.CellOffset,
UIDefault.CellSize, UIDefault.CellSize, "tc:hammer"), 65)
-- 66-68: accessory slots
for i = 0, 2 do
panel:addChild(UIUtil.createSlot("slot",
222, statusStartY + i * UIDefault.CellOffset,
UIDefault.CellSize, UIDefault.CellSize
), 66 + i)
end
-- 69: drop slots
panel:addChild(UIUtil.createSlot("slot",
UI_SIZE.width + 16, UI_SIZE.height - 154,
UIDefault.CellSize, UIDefault.CellSize, "tc:trash"), 69)
panel:addChild(UIUtil.createButtonWithImage("btn_recipe", "tc:recipe_book",
UI_SIZE.width + 16, UI_SIZE.height - UIDefault.ButtonHeight, UIDefault.ButtonHeight, UIDefault.ButtonHeight, {
targetSprite = {
color = Color.new(128, 128, 128)
}
}))
panel:addChild(UIUtil.createButtonWithImage("btn_sort", "tc:sort",
UI_SIZE.width + 16, UI_SIZE.height - UIDefault.ButtonHeight - 54, UIDefault.ButtonHeight, UIDefault.ButtonHeight, {
targetSprite = {
color = Color.new(128, 128, 128)
}
}))
return root
end
function UIDesign.getRecipeBookUI()
local UI_SIZE = Size.new(372, 468)
local panel = UIUtil.createWindowPattern(nil, UI_SIZE, {
style = "Gray",
})
local panelList = UIUtil.createScrollView("panel_list", 0, 0, 336, 32, {
margins = { 0, 16, 0, 16, false, true },
})
panelList.isScrollHorizontal = false
panelList.isScrollVertical = true
panel:addChild(panelList)
local panelItem = UIUtil.createSlotStyle("panel_item", 0, 0,
UIDefault.CellHugeSize, UIDefault.CellHugeSize, 4)
panelList:addChild(panelItem)
return panel
end
function UIDesign.getNeiUI()
local UI_SIZE = Size.new(622, 380)
local UI_LIST_WIDTH = UIDefault.CellSize * 6
local TAB_SIZE = 54
local root = UIUtil.createBlackFullScreenLayer("nei_ui")
local infoPanel = UIUtil.createWindowPattern(root, UI_SIZE, {
style = "Gray",
})
UIUtil.setMargins(infoPanel, 0, 0, UI_LIST_WIDTH, 0, false, false)
local panelSearch = UIUtil.createPanel("panel_search", 0, 0, UI_LIST_WIDTH, 32, {
margins = { nil, 8, 8, 8, false, true }
})
root:addChild(panelSearch)
local panelCells = UIUtil.createPanel("panel_cells", 0, 0, 32, 32, {
margins = { 0, 64, 0, 32, true, true }
})
panelSearch:addChild(panelCells)
panelSearch:addChild(UIUtil.createLabel("lb_page", "114/514",
0, 0, UI_LIST_WIDTH, 48,
TextAlignment.HCenter, TextAlignment.VCenter, {
fontSize = UIDefault.FontSize,
}))
panelSearch:addChild(UIUtil.createButtonWithImage("btn_prev", "tc:arrow1",
0, 0, 48, 48, {
targetSprite = {
color = Color.new(128, 128, 128)
}
}))
panelSearch:addChild(UIUtil.createButtonWithImage("btn_next", "tc:arrow2",
UI_LIST_WIDTH - 48, 0, 48, 48, {
targetSprite = {
color = Color.new(128, 128, 128)
}
}))
root:addChild(UIUtil.createButton("btn_search_mode", Locale.SEARCH_FROM_OUTPUT,
8, 8, 160, 48, {
margins = { nil, nil, UI_LIST_WIDTH + 32, 8 },
targetSprite = {
color = Color.new(128, 128, 128)
}
}))
root:addChild(UIUtil.createButton("btn_back_history", Locale.PRE_ITEM,
8, 8, 160, 48, {
margins = { nil, nil, UI_LIST_WIDTH + 32, nil },
targetSprite = {
color = Color.new(128, 128, 128)
}
}))
local panelCell = UIUtil.createPanel("panel_cell", 0, 0, UIDefault.CellSize, UIDefault.CellSize, {
sprite = {
name = "tc:white",
color = Color.new(100, 100, 100, 100)
}
})
panelSearch:addChild(panelCell)
local panelTabs = UIUtil.createPanel("panel_tabs", 16, -TAB_SIZE + 7, TAB_SIZE, TAB_SIZE)
infoPanel:addChild(panelTabs)
local panelTab = UIUtil.createPanel("panel_tab", 16, -TAB_SIZE + 7, TAB_SIZE, TAB_SIZE, {
sprite = {
name = "tc:tab_clicked",
}
})
infoPanel:addChild(panelTab)
local panelPositionDetail = UIUtil.createPanel("panel_position_detail", 0, 0, 360 - 16, 32, {
margins = { nil, 16, 8, 16, false, true }
})
infoPanel:addChild(panelPositionDetail)
panelPositionDetail:addChild(UIUtil.createPanel("panel_detail", 0, 0, 344, 300, {
margins = { 0, 0, 0, 0, false, false }
}))
infoPanel:addChild(UIUtil.createLabel("lb_recipe_name", "",
0, 0, 32, 32, TextAlignment.HCenter, TextAlignment.VCenter, {
margins = { 0, 8, 360, nil, true, false }
}))
local panelList = UIUtil.createScrollView("panel_list", 0, 0, 32, 32, {
margins = { 16, 40, 360, 16, true, true },
sprite = {
name = "tc:base_list_cell",
}
})
infoPanel:addChild(panelList)
local panelItem = UIUtil.createPanel("panel_item", 0, 0, 32, 32, {
sprite = {
name = "tc:base_list_cell",
}
})
panelList:addChild(panelItem)
local panelPreviewCell = UIUtil.createPanel("panel_preview_cell", 0, 0, UIDefault.CellSize, UIDefault.CellSize, {
sprite = {
name = "tc:white",
color = Color.new(100, 100, 100, 0)
}
})
panelItem:addChild(panelPreviewCell)
panelItem:addChild(UIUtil.createPanel("img_arrow", 0, 0, 32, 24, {
sprite = {
name = "tc:arrow3",
color = Color.Gray
},
touchable = false,
}))
return root
end
function UIDesign.generateBackpackPattern(panel, UI_SIZE)
panel:addChild(UIUtil.createLabel("lb_inventory", Locale.INVENTORY,
16, 170, 32, 32,
TextAlignment.Left, TextAlignment.VCenter, {
fontSize = UIDefault.SmallFontSize,
color = Color.Gray
}))
local inventoryStartY = UI_SIZE.height - 268
-- 0-9: shortcut slots
for i = 0, 9 do
panel:addChild(UIUtil.createSlot("slot",
16 + i * UIDefault.CellOffset, inventoryStartY + 204), i)
end
-- 10-49: inner backpack slots
for i = 0, 39 do
panel:addChild(UIUtil.createSlot("slot",
16 + math.fmod(i, 10) * UIDefault.CellOffset,
inventoryStartY + math.floor(i / 10) * UIDefault.CellOffset), 10 + i)
end
end
function UIDesign.getCraft3xUI()
local UI_SIZE = Size.new(512, 468)
local root = UIUtil.createBlackFullScreenLayer("craft3x_ui")
local panel = UIUtil.createWindowPattern(root, UI_SIZE, {
style = "Gray",
})
panel:addChild(UIUtil.createLabel("lb_title", Locale.CRAFT,
100, 8, 32, 32,
TextAlignment.Left, TextAlignment.VCenter, {
fontSize = UIDefault.SmallFontSize,
color = Color.Gray
}))
UIDesign.generateBackpackPattern(panel, UI_SIZE)
local offsetX = 100
local offsetY = 38
-- 50-58: input
for i = 0, 8 do
panel:addChild(UIUtil.createSlot("slot_input",
offsetX + UIDefault.CellSize * (i % 3),
offsetY + UIDefault.CellSize * math.floor(i / 3),
UIDefault.CellSize, UIDefault.CellSize), 50 + i)
end
-- 59: output
panel:addChild(UIUtil.createSlot("slot_output",
offsetX + 240,
offsetY + UIDefault.CellSize * 1.5 - UIDefault.CellLargeSize * 0.5,
UIDefault.CellLargeSize, UIDefault.CellLargeSize), 50 + 9)
panel:addChild(UIUtil.createImage("img_arrow", offsetX + 170, offsetY + 56, 40, 32, {
sprite = {
name = "tc:arrow4",
color = Color.new(100, 100, 100),
}
}))
panel:addChild(UIUtil.createButtonWithImage("btn_recipe", "tc:recipe_book",
UI_SIZE.width + 16, UI_SIZE.height - UIDefault.ButtonHeight, UIDefault.ButtonHeight, UIDefault.ButtonHeight, {
targetSprite = {
color = Color.new(128, 128, 128)
}
}))
return root
end
function UIDesign.getSmeltUI()
local UI_SIZE = Size.new(512, 468)
local root = UIUtil.createBlackFullScreenLayer("smelt_ui")
local panel = UIUtil.createWindowPattern(root, UI_SIZE, {
style = "Gray",
})
panel:addChild(UIUtil.createLabel("lb_title", Locale.FURNACE,
240, 8, 32, 32,
TextAlignment.HCenter, TextAlignment.VCenter, {
fontSize = UIDefault.SmallFontSize,
color = Color.Gray
}))
UIDesign.generateBackpackPattern(panel, UI_SIZE)
local offsetX = 160
local offsetY = 38
-- 50: input 51: fuel 52: output 53: back
panel:addChild(UIUtil.createSlot("slot_input",
offsetX, offsetY, UIDefault.CellSize, UIDefault.CellSize), 50)
panel:addChild(UIUtil.createSlot("slot_fuel",
offsetX, offsetY + 88, UIDefault.CellSize, UIDefault.CellSize, "tc:fire"), 51)
panel:addChild(UIUtil.createSlot("slot_output",
offsetX + 150, offsetY + 40, UIDefault.CellLargeSize, UIDefault.CellLargeSize), 52)
panel:addChild(UIUtil.createSlot("slot_back",
offsetX - 60, offsetY + 88, UIDefault.CellSize, UIDefault.CellSize, "tc:fuel_return"), 53)
panel:addChild(UIUtil.createImage("img_cook",
offsetX + 80, offsetY + 52, 40, 32, {
sprite = {
name = "tc:process_00",
}
}))
panel:addChild(UIUtil.createImage("img_burn",
offsetX + 8, offsetY + 52, 30, 30, {
sprite = {
name = "tc:burn_00"
}
}))
panel:addChild(UIUtil.createButtonWithImage("btn_recipe", "tc:recipe_book",
UI_SIZE.width + 16, UI_SIZE.height - UIDefault.ButtonHeight, UIDefault.ButtonHeight, UIDefault.ButtonHeight, {
targetSprite = {
color = Color.new(128, 128, 128)
}
}))
return root
end
function UIDesign.getEnchantmentUI()
local UI_SIZE = Size.new(512, 468)
local root = UIUtil.createBlackFullScreenLayer("enchantment_ui")
local panel = UIUtil.createWindowPattern(root, UI_SIZE, {
style = "Gray",
})
panel:addChild(UIUtil.createLabel("lb_title", Locale.ENCHANT,
60, 8, 32, 32,
TextAlignment.Left, TextAlignment.VCenter, {
fontSize = UIDefault.SmallFontSize,
color = Color.Gray
}))
UIDesign.generateBackpackPattern(panel, UI_SIZE)
-- 50-51: tool, lapis
panel:addChild(UIUtil.createSlot("slot_tool",
60,
42,
UIDefault.CellLargeSize, UIDefault.CellLargeSize, "tc:hammer"), 50)
panel:addChild(UIUtil.createSlot("slot_lapis",
65,
120,
UIDefault.CellSize, UIDefault.CellSize, "tc:lapis_lazuli_gray"), 51)
local BTN_X, BTN_Y = 160, 30
local BTN_WIDTH, BTN_HEIGHT = 336, 48
for i = 1, 3 do
local panelBtn = UIUtil.createPanel(string.format("panel_btn_%d", i),
BTN_X, BTN_Y + (i - 1) * BTN_HEIGHT, BTN_WIDTH, BTN_HEIGHT, {
sprite = {
name = "tc:base_list_cell_highlight_2",
}
})
panel:addChild(panelBtn)
panelBtn:addChild(UIUtil.createImage("img_exp",
12, 8, 32, 32, {
sprite = {
name = string.format("tc:enchantment_exp_%d", i),
},
touchable = false
}))
panelBtn:addChild(UIUtil.createLabel("lb_cost", "3",
40, 8, 32, 32, TextAlignment.Left, TextAlignment.VCenter, {
color = Color.Yellow
}
))
panelBtn:addChild(UIUtil.createLabel("lb_exp", "30",
290, 8, 32, 32, TextAlignment.Right, TextAlignment.VCenter, {
color = Color.Yellow
}
))
panelBtn:addChild(UIUtil.createLabel("lb_preview", "精准采集IV ...",
160, 8, 32, 32, TextAlignment.HCenter, TextAlignment.VCenter, {
color = Color.Gray
}
))
end
return root
end
function UIDesign.getRepairUI()
local UI_SIZE = Size.new(512, 468)
local root = UIUtil.createBlackFullScreenLayer("repair_ui")
local panel = UIUtil.createWindowPattern(root, UI_SIZE, {
style = "Gray",
})
panel:addChild(UIUtil.createLabel("lb_title", Locale.REPAIR,
240, 8, 32, 32,
TextAlignment.HCenter, TextAlignment.VCenter, {
fontSize = UIDefault.FontSize,
color = Color.Gray
}))
UIDesign.generateBackpackPattern(panel, UI_SIZE)
local offsetX, offsetY = 100, 90
-- 50-52: tool, source, output
panel:addChild(UIUtil.createSlot("slot_tool",
offsetX + 0,
offsetY + 0,
UIDefault.CellSize, UIDefault.CellSize, "tc:hammer"), 50)
panel:addChild(UIUtil.createSlot("slot_source",
offsetX + 120,
offsetY + 0,
UIDefault.CellSize, UIDefault.CellSize, "tc:ingot_gray"), 51)
panel:addChild(UIUtil.createSlot("slot_output",
offsetX + 250,
offsetY - 5,
UIDefault.CellLargeSize, UIDefault.CellLargeSize, "tc:hammer"), 52)
panel:addChild(UIUtil.createLabel("lb_exp", "附魔消耗:22",
offsetX + 130, offsetY + 54, 32, 32, TextAlignment.HCenter, TextAlignment.VCenter, {
color = Color.Yellow,
visible = false,
}
))
panel:addChild(UIUtil.createImage("img_add", offsetX + 68, offsetY + 8, 32, 32, {
sprite = {
name = "tc:adding",
}
}))
panel:addChild(UIUtil.createImage("img_process", offsetX + 190, offsetY + 8, 40, 32, {
sprite = {
name = "tc:process_00",
}
}))
panel:addChild(UIUtil.createButtonWithImage("btn_recipe", "tc:recipe_book",
UI_SIZE.width + 16, UI_SIZE.height - UIDefault.ButtonHeight, UIDefault.ButtonHeight, UIDefault.ButtonHeight, {
targetSprite = {
color = Color.new(128, 128, 128)
}
}))
return root
end
function UIDesign.getBrewingUI()
local UI_SIZE = Size.new(512, 468)
local root = UIUtil.createBlackFullScreenLayer("brewing_ui")
local panel = UIUtil.createWindowPattern(root, UI_SIZE, {
style = "Gray",
})
panel:addChild(UIUtil.createLabel("lb_title", Locale.BREWING_STAND,
240, 8, 32, 32,
TextAlignment.HCenter, TextAlignment.VCenter, {
fontSize = UIDefault.SmallFontSize,
color = Color.Gray
}))
UIDesign.generateBackpackPattern(panel, UI_SIZE)
local offsetX = 240
local offsetY = 38
panel:addChild(UIUtil.createImage("img_tube", offsetX, offsetY + 52, 30, 30, {
sprite = {
name = "tc:tube"
}
}))
panel:addChild(UIUtil.createImage("img_process", offsetX + 38, offsetY + 12, 24, 80, {
sprite = {
name = "tc:brewing_process_00",
}
}))
panel:addChild(UIUtil.createImage("img_bubble", offsetX - 48, offsetY + 4, 40, 64, {
sprite = {
name = "tc:brewing_bubble_00"
}
}))
panel:addChild(UIUtil.createImage("img_fuel", offsetX - 48, offsetY + 70, 40, 12, {
sprite = {
name = "tc:brewing_fuel_00"
}
}))
-- 50: potion 51: source 52: output 53: fuel
panel:addChild(UIUtil.createSlot("slot_potion",
offsetX - 82, offsetY + 88, UIDefault.CellSize, UIDefault.CellSize, "tc:glass_bottle"), 50)
panel:addChild(UIUtil.createSlot("slot_input",
offsetX - 8, offsetY, UIDefault.CellSize, UIDefault.CellSize), 51)
panel:addChild(UIUtil.createSlot("slot_output",
offsetX + 66, offsetY + 80, UIDefault.CellLargeSize, UIDefault.CellLargeSize, "tc:glass_bottle"), 52)
panel:addChild(UIUtil.createSlot("slot_fuel",
offsetX - 100, offsetY, UIDefault.CellSize, UIDefault.CellSize, "tc:blaze_powder"), 53)
panel:addChild(UIUtil.createButtonWithImage("btn_recipe", "tc:recipe_book",
UI_SIZE.width + 16, UI_SIZE.height - UIDefault.ButtonHeight, UIDefault.ButtonHeight, UIDefault.ButtonHeight, {
targetSprite = {
color = Color.new(128, 128, 128)
}
}))
return root
end
function UIDesign.getChest30UI()
local UI_SIZE = Size.new(512, 468)
local root = UIUtil.createBlackFullScreenLayer("chest30_ui")
local panel = UIUtil.createWindowPattern(root, UI_SIZE, {
style = "Gray",
})
panel:addChild(UIUtil.createLabel("lb_title", Locale.STORAGE,
16, 4, 32, 32,
TextAlignment.Left, TextAlignment.VCenter, {
fontSize = UIDefault.SmallFontSize,
color = Color.Gray
}))
UIDesign.generateBackpackPattern(panel, UI_SIZE)
local offsetX = 240
local offsetY = 34
for i = 0, 29 do
panel:addChild(UIUtil.createSlot("slot",
16 + math.fmod(i, 10) * UIDefault.CellOffset,
offsetY + math.floor(i / 10) * UIDefault.CellOffset), 50 + i)
end
local btnOffsetY = 76
panel:addChild(UIUtil.createButton("btn_sort", Locale.ARRANGE,
528, btnOffsetY, 160, UIDefault.ButtonHeight))
panel:addChild(UIUtil.createButton("btn_quick_pick", Locale.QUICK_PICK,
528, btnOffsetY + UIDefault.ButtonOffset, 160, UIDefault.ButtonHeight))
panel:addChild(UIUtil.createButton("btn_quick_push", Locale.QUICK_PUSH,
528, btnOffsetY + UIDefault.ButtonOffset * 2, 160, UIDefault.ButtonHeight))
panel:addChild(UIUtil.createButton("btn_quick_stack", Locale.QUICK_STACK,
528, btnOffsetY + UIDefault.ButtonOffset * 3, 160, UIDefault.ButtonHeight))
return root
end
function UIDesign.getShooter9UI()
local UI_SIZE = Size.new(512, 468)
local root = UIUtil.createBlackFullScreenLayer("shooter9_ui")
local panel = UIUtil.createWindowPattern(root, UI_SIZE, {
style = "Gray",
})
panel:addChild(UIUtil.createLabel("lb_title", Locale.STORAGE,
16, 4, 32, 32,
TextAlignment.Left, TextAlignment.VCenter, {
fontSize = UIDefault.SmallFontSize,
color = Color.Gray
}))
UIDesign.generateBackpackPattern(panel, UI_SIZE)
local offsetX = 240
local offsetY = 34
for i = 0, 8 do
panel:addChild(UIUtil.createSlot("slot",
16 + math.fmod(i, 3) * UIDefault.CellOffset,
offsetY + math.floor(i / 3) * UIDefault.CellOffset), 50 + i)
end
return root
end
function UIDesign.getDeathUI()
local root = UIUtil.createBlackFullScreenLayer("death_ui")
local panel = UIUtil.createPanel("panel", 0, 0, 100, 200, {
margins = { 0, 0, 0, 0, false, false }
})
root:addChild(panel)
panel:addChild(UIUtil.createLabel("lb_title", Locale.YOU_DIED,
0, 0, 100, 32,
TextAlignment.HCenter, TextAlignment.VCenter, {
fontSize = 60,
color = Color.Red,
}))
panel:addChild(UIUtil.createLabel("lb_title_2", "重生中... 3",
0, 100, 100, 32,
TextAlignment.HCenter, TextAlignment.VCenter, {
fontSize = 40,
color = Color.Red,
}))
return root
end
return UIDesign
================================================
FILE: ui/UILayerDefine.lua
================================================
local UILayerDefine = {
BaseLayer = 1,
AdvancementTipsLayer = 2,
Totals = 2,
}
return UILayerDefine
================================================
FILE: ui/UIManager.lua
================================================
---@class TC.UIManager
local UIManager = class("UIManager")
local OrderedArray = require("util.OrderedArray")
local UISpritePool = require("UISpritePool")
local MouseItemData = require("MouseItemData")
local SettingsData = require("settings.SettingsData")
local UILayerDefine = require("UILayerDefine")
local g_instance
---@return TC.UIManager
function UIManager.getInstance()
if g_instance == nil then
g_instance = UIManager.new()
end
return g_instance
end
function UIManager:__init()
self.spritePool = UISpritePool.getInstance()
self.canvasGameObject = nil
self.canvas = nil
self.baseLayers = {} ---@type UINode[]
self.baseLayer = nil
self.debugCanvasGameObject = nil
self.debugCanvas = nil
self._windowsLoaded = OrderedArray.new()
self.durableBarTexture = nil
self.cursorTexture = nil
end
function UIManager:init()
self.canvasGameObject = GameObject.instantiate()
self.canvasGameObject.canvas:init()
self.canvas = self.canvasGameObject.canvas.uiRoot
for i = 1, UILayerDefine.Totals do
local layerName = string.format("layer_%d", i)
local panel = UIPanel.new(layerName)
panel:setLeftMargin(0, true)
panel:setRightMargin(0, true)
panel:setTopMargin(0, true)
panel:setBottomMargin(0, true)
panel.autoStretchWidth = true
panel.autoStretchHeight = true
panel.touchable = false
self.canvas:addChild(panel)
table.insert(self.baseLayers, panel)
end
self.canvas:applyMargin()
self.baseLayer = self.baseLayers[UILayerDefine.BaseLayer]
self:initDebug()
self:onWindowResize()
end
function UIManager:initDebug()
self.debugCanvasGameObject = GameObject.instantiate()
self.debugCanvasGameObject.canvas:init()
self.debugCanvas = self.debugCanvasGameObject.canvas.uiRoot
self.debugCanvas.touchable = false
self.debugRect = nil
self.debugPoint = nil
local panel = UIPanel.new("panel")
panel:setMarginEnabled(true, true, true, true)
panel.autoStretchWidth = true
panel.autoStretchHeight = true
self.debugCanvas:addChild(panel)
local textDebug = UIText.new("text", 0, 0, 32, 32)
textDebug.horizontalOverflow = TextHorizontalOverflow.Overflow
textDebug.color = Color.Yellow
panel:addChild(textDebug)
local textDebug2 = UIText.new("text2", 32, 180, 32, 32)
textDebug2:setBottomMargin(100, true)
textDebug2.horizontalOverflow = TextHorizontalOverflow.Overflow
textDebug2.isRichText = true
textDebug2.fontSize = 18
panel:addChild(textDebug2)
end
---addWindowsLoaded
---@param uiWindow TC.UIWindow
---@return number
function UIManager:addWindowsLoaded(uiWindow)
--self.canvas:addChild(uiWindow.root)
self.baseLayer:addChild(uiWindow.root)
return self._windowsLoaded:add(uiWindow)
end
function UIManager:removeWindowsLoaded(index)
--self.canvas:removeChild(self._windowsLoaded:get(index).root)
self.baseLayer:removeChild(self._windowsLoaded:get(index).root)
self._windowsLoaded:remove(index)
end
---initUISpriteResources
---@param mod Mod
---@param uiSpriteResourcePathInMod string
function UIManager:initUISpriteResources(mod, uiSpriteResourcePathInMod)
local searchPath = Path.join(mod.assetRootPath, uiSpriteResourcePathInMod)
--print(searchPath)
local texNames = AssetManager.getAllFiles(searchPath, ".png", true, false, true)
for _, texPath in pairs(texNames) do
local absPath = Path.join(searchPath, texPath) .. ".png"
local texName = mod.modId .. ":" .. texPath
UITexturePool.register(texName, TextureManager.load(absPath))
end
for _, texPath in pairs(texNames) do
local texName = mod.modId .. ":" .. texPath
local cfgPath = Path.join(searchPath, texPath) .. ".json"
local sprite
if AssetManager.isPathExist(cfgPath) then
sprite = UISprite.new()
local json = AssetManager.readAsString(cfgPath)
sprite:fromJson(json)
else
sprite = UISprite.new(texName)
end
--print("loading sprite: " .. texName)
self.spritePool:add(texName, sprite)
end
end
function UIManager:postInit()
self.durableBarTexture = self.spritePool:get("tc:durable").textureLocation
self.cursorTexture = self.spritePool:get("tc:cursor2").textureLocation
---@param mod Mod
for _, mod in each(Mod.modList) do
local modIconPath = Path.join(mod.assetRootPath, "mod_icon.png")
if AssetManager.isPathExist(modIconPath) then
local texName = mod.modId .. ":__icon"
UITexturePool.register(texName, TextureManager.load(modIconPath))
local sprite = UISprite.new(texName)
self.spritePool:add(texName, sprite)
end
end
end
function UIManager:update()
if SettingsData.isShowUIDebug or SettingsData.isShowDebugInfo then
self.debugCanvas.visible = true
local lbText = UIText.cast(self.debugCanvas:getChild("panel.text"))
local lbText2 = UIText.cast(self.debugCanvas:getChild("panel.text2"))
lbText.visible = false
lbText2.visible = false
if SettingsData.isShowDebugInfo then
lbText2.text = string.format("FPS:%d \nLogic:%d \nBatches:%d \nTriangles:%d",
IntegratedClient.main.fps,
IntegratedClient.main.gameSpeed,
GraphicsDevice.drawCalls,
GraphicsDevice.primitiveCount
)
lbText2.visible = true
end
if SettingsData.isShowUIDebug then
local pointer = self.canvas:screenPointToCanvasPoint(Input.mouse.position)
--local node = self.canvas:getPointedNode(pointer)
local node = self.baseLayer:getPointedNode(pointer)
if node:valid() then
local nodeScreenPos = self.canvas:canvasPointToScreenPoint(node.positionInCanvas)
local bound = RectFloat.new(nodeScreenPos.x, nodeScreenPos.y, node.size.width, node.size.height)
self.debugRect = bound
self.debugPoint = Vector2.new(
bound.x + bound.width * node.anchorPointX,
bound.y + bound.height * node.anchorPointY
)
lbText.fontSize = 16
lbText.text = node.name ..
" (position:" .. tostring(node.positionInCanvas) ..
" size:" .. tostring(node.size) .. ")"
else
self.debugRect = nil
self.debugPoint = nil
lbText.text = "[UI Debug Mode]"
end
lbText.visible = true
end
else
self.debugCanvas.visible = false
end
if ClientState.current == ClientState.Gaming then
MouseItemData.getInstance():update()
end
end
function UIManager:render()
if SettingsData.isShowUIDebug then
if self.debugRect ~= nil then
GraphicsDevice.drawRect2D(self.debugRect, Color.new(255, 255, 0, 20))
GraphicsDevice.drawRectHollow2D(self.debugRect, Color.new(255, 255, 0, 200))
end
if self.debugPoint ~= nil then
GraphicsDevice.drawRect2D(RectFloat.new(self.debugPoint.x - 2, self.debugPoint.y - 2, 4, 4), Color.new(255, 255, 0, 200))
end
end
if ClientState.current == ClientState.Gaming then
MouseItemData.getInstance():render()
end
if not SettingsData.isMobileOperation then
Sprite.beginBatch()
local area = TextureManager.getSourceRect(self.cursorTexture)
Sprite.draw(self.cursorTexture, Input.mouse.position, area, Color.White)
Sprite.endBatch()
Input.mouse:setCursorVisible(false)
else
Input.mouse:setCursorVisible(true)
end
end
function UIManager:isWindowOpened(uiClassName)
for _, index in ipairs(self._windowsLoaded.indices) do
---@type TC.UIWindow
local uiWindow = self._windowsLoaded:get(index)
if uiWindow.uiClassName == uiClassName then
return true
end
end
return false
end
function UIManager:hasUIGroup(uiGroup)
for _, index in ipairs(self._windowsLoaded.indices) do
---@type TC.UIWindow
local uiWindow = self._windowsLoaded:get(index)
if uiWindow.uiGroup == uiGroup then
return true
end
end
return false
end
function UIManager:onWindowResize()
self.canvas.size = GameWindow.displayResolution
self.canvas:applyMargin()
self.debugCanvas.size = GameWindow.displayResolution
self.debugCanvas:applyMargin()
for _, index in ipairs(self._windowsLoaded.indices) do
---@type TC.UIWindow
local uiWindow = self._windowsLoaded:get(index)
uiWindow:onWindowResize()
end
end
function UIManager:_onEscPressed()
local lastEscWindow = self:getLastAllowEscWindow()
if lastEscWindow == nil then
return
end
lastEscWindow:closeWindow()
end
function UIManager:getLastAllowEscWindow()
local lastEscWindow
for _, index in ipairs(self._windowsLoaded.indices) do
---@type TC.UIWindow
local uiWindow = self._windowsLoaded:get(index)
if uiWindow.allowCloseByEsc then
lastEscWindow = uiWindow
end
end
return lastEscWindow
end
---getScreenPosition
---@param uiNode UINode
function UIManager:getScreenPosition(uiNode)
return self.canvas:canvasPointToScreenPoint(uiNode.positionInCanvas)
end
function UIManager:playClickSound()
SoundUtils.PlaySound(Reg.SoundID("tc:click"))
end
return UIManager
================================================
FILE: ui/UISlotOp.lua
================================================
local UISlotOp = class("UISlotOp")
local MouseItemData = require("MouseItemData")
local SettingsData = require("settings.SettingsData")
local SLOT_TAG_SELECTING = -10000
---@param guiContainer any
---@param container Container
---@param slotIndex int
---@param slot Slot
---@param node UINode
---@param touch Touch
function UISlotOp.slotOnTouchDown(guiContainer, container, slotIndex, slot, node, touch)
if SettingsData.isMobileOperation then
-- Mobile
UISlotOp.slotOnTouchShowTip(slot, node, touch)
else
-- PC
local isLeftButtonPressed = Input.mouse.isLeftButtonPressed
local mouseItemData = MouseItemData.getInstance()
local mouseSlot = mouseItemData.slot
if not mouseSlot.hasStack then
-- Current: Mouse:[]
if slot.hasStack then
-- Current: Mouse:[] Target:[item]
if Input.keyboard:isKeyPressed(Keys.LeftShift) and guiContainer.checkSlotShiftMove ~= nil then
-- Pressing Shift
local targetContainer, targetIndexStart, targetCount = guiContainer:checkSlotShiftMove(slotIndex, slot:GetStack())
if targetContainer ~= nil then
local maxSlots = targetContainer:GetSlotCount()
local targetIndexEnd = math.min(maxSlots - 1, targetIndexStart + targetCount - 1)
for targetIndex = targetIndexStart, targetIndexEnd do
if not slot.hasStack then
break
end
---@type Slot
local targetSlot = targetContainer:GetSlot(targetIndex)
if targetSlot.hasStack then
local fromStack = slot:GetStack()
local toStack = targetSlot:GetStack()
local merges = toStack:GetMergeCount(fromStack)
if merges > 0 then
toStack:SetStackSize(toStack.stackSize + merges)
slot:DecrStackSize(merges)
container:CommandSlotMoveTo(container, slotIndex, targetContainer, targetIndex, merges)
end
end
end
if slot.hasStack then
for targetIndex = targetIndexStart, targetIndexEnd do
---@type Slot
local targetSlot = targetContainer:GetSlot(targetIndex)
if not targetSlot.hasStack then
targetSlot:SwapStack(slot)
UISlotOp._EnsureSwapAndFirstHasItemOnly(container,
targetContainer, targetIndex,
container, slotIndex)
break
end
end
end
end
else
if isLeftButtonPressed then
mouseSlot:SwapStack(slot)
-- Current: Mouse:[item] Target:[]
UISlotOp._EnsureSwapAndFirstHasItemOnly(container,
nil, -1,
container, slotIndex)
else
-- Get half of target slot items.
local pickOutNum = math.ceil(slot:GetStack().stackSize / 2.0)
if pickOutNum > 0 then
mouseSlot:PushStack(slot:GetStack():SplitStack(pickOutNum))
local checkEmpty = false
if slot:GetStack().stackSize == 0 then
slot:ClearStack()
checkEmpty = true
end
container:CommandEnsureSlotEmpty(nil, -1)
container:CommandSlotMoveTo(container, slotIndex,
nil, -1,
mouseSlot:GetStack().stackSize)
if checkEmpty then
container:CommandEnsureSlotEmpty(container, slotIndex)
end
end
end
mouseItemData.isPcCurrentPicking = true
end
else
-- Current: Mouse:[] Target:[]
-- do nothing
end
else
-- Current: Mouse:[item]
if slot.hasStack then
-- Current: Mouse:[item] Target:[item]
mouseSlot:SwapStack(slot)
UISlotOp._EnsureSwapAndBothHasItem(container,
nil, -1,
container, slotIndex)
else
-- Current: Mouse:[item] Target:[]
end
if isLeftButtonPressed then
mouseItemData.pcIsAverageMode = true
else
mouseItemData.pcIsAverageMode = false
end
end
end
end
---slotOnTouchDown
---@param container Container
---@param slotIndex int
---@param slot Slot
---@param touch Touch
---@param node UINode
function UISlotOp.slotOnTouchDoubleDown(container, slotIndex, slot, node, touch)
if SettingsData.isMobileOperation then
-- Mobile
if slot.hasStack then
local mouseItemData = MouseItemData.getInstance()
local mouseSlot = mouseItemData.slot
if not mouseSlot.hasStack then
if slot:CanPick(slot:GetStack()) then
mouseSlot:PushStack(slot:GetStack():SplitStack(1))
if slot:GetStack().stackSize == 0 then
slot:ClearStack()
end
mouseItemData:startDragging(container, slotIndex)
mouseItemData.touchingPosition = touch.position
mouseItemData:startPicking()
SoundUtils.PlaySound(Reg.SoundID("pop"))
end
end
end
else
-- PC
end
end
function UISlotOp.slotOnMousePointed(slot, node)
if not SettingsData.isMobileOperation then
UISlotOp.ensureMousePointedShowTips(slot)
end
end
function UISlotOp.ensureMousePointedShowTips(slot)
local TipUI = require("TipUI")
if slot.hasStack then
local mouseItemData = MouseItemData.getInstance()
mouseItemData:showTip(slot:GetStack(), Input.mouse.position, 4)
mouseItemData:stopKeepingTip()
end
end
function UISlotOp.slotOnMousePointedEnter(slot, node)
if not SettingsData.isMobileOperation then
-- PC
UISlotOp.ensureMousePointedShowTips(slot)
end
end
function UISlotOp.slotOnMousePointedLeave(slot, node)
if not SettingsData.isMobileOperation then
-- PC
end
end
---slotOnTouchPointedMove
---@param container Container
---@param slotIndex int
---@param slot Slot
---@param node UINode
---@param touch Touch
---@param pos Vector2
function UISlotOp.slotOnTouchPointedMove(container, slotIndex, slot, node, touch, pos)
local mouseItemData = MouseItemData.getInstance()
if not SettingsData.isMobileOperation then
-- PC
if mouseItemData.isPcCurrentPicking then
return
end
UISlotOp.addAndUpdateSelectingSlot(container, slotIndex, slot)
end
end
function UISlotOp.isSlotSelecting(slot)
return slot.tag < 0
end
---slotOnTouchMove
---@param container Container
---@param slotIndex int
---@param slot Slot
---@param node UINode
---@param touch Touch
---@param pos Vector2
function UISlotOp.slotOnTouchMove(container, slotIndex, slot, node, touch, pos)
local mouseItemData = MouseItemData.getInstance()
if SettingsData.isMobileOperation then
-- Mobile
local outOfCell = not (pos.x >= 0 and pos.y >= 0 and pos.x < node.width and pos.y < node.height)
if outOfCell then
if mouseItemData.pickingOneByOne then
UISlotOp._stopMousePickingItem(container)
end
mouseItemData:closeTip()
end
if slot.hasStack then
if outOfCell then
local mouseSlot = mouseItemData.slot
if not mouseSlot.hasStack then
-- Current: Mouse:[] Target:[item]
if slot:CanPick(slot:GetStack()) then
-- touch is out of the origin slot, move the origin slot item to mouse item!
-- Do: Target:[item] --> Mouse:[]
mouseSlot:SwapStack(slot)
slot:OnPick(mouseSlot:GetStack())
-- Current: Mouse:[item] Target:[]
UISlotOp._EnsureSwapAndFirstHasItemOnly(container,
nil, -1,
container, slotIndex)
mouseItemData:startDragging(container, slotIndex)
mouseItemData.touchingPosition = touch.position
mouseItemData:fixDisplayOffset()
SoundUtils.PlaySound(Reg.SoundID("pop"))
end
end
end
end
mouseItemData.touchingPosition = touch.position
else
-- PC
end
end
---
---@param container Container
---@param slotIndex int
---@param slot Slot
---@param touch Touch
---@param node UINode
function UISlotOp.slotOnTouchPointedUp(container, slotIndex, slot, node, touch)
local mouseItemData = MouseItemData.getInstance()
local mouseSlot = mouseItemData.slot ---@type Slot
if SettingsData.isMobileOperation then
-- Mobile
local originSlot = mouseItemData.originSlot
if mouseSlot.hasStack then
-- Current: Mouse:[item]
if mouseItemData.pickingOneByOne then
UISlotOp._stopMousePickingItem(container)
end
if not slot.hasStack then
-- Current: Mouse:[item] Target:[]
if slot:CanPush(mouseSlot:GetStack()) then
-- Do: Mouse:[item] --> Target:[]
slot:SwapStack(mouseSlot)
slot:OnPush(slot:GetStack())
-- Current: Mouse:[] Target:[item]
UISlotOp._EnsureSwapAndFirstHasItemOnly(container,
container, slotIndex,
nil, -1)
SoundUtils.PlaySound(Reg.SoundID("pop"))
else
-- Current: Mouse:[item] Target:[]
UISlotOp._solveMouseItemSendBackToOriginSlot(container)
end
else
-- Current: Mouse:[item] Target:[item]
if slot:CanPush(mouseSlot:GetStack()) then
local merges = slot:GetStack():GetMergeCount(mouseSlot:GetStack())
if merges > 0 then
-- same item type, do merge
-- Mouse:[item] --> Target:[item]
slot:GetStack():SetStackSize(slot:GetStack().stackSize + merges)
mouseSlot:DecrStackSize(merges)
slot:OnPush(slot:GetStack())
container:CommandSlotMoveTo(nil, -1,
container, slotIndex,
merges)
SoundUtils.PlaySound(Reg.SoundID("pop"))
if mouseSlot.hasStack then
-- Current: Mouse:[item] Target:[item]
UISlotOp._solveMouseItemSendBackToOriginSlot(container)
else
-- Current: Mouse:[] Target:[item]
container:CommandEnsureSlotHasItem(container, slotIndex, slot:GetStack())
container:CommandEnsureSlotEmpty(nil, -1)
end
else
if originSlot ~= nil then
-- not same item type, do swap
if not originSlot.hasStack then
-- Current: Mouse:[item] Target:[item] Origin:[]
if originSlot:CanPush(slot:GetStack()) and slot:CanPick(slot:GetStack()) and slot:CanPush(mouseSlot:GetStack()) then
-- Do: Target:[item] --> Origin:[]
originSlot:SwapStack(slot)
SoundUtils.PlaySound(Reg.SoundID("pop"))
originSlot:OnPush(originSlot:GetStack())
slot:OnPick(originSlot:GetStack())
-- Current: Mouse:[item] Target:[] Origin:[item]
UISlotOp._EnsureSwapAndFirstHasItemOnly(container,
mouseItemData.originContainer, mouseItemData.originSlotIndex,
container, slotIndex)
-- Do: Mouse:[item] --> Target:[]
slot:SwapStack(mouseSlot)
slot:OnPush(slot:GetStack())
-- Current: Mouse:[] Target:[item] Origin:[item]
UISlotOp._EnsureSwapAndFirstHasItemOnly(container,
container, slotIndex,
nil, -1)
else
UISlotOp._solveMouseItemSendBackToOriginSlot(container)
end
else
-- Current: Mouse:[item] Target:[item] Origin:[item]
-- TODO
end
else
-- never happened, in case
mouseSlot:ClearStack()
end
end
end
end
end
else
-- PC
if mouseItemData.isPcCurrentPicking then
return
end
UISlotOp.addAndUpdateSelectingSlot(container, slotIndex, slot)
end
end
---slotOnTouchUp
---@param container Container
---@param slotIndex int
---@param slot Slot
---@param node UINode
---@param touch Touch
function UISlotOp.slotOnTouchUp(container, slotIndex, slot, node, touch)
local mouseItemData = MouseItemData.getInstance()
if SettingsData.isMobileOperation then
-- Mobile
if mouseItemData.slot.hasStack then
if mouseItemData.pickingOneByOne then
UISlotOp._stopMousePickingItem(container)
end
-- the mouse has item, send back to the origin slot
UISlotOp._solveMouseItemSendBackToOriginSlot(container)
end
mouseItemData:stopDragging()
mouseItemData:stopKeepingTip()
else
-- PC
if not mouseItemData.isPcCurrentPicking then
UISlotOp.sendAllSelectingSlots(container)
end
mouseItemData.isPcCurrentPicking = false
end
end
---addAndUpdateSelectingSlot
---@param container Container
---@param slotIndex int
---@param slot Slot
function UISlotOp.addAndUpdateSelectingSlot(container, slotIndex, slot)
-- processed
if UISlotOp.isSlotSelecting(slot) then
return
end
-- check mouse item exist
local mouseItemData = MouseItemData.getInstance()
local mouseSlot = mouseItemData.slot
if not mouseSlot.hasStack then
return
end
-- reach max size
if #mouseItemData.pcSelectingSlots >= mouseSlot:GetStack().stackSize then
return
end
-- cannot merge
if slot.hasStack and slot:GetStack():GetMergeCount(mouseSlot:GetStack()) == 0 then
return
end
UISlotOp.setSelectedNum(slot, 0)
table.insert(mouseItemData.pcSelectingSlots, slot)
table.insert(mouseItemData.pcSelectingContainerAndSlotIndices, { container, slotIndex })
UISlotOp.updateSelectingSlots()
end
---sendAllSelectingSlots
---@param container Container
function UISlotOp.sendAllSelectingSlots(container)
local mouseItemData = MouseItemData.getInstance()
local mouseSlot = mouseItemData.slot
---@param slot Slot
for i, slot in ipairs(mouseItemData.pcSelectingSlots) do
if not mouseSlot.hasStack then
break
end
local targetContainerAndIndex = mouseItemData.pcSelectingContainerAndSlotIndices[i]
local appends = UISlotOp.getSelectedNum(slot)
local actualMoves = 0
if appends > 0 then
local mouseStack = mouseSlot:GetStack()
if not slot.hasStack then
local outStack = mouseStack:SplitStack(appends)
slot:PushStack(outStack)
actualMoves = appends
if mouseStack.stackSize == 0 then
mouseSlot:ClearStack()
end
else
local stack = slot:GetStack()
local merges = stack:GetMergeCount(mouseStack)
local actualAppends = math.min(merges, appends)
if actualAppends > 0 then
stack:SetStackSize(stack.stackSize + actualAppends)
mouseSlot:DecrStackSize(actualAppends)
actualMoves = actualAppends
end
end
end
if actualMoves > 0 then
container:CommandSlotMoveTo(nil, -1,
targetContainerAndIndex[1], targetContainerAndIndex[2],
actualMoves
)
end
end
for _, slot in ipairs(mouseItemData.pcSelectingSlots) do
UISlotOp.clearSelected(slot)
end
UISlotOp.clearSelected(mouseItemData.slot)
mouseItemData.pcSelectingSlots = {}
mouseItemData.pcSelectingContainerAndSlotIndices = {}
end
function UISlotOp.updateSelectingSlots()
local mouseItemData = MouseItemData.getInstance()
local mouseSlot = mouseItemData.slot
if not mouseSlot.hasStack then
return
end
local mouseStack = mouseSlot:GetStack()
local mouseStackSize = mouseStack.stackSize
local slots = mouseItemData.pcSelectingSlots
local totalSlots = #slots
if totalSlots == 0 then
return
end
local everyAppends = 1
local actualAppends = 0
if mouseItemData.pcIsAverageMode then
everyAppends = math.floor(mouseStackSize / totalSlots)
end
---@param slot Slot
for _, slot in ipairs(slots) do
local actual = 0
if not slot.hasStack then
actual = everyAppends
else
actual = math.min(slot:GetStack():GetMergeCount(mouseStack), everyAppends)
end
UISlotOp.setSelectedNum(slot, actual)
actualAppends = actualAppends + actual
end
UISlotOp.setSelectedNum(mouseSlot, mouseStackSize - actualAppends)
end
function UISlotOp.getSelectedNum(slot)
return slot.tag - SLOT_TAG_SELECTING
end
function UISlotOp.setSelectedNum(slot, num)
slot.tag = SLOT_TAG_SELECTING + num
end
function UISlotOp.clearSelected(slot)
slot.tag = 0
end
function UISlotOp._GetCommandTargetItemStack(container, slotIndex)
return slotIndex == -1 and MouseItemData.getInstance().slot:GetStack() or container:GetSlot(slotIndex):GetStack()
end
---EnsureSwapAndFirstHasItem
---@param container Container
---@param containerA Container
---@param slotIndexA int
---@param containerB Container
---@param slotIndexB int
function UISlotOp._EnsureSwapAndFirstHasItemOnly(container, containerA, slotIndexA, containerB, slotIndexB)
container:CommandSwapSlot(containerA, slotIndexA, containerB, slotIndexB)
container:CommandEnsureSlotHasItem(containerA, slotIndexA, UISlotOp._GetCommandTargetItemStack(containerA, slotIndexA))
container:CommandEnsureSlotEmpty(containerB, slotIndexB)
end
---EnsureSwapAndBothHasItem
---@param container Container
---@param containerA Container
---@param slotIndexA int
---@param containerB Container
---@param slotIndexB int
function UISlotOp._EnsureSwapAndBothHasItem(container, containerA, slotIndexA, containerB, slotIndexB)
container:CommandSwapSlot(containerA, slotIndexA, containerB, slotIndexB)
container:CommandEnsureSlotHasItem(containerA, slotIndexA, UISlotOp._GetCommandTargetItemStack(containerA, slotIndexA))
container:CommandEnsureSlotHasItem(containerB, slotIndexB, UISlotOp._GetCommandTargetItemStack(containerB, slotIndexB))
end
---stopMousePickingItem
---@param container Container
function UISlotOp._stopMousePickingItem(container)
local mouseItemData = MouseItemData.getInstance()
if mouseItemData.pickingOneByOne then
local mouseSlot = mouseItemData.slot
if mouseSlot.hasStack then
container:CommandEnsureSlotEmpty(nil, -1)
container:CommandSlotMoveTo(
mouseItemData.originContainer, mouseItemData.originSlotIndex,
nil, -1, mouseSlot:GetStack().stackSize)
container:CommandEnsureSlotHasItem(
nil, -1, mouseSlot:GetStack())
mouseItemData.originSlot:OnPick(mouseSlot:GetStack())
if mouseItemData.originSlot.hasStack then
-- Current: Mouse:[item] Origin:[item]
container:CommandEnsureSlotHasItem(
mouseItemData.originContainer, mouseItemData.originSlotIndex,
mouseItemData.originSlot:GetStack())
else
-- Current: Mouse:[item] Origin:[]
container:CommandEnsureSlotEmpty(mouseItemData.originContainer, mouseItemData.originSlotIndex)
end
end
mouseItemData:stopPicking()
end
end
---solveMouseItemSendBackToOriginSlot
---@param container Container
function UISlotOp._solveMouseItemSendBackToOriginSlot(container)
local mouseItemData = MouseItemData.getInstance()
local mouseSlot = mouseItemData.slot
if mouseSlot.hasStack then
local originSlot = mouseItemData.originSlot
if originSlot ~= nil then
-- mouse item left, send back to the origin slot
container:CommandEnsureSlotHasItem(nil, -1, UISlotOp._GetCommandTargetItemStack(nil, -1))
if not originSlot.hasStack then
if originSlot:CanPush(mouseSlot:GetStack()) then
originSlot:SwapStack(mouseSlot)
originSlot:OnPush(originSlot:GetStack())
-- now the origin slot has item and mouse item is empty
UISlotOp._EnsureSwapAndFirstHasItemOnly(container,
mouseItemData.originContainer, mouseItemData.originSlotIndex,
nil, -1)
SoundUtils.PlaySound(Reg.SoundID("pop"))
end
else
if originSlot:CanPush(mouseSlot:GetStack()) then
local merges = originSlot:GetStack():GetMergeCount(mouseSlot:GetStack())
if merges > 0 then
originSlot:GetStack():SetStackSize(originSlot:GetStack().stackSize + merges)
originSlot:OnPush(originSlot:GetStack())
mouseSlot:DecrStackSize(merges)
container:CommandSlotMoveTo(nil, -1,
mouseItemData.originContainer, mouseItemData.originSlotIndex,
merges)
SoundUtils.PlaySound(Reg.SoundID("pop"))
end
end
end
else
-- in case
mouseSlot:ClearStack()
end
if mouseSlot.hasStack then
-- TODO DROP OUT!
end
end
end
---slotOnTouchShowTip
---@param slot Slot
---@param node UINode
---@param touch Touch
function UISlotOp.slotOnTouchShowTip(slot, node, touch)
if slot.hasStack then
local mouseItemData = MouseItemData.getInstance()
mouseItemData:showTip(slot:GetStack(), touch.position, 128)
mouseItemData.touchingPosition = touch.position
mouseItemData:stopKeepingTip()
end
end
---
---@param stack ItemStack
---@param node UINode
---@param canvasPos Vector2
function UISlotOp.itemStackOnRenderWithShadow(stack, node, canvasPos)
local SHADOW_OFFSET = 2
local SHADOW_OFFSET_HALF = SHADOW_OFFSET / 2
local pos = node.positionInCanvas + canvasPos +
Vector2.new(node.width / 2 + SHADOW_OFFSET_HALF, node.height / 2 + SHADOW_OFFSET_HALF)
local exData = SpriteExData.new()
exData.origin = Vector2.new(16, 16)
stack:Render(pos, Color.Black, exData)
pos.x = pos.x - SHADOW_OFFSET
pos.y = pos.y - SHADOW_OFFSET
stack:Render(pos, Color.White, exData)
end
---
---@param stack ItemStack
---@param node UINode
---@param canvasPos Vector2
function UISlotOp.itemStackOnRender(stack, node, canvasPos)
local pos = node.positionInCanvas + canvasPos + Vector2.new(node.width / 2, node.height / 2)
local exData = SpriteExData.new()
exData.origin = Vector2.new(16, 16)
stack:Render(pos, Color.White, exData)
end
---slotOnRender
---@param slot Slot
---@param node UINode
---@param canvasPos Vector2
function UISlotOp.slotOnRender(slot, node, canvasPos)
if slot.hasStack then
UISlotOp.itemStackOnRender(slot:GetStack(), node, canvasPos)
elseif slot.tag < 0 then
local mouseItemData = MouseItemData.getInstance()
local mouseSlot = mouseItemData.slot
if mouseSlot.hasStack then
UISlotOp.itemStackOnRender(mouseSlot:GetStack(), node, canvasPos)
end
end
end
---slotOnRenderNum
---@param slot Slot
---@param node UINode
---@param canvasPos Vector2
function UISlotOp.slotOnRenderNum(slot, node, canvasPos)
if slot.hasStack or slot.tag < 0 then
local stack
local useCustomNum = slot.tag < 0
if slot.hasStack then
stack = slot:GetStack()
else
local mouseItemData = MouseItemData.getInstance()
local mouseSlot = mouseItemData.slot
if mouseSlot.hasStack then
stack = mouseSlot:GetStack()
end
end
if stack == nil then
return
end
local pos = node.positionInCanvas + canvasPos + Vector2.new(node.width / 2, node.height / 2)
local exData = SpriteExData.new()
exData.origin = Vector2.new(16, 16)
if useCustomNum then
stack:RenderCustomNum(UISlotOp.getSelectedNum(slot), pos, Color.Yellow, exData)
else
stack:RenderNum(pos, Color.White, exData)
end
end
end
---@param slot Slot
---@param node UINode
---@param canvasPos Vector2
function UISlotOp.slotOnRenderDurableBar(slot, node, canvasPos)
if not slot.hasStack then
return
end
local stack = slot:GetStack()
local item = stack:GetItem()
if item.maxDurable <= 0 or stack.durable >= item.maxDurable then
return
end
local rate = stack.durable * 1.0 / item.maxDurable
--local rate = 0.8
local UIManager = require("ui.UIManager")
local texture = UIManager.getInstance().durableBarTexture
local cutRect = Rect.new(0, 0, 32, 12)
local cutRectContent = Rect.new(0, 12, math.floor(32 * rate), 12)
local pos = node.positionInCanvas + canvasPos + Vector2.new(node.width / 2 - 16, node.height / 2 + 10)
Sprite.draw(texture, pos, cutRect, Color.White)
local colorContent = Color.new(220 * (1 - rate), 220 * rate, 0, 255)
Sprite.draw(texture, pos, cutRectContent, colorContent)
end
function UISlotOp.onCheckPCDropOutItem()
if SettingsData.isMobileOperation then
return false
end
local mouseItemData = MouseItemData.getInstance()
local mouseSlot = mouseItemData.slot
if mouseSlot.hasStack then
local NetworkProxy = require("network.NetworkProxy")
local RPC_ID = require("network.RPC_ID")
NetworkProxy.RPCSendServerBound(Mod.GetByID("tc"), RPC_ID.SB_DROP_ITEM_MOUSE)
mouseSlot:ClearStack()
return true
end
return false
end
return UISlotOp
================================================
FILE: ui/UISpritePool.lua
================================================
---@class TC.UISpritePool
local UISpritePool = class("UISpritePool")
local s_uiSpritePool = nil
---@return TC.UISpritePool
function UISpritePool.getInstance()
if s_uiSpritePool == nil then
s_uiSpritePool = UISpritePool.new()
end
return s_uiSpritePool
end
function UISpritePool:__init()
self._pool = {}
end
---add
---@param name string
---@param sprite UISprite
function UISpritePool:add(name, sprite)
self._pool[name] = sprite:clone()
end
---@param name string
---@return boolean
function UISpritePool:has(name)
return self._pool[name] ~= nil
end
---get
---@param name string
---@return UISprite
function UISpritePool:get(name)
local sprite = self._pool[name]
assert(sprite ~= nil, "cannot find " .. name .. " in UISpritePool.")
return sprite:clone()
end
function UISpritePool:clear()
for k in pairs(self._pool) do
self._pool[k] = nil
end
end
return UISpritePool
================================================
FILE: ui/UIUtil.lua
================================================
---@class TC.UIUtil
local UIUtil = class("UIUtil")
local UIDefault = require("UIDefault")
local UISpritePool = require("UISpritePool").getInstance()
local UISlotOp = require("UISlotOp")
---
---@param btn UIButton
---@param infoTable table
function UIUtil.doInfoTableForButton(btn, infoTable)
UIUtil.doInfoTable(btn, infoTable)
if infoTable ~= nil then
if infoTable.targetSprite ~= nil then
if infoTable.targetSprite.name ~= nil then
btn.targetSprite = UISpritePool:get(infoTable.targetSprite.name)
end
UIUtil.doInfoTableForSprite(btn.targetSprite, infoTable.targetSprite)
end
end
end
---createButton
---@param name string
---@param caption string
---@param x number
---@param y number
---@param width number
---@param height number
---@param infoTable table
---@return UIButton
function UIUtil.createButton(name, caption, x, y, width, height, infoTable)
assert(x ~= nil)
assert(y ~= nil)
assert(width ~= nil)
assert(height ~= nil)
local btn = UIButton.new(name, x, y, width, height)
btn.targetSprite = UISpritePool:get("tc:button_normal")
btn.highlightedSprite = UISpritePool:get("tc:button_highlight")
--btn.highlightedSprite.positionOffset.y = -3
btn.selectedSprite = UISpritePool:get("tc:button_highlight")
btn.pressedSprite = UISpritePool:get("tc:button_pressed")
btn.pressedSprite.positionOffset.y = 2
if caption ~= nil and caption ~= "" then
local lb = UIText.new("lb_caption")
lb.outlineSize = 1
lb:setMarginEnabled(true, true, true, true)
lb.horizontalOverflow = TextHorizontalOverflow.Overflow
--lb:setAutoStretch(true,true)
lb.text = caption
lb.fontSize = UIDefault.FontSize
lb.horizontalAlignment = TextAlignment.HCenter
lb.verticalAlignment = TextAlignment.VCenter
btn:addChild(lb)
end
UIUtil.doInfoTableForButton(btn, infoTable)
return btn
end
---createButtonWithImage
---@param name string
---@param uiSpriteName string
---@param x number
---@param y number
---@param width number
---@param height number
---@param infoTable table
---@param imgInfoTable table
---@return UIButton
function UIUtil.createButtonWithImage(name, uiSpriteName, x, y, width, height, infoTable, imgInfoTable)
local btn = UIUtil.createButton(name, nil, x, y, width, height, infoTable)
local image = UIImage.new("img")
image:setMarginEnabled(true, true, true, true)
image.sprite = UISpritePool:get(uiSpriteName)
image.touchable = false
btn:addChild(image)
if imgInfoTable ~= nil then
UIUtil.doInfoTableForImage(image, imgInfoTable)
end
return btn
end
function UIUtil.setSlotStyle(slot, cellStyle)
cellStyle = cellStyle or 1
local targetSpriteName = "tc:cell_empty"
local highlightedSpriteName = "tc:cell_selected"
local selectedSpriteName = "tc:cell_selected"
local pressedSpriteName = "tc:cell_selected"
if cellStyle > 1 then
local postFix = string.format("_%d", cellStyle)
targetSpriteName = targetSpriteName .. postFix
highlightedSpriteName = highlightedSpriteName .. postFix
selectedSpriteName = selectedSpriteName .. postFix
pressedSpriteName = pressedSpriteName .. postFix
end
local btn = UIButton.cast(slot)
btn.targetSprite = UISpritePool:get(targetSpriteName)
btn.highlightedSprite = UISpritePool:get(highlightedSpriteName)
btn.selectedSprite = UISpritePool:get(selectedSpriteName)
btn.pressedSprite = UISpritePool:get(pressedSpriteName)
end
function UIUtil.innerCreateSlot(name, x, y, width, height, iconName, cellStyle)
width = width or UIDefault.CellSize
height = height or UIDefault.CellSize
local btn = UIButton.new(name, x, y, width, height)
if iconName then
local image = UIImage.new("img")
image:setMarginEnabled(true, true, true, true)
image.sprite = UISpritePool:get(iconName)
image.sprite.color = Color.new(255, 255, 255, 128)
image.touchable = false
btn:addChild(image)
end
UIUtil.setSlotStyle(btn, cellStyle)
return btn
end
function UIUtil.createSlot(name, x, y, width, height, iconName)
return UIUtil.innerCreateSlot(name, x, y, width, height, iconName)
end
function UIUtil.createSlotStyle(name, x, y, width, height, style)
return UIUtil.innerCreateSlot(name, x, y, width, height, nil, style)
end
---hookSlotView
---@param slotNode UINode
---@param itemSlot Slot
---@param isClickShowTip boolean
function UIUtil.hookSlotView(slotNode, itemSlot, isClickShowTip)
if isClickShowTip == nil then
isClickShowTip = true
end
slotNode:getPostDrawLayer(0):addListener({ UISlotOp.slotOnRender, itemSlot })
slotNode:getPostDrawLayer(1):addListener({ UISlotOp.slotOnRenderNum, itemSlot })
slotNode:getPostDrawLayer(1):addListener({ UISlotOp.slotOnRenderDurableBar, itemSlot })
slotNode:addMousePointedListener({ UISlotOp.slotOnMousePointed, itemSlot })
slotNode:addMousePointedEnterListener({ UISlotOp.slotOnMousePointedEnter, itemSlot })
slotNode:addMousePointedLeaveListener({ UISlotOp.slotOnMousePointedLeave, itemSlot })
if isClickShowTip then
slotNode:addTouchDownListener({ UISlotOp.slotOnTouchShowTip, itemSlot })
end
end
---hookSlot
---@param slotNode UINode
---@param guiContainer GuiContainer
---@param slotIndex int
function UIUtil.hookSlot(slotNode, guiContainer, slotIndex)
local slot = guiContainer.container:GetSlot(slotIndex)
slotNode.allowDoubleClick = true
UIUtil.hookSlotView(slotNode, slot, false)
slotNode:addTouchDownListener({ UISlotOp.slotOnTouchDown, guiContainer, guiContainer.container, slotIndex, slot })
slotNode:addTouchDoubleDownListener({ UISlotOp.slotOnTouchDoubleDown, guiContainer.container, slotIndex, slot })
slotNode:addTouchMoveListener({ UISlotOp.slotOnTouchMove, guiContainer.container, slotIndex, slot })
slotNode:addTouchPointedMoveListener({ UISlotOp.slotOnTouchPointedMove, guiContainer.container, slotIndex, slot })
slotNode:addTouchPointedUpListener({ UISlotOp.slotOnTouchPointedUp, guiContainer.container, slotIndex, slot })
slotNode:addTouchUpAfterMoveListener({ UISlotOp.slotOnTouchUp, guiContainer.container, slotIndex, slot })
end
---doInfoTableForSprite
---@param uiSprite UISprite
---@param infoTable table
function UIUtil.doInfoTableForSprite(uiSprite, infoTable)
if infoTable ~= nil then
if infoTable.color ~= nil then
uiSprite.color = infoTable.color
end
if infoTable.style ~= nil then
uiSprite.style = infoTable.style
end
end
end
---doInfoTable
---@param uiNode UINode
---@param infoTable table
function UIUtil.doInfoTable(uiNode, infoTable)
if infoTable ~= nil then
if infoTable.anchorPoint ~= nil then
uiNode:setAnchorPoint(infoTable.anchorPoint[1], infoTable.anchorPoint[2])
end
if infoTable.positionY ~= nil then
uiNode.positionY = infoTable.positionY
end
if infoTable.positionX ~= nil then
uiNode.positionX = infoTable.positionX
end
if infoTable.size ~= nil then
uiNode.size = infoTable.size
end
if infoTable.touchable ~= nil then
uiNode.touchable = infoTable.touchable
end
if infoTable.margins ~= nil then
local autoStretchWidth = nil
local autoStretchHeight = nil
if infoTable.margins[5] ~= nil then
autoStretchWidth = infoTable.margins[5]
end
if infoTable.margins[6] ~= nil then
autoStretchHeight = infoTable.margins[6]
end
UIUtil.setMargins(uiNode, infoTable.margins[1], infoTable.margins[2],
infoTable.margins[3], infoTable.margins[4], autoStretchWidth, autoStretchHeight)
end
if infoTable.marginsLR ~= nil then
local autoStretch = nil
if infoTable.marginsLR[3] ~= nil then
autoStretch = infoTable.marginsLR[3]
end
UIUtil.setMarginsLR(uiNode, infoTable.marginsLR[1], infoTable.marginsLR[2], autoStretch)
end
if infoTable.marginsTB ~= nil then
local autoStretch = false
if infoTable.marginsTB[3] ~= nil then
autoStretch = infoTable.marginsTB[3]
end
UIUtil.setMarginsTB(uiNode, infoTable.marginsTB[1], infoTable.marginsTB[2], autoStretch)
end
if infoTable.visible ~= nil then
uiNode.visible = infoTable.visible
end
end
end
---doInfoTableForImage
---@param img UIImage
---@param infoTable table
function UIUtil.doInfoTableForImage(img, infoTable)
UIUtil.doInfoTable(img, infoTable)
if infoTable ~= nil then
if infoTable.sprite ~= nil then
if infoTable.sprite.name ~= nil then
img.sprite = UISpritePool:get(infoTable.sprite.name)
end
UIUtil.doInfoTableForSprite(img.sprite, infoTable.sprite)
end
end
end
---@param panel UIPanel
---@param infoTable table
function UIUtil.doInfoTableForPanel(panel, infoTable)
UIUtil.doInfoTable(panel, infoTable)
if infoTable ~= nil then
if infoTable.sprite ~= nil then
if infoTable.sprite.name ~= nil then
panel.sprite = UISpritePool:get(infoTable.sprite.name)
end
UIUtil.doInfoTableForSprite(panel.sprite, infoTable.sprite)
end
end
end
---createImage
---@param name string
---@param x number
---@param y number
---@param width number
---@param height number
---@param infoTable table
function UIUtil.createImage(name, x, y, width, height, infoTable)
local img = UIImage.new(name, x, y, width, height)
UIUtil.doInfoTableForImage(img, infoTable)
return img
end
---createImage
---@param name string
---@param infoTable table
function UIUtil.createImageNoPos(name, infoTable)
local img = UIImage.new(name)
UIUtil.doInfoTableForImage(img, infoTable)
return img
end
---@param name string
---@param x number
---@param y number
---@param width number
---@param height number
---@param infoTable table
---@return UIPanel
function UIUtil.createPanel(name, x, y, width, height, infoTable)
local panel = UIPanel.new(name, x, y, width, height)
UIUtil.doInfoTableForPanel(panel, infoTable)
return panel
end
---@param name string
---@param infoTable table
---@return UIPanel
function UIUtil.createPanelNoPos(name, infoTable)
local panel = UIPanel.new(name)
UIUtil.doInfoTableForPanel(panel, infoTable)
return panel
end
---doInfoTableForSlider
---@param lb UISlider
---@param infoTable table
function UIUtil.doInfoTableForSlider(slider, infoTable)
UIUtil.doInfoTable(slider, infoTable)
if infoTable ~= nil then
end
end
---createSlider
---@param name string
---@param x number
---@param y number
---@param width number
---@param height number
---@param infoTable table
function UIUtil.createSlider(name, x, y, width, height, infoTable)
local slider = UISlider.new(name, x, y, width, height)
slider.barSprite = UISpritePool:get("tc:round_rect_white")
slider.barSprite.color = Color.new(20, 20, 30)
slider.activeBarSprite = UISpritePool:get("tc:round_rect_white")
slider.activeBarSprite.color = Color.new(80, 80, 120)
slider.sliderSprite = UISpritePool:get("tc:white_circle")
slider.sliderSize = Size.new(24, 24)
slider.sliderSprite.color = Color.new(140, 140, 180)
UIUtil.doInfoTableForSlider(slider, infoTable)
return slider
end
---doInfoTableForLabel
---@param lb UIText
---@param infoTable table
function UIUtil.doInfoTableForLabel(lb, infoTable)
UIUtil.doInfoTable(lb, infoTable)
if infoTable ~= nil then
if infoTable.color ~= nil then
lb.color = infoTable.color
end
if infoTable.fontSize ~= nil then
lb.fontSize = infoTable.fontSize
end
if infoTable.isRichText ~= nil then
lb.isRichText = infoTable.isRichText
end
if infoTable.autoAdaptSize ~= nil then
lb.autoAdaptSize = infoTable.autoAdaptSize
end
if infoTable.horizontalOverflow ~= nil then
lb.horizontalOverflow = infoTable.horizontalOverflow
end
end
end
---createLabel
---@param name string
---@param content string
---@param x number
---@param y number
---@param width number
---@param height number
---@param horizontalAlignment TextAlignment_Value
---@param verticalAlignment TextAlignment_Value
---@param infoTable table
---@return UIText
function UIUtil.createLabel(name, content, x, y, width, height, horizontalAlignment, verticalAlignment, infoTable)
if horizontalAlignment == nil then
horizontalAlignment = TextAlignment.Left
end
if verticalAlignment == nil then
verticalAlignment = TextAlignment.Top
end
local lb = UIText.new(name, x, y, width, height)
lb.outlineSize = 1
lb.text = content
lb.fontSize = UIDefault.FontSize
lb.horizontalAlignment = horizontalAlignment
lb.verticalAlignment = verticalAlignment
lb.horizontalOverflow = TextHorizontalOverflow.Overflow
UIUtil.doInfoTableForLabel(lb, infoTable)
return lb
end
---createLabelNoPos
---@param name string
---@param content string
---@param horizontalAlignment TextAlignment_Value
---@param verticalAlignment TextAlignment_Value
---@param infoTable table
---@return UIText
function UIUtil.createLabelNoPos(name, content, horizontalAlignment, verticalAlignment, infoTable)
local lb = UIUtil.createLabel(name, content, 0, 0, 32, 32,
horizontalAlignment, verticalAlignment, infoTable)
return lb
end
---
---@param panelList UIScrollView
---@param infoTable table
function UIUtil.doInfoTableForScrollView(panelList, infoTable)
UIUtil.doInfoTable(panelList, infoTable)
if infoTable ~= nil then
if infoTable.sprite ~= nil then
if infoTable.sprite.name ~= nil then
panelList.sprite = UISpritePool:get(infoTable.sprite.name)
UIUtil.doInfoTableForSprite(panelList.sprite, infoTable.sprite)
end
end
end
end
---createScrollView
---@param name string
---@param x number
---@param y number
---@param width number
---@param height number
---@param infoTable table
---@return UIScrollView
function UIUtil.createScrollView(name, x, y, width, height, infoTable)
local panelList = UIScrollView.new(name, x, y, width, height)
panelList.viewSize = Size.new(panelList.size.width, 600)
UIUtil.doInfoTableForScrollView(panelList, infoTable)
return panelList
end
---createScrollView
---@param name string
---@param infoTable table
function UIUtil.createScrollViewNoPos(name, infoTable)
local panelList = UIScrollView.new(name)
UIUtil.doInfoTableForScrollView(panelList, infoTable)
panelList.viewSize = Size.new(panelList.size.width, 600)
return panelList
end
---
---@param panel UIPanel
---@param infoTable table
function UIUtil.doInfoTableForPanel(panel, infoTable)
UIUtil.doInfoTable(panel, infoTable)
if infoTable ~= nil then
if infoTable.sprite ~= nil then
if infoTable.sprite.name ~= nil then
panel.sprite = UISpritePool:get(infoTable.sprite.name)
UIUtil.doInfoTableForSprite(panel.sprite, infoTable.sprite)
end
end
end
end
---@param name string
---@param x number
---@param y number
---@param width number
---@param height number
---@param infoTable table
function UIUtil.createPanel(name, x, y, width, height, infoTable)
local panel = UIPanel.new(name, x, y, width, height)
UIUtil.doInfoTableForPanel(panel, infoTable)
return panel
end
---
---@param sw UISwitch
---@param infoTable table
function UIUtil.doInfoTableForSwitch(sw, infoTable)
UIUtil.doInfoTable(sw, infoTable)
if infoTable ~= nil then
if infoTable.selected ~= nil then
sw:setSelected(infoTable.selected, false)
end
end
end
---@param name string
---@param x number
---@param y number
---@param width number
---@param height number
---@param infoTable table
function UIUtil.createSwitch(name, x, y, width, height, infoTable)
local sw = UISwitch.new(name, x, y, width, height)
sw.offBackgroundSprite = UISpritePool:get("tc:round_rect_white")
sw.offBackgroundSprite.color = Color.new(20, 20, 30)
sw.onBackgroundSprite = UISpritePool:get("tc:round_rect_white")
sw.onBackgroundSprite.color = Color.new(80, 80, 120)
sw.offSliderSprite = UISpritePool:get("tc:white_circle")
sw.offSliderSprite.color = Color.new(140, 140, 180)
sw.fadeTime = 0.25
sw.sliderSize = Size.new(24, 24)
UIUtil.doInfoTableForSwitch(sw, infoTable)
return sw
end
---setMargins
---@param node UINode
---@param left number
---@param top number
---@param right number
---@param bottom number
---@param autoStretchWidth boolean
---@param autoStretchHeight boolean
function UIUtil.setMargins(node, left, top, right, bottom, autoStretchWidth, autoStretchHeight)
if left ~= nil then
node:setLeftMargin(left, true)
else
node:setLeftMargin(0, false)
end
if top ~= nil then
node:setTopMargin(top, true)
else
node:setTopMargin(0, false)
end
if right ~= nil then
node:setRightMargin(right, true)
else
node:setRightMargin(0, false)
end
if bottom ~= nil then
node:setBottomMargin(bottom, true)
else
node:setBottomMargin(0, false)
end
if autoStretchWidth == nil then
if left ~= nil and right ~= nil then
autoStretchWidth = true
else
autoStretchWidth = false
end
end
if autoStretchHeight == nil then
if top ~= nil and bottom ~= nil then
autoStretchHeight = true
else
autoStretchHeight = false
end
end
node.autoStretchWidth = autoStretchWidth
node.autoStretchHeight = autoStretchHeight
end
---setMarginsLR
---@param node UINode
---@param left number
---@param right number
---@param autoStretch boolean
function UIUtil.setMarginsLR(node, left, right, autoStretch)
UIUtil.setMargins(node, left, nil, right, nil, autoStretch, nil)
end
---setMarginsTB
---@param node UINode
---@param top number
---@param bottom number
---@param autoStretch boolean
function UIUtil.setMarginsTB(node, top, bottom, autoStretch)
UIUtil.setMargins(node, nil, top, nil, bottom, nil, autoStretch)
end
---setTable
---@param panelList UINode
---@param proxy any
---@param isVertical boolean
---@param countPreLine number
---@return boolean
function UIUtil.setTable(panelList, proxy, isVertical, countPreLine)
if not panelList:getChild("panel_item"):valid() then
return false
end
isVertical = isVertical or true
countPreLine = countPreLine or 1
local sv = UIScrollView.cast(panelList)
sv:ScrollToLeft()
sv:ScrollToTop()
local count = 0
local panelItem = panelList:getChild("panel_item")
panelItem.visible = false
local lastCount = panelList:getChildrenCount()
local childrenToRemoved = {}
for i = 1, lastCount do
local child = panelList:getChildByIndex(i - 1)
if child.name ~= "panel_item" then
table.insert(childrenToRemoved, child)
end
end
---@param child UINode
for _, child in pairs(childrenToRemoved) do
panelList:removeChild(child)
end
childrenToRemoved = {}
if proxy._getTableElementCount == nil then
count = 0
else
count = proxy:_getTableElementCount()
end
local offsetX = 0
local offsetY = 0
local maxX = 0
local maxY = 0
local indexPreLine = 1
for i = 1, count do
local itemName = string.format("panel_item_%d", i)
local tempItem = panelList:getChild(itemName)
local needCreate = false
if tempItem:valid() then
panelList:removeChild(tempItem)
needCreate = true
else
needCreate = true
end
if needCreate then
tempItem = panelItem:clone()
tempItem.name = itemName
panelList:addChild(tempItem, i)
end
tempItem:setAnchorPoint(0, 0)
tempItem.visible = true
if proxy._getTableElementSize ~= nil then
local size = proxy:_getTableElementSize(i)
if size ~= nil then
tempItem.size = size
tempItem:applyMargin()
end
end
tempItem:setPosition(offsetX, offsetY)
if proxy._setTableElement ~= nil then
proxy:_setTableElement(tempItem, i)
end
local offsetWidth = tempItem.width
local offsetHeight = tempItem.height
if proxy._getTableElementPositionOffset ~= nil then
local size = proxy:_getTableElementPositionOffset(i)
offsetWidth, offsetHeight = size.width, size.height
end
maxX = tempItem.positionX + offsetWidth
maxY = tempItem.positionY + offsetHeight
if indexPreLine >= countPreLine then
indexPreLine = 1
if isVertical then
offsetY = offsetY + offsetHeight
offsetX = 0
else
offsetX = offsetX + offsetWidth
offsetY = 0
end
else
indexPreLine = indexPreLine + 1
if isVertical then
offsetX = offsetX + offsetWidth
else
offsetY = offsetY + offsetHeight
end
end
end
maxX = math.max(maxX, sv.width)
maxY = math.max(maxY, sv.height)
sv.viewSize = Size.new(maxX, maxY)
sv:ScrollToLeft()
sv:ScrollToTop()
return true
end
---getTableElement
---@param uiTable UIScrollView
---@param index number
function UIUtil.getTableElement(uiTable, index)
return uiTable:getChildByTag(index)
end
---createBlackFullScreenLayer
---@param name string
---@return UIPanel
function UIUtil.createBlackFullScreenLayer(name)
local cover = UIPanel.new(name)
cover.size = GameWindow.displayResolution
cover:setMarginEnabled(true, true, true, true)
cover:setAutoStretch(true, true)
cover.sprite = UISpritePool:get("tc:black")
cover.sprite.color = Color.new(255, 255, 255, 192)
return cover
end
---createWindowPattern
---@param root UINode
---@param windowSize Size
---@param cfgTable table
---@return UIPanel
function UIUtil.createWindowPattern(root, windowSize, cfgTable)
local panel = UIPanel.new("layer", 0, 0, windowSize.width, windowSize.height)
UIUtil.setMargins(panel, 0, 0, 0, 0, false, false)
if root ~= nil then
root:addChild(panel)
end
if cfgTable and cfgTable.style then
if cfgTable.style == "Gray" then
local bg = UIImage.new("bg")
bg.sprite = UISpritePool:get("tc:base")
UIUtil.setMargins(bg, 0, 0, 0, 0)
panel:addChild(bg)
end
else
local bg_frame = UIImage.new("bg_frame")
bg_frame.sprite = UISpritePool:get("tc:window_frame_01")
bg_frame.sprite.color = Color.new(255, 255, 255, 160)
UIUtil.setMargins(bg_frame, 0, 0, 0, 0)
panel:addChild(bg_frame)
local bg = UIImage.new("bg")
UIUtil.setMargins(bg, 2, 2, 2, 2)
bg.sprite = UISpritePool:get("tc:window_bg_01")
bg.sprite.style = UISpriteStyle.Filled
bg.sprite.color = Color.new(255, 255, 255, 30)
bg_frame:addChild(bg)
end
return panel
end
---renderProgress
---@param source string|TextureLocation
---@param pos Vector2
---@param steps int
---@param totalSteps int
---@param dirX int L->R: 1 R->L: -1
---@param dirY int T->B 1 B->T: -1
function UIUtil.renderProgress(source, pos, steps, totalSteps, dirX, dirY)
if steps <= 0 or totalSteps <= 0 then
return
end
if dirX == nil then
dirX = 0
end
if dirY == nil then
dirY = 0
end
if dirX == 0 and dirY == 0 then
return
end
local texture
if type(source) == 'string' then
texture = UISpritePool:get(source).textureLocation
else
texture = source
end
local sourceRect = TextureManager.getSourceRect(texture)
local sw = sourceRect.width
local sh = sourceRect.height
local offsetX = 0
local offsetY = 0
local rate = steps * 1.0 / totalSteps
local rectCut
if dirX ~= 0 then
local pw = math.floor(sw * rate)
if dirX > 0 then
rectCut = Rect.new(0, 0, pw, sh)
else
offsetX = sw - pw
rectCut = Rect.new(offsetX, 0, pw, sh)
end
else
local ph = math.floor(sh * rate)
if dirY > 0 then
rectCut = Rect.new(0, 0, sw, ph)
else
offsetY = sh - ph
rectCut = Rect.new(0, offsetY, sw, ph)
end
end
local drawPos = Vector2.new(pos.x + offsetX, pos.y + offsetY)
Sprite.draw(texture, drawPos, rectCut, Color.White)
end
return UIUtil
================================================
FILE: ui/UIWindow.lua
================================================
---@class TC.UIWindow
local UIWindow = class("UIWindow")
local UIManager = require("UIManager")
local MouseItemData = require("MouseItemData")
local API = require("api")
local UIDefault = require("ui.UIDefault")
---__init
---@param root UIPanel
function UIWindow:__init(root, uiGroup)
self.root = root
self.manager = UIManager.getInstance()
self.mouseItemData = MouseItemData.getInstance()
self.windowId = self.manager:addWindowsLoaded(self)
self.closed = false
self.scheduleIds = {}
self.allowCloseByEsc = false
self.uiGroup = UIDefault.GROUP_NONE
if uiGroup ~= nil then
self.uiGroup = uiGroup
end
self.root.textBatchRendering = true
self.uiClassName = self.__cname
self._modifyInstances = {}
self:initModifyFromOutside()
end
function UIWindow:initModifyFromOutside()
local dict = API.getInstance().uiModifyDict[self.uiClassName]
if dict ~= nil then
for _, modifyClass in ipairs(dict) do
local ins = modifyClass.new(self)
table.insert(self._modifyInstances, ins)
end
end
end
function UIWindow:closeWindow()
self.manager:removeWindowsLoaded(self.windowId)
self.closed = true
self:onDestroy()
for _, scheduleID in ipairs(self.scheduleIds) do
IntegratedClient.main:removeSchedule(scheduleID)
end
self.scheduleIds = {}
end
function UIWindow:onDestroy()
end
function UIWindow:initUpdateFunc(listener, intervalTicks)
intervalTicks = intervalTicks or 0
local scheduleID = IntegratedClient.main:createSchedule(intervalTicks)
IntegratedClient.main:getSchedule(scheduleID):addListener(listener)
table.insert(self.scheduleIds, scheduleID)
end
function UIWindow:onWindowResize()
self.root:applyMargin()
end
function UIWindow:onUpdate()
end
function UIWindow:postInitContent()
for _, ins in ipairs(self._modifyInstances) do
if ins.initContent ~= nil then
ins:initContent()
end
end
end
return UIWindow
================================================
FILE: ui/WorldListUI.lua
================================================
---@class TC.WorldListUI:TC.UIWindow
local WorldListUI = class("WorldListUI", require("UIWindow"))
local UIUtil = require("UIUtil")
local MenuJoinInfo = require("client.MenuJoinInfo")
local Locale = require("languages.Locale")
function WorldListUI:__init()
WorldListUI.super.__init(self, require("UIDesign").getWorldListUI())
---@type UIScrollView
self._panelList = nil
self._indexSelected = 0
self._worldInfoList = {}
self:initContent()
end
function WorldListUI:initContent()
self:initWorldData()
self._panelList = self.root:getChild("layer.panel_list")
local panelItem = self._panelList:getChild("panel_item")
self.itemSize = Size.new(panelItem.width / 1, panelItem.height)
UIUtil.setTable(self._panelList, self, true, 1)
self:updateSelection()
self.root:getChild("layer.btn_ok"):addTouchUpListener({ self._onOkButtonClicked, self })
self.root:getChild("layer.btn_back"):addTouchUpListener({ self._onBackButtonClicked, self })
self.root:getChild("layer.btn_create"):addTouchUpListener({ self._onNewWorldClicked, self })
end
function WorldListUI:getWorldLastModifiedTime(name)
local filePath = Path.join(App.persistentDataPath, "worlds", name, "base.dat")
if File.isPathExist(filePath) then
return File.getLastWriteTime(filePath)
end
local filePathBackup = Path.join(App.persistentDataPath, "worlds", name, "base.dat.bak")
return File.getLastWriteTime(filePathBackup)
end
function WorldListUI:initWorldData()
local worldNames = File.getAllSubFolders(Path.join(App.persistentDataPath, "worlds"))
for _, worldName in pairs(worldNames) do
local worldData = WorldData.new()
if WorldDataUtils.Load(worldName, worldData) then
local info = {
name = worldName,
data = worldData,
isCSC = worldData.clientSideCharacters,
lastModifiedTime = self:getWorldLastModifiedTime(worldName)
}
table.insert(self._worldInfoList, info)
end
end
table.sort(self._worldInfoList, function(element1, element2)
return element1.lastModifiedTime > element2.lastModifiedTime
end)
end
function WorldListUI:_getTableElementCount()
return #self._worldInfoList
end
function WorldListUI:_getTableElementSize()
return self.itemSize
end
---_setTableElement
---@param node UINode
---@param index number
function WorldListUI:_setTableElement(node, index)
node.tag = index
local info = self._worldInfoList[index]
local tipText = ""
tipText = tipText .. (info.isCSC and Locale.BP_SHARED_MODE or Locale.FORCE_NEW_PLAYER_MODE)
UIText.cast(node:getChild("lb_world_name")).text = info.name
UIText.cast(node:getChild("lb_time")).text = tostring(info.lastModifiedTime)
UIText.cast(node:getChild("lb_tips")).text = tipText
node.allowDoubleClick = true
node:addTouchUpListener({ self._onElementClicked, self })
node:addTouchDoubleDownListener({ self._onElementDoubleClicked, self })
node:getChild("btn_remove"):addTouchUpListener({ self._onRemoveButtonClicked, self, index })
end
function WorldListUI:_onOkButtonClicked()
if self._indexSelected > 0 then
MenuJoinInfo.getInstance().worldInfo.name = self._worldInfoList[self._indexSelected].name
ClientStateManager.StartJoining(MenuJoinInfo.getInstance():getData())
self:closeWindow()
self.manager:playClickSound()
end
end
function WorldListUI:_onBackButtonClicked()
self:closeWindow()
self.manager:playClickSound()
require("PlayerListUI").new()
end
function WorldListUI:_onNewWorldClicked()
self.manager:playClickSound()
self:closeWindow()
require("NewWorldUI").new()
end
---_onElementClicked
---@param node UINode
---@param _ Touch
function WorldListUI:_onElementClicked(node)
local index = node.tag
if self._indexSelected ~= index then
self.manager:playClickSound()
self._indexSelected = index
self:updateSelection()
end
end
---@param _ Touch
---@param node UINode
function WorldListUI:_onElementDoubleClicked(node)
self:_onElementClicked(node)
self:_onOkButtonClicked()
end
---@param index number
function WorldListUI:_onRemoveButtonClicked(index)
if self._indexSelected == index then
local name = self._worldInfoList[index].name
self.manager:playClickSound()
local InfoPopupUI = require("InfoPopupUI")
local infoUI = InfoPopupUI.new(
Locale.SURE_TO_DELETE_WORLD_1 .. "\"" .. name .. "\"" .. Locale.SURE_TO_DELETE_WORLD_2,
function()
if name ~= nil and name ~= "" then
print("remove world", name)
WorldDataUtils.Remove(name)
end
end,
function()
WorldListUI.new()
end
)
self:closeWindow()
end
end
function WorldListUI:updateSelection()
for index = 1, #self._worldInfoList do
local node = self._panelList:getChildByTag(index)
local show = false
if node.tag == self._indexSelected then
show = true
end
node:getChild("img_selected").visible = show
node:getChild("btn_remove").visible = show
end
local btnColor = self._indexSelected and Color.White or Color.Gray
UIText.cast(self.root:getChild("layer.btn_ok.lb_caption")).color = btnColor
end
function WorldListUI:closeWindow()
WorldListUI.super.closeWindow(self)
end
return WorldListUI
================================================
FILE: ui/advancement/AdvancementContainerClient.lua
================================================
---@class TC.AdvancementContainerClient:Container
local AdvancementContainerClient = class("AdvancementContainerClient", Container)
local AdvancementTree = require("AdvancementTree")
local UIData = require("AdvancementUIData")
---@param player Player
function AdvancementContainerClient:__init(player)
AdvancementContainerClient.super.__init(self)
local source = self:_BuildTreeSource()
self.tree = AdvancementTree.new(source)
self:_ProcessData(player)
end
---_ProcessData
---@param player Player
function AdvancementContainerClient:_ProcessData(player)
---_DFS
---@param node TC.AdvancementTreeNode
local function _DFS(node, state)
local id = node.data
local advancement = AdvancementUtils.Get(id)
if player:IsAdvancementFinished(id) then
print("advancement finish id", id, Reg.AdvancementIDName(id))
state = UIData.FINISH
end
node.displayState = state
if state ~= UIData.FULL_LOCK then
node.itemStack = ItemStack.new(ItemRegistry.GetItemByID(advancement.itemID))
end
if state == UIData.FINISH then
state = UIData.UNLOCK
elseif state == UIData.UNLOCK then
state = UIData.NEXT_UNLOCK
else
--state = UIData.FULL_LOCK
state = UIData.NEXT_UNLOCK
end
for _, child in ipairs(node.children) do
_DFS(child, state)
end
end
--_DFS(self.tree.root, UIData.FULL_LOCK)
_DFS(self.tree.root, UIData.NEXT_UNLOCK)
end
function AdvancementContainerClient:_BuildTreeSource()
local maxID = Reg.MaxAdvancementID()
local tempArray = {}
local rootID = {}
for id = 1, maxID do
tempArray[id] = {}
end
for id = 1, maxID do
local advancement = AdvancementUtils.Get(id)
if advancement.parentID == 0 then
rootID = id
else
table.insert(tempArray[advancement.parentID], id)
end
end
local function dfs(curID)
local tmp = { data = curID, nexts = {}, name = Reg.AdvancementIDName(curID) }
for _, childID in ipairs(tempArray[curID]) do
local child = dfs(childID)
table.insert(tmp.nexts, child)
end
return tmp
end
return dfs(rootID)
end
function AdvancementContainerClient:OnEvent(eventId, eventString)
end
return AdvancementContainerClient
================================================
FILE: ui/advancement/AdvancementTree.lua
================================================
---@class TC.AdvancementTreeNode
local AdvancementTreeNode = class("AdvancementTreeNode")
---@class TC.AdvancementTree
local AdvancementTree = class("AdvancementTree")
local UIData = require("AdvancementUIData")
local OFFSET_X = UIData.OFFSET_X
local NODE_WIDTH = UIData.NODE_WIDTH
local NODE_FULL_WIDTH = UIData.NODE_FULL_WIDTH
local LEVEL_OFFSET = UIData.LEVEL_OFFSET
function AdvancementTreeNode:__init()
self.parent = nil ---@type TC.AdvancementTreeNode
self.children = {} ---@type TC.AdvancementTreeNode[]
self.level = 0
self.left = 0
self.right = 0
self.moveOffset = 0
self.data = 0
self.cellArea = RectFloat.new()
self.displayState = UIData.FULL_LOCK
self.itemStack = nil ---@type ItemStack
end
function AdvancementTreeNode:getArea()
return RectFloat.new(self.left + OFFSET_X / 2, self.level * LEVEL_OFFSET, NODE_WIDTH, NODE_WIDTH)
end
function AdvancementTreeNode:renderDebug()
local area = self:getArea()
GraphicsDevice.drawRectHollow2D(area, Color.White)
for _, child in ipairs(self.children) do
child:renderDebug()
local childArea = child:getArea()
GraphicsDevice.drawLine2D(Vector2.new(area.centerX, area.bottomY),
Vector2.new(childArea.centerX, childArea.y), Color.White)
end
end
function AdvancementTree:__init(source)
--source = self:randomGenSource(0)
self.levelLastNodes = {} ---@type TC.AdvancementTreeNode[]
self.root = self:genFromTable(source, 0)
self.width = 0
self.height = 0
self:dfs(self.root)
self:adaptData()
end
function AdvancementTree:randomGenSource(level)
local source = {}
source.data = 0
if level <= 5 and (level == 0 or math.random(0, 1) == 0) then
local cnt = math.random(2, 4)
source.nexts = {}
for _ = 1, cnt do
table.insert(source.nexts, self:randomGenSource(level + 1))
end
end
return source
end
function AdvancementTree:adaptData()
---@param node TC.AdvancementTreeNode
local function _dfs(node)
node.cellArea = RectFloat.new(
node.left + OFFSET_X / 2,
node.level * LEVEL_OFFSET,
NODE_WIDTH, NODE_WIDTH)
self.width = math.max(self.width, node.cellArea.rightX)
self.height = math.max(self.height, node.cellArea.bottomY)
for _, child in ipairs(node.children) do
_dfs(child)
end
end
_dfs(self.root)
end
---genFromTable
---@param source table
---@param level number
function AdvancementTree:genFromTable(source, level)
local node = AdvancementTreeNode.new()
node.level = level
node.data = source.data
if source.nexts ~= nil then
for _, childSource in ipairs(source.nexts) do
local childNode = self:genFromTable(childSource, level + 1)
childNode.parent = node
table.insert(node.children, childNode)
end
end
return node
end
---getLevelRightPos
---@param level number
function AdvancementTree:getLevelRightPos(level)
local pos = 0
local lastNode = self.levelLastNodes[level + 1]
if lastNode ~= nil then
pos = lastNode.right
end
return pos
end
---dfs
---@param node TC.AdvancementTreeNode
function AdvancementTree:dfs(node)
if #node.children == 0 then
node.left = self:getLevelRightPos(node.level)
node.right = node.left + NODE_FULL_WIDTH
else
local cl, cr = 1000000000, -1000000000
for _, child in ipairs(node.children) do
self:dfs(child)
cl = math.min(cl, child.left)
cr = math.max(cr, child.right)
end
local l = self:getLevelRightPos(node.level)
local cx = math.floor((cl + cr) / 2 - NODE_FULL_WIDTH / 2)
node.moveOffset = math.max(cx, l) - cx
node.left = cx
node.right = cx + NODE_FULL_WIDTH
self:sink(node, 0)
end
self.levelLastNodes[node.level + 1] = node
end
---sink
---@param node TC.AdvancementTreeNode
---@param move number
function AdvancementTree:sink(node, move)
local moveAll = node.moveOffset + move
for _, child in ipairs(node.children) do
self:sink(child, moveAll)
end
node.moveOffset = 0
node.left = node.left + moveAll
node.right = node.right + moveAll
end
return AdvancementTree
================================================
FILE: ui/advancement/AdvancementUI.lua
================================================
---@class TC.AdvancementUI:GuiContainer
local AdvancementUI = class("AdvancementUI", GuiContainer)
local UIUtil = require("ui.UIUtil")
local UISlotOp = require("ui.UISlotOp")
local UIData = require("AdvancementUIData")
local HotkeyUIHelper = require("ui.HotkeyUIHelper")
local GuiID = require("ui.GuiID")
local SettingsData = require("settings.SettingsData")
---@param container TC.AdvancementContainerClient
function AdvancementUI:__init(container)
AdvancementUI.super.__init(self, container)
self.ui = require("ui.UIWindow").new(require("ui.UIDesign").getAdvancementUI(), require("ui.UIDefault").GROUP_GAME_WINDOW)
self.currentContainer = container
self._hkHelper = HotkeyUIHelper.new(Mod.current, GuiID.Advancement)
self:_initContent()
end
function AdvancementUI:DoClose()
local player = PlayerUtils.GetCurrentClientPlayer()
if player ~= nil and player:IsGuiOpened(Mod.current, GuiID.Advancement) then
player:CloseGui(Mod.current, GuiID.Advancement)
end
end
function AdvancementUI:_initContent()
local scrollPanel = UIScrollView.cast(self.ui.root:getChild("scroll"))
local basePanel = scrollPanel:getChild("panel")
local panelOffsetX = 100
local panelOffsetY = 100
local originalWidth = scrollPanel.width
local originalHeight = scrollPanel.height
self.ui.root:getChild("btn_ok"):addTouchUpListener({ function(self)
self:DoClose()
end, self })
local tree = self.currentContainer.tree
local inWidth = panelOffsetX * 2 + tree.width
local inHeight = panelOffsetY * 2 + tree.height
if inWidth < originalWidth then
panelOffsetX = math.ceil((originalWidth - tree.width) / 2)
inWidth = originalWidth
end
if inHeight < originalHeight then
panelOffsetY = math.ceil((originalHeight - tree.height) / 2)
inHeight = originalHeight
end
basePanel:setSize(inWidth, inHeight)
scrollPanel.viewSize = basePanel.size
local lineColors = {
[UIData.FINISH] = Color.new(90, 90, 90),
[UIData.UNLOCK] = Color.new(70, 70, 70),
[UIData.NEXT_UNLOCK] = Color.new(50, 50, 50),
[UIData.FULL_LOCK] = Color.new(30, 30, 30),
}
local cellColors = {
[UIData.FINISH] = Color.White,
[UIData.UNLOCK] = Color.new(128, 128, 128),
[UIData.NEXT_UNLOCK] = Color.new(64, 64, 64),
[UIData.FULL_LOCK] = Color.new(32, 32, 32),
}
---@param node TC.AdvancementTreeNode
local function _DFSLine(node)
if #node.children > 0 then
local area = node.cellArea
local lineColor = lineColors[node.displayState]
local parentCenterX = area.centerX
local parentCenterY = area.centerY
local lineSize = 4
local lineExtentHeight = UIData.LEVEL_OFFSET / 2
local lineExtentY = parentCenterY + lineExtentHeight
local lineParentDown = UIUtil.createImage("img_line",
panelOffsetX + parentCenterX - lineSize / 2, panelOffsetY + parentCenterY, lineSize, lineExtentHeight, {
sprite = {
name = "tc:white",
color = lineColor
}
})
basePanel:addChild(lineParentDown)
local lineExternMinX
local lineExternMaxX
for _, child in ipairs(node.children) do
local childArea = child.cellArea
local childCenterX = childArea.centerX
local lineChildDown = UIUtil.createImage("img_line",
panelOffsetX + childCenterX - lineSize / 2, panelOffsetY + lineExtentY, lineSize, lineExtentHeight, {
sprite = {
name = "tc:white",
color = lineColor
}
})
basePanel:addChild(lineChildDown)
if lineExternMinX == nil then
lineExternMinX = childCenterX
lineExternMaxX = childCenterX
else
lineExternMinX = math.min(lineExternMinX, childCenterX)
lineExternMaxX = math.max(lineExternMaxX, childCenterX)
end
end
if lineExternMinX ~= nil and lineExternMinX < lineExternMaxX then
local externWidth = lineExternMaxX - lineExternMinX
local lineExtern = UIUtil.createImage("img_line",
panelOffsetX + lineExternMinX, panelOffsetY + lineExtentY - lineSize / 2, externWidth, lineSize, {
sprite = {
name = "tc:white",
color = lineColor
}
})
basePanel:addChild(lineExtern)
end
end
for _, child in ipairs(node.children) do
_DFSLine(child)
end
end
---@param node TC.AdvancementTreeNode
local function _DFSCell(node)
local area = node.cellArea
local cellColor = cellColors[node.displayState]
local cell = UIUtil.createImage("cell", panelOffsetX + area.x, panelOffsetY + area.y, area.width, area.height, {
sprite = {
name = "tc:advancement_cell",
color = cellColor
}
})
if node.itemStack ~= nil then
cell:getPostDrawLayer(0):addListener({ UISlotOp.itemStackOnRenderWithShadow, node.itemStack })
end
if SettingsData.isMobileOperation then
cell:addTouchUpListener({ AdvancementUI.OnClickCell, self, node })
else
cell:addMousePointedListener({ AdvancementUI.OnPointedInCell, self, node })
end
basePanel:addChild(cell)
for _, child in ipairs(node.children) do
_DFSCell(child)
end
end
_DFSLine(tree.root)
_DFSCell(tree.root)
end
---OnClickCell
---@param node TC.AdvancementTreeNode
---@param touch Touch
function AdvancementUI:OnClickCell(node, _, touch)
self:UpdateTips(touch.position, node)
end
function AdvancementUI:OnPointedInCell(node, _)
self:UpdateTips(Input.mouse.position, node)
end
function AdvancementUI:UpdateTips(position, node)
local TipUI = require("ui.TipUI")
local advancement = AdvancementUtils.Get(node.data)
local name = LangUtils.AdvancementName(node.data)
local desc = LangUtils.AdvancementDescription(node.data)
local contentTable
if node.displayState == UIData.FINISH then
contentTable = {
--"量子科技",
--"制造出一颗量子电池!",
name,
"" .. desc .. "",
"已得到!",
}
elseif node.displayState == UIData.UNLOCK then
contentTable = {
--"量子科技",
--"制造出一颗量子电池!",
name,
"" .. desc .. "",
}
elseif node.displayState == UIData.NEXT_UNLOCK then
local parentName = advancement.parentID > 0 and LangUtils.AdvancementName(advancement.parentID) or ""
contentTable = {
--"量子发电机",
--"需要完成: 量子科技",
name,
"需要完成: " .. parentName .. "",
}
else
contentTable = {
"???",
"未解锁",
}
end
if SettingsData.isMobileOperation then
TipUI.generate(contentTable)
else
if TipUI.isShowing() then
TipUI.changeNewContent(contentTable)
TipUI.resetKeepTime()
else
TipUI.generate(contentTable, 2)
end
end
TipUI.adaptPosition(position)
end
function AdvancementUI:OnClose()
self._hkHelper:destroy()
self.ui:closeWindow()
end
return AdvancementUI
================================================
FILE: ui/advancement/AdvancementUIData.lua
================================================
local AdvancementUIData = {
OFFSET_X = 8,
NODE_WIDTH = 44,
NODE_FULL_WIDTH = 52,
LEVEL_OFFSET = 60,
FINISH = 0,
UNLOCK = 1,
NEXT_UNLOCK = 2,
FULL_LOCK = 3,
}
return AdvancementUIData
================================================
FILE: ui/backpack/BackpackContainerClient.lua
================================================
---@class TC.BackpackContainerClient:Container
local BackpackContainerClient = class("BackpackContainerClient", Container)
local ContainerHelper = require("ui.ContainerHelper")
---@param player Player
function BackpackContainerClient:__init(player)
BackpackContainerClient.super.__init(self)
self.TOTAL_SLOT = 70
self.tempSlots = Inventory.new(self.TOTAL_SLOT)
ContainerHelper.ContainerClientInitSlots(self, self.tempSlots)
end
function BackpackContainerClient:OnEvent(eventId, eventString)
end
function BackpackContainerClient:OnUpdate()
end
function BackpackContainerClient:OnClose()
end
function BackpackContainerClient:CanInteractWith(player)
return true
end
return BackpackContainerClient
================================================
FILE: ui/backpack/BackpackContainerServer.lua
================================================
---@class TC.BackpackContainerServer:Container
local BackpackContainerServer = class("BackpackContainerServer", Container)
local UIData = require("BackpackUIData")
local ContainerHelper = require("ui.ContainerHelper")
local Craft3xHelper = require("ui.craft3x.Craft3xHelper")
local RecipeBookServer = require("ui.recipe_book.RecipeBookServer")
local GPlayer = require("player.GPlayer")
---@param player Player
function BackpackContainerServer:__init(player)
BackpackContainerServer.super.__init(self)
self.playerIndex = player.entityIndex
self.inventory = player.backpackInventory
self.equipmentInventory = player.equipmentInventory
self.accessoryInventory = GPlayer.GetInstance(player).accessoryInventory
self.trashInventory = GPlayer.GetInstance(player).trashInventory
self.xi = player.centerXi
self.yi = player.centerYi
-- 0-8 inputs 9 output
self.craftSlots = Inventory.new(10)
-- 0-49 inventory
ContainerHelper.ContainerServerAddBackpack(player, self)
for i = 1, 3 do
-- 50-52 equipment
self:AddSlotToContainer(self.equipmentInventory, i - 1)
end
for i = 1, 3 do
-- 53-55 appearance
self:AddSlotToContainer(self.equipmentInventory, i - 1 + 3)
end
--local craft2xMapping = { 0, 1, 3, 4 }
--for i = 1, 4 do
-- -- 56-59 craft inputs
-- local slotIndexInCraft = craft2xMapping[i]
--
-- Craft3xHelper.InitSlot(self, self.craftSlots, slotIndexInCraft)
--end
for i = 0, 8 do
-- 56-64 craft inputs
Craft3xHelper.InitSlot(self, self.craftSlots, i)
end
-- 65 craft output
Craft3xHelper.InitSlot(self, self.craftSlots, 9)
for i = 1, 3 do
-- 66-68 accessory
self:AddSlotToContainer(self.accessoryInventory, i - 1)
end
-- 69 trash
self:AddSlotToContainer(self.trashInventory, 0)
self.recipeBookServer = RecipeBookServer.new(
Reg.RecipeConfigID("Craft3x"),
player, self.craftSlots, 0, 9)
end
function BackpackContainerServer:OnEvent(eventId, eventString)
if eventId == UIData.EventID.SortBackpack then
--self.inventory:SortAll()
self.inventory:Sort(10, 40)
elseif eventId == UIData.EventID.RecipeBookRequest then
local recipeID = tonumber(eventString)
self.recipeBookServer:FlushValidRecipe(recipeID)
if PlayerUtils.IsAlive(self.playerIndex) then
local player = PlayerUtils.Get(self.playerIndex)
player:FinishAdvancement(Reg.AdvancementID("recipe_book"))
end
elseif eventId == UIData.EventID.PickOutput then
Craft3xHelper.TryPickOutput(self.playerIndex, self, self.craftSlots)
end
end
function BackpackContainerServer:OnUpdate()
end
function BackpackContainerServer:OnClose()
Craft3xHelper.Close(self.craftSlots, self.playerIndex, self.xi, self.yi)
end
function BackpackContainerServer:CanInteractWith(_)
return true
end
return BackpackContainerServer
================================================
FILE: ui/backpack/BackpackUI.lua
================================================
---@class TC.BackpackUI:GuiContainer
local BackpackUI = class("BackpackUI", GuiContainer)
local UIUtil = require("ui.UIUtil")
local BackpackUIData = require("BackpackUIData")
local InputControl = require("client.InputControl")
local HotkeyUIHelper = require("ui.HotkeyUIHelper")
local s_isRecipeBookReminded = false
---@param container TC.BackpackContainerClient
function BackpackUI:__init(container)
BackpackUI.super.__init(self, container)
self.currentContainer = container
self.ui = require("ui.UIWindow").new(require("ui.UIDesign").getBackpackUI(), require("ui.UIDefault").GROUP_GAME_WINDOW)
self._rootLayer = self.ui.root:getChild("layer")
self._recipeBookIcon = UIImage.cast(self._rootLayer:getChild("btn_recipe.img"))
self._reminderTicks = 0
self._panelStatus = self._rootLayer:getChild("panel_status")
self._playerBone = nil
local listenSlots = {}
for i = 0, 49 do
table.insert(listenSlots, self.currentContainer.tempSlots:GetSlot(i))
end
for i = 56, 59 do
table.insert(listenSlots, self.currentContainer.tempSlots:GetSlot(i))
end
table.insert(listenSlots, PlayerUtils.GetCurrentClientPlayer().mouseInventory:GetSlot(0))
self.recipeBookUI = require("ui.recipe_book.RecipeBookUI").new(
Reg.RecipeConfigID("Craft3x"),
self._rootLayer, false, listenSlots,
{ self._onValidRecipeClicked, self },
"110" .. "110" .. "000"
)
local GuiID = require("ui.GuiID")
self._hkHelper = HotkeyUIHelper.new(Mod.current, GuiID.Backpack)
self:_initContent()
end
function BackpackUI:_initContent()
-- bone module
local player = PlayerUtils.GetCurrentClientPlayer()
local gPlayer = require("player.GPlayer").GetInstance(player)
self._playerBone = gPlayer.bone
self._panelStatus:getPostDrawLayer(0):addListener({ self._onRenderBone, self })
self.ui.root:addTouchUpListener({ BackpackUI._onBgClicked, self })
local maxSlots = self.container:GetSlotCount()
local craftOutputTag = 65
for i = 1, maxSlots do
local tag = i - 1
if tag ~= craftOutputTag then
UIUtil.hookSlot(self._rootLayer:getChildByTag(tag), self, tag)
end
end
local outputNode = self._rootLayer:getChildByTag(craftOutputTag)
local outputSlot = self.currentContainer.tempSlots:GetSlot(craftOutputTag)
UIUtil.hookSlotView(outputNode, outputSlot, true)
outputNode:addTouchUpListener({ BackpackUI._onOutputClicked, self, outputSlot })
self._rootLayer:getChild("btn_recipe"):addTouchUpListener({ BackpackUI._onRecipeTriggerClicked, self })
self._rootLayer:getChild("btn_sort"):addTouchUpListener({ BackpackUI._onSortClicked, self })
self.ui:initUpdateFunc({ BackpackUI._onUpdate, self })
end
function BackpackUI:_onUpdate()
if not s_isRecipeBookReminded then
self._reminderTicks = self._reminderTicks + 1
self._recipeBookIcon.sprite.style = UISpriteStyle.Filled
local rate = 1.10 + Utils.SinValue(self._reminderTicks, 64) * 0.10
self._recipeBookIcon.width = 32 * rate
self._recipeBookIcon.height = 32 * rate
self._recipeBookIcon:applyMargin()
end
end
function BackpackUI:_onRenderBone()
local screenPos = self.ui.manager:getScreenPosition(self._panelStatus)
self._playerBone.joints.position = screenPos + Vector2.new(44, 120)
self._playerBone.joints.scale = Vector2.new(1.5, 1.5)
--self._playerBone:update()
self._playerBone.joints:render()
end
---_onOutputClicked
---@param slot Slot
function BackpackUI:_onOutputClicked(slot)
if slot.hasStack then
self.ui.manager:playClickSound()
self:TriggerServerEvent(BackpackUIData.EventID.PickOutput)
end
end
function BackpackUI:_onValidRecipeClicked(recipeID)
self:TriggerServerEvent(BackpackUIData.EventID.RecipeBookRequest, tostring(recipeID))
end
function BackpackUI:_onRecipeTriggerClicked()
self.recipeBookUI:SetDisplayState(not self.recipeBookUI.showing)
if not s_isRecipeBookReminded then
s_isRecipeBookReminded = true
self._recipeBookIcon.sprite.style = UISpriteStyle.Filled
self._recipeBookIcon.width = 32
self._recipeBookIcon.height = 32
self._recipeBookIcon:applyMargin()
end
self.ui.manager:playClickSound()
end
function BackpackUI:_onSortClicked()
self.ui.manager:playClickSound()
self:TriggerServerEvent(BackpackUIData.EventID.SortBackpack)
end
function BackpackUI:OnUpdate()
end
function BackpackUI:OnClose()
self._hkHelper:destroy()
self.ui:closeWindow()
self.recipeBookUI:closeWindow()
end
function BackpackUI:_onBgClicked()
if require("ui.UISlotOp").onCheckPCDropOutItem() then
return
end
self:_closeMe()
end
function BackpackUI:_closeMe()
local player = PlayerUtils.GetCurrentClientPlayer()
if player then
local GuiID = require("ui.GuiID")
player:CloseGui(Mod.current, GuiID.Backpack)
end
end
---checkSlotShiftMove
---@param slotIndex int
---@param itemStack ItemStack
function BackpackUI:checkSlotShiftMove(slotIndex, itemStack)
if slotIndex < 50 then
-- shortcut/backpack to equipment
local item = itemStack:GetItem()
if item.toolType == "HELMET" then
if not self.container:GetSlot(50).hasStack then
return self.container, 50, 1
end
elseif item.toolType == "CHESTPLATE" then
if not self.container:GetSlot(51).hasStack then
return self.container, 51, 1
end
elseif item.toolType == "LEGGINGS" then
if not self.container:GetSlot(52).hasStack then
return self.container, 52, 1
end
end
end
if slotIndex < 10 then
-- shortcut to backpack
return self.container, 10, 40
elseif slotIndex < 50 then
-- backpack to shortcut
return self.container, 0, 10
else
-- equipment/craft2x to backpack/shortcut
return self.container, 0, 50
end
end
return BackpackUI
================================================
FILE: ui/backpack/BackpackUIData.lua
================================================
local BackpackUIData = {
EventID = { SortBackpack = 1, RecipeBookRequest = 2, PickOutput = 3, },
}
return BackpackUIData
================================================
FILE: ui/brewing/BrewingContainerClient.lua
================================================
---@class TC.BrewingContainerClient:Container
local BrewingContainerClient = class("BrewingContainerClient", Container)
local ContainerHelper = require("ui.ContainerHelper")
function BrewingContainerClient:__init(player, xi, yi)
BrewingContainerClient.super.__init(self)
self.progress = 0
self.remainTimes = 0
self.bubbleProgressRate = 0.0
self.isBrewing = false
self.TOTAL_SLOT = 54
self.tempSlots = Inventory.new(self.TOTAL_SLOT)
ContainerHelper.ContainerClientInitSlots(self, self.tempSlots)
end
function BrewingContainerClient:OnUpdate()
if not self.isBrewing then
self.bubbleProgressRate = 0
else
self.bubbleProgressRate = self.bubbleProgressRate + Time.deltaTime
if self.bubbleProgressRate >= 1.0 then
self.bubbleProgressRate = 0.0
end
end
end
function BrewingContainerClient:OnReceiveChange(id, value)
if id == 0 then
self.progress = value
elseif id == 1 then
self.remainTimes = value
elseif id == 2 then
self.isBrewing = value
end
end
return BrewingContainerClient
================================================
FILE: ui/brewing/BrewingContainerServer.lua
================================================
---@class TC.BrewingContainerServer:Container
local BrewingContainerServer = class("BrewingContainerServer", Container)
local ContainerHelper = require("ui.ContainerHelper")
local UIData = require("BrewingUIData")
local RecipeBookServer = require("ui.recipe_book.RecipeBookServer")
---__init
---@param player Player
---@param xi int
---@param yi int
function BrewingContainerServer:__init(player, xi, yi)
BrewingContainerServer.super.__init(self)
self.playerIndex = player.entityIndex
self.inventory = player.backpackInventory
self.xi = xi
self.yi = yi
-- 0-49 inventory
ContainerHelper.ContainerServerAddBackpack(player, self)
local brewingEntity = self:GetBrewingEntity()
for i = 0, 3 do
local slot = brewingEntity.inventory:GetSlot(i)
self:AddSlotToContainer(brewingEntity.inventory, i)
if i ~= 2 then
slot:AddOnPickListener({ BrewingContainerServer.OnChanged, self })
slot:AddOnPushListener({ BrewingContainerServer.OnChanged, self })
end
end
self.recipeBookServer = RecipeBookServer.new(
Reg.RecipeConfigID("Brew"),
player, brewingEntity.inventory, 0, 2)
end
function BrewingContainerServer:GetBrewingEntity()
local blockEntity = MapUtils.GetBlockEntity(Reg.BlockEntityID("BrewingEntity"), self.xi, self.yi)
if blockEntity == nil then
return nil
end
---@type TC.BrewingEntity
local modEntity = blockEntity:GetModBlockEntity()
return modEntity
end
function BrewingContainerServer:OnChanged()
local modEntity = self:GetBrewingEntity()
if modEntity then
modEntity:FlushRecipeData()
end
end
function BrewingContainerServer:OnDetectChange()
local modEntity = self:GetBrewingEntity()
if modEntity then
local progress = 0
if modEntity.totalProcessTime > 0 then
progress = math.ceil(modEntity.processedTime * 16.0 / modEntity.totalProcessTime)
progress = math.min(math.max(progress, 0), 16)
end
self:DetectAndSendChangeInteger(0, progress)
self:DetectAndSendChangeInteger(1, modEntity.remainProcessTimes)
self:DetectAndSendChangeBoolean(2, modEntity.currentRecipeID > 0)
end
end
function BrewingContainerServer:OnEvent(eventId, eventString)
if eventId == UIData.EventID.RecipeBookRequest then
local recipeID = tonumber(eventString)
self.recipeBookServer:FlushValidRecipe(recipeID)
elseif eventId == UIData.EventID.PickOutput then
self:TryPickOutput()
end
end
function BrewingContainerServer:TryPickOutput()
if not PlayerUtils.IsAlive(self.playerIndex) then
return
end
local player = PlayerUtils.Get(self.playerIndex)
local brewingEntity = self:GetBrewingEntity()
if brewingEntity == nil then
return
end
local inventory = player.backpackInventory
local outputSlot = brewingEntity.inventory:GetSlot(2)
if outputSlot.hasStack then
local outStack = inventory:AddItemStack(outputSlot:GetStack())
if outStack:Valid() then
player:DropItem(outStack)
end
outputSlot:ClearStack()
end
self:OnChanged()
end
function BrewingContainerServer:CanInteractWith(player)
if self:GetBrewingEntity() == nil then
return false
end
local ok = ContainerHelper.InInteractDistance(player, self.xi, self.yi)
return ok
end
return BrewingContainerServer
================================================
FILE: ui/brewing/BrewingUI.lua
================================================
---@class TC.BrewingUI:GuiContainer
local BrewingUI = class("BrewingUI", GuiContainer)
local UIUtil = require("ui.UIUtil")
local GuiID = require("ui.GuiID")
local UIData = require("BrewingUIData")
local HotkeyUIHelper = require("ui.HotkeyUIHelper")
---@param container TC.BrewingContainerClient
function BrewingUI:__init(container)
BrewingUI.super.__init(self, container)
self.brewingContainer = container
self.ui = require("ui.UIWindow").new(require("ui.UIDesign").getBrewingUI(), require("ui.UIDefault").GROUP_GAME_WINDOW)
self.rootLayer = self.ui.root:getChild("layer")
local listenSlots = {}
for i = 0, 49 do
table.insert(listenSlots, self.brewingContainer.tempSlots:GetSlot(i))
end
for i = 50, 51 do
table.insert(listenSlots, self.brewingContainer.tempSlots:GetSlot(i))
end
table.insert(listenSlots, PlayerUtils.GetCurrentClientPlayer().mouseInventory:GetSlot(0))
self.recipeBookUI = require("ui.recipe_book.RecipeBookUI").new(
Reg.RecipeConfigID("Brew"),
self.rootLayer, false, listenSlots,
{ self._onValidRecipeClicked, self },
"11"
)
self._hkHelper = HotkeyUIHelper.new(Mod.current, GuiID.Brewing)
self:_initContent()
end
function BrewingUI:_initContent()
local maxSlots = self.container:GetSlotCount()
for i = 1, maxSlots do
local tag = i - 1
if tag == 52 then
local outputNode = self.rootLayer:getChildByTag(tag)
local outputSlot = self.brewingContainer.tempSlots:GetSlot(tag)
UIUtil.hookSlotView(outputNode, outputSlot, true)
outputNode:addTouchUpListener({ self._onOutputClicked, self, outputSlot })
else
UIUtil.hookSlot(self.rootLayer:getChildByTag(tag), self, tag)
end
end
self.rootLayer:getChild("img_process"):getPostDrawLayer(0):addListener({ BrewingUI.OnRenderProcessProgress, self })
self.rootLayer:getChild("img_bubble"):getPostDrawLayer(0):addListener({ BrewingUI.OnRenderBubbleProgress, self })
self.rootLayer:getChild("img_fuel"):getPostDrawLayer(0):addListener({ BrewingUI.OnRenderFuelProgress, self })
self.rootLayer:getChild("btn_recipe"):addTouchUpListener({ self._onRecipeTriggerClicked, self })
self.ui.root:addTouchUpListener({ self.OnBgClicked, self })
end
---
---@param node UINode
---@param canvasPos Vector2
function BrewingUI:OnRenderProcessProgress(node, canvasPos)
UIUtil.renderProgress("tc:brewing_process_01",
node.positionInCanvas + canvasPos,
self.brewingContainer.progress,
16, 0, 1)
end
---
---@param node UINode
---@param canvasPos Vector2
function BrewingUI:OnRenderBubbleProgress(node, canvasPos)
UIUtil.renderProgress("tc:brewing_bubble_01",
node.positionInCanvas + canvasPos,
math.floor(self.brewingContainer.bubbleProgressRate * 32.0),
32, 0, -1)
end
---
---@param node UINode
---@param canvasPos Vector2
function BrewingUI:OnRenderFuelProgress(node, canvasPos)
UIUtil.renderProgress("tc:brewing_fuel_01",
node.positionInCanvas + canvasPos,
self.brewingContainer.remainTimes,
20, 0, -1)
end
---@param slot Slot
function BrewingUI:_onOutputClicked(slot)
if slot.hasStack then
self.ui.manager:playClickSound()
self:TriggerServerEvent(UIData.EventID.PickOutput)
end
end
function BrewingUI:_onValidRecipeClicked(recipeID)
self:TriggerServerEvent(UIData.EventID.RecipeBookRequest, tostring(recipeID))
end
function BrewingUI:_onRecipeTriggerClicked()
self.recipeBookUI:SetDisplayState(not self.recipeBookUI.showing)
self.ui.manager:playClickSound()
end
function BrewingUI:OnBgClicked()
if require("ui.UISlotOp").onCheckPCDropOutItem() then
return
end
local player = PlayerUtils.GetCurrentClientPlayer()
if player then
player:CloseGui(Mod.current, GuiID.Brewing)
end
end
function BrewingUI:OnClose()
self._hkHelper:destroy()
self.ui:closeWindow()
self.recipeBookUI:closeWindow()
end
return BrewingUI
================================================
FILE: ui/brewing/BrewingUIData.lua
================================================
local BackpackUIData = {
EventID = { RecipeBookRequest = 1, PickOutput = 2, },
}
return BackpackUIData
================================================
FILE: ui/chest/Chest30ContainerClient.lua
================================================
---@class TC.Chest30ContainerClient:TC.IChestContainerClient
local Chest30ContainerClient = class("Chest30ContainerClient", require("IChestContainerClient"))
function Chest30ContainerClient:__init(player, xi, yi)
Chest30ContainerClient.super.__init(self, 30, player, xi, yi)
end
return Chest30ContainerClient
================================================
FILE: ui/chest/Chest30ContainerServer.lua
================================================
---@class TC.Chest30ContainerServer:TC.IChestContainerServer
local Chest30ContainerServer = class("Chest30ContainerServer", require("IChestContainerServer"))
---__init
---@param player Player
---@param xi int
---@param yi int
function Chest30ContainerServer:__init(player, xi, yi)
Chest30ContainerServer.super.__init(self, 30, "Chest30Entity", player, xi, yi)
end
return Chest30ContainerServer
================================================
FILE: ui/chest/Chest30UI.lua
================================================
---@class TC.Chest30UI:TC.IChestUI
local Chest30UI = class("Chest30UI", require("IChestUI"))
---@param container TC.Chest30ContainerClient
function Chest30UI:__init(container)
Chest30UI.super.__init(self, require("ui.UIDesign").getChest30UI(), container,
require("ui.GuiID").Chest30)
end
return Chest30UI
================================================
FILE: ui/chest/ChestUIData.lua
================================================
local ChestUIData = {
EventID = {
SortChest = 1,
QuickPick = 2,
QuickPush = 3,
QuickStack = 4,
},
}
return ChestUIData
================================================
FILE: ui/chest/EnderChest30ContainerServer.lua
================================================
---@class TC.EnderChest30ContainerServer:TC.IChestContainerServer
local EnderChest30ContainerServer = class("EnderChest30ContainerServer", require("IChestContainerServer"))
---__init
---@param player Player
---@param xi int
---@param yi int
function EnderChest30ContainerServer:__init(player, xi, yi)
EnderChest30ContainerServer.super.__init(self, 30, "", player, xi, yi, player.enderInventory)
end
return EnderChest30ContainerServer
================================================
FILE: ui/chest/EnderChest30UI.lua
================================================
---@class TC.EnderChest30UI:TC.IChestUI
local EnderChest30UI = class("EnderChest30UI", require("IChestUI"))
---@param container TC.Chest30ContainerClient
function EnderChest30UI:__init(container)
EnderChest30UI.super.__init(self, require("ui.UIDesign").getChest30UI(), container,
require("ui.GuiID").EnderChest30)
end
return EnderChest30UI
================================================
FILE: ui/chest/IChestContainerClient.lua
================================================
---@class TC.IChestContainerClient:Container
local IChestContainerClient = class("IChestContainerClient", Container)
local ContainerHelper = require("ui.ContainerHelper")
function IChestContainerClient:__init(slotCount, player, xi, yi)
IChestContainerClient.super.__init(self)
self.TOTAL_SLOT = slotCount + 50
self.tempSlots = Inventory.new(self.TOTAL_SLOT)
ContainerHelper.ContainerClientInitSlots(self, self.tempSlots)
end
return IChestContainerClient
================================================
FILE: ui/chest/IChestContainerServer.lua
================================================
---@class TC.IChestContainerServer:Container
local IChestContainerServer = class("IChestContainerServer", Container)
local ContainerHelper = require("ui.ContainerHelper")
local UIData = require("ChestUIData")
---__init
---@param slotCount int
---@param blockEntityName string
---@param player Player
---@param xi int
---@param yi int
---@param hookInventory Inventory
function IChestContainerServer:__init(slotCount, blockEntityName, player, xi, yi, hookInventory)
IChestContainerServer.super.__init(self)
self.playerIndex = player.entityIndex
self.backpackInventory = player.backpackInventory
self.xi = xi
self.yi = yi
-- 0-49 inventory
ContainerHelper.ContainerServerAddBackpack(player, self)
self.slotCount = slotCount
self.hasBlockEntity = not (blockEntityName == nil or blockEntityName == "")
self.blockEntityName = blockEntityName
---@type Inventory
self.chestInventory = nil
if self.hasBlockEntity then
local chestEntity = self:GetMyEntity()
self.chestInventory = chestEntity.inventory
else
self.chestInventory = hookInventory
end
for i = 1, slotCount do
self:AddSlotToContainer(self.chestInventory, i - 1)
end
local frontID = MapUtils.GetFrontID(xi, yi)
if frontID > 0 then
local data = BlockUtils.GetData(frontID)
if data:HasAnimation() then
MapUtils.PlayAnimation(self.xi, self.yi,
0, 4, 4, true)
MapUtils.SetAnimationIndex(self.xi, self.yi, 1)
end
if data.functionSoundId then
SoundUtils.PlaySound(data.functionSoundId, xi, yi)
end
if data.functionSoundGroupId then
SoundUtils.PlaySoundGroup(data.functionSoundGroupId, xi, yi)
end
end
end
function IChestContainerServer:OnClose()
if not self.hasBlockEntity or (self.hasBlockEntity and self:IsMyEntityExist()) then
local frontID = MapUtils.GetFrontID(self.xi, self.yi)
if frontID > 0 then
local data = BlockUtils.GetData(frontID)
if data:HasAnimation() then
MapUtils.PlayAnimation(self.xi, self.yi,
0, 4, 4, false)
MapUtils.SetAnimationIndex(self.xi, self.yi, 0)
end
if data.functionSoundId2 then
SoundUtils.PlaySound(data.functionSoundId2, self.xi, self.yi)
end
if data.functionSoundGroupId2 then
SoundUtils.PlaySoundGroup(data.functionSoundGroupId2, self.xi, self.yi)
end
end
end
end
function IChestContainerServer:IsMyEntityExist()
local blockEntity = MapUtils.GetBlockEntity(Reg.BlockEntityID(self.blockEntityName), self.xi, self.yi)
return blockEntity ~= nil
end
function IChestContainerServer:GetMyEntity()
local blockEntity = MapUtils.GetBlockEntity(Reg.BlockEntityID(self.blockEntityName), self.xi, self.yi)
if blockEntity == nil then
return nil
end
---@type TC.IChestEntity
local modEntity = blockEntity:GetModBlockEntity()
return modEntity
end
function IChestContainerServer:CanInteractWith(player)
if (self.hasBlockEntity and not self:IsMyEntityExist()) then
return false
end
return ContainerHelper.InInteractDistance(player, self.xi, self.yi)
end
function IChestContainerServer:OnEvent(eventId, eventString)
if eventId == UIData.EventID.SortChest then
self.chestInventory:SortAll()
elseif eventId == UIData.EventID.QuickPick then
self.chestInventory:QuickPushAllTo(
0, self.chestInventory.slotCount,
self.backpackInventory, 0, self.backpackInventory.slotCount
)
elseif eventId == UIData.EventID.QuickPush then
self.backpackInventory:QuickPushAllTo(
10, 40,
self.chestInventory, 0, self.chestInventory.slotCount
)
elseif eventId == UIData.EventID.QuickStack then
self.backpackInventory:QuickPushAllTo(
0, self.backpackInventory.slotCount,
self.chestInventory, 0, self.chestInventory.slotCount,
true
)
end
end
return IChestContainerServer
================================================
FILE: ui/chest/IChestUI.lua
================================================
---@class TC.IChestUI:GuiContainer
local IChestUI = class("IChestUI", GuiContainer)
local UIUtil = require("ui.UIUtil")
local UIData = require("ChestUIData")
local HotkeyUIHelper = require("ui.HotkeyUIHelper")
---@param container TC.IChestContainerClient
function IChestUI:__init(rootNode, container, guiID)
IChestUI.super.__init(self, container)
self.ui = require("ui.UIWindow").new(rootNode, require("ui.UIDefault").GROUP_GAME_WINDOW)
self.rootLayer = self.ui.root:getChild("layer")
self.guiID = guiID
self._hkHelper = HotkeyUIHelper.new(Mod.current, self.guiID)
self:_innerInitContent()
end
function IChestUI:_innerInitContent()
local maxSlots = self.container:GetSlotCount()
for i = 1, maxSlots do
UIUtil.hookSlot(self.rootLayer:getChildByTag(i - 1), self, i - 1)
end
local btnSort = self.rootLayer:getChild("btn_sort")
local btnQuickPick = self.rootLayer:getChild("btn_quick_pick")
local btnQuickPush = self.rootLayer:getChild("btn_quick_push")
local btnQuickStack = self.rootLayer:getChild("btn_quick_stack")
if btnSort:valid() then
btnSort:addTouchUpListener({ IChestUI.OnSortBtnClicked, self })
end
if btnQuickPick:valid() then
btnQuickPick:addTouchUpListener({ IChestUI.OnQuickPickBtnClicked, self })
end
if btnQuickPush:valid() then
btnQuickPush:addTouchUpListener({ IChestUI.OnQuickPushBtnClicked, self })
end
if btnQuickStack:valid() then
btnQuickStack:addTouchUpListener({ IChestUI.OnQuickStackBtnClicked, self })
end
self.ui.root:addTouchUpListener({ IChestUI.OnBgClicked, self })
end
function IChestUI:OnSortBtnClicked()
self.ui.manager:playClickSound()
self:TriggerServerEvent(UIData.EventID.SortChest)
end
function IChestUI:OnQuickPushBtnClicked()
self.ui.manager:playClickSound()
self:TriggerServerEvent(UIData.EventID.QuickPush)
end
function IChestUI:OnQuickPickBtnClicked()
self.ui.manager:playClickSound()
self:TriggerServerEvent(UIData.EventID.QuickPick)
end
function IChestUI:OnQuickStackBtnClicked()
self.ui.manager:playClickSound()
self:TriggerServerEvent(UIData.EventID.QuickStack)
end
function IChestUI:OnBgClicked()
if require("ui.UISlotOp").onCheckPCDropOutItem() then
return
end
local player = PlayerUtils.GetCurrentClientPlayer()
if player then
player:CloseGui(Mod.current, self.guiID)
end
end
function IChestUI:OnClose()
self._hkHelper:destroy()
self.ui:closeWindow()
end
---checkSlotShiftMove
---@param slotIndex int
---@param itemStack ItemStack
function IChestUI:checkSlotShiftMove(slotIndex, itemStack)
if slotIndex < 50 then
-- shortcut/backpack to chest
return self.container, 50, self.container:GetSlotCount() - 50
else
-- chest to shortcut/backpack
return self.container, 0, 50
end
end
return IChestUI
================================================
FILE: ui/craft3x/Craft3xContainerClient.lua
================================================
---@class TC.Craft3xContainerClient:Container
local Craft3xContainerClient = class("Craft3xContainerClient", Container)
local ContainerHelper = require("ui.ContainerHelper")
---@param player Player
function Craft3xContainerClient:__init(player)
Craft3xContainerClient.super.__init(self)
self.TOTAL_SLOT = 60 -- 50 + 9 + 1
self.tempSlots = Inventory.new(self.TOTAL_SLOT)
ContainerHelper.ContainerClientInitSlots(self, self.tempSlots)
end
function Craft3xContainerClient:OnEvent(eventId, eventString)
end
function Craft3xContainerClient:CanInteractWith(player)
return true
end
return Craft3xContainerClient
================================================
FILE: ui/craft3x/Craft3xContainerServer.lua
================================================
---@class TC.Craft3xContainerServer:Container
local Craft3xContainerServer = class("Craft3xContainerServer", Container)
local ContainerHelper = require("ui.ContainerHelper")
local Craft3xHelper = require("Craft3xHelper")
local RecipeBookServer = require("ui.recipe_book.RecipeBookServer")
local Craft3xUIData = require("Craft3xUIData")
---__init
---@param player Player
---@param xi int
---@param yi int
function Craft3xContainerServer:__init(player, xi, yi)
Craft3xContainerServer.super.__init(self)
self.playerIndex = player.entityIndex
self.backpackInventory = player.backpackInventory
self.xi = xi
self.yi = yi
-- 0-49 inventory
ContainerHelper.ContainerServerAddBackpack(player, self)
-- 0-8 inputs 9 output
self.craftSlots = Inventory.new(10)
for i = 0, 9 do
Craft3xHelper.InitSlot(self, self.craftSlots, i)
end
self.recipeBookServer = RecipeBookServer.new(
Reg.RecipeConfigID("Craft3x"),
player, self.craftSlots, 0, 9)
end
function Craft3xContainerServer:OnClose()
Craft3xHelper.Close(self.craftSlots, self.playerIndex, self.xi, self.yi)
end
function Craft3xContainerServer:CanInteractWith(player)
return ContainerHelper.InInteractDistance(player, self.xi, self.yi)
end
function Craft3xContainerServer:OnEvent(eventId, eventString)
if eventId == Craft3xUIData.EventID.RecipeBookRequest then
local recipeID = tonumber(eventString)
self.recipeBookServer:FlushValidRecipe(recipeID)
if PlayerUtils.IsAlive(self.playerIndex) then
local player = PlayerUtils.Get(self.playerIndex)
player:FinishAdvancement(Reg.AdvancementID("recipe_book"))
end
elseif eventId == Craft3xUIData.EventID.PickOutput then
Craft3xHelper.TryPickOutput(self.playerIndex, self, self.craftSlots)
end
end
return Craft3xContainerServer
================================================
FILE: ui/craft3x/Craft3xHelper.lua
================================================
local Craft3xHelper = class("Craft3xHelper")
local ContainerHelper = require("ui.ContainerHelper")
---InitSlot
---@param containerServer Container
---@param craftSlots Inventory
---@param slotIndexInCraft int
function Craft3xHelper.InitSlot(containerServer, craftSlots, slotIndexInCraft)
local slot = craftSlots:GetSlot(slotIndexInCraft)
if slotIndexInCraft <= 8 then
slot:AddOnPickListener({ Craft3xHelper.FlushDataFromInputs, containerServer, craftSlots })
slot:AddOnPushListener({ Craft3xHelper.FlushDataFromInputs, containerServer, craftSlots })
else
--slot:AddOnPickListener({ Craft3xHelper.FlushDataFromOutput, containerServer, craftSlots })
end
containerServer:AddSlotToContainer(craftSlots, slotIndexInCraft, true)
end
---@param containerServer Container
---@param craftSlots Inventory
function Craft3xHelper.FlushDataFromInputs(containerServer, craftSlots)
local recipeID = RecipeUtils.SearchRecipe(Reg.RecipeConfigID("Craft3x"), craftSlots, 0, 9)
if containerServer._lastCraftRecipeID == nil or containerServer._lastCraftRecipeID ~= recipeID then
containerServer._lastCraftRecipeID = recipeID
local outputSlot = craftSlots:GetSlot(9)
outputSlot:ClearStack()
if recipeID > 0 then
local recipe = RecipeUtils.GetRecipe(recipeID)
local resultStack = recipe.outputs[1]:GetStack()
outputSlot:PushStack(resultStack:Clone())
end
end
end
---@param playerIndex int
---@param containerServer Container
---@param craftSlots Inventory
---@param isToMouse boolean
function Craft3xHelper.TryPickOutput(playerIndex, containerServer, craftSlots, isToMouse)
if PlayerUtils.IsAlive(playerIndex) then
local player = PlayerUtils.Get(playerIndex)
local inventory = player.backpackInventory
local outputSlot = craftSlots:GetSlot(9)
if outputSlot.hasStack then
local ok = false
if isToMouse then
local mouseSlot = player.mouseInventory:GetSlot(0)
if not mouseSlot.hasStack then
mouseSlot:PushStack(outputSlot:GetStack())
outputSlot:ClearStack()
ok = true
end
end
if not ok then
local outStack = inventory:AddItemStack(outputSlot:GetStack())
if outStack:Valid() then
player:DropItem(outStack)
end
outputSlot:ClearStack()
end
end
Craft3xHelper.FlushDataFromOutput(containerServer, craftSlots)
end
end
---@param containerServer Container
---@param craftSlots Inventory
function Craft3xHelper.FlushDataFromOutput(containerServer, craftSlots)
if containerServer._lastCraftRecipeID == nil or containerServer._lastCraftRecipeID == 0 then
return
end
-- We consider that every input element only has one item!
-- So just decrease every input slot by one directly.
local recipe = RecipeUtils.GetRecipe(containerServer._lastCraftRecipeID)
for i = 0, 8 do
local inputSlot = craftSlots:GetSlot(i)
if inputSlot.hasStack then
inputSlot:DecrStackSize(1)
end
end
containerServer._lastCraftRecipeID = nil
Craft3xHelper.FlushDataFromInputs(containerServer, craftSlots)
-- return back
local returnItemSlot = recipe.outputs[2]
if returnItemSlot.hasStack then
local stack = returnItemSlot:GetStack():Clone()
if containerServer.playerIndex ~= nil then
local player = PlayerUtils.Get(containerServer.playerIndex)
if player then
local remain = player.backpackInventory:AddItemStack(stack)
if remain:Valid() then
player:DropItem(remain)
end
end
end
end
end
function Craft3xHelper.Close(craftSlots, playerIndex, xi, yi)
ContainerHelper.CloseSendBackItems(playerIndex,
xi, yi, craftSlots,
{ 0, 1, 2, 3, 4, 5, 6, 7, 8 })
-- directly remove the result item
craftSlots:GetSlot(9):ClearStack()
end
return Craft3xHelper
================================================
FILE: ui/craft3x/Craft3xUI.lua
================================================
---@class TC.Craft3xUI:GuiContainer
local Craft3xUI = class("Craft3xUI", GuiContainer)
local UIUtil = require("ui.UIUtil")
local GuiID = require("ui.GuiID")
local UIData = require("Craft3xUIData")
local HotkeyUIHelper = require("ui.HotkeyUIHelper")
---@param container TC.Craft3xContainerClient
function Craft3xUI:__init(container)
Craft3xUI.super.__init(self, container)
self.craftContainer = container
self.ui = require("ui.UIWindow").new(require("ui.UIDesign").getCraft3xUI(), require("ui.UIDefault").GROUP_GAME_WINDOW)
self.rootLayer = self.ui.root:getChild("layer")
local listenSlots = {}
for i = 0, 49 do
table.insert(listenSlots, self.craftContainer.tempSlots:GetSlot(i))
end
for i = 50, 58 do
table.insert(listenSlots, self.craftContainer.tempSlots:GetSlot(i))
end
table.insert(listenSlots, PlayerUtils.GetCurrentClientPlayer().mouseInventory:GetSlot(0))
self.recipeBookUI = require("ui.recipe_book.RecipeBookUI").new(
Reg.RecipeConfigID("Craft3x"),
self.rootLayer, false, listenSlots,
{ self._onValidRecipeClicked, self },
"111" .. "111" .. "111"
)
self._hkHelper = HotkeyUIHelper.new(Mod.current, GuiID.Craft3x)
self:_initContent()
end
function Craft3xUI:_initContent()
for i = 0, 58 do
UIUtil.hookSlot(self.rootLayer:getChildByTag(i), self, i)
end
local outputNode = self.rootLayer:getChildByTag(59)
local outputSlot = self.craftContainer.tempSlots:GetSlot(59)
UIUtil.hookSlotView(outputNode, outputSlot, true)
outputNode:addTouchUpListener({ self._onOutputClicked, self, outputSlot })
self.rootLayer:getChild("btn_recipe"):addTouchUpListener({ Craft3xUI._onRecipeTriggerClicked, self })
self.ui.root:addTouchUpListener({ Craft3xUI.OnBgClicked, self })
end
---_onOutputClicked
---@param slot Slot
function Craft3xUI:_onOutputClicked(slot)
if slot.hasStack then
self.ui.manager:playClickSound()
if require("settings.SettingsData").isMobileOperation then
self:TriggerServerEvent(UIData.EventID.PickOutput)
else
if Input.keyboard:isKeyPressed(Keys.LeftShift) then
self:TriggerServerEvent(UIData.EventID.PickOutput)
else
self:TriggerServerEvent(UIData.EventID.PickOutput, "1")
end
end
end
end
function Craft3xUI:_onValidRecipeClicked(recipeID)
self:TriggerServerEvent(UIData.EventID.RecipeBookRequest, tostring(recipeID))
end
function Craft3xUI:_onRecipeTriggerClicked()
self.recipeBookUI:SetDisplayState(not self.recipeBookUI.showing)
self.ui.manager:playClickSound()
end
function Craft3xUI:OnBgClicked()
if require("ui.UISlotOp").onCheckPCDropOutItem() then
return
end
local player = PlayerUtils.GetCurrentClientPlayer()
if player then
player:CloseGui(Mod.current, GuiID.Craft3x)
end
end
function Craft3xUI:OnClose()
self._hkHelper:destroy()
self.ui:closeWindow()
self.recipeBookUI:closeWindow()
end
---checkSlotShiftMove
---@param slotIndex int
---@param itemStack ItemStack
function Craft3xUI:checkSlotShiftMove(slotIndex, itemStack)
if slotIndex < 10 then
-- shortcut to backpack
return self.container, 10, 40
elseif slotIndex < 50 then
-- backpack to shortcut
return self.container, 0, 10
end
end
return Craft3xUI
================================================
FILE: ui/craft3x/Craft3xUIData.lua
================================================
local Craft3xUIData = {
EventID = { RecipeBookRequest = 1, PickOutput = 2, },
}
return Craft3xUIData
================================================
FILE: ui/enchant/EnchantContainerClient.lua
================================================
---@class TC.EnchantContainerClient:Container
local EnchantContainerClient = class("EnchantContainerClient", Container)
local ContainerHelper = require("ui.ContainerHelper")
function EnchantContainerClient:__init(player, xi, yi)
EnchantContainerClient.super.__init(self)
self.TOTAL_SLOT = 50 + 2
self.tempSlots = Inventory.new(self.TOTAL_SLOT)
ContainerHelper.ContainerClientInitSlots(self, self.tempSlots)
self.dataChangedCallback = nil
self.btnData = {}
for _ = 1, 3 do
table.insert(self.btnData, {
needExp = 0,
cost = 0,
firstEnchantmentID = 0,
firstEnchantmentLevel = 0,
})
end
end
function EnchantContainerClient:OnReceiveChange(id, value)
if id == 0 then
local tableData = JsonUtil.fromJson(value)
for i, element in ipairs(tableData) do
local data = self.btnData[i]
data.needExp = element.needExp
data.cost = element.cost
data.firstEnchantmentID = element.firstEnchantmentID
data.firstEnchantmentLevel = element.firstEnchantmentLevel
end
if self.dataChangedCallback ~= nil and #self.dataChangedCallback == 2 then
self.dataChangedCallback[1](self.dataChangedCallback[2])
end
end
end
return EnchantContainerClient
================================================
FILE: ui/enchant/EnchantContainerServer.lua
================================================
---@class TC.EnchantContainerServer:Container
local EnchantContainerServer = class("EnchantContainerServer", Container)
local ContainerHelper = require("ui.ContainerHelper")
local UIData = require("EnchantUIData")
local Algorithm = require("util.Algorithm")
local ENCHANT_SLOTS = 2
local ENCHANT_BTN_COUNT = 3
local MAX_ENCHANT_LEVEL = 30
---__init
---@param player Player
---@param xi int
---@param yi int
function EnchantContainerServer:__init(player, xi, yi)
EnchantContainerServer.super.__init(self)
self.playerIndex = player.entityIndex
self.inventory = player.backpackInventory
self.xi = xi
self.yi = yi
-- 0-49 inventory
ContainerHelper.ContainerServerAddBackpack(player, self)
self._tempSlots = Inventory.new(ENCHANT_SLOTS)
self._toolSlot = self._tempSlots:GetSlot(0)
self._lapisSlot = self._tempSlots:GetSlot(1)
self._btnData = {}
for i = 0, ENCHANT_SLOTS - 1 do
local slot = self._tempSlots:GetSlot(i)
self:AddSlotToContainer(self._tempSlots, i)
slot:AddOnPickListener({ EnchantContainerServer.OnChanged, self })
slot:AddOnPushListener({ EnchantContainerServer.OnChanged, self })
end
end
function EnchantContainerServer:OnChanged()
self:_OnFlushData()
end
function EnchantContainerServer:_OnFlushData()
local canEnchant = false
local isBookEnchanting = false
if self._toolSlot.hasStack then
local stack = self._toolSlot:GetStack()
if stack:GetItem().id == Reg.ItemID("book") then
if stack.stackSize == 1 then
canEnchant = true
isBookEnchanting = true
end
elseif not stack:HasEnchantment() then
canEnchant = true
end
end
self._btnData = {}
if canEnchant then
local stack = self._toolSlot:GetStack()
local maxCheckLevel = self:_CheckMaxLevel()
-- generate level for every button
local expLevels = {}
for i = 1, ENCHANT_BTN_COUNT do
local expLevel = math.ceil(maxCheckLevel * i / ENCHANT_BTN_COUNT - 2 + math.random(0, 4))
expLevels[i] = math.max(1, math.min(MAX_ENCHANT_LEVEL, expLevel))
end
for i = 1, ENCHANT_BTN_COUNT do
local expLevel = expLevels[i]
-- calculate how many enchantments can attach in current item
local maxAttachCount = math.max(1, math.ceil(expLevel / 30 * 4))
maxAttachCount = math.random(1, maxAttachCount)
-- get all available enchantments
local pendingEnchantmentIDs = {}
for enchantmentID = 1, Reg.MaxEnchantmentID() do
local data = EnchantmentUtils.GetData(enchantmentID)
-- reach the enchantment level limit
if not data.noCreating and expLevel >= data.minCreatingLevel then
-- current item can use this enchantment
if isBookEnchanting or data:IsToolTypeValid(stack:GetItem().toolType) then
table.insert(pendingEnchantmentIDs, enchantmentID)
end
end
end
-- random shuffle the available enchantment list
Algorithm.Shuffle(pendingEnchantmentIDs)
local resultIDs = {}
local resultEnchantments = {}
local times = 0
for _, enchantmentID in ipairs(pendingEnchantmentIDs) do
local ok = false
if #resultIDs == 0 then
ok = true
else
-- skip if this enchantment conflict with exist enchantments
ok = true
for _, existID in ipairs(resultIDs) do
if EnchantmentUtils.IsConflict(enchantmentID, existID) then
ok = false
break
end
end
end
if ok then
local data = EnchantmentUtils.GetData(enchantmentID)
local t = math.max(1, math.floor(data.allowMaxLevel * expLevel / 30))
local level = math.random(1, t)
times = times + 1
if times > maxAttachCount then
break
end
local enchantment = Enchantment.new(enchantmentID, level)
table.insert(resultIDs, enchantmentID)
table.insert(resultEnchantments, enchantment)
end
end
local cost = self:_GetCostExpLevel(expLevel)
table.insert(self._btnData, {
expLevel = expLevel,
enchantments = resultEnchantments,
costExpLevel = cost,
enabled = self:_IsBtnEnable(expLevel, cost)
})
end
end
if #self._btnData ~= ENCHANT_BTN_COUNT then
canEnchant = false
else
for _, data in ipairs(self._btnData) do
if #data.enchantments == 0 then
canEnchant = false
break
end
end
end
if not canEnchant then
-- remove all data
self._btnData = {}
end
self:_SendData()
end
function EnchantContainerServer:_SendData()
local tableData = {}
for i = 1, ENCHANT_BTN_COUNT do
local data = self._btnData[i]
local needExp = 0
local cost = 0
local firstEnchantmentID = 0
local firstEnchantmentLevel = 0
if data ~= nil then
needExp = data.expLevel * (data.enabled and 1 or -1)
cost = data.costExpLevel
local enchantment = data.enchantments[1]
if enchantment then
firstEnchantmentID = enchantment.id
firstEnchantmentLevel = enchantment.level
end
end
table.insert(tableData, {
needExp = needExp,
cost = cost,
firstEnchantmentID = firstEnchantmentID,
firstEnchantmentLevel = firstEnchantmentLevel,
})
end
local jsonString = JsonUtil.toJson(tableData)
self:DetectAndSendChangeString(0, jsonString)
end
function EnchantContainerServer:_CheckMaxLevel()
local sourceXi = self.xi
local sourceYi = self.yi
local BLOCK_BOOK_ID = Reg.BlockID("tc:book")
local BOOKCASE_SUB_GROUP_ID = Reg.BlockSubGroupID("BOOKCASE")
-- Get books and bookcases around the enchantment table to
-- gain how many level can reach.
local maxCheckLevel = 0
for xi = sourceXi - 5, sourceXi + 5 do
for yi = sourceYi - 6, sourceYi do
local blockID = MapUtils.GetFrontID(xi, yi)
if blockID > 0 then
local cxi, cyi = MapUtils.GetBodyPos(xi, yi)
if xi == cxi and yi == cyi then
if blockID == BLOCK_BOOK_ID then
maxCheckLevel = maxCheckLevel + 2
else
local data = BlockUtils.GetData(blockID)
if data.subGroup == BOOKCASE_SUB_GROUP_ID then
maxCheckLevel = maxCheckLevel + 8
end
end
end
end
end
end
maxCheckLevel = math.max(1, math.min(MAX_ENCHANT_LEVEL, maxCheckLevel))
return maxCheckLevel
end
function EnchantContainerServer:OnEvent(eventId, eventString)
if eventId == UIData.EventID.ClickBtn then
local index = tonumber(eventString)
if index == nil then
return
end
if not (index >= 1 and index <= 3) then
return
end
self:_OnClickBtn(index)
end
end
function EnchantContainerServer:_OnClickBtn(index)
if not (index >= 1 and index <= ENCHANT_BTN_COUNT) then
return
end
if #self._btnData ~= ENCHANT_BTN_COUNT then
return
end
if not self._toolSlot.hasStack then
return
end
local data = self._btnData[index]
if not data.enabled then
return
end
local stack = self._toolSlot:GetStack()
if stack:GetItem().id == Reg.ItemID("book") then
if stack.stackSize ~= 1 then
return
end
self._toolSlot:ClearStack()
self._toolSlot:PushStack(ItemStack.new(ItemRegistry.GetItemByIDName("enchanted_book")))
end
local costExpLevel = data.costExpLevel
local enchantments = data.enchantments
stack = self._toolSlot:GetStack()
for _, enchantment in ipairs(enchantments) do
stack:AddEnchantment(enchantment.id, enchantment.level)
end
SoundUtils.PlaySoundGroup(Reg.SoundGroupID("enchant"), self.xi, self.yi)
-- reduce exp
local player = PlayerUtils.Get(self.playerIndex)
if player then
player:RemoveExpLevel(costExpLevel)
end
-- reduce lapis
if self._lapisSlot.hasStack then
self._lapisSlot:DecrStackSize(costExpLevel)
end
self:OnChanged()
end
function EnchantContainerServer:_GetCostExpLevel(targetExpLevel)
return math.max(1, math.ceil(targetExpLevel / 10.0))
end
function EnchantContainerServer:_IsBtnEnable(targetExpLevel, costExpLevel)
local player = PlayerUtils.Get(self.playerIndex)
if not player then
return false
end
-- check player experience level
if player.expLevel < targetExpLevel or player.expLevel < costExpLevel then
return false
end
-- check lapis count
if not self._lapisSlot.hasStack then
return false
end
local stack = self._lapisSlot:GetStack()
if stack:GetItem().id ~= Reg.ItemID("lapis_lazuli") then
return false
end
if stack.stackSize < costExpLevel then
return false
end
return true
end
function EnchantContainerServer:CanInteractWith(player)
local ok = ContainerHelper.InInteractDistance(player, self.xi, self.yi)
return ok
end
function EnchantContainerServer:OnClose()
ContainerHelper.CloseSendBackItems(self.playerIndex,
self.xi, self.yi, self._tempSlots,
{ 0, 1 })
end
return EnchantContainerServer
================================================
FILE: ui/enchant/EnchantUI.lua
================================================
---@class TC.EnchantUI:GuiContainer
local EnchantUI = class("EnchantUI", GuiContainer)
local UIUtil = require("ui.UIUtil")
local GuiID = require("ui.GuiID")
local UISpritePool = require("ui.UISpritePool")
local StringUtil = require("util.StringUtil")
local UIData = require("EnchantUIData")
local HotkeyUIHelper = require("ui.HotkeyUIHelper")
---@param container TC.EnchantContainerClient
function EnchantUI:__init(container)
EnchantUI.super.__init(self, container)
self.enchantContainer = container
self.enchantContainer.dataChangedCallback = { self._OnDataChanged, self }
self.ui = require("ui.UIWindow").new(require("ui.UIDesign").getEnchantmentUI(), require("ui.UIDefault").GROUP_GAME_WINDOW)
self.rootLayer = self.ui.root:getChild("layer")
self._panelButtons = {
UIPanel.cast(self.rootLayer:getChild("panel_btn_1")),
UIPanel.cast(self.rootLayer:getChild("panel_btn_2")),
UIPanel.cast(self.rootLayer:getChild("panel_btn_3")),
}
self._hkHelper = HotkeyUIHelper.new(Mod.current, GuiID.Enchantment)
self:_initContent()
end
function EnchantUI:_initContent()
local maxSlots = self.container:GetSlotCount()
for i = 1, maxSlots do
local tag = i - 1
UIUtil.hookSlot(self.rootLayer:getChildByTag(tag), self, tag)
end
self.ui.root:addTouchUpListener({ self.OnBgClicked, self })
---@param panelBtn UIPanel
for i, panelBtn in ipairs(self._panelButtons) do
panelBtn:addTouchUpListener({ self._OnBtnClicked, self, i })
end
self:_FlushButtons()
end
function EnchantUI:_OnBtnClicked(index)
self:TriggerServerEvent(UIData.EventID.ClickBtn, tostring(index))
end
function EnchantUI:_OnDataChanged()
self:_FlushButtons()
end
function EnchantUI:_FlushButtons()
local btnData = self.enchantContainer.btnData
for i, data in ipairs(btnData) do
---@type UIPanel
local panelBtn = self._panelButtons[i]
local visible = data.needExp ~= 0
panelBtn:getChild("img_exp").visible = visible
panelBtn:getChild("lb_exp").visible = visible
panelBtn:getChild("lb_cost").visible = visible
panelBtn:getChild("lb_preview").visible = visible
if data.needExp <= 0 then
panelBtn.sprite = UISpritePool.getInstance():get("tc:base_list_cell")
else
panelBtn.sprite = UISpritePool.getInstance():get("tc:base_list_cell_highlight_2")
end
if visible then
local previewText = "..."
if data.firstEnchantmentID > 0 and data.cost <= 20 then
previewText = string.format("%s %s ...",
LangUtils.EnchantmentName(data.firstEnchantmentID),
StringUtil.NumberToRoman(data.firstEnchantmentLevel)
)
end
local displayNeedExp = math.abs(data.needExp)
local cost = data.cost
if cost >= 1 and cost <= 3 then
UIImage.cast(panelBtn:getChild("img_exp")).sprite = UISpritePool.getInstance():get(
string.format("tc:enchantment_exp_%d", cost))
end
UIText.cast(panelBtn:getChild("lb_preview")).text = previewText
UIText.cast(panelBtn:getChild("lb_exp")).text = tostring(displayNeedExp)
UIText.cast(panelBtn:getChild("lb_cost")).text = tostring(cost)
end
end
end
function EnchantUI:OnBgClicked()
if require("ui.UISlotOp").onCheckPCDropOutItem() then
return
end
local player = PlayerUtils.GetCurrentClientPlayer()
if player then
player:CloseGui(Mod.current, GuiID.Enchantment)
end
end
function EnchantUI:OnClose()
self._hkHelper:destroy()
self.ui:closeWindow()
end
---checkSlotShiftMove
---@param slotIndex int
---@param itemStack ItemStack
function EnchantUI:checkSlotShiftMove(slotIndex, itemStack)
if slotIndex ~= 51 then
if itemStack:GetItem().id == Reg.ItemID("lapis_lazuli") then
return self.container, 51, 1
end
else
return self.container, 0, 50
end
if slotIndex < 10 then
-- shortcut to backpack
return self.container, 10, 40
elseif slotIndex < 50 then
-- backpack to shortcut
return self.container, 0, 10
end
end
return EnchantUI
================================================
FILE: ui/enchant/EnchantUIData.lua
================================================
local EnchantUIData = {
EventID = { ClickBtn = 1, },
}
return EnchantUIData
================================================
FILE: ui/hud/HudUI.lua
================================================
---@class TC.HudUI:TC.UIWindow
local HudUI = class("HudUI", require("ui.UIWindow"))
local InputControl = require("client.InputControl")
local UISpritePool = require("ui.UISpritePool")
local UIUtil = require("ui.UIUtil")
local UISlotOp = require("ui.UISlotOp")
local SettingsData = require("settings.SettingsData")
local GPlayer = require("player.GPlayer")
local MusicSystem = require("client.MusicSystem")
local UIDefault = require("ui.UIDefault")
local s_instance
local ADVANCEMENT_TIP_FADE_IN_TIME = 32
local ADVANCEMENT_TIP_FADE_OUT_TIME = 64 * 5
local ADVANCEMENT_TIP_FADE_IDLE_TIME = 32
local ADVANCEMENT_TIP_FADE_OUT_START_TIME = ADVANCEMENT_TIP_FADE_IN_TIME + ADVANCEMENT_TIP_FADE_OUT_TIME
local ADVANCEMENT_TIP_TOTAL_TIME = ADVANCEMENT_TIP_FADE_OUT_START_TIME + ADVANCEMENT_TIP_FADE_IDLE_TIME
---@class TC.AdvancementTipData
local AdvancementTipData = class("AdvancementTipData")
---__init
---@param node UINode
---@param itemStack ItemStack
function AdvancementTipData:__init(node, itemStack)
self.node = node
self.itemStack = itemStack
self.tickTime = 0
end
function HudUI:__init()
HudUI.super.__init(self, require("ui.UIDesign").getHudUI(), UIDefault.GROUP_GAME_HUD)
s_instance = self
self._centerTouchTicks = 0
self._lastCenterTouchPos = nil
self._debugLabel = UIText.cast(self.root:getChild("lb_debug"))
self._lbHp = UIText.cast(self.root:getChild("lb_hp"))
self._lbMana = UIText.cast(self.root:getChild("lb_mana"))
self._lbExpLevel = UIText.cast(self.root:getChild("panel_shortcut.lb_exp"))
self._lbItemName = UIText.cast(self.root:getChild("panel_shortcut.lb_item_name"))
self._panelBtn = self.root:getChild("panel_btn")
self._btnFrontWall = UIButton.cast(self._panelBtn:getChild("check_box_front_or_wall"))
self._btnSmart = UIButton.cast(self._panelBtn:getChild("check_box_smart"))
self._btnBackpack = UIButton.cast(self._panelBtn:getChild("button_backpack"))
self._btnRecipe = UIButton.cast(self._panelBtn:getChild("button_recipe"))
self._btnOption = UIButton.cast(self._panelBtn:getChild("button_option"))
self._btnAdvancement = UIButton.cast(self._panelBtn:getChild("button_task"))
self._jl = UIJoystick.cast(self.root:getChild("joystick_left"))
self._jr = UIJoystick.cast(self.root:getChild("joystick_right"))
self._jc = UIJoystick.cast(self.root:getChild("joystick_center"))
self._musicNameCR = UIText.cast(self.root:getChild("lb_music_name"))
self._musicAuthorCR = UIText.cast(self.root:getChild("lb_music_author"))
self._advancementPanel = UIPanel.cast(self.root:getChild("panel_advancements"))
self._baseAdvancementTipNode = UIPanel.cast(self._advancementPanel:getChild("panel_advancement_tip"))
self._advancementTips = {} ---@type TC.AdvancementTipData[]
self._advancementTipX = self._baseAdvancementTipNode.positionX
self._advancementTipHeight = self._baseAdvancementTipNode.height
local uiSpritePool = UISpritePool.getInstance()
self._textureAim = uiSpritePool:get("tc:aim").textureLocation
self._textureHealth = uiSpritePool:get("tc:health").textureLocation
self._textureHunger = uiSpritePool:get("tc:hunger").textureLocation
self._textureMana = uiSpritePool:get("tc:mana").textureLocation
self._textureExpBar = uiSpritePool:get("tc:exp_bar").textureLocation
self._lastHp = -1
self._lastMaxHp = -1
self._lastMana = -1
self._lastMaxMana = -1
self._lastExpLevel = -1
self._lastHeldIndex = -1
self._lastManaIconLines = 0
self._manaIconLines = 0
self._tickTime = 0
self._itemNameHideTickTime = 0
self._initPlayerData = false
self._shortcutSlotNodes = {}
self:loadHotkeys()
self:initContent()
end
function HudUI:loadHotkeys()
local inputControl = InputControl.getInstance()
self._backpackHotKey = Input.keyboard:getHotKeys(inputControl.keyMap.Backpack):addListener({ HudUI._tryOpenBackpack, self })
self._taskHotKey = Input.keyboard:getHotKeys(inputControl.keyMap.Task):addListener({ HudUI._tryOpenTask, self })
self._neiHotKey = Input.keyboard:getHotKeys(inputControl.keyMap.Nei):addListener({ HudUI._tryOpenNei, self })
self._optionHotKey = Input.keyboard:getHotKeys(inputControl.keyMap.Esc):addListener({ HudUI._onEsc, self })
self._smartHotKey = Input.keyboard:getHotKeys(inputControl.keyMap.Ctrl):addListener({ HudUI._onCtrl, self })
end
function HudUI:destroyHotkeys()
if self._backpackHotKey then
Input.keyboard:getHotKeys(InputControl.getInstance().keyMap.Backpack):removeListener(self._backpackHotKey)
self._backpackHotKey = nil
end
if self._taskHotKey then
Input.keyboard:getHotKeys(InputControl.getInstance().keyMap.Task):removeListener(self._taskHotKey)
self._taskHotKey = nil
end
if self._neiHotKey then
Input.keyboard:getHotKeys(InputControl.getInstance().keyMap.Nei):removeListener(self._neiHotKey)
self._neiHotKey = nil
end
if self._optionHotKey then
Input.keyboard:getHotKeys(InputControl.getInstance().keyMap.Esc):removeListener(self._optionHotKey)
self._optionHotKey = nil
end
if self._smartHotKey then
Input.keyboard:getHotKeys(InputControl.getInstance().keyMap.Ctrl):removeListener(self._smartHotKey)
self._smartHotKey = nil
end
end
function HudUI:initContent()
local inputControl = InputControl.getInstance()
local jl = self._jl
local jr = self._jr
local jc = self._jc
inputControl.virtualJoystickLeftNode = jl
inputControl.virtualJoystickRightNode = jr
inputControl.virtualJoystickCenterNode = jc
-- catch all touches for map operation
self.root.touchable = true
self.root:addTouchDownListener({ HudUI.onMapTouchDown, self })
jc:addTouchDownListener({ HudUI.onTouchDownCenter, self })
jc:addTouchUpAfterMoveListener({ HudUI.onTouchUpCenter, self })
self.root:getChild("panel_shortcut"):getPreDrawLayer(0):addListener({ HudUI._onRenderExpBar, self })
self.root:getChild("panel_element_base"):getPreDrawLayer(0):addListener({ HudUI._onRenderHudElement, self })
self._btnFrontWall:addTouchUpListener({ HudUI._onFrontWallClicked, self })
self._btnSmart:addTouchUpListener({ HudUI._onSmartClicked, self })
self._btnBackpack:addTouchUpListener({ HudUI._onBackpackClicked, self })
self._btnRecipe:addTouchUpListener({ HudUI._onRecipeBtnClicked, self })
self._btnOption:addTouchUpListener({ HudUI._onOptionBtnClicked, self })
self._btnAdvancement:addTouchUpListener({ HudUI._onTaskBtnClicked, self })
end
function HudUI.showAdvancementTip(advancementID)
if s_instance == nil then
return
end
s_instance:createAdvancementTipUI(advancementID)
end
function HudUI:createAdvancementTipUI(advancementID)
local advancement = AdvancementUtils.Get(advancementID)
local itemStack = ItemStack.new(ItemRegistry.GetItemByID(advancement.itemID))
local node = self._baseAdvancementTipNode:clone()
UIText.cast(node:getChild("lb_sub_caption")).text = LangUtils.AdvancementName(advancementID)
node:getChild("panel_icon"):getPostDrawLayer(0):addListener(
{ UISlotOp.itemStackOnRenderWithShadow, itemStack })
node.visible = true
self._advancementPanel:addChild(node)
table.insert(self._advancementTips, AdvancementTipData.new(node, itemStack))
end
function HudUI._changeBtnSprite(btn, flag, spriteName1, spriteName2)
local spriteName = flag and spriteName1 or spriteName2
local sprite = UISpritePool.getInstance():get(spriteName)
local color = Color.new(255, 255, 255, 200)
btn.targetSprite = sprite
btn.targetSprite.color = color
btn.selectedSprite = sprite
btn.selectedSprite.color = color
btn.pressedSprite = sprite
btn.pressedSprite.color = color
btn.highlightedSprite = sprite
btn.highlightedSprite.color = color
end
function HudUI:_onFrontWallClicked()
self.manager:playClickSound()
local inputControl = InputControl.getInstance()
inputControl.operatingWall = not inputControl.operatingWall
HudUI._changeBtnSprite(self._btnFrontWall, inputControl.operatingWall,
"tc:check_box_front_or_wall_2",
"tc:check_box_front_or_wall"
)
end
function HudUI:_onSmartClicked()
self.manager:playClickSound()
local inputControl = InputControl.getInstance()
inputControl.isSmart = not inputControl.isSmart
HudUI._changeBtnSprite(self._btnSmart, inputControl.isSmart,
"tc:check_box_smart_2",
"tc:check_box_smart"
)
end
function HudUI:_onBackpackClicked()
self:_tryOpenBackpack()
self.manager:playClickSound()
end
function HudUI:_tryOpenBackpack()
if self.manager:hasUIGroup(UIDefault.GROUP_GAME_WINDOW) then
return
end
local player = PlayerUtils.GetCurrentClientPlayer()
if not player then
return
end
local GuiID = require("ui.GuiID")
if player:IsGuiOpened(Mod.current, GuiID.Backpack) then
return
end
player:OpenGuiRemote(Mod.current, GuiID.Backpack, player.centerXi, player.centerYi)
end
function HudUI:_onTaskBtnClicked()
self:_tryOpenTask()
self.manager:playClickSound()
end
function HudUI:_tryOpenTask()
if self.manager:hasUIGroup(UIDefault.GROUP_GAME_WINDOW) then
return
end
local player = PlayerUtils.GetCurrentClientPlayer()
if not player then
return
end
local GuiID = require("ui.GuiID")
if player:IsGuiOpened(Mod.current, GuiID.Advancement) then
return
end
player:OpenGui(Mod.current, GuiID.Advancement, player.centerXi, player.centerYi)
end
function HudUI:_tryOpenNei()
if self.manager:hasUIGroup(UIDefault.GROUP_GAME_WINDOW) then
return
end
require("ui.nei.NeiUI").new()
end
function HudUI:_openRecipe()
self:_tryOpenNei()
end
function HudUI:_onRecipeBtnClicked()
self.manager:playClickSound()
self:_openRecipe()
end
function HudUI:_onOptionBtnClicked()
self.manager:playClickSound()
self:_tryOpenOption()
end
function HudUI:_onEsc()
self:_tryOpenOption()
end
function HudUI:_onCtrl()
if self.manager:hasUIGroup(UIDefault.GROUP_GAME_WINDOW) then
return
end
self:_onSmartClicked()
end
function HudUI:_tryOpenOption()
if self.manager:hasUIGroup(UIDefault.GROUP_GAME_WINDOW) then
return
end
if self.manager:isWindowOpened("OptionUI") then
return
end
require("ui.OptionUI").new()
end
function HudUI:_checkPlayerData()
if self._initPlayerData then
return
end
local player = PlayerUtils.GetCurrentClientPlayer()
if player then
self._initPlayerData = true
local backpackInventory = player.backpackInventory
local panelShortcut = self.root:getChild("panel_shortcut")
for i = 1, 10 do
local slotNode = UIButton.cast(panelShortcut:getChildByTag(i - 1))
table.insert(self._shortcutSlotNodes, slotNode)
UIUtil.hookSlotView(slotNode, backpackInventory:GetSlot(i - 1), false)
slotNode:addTouchDownListener({ HudUI._onSlotTouchDown, self, i - 1 })
end
self:refreshShortcut(player)
end
end
function HudUI:_onSlotTouchDown(index, _, _)
local player = PlayerUtils.GetCurrentClientPlayer()
if player then
player.heldSlotIndex = index
self:refreshShortcut(player)
end
end
---@param player Player
function HudUI:refreshShortcut(player)
local heldIndex = player.heldSlotIndex
if self._lastHeldIndex == heldIndex then
return
end
self._lastHeldIndex = heldIndex
for i = 1, #self._shortcutSlotNodes do
self._shortcutSlotNodes[i].selected = (i - 1 == heldIndex)
end
local itemName = ""
local slot = player.backpackInventory:GetSlot(heldIndex)
if slot.hasStack then
local itemId = slot:GetStack():GetItem().id
itemName = LangUtils.ItemName(itemId)
end
self._lbItemName.text = itemName
self._lbItemName.color = Color.new(193, 187, 220)
self._lbItemName.visible = true
self._itemNameHideTickTime = 64
end
---onTouchDownCenter
---@param touch Touch
function HudUI:onTouchDownCenter(_, touch)
self._lastCenterTouchPos = touch.position:clone()
self._centerTouchTicks = 64
end
---@param touch Touch
function HudUI:onTouchUpCenter(_, touch)
if self._lastCenterTouchPos ~= nil then
local d = touch.position:getDistance(self._lastCenterTouchPos)
if d < 6 then
self:activateMapClicking(touch.position)
end
end
end
function HudUI:updateTouchTicking()
if self._centerTouchTicks == 0 then
self._lastCenterTouchPos = nil
elseif self._centerTouchTicks > 0 then
self._centerTouchTicks = self._centerTouchTicks - 1
end
end
---activateMapClicking
---@param touchPosition Vector2
function HudUI:activateMapClicking(touchPosition)
local inputControl = InputControl.getInstance()
inputControl.isMapClicking = true
inputControl.touchMapPosition = touchPosition:clone()
--print("touch map", inputControl.touchMapPosition)
end
---onMapTouchDown
---@param touch Touch
function HudUI:onMapTouchDown(_, touch)
if not SettingsData.isMobileOperation then
if not Input.mouse.isRightButtonPressed then
return
end
end
self:activateMapClicking(touch.position)
end
function HudUI:update()
--self._debugLabel.text = string.format("FPS:%d Logic:%d Batches:%d Triangles:%d",
-- IntegratedClient.main.fps,
-- IntegratedClient.main.gameSpeed,
-- GraphicsDevice.drawCalls,
-- GraphicsDevice.primitiveCount
--)
--self._debugLabel.isRichText = true
self._debugLabel.visible = false
local showMobileLayout = SettingsData.isMobileOperation
self._jl.visible = showMobileLayout
self._jr.visible = showMobileLayout
self._jc.visible = showMobileLayout
self._panelBtn.visible = showMobileLayout
local inputControl = InputControl.getInstance()
inputControl.isPcMouseAtMap = false
if not SettingsData.isMobileOperation then
local pointer = self.manager.canvas:screenPointToCanvasPoint(Input.mouse.position)
local node = self.manager.baseLayer:getPointedNode(pointer)
if node:valid() then
if node.name == "hud_ui" then
inputControl.isPcMouseAtMap = true
end
end
end
if SettingsData.showMusicInfo and MusicSystem.getInstance().musicCopyright ~= nil and Audio.musicVolume > 0.3 then
local cr = MusicSystem.getInstance().musicCopyright
self._musicNameCR.visible = true
self._musicAuthorCR.visible = true
self._musicNameCR.text = cr.title
self._musicAuthorCR.text = cr.author
else
self._musicNameCR.visible = false
self._musicAuthorCR.visible = false
end
-- 先屏蔽
self._musicNameCR.visible = false
self._musicAuthorCR.visible = false
self:_checkPlayerData()
local player = PlayerUtils.GetCurrentClientPlayer()
if player then
self:refreshShortcut(player)
if not (player.health == self._lastHp and player.maxHealth == self._lastMaxHp) then
self._lastHp = player.health
self._lastMaxHp = player.maxHealth
self._lbHp.text = string.format("%d/%d", player.health, player.maxHealth)
self._lbHp.isRichText = true
self._lbHp:setPosition(16, 46)
end
if not (player.mana == self._lastMana and player.maxMana == self._lastMaxMana and self._manaIconLines == self._lastManaIconLines) then
self._lastMana = player.mana
self._lastHp = player.health
self._lastManaIconLines = self._manaIconLines
self._lbMana.text = string.format("%d/%d", player.mana, player.maxMana)
self._lbMana.isRichText = true
self._lbMana:setPosition(16, 100 + (self._manaIconLines - 1) * 32)
end
if not (player.expLevel == self._lastExpLevel) then
self._lastExpLevel = player.expLevel
self._lbExpLevel.text = string.format("%d", player.expLevel)
self._lbExpLevel.isRichText = true
end
end
self._tickTime = self._tickTime + 1
if self._itemNameHideTickTime > 0 then
self._itemNameHideTickTime = self._itemNameHideTickTime - 1
if self._itemNameHideTickTime == 0 then
self._lbItemName.visible = false
end
end
local currentX = self._advancementTipX
local currentY = 0
local TIP_HEIGHT = self._advancementTipHeight
for i = #self._advancementTips, 1, -1 do
local data = self._advancementTips[i]
data.tickTime = data.tickTime + 1
local t = data.tickTime
if t >= ADVANCEMENT_TIP_TOTAL_TIME then
self._advancementPanel:removeChild(data.node)
table.remove(self._advancementTips, i)
else
local deltaY = 0
if t < ADVANCEMENT_TIP_FADE_IN_TIME then
deltaY = (t * 1.0 / ADVANCEMENT_TIP_FADE_IN_TIME - 1.0) * TIP_HEIGHT
elseif t < ADVANCEMENT_TIP_FADE_OUT_START_TIME then
deltaY = 0
else
deltaY = ((ADVANCEMENT_TIP_TOTAL_TIME - t) * 1.0 / ADVANCEMENT_TIP_FADE_IN_TIME - 1.0) * TIP_HEIGHT
end
currentY = currentY + deltaY
data.node:setPosition(currentX, currentY)
currentY = currentY + TIP_HEIGHT
end
end
end
function HudUI:_onRenderHudElement()
local player = PlayerUtils.GetCurrentClientPlayer()
if not player then
return
end
self:_renderAim(player)
self:_renderHp(player)
self:_renderMana(player)
self:_renderHunger(player)
end
function HudUI:renderGaming()
end
---@param player Player
function HudUI:_renderAim(player)
-- only render in mobile
if not SettingsData.isMobileOperation then
return
end
local globalPlayer = GPlayer.GetInstance(player)
if not globalPlayer.showingAimPoint then
return
end
local show = false
local inputControl = InputControl.getInstance()
if inputControl.aimMode == 1 then
if inputControl.aimDistance > 0.05 and inputControl.aimPressing then
show = true
end
else
show = true
end
if show and not (globalPlayer.aimOffsetX == 0 and globalPlayer.aimOffsetY == 0) then
local cutRect = Rect.new(0, 0, 32, 32)
local drawX = player.centerX + globalPlayer.aimOffsetX - 16 - MiscUtils.screenX
local drawY = player.centerY + globalPlayer.aimOffsetY - 16 - MiscUtils.screenY
Sprite.draw(self._textureAim, Vector2.new(drawX, drawY), cutRect, Color.White)
end
end
---@param player Player
function HudUI:_renderHp(player)
if player.gameMode == GameMode.Creative then
return
end
local FIX_LEFT_X = 16
local FIX_TOP_Y = 16
local VALUE_PRE_HEART = 20
local ALPHA_EMPTY = 32
local SCALE_EMPTY = 0.75
local DEFAULT_STEP = 26
local maxHp = player.maxHealth
local hp = player.health
local cnt = math.ceil(maxHp * 1.0 / VALUE_PRE_HEART)
local index = math.min(math.floor(hp / VALUE_PRE_HEART), cnt - 1)
local drawX, drawY = FIX_LEFT_X, FIX_TOP_Y
local cutRect = Rect.new(0, 0, 32, 32)
local color = Color.White
local spriteEx = SpriteExData.new()
for i = 0, cnt - 1 do
local scale = 1
local alpha = 255
if i == index then
if hp ~= maxHp then
scale = 1 + Utils.SinValue(self._tickTime, 64) * 0.0625
alpha = math.floor(ALPHA_EMPTY + (255 - ALPHA_EMPTY) * (hp - index * VALUE_PRE_HEART) / VALUE_PRE_HEART)
end
elseif i > index then
scale = SCALE_EMPTY
alpha = ALPHA_EMPTY
end
color = Color.new(255, 255, 255, alpha)
spriteEx.scaleRateX = scale
spriteEx.scaleRateY = scale
local offset = 32 * -(scale - 1) / 2
local realDrawX = math.floor(drawX + offset)
local realDrawY = math.floor(drawY + offset)
Sprite.draw(self._textureHealth, Vector2.new(realDrawX, realDrawY), cutRect, color, spriteEx, 0)
local step = DEFAULT_STEP
if maxHp > 100 then
step = step - math.floor((maxHp - 100) / 40)
end
step = math.max(step, 14)
drawX = drawX + step
end
end
---@param player Player
function HudUI:_renderHunger(player)
if player.gameMode == GameMode.Creative then
return
end
local VALUE_PRE_HEART = 10
local MAX_HUNGER = 100
local DEFAULT_STEP = 26
local ALPHA_EMPTY = 32
local SCALE_EMPTY = 0.75
local hunger = player.foodLevel
local cnt = math.ceil(MAX_HUNGER * 1.0 / VALUE_PRE_HEART)
local index = math.min(math.floor(hunger / VALUE_PRE_HEART), cnt - 1)
local FIX_RIGHT_X = GameWindow.displayResolution.width - 16
local FIX_TOP_Y = 16
local drawX, drawY = FIX_RIGHT_X - DEFAULT_STEP, FIX_TOP_Y
local cutRect = Rect.new(0, 0, 32, 32)
local color = Color.White
local spriteEx = SpriteExData.new()
for i = 0, cnt - 1 do
local scale = 1
local alpha = 255
if i == index then
if hunger ~= MAX_HUNGER then
scale = 1 + Utils.SinValue(self._tickTime, 64) * 0.0625
alpha = math.floor(ALPHA_EMPTY + (255 - ALPHA_EMPTY) * (hunger - index * VALUE_PRE_HEART) / VALUE_PRE_HEART)
end
elseif i > index then
scale = SCALE_EMPTY
alpha = ALPHA_EMPTY
end
color = Color.new(255, 255, 255, alpha)
spriteEx.scaleRateX = scale
spriteEx.scaleRateY = scale
local offset = 32 * -(scale - 1) / 2
local realDrawX = math.floor(drawX + offset)
local realDrawY = math.floor(drawY + offset)
Sprite.draw(self._textureHunger, Vector2.new(realDrawX, realDrawY), cutRect, color, spriteEx, 0)
drawX = drawX - DEFAULT_STEP
end
end
---@param player Player
function HudUI:_renderMana(player)
if player.gameMode == GameMode.Creative then
return
end
local FIX_LEFT_X = 16
local FIX_TOP_Y = 70
local VALUE_PRE_HEART = 20
local ALPHA_EMPTY = 128
local SCALE_EMPTY = 0.75
local DEFAULT_STEP = 26
local DEFAULT_STEP_Y = 32
local DISPLAY_DISTANCE_PRE_LINE = 260
local maxMana = player.maxMana
local mana = player.mana
local cnt = math.ceil(maxMana * 1.0 / VALUE_PRE_HEART)
local index = math.min(math.floor(mana / VALUE_PRE_HEART), cnt - 1)
local drawX, drawY = FIX_LEFT_X, FIX_TOP_Y
local maxDrawX = FIX_LEFT_X + DISPLAY_DISTANCE_PRE_LINE
local cutRect = Rect.new(0, 0, 32, 32)
local color = Color.White
local spriteEx = SpriteExData.new()
self._manaIconLines = 1
for i = 0, cnt - 1 do
local scale = 1
local alpha = 255
if i == index then
if mana ~= maxMana then
scale = 1 + Utils.SinValue(self._tickTime, 64) * 0.0625
alpha = math.floor(ALPHA_EMPTY + (255 - ALPHA_EMPTY) * (mana - index * VALUE_PRE_HEART) / VALUE_PRE_HEART)
end
elseif i > index then
scale = SCALE_EMPTY
alpha = ALPHA_EMPTY
end
color = Color.new(255, 255, 255, alpha)
spriteEx.scaleRateX = scale
spriteEx.scaleRateY = scale
local offset = 32 * -(scale - 1) / 2
local realDrawX = math.floor(drawX + offset)
local realDrawY = math.floor(drawY + offset)
Sprite.draw(self._textureMana, Vector2.new(realDrawX, realDrawY), cutRect, color, spriteEx, 0)
local step = DEFAULT_STEP
drawX = drawX + step
if drawX >= maxDrawX then
drawX = FIX_LEFT_X
drawY = drawY + DEFAULT_STEP_Y
if i < cnt - 1 then
self._manaIconLines = self._manaIconLines + 1
end
end
end
end
---@param node UINode
---@param canvasPos Vector2
function HudUI:_onRenderExpBar(node, canvasPos)
local player = PlayerUtils.GetCurrentClientPlayer()
if not player then
return
end
local needExp = player:GetLevelNeedExp(player.expLevel)
if needExp <= 0 then
return
end
local barWidth, barHeight = 560, 12
local drawX = canvasPos.x + node.positionInCanvas.x
local drawY = canvasPos.y + node.positionInCanvas.y - barHeight - 4
local drawPos = Vector2.new(drawX, drawY)
local remainExp = player.remainExp
local rate = math.min(1.0, math.max(0.0, remainExp * 1.0 / needExp))
local cutRectBack = Rect.new(0, barHeight, barWidth, barHeight)
local cutRectFront = Rect.new(0, 0, barWidth * rate, barHeight)
Sprite.draw(self._textureExpBar, drawPos, cutRectBack, Color.White)
Sprite.draw(self._textureExpBar, drawPos, cutRectFront, Color.White)
end
function HudUI:closeWindow()
self:destroyHotkeys()
HudUI.super.closeWindow(self)
s_instance = nil
end
return HudUI
================================================
FILE: ui/nei/NeiDataBrewing.lua
================================================
local NeiDataBrewing = class("NeiDataBrewing")
local UIUtil = require("ui.UIUtil")
local UIDefault = require("ui.UIDefault")
local Locale = require("languages.Locale")
local MAX_ANIMATION_INDEX = 32
local ANIMATION_SPEED = 4
function NeiDataBrewing:__init()
self._animationTick = 0
self._animationIndex = 0
end
function NeiDataBrewing:getPanelSize()
return Size.new(280, 180)
end
function NeiDataBrewing:getTitle()
return "酿造"
end
function NeiDataBrewing:createUI(panelRoot, recipeID)
local offsetX = 120
local offsetY = 10
panelRoot:addChild(UIUtil.createImage("img_tube", offsetX, offsetY + 52, 30, 30, {
sprite = {
name = "tc:tube"
}
}))
panelRoot:addChild(UIUtil.createImage("img_process", offsetX + 38, offsetY + 12, 24, 80, {
sprite = {
name = "tc:brewing_process_00",
}
}))
panelRoot:addChild(UIUtil.createImage("img_bubble", offsetX - 48, offsetY + 4, 40, 64, {
sprite = {
name = "tc:brewing_bubble_00"
}
}))
panelRoot:addChild(UIUtil.createImage("img_fuel", offsetX - 48, offsetY + 70, 40, 12, {
sprite = {
name = "tc:brewing_fuel_00"
}
}))
-- 0: potion 1: source 2: output 3: fuel
panelRoot:addChild(UIUtil.createSlot("slot_potion",
offsetX - 82, offsetY + 88, UIDefault.CellSize, UIDefault.CellSize, "tc:glass_bottle"), 0)
panelRoot:addChild(UIUtil.createSlot("slot_input",
offsetX - 8, offsetY, UIDefault.CellSize, UIDefault.CellSize), 1)
panelRoot:addChild(UIUtil.createSlot("slot_output",
offsetX + 66, offsetY + 80, UIDefault.CellLargeSize, UIDefault.CellLargeSize, "tc:glass_bottle"), 2)
--panelRoot:addChild(UIUtil.createSlot("slot_fuel",
-- offsetX - 100, offsetY, UIDefault.CellSize, UIDefault.CellSize, "tc:blaze_powder"), 3)
local recipe = RecipeUtils.GetRecipe(recipeID)
local time = recipe.exData.time
local text = string.format(Locale.TIME_COST, time * 0.02)
panelRoot:addChild(UIUtil.createLabel("lb_desc", text,
120, 160, 32, 32, TextAlignment.HCenter, TextAlignment.VCenter
))
panelRoot:getChild("img_process"):getPostDrawLayer(0):addListener({ NeiDataBrewing.OnRenderProcessProgress, self })
panelRoot:getChild("img_bubble"):getPostDrawLayer(0):addListener({ NeiDataBrewing.OnRenderBubbleProgress, self })
panelRoot:getChild("img_fuel"):getPostDrawLayer(0):addListener({ NeiDataBrewing.OnRenderFuelProgress, self })
end
function NeiDataBrewing:onUpdateTick()
self._animationTick = self._animationTick + 1
if self._animationTick > ANIMATION_SPEED then
self._animationTick = 0
self._animationIndex = self._animationIndex + 1
if self._animationIndex > MAX_ANIMATION_INDEX then
self._animationIndex = 0
end
end
end
---
---@param node UINode
---@param canvasPos Vector2
function NeiDataBrewing:OnRenderProcessProgress(node, canvasPos)
local step = math.ceil(self._animationIndex / MAX_ANIMATION_INDEX * 16)
UIUtil.renderProgress("tc:brewing_process_01",
node.positionInCanvas + canvasPos,
step,
16, 0, 1)
end
---
---@param node UINode
---@param canvasPos Vector2
function NeiDataBrewing:OnRenderBubbleProgress(node, canvasPos)
local step = math.ceil(self._animationIndex / MAX_ANIMATION_INDEX * 32)
UIUtil.renderProgress("tc:brewing_bubble_01",
node.positionInCanvas + canvasPos,
step,
32, 0, -1)
end
---
---@param node UINode
---@param canvasPos Vector2
function NeiDataBrewing:OnRenderFuelProgress(node, canvasPos)
local step = math.ceil(self._animationIndex / MAX_ANIMATION_INDEX * 20)
UIUtil.renderProgress("tc:brewing_fuel_01",
node.positionInCanvas + canvasPos,
20 - step,
20, 0, -1)
end
return NeiDataBrewing
================================================
FILE: ui/nei/NeiDataCrafting.lua
================================================
local NeiDataCrafting = class("NeiDataCrafting")
local UIUtil = require("ui.UIUtil")
local UIDefault = require("ui.UIDefault")
function NeiDataCrafting:getPanelSize()
return Size.new(256, 144)
end
function NeiDataCrafting:getTitle()
return "合成"
end
function NeiDataCrafting:createUI(panelRoot, recipeID)
for i = 0, 8 do
panelRoot:addChild(UIUtil.createSlot("slot",
(i % 3) * UIDefault.CellOffset, math.floor(i / 3) * UIDefault.CellOffset), i)
end
panelRoot:addChild(UIUtil.createSlot("slot",
200, 43, UIDefault.CellLargeSize, UIDefault.CellLargeSize), 9)
panelRoot:addChild(UIUtil.createImage("img_craft_arrow", 158, 60, 32, 24, {
sprite = {
name = "tc:arrow3",
color = Color.new(100, 100, 100, 188)
}
}))
end
return NeiDataCrafting
================================================
FILE: ui/nei/NeiDataProxy.lua
================================================
local NeiDataProxy = class("NeiDataProxy")
function NeiDataProxy:__init()
self._dataDict = {
[Reg.RecipeConfigID("Craft3x")] = require("NeiDataCrafting").new(),
[Reg.RecipeConfigID("Smelt")] = require("NeiDataSmelting").new(),
[Reg.RecipeConfigID("Repair")] = require("NeiDataRepairing").new(),
[Reg.RecipeConfigID("Brew")] = require("NeiDataBrewing").new(),
}
end
function NeiDataProxy:getData(recipeConfigID)
return self._dataDict[recipeConfigID]
end
return NeiDataProxy
================================================
FILE: ui/nei/NeiDataRepairing.lua
================================================
local NeiDataRepairing = class("NeiDataRepairing")
local UIUtil = require("ui.UIUtil")
local UIDefault = require("ui.UIDefault")
function NeiDataRepairing:getPanelSize()
return Size.new(320, 60)
end
function NeiDataRepairing:getTitle()
return "修复"
end
function NeiDataRepairing:createUI(panelRoot, recipeID)
local offsetX, offsetY = 0, 0
local recipe = RecipeUtils.GetRecipe(recipeID)
local repairPercent = math.ceil(recipe.exData.repairRate * 100)
-- 50-52: tool, source, output
panelRoot:addChild(UIUtil.createSlot("slot_tool",
offsetX + 0,
offsetY + 0,
UIDefault.CellSize, UIDefault.CellSize, "tc:hammer"), 0)
panelRoot:addChild(UIUtil.createSlot("slot_source",
offsetX + 120,
offsetY + 0,
UIDefault.CellSize, UIDefault.CellSize, "tc:ingot_gray"), 1)
panelRoot:addChild(UIUtil.createSlot("slot_output",
offsetX + 250,
offsetY - 5,
UIDefault.CellLargeSize, UIDefault.CellLargeSize, "tc:hammer"), 2)
panelRoot:addChild(UIUtil.createLabel("lb_exp",
string.format("修复率:%d%%", repairPercent),
offsetX + 130, offsetY + 54, 32, 32,
TextAlignment.HCenter, TextAlignment.VCenter, {
color = Color.Yellow
}
))
panelRoot:addChild(UIUtil.createImage("img_add", offsetX + 68, offsetY + 8, 32, 32, {
sprite = {
name = "tc:adding",
}
}))
panelRoot:addChild(UIUtil.createImage("img_process", offsetX + 190, offsetY + 8, 40, 32, {
sprite = {
name = "tc:process_00",
}
}))
end
return NeiDataRepairing
================================================
FILE: ui/nei/NeiDataSmelting.lua
================================================
local NeiDataSmelting = class("NeiDataSmelting")
local UIUtil = require("ui.UIUtil")
local UIDefault = require("ui.UIDefault")
local Locale = require("languages.Locale")
local MAX_ANIMATION_INDEX = 16
local ANIMATION_SPEED = 8
function NeiDataSmelting:__init()
self._animationTick = 0
self._animationIndex = 0
end
function NeiDataSmelting:getPanelSize()
return Size.new(190, 130)
end
function NeiDataSmelting:getTitle()
return "烧炼"
end
function NeiDataSmelting:createUI(panelRoot, recipeID)
panelRoot:addChild(UIUtil.createSlot("slot",
0, 5), 0)
panelRoot:addChild(UIUtil.createSlot("slot",
130, 20, UIDefault.CellLargeSize, UIDefault.CellLargeSize), 1)
panelRoot:addChild(UIUtil.createImage("img_cook",
70, 34, 40, 32, {
sprite = {
name = "tc:process_00"
}
}))
panelRoot:addChild(UIUtil.createImage("img_burn",
8, 68, 30, 30, {
sprite = {
name = "tc:burn_00"
}
}))
local recipe = RecipeUtils.GetRecipe(recipeID)
local time = recipe.exData.time
local text = string.format(Locale.BURN_TIME_COST, time * 0.02)
panelRoot:addChild(UIUtil.createLabel("lb_desc", text,
80, 120, 32, 32, TextAlignment.HCenter, TextAlignment.VCenter
))
panelRoot:getChild("img_cook"):getPostDrawLayer(0):addListener({ NeiDataSmelting.OnRenderCookProgress, self })
panelRoot:getChild("img_burn"):getPostDrawLayer(0):addListener({ NeiDataSmelting.OnRenderBurnProgress, self })
end
function NeiDataSmelting:onUpdateTick()
self._animationTick = self._animationTick + 1
if self._animationTick > ANIMATION_SPEED then
self._animationTick = 0
self._animationIndex = self._animationIndex + 1
if self._animationIndex > MAX_ANIMATION_INDEX then
self._animationIndex = 0
end
end
end
---OnRenderCookProgress
---@param node UINode
---@param canvasPos Vector2
function NeiDataSmelting:OnRenderCookProgress(node, canvasPos)
UIUtil.renderProgress("tc:process_01",
node.positionInCanvas + canvasPos,
self._animationIndex,
16,
1, 0)
end
---
---@param node UINode
---@param canvasPos Vector2
function NeiDataSmelting:OnRenderBurnProgress(node, canvasPos)
UIUtil.renderProgress("tc:burn_01",
node.positionInCanvas + canvasPos,
16 - self._animationIndex,
16,
0, -1)
end
return NeiDataSmelting
================================================
FILE: ui/nei/NeiUI.lua
================================================
---@class TC.NeiUI:TC.UIWindow
local NeiUI = class("NeiUI", require("ui.UIWindow"))
local UIUtil = require("ui.UIUtil")
local UIDefault = require("ui.UIDefault")
local SettingsData = require("settings.SettingsData")
local RawHotkeyUIHelper = require("ui.RawHotkeyUIHelper")
local Locale = require("languages.Locale")
local ORE_DICTIONARY_FLUSH_TICKS = 40
local PREVIEW_INPUT_CNT_PRE_LINE = 3
local PREVIEW_OUTPUT_CNT_PRE_LINE = 1
---@class TC.NeiHistoryEntity
local NeiHistoryEntity = class("NeiHistoryEntity")
---__init
---@param itemStack ItemStack
---@param fromOutput boolean
---@param tabIndex int
---@param recipeIndexInTab int
function NeiHistoryEntity:__init(itemStack, fromOutput, tabIndex, recipeIndexInTab)
self.itemStack = itemStack
self.fromOutput = fromOutput
self.tabIndex = tabIndex
self.recipeIndexInTab = recipeIndexInTab
end
local NeiHistory = class("NeiHistory")
local MAX_HISTORY_SIZE = 100
function NeiHistory:__init()
self._entities = {} ---@type TC.NeiHistoryEntity[]
end
---push
---@param entity TC.NeiHistoryEntity
function NeiHistory:push(entity)
if #self._entities >= MAX_HISTORY_SIZE then
table.remove(self._entities, 1)
end
table.insert(self._entities, entity)
end
function NeiHistory:pop()
if #self._entities > 0 then
return table.remove(self._entities, #self._entities)
end
return nil
end
---@class TC.SearchRequest
local SearchRequest = class("SearchRequest")
---__init
---@param itemStack ItemStack
---@param itemID int
---@param fromOutput boolean
function SearchRequest:__init(itemStack, itemID, fromOutput)
self.itemStack = itemStack
self.itemID = itemID
self.fromOutput = fromOutput
self._relateOreDictionaryIDs = ItemRegistry.GetItemByID(itemID).oreDictionaryIDs
end
---isSameRequest
---@param itemStack ItemStack
---@param fromOutput boolean
function SearchRequest:isSameRequest(itemStack, fromOutput)
if fromOutput == self.fromOutput then
if itemStack:GetItem().id == self.itemID then
return true
end
end
return false
end
function SearchRequest:_fixInputTypeAndID(type, id)
if not self.fromOutput and type == RecipeInputSlotType.OreDictionary then
for _, oreDictionaryID in each(self._relateOreDictionaryIDs) do
if id == oreDictionaryID then
return RecipeInputSlotType.Item, self.itemID
end
end
end
return type, id
end
---@class TC.PreviewRecipeData
local PreviewRecipeData = class("PreviewRecipeData")
---__init
---@param validInputCache table
---@param validOutputSlots Slot[]
function PreviewRecipeData:__init(validInputCache, validOutputSlots)
self.validInputCache = validInputCache
self.validOutputSlots = validOutputSlots
end
---@class TC.OreDictionaryRecord
local OreDictionaryRecord = class("OreDictionaryRecord")
function OreDictionaryRecord:__init(oreDictionaryID, stackSize, slotIndex)
self.oreDictionaryID = oreDictionaryID
self.stackSize = stackSize
self.slotIndex = slotIndex
self.cursor = 1
end
function OreDictionaryRecord:getCurrentItemID()
local ids = ItemUtils.GetOreDictionaryItemIDs(self.oreDictionaryID)
return ids[self.cursor]
end
function OreDictionaryRecord:nextCursor()
local ids = ItemUtils.GetOreDictionaryItemIDs(self.oreDictionaryID)
if self.cursor >= ids.count then
self.cursor = 1
else
self.cursor = self.cursor + 1
end
end
function NeiUI:__init()
NeiUI.super.__init(self, require("ui.UIDesign").getNeiUI(), require("ui.UIDefault").GROUP_GAME_WINDOW)
self._searchListInventory = Inventory.new(0)
self._searchPanelCells = self.root:getChild("panel_search.panel_cells")
self._searchBaseCell = self.root:getChild("panel_search.panel_cell")
self._lbSearchListPage = UIText.cast(self.root:getChild("panel_search.lb_page"))
self._baseInfoPanel = UIPanel.cast(self.root:getChild("layer"))
self._tabsNode = UIPanel.cast(self._baseInfoPanel:getChild("panel_tabs"))
self._baseTabNode = UIPanel.cast(self._baseInfoPanel:getChild("panel_tab"))
self._previewPanelList = self._baseInfoPanel:getChild("panel_list")
self._positionPanelDetail = UIPanel.cast(self._baseInfoPanel:getChild("panel_position_detail"))
self._lbInfoTitle = UIText.cast(self._baseInfoPanel:getChild("lb_recipe_name"))
self._panelDetail = UIPanel.cast(self._positionPanelDetail:getChild("panel_detail"))
self._btnSearchMode = UIButton.cast(self.root:getChild("btn_search_mode"))
self._btnBackHistory = UIButton.cast(self.root:getChild("btn_back_history"))
self._dataProxy = require("NeiDataProxy").new()
self._isCurrentSearchFromOutput = true
self._oreDictionaryFlushTicks = ORE_DICTIONARY_FLUSH_TICKS
self._isDisplayAll = true
self._currentItemRootGroupID = 1
self._displayLines = 1
self._displayCntPreLine = 1
self._displayCellCntPrePage = 1
self._currentPageIndex = 0
self._totalPageCnt = 1
self._searchTotalDisplayCnt = 0
self._history = NeiHistory.new()
---@type TC.SearchRequest
self._currentSearchRequest = nil
---@type ItemStack
self._nextSearchRequestStack = nil
self._currentSearchData = {}
self._tabRecipeConfigs = {}
self._currentTabIndex = 0
self._currentRecipeIndexInTab = 0
self._tabCount = 0
self._tabInventory = Inventory.new(0)
self._detailData = nil
self._previewInventory = Inventory.new(0)
self._detailInventory = Inventory.new(0)
self._previewOreDictionaryRecords = {} ---@type TC.OreDictionaryRecord[]
self._detailOreDictionaryRecords = {} ---@type TC.OreDictionaryRecord[]
---@type UINode[]
self._previewNodes = {}
self._hkHelper = RawHotkeyUIHelper.new(self)
self:_initContent()
end
function NeiUI:_initContent()
self._baseInfoPanel.visible = false
self._baseTabNode.visible = false
self._searchBaseCell.visible = false
self.root:addTouchUpListener({ function(self)
self:closeWindow()
end, self })
self._btnSearchMode.visible = SettingsData.isMobileOperation
self._btnSearchMode:addTouchUpListener({ NeiUI._onSearchModeBtnClicked, self })
self._btnBackHistory:addTouchUpListener({ NeiUI._onBackHistoryClicked, self })
self:initUpdateFunc({ NeiUI._onUpdateTick, self })
self.root:getChild("panel_search.btn_next"):addTouchUpListener({ NeiUI._onSearchListNextPageClicked, self })
self.root:getChild("panel_search.btn_prev"):addTouchUpListener({ NeiUI._onSearchListPrevPageClicked, self })
self:_refreshSearchListData()
end
function NeiUI:_onUpdateTick()
if self._oreDictionaryFlushTicks > 0 then
self._oreDictionaryFlushTicks = self._oreDictionaryFlushTicks - 1
end
if self._oreDictionaryFlushTicks == 0 then
self._oreDictionaryFlushTicks = ORE_DICTIONARY_FLUSH_TICKS
self:flushOreDictionaryItems(self._previewOreDictionaryRecords, self._previewInventory)
self:flushOreDictionaryItems(self._detailOreDictionaryRecords, self._detailInventory)
end
if self._detailData ~= nil and self._detailData.onUpdateTick ~= nil then
self._detailData:onUpdateTick()
end
if self._nextSearchRequestStack ~= nil then
local stack = self._nextSearchRequestStack
self._nextSearchRequestStack = nil
self:_checkPCSearchOperation()
self:_trySearch(stack, self._isCurrentSearchFromOutput, true)
end
end
function NeiUI:_onBackHistoryClicked()
local historyEntity = self._history:pop()
if historyEntity == nil then
return
end
self:_trySearch(historyEntity.itemStack, historyEntity.fromOutput, false)
self:_onInfoTabClicked(historyEntity.tabIndex)
self:_onPreviewItemClicked(historyEntity.recipeIndexInTab)
self.manager:playClickSound()
end
function NeiUI:flushOreDictionaryItems(records, inventory)
for _, record in ipairs(records) do
record:nextCursor()
local slot = inventory:GetSlot(record.slotIndex)
local itemID = record:getCurrentItemID()
local stack = ItemStack.new(ItemRegistry.GetItemByID(itemID), record.stackSize)
slot:PushStack(stack)
end
end
---_initInputSlot
---@param node UINode
---@param records TC.OreDictionaryRecord[]
---@param inventory Inventory
---@param slotIndex int
---@param type int
---@param id int
---@param stackSize int
function NeiUI:_initInputSlot(node, records, inventory, slotIndex, type, id, stackSize)
local slot = inventory:GetSlot(slotIndex)
if type == RecipeInputSlotType.Empty then
slot:ClearStack()
else
local itemID
if type == RecipeInputSlotType.OreDictionary then
local record = OreDictionaryRecord.new(id, stackSize, slotIndex)
table.insert(records, record)
itemID = record:getCurrentItemID()
else
itemID = id
end
local stack = ItemStack.new(ItemRegistry.GetItemByID(itemID), stackSize)
slot:PushStack(stack)
end
UIUtil.hookSlotView(node, slot, true)
node:addTouchUpListener({ NeiUI._onDetailCellClicked, self, slot })
end
---_initOutputSlot
---@param node UINode
---@param slot Slot
function NeiUI:_initOutputSlot(node, slot)
UIUtil.hookSlotView(node, slot, true)
node:addTouchUpListener({ NeiUI._onDetailCellClicked, self, slot })
end
---_onDetailCellClicked
---@param slot Slot
function NeiUI:_onDetailCellClicked(slot)
if slot.hasStack then
self.manager:playClickSound()
self._nextSearchRequestStack = slot:GetStack()
end
end
function NeiUI:_onSearchModeBtnClicked()
self.manager:playClickSound()
self._isCurrentSearchFromOutput = not self._isCurrentSearchFromOutput
local name
if self._isCurrentSearchFromOutput then
name = Locale.SEARCH_FROM_OUTPUT
else
name = Locale.SEARCH_FROM_INPUT
end
UIText.cast(self._btnSearchMode:getChild("lb_caption")).text = name
end
function NeiUI:_checkPCSearchOperation()
if not SettingsData.isMobileOperation then
self._isCurrentSearchFromOutput = not Input.mouse.isRightButtonInstantUp
end
end
function NeiUI:_onSearchListNextPageClicked()
self.manager:playClickSound()
self._currentPageIndex = self._currentPageIndex + 1
if self._currentPageIndex >= self._totalPageCnt then
self._currentPageIndex = 0
end
self:_resetSearchListUI()
end
function NeiUI:_onSearchListPrevPageClicked()
self.manager:playClickSound()
if self._currentPageIndex == 0 then
self._currentPageIndex = self._totalPageCnt - 1
else
self._currentPageIndex = self._currentPageIndex - 1
end
self:_resetSearchListUI()
end
function NeiUI:_refreshSearchListData()
local width, height = self._searchPanelCells.width, self._searchPanelCells.height
local cellWidth, cellHeight = self._searchBaseCell.width, self._searchBaseCell.height
self._displayCntPreLine = math.max(1, math.floor(width / cellWidth))
self._displayLines = math.max(1, math.floor(height / cellHeight))
self._displayCellCntPrePage = self._displayLines * self._displayCntPreLine
local groupIDs = ItemUtils.GetGroupIDsFromRootID(self._currentItemRootGroupID)
self._searchTotalDisplayCnt = 0
for _, groupID in each(groupIDs) do
self._searchTotalDisplayCnt = self._searchTotalDisplayCnt + ItemUtils.GetGroupItemIDs(groupID).count
end
self._searchListInventory:SetSlotCount(self._searchTotalDisplayCnt)
local index = 0
for _, groupID in each(groupIDs) do
local itemIDs = ItemUtils.GetGroupItemIDs(groupID)
for _, itemID in each(itemIDs) do
local item = ItemRegistry.GetItemByID(itemID)
self._searchListInventory:GetSlot(index):PushStack(ItemStack.new(item))
index = index + 1
end
end
self._totalPageCnt = math.ceil(self._searchTotalDisplayCnt / self._displayCellCntPrePage)
self._currentPageIndex = 0
print("Total:", self._searchTotalDisplayCnt, "Pages:", self._totalPageCnt)
self:_resetSearchListUI()
end
function NeiUI:_resetSearchListUI()
local cellWidth, cellHeight = self._searchBaseCell.width, self._searchBaseCell.height
self._searchPanelCells:removeAllChildren()
local itemSlotIndexStart = self._currentPageIndex * self._displayCellCntPrePage
for index = 0, self._displayCellCntPrePage - 1 do
local slotIndex = itemSlotIndexStart + index
if slotIndex >= self._searchTotalDisplayCnt then
break
end
local slot = self._searchListInventory:GetSlot(slotIndex)
node = self._searchBaseCell:clone()
node.name = string.format("cell_%d", index)
self._searchPanelCells:addChild(node, index)
node.visible = true
local xi = index % self._displayCntPreLine
local yi = math.floor(index / self._displayCntPreLine)
node:setPosition(xi * cellWidth, yi * cellHeight)
UIUtil.hookSlotView(node, slot)
node:addTouchUpListener({ NeiUI._onSearchCellClicked, self, slotIndex })
end
self._lbSearchListPage.text = string.format("%d/%d", self._currentPageIndex + 1, self._totalPageCnt)
end
function NeiUI:_onSearchCellClicked(slotIndex)
if slotIndex >= self._searchListInventory.slotCount then
return
end
local slot = self._searchListInventory:GetSlot(slotIndex)
if not slot.hasStack then
return
end
local stack = slot:GetStack()
self:_checkPCSearchOperation()
self:_trySearch(stack, self._isCurrentSearchFromOutput, true)
self.manager:playClickSound()
end
function NeiUI:_resetInfoUI()
if next(self._currentSearchData) == nil then
self._baseInfoPanel.visible = false
return
end
self._baseInfoPanel.visible = true
self._tabRecipeConfigs = {}
self._tabsNode:removeAllChildren()
self._currentTabIndex = 0
local tabIndex = 0
for configID, _ in pairs(self._currentSearchData) do
local tabNode = self._baseTabNode:clone()
self._tabRecipeConfigs[tabIndex + 1] = configID
self._tabsNode:addChild(tabNode, tabIndex)
tabNode:setPosition(tabIndex * tabNode.width, 0)
tabNode.visible = true
tabNode:addTouchUpListener({ NeiUI._onInfoTabClicked, self, tabIndex })
tabIndex = tabIndex + 1
end
self._tabCount = tabIndex
self._tabInventory:SetSlotCount(self._tabCount)
for i = 0, self._tabCount - 1 do
local configID = self._tabRecipeConfigs[i + 1]
local config = RecipeUtils.GetConfig(configID)
if config.iconItemID > 0 then
local tabNode = self._tabsNode:getChildByTag(i)
local item = ItemRegistry.GetItemByID(config.iconItemID)
local slot = self._tabInventory:GetSlot(i)
slot:PushStack(ItemStack.new(item))
UIUtil.hookSlotView(tabNode, slot, false)
end
end
self:_resetTabState()
self:_resetInfoPanel()
end
function NeiUI:_onInfoTabClicked(tabIndex)
if tabIndex == self._currentTabIndex then
return
end
self.manager:playClickSound()
self._currentTabIndex = tabIndex
self:_resetTabState()
self:_resetInfoPanel()
end
function NeiUI:_resetTabState()
local UISpritePool = require("ui.UISpritePool")
for i = 0, self._tabCount - 1 do
local tabNode = UIPanel.cast(self._tabsNode:getChildByTag(i))
local spriteName = "tc:tab"
if i == self._currentTabIndex then
spriteName = "tc:tab_clicked"
end
tabNode.sprite = UISpritePool.getInstance():get(spriteName)
end
end
function NeiUI:_resetInfoPanel()
local configID = self._tabRecipeConfigs[self._currentTabIndex + 1]
local recipeIDs = self._currentSearchData[configID]
local recipeCount = #recipeIDs
---@type TC.PreviewRecipeData[]
local previews = {}
for _, recipeID in ipairs(recipeIDs) do
table.insert(previews, self:_getPreviewRecipeData(recipeID))
end
local totalSlotCount = 0
for _, preview in ipairs(previews) do
totalSlotCount = totalSlotCount + #preview.validInputCache
end
self._previewInventory:SetSlotCount(totalSlotCount)
self._previewOreDictionaryRecords = {}
self._currentRecipeIndexInTab = 0
self._previewNodes = {}
---@param preview TC.PreviewRecipeData
local function _getPreviewLineData(preview)
local inputLines = math.ceil(#preview.validInputCache / PREVIEW_INPUT_CNT_PRE_LINE)
local outputLines = math.ceil(#preview.validOutputSlots / PREVIEW_OUTPUT_CNT_PRE_LINE)
local maxLines = math.max(inputLines, outputLines)
return inputLines, outputLines, maxLines
end
local slotCursor = 0
local proxy = {
_getTableElementCount = function()
return recipeCount
end,
_getTableElementSize = function(_, index)
local _, _, maxLines = _getPreviewLineData(previews[index])
local height = 16 + maxLines * UIDefault.CellSize
return Size.new(self._previewPanelList.width, height)
end,
_setTableElement = function(_, node, index)
local preview = previews[index]
local inputLines, outputLines, maxLines = _getPreviewLineData(preview)
local inputX = 8
local outputX = inputX + (PREVIEW_INPUT_CNT_PRE_LINE + 1) * UIDefault.CellSize
local inputY = 8 + (maxLines - inputLines) * UIDefault.CellSize / 2
local outputY = 8 + (maxLines - outputLines) * UIDefault.CellSize / 2
---@type UINode
local baseCellNode = node:getChild("panel_preview_cell")
baseCellNode.visible = false
---@type UINode
local imgArrow = node:getChild("img_arrow")
imgArrow:setPosition(
inputX + PREVIEW_INPUT_CNT_PRE_LINE * UIDefault.CellSize + (UIDefault.CellSize - 32) / 2,
(node.height - 24) / 2
)
for i, cache in ipairs(preview.validInputCache) do
local cellNode = baseCellNode:clone()
cellNode.visible = true
node:addChild(cellNode)
cellNode:setPosition(
inputX + ((i - 1) % PREVIEW_INPUT_CNT_PRE_LINE) * UIDefault.CellSize,
inputY + math.floor((i - 1) / PREVIEW_INPUT_CNT_PRE_LINE) * UIDefault.CellSize
)
cellNode.touchable = false
local type, id, stackSize = cache[1], cache[2], cache[3]
self:_initInputSlot(cellNode, self._previewOreDictionaryRecords, self._previewInventory, slotCursor, type, id, stackSize)
slotCursor = slotCursor + 1
end
for i, e in ipairs(preview.validOutputSlots) do
local cellNode = baseCellNode:clone()
cellNode.visible = true
node:addChild(cellNode)
cellNode:setPosition(
outputX + ((i - 1) % PREVIEW_OUTPUT_CNT_PRE_LINE) * UIDefault.CellSize,
outputY + math.floor((i - 1) / PREVIEW_OUTPUT_CNT_PRE_LINE) * UIDefault.CellSize
)
cellNode.touchable = false
self:_initOutputSlot(cellNode, e)
end
node:addTouchUpListener({ NeiUI._onPreviewItemClicked, self, index })
table.insert(self._previewNodes, node)
end
}
UIUtil.setTable(self._previewPanelList, proxy, true, 1)
self:_setDetailPanel(1)
end
function NeiUI:_resetPreviewBg(index)
local UISpritePool = require("ui.UISpritePool")
for i, node in ipairs(self._previewNodes) do
local panel = UIPanel.cast(node)
local spriteName
if i == index then
spriteName = "tc:base_list_cell_highlight"
else
spriteName = "tc:base_list_cell"
end
panel.sprite = UISpritePool.getInstance():get(spriteName)
end
end
function NeiUI:_onPreviewItemClicked(index)
if index == self._currentRecipeIndexInTab then
return
end
self.manager:playClickSound()
self:_setDetailPanel(index)
end
function NeiUI:_setDetailPanel(index)
if index == self._currentRecipeIndexInTab then
return
end
local configID = self._tabRecipeConfigs[self._currentTabIndex + 1]
local recipeIDs = self._currentSearchData[configID]
if index > #recipeIDs then
return
end
self:_resetPreviewBg(index)
self._currentRecipeIndexInTab = index
local recipeID = recipeIDs[index]
local config = RecipeUtils.GetConfig(configID)
local recipe = RecipeUtils.GetRecipe(recipeID)
local data = self._dataProxy:getData(configID)
self._detailData = data
self._panelDetail:removeAllChildren()
self._detailOreDictionaryRecords = {}
if data.getPanelSize == nil then
self._panelDetail:setSize(self._positionPanelDetail.width, self._positionPanelDetail.height)
else
self._panelDetail.size = data:getPanelSize()
end
self._panelDetail:applyMargin(false)
if data.getTitle == nil then
self._lbInfoTitle.text = ""
else
self._lbInfoTitle.text = data:getTitle()
end
data:createUI(self._panelDetail, recipeID)
local inputs = recipe.inputs
local outputs = recipe.outputs
self._detailInventory:SetSlotCount(config.inputCount + config.outputCount)
local slotIndex = 0
for i = 0, config.inputCount - 1 do
local node = self._panelDetail:getChildByTag(i)
if node:valid() then
local e = inputs[i + 1]
local type, id = self._currentSearchRequest:_fixInputTypeAndID(e.type, e.id)
self:_initInputSlot(node, self._detailOreDictionaryRecords, self._detailInventory, slotIndex, type, id, e.stackSize)
end
slotIndex = slotIndex + 1
end
for i = 0, config.outputCount - 1 do
local node = self._panelDetail:getChildByTag(config.inputCount + i)
if node:valid() then
local e = outputs[i + 1]
self:_initOutputSlot(node, e)
end
slotIndex = slotIndex + 1
end
end
function NeiUI:_getPreviewRecipeData(recipeID)
local recipe = RecipeUtils.GetRecipe(recipeID)
local inputCache = {}
local outputValidCells = {}
---@param e RecipeInputSlot
for _, e in each(recipe.inputs) do
if e.type ~= RecipeInputSlotType.Empty then
local type, id = self._currentSearchRequest:_fixInputTypeAndID(e.type, e.id)
local isExistInCache = false
for _, c in ipairs(inputCache) do
if c[1] == type and c[2] == id then
c[3] = c[3] + e.stackSize
isExistInCache = true
break
end
end
if not isExistInCache then
table.insert(inputCache, { type, id, e.stackSize })
end
end
end
---@param e Slot
for _, e in each(recipe.outputs) do
if e.hasStack then
table.insert(outputValidCells, e)
end
end
return PreviewRecipeData.new(inputCache, outputValidCells)
end
function NeiUI:trySearch(itemStack, fromOutput)
self:_trySearch(itemStack, fromOutput, true)
end
---_trySearch
---@param itemStack ItemStack
---@param fromOutput boolean
---@param saveHistory boolean
function NeiUI:_trySearch(itemStack, fromOutput, saveHistory)
if self._currentSearchRequest then
if itemStack:GetItem().id == self._currentSearchRequest.itemID and fromOutput == self._currentSearchRequest.fromOutput then
return
end
end
local data = NeiUI.doSearch(itemStack, fromOutput)
if next(data) == nil then
return
end
if saveHistory and self._currentSearchRequest then
local historyEntity = NeiHistoryEntity.new(
self._currentSearchRequest.itemStack,
self._currentSearchRequest.fromOutput,
self._currentTabIndex,
self._currentRecipeIndexInTab
)
self._history:push(historyEntity)
end
self._currentSearchRequest = SearchRequest.new(itemStack, itemStack:GetItem().id, fromOutput)
self._currentSearchData = data
self:_resetInfoUI()
end
function NeiUI.doSearch(itemStack, fromOutput)
local res = {}
local maxConfigID = Reg.MaxRecipeConfigID()
for configID = 1, maxConfigID do
local recipeIDs = NeiUI.doSearchByRecipeConfig(configID, itemStack, fromOutput)
if #recipeIDs > 0 then
res[configID] = recipeIDs
end
end
return res
end
function NeiUI.doSearchByRecipeConfig(recipeConfigID, itemStack, fromOutput)
if fromOutput then
return RecipeUtils.SearchRecipeHasOutputItem(recipeConfigID, itemStack, 0)
else
return RecipeUtils.SearchRecipeHasInputItem(recipeConfigID, itemStack)
end
end
function NeiUI:onWindowResize()
NeiUI.super.onWindowResize(self)
self:_refreshSearchListData()
end
function NeiUI:closeWindow()
self._hkHelper:destroy()
NeiUI.super.closeWindow(self)
end
return NeiUI
================================================
FILE: ui/recipe_book/RecipeBookServer.lua
================================================
---@class TC.RecipeBookServer
local RecipeBookServer = class("RecipeBookServer")
---@param player Player
---@param inputInventory Inventory
---@param inputInventorySlotStartIndex int
---@param inputInventorySlotSize int
function RecipeBookServer:__init(recipeConfigID, player, inputInventory, inputInventorySlotStartIndex, inputInventorySlotSize)
self._recipeConfigID = recipeConfigID
self._playerIndex = player.entityIndex
self._inputInventory = inputInventory
self._inputInventorySlotStartIndex = inputInventorySlotStartIndex
self._inputInventorySlotSize = inputInventorySlotSize
end
function RecipeBookServer:FlushValidRecipe(recipeID)
if recipeID == nil then
return
end
local player = PlayerUtils.Get(self._playerIndex)
if player == nil then
return
end
print("Valid:", recipeID)
if recipeID <= 0 or recipeID > Reg.MaxRecipeID() then
return
end
-- all input slots are empty, move directly
if self:_IsInputSlotsAllEmpty() then
self:_InitSendRecipeInputItems(player, recipeID)
else
-- has input slots
local lastRecipeID = RecipeUtils.SearchRecipe(self._recipeConfigID,
self._inputInventory, self._inputInventorySlotStartIndex, self._inputInventorySlotSize)
if lastRecipeID ~= recipeID then
self:_SendBackAllInputItems(player)
self:_InitSendRecipeInputItems(player, recipeID)
else
self:_SendSameInputItems(player)
end
end
end
function RecipeBookServer:_SendSameInputItems(player)
local layouts = self:_GetBackpackLayouts(player)
if not self:_CanPeekSameInputs(layouts) then
return
end
for i = 1, self._inputInventorySlotSize do
self:_TryPeekAndAdd(i, player)
end
end
function RecipeBookServer:_CanPeekSameInputs(layouts)
local cache = {}
for i = self._inputInventorySlotStartIndex, self._inputInventorySlotStartIndex + self._inputInventorySlotSize - 1 do
local slot = self._inputInventory:GetSlot(i)
if slot.hasStack then
local stack = slot:GetStack()
local item = stack:GetItem()
local size = stack.stackSize
if size >= item.maxStackSize then
return false
end
local id = item.id
if cache[id] == nil then
cache[id] = 1
else
cache[id] = cache[id] + 1
end
end
end
for id, size in pairs(cache) do
if layouts[id] == nil then
return false
end
local sizeOwned = layouts[id][1]
if sizeOwned < size then
return false
end
end
return true
end
---@param player Player
---@param recipeID int
function RecipeBookServer:_InitSendRecipeInputItems(player, recipeID)
local recipe = RecipeUtils.GetRecipe(recipeID)
---@param ie RecipeInputSlot
for i, ie in each(recipe.inputs) do
if i <= self._inputInventorySlotSize then
if ie.type == RecipeInputSlotType.Item then
self:_TryPeekAndPushStack(i, player,{ ie.id }, ie.stackSize)
end
end
end
---@param ie RecipeInputSlot
for i, ie in each(recipe.inputs) do
if i <= self._inputInventorySlotSize then
if ie.type == RecipeInputSlotType.OreDictionary then
local ids = ItemUtils.GetOreDictionaryItemIDs(ie.id)
local peekItemIDs = {}
for _, id in each(ids) do
table.insert(peekItemIDs, id)
end
self:_TryPeekAndPushStack(i, player, peekItemIDs, ie.stackSize)
end
end
end
end
---_SendBackAllInputItems
---@param player Player
function RecipeBookServer:_SendBackAllInputItems(player)
local inventory = player.backpackInventory
for i = self._inputInventorySlotStartIndex, self._inputInventorySlotStartIndex + self._inputInventorySlotSize - 1 do
local slot = self._inputInventory:GetSlot(i)
if slot.hasStack then
local stack = slot:GetStack()
slot:ClearStack()
local remain = inventory:AddItemStack(stack)
if remain:Valid() then
player:DropItem(remain)
end
end
end
end
function RecipeBookServer:_TryPeekAndPushStack(i, player, peekItemIDs, stackSize)
local layouts = self:_GetBackpackLayouts(player)
--print(layouts)
local stack = self:_PeekStackFromBackpackLayouts(layouts, peekItemIDs, stackSize)
if stack ~= nil then
local slot = self._inputInventory:GetSlot(self._inputInventorySlotStartIndex + i - 1)
slot:PushStack(stack)
end
end
function RecipeBookServer:_TryPeekAndAdd(i, player)
local layouts = self:_GetBackpackLayouts(player)
local slot = self._inputInventory:GetSlot(self._inputInventorySlotStartIndex + i - 1)
if slot.hasStack then
local originalStack = slot:GetStack()
local stack = self:_PeekStackFromBackpackLayouts(layouts, { originalStack:GetItem().id }, 1)
if stack ~= nil then
originalStack:SetStackSize(originalStack.stackSize + 1)
end
end
end
-- key: item id, value: { total size, list of {slot, count}}
---@param player Player
function RecipeBookServer:_GetBackpackLayouts(player)
local res = {}
local inventory = player.backpackInventory
for i = 0, 49 do
local slot = inventory:GetSlot(i)
if slot.hasStack then
local stack = slot:GetStack()
local itemID = stack:GetItem().id
local info = { slot, stack.stackSize }
if res[itemID] == nil then
res[itemID] = { stack.stackSize, { info } }
else
local data = res[itemID]
data[1] = data[1] + stack.stackSize
table.insert(data[2], info)
end
end
end
return res
end
function RecipeBookServer:_PeekStackFromBackpackLayouts(layouts, peekItemIDs, peekCount)
assert(#peekItemIDs > 0 and peekCount > 0)
for i, itemID in ipairs(peekItemIDs) do
local data = layouts[itemID]
if data ~= nil then
if data[1] >= peekCount then
data[1] = data[1] - peekCount
local slots = data[2]
local remainPeekCount = peekCount
local resStack
for j = #slots, 1, -1 do
local info = slots[j]
local slot = info[1] ---@type Slot
local slotSize = info[2]
if resStack == nil then
resStack = slot:GetStack():Clone(peekCount)
end
if slotSize > remainPeekCount then
slot:DecrStackSize(remainPeekCount)
remainPeekCount = 0
else
slot:ClearStack()
remainPeekCount = remainPeekCount - slotSize
end
if remainPeekCount == 0 then
return resStack
end
end
end
end
end
return nil
end
function RecipeBookServer:_IsInputSlotsAllEmpty()
for i = self._inputInventorySlotStartIndex, self._inputInventorySlotStartIndex + self._inputInventorySlotSize - 1 do
local slot = self._inputInventory:GetSlot(i)
if slot.hasStack then
return false
end
end
return true
end
return RecipeBookServer
================================================
FILE: ui/recipe_book/RecipeBookUI.lua
================================================
---@class TC.RecipeBookUI:TC.UIWindow
local RecipeBookUI = class("RecipeBookUI", require("ui.UIWindow"))
local UIUtil = require("ui.UIUtil")
local UIDefault = require("ui.UIDefault")
---__init
---@param recipeConfigID int
---@param attachFrameworkNode UINode
---@param showing boolean
---@param listenedSlots Slot[]
---@param onClickedCallback table
---@param searchMask string
function RecipeBookUI:__init(recipeConfigID, attachFrameworkNode, showing, listenedSlots, onClickedCallback, searchMask)
RecipeBookUI.super.__init(self, require("ui.UIDesign").getRecipeBookUI())
self.DISPLAY_CNT_PRE_LINE = 5
self._recipeConfigID = recipeConfigID
self._rootLayer = self.root
self._panelList = self._rootLayer:getChild("panel_list")
self._itemOffsetSize = Size.new(UIDefault.CellHugeOffset, UIDefault.CellHugeOffset)
self.uiSize = self._rootLayer.size
self._itemIDExistDict = {}
self._recipeShowInventory = Inventory.new(0)
self._onRecipeShowChangedListener = {}
self._recipeCacheItemData = {}
self._validItemCount = 0
self._invalidItemCount = 0
self._totalItemCount = 0
self._attachFrameworkNode = attachFrameworkNode
self._listenedSlots = listenedSlots
self._onClickedCallback = onClickedCallback
self._searchMask = searchMask
self.showing = showing
self:_initContent()
end
function RecipeBookUI:_initContent()
local player = PlayerUtils.GetCurrentClientPlayer()
require("player.GPlayer").GetInstance(player).recipeBookHookUI = self
self:RefreshDisplayState()
end
function RecipeBookUI:SetDisplayState(showing)
self.showing = showing
self:RefreshDisplayState()
end
function RecipeBookUI:RefreshDisplayState()
self._rootLayer.visible = self.showing
if self.showing then
local OFFSET = 8
local totalWidth = self._attachFrameworkNode.width + self.uiSize.width + OFFSET
self._rootLayer.positionX = GameWindow.displayResolution.width / 2 - totalWidth / 2
self._attachFrameworkNode.positionX = self._rootLayer.positionX + self.uiSize.width + OFFSET
self:_refreshData()
self:_resetTable()
else
self._attachFrameworkNode.positionX = GameWindow.displayResolution.width / 2 - self._attachFrameworkNode.width / 2
end
end
function RecipeBookUI:SetOnRecipeChangedListener(callback, caller)
self._onRecipeShowChangedListener = { callback, caller }
end
function RecipeBookUI:_resetTable()
UIUtil.setTable(self._panelList, self, true, self.DISPLAY_CNT_PRE_LINE)
end
function RecipeBookUI:_getTableElementCount()
return self._recipeShowInventory.slotCount
end
function RecipeBookUI:_getTableElementPositionOffset()
return self._itemOffsetSize
end
---_setTableElement
---@param node UINode
---@param index number
function RecipeBookUI:_setTableElement(node, index)
node.tag = index
if index <= self._recipeShowInventory.slotCount then
local slot = self._recipeShowInventory:GetSlot(index - 1)
if slot.hasStack then
local itemID = slot:GetStack():GetItem().id
local data = self._recipeCacheItemData[itemID]
local validRecipeID = 0
if data ~= nil and #data.validRecipeIDs > 0 then
validRecipeID = data.validRecipeIDs[1]
end
UIUtil.setSlotStyle(node, validRecipeID > 0 and 4 or 3)
UIUtil.hookSlotView(node, slot)
if validRecipeID > 0 then
node:addTouchUpListener({ RecipeBookUI._OnValidRecipeClicked, self, validRecipeID })
else
node:addTouchUpListener({ RecipeBookUI._OnInvalidRecipeClicked, self, slot })
end
end
end
end
function RecipeBookUI:_OnValidRecipeClicked(recipeID)
self.manager:playClickSound()
print("Valid:", recipeID)
if self._onClickedCallback ~= nil and #self._onClickedCallback == 2 then
local func = self._onClickedCallback[1]
local obj = self._onClickedCallback[2]
func(obj, recipeID)
end
end
---_OnInvalidRecipeClicked
---@param slot Slot
function RecipeBookUI:_OnInvalidRecipeClicked(slot)
self.manager:playClickSound()
if slot.hasStack then
local stack = slot:GetStack()
local nei = require("ui.nei.NeiUI").new()
nei:trySearch(stack, true)
end
end
function RecipeBookUI:OnUpdate()
--print("BackpackUI:OnUpdate!!")
end
function RecipeBookUI:OnClose()
require("player.GPlayer").GetInstance().recipeBookHookUI = nil
self.ui:closeWindow()
end
function RecipeBookUI:_refreshData()
local tempItemIDAndSizes = {}
---@param slot Slot
for _, slot in ipairs(self._listenedSlots) do
if slot.hasStack then
local itemID = slot:GetStack():GetItem().id
if tempItemIDAndSizes[itemID] == nil then
tempItemIDAndSizes[itemID] = slot:GetStack().stackSize
else
tempItemIDAndSizes[itemID] = tempItemIDAndSizes[itemID] + slot:GetStack().stackSize
end
end
end
local needToSearch = false
local tempCount = 0
local oldCount = 0
for _, _ in pairs(tempItemIDAndSizes) do
tempCount = tempCount + 1
end
for _, _ in pairs(self._itemIDExistDict) do
oldCount = oldCount + 1
end
if tempCount ~= oldCount then
needToSearch = true
else
for id, size in pairs(tempItemIDAndSizes) do
if not self._itemIDExistDict[id] then
needToSearch = true
break
elseif self._itemIDExistDict[id] ~= size then
needToSearch = true
break
end
end
end
if needToSearch then
self._validItemCount = 0
self._invalidItemCount = 0
self._totalItemCount = 0
self._recipeCacheItemData = {}
self._itemIDExistDict = tempItemIDAndSizes
local allRecipeIDExists = {}
-- search all recipe by every slot
local configID = self._recipeConfigID
---@param slot Slot
for _, slot in ipairs(self._listenedSlots) do
if slot.hasStack then
local results = RecipeUtils.SearchRecipeHasInputItem(configID, slot:GetStack())
for _, recipeID in pairs(results) do
local recipe = RecipeUtils.GetRecipe(recipeID)
if recipe:IsValidByMask(self._searchMask) then
allRecipeIDExists[recipeID] = true
end
end
end
end
local validRecipeIDs = {}
local invalidRecipeIDs = {}
for recipeID, _ in pairs(allRecipeIDExists) do
local temps = clone(self._itemIDExistDict)
local recipe = RecipeUtils.GetRecipe(recipeID)
local valid = true
-- first, check the fix item input
---@param ie RecipeInputSlot
for _, ie in each(recipe.inputs) do
if ie.type == RecipeInputSlotType.Item then
local itemID = ie.itemStack:GetItem().id
local size = ie.itemStack.stackSize
local tempSize = temps[itemID]
if tempSize == nil then
valid = false
break
elseif tempSize > size then
temps[itemID] = tempSize - size
elseif tempSize == size then
temps[itemID] = nil
else
valid = false
break
end
end
end
if valid then
-- second, check the ore dictionary
---@param ie RecipeInputSlot
for _, ie in each(recipe.inputs) do
if ie.type == RecipeInputSlotType.OreDictionary then
local ids = ItemUtils.GetOreDictionaryItemIDs(ie.id)
local checkSize = ie.stackSize
for _, subItemID in each(ids) do
local tempSize = temps[subItemID]
if tempSize ~= nil then
if tempSize > checkSize then
temps[subItemID] = tempSize - checkSize
checkSize = 0
elseif tempSize == checkSize then
temps[subItemID] = nil
checkSize = 0
else
checkSize = checkSize - tempSize
temps[subItemID] = nil
end
end
if checkSize <= 0 then
break
end
end
if checkSize > 0 then
valid = false
break
end
end
end
end
if valid then
table.insert(validRecipeIDs, recipeID)
else
local canDisplay = false
-- check if contains recipe important input element
---@param ie RecipeInputSlot
for _, ie in each(recipe.inputs) do
if ie.isImportant then
if ie.type == RecipeInputSlotType.Item then
local itemID = ie.itemStack:GetItem().id
if self._itemIDExistDict[itemID] ~= nil then
canDisplay = true
break
end
elseif ie.type == RecipeInputSlotType.OreDictionary then
local ids = ItemUtils.GetOreDictionaryItemIDs(ie.id)
for _, subItemID in each(ids) do
if self._itemIDExistDict[subItemID] ~= nil then
canDisplay = true
break
end
end
if canDisplay then
break
end
end
end
end
if canDisplay then
table.insert(invalidRecipeIDs, recipeID)
end
end
end
local validItemStacks = {}
local validItemCount = 0
local invalidItemStacks = {}
local invalidItemCount = 0
local function doCacheData(recipeID, isCacheValidItem)
local recipe = RecipeUtils.GetRecipe(recipeID)
local stack = recipe.outputs[1]:GetStack()
local itemID = stack:GetItem().id
if self._recipeCacheItemData[itemID] == nil then
local resStack = stack:Clone()
resStack:SetStackSize(1)
if isCacheValidItem then
validItemStacks[itemID] = resStack
validItemCount = validItemCount + 1
else
invalidItemStacks[itemID] = resStack
invalidItemCount = invalidItemCount + 1
end
self._recipeCacheItemData[itemID] = {
itemStack = resStack,
validRecipeIDs = {},
invalidRecipeIDs = {}
}
end
if isCacheValidItem then
table.insert(self._recipeCacheItemData[itemID].validRecipeIDs, recipeID)
else
table.insert(self._recipeCacheItemData[itemID].invalidRecipeIDs, recipeID)
end
end
for _, recipeID in pairs(validRecipeIDs) do
doCacheData(recipeID, true)
end
for _, recipeID in pairs(invalidRecipeIDs) do
doCacheData(recipeID, false)
end
self._recipeShowInventory:SetSlotCount(validItemCount + invalidItemCount)
local index = 0
for _, itemStack in pairs(validItemStacks) do
self._recipeShowInventory:GetSlot(index):PushStack(itemStack)
index = index + 1
end
self._recipeShowInventory:Sort(0, validItemCount)
for _, itemStack in pairs(invalidItemStacks) do
self._recipeShowInventory:GetSlot(index):PushStack(itemStack)
index = index + 1
end
self._recipeShowInventory:Sort(validItemCount, invalidItemCount)
self._validItemCount = validItemCount
self._invalidItemCount = invalidItemCount
self._totalItemCount = self._validItemCount + self._invalidItemCount
--self._recipeShowInventory:Sort(0, self._totalItemCount)
if #self._onRecipeShowChangedListener == 2 then
local caller = self._onRecipeShowChangedListener[2]
local callback = self._onRecipeShowChangedListener[1]
callback(caller)
end
print("Valid:", validItemCount, "Invalid:", invalidItemCount)
end
end
return RecipeBookUI
================================================
FILE: ui/repair/RepairContainerClient.lua
================================================
---@class TC.RepairContainerClient:Container
local RepairContainerClient = class("RepairContainerClient", Container)
local ContainerHelper = require("ui.ContainerHelper")
function RepairContainerClient:__init(player, xi, yi)
RepairContainerClient.super.__init(self)
self.TOTAL_SLOT = 50 + 3
self.tempSlots = Inventory.new(self.TOTAL_SLOT)
ContainerHelper.ContainerClientInitSlots(self, self.tempSlots)
self.dataChangedCallback = nil
self.needExpLevel = 0
end
function RepairContainerClient:OnReceiveChange(id, value)
if id == 0 then
self.needExpLevel = value
end
end
return RepairContainerClient
================================================
FILE: ui/repair/RepairContainerServer.lua
================================================
---@class TC.RepairContainerServer:Container
local RepairContainerServer = class("RepairContainerServer", Container)
local ContainerHelper = require("ui.ContainerHelper")
local UIData = require("RepairUIData")
local RecipeBookServer = require("ui.recipe_book.RecipeBookServer")
local REPAIR_SLOT_COUNT = 3
local REPAIR_OUTPUT_INDEX = 2
---__init
---@param player Player
---@param xi int
---@param yi int
function RepairContainerServer:__init(player, xi, yi)
RepairContainerServer.super.__init(self)
self.playerIndex = player.entityIndex
self.inventory = player.backpackInventory
self.xi = xi
self.yi = yi
-- 0-49 inventory
ContainerHelper.ContainerServerAddBackpack(player, self)
self._tempSlots = Inventory.new(REPAIR_SLOT_COUNT)
self._toolSlot = self._tempSlots:GetSlot(0)
self._sourceSlot = self._tempSlots:GetSlot(1)
self._outputSlot = self._tempSlots:GetSlot(2)
self._needExpLevel = 0
for i = 0, REPAIR_SLOT_COUNT - 1 do
local slot = self._tempSlots:GetSlot(i)
self:AddSlotToContainer(self._tempSlots, i)
if i ~= REPAIR_OUTPUT_INDEX then
slot:AddOnPickListener({ RepairContainerServer.OnChanged, self })
slot:AddOnPushListener({ RepairContainerServer.OnChanged, self })
end
end
self.recipeBookServer = RecipeBookServer.new(
Reg.RecipeConfigID("Repair"),
player, self._tempSlots, 0, 2)
end
function RepairContainerServer:OnChanged()
self:_OnFlushData()
end
function RepairContainerServer:_OnFlushData()
self._outputSlot:ClearStack()
if self._toolSlot.hasStack and self._sourceSlot.hasStack then
local toolStack = self._toolSlot:GetStack()
local toolItem = toolStack:GetItem()
if toolItem.isTool then
local sourceStack = self._sourceSlot:GetStack()
local sourceItem = sourceStack:GetItem()
-- repair by an enchantment book
if sourceItem.id == Reg.ItemID("enchanted_book") then
local wasteLevel = 0.0
for i = 0, toolStack.enchantmentCount - 1 do
local enchantment = toolStack:GetEnchantmentByIndex(i)
local enchantmentData = EnchantmentUtils.GetData(enchantment.id)
wasteLevel = wasteLevel + (enchantmentData.minCreatingLevel + enchantment.level) * 0.25
end
self._needExpLevel = math.max(1, math.ceil(wasteLevel))
else
local recipeID = RecipeUtils.SearchRecipe(Reg.RecipeConfigID("Repair"), self._tempSlots, 0, 2)
if recipeID > 0 then
local recipe = RecipeUtils.GetRecipe(recipeID)
local recipeOutputSlot = recipe.outputs[1]
if recipeOutputSlot.hasStack then
local recipeInputToolElement = recipe.inputs[1]
local isFixDurable = false
local isCrafting = false
if recipeInputToolElement.type == RecipeInputSlotType.Item and
recipeInputToolElement.id == recipeOutputSlot:GetStack():GetItem().id then
isFixDurable = true
else
isCrafting = true
end
local outputStack
if isFixDurable then
local repairRate = recipe.exData.repairRate
outputStack = toolStack:Clone()
outputStack:AddDurable(toolItem.maxDurable * repairRate)
elseif isCrafting then
outputStack = recipeOutputSlot:GetStack():Clone()
local outputItem = outputStack:GetItem()
local rate
if toolItem.maxDurable > 0 then
rate = toolStack.durable / toolItem.maxDurable
else
rate = 1.0
end
outputStack:SetDurable(outputItem.maxDurable * rate)
end
self._outputSlot:PushStack(outputStack)
end
end
end
end
end
self:_SendData()
end
function RepairContainerServer:_SendData()
self:DetectAndSendChangeInteger(0, self._needExpLevel)
end
function RepairContainerServer:OnEvent(eventId, eventString)
if eventId == UIData.EventID.PickOutput then
self:TryPickOutput()
elseif eventId == UIData.EventID.RecipeBookRequest then
local recipeID = tonumber(eventString)
self.recipeBookServer:FlushValidRecipe(recipeID)
end
end
function RepairContainerServer:TryPickOutput()
if not PlayerUtils.IsAlive(self.playerIndex) then
return
end
local player = PlayerUtils.Get(self.playerIndex)
local inventory = player.backpackInventory
if self._outputSlot.hasStack then
local outStack = inventory:AddItemStack(self._outputSlot:GetStack())
if outStack:Valid() then
player:DropItem(outStack)
end
self._outputSlot:ClearStack()
end
self._toolSlot:DecrStackSize(1)
self._sourceSlot:DecrStackSize(1)
self:OnChanged()
end
function RepairContainerServer:CanInteractWith(player)
local ok = ContainerHelper.InInteractDistance(player, self.xi, self.yi)
return ok
end
function RepairContainerServer:OnClose()
ContainerHelper.CloseSendBackItems(self.playerIndex,
self.xi, self.yi, self._tempSlots,
{ 0, 1 })
self._outputSlot:ClearStack()
end
return RepairContainerServer
================================================
FILE: ui/repair/RepairUI.lua
================================================
---@class TC.RepairUI:GuiContainer
local RepairUI = class("RepairUI", GuiContainer)
local UIUtil = require("ui.UIUtil")
local GuiID = require("ui.GuiID")
local UIData = require("RepairUIData")
local HotkeyUIHelper = require("ui.HotkeyUIHelper")
---@param container TC.RepairContainerClient
function RepairUI:__init(container)
RepairUI.super.__init(self, container)
self.repairContainer = container
self.repairContainer.dataChangedCallback = { self._OnDataChanged, self }
self.ui = require("ui.UIWindow").new(require("ui.UIDesign").getRepairUI(), require("ui.UIDefault").GROUP_GAME_WINDOW)
self.rootLayer = self.ui.root:getChild("layer")
local listenSlots = {}
for i = 0, 49 do
table.insert(listenSlots, self.repairContainer.tempSlots:GetSlot(i))
end
for i = 50, 51 do
table.insert(listenSlots, self.repairContainer.tempSlots:GetSlot(i))
end
table.insert(listenSlots, PlayerUtils.GetCurrentClientPlayer().mouseInventory:GetSlot(0))
self.recipeBookUI = require("ui.recipe_book.RecipeBookUI").new(
Reg.RecipeConfigID("Repair"),
self.rootLayer, false, listenSlots,
{ self._onValidRecipeClicked, self },
"11"
)
self._hkHelper = HotkeyUIHelper.new(Mod.current, GuiID.Repair)
self:_initContent()
end
function RepairUI:_initContent()
local maxSlots = self.container:GetSlotCount()
for i = 1, maxSlots do
local tag = i - 1
if tag == 52 then
local outputNode = self.rootLayer:getChildByTag(tag)
local outputSlot = self.repairContainer.tempSlots:GetSlot(tag)
UIUtil.hookSlotView(outputNode, outputSlot, true)
outputNode:addTouchUpListener({ self._onOutputClicked, self, outputSlot })
else
UIUtil.hookSlot(self.rootLayer:getChildByTag(tag), self, tag)
end
end
self.rootLayer:getChild("btn_recipe"):addTouchUpListener({ self._onRecipeTriggerClicked, self })
self.ui.root:addTouchUpListener({ self.OnBgClicked, self })
end
function RepairUI:_onValidRecipeClicked(recipeID)
self:TriggerServerEvent(UIData.EventID.RecipeBookRequest, tostring(recipeID))
end
function RepairUI:_onRecipeTriggerClicked()
self.recipeBookUI:SetDisplayState(not self.recipeBookUI.showing)
self.ui.manager:playClickSound()
end
---@param slot Slot
function RepairUI:_onOutputClicked(slot)
if slot.hasStack then
self.ui.manager:playClickSound()
self:TriggerServerEvent(UIData.EventID.PickOutput)
end
end
function RepairUI:_OnDataChanged()
end
function RepairUI:OnBgClicked()
if require("ui.UISlotOp").onCheckPCDropOutItem() then
return
end
local player = PlayerUtils.GetCurrentClientPlayer()
if player then
player:CloseGui(Mod.current, GuiID.Repair)
end
end
function RepairUI:OnClose()
self._hkHelper:destroy()
self.ui:closeWindow()
self.recipeBookUI:closeWindow()
end
---checkSlotShiftMove
---@param slotIndex int
---@param itemStack ItemStack
function RepairUI:checkSlotShiftMove(slotIndex, itemStack)
if slotIndex < 10 then
-- shortcut to backpack
return self.container, 10, 40
elseif slotIndex < 50 then
-- backpack to shortcut
return self.container, 0, 10
end
end
return RepairUI
================================================
FILE: ui/repair/RepairUIData.lua
================================================
local RepairUIData = {
EventID = { PickOutput = 1, RecipeBookRequest = 2, },
}
return RepairUIData
================================================
FILE: ui/shooter/IShooterContainerClient.lua
================================================
---@class TC.IShooterContainerClient:Container
local IShooterContainerClient = class("IShooterContainerClient", Container)
local ContainerHelper = require("ui.ContainerHelper")
function IShooterContainerClient:__init(slotCount, player, xi, yi)
IShooterContainerClient.super.__init(self)
self.TOTAL_SLOT = slotCount + 50
self.tempSlots = Inventory.new(self.TOTAL_SLOT)
ContainerHelper.ContainerClientInitSlots(self, self.tempSlots)
end
return IShooterContainerClient
================================================
FILE: ui/shooter/IShooterContainerServer.lua
================================================
---@class TC.IShooterContainerServer:Container
local IShooterContainerServer = class("IChestContainerServer", Container)
local ContainerHelper = require("ui.ContainerHelper")
---__init
---@param slotCount int
---@param blockEntityName string
---@param player Player
---@param xi int
---@param yi int
function IShooterContainerServer:__init(slotCount, blockEntityName, player, xi, yi)
IShooterContainerServer.super.__init(self)
self.playerIndex = player.entityIndex
self.backpackInventory = player.backpackInventory
self.xi = xi
self.yi = yi
-- 0-49 inventory
ContainerHelper.ContainerServerAddBackpack(player, self)
self.slotCount = slotCount
self.blockEntityName = blockEntityName
---@type Inventory
self.shooterInventory = self:GetMyEntity().inventory
for i = 1, slotCount do
self:AddSlotToContainer(self.shooterInventory, i - 1)
end
end
function IShooterContainerServer:GetMyEntity()
local blockEntity = MapUtils.GetBlockEntity(Reg.BlockEntityID(self.blockEntityName), self.xi, self.yi)
if blockEntity == nil then
return nil
end
---@type TC.IShooterEntity
local modEntity = blockEntity:GetModBlockEntity()
return modEntity
end
function IShooterContainerServer:CanInteractWith(player)
if self:GetMyEntity() == nil then
return false
end
return ContainerHelper.InInteractDistance(player, self.xi, self.yi)
end
return IShooterContainerServer
================================================
FILE: ui/shooter/IShooterUI.lua
================================================
---@class TC.IShooterUI:GuiContainer
local IShooterUI = class("IShooterUI", GuiContainer)
local UIUtil = require("ui.UIUtil")
local GuiID = require("ui.GuiID")
local HotkeyUIHelper = require("ui.HotkeyUIHelper")
---@param container TC.IChestContainerClient
function IShooterUI:__init(rootNode, container)
IShooterUI.super.__init(self, container)
self.ui = require("ui.UIWindow").new(rootNode, require("ui.UIDefault").GROUP_GAME_WINDOW)
self.rootLayer = self.ui.root:getChild("layer")
self._hkHelper = HotkeyUIHelper.new(Mod.current, GuiID.Shooter9)
self:_innerInitContent()
end
function IShooterUI:_innerInitContent()
local maxSlots = self.container:GetSlotCount()
for i = 1, maxSlots do
UIUtil.hookSlot(self.rootLayer:getChildByTag(i - 1), self, i - 1)
end
end
function IShooterUI:OnClose()
self._hkHelper:destroy()
self.ui:closeWindow()
end
return IShooterUI
================================================
FILE: ui/shooter/Shooter9ContainerClient.lua
================================================
---@class TC.Shooter9ContainerClient:TC.IShooterContainerClient
local Shooter9ContainerClient = class("Shooter9ContainerClient", require("IShooterContainerClient"))
function Shooter9ContainerClient:__init(player, xi, yi)
Shooter9ContainerClient.super.__init(self, 9, player, xi, yi)
end
return Shooter9ContainerClient
================================================
FILE: ui/shooter/Shooter9ContainerServer.lua
================================================
---@class TC.Shooter9ContainerServer:TC.IShooterContainerServer
local Shooter9ContainerServer = class("Shooter9ContainerServer", require("IShooterContainerServer"))
---__init
---@param player Player
---@param xi int
---@param yi int
function Shooter9ContainerServer:__init(player, xi, yi)
Shooter9ContainerServer.super.__init(self, 9, "Shooter9Entity", player, xi, yi)
end
return Shooter9ContainerServer
================================================
FILE: ui/shooter/Shooter9UI.lua
================================================
---@class TC.Shooter9UI:TC.IShooterUI
local Shooter9UI = class("Shooter9UI", require("IShooterUI"))
---@param container TC.Shooter9ContainerClient
function Shooter9UI:__init(container)
Shooter9UI.super.__init(self, require("ui.UIDesign").getShooter9UI(), container)
end
return Shooter9UI
================================================
FILE: ui/smelt/SmeltContainerClient.lua
================================================
---@class TC.SmeltContainerClient:Container
local SmeltContainerClient = class("SmeltContainerClient", Container)
local ContainerHelper = require("ui.ContainerHelper")
function SmeltContainerClient:__init(player, xi, yi)
SmeltContainerClient.super.__init(self)
self.cookProgress = 0
self.burnProgress = 0
self.TOTAL_SLOT = 54
self.tempSlots = Inventory.new(self.TOTAL_SLOT)
ContainerHelper.ContainerClientInitSlots(self, self.tempSlots)
end
function SmeltContainerClient:OnEvent(eventId, eventString)
end
function SmeltContainerClient:OnUpdate()
end
function SmeltContainerClient:OnClose()
end
function SmeltContainerClient:OnReceiveChange(id, value)
if id == 0 then
self.cookProgress = value
elseif id == 1 then
self.burnProgress = value
end
end
function SmeltContainerClient:CanInteractWith(player)
return true
end
return SmeltContainerClient
================================================
FILE: ui/smelt/SmeltContainerServer.lua
================================================
---@class TC.SmeltContainerServer:Container
local SmeltContainerServer = class("SmeltContainerServer", Container)
local UIData = require("SmeltUIData")
local ContainerHelper = require("ui.ContainerHelper")
local RecipeBookServer = require("ui.recipe_book.RecipeBookServer")
---__init
---@param player Player
---@param xi int
---@param yi int
function SmeltContainerServer:__init(player, xi, yi)
SmeltContainerServer.super.__init(self)
self.playerIndex = player.entityIndex
self.xi = xi
self.yi = yi
-- 0-49 inventory
ContainerHelper.ContainerServerAddBackpack(player, self)
local smeltEntity = self:GetSmeltEntity()
for i = 0, 3 do
local slot = smeltEntity.inventory:GetSlot(i)
self:AddSlotToContainer(smeltEntity.inventory, i)
if i ~= 2 then
slot:AddOnPickListener({ SmeltContainerServer.OnChanged, self })
slot:AddOnPushListener({ SmeltContainerServer.OnChanged, self })
end
end
self.recipeBookServer = RecipeBookServer.new(
Reg.RecipeConfigID("Smelt"),
player, smeltEntity.inventory, 0, 1)
end
function SmeltContainerServer:GetSmeltEntity()
local blockEntity = MapUtils.GetBlockEntity(Reg.BlockEntityID("SmeltEntity"), self.xi, self.yi)
if blockEntity == nil then
return nil
end
---@type TC.SmeltEntity
local smeltEntity = blockEntity:GetModBlockEntity()
return smeltEntity
end
function SmeltContainerServer:OnChanged()
local smeltEntity = self:GetSmeltEntity()
if smeltEntity then
smeltEntity:FlushRecipeData()
end
end
function SmeltContainerServer:OnDetectChange()
local smeltEntity = self:GetSmeltEntity()
if smeltEntity then
local cookProgress = 0
local burnProgress = 0
if smeltEntity.totalCookTime > 0 then
cookProgress = math.ceil(smeltEntity.cookedTime * 16.0 / smeltEntity.totalCookTime)
cookProgress = math.min(math.max(cookProgress, 0), 16)
end
if smeltEntity.burnTotalTime > 0 then
burnProgress = math.ceil(smeltEntity.burnTime * 16.0 / smeltEntity.burnTotalTime)
burnProgress = math.min(math.max(burnProgress, 0), 16)
end
self:DetectAndSendChangeInteger(0, cookProgress)
self:DetectAndSendChangeInteger(1, burnProgress)
end
end
function SmeltContainerServer:OnEvent(eventId, eventString)
if eventId == UIData.EventID.RecipeBookRequest then
local recipeID = tonumber(eventString)
self.recipeBookServer:FlushValidRecipe(recipeID)
elseif eventId == UIData.EventID.PickOutput then
self:TryPickOutput()
end
end
function SmeltContainerServer:TryPickOutput()
if not PlayerUtils.IsAlive(self.playerIndex) then
return
end
local player = PlayerUtils.Get(self.playerIndex)
local smeltEntity = self:GetSmeltEntity()
if smeltEntity == nil then
return
end
local inventory = player.backpackInventory
local outputSlot = smeltEntity.inventory:GetSlot(2)
if outputSlot.hasStack then
local outStack = inventory:AddItemStack(outputSlot:GetStack())
if outStack:Valid() then
player:DropItem(outStack)
end
outputSlot:ClearStack()
end
self:OnChanged()
end
function SmeltContainerServer:CanInteractWith(player)
if self:GetSmeltEntity() == nil then
return false
end
local ok = ContainerHelper.InInteractDistance(player, self.xi, self.yi)
return ok
end
return SmeltContainerServer
================================================
FILE: ui/smelt/SmeltUI.lua
================================================
---@class TC.SmeltUI:GuiContainer
local SmeltUI = class("SmeltUI", GuiContainer)
local UIUtil = require("ui.UIUtil")
local GuiID = require("ui.GuiID")
local UIData = require("SmeltUIData")
local HotkeyUIHelper = require("ui.HotkeyUIHelper")
---@param container TC.SmeltContainerClient
function SmeltUI:__init(container)
SmeltUI.super.__init(self, container)
self.smeltContainer = container
self.ui = require("ui.UIWindow").new(require("ui.UIDesign").getSmeltUI(), require("ui.UIDefault").GROUP_GAME_WINDOW)
self.rootLayer = self.ui.root:getChild("layer")
local listenSlots = {}
for i = 0, 49 do
table.insert(listenSlots, self.smeltContainer.tempSlots:GetSlot(i))
end
table.insert(listenSlots, self.smeltContainer.tempSlots:GetSlot(50))
table.insert(listenSlots, PlayerUtils.GetCurrentClientPlayer().mouseInventory:GetSlot(0))
self.recipeBookUI = require("ui.recipe_book.RecipeBookUI").new(
Reg.RecipeConfigID("Smelt"),
self.rootLayer, false, listenSlots,
{ self._onValidRecipeClicked, self },
"1"
)
self._hkHelper = HotkeyUIHelper.new(Mod.current, GuiID.Smelt)
self:_initContent()
end
function SmeltUI:_initContent()
local maxSlots = self.container:GetSlotCount()
for i = 1, maxSlots do
local tag = i - 1
if tag == 52 then
local outputNode = self.rootLayer:getChildByTag(tag)
local outputSlot = self.smeltContainer.tempSlots:GetSlot(tag)
UIUtil.hookSlotView(outputNode, outputSlot, true)
outputNode:addTouchUpListener({ self._onOutputClicked, self, outputSlot })
else
UIUtil.hookSlot(self.rootLayer:getChildByTag(tag), self, tag)
end
end
self.rootLayer:getChild("img_cook"):getPostDrawLayer(0):addListener({ SmeltUI.OnRenderCookProgress, self })
self.rootLayer:getChild("img_burn"):getPostDrawLayer(0):addListener({ SmeltUI.OnRenderBurnProgress, self })
self.rootLayer:getChild("btn_recipe"):addTouchUpListener({ self._onRecipeTriggerClicked, self })
self.ui.root:addTouchUpListener({ self.OnBgClicked, self })
end
---@param slot Slot
function SmeltUI:_onOutputClicked(slot)
if slot.hasStack then
self.ui.manager:playClickSound()
self:TriggerServerEvent(UIData.EventID.PickOutput)
end
end
function SmeltUI:_onValidRecipeClicked(recipeID)
self:TriggerServerEvent(UIData.EventID.RecipeBookRequest, tostring(recipeID))
end
function SmeltUI:_onRecipeTriggerClicked()
self.recipeBookUI:SetDisplayState(not self.recipeBookUI.showing)
self.ui.manager:playClickSound()
end
---OnRenderCookProgress
---@param node UINode
---@param canvasPos Vector2
function SmeltUI:OnRenderCookProgress(node, canvasPos)
UIUtil.renderProgress("tc:process_01",
node.positionInCanvas + canvasPos,
self.smeltContainer.cookProgress,
16,
1, 0)
end
---
---@param node UINode
---@param canvasPos Vector2
function SmeltUI:OnRenderBurnProgress(node, canvasPos)
UIUtil.renderProgress("tc:burn_01",
node.positionInCanvas + canvasPos,
self.smeltContainer.burnProgress,
16,
0, -1)
end
function SmeltUI:OnBgClicked()
if require("ui.UISlotOp").onCheckPCDropOutItem() then
return
end
local player = PlayerUtils.GetCurrentClientPlayer()
if player then
player:CloseGui(Mod.current, GuiID.Smelt)
end
end
function SmeltUI:OnUpdate()
end
function SmeltUI:OnClose()
self._hkHelper:destroy()
self.ui:closeWindow()
self.recipeBookUI:closeWindow()
end
---checkSlotShiftMove
---@param slotIndex int
---@param itemStack ItemStack
function SmeltUI:checkSlotShiftMove(slotIndex, itemStack)
if slotIndex < 10 then
-- shortcut to backpack
return self.container, 10, 40
elseif slotIndex < 50 then
-- backpack to shortcut
return self.container, 0, 10
end
end
return SmeltUI
================================================
FILE: ui/smelt/SmeltUIData.lua
================================================
local BackpackUIData = {
EventID = { RecipeBookRequest = 1, PickOutput = 2, },
}
return BackpackUIData
================================================
FILE: ui_res/advance_tip.json
================================================
{
"textureInfo": {
"name": "tc:advance_tip"
},
"style": "Slices9",
"slices9": {
"left": 20,
"right": 20,
"top": 20,
"bottom": 20
}
}
================================================
FILE: ui_res/advancement_cell.json
================================================
{
"textureInfo": {
"name": "tc:advancement_cell"
},
"style": "Slices9",
"slices9": {
"left": 8,
"right": 8,
"top": 8,
"bottom": 8
}
}
================================================
FILE: ui_res/base.json
================================================
{
"textureInfo": {
"name": "tc:base"
},
"style": "Slices9",
"slices9": {
"left": 16,
"right": 16,
"top": 16,
"bottom": 16
}
}
================================================
FILE: ui_res/base2.json
================================================
{
"textureInfo": {
"name": "tc:base2"
},
"style": "Slices9",
"slices9": {
"left": 16,
"right": 16,
"top": 16,
"bottom": 16
}
}
================================================
FILE: ui_res/base3.json
================================================
{
"textureInfo": {
"name": "tc:base3"
},
"style": "Slices9",
"slices9": {
"left": 16,
"right": 16,
"top": 16,
"bottom": 16
}
}
================================================
FILE: ui_res/base_list_cell.json
================================================
{
"textureInfo": {
"name": "tc:base_list_cell"
},
"style": "Slices9",
"slices9": {
"left": 16,
"right": 16,
"top": 16,
"bottom": 16
}
}
================================================
FILE: ui_res/base_list_cell_highlight.json
================================================
{
"textureInfo": {
"name": "tc:base_list_cell_highlight"
},
"style": "Slices9",
"slices9": {
"left": 16,
"right": 16,
"top": 16,
"bottom": 16
}
}
================================================
FILE: ui_res/base_list_cell_highlight_2.json
================================================
{
"textureInfo": {
"name": "tc:base_list_cell_highlight"
},
"style": "Slices9",
"slices9": {
"left": 16,
"right": 16,
"top": 16,
"bottom": 16
}
}
================================================
FILE: ui_res/black.json
================================================
{
"textureInfo": {
"name": "tc:black"
},
"style": "Filled"
}
================================================
FILE: ui_res/button_disabled.json
================================================
{
"textureInfo": {
"name": "tc:button_disabled"
},
"style": "Slices9",
"slices9": {
"left": 16,
"right": 16,
"top": 16,
"bottom": 16
}
}
================================================
FILE: ui_res/button_highlight.json
================================================
{
"textureInfo": {
"name": "tc:button_highlight"
},
"style": "Slices9",
"slices9": {
"left": 16,
"right": 16,
"top": 16,
"bottom": 16
}
}
================================================
FILE: ui_res/button_normal.json
================================================
{
"textureInfo": {
"name": "tc:button_normal"
},
"style": "Slices9",
"slices9": {
"left": 16,
"right": 16,
"top": 16,
"bottom": 16
}
}
================================================
FILE: ui_res/button_pressed.json
================================================
{
"textureInfo": {
"name": "tc:button_pressed"
},
"style": "Slices9",
"slices9": {
"left": 16,
"right": 16,
"top": 16,
"bottom": 16
}
}
================================================
FILE: ui_res/cell_empty.json
================================================
{
"textureInfo": {
"name": "tc:cell_empty"
},
"style": "Slices9",
"slices9": {
"left": 16,
"right": 16,
"top": 16,
"bottom": 16
}
}
================================================
FILE: ui_res/cell_empty_2.json
================================================
{
"textureInfo": {
"name": "tc:cell_empty_2"
},
"style": "Slices9",
"slices9": {
"left": 16,
"right": 16,
"top": 16,
"bottom": 16
}
}
================================================
FILE: ui_res/cell_empty_3.json
================================================
{
"textureInfo": {
"name": "tc:cell_empty_3"
},
"style": "Slices9",
"slices9": {
"left": 16,
"right": 16,
"top": 16,
"bottom": 16
}
}
================================================
FILE: ui_res/cell_empty_4.json
================================================
{
"textureInfo": {
"name": "tc:cell_empty_4"
},
"style": "Slices9",
"slices9": {
"left": 16,
"right": 16,
"top": 16,
"bottom": 16
}
}
================================================
FILE: ui_res/cell_normal.json
================================================
{
"textureInfo": {
"name": "tc:cell_normal"
},
"style": "Slices9",
"slices9": {
"left": 16,
"right": 16,
"top": 16,
"bottom": 16
}
}
================================================
FILE: ui_res/cell_selected.json
================================================
{
"textureInfo": {
"name": "tc:cell_selected"
},
"style": "Slices9",
"slices9": {
"left": 16,
"right": 16,
"top": 16,
"bottom": 16
}
}
================================================
FILE: ui_res/cell_selected_2.json
================================================
{
"textureInfo": {
"name": "tc:cell_selected_2"
},
"style": "Slices9",
"slices9": {
"left": 16,
"right": 16,
"top": 16,
"bottom": 16
}
}
================================================
FILE: ui_res/cell_selected_3.json
================================================
{
"textureInfo": {
"name": "tc:cell_selected_3"
},
"style": "Slices9",
"slices9": {
"left": 16,
"right": 16,
"top": 16,
"bottom": 16
}
}
================================================
FILE: ui_res/cell_selected_4.json
================================================
{
"textureInfo": {
"name": "tc:cell_selected_4"
},
"style": "Slices9",
"slices9": {
"left": 16,
"right": 16,
"top": 16,
"bottom": 16
}
}
================================================
FILE: ui_res/round_rect_white.json
================================================
{
"textureInfo": {
"name": "tc:round_rect_white"
},
"style": "Slices9",
"slices9": {
"left": 16,
"right": 16,
"top": 16,
"bottom": 16
}
}
================================================
FILE: ui_res/tab.json
================================================
{
"textureInfo": {
"name": "tc:tab"
},
"style": "Slices9",
"slices9": {
"left": 16,
"right": 16,
"top": 16,
"bottom": 16
}
}
================================================
FILE: ui_res/tab_clicked.json
================================================
{
"textureInfo": {
"name": "tc:tab_clicked"
},
"style": "Slices9",
"slices9": {
"left": 16,
"right": 16,
"top": 16,
"bottom": 16
}
}
================================================
FILE: ui_res/tipbox.json
================================================
{
"textureInfo": {
"name": "tc:tipbox"
},
"style": "Slices9",
"slices9": {
"left": 16,
"right": 16,
"top": 16,
"bottom": 16
}
}
================================================
FILE: ui_res/white.json
================================================
{
"textureInfo": {
"name": "tc:white"
},
"style": "Filled"
}
================================================
FILE: ui_res/white_circle.json
================================================
{
"textureInfo": {
"name": "tc:white_circle"
},
"style": "Filled"
}
================================================
FILE: ui_res/window_frame_01.json
================================================
{
"textureInfo": {
"name": "tc:window_frame_01"
},
"style": "Slices9",
"slices9": {
"left": 16,
"right": 16,
"top": 16,
"bottom": 16
}
}
================================================
FILE: util/Algorithm.lua
================================================
local Algorithm = class("Algorithm")
--- make an array random order
function Algorithm.Shuffle(array)
--print("in", array)
local n = #array
for i = 1, n do
local j = math.random(1, n)
if i ~= j then
local temp = array[i]
array[i] = array[j]
array[j] = temp
end
end
--print("out", array)
end
function Algorithm.isRectTouch(x1, y1, w1, h1, x2, y2, w2, h2)
if x1 < x2 + w2 and x1 + w1 > x2 and y1 + h1 > y2 and y1 < y2 + h2 then
return true
end
end
function Algorithm.isPointInPolygon(x, y, poly)
-- poly is a Lua list of pairs like {x1, y1, x2, y2, ... xn, yn}
-- see: https://love2d.org/forums/viewtopic.php?t=89699
local x1, y1, x2, y2
local len = #poly
x2, y2 = poly[len - 1], poly[len]
local wn = 0
for idx = 1, len, 2 do
x1, y1 = x2, y2
x2, y2 = poly[idx], poly[idx + 1]
if y1 > y then
if (y2 <= y) and (x1 - x) * (y2 - y) < (x2 - x) * (y1 - y) then
wn = wn + 1
end
else
if (y2 > y) and (x1 - x) * (y2 - y) > (x2 - x) * (y1 - y) then
wn = wn - 1
end
end
end
return wn % 2 ~= 0 -- even/odd rule
end
return Algorithm
================================================
FILE: util/DictUtil.lua
================================================
local DictUtils = class("DictUtils")
return DictUtils
================================================
FILE: util/MiscHelper.lua
================================================
local MiscHelper = class("MiscHelper")
local s_dirt = Reg.BlockID("dirt")
local s_coarse_dirt = Reg.BlockID("coarse_dirt")
local s_farmland = Reg.BlockID("farmland")
local s_cow = Reg.NpcID("cow")
local s_brown_mushroom_cow = Reg.NpcID("brown_mushroom_cow")
local s_red_mushroom_cow = Reg.NpcID("red_mushroom_cow")
local s_bone_meal = Reg.ItemID("bone_meal")
local s_bowl = Reg.ItemID("bowl")
local s_mushroom_stew = Reg.ItemID("mushroom_stew")
local s_glass_bottle = Reg.ItemID("glass_bottle")
local s_bucket_empty = Reg.ItemID("bucket_empty")
local s_bucket_milk = Reg.ItemID("bucket_milk")
local s_liquid_to_bucket_item_names = {
{ "water", "bucket_water" },
{ "lava", "bucket_lava" },
}
local s_liquid_2_buckets = {}
for _, v in ipairs(s_liquid_to_bucket_item_names) do
s_liquid_2_buckets[Reg.LiquidID(v[1])] = Reg.ItemID(v[2])
end
local s_bucket_2_liquids = {}
for _, v in ipairs(s_liquid_to_bucket_item_names) do
s_bucket_2_liquids[Reg.ItemID(v[2])] = Reg.LiquidID(v[1])
end
function MiscHelper.GetBucketIDFromLiquidID(liquidID)
local res = s_liquid_2_buckets[liquidID]
if res ~= nil then
return res
end
return 0
end
function MiscHelper.GetLiquidIDFromBucket(itemID)
local res = s_bucket_2_liquids[itemID]
if res ~= nil then
return res
end
return 0
end
function MiscHelper.GetMilkBucketID()
return s_bucket_milk
end
function MiscHelper.GetEmptyBucketID()
return s_bucket_empty
end
function MiscHelper.GetEmptyGrassBottleID()
return s_glass_bottle
end
function MiscHelper.IsPullableBucket(itemID)
return MiscHelper.GetLiquidIDFromBucket(itemID) > 0
end
function MiscHelper.IsEmptyGrassBottle(itemID)
return itemID == s_glass_bottle
end
function MiscHelper.IsEmptyBucket(itemID)
return itemID == s_bucket_empty
end
function MiscHelper.IsMushroomCow(npcID)
return npcID == s_brown_mushroom_cow or npcID == s_red_mushroom_cow
end
function MiscHelper.IsCow(npcID)
return npcID == s_cow or MiscHelper.IsMushroomCow(npcID)
end
function MiscHelper.IsEmptyBowl(itemID)
return itemID == s_bowl
end
function MiscHelper.GetMushroomBowl()
return s_mushroom_stew
end
function MiscHelper.IsBoneMeal(itemID)
return s_bone_meal == itemID
end
function MiscHelper.CanTransformToFramland(blockID)
return blockID == s_dirt or blockID == s_coarse_dirt
end
function MiscHelper.GetFarmlandID()
return s_farmland
end
function MiscHelper.OpenURL(url)
print("open url:", url)
if not App.isPC then
require("tc.ui.InfoPopupUI").new(url)
return
end
os.execute("start " .. url)
end
return MiscHelper
================================================
FILE: util/OrderedArray.lua
================================================
local OrderedArray = class("OrderedArray")
function OrderedArray:__init()
self.indices = {}
self._elements = {}
self._frees = {}
end
function OrderedArray:add(element)
local index = 0
if #self._frees ~= 0 then
index = self._frees[#self._frees]
table.remove(self._frees, #self._frees)
self._elements[index] = element
else
table.insert(self._elements, element)
index = #self._elements
end
table.insert(self.indices, index)
return index
end
function OrderedArray:remove(index)
table.insert(self._frees, index)
self._elements[index] = false
for i, ii in ipairs(self.indices) do
if ii == index then
table.remove(self.indices, i)
break
end
end
end
function OrderedArray:get(index)
return self._elements[index]
end
function OrderedArray:clear()
self.indices = {}
self._elements = {}
self._frees = {}
end
return OrderedArray
================================================
FILE: util/PhysicsUtil.lua
================================================
local PhysicsUtil = class("PhysicsUtil")
function PhysicsUtil.SightChaseSpeed2D(spx, spy, force, forceAngle, maxSpeed)
local PI = math.pi
local oldAngle = Utils.FixAngle(Utils.GetAngle(spx, spy))
forceAngle = Utils.FixAngle(forceAngle)
local moveAngle = forceAngle - oldAngle
if math.abs(moveAngle) > PI then
moveAngle = moveAngle + 2 * PI * (moveAngle > 0 and -1 or 1)
end
moveAngle = Utils.FixAngle(moveAngle)
if math.abs(moveAngle) > PI / 2 then
forceAngle = oldAngle + PI / 2 * (moveAngle < 0 and -1 or 1)
end
return Utils.ForceSpeed2D(spx, spy, force, forceAngle, maxSpeed)
end
return PhysicsUtil
================================================
FILE: util/SnakeModel.lua
================================================
local SnakeMass = class("SnakeMass")
function SnakeMass:__init(x, y, nextDistance)
self.x = x
self.y = y
self.nextDistance = nextDistance
self.resAngle = 0
self.resCenterX = 0
self.resCenterY = 0
end
function SnakeMass:setData(x, y, nextDistance)
self.x = x
self.y = y
if nextDistance ~= nil then
self.nextDistance = nextDistance
end
end
local SnakeModel = class("SnakeModel")
function SnakeModel:__init()
self.m_masses = {}
end
function SnakeModel:clear()
self.m_masses = {}
end
function SnakeModel:addHead(centerX, centerY, angle, jointLength)
if #self.m_masses ~= 0 then
return
end
table.insert(self.m_masses, SnakeMass.new(0, 0, 0))
table.insert(self.m_masses, SnakeMass.new(0, 0, 0))
self:setHead(centerX, centerY, angle, jointLength)
end
function SnakeModel:setHead(centerX, centerY, angle, jointLength)
if #self.m_masses < 2 then
return
end
local headLength = jointLength
if headLength == nil then
headLength = self.m_masses[1].nextDistance
end
local c = math.cos(angle + math.pi) * headLength * 0.5
local s = math.sin(angle + math.pi) * headLength * 0.5
if jointLength == nil then
self.m_masses[1]:setData(centerX - c, centerY - s)
self.m_masses[2]:setData(centerX + c, centerY + s)
else
self.m_masses[1]:setData(centerX - c, centerY - s, jointLength)
self.m_masses[2]:setData(centerX + c, centerY + s, 0)
end
end
function SnakeModel:addBody(angle, jointLength)
if #self.m_masses < 2 then
return
end
local lastMass = self.m_masses[#self.m_masses]
lastMass.nextDistance = jointLength
table.insert(self.m_masses, SnakeMass.new(
lastMass.x + math.cos(angle) * jointLength,
lastMass.y + math.sin(angle) * jointLength,
0
))
end
function SnakeModel:getRes(index)
if not (index >= 1 and index < #self.m_masses) then
return 0.0, 0.0, 0.0
end
local mass = self.m_masses[index]
return mass.resCenterX, mass.resCenterY, mass.resAngle
end
function SnakeModel:update(headX, headY, headSpx, headSpy, headAngle)
if #self.m_masses > 0 then
self:setHead(headX, headY, headAngle)
end
local sqrt = math.sqrt
local sin = math.sin
local cos = math.cos
local total = #self.m_masses
local spx, spy = headSpx, headSpy
for i = 1, total do
local mass = self.m_masses[i]
mass.x = mass.x + spx
mass.y = mass.y + spy
if i < total then
local nextMass = self.m_masses[i + 1]
local dx = nextMass.x - mass.x
local dy = nextMass.y - mass.y
local newDistance = sqrt(dx * dx + dy * dy)
local newAngle = Utils.GetAngle(mass.x - nextMass.x, mass.y - nextMass.y)
local moveDistance = newDistance - mass.nextDistance
spx = cos(newAngle) * moveDistance
spy = sin(newAngle) * moveDistance
end
end
for i = 1, total - 1 do
local mass = self.m_masses[i]
local nextMass = self.m_masses[i + 1]
mass.resAngle = Utils.FixAngle(Utils.GetAngle(nextMass.x - mass.x, nextMass.y - mass.y) + math.pi)
mass.resCenterX = (mass.x + nextMass.x) * 0.5
mass.resCenterY = (mass.y + nextMass.y) * 0.5
end
end
return SnakeModel
================================================
FILE: util/StringUtil.lua
================================================
local StringUtils = class("StringUtils")
local STR_ROMANS = {
"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"
}
local ROMAN_VALUES = {
1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1
}
function StringUtils.NumberToRoman(n)
local result = ""
for i = 1, 13 do
while n - ROMAN_VALUES[i] >= 0 do
result = result .. STR_ROMANS[i]
n = n - ROMAN_VALUES[i]
end
end
return result
end
function StringUtils.TicksToTimeFormat(ticks)
local seconds = math.ceil(ticks / 60)
local m = math.floor(seconds / 60)
local s = seconds % 60
return string.format("%02d:%02d", m, s)
end
return StringUtils
================================================
FILE: util/ValidChecker.lua
================================================
local ValidChecker = class("ValidChecker")
function ValidChecker.checkValidFileName(s)
local last = ""
for i, sub, b in utf8string.chars(s) do
---@type string
local c = sub
if c:len() ~= 1 then
return false
end
if c ~= "_" and c ~= " " and c:match("%W") then
return false
end
last = c
end
-- blank cannot locate at the end
if last == " " then
return false
end
return true
end
return ValidChecker
================================================
FILE: world/Portals.lua
================================================
local PortalEntity = class("PortalEntity")
function PortalEntity:__init(xi, yi)
self.xi = xi
self.yi = yi
end
local Portals = class("Portals")
function Portals:__init()
self._dataList = {}
end
function Portals:Register(xi, yi)
if self:IsExist(xi, yi) then
return
end
table.insert(self._dataList, PortalEntity.new(xi, yi))
end
function Portals:IsExist(xi, yi)
return self:GetData(xi, yi) ~= nil
end
function Portals:GetList()
return self._dataList
end
function Portals:GetData(xi, yi)
for _, e in ipairs(self._dataList) do
if e.xi == xi and e.yi == yi then
return e
end
end
return nil
end
function Portals:Save()
local resList = {}
for _, e in ipairs(self._dataList) do
local elementData = {
xi = e.xi,
yi = e.yi,
}
table.insert(resList, elementData)
end
return {
list = resList
}
end
function Portals:Load(data)
if data.list ~= nil then
local resList = data.list
for _, e in ipairs(resList) do
local xi, yi = e.xi, e.yi
self:Register(xi, yi)
end
end
end
return Portals
================================================
FILE: world/TCModWorldData.lua
================================================
---@class TC.TCModWorldData
local TCModWorldData = class("TCModWorldData")
local Portals = require("Portals")
local s_instance
---@return TC.TCModWorldData
function TCModWorldData.getInstance()
if s_instance == nil then
s_instance = TCModWorldData.new()
end
return s_instance
end
function TCModWorldData:__init()
self.portals = Portals.new()
end
function TCModWorldData:Save()
local resPortals = self.portals:Save()
return {
portals = resPortals
}
end
function TCModWorldData:Load(data)
if data.portals ~= nil then
self.portals:Load(data.portals)
end
end
return TCModWorldData
================================================
FILE: world_gen/ChunkGenerator.lua
================================================
--- This is the main world generation code
---
--- 世界生成代码,有些复杂,英文中文注释都补上
---@class TC.ChunkGenerator
local ChunkGenerator = class("ChunkGenerator")
local TerrainProxies = require("TerrainProxies")
local SpecialTerrainProxies = require("SpecialTerrainProxies")
local TransitionProxies = require("TransitionProxies")
local ModChunkGenerator = require("ModChunkGenerator")
local Algorithm = require("util.Algorithm")
local WorldGenDefine = require("WorldGenDefine")
local BiomeType_Surface = Reg.BiomeTypeID("Surface")
local BiomeType_Underground = Reg.BiomeTypeID("Underground")
local BiomeType_Nether = Reg.BiomeTypeID("Nether")
local DEFAULT_SURFACE_BIOME_ID = Reg.BiomeID("forest")
local DEFAULT_UNDERGROUND_BIOME_ID = Reg.BiomeID("normal_cave")
local UNDERGROUND_PERLIN_GEN_RATE = 0.36
local DEFAULT_UNDERGROUND_BIOME_AREAS = {
{ 0, 1024, Reg.BiomeID("normal_cave") },
{ 1024, 1536, Reg.BiomeID("mud_cave") },
{ 1536, 2048, Reg.BiomeID("stone_cave") },
{ 2048, 2176, Reg.BiomeID("lava_cave") },
{ 2176, 2560, Reg.BiomeID("magma_cave") },
}
-- ========================================
-- AIR 空气层
-- ========================================
-- SURFACE 地表层
-- ========================================
-- UNDERGROUND 地下层
-- ----------------------------------------
-- DIRT/MUD (地下泥土层)
-- ----------------------------------------
-- STONE (地下岩石层)
-- ----------------------------------------
-- LAVA ZONE (地下熔岩层)
-- ========================================
-- NETHER 地狱层
-- ========================================
-- TWILIGHT FOREST 暮色森林层
-- ========================================
local SURFACE_LINE = WorldGenDefine.SURFACE_LINE
local UNDERGROUND_LINE = WorldGenDefine.UNDERGROUND_LINE
local NETHER_LINE = WorldGenDefine.NETHER_LINE
local NETHER_LAVA_LINE = WorldGenDefine.NETHER_LAVA_LINE
local NETHER_LAVE_CAVE_HEIGHT = WorldGenDefine.NETHER_LAVE_CAVE_HEIGHT
local UNDERGROUND_LAKE_LINE = WorldGenDefine.UNDERGROUND_LAKE_LINE
local BEDROCK_CHUNK_YI = WorldGenDefine.BEDROCK_CHUNK_YI
---__init
---@param chunkXi int
---@param chunkYi int
---@param noise WorldGenNoise
---@param buffer WorldGenChunkBuffer
function ChunkGenerator:__init(chunkXi, chunkYi, noise, buffer)
self.chunkXi = chunkXi
self.chunkYi = chunkYi
self.chunkXiInMap = self.chunkXi * 1024
self.chunkYiInMap = self.chunkYi * 1024
self.noise = noise
self.buffer = buffer
self.isBedrockOnly = false
self.isGenSurface = false
self.isGenUnderground = false
self.isGenNether = false
self.isGenTwilightForest = false
-- surface cache
self.surfaceBiomeID = 0
self.surfaceBiomeID_Left = 0
self.surfaceBiomeID_Right = 0
local function _initMatrix(size, value)
local temp = {}
for i = 1, size * size do
temp[i] = value
end
return temp
end
-- underground cache
-- 34x34 matrix, 1-32: in current chunk, 0,33: adjust chunk
self.undergroundBiomeIDMatrix = _initMatrix(34)
local function _initBoundary(precise)
local temp = {}
if precise then
for i = 1, 1024 do
temp[i] = 0.0
end
else
for i = 1, 1024 do
temp[i] = 0
end
end
return temp
end
-- All boundary array are using world coordinate system,
-- you need to sub chunkYiInMap to get position in chunk coordinate system.
--
-- 分界线数组都使用世界坐标系,你需要减掉chunkYiInMap来得到区间坐标系
self.surfacePreciseBoundary = _initBoundary(true)
self.surfaceBoundary = _initBoundary(false)
self.undergroundBoundary = _initBoundary(false)
self.netherBoundary = _initBoundary(false)
self.surfaceBiomeIDArray = _initBoundary(false)
self.surfaceBoundaryID = 0
self.undergroundBoundaryID = 0
self.terrainProxies = TerrainProxies.new()
self.specialTerrainProxies = SpecialTerrainProxies.new(buffer, noise, self.chunkYiInMap)
self.transitionProxies = TransitionProxies.new(chunkXi, chunkYi, noise, buffer)
self._pendingSortableBuildingList = {}
self._modChunkGenerators = {} ---@type TC.ModChunkGenerator[]
for _, c in ipairs(ModChunkGenerator.getProxy()) do
local instance = c.new(self)
table.insert(self._modChunkGenerators, instance)
end
end
function ChunkGenerator:start()
local timeDiff = TimeDiff.new()
print("==> Init Layer")
self:initLayer()
print("==> Calculate Layer Boundary")
self:calculateLayerBoundary()
print("==> Process Layer")
self:processLayer()
print("==> Put Sub Blocks")
self:putSubBlocks()
print("==> Generate Sub Biomes")
self:generateSubBiomes()
print("==> Generate Caves")
self:generateCaves()
print("==> Generate Special Group")
self:generateSpecialGroup()
print("==> Generate Special Terrains")
self:generateSpecialTerrains()
print("==> Generate Underground Lake")
self:generateUnderLake()
self:generateSurfaceGrassCover()
print("==> Settle All Element By Biomes")
self.buffer:SettleAllElementByBiomes()
print("==> Generate Ores")
self:generateOres()
print("==> Generate Trees")
self:generateTrees()
print("==> Generate Mushrooms")
self:generateMushrooms()
print("==> Generate Placeable")
self:generatePlaceable()
print("==> Generate Cobwebs")
self:generateCobwebs()
print("==> Generate Buildings")
self:generateBuildings()
if self.isBedrockOnly then
return
end
print("==> Finish Chunk Generating in", timeDiff:diff(), "ms")
end
function ChunkGenerator:destroy()
end
--- decide what base layer will be generated (surface, underground, nether ...)
---
--- 决定哪些层会被生成。(比如地表、地下、地狱)
function ChunkGenerator:initLayer()
if self.chunkYi >= BEDROCK_CHUNK_YI then
self.isBedrockOnly = true
return
end
if self.chunkYi == 0 then
self.isGenSurface = true
self.isGenUnderground = true
elseif self.chunkYi == 1 then
self.isGenUnderground = true
elseif self.chunkYi == 2 then
self.isGenUnderground = true
self.isGenNether = true
end
for _, modChunkGenerator in ipairs(self._modChunkGenerators) do
modChunkGenerator:onInitLayer()
end
end
function ChunkGenerator:_getUndergroundYiAreaInChunk()
if not self.isGenUnderground then
return 0, 0
end
local yi = 0
local yi2 = 1024
if self.isGenSurface then
yi = UNDERGROUND_LINE - self.chunkYiInMap
end
if self.isGenNether then
yi2 = NETHER_LINE - self.chunkYiInMap
end
yi = math.min(1024, math.max(0, yi))
yi2 = math.min(1024, math.max(yi, yi2))
return yi, yi2 - yi
end
--- Save boundary data between every layers.
---
--- 计算层与层之间的边界。
function ChunkGenerator:calculateLayerBoundary()
local max = math.max
local min = math.min
local defaultSurfaceBiomeID = DEFAULT_SURFACE_BIOME_ID
local defaultUndergroundBiomeID = DEFAULT_UNDERGROUND_BIOME_ID
local chunkXiInMap = self.chunkXiInMap
local chunkYiInMap = self.chunkYiInMap
local surfacePreciseBoundary = self.surfacePreciseBoundary
local surfaceBoundary = self.surfaceBoundary
local undergroundBoundary = self.undergroundBoundary
local netherBoundary = self.netherBoundary
local noise = self.noise
local buffer = self.buffer
local mapXi = 0
local perlinRes = 0
noise:SetData(0.5, 8)
if self.isGenSurface and self.isGenUnderground then
-- Current chunk has boundary between surface and underground.
-- 当前区块有地表层和地下层的分界线。
for xi = 0, 1023 do
mapXi = chunkXiInMap + xi
-- surface line
perlinRes = noise:Perlin1D(mapXi * 0.02)
surfacePreciseBoundary[xi + 1] = SURFACE_LINE + perlinRes * 10.0
-- underground line
perlinRes = noise:Perlin1D(mapXi * 0.33)
undergroundBoundary[xi + 1] = UNDERGROUND_LINE + perlinRes * 8.0
end
self:_fixSurfaceBoundary()
self:_genSurfaceBiomeIDInfo()
self:_genSurfaceTerrains()
self:_fixSurfaceBoundary()
self.surfaceBoundaryID = buffer:AddBoundaryArray(self.surfaceBoundary)
self.undergroundBoundaryID = buffer:AddBoundaryArray(self.undergroundBoundary)
-- Apply boundary to buffer.
-- 应用分界。
for xi = 0, 1023 do
local top = max(surfaceBoundary[xi + 1] - chunkYiInMap, 0)
local bottom = min(undergroundBoundary[xi + 1] - chunkYiInMap, 1024)
-- Surface layer
buffer:SetBiomeArea(xi, top, 1, bottom - top,
BiomeType_Surface, defaultSurfaceBiomeID,
true, true)
-- Underground layer
buffer:SetBiomeArea(xi, bottom, 1, 1024 - bottom,
BiomeType_Underground, defaultUndergroundBiomeID,
true, true)
end
elseif self.isGenUnderground and self.isGenNether then
-- Current chunk has boundary between underground and nether.
-- 当前区块有地下层和地狱的分界线。
local netherBiomeID = Reg.BiomeID("nether")
for xi = 0, 1023 do
mapXi = chunkXiInMap + xi
perlinRes = noise:Perlin1D(mapXi * 0.125)
netherBoundary[xi + 1] = math.floor(NETHER_LINE + perlinRes * 20.0)
end
for xi = 0, 1023 do
local bottom = min(netherBoundary[xi + 1] - chunkYiInMap, 1024)
-- Underground layer
buffer:SetBiomeArea(xi, 0, 1, bottom,
BiomeType_Underground, defaultUndergroundBiomeID,
true, true
)
-- Nether layer
buffer:SetBiomeArea(xi, bottom, 1, 1024 - bottom,
BiomeType_Nether, netherBiomeID,
true, true
)
end
elseif self.isGenUnderground then
-- Underground layer only, there is no boundary in current chunk.
-- 只有地下层,没有分界线。
buffer:SetBiomeArea(0, 0, 1024, 1024,
BiomeType_Underground, defaultUndergroundBiomeID,
true, true)
end
end
function ChunkGenerator:_fixSurfaceBoundary()
local surfacePreciseBoundary = self.surfacePreciseBoundary
local surfaceBoundary = self.surfaceBoundary
local floor = math.floor
-- Transform to real surface boundary data. (double -> int)
for xi = 0, 1023 do
-- floor(a + 0.5) => round(a)
surfaceBoundary[xi + 1] = floor(surfacePreciseBoundary[xi + 1] + 0.5)
end
end
function ChunkGenerator:_genSurfaceBiomeIDInfo()
local noise = self.noise
noise:SetData(0.5, 8)
for i = -1, 1 do
local checkChunkXi = self.chunkXi + i
local biomeID = self:getSurfaceMainBiomeID(checkChunkXi)
if i == 0 then
self.surfaceBiomeID = biomeID
elseif i == -1 then
self.surfaceBiomeID_Left = biomeID
else
self.surfaceBiomeID_Right = biomeID
end
end
local surfaceBiomeID = self.surfaceBiomeID
for xi = 0, 1023 do
self.surfaceBiomeIDArray[xi + 1] = surfaceBiomeID
end
end
function ChunkGenerator:_genSurfaceTerrains()
local abs = math.abs
local floor = math.floor
local ceil = math.ceil
local noise = self.noise
local chunkXi = self.chunkXi
local chunkYi = self.chunkYi
local terrainProxies = self.terrainProxies
local surfacePreciseBoundary = self.surfacePreciseBoundary
noise:SetData(0.5, 8)
local biomeData = BiomeUtils.GetData(self.surfaceBiomeID)
local terrains = biomeData.terrains.terrains
-- add terrains, just modify boundary array.
-- 添加地形,只是修改边界数组的数据。
for i = 1, terrains.count do
local terrain = terrains[i]
local terrainTimes = terrain.times
local times = 0
if terrainTimes < 1 then
-- less than 1, use possibility
-- 小于1就使用概率
local ranRate = noise:GetDoubleFromInt1D(chunkXi * 7 + terrain.size * 13 + terrain.height * 7)
if abs(ranRate) < terrainTimes then
times = 1
end
else
times = ceil(terrainTimes)
end
if times > 0 then
for j = 1, times do
local terrainName = terrain.name
local locateRateX = abs(noise:GetDoubleFromInt2D(terrain.size + j, chunkYi * 7 + j + terrain.height))
local xi = floor(locateRateX * 1024)
terrainProxies:calculateBoundaryFromTerrain(terrainName, surfacePreciseBoundary, xi, terrain.size, terrain.height)
end
end
end
end
--- Write biome data into buffer for every layer.
---
--- 根据不同层,初步填入群系数据。
function ChunkGenerator:processLayer()
if self.isBedrockOnly then
self:_genBedrockLayer()
return
end
if self.isGenSurface then
self:_genSurfaceBiomes()
end
if self.isGenUnderground then
self:_genUndergroundBiomes()
end
if self.isGenNether then
self:_genNetherBiomes()
end
end
function ChunkGenerator:_genBedrockLayer()
end
--- Write surface biome data into buffer.
---
--- 保存地表群落数据到缓冲区。
function ChunkGenerator:_genSurfaceBiomes()
local leftTransition
local rightTransition
local currentTransition = BiomeUtils.GetData(self.surfaceBiomeID).terrains.transition
if self.surfaceBiomeID > self.surfaceBiomeID_Left then
leftTransition = currentTransition
end
if self.surfaceBiomeID > self.surfaceBiomeID_Right then
rightTransition = currentTransition
end
if leftTransition ~= nil or rightTransition ~= nil then
self.transitionProxies:doTransition(leftTransition, rightTransition,
0, 1024, self.surfaceBoundary, self.undergroundBoundary,
{
{ BiomeType_Surface, self.surfaceBiomeID_Left },
{ BiomeType_Surface, self.surfaceBiomeID },
{ BiomeType_Surface, self.surfaceBiomeID_Right },
}, false, false)
else
local surfaceBoundary = self.surfaceBoundary
local undergroundBoundary = self.undergroundBoundary
local buffer = self.buffer
local chunkYiInMap = self.chunkYiInMap
local max = math.max
local min = math.min
for xi = 0, 1023 do
local top = max(surfaceBoundary[xi + 1] - chunkYiInMap, 0)
local bottom = min(undergroundBoundary[xi + 1] - chunkYiInMap, 1024)
-- Surface layer
buffer:SetBiomeArea(xi, top, 1, bottom - top,
BiomeType_Surface, self.surfaceBiomeID,
true, true)
end
end
end
function ChunkGenerator:generateSurfaceGrassCover()
local buffer = self.buffer
for xi = 0, 1023 do
local yi = self.surfaceBoundary[xi + 1]
if yi >= 0 and yi < 1023 then
local bu = buffer:GetUnit(xi, yi)
bu.isGrassCoverPreset = true
end
end
end
function ChunkGenerator:_genNetherBiomes()
local chunkXiInMap = self.chunkXiInMap
local chunkYiInMap = self.chunkYiInMap
local netherBoundary = self.netherBoundary
local min = math.min
local max = math.max
local buffer = self.buffer
local sampleIf = buffer:GetSample(1)
local maskIf = buffer:GetMask(1)
sampleIf.biomeType = BiomeType_Underground
maskIf.biomeType = true
local sampleApply = buffer:GetSample(2)
local maskApply = buffer:GetMask(2)
sampleApply.biomeType = BiomeType_Nether
maskApply.biomeType = true
for xi = 0, 1023 do
local netherYi = min(1023, max(0, netherBoundary[xi + 1] - chunkYiInMap))
local topCaveYi = min(1023, max(0, netherYi - 120))
buffer:ApplySampleByMaskByCondition(xi, topCaveYi, 1, 120,
2, 2, 1, 1)
end
buffer:ClearSample(1)
buffer:ClearMask(1)
buffer:ClearSample(2)
buffer:ClearMask(2)
end
--- Write underground biome data into buffer.
---
--- 保存地下群落数据到缓冲区。
function ChunkGenerator:_genUndergroundBiomes()
self:_genUndergroundBiomeMatrix()
for _, modChunkGenerator in ipairs(self._modChunkGenerators) do
modChunkGenerator:onGenerateUndergroundMatrix()
end
self.buffer:SetBiomeIDFromMatrixByBiomeType(BiomeType_Underground, self.undergroundBiomeIDMatrix)
end
function ChunkGenerator:_genUndergroundBiomeMatrix()
local defaultUndergroundBiomeID = DEFAULT_UNDERGROUND_BIOME_ID
local defaultUndergroundBiomeAreas = DEFAULT_UNDERGROUND_BIOME_AREAS
local noise = self.noise
local matrix = self.undergroundBiomeIDMatrix
local chunkYiInMap = self.chunkYiInMap
noise:SetData(0.6, 2)
for i = 0, 33 do
local ii = i * 34
for j = 0, 33 do
local biomeID = defaultUndergroundBiomeID
local sourceY = chunkYiInMap + (j - 1) * 32 - 16
for _, data in ipairs(defaultUndergroundBiomeAreas) do
if sourceY >= data[1] and sourceY < data[2] then
biomeID = data[3]
break
end
end
matrix[ii + j + 1] = biomeID
end
end
self:_randomUndergroundBiome()
self:_specialGenUndergroundBiome()
end
function ChunkGenerator:_testInMatrixArea(globalXi, globalYi, width, height)
return Algorithm.isRectTouch(globalXi, globalYi, width, height,
self.chunkXiInMap - 32, self.chunkYiInMap - 32, 1024 + 64, 1024 + 64)
end
function ChunkGenerator:_getPolyArea(poly)
local minX = 99999999
local maxX = -99999999
local minY = 99999999
local maxY = -99999999
local min = math.min
local max = math.max
local len = #poly
for idx = 1, len, 2 do
local x, y = poly[idx], poly[idx + 1]
minX = min(x, minX)
minY = min(y, minY)
maxX = max(x, maxX)
maxY = max(y, maxY)
end
return minX, minY, maxX, maxY
end
function ChunkGenerator:writeBiomeMatrixRect(globalXi, globalYi, width, height, matrixData, biomeID)
if not self:_testInMatrixArea(globalXi, globalYi, width, height) then
return
end
local globalXi2 = globalXi + width
local globalYi2 = globalYi + height
local chunkXiInMap = self.chunkXiInMap
local chunkYiInMap = self.chunkYiInMap
local matrix = matrixData
for i = 0, 33 do
local ii = i * 34
local sourceX = chunkXiInMap + (i - 1) * 32 - 16
if sourceX >= globalXi and sourceX < globalXi2 then
for j = 0, 33 do
local sourceY = chunkYiInMap + (j - 1) * 32 - 16
if sourceY >= globalYi and sourceY < globalYi2 then
matrix[ii + j + 1] = biomeID
end
end
end
end
end
function ChunkGenerator:writeBiomeMatrixPolygon(poly, matrixData, biomeID)
local minX, minY, maxX, maxY = self:_getPolyArea(poly)
if not self:_testInMatrixArea(minX, minY, maxX - minX, maxY - minY) then
return
end
local chunkXiInMap = self.chunkXiInMap
local chunkYiInMap = self.chunkYiInMap
local matrix = matrixData
local isPointInPolygon = Algorithm.isPointInPolygon
for i = 0, 33 do
local ii = i * 34
local sourceX = chunkXiInMap + (i - 1) * 32 - 16
if sourceX >= minX and sourceX < maxX then
for j = 0, 33 do
local sourceY = chunkYiInMap + (j - 1) * 32 - 16
if sourceY >= minY and sourceY < maxY then
if isPointInPolygon(sourceX, sourceY, poly) then
matrix[ii + j + 1] = biomeID
end
end
end
end
end
end
function ChunkGenerator:_randomUndergroundBiome()
local noise = self.noise
local matrix = self.undergroundBiomeIDMatrix
noise:SetData(0.6, 2)
local chunkXiInMap = self.chunkXiInMap
local chunkYiInMap = self.chunkYiInMap
local allBiomeIDs = {
Reg.BiomeID("andesite_cave"),
Reg.BiomeID("blue_mushroom_cave"),
Reg.BiomeID("desert_cave"),
Reg.BiomeID("flesh_cave"),
Reg.BiomeID("granite_cave"),
Reg.BiomeID("tainted_cave"),
Reg.BiomeID("waste_cave"),
Reg.BiomeID("diorite_cave"),
Reg.BiomeID("jungle_cave"),
}
-- use perlin noise to decide every underground biome areas (old generate algorithm)
-- 使用柏林噪声来决定每一个群系位置
for _, biomeID in ipairs(allBiomeIDs) do
local biomeData = BiomeUtils.GetData(biomeID)
local limitRate = UNDERGROUND_PERLIN_GEN_RATE * biomeData.scale
local ddx = (biomeID) * 13217
local ddy = (biomeID) * 14537
for i = 0, 33 do
local ii = i * 34
local perlinOffsetX = (chunkXiInMap + (i - 1) * 32 + ddx) * 0.0015625
for j = 0, 33 do
local perlinOffsetY = (chunkYiInMap + (j - 1) * 32 + ddy) * 0.0015625
local rate = noise:Perlin2D(
perlinOffsetX,
perlinOffsetY
) * 0.5 + 0.5
if rate < limitRate then
matrix[ii + j + 1] = biomeID
end
end
end
end
end
--- Set sub blocks to buffer.
---
--- 把子方块写入到缓冲区。
function ChunkGenerator:putSubBlocks()
local buffer = self.buffer
local noise = self.noise
noise:SetData(0.6, 2)
buffer:PushAllSubBlocks()
end
---
function ChunkGenerator:generateCaves()
self:_makeCaveHorizontal()
self:_makeCaveRandomDirection()
self:_makeCavePerlin()
self:_specialMakeCave()
for _, modChunkGenerator in ipairs(self._modChunkGenerators) do
modChunkGenerator:onPostGenerateCaves()
end
end
function ChunkGenerator:makeCaveHorizontalPoly(
poly, randomKey, elementWidthMin, elementWidthMax, elementHeightMin, elementHeightMax, density,
scaleX, persistence, octaves, amplitude,
scaleXTop, persistenceTop, octavesTop, amplitudeTop,
scaleXBottom, persistenceBottom, octavesBottom, amplitudeBottom)
local minX, minY, maxX, maxY = self:_getPolyArea(poly)
if not Algorithm.isRectTouch(minX, minY, maxX - minX, maxY - minY,
self.chunkXiInMap, self.chunkYiInMap, 1024, 1024) then
return
end
local buffer = self.buffer
local wga = WorldGenArea.new(self.chunkXiInMap, self.chunkYiInMap, 1024, 1024)
local areas = buffer:GetRandomAreas(randomKey, wga,
elementWidthMin, elementWidthMax,
elementHeightMin, elementHeightMax,
density
)
---@param area WorldGenArea
for _, area in ipairs(areas) do
local x, y = area.xi + area.wi / 2, area.yi + area.hi / 2
if Algorithm.isPointInPolygon(x, y, poly) then
buffer:PerlinMakeCaveHorizontal(
area.xi - self.chunkXiInMap, area.yi - self.chunkYiInMap, area.wi, area.hi,
scaleX, persistence, octaves, amplitude,
scaleXTop, persistenceTop, octavesTop, amplitudeTop,
scaleXBottom, persistenceBottom, octavesBottom, amplitudeBottom
)
end
end
end
function ChunkGenerator:_makeCaveHorizontal()
local buffer = self.buffer
local noise = self.noise
noise:SetData(0.3, 4)
-- generate horizontal cave
-- 生成横向洞穴
local wga = WorldGenArea.new(self.chunkXiInMap, self.chunkYiInMap, 1024, 1024)
local areas = buffer:GetRandomAreas(123, wga,
30, 250,
10, 13,
120.0
)
---@param area WorldGenArea
for _, area in ipairs(areas) do
buffer:PerlinMakeCaveHorizontal(
area.xi - self.chunkXiInMap, area.yi - self.chunkYiInMap, area.wi, area.hi,
0.01, 0.5, 8, 60.0,
0.15, 0.3, 4, 10.0,
0.3, 0.3, 4, 2.0
)
end
local largeAreas = buffer:GetRandomAreas(777, wga,
100, 250,
13, 15,
26.0
)
---@param area WorldGenArea
for _, area in ipairs(largeAreas) do
buffer:PerlinMakeCaveHorizontal(
area.xi - self.chunkXiInMap, area.yi - self.chunkYiInMap, area.wi, area.hi,
0.022, 0.5, 8, 30.0,
0.15, 0.3, 4, 18.0,
0.25, 0.3, 4, 3.0
)
end
end
function ChunkGenerator:_makeCaveRandomDirection()
local chunkYiInMap = self.chunkYiInMap
local buffer = self.buffer
local noise = self.noise
noise:SetData(0.3, 4)
local pc = 4
local cc = 1024 / pc
for i = 0, pc - 1 do
for j = 0, pc - 1 do
local xi = i * cc + noise:GetByteFromInt2D(i, j, cc)
local yi = j * cc + noise:GetByteFromInt2D(j + i, i, cc)
local sourceY = chunkYiInMap + yi
if sourceY > SURFACE_LINE + 30 then
buffer:MakeCaveRandomDirection(xi, yi)
end
end
end
end
function ChunkGenerator:_makeCavePerlin()
local chunkYiInMap = self.chunkYiInMap
local buffer = self.buffer
local noise = self.noise
noise:SetData(0.3, 4)
buffer:PerlinMakeCave(0, 0, 1024, 1024, 0.03125, 0.041,
0.18, 1.0,
SURFACE_LINE - chunkYiInMap + 100, 100,
NETHER_LINE - chunkYiInMap, 50
)
end
function ChunkGenerator:_testCode()
local buffer = self.buffer
local noise = self.noise
noise:SetData(0.3, 4)
local code = buffer:GetCode()
--int testInt = (xi + 123) * 0.456 + 7 / 8.0 > 77 and true and 3 > 2 or false;
--double testDouble = 0.333;
local rawCode = [[
double testDouble = (xi+123*xi*(yi*0.6+666));
if testDouble<2 then
int a = 1;
elseif true then
int aa = 2233;
aa = aa + 1;
elseif xi < 20 then
testDouble = 2;
else
int b = 2;
endif
]]
code:CompileCode(rawCode)
end
function ChunkGenerator:_testMakeCave()
local buffer = self.buffer
local chunkXiInMap = self.chunkXiInMap
local chunkYiInMap = self.chunkYiInMap
local noise = self.noise
noise:SetData(0.3, 4)
local timeDiff = TimeDiff.new()
for xi = 0, 1023 do
local mapXi = chunkXiInMap + xi
for yi = 0, 1023 do
local bu = buffer:GetUnit(xi, yi)
if bu.isFrontPreset then
local mapYi = chunkYiInMap + yi
local res = noise:Perlin2D(mapXi * 0.03125, mapYi * 0.041) * 0.5 + 0.5
if res < 0.41 then
buffer:ClearFrontAndWall(xi, yi)
end
end
end
end
print("LUA GEN CAVE TIME:", timeDiff:diff(), "ms")
end
--- Generate underground lake.
---
--- 生成地下湖泊。
function ChunkGenerator:generateUnderLake()
local buffer = self.buffer
local chunkXiInMap = self.chunkXiInMap
local chunkYiInMap = self.chunkYiInMap
local noise = self.noise
local surfaceLine = SURFACE_LINE
local undergroundLakeLine = UNDERGROUND_LAKE_LINE
local netherLine = NETHER_LINE
noise:SetData(0.3, 4)
local SAMPLE_TIMES = 1
local LIQUID_ID_LAVA = Reg.LiquidID("lava")
for i = 0, 31 do
for j = 0, 31 do
for t = 0, SAMPLE_TIMES - 1 do
local xi = i * 32 + noise:GetByteFromInt2D(i * 2 + t * 233, j, 32)
local yi = j * 32 + noise:GetByteFromInt2D(j + i, i - j + t * 233, 32)
if xi >= 0 and xi < 1024 and yi >= 0 and yi < 1024 then
local mapYi = chunkYiInMap + yi
if mapYi > surfaceLine and mapYi < undergroundLakeLine then
local bu = buffer:GetUnit(xi, yi)
local biomeData = BiomeUtils.GetData(bu.biomeID)
local liquidInfo = biomeData.liquidInfo
if liquidInfo.liquidID > 0 and liquidInfo.maxAllowCount > 0 then
buffer:GenerateLake(xi, yi, liquidInfo.liquidID, liquidInfo.maxAllowCount)
end
elseif mapYi >= undergroundLakeLine and mapYi < netherLine then
buffer:GenerateLake(xi, yi, LIQUID_ID_LAVA, 250)
end
end
end
end
end
-- nether lava
if self.isGenNether then
local lavaID = Reg.LiquidID("tc:lava")
local lavaYi = NETHER_LAVA_LINE - chunkYiInMap
local sampleIf = buffer:GetSample(1)
local maskIf = buffer:GetMask(1)
sampleIf.isFrontPreset = false
maskIf.isFrontPreset = true
buffer:SetLiquidAreaByCondition(0, lavaYi, 1024, 1024 - lavaYi, lavaID, 63,
1, 1)
buffer:ClearSample(1)
buffer:ClearMask(1)
-- fill lava to make many levels
for i = 0, 63 do
local xi = 16 * i
local yi = lavaYi - math.floor(math.abs(noise:GetDoubleFromInt1D(chunkXiInMap + chunkYiInMap + i)) * 48)
buffer:GenerateLake(xi, yi, lavaID, 1000)
end
end
end
function ChunkGenerator:generateOres()
local buffer = self.buffer
local chunkXiInMap = self.chunkXiInMap
local chunkYiInMap = self.chunkYiInMap
local oreGroups = BlockUtils.oreGroups
for i = 1, oreGroups.count do
local oreGroup = oreGroups[i]
local groupName = oreGroup.name
local dataList = oreGroup.dataList
for j = 1, dataList.count do
local data = dataList[j]
--print(groupName, data.oreID, data.radius, data.density)
local oreID = data.oreID
local r = data.radius
local r2 = r * 2
local density = data.density
local areaYi = math.max(chunkYiInMap, data.startYi)
local areaYi2 = math.min(chunkYiInMap + 1024, data.endYi)
if areaYi < areaYi2 then
local mainArea = WorldGenArea.new(chunkXiInMap, areaYi, 1024, areaYi2 - areaYi)
local areas = buffer:GetRandomAreas(data.oreID, mainArea, r2, r2, r2, r2, density)
local lastBiomeID = -1
local canPlace = false
---@param area WorldGenArea
for _, area in ipairs(areas) do
local xi = area.xi - chunkXiInMap + r
local yi = area.yi - chunkYiInMap + r
if xi >= 0 and xi < 1024 and yi >= 0 and yi < 1024 then
local bu = buffer:GetUnit(xi, yi)
local biomeID = bu.biomeID
if biomeID ~= lastBiomeID then
local biomeData = BiomeUtils.GetData(biomeID)
canPlace = (biomeData.oreGroupName == groupName)
end
if canPlace then
buffer:AddBlockRandomOval(
oreID, xi - r, yi - r, r2, r2,
true,
false,
false
)
end
end
end
end
end
end
end
function ChunkGenerator:generateCobwebs()
if not self.isGenUnderground then
return
end
local buffer = self.buffer
local chunkXiInMap = self.chunkXiInMap
local chunkYiInMap = self.chunkYiInMap
local cobwebID = Reg.BlockID("tc:cobweb")
local r = 6
local r2 = r * 2
local r_half = math.ceil(r / 2)
local density = 1000
local mainArea = WorldGenArea.new(chunkXiInMap, chunkYiInMap, 1024, 1024)
local areas = buffer:GetRandomAreas(chunkXiInMap + chunkYiInMap + 233,
mainArea, r2, r2, r2, r2, density
)
---@param area WorldGenArea
for _, area in ipairs(areas) do
local mapYi = area.yi
if mapYi > UNDERGROUND_LINE and mapYi < NETHER_LINE then
local mapXi = area.xi
local xi = mapXi - chunkXiInMap
local yi = mapYi - chunkYiInMap
local hasSolid = buffer:IsAreaHasSolid(xi, yi, r, r_half)
if hasSolid then
buffer:AddBlockRandomOval(
cobwebID, xi, yi, r2, r2,
false, false, true)
end
end
end
end
function ChunkGenerator:generateBuildings()
for _, modChunkGenerator in ipairs(self._modChunkGenerators) do
modChunkGenerator:onGenerateBuildings()
end
self:_onGenerateBuildings()
-- sort by key and add all pending building to map.
table.sort(self._pendingSortableBuildingList, function(a, b)
return a.sizeAsSortKey > b.sizeAsSortKey
end)
for _, pendingBuilding in ipairs(self._pendingSortableBuildingList) do
self.buffer:CreateBuilding(pendingBuilding.buildingID, pendingBuilding.xi, pendingBuilding.yi)
end
self.buffer:ApplyBuildings()
end
function ChunkGenerator:generateTrees()
if self.isGenSurface then
self:_genSurfaceTrees()
end
if self.isGenUnderground then
self:_genUndergroundTrees()
end
end
function ChunkGenerator:generateMushrooms()
if self.isGenSurface then
self:_genSurfaceMushrooms()
end
end
function ChunkGenerator:_genSurfaceTrees()
local abs = math.abs
local buffer = self.buffer
local lastBiomeID = 0
local biomeData ---@type BiomeData
local noise = self.noise
local rate = 0
local styles = 0
local totalStyles = 0
for xi = 4, 1019 do
local biomeID = self.surfaceBiomeIDArray[xi + 1]
if biomeData == nil or biomeID ~= lastBiomeID then
lastBiomeID = biomeID
biomeData = BiomeUtils.GetData(biomeID)
rate = biomeData.treeInfo.density
styles = biomeData.treeInfo.styles
totalStyles = styles.count
end
if totalStyles > 0 and abs(noise:GetDoubleFromInt1D(xi * 32)) < rate then
-- random pick a tree block to generate
local yi = self.surfaceBoundary[xi + 1]
local index = noise:GetByteFromInt2D(xi, xi * 32, totalStyles) + 1
local blockID = styles[index]
local ok = buffer:GenerateTree(xi, yi, blockID)
if ok then
-- two trees must has at least 7 distance
-- 两棵树必须距离至少7个格子
xi = xi + 6
end
end
end
end
function ChunkGenerator:_genSurfaceMushrooms()
local abs = math.abs
local buffer = self.buffer
local lastBiomeID = 0
local biomeData ---@type BiomeData
local noise = self.noise
local rate = 0
local styles = 0
local totalStyles = 0
local stemID = Reg.BlockID("tc:mushroom_stem")
for xi = 4, 1019 do
local biomeID = self.surfaceBiomeIDArray[xi + 1]
if biomeData == nil or biomeID ~= lastBiomeID then
lastBiomeID = biomeID
biomeData = BiomeUtils.GetData(biomeID)
rate = biomeData.mushroomInfo.density
styles = biomeData.mushroomInfo.styles
totalStyles = styles.count
end
if totalStyles > 0 and abs(noise:GetDoubleFromInt1D(xi * 32)) < rate then
-- random pick a tree block to generate
local yi = self.surfaceBoundary[xi + 1]
local index = noise:GetByteFromInt2D(xi, xi * 3, totalStyles) + 1
local blockID = styles[index]
local ok = buffer:GenerateLargeMushroom(xi, yi, blockID, stemID)
if ok then
xi = xi + 6
end
end
end
end
function ChunkGenerator:_genUndergroundTrees()
local abs = math.abs
local buffer = self.buffer
local noise = self.noise
local SAMPLE_TIMES = 1024 * 8
local startYi, yiSize = self:_getUndergroundYiAreaInChunk()
local posList = buffer:GetAllFloors(0, startYi, 1024, yiSize)
local totalPos = posList.count
local sampleStep = math.floor(totalPos / SAMPLE_TIMES)
if sampleStep <= 0 then
return
end
local lastBiomeID = -1
local treeInfo
local styles
local styleCount
for step = 0, SAMPLE_TIMES - 1 do
local index = step * sampleStep + 1
if index <= totalPos then
local pos = posList[index]
local xi = pos.xi
local yi = pos.yi
local bu = buffer:GetUnit(xi, yi)
if bu.biomeID ~= lastBiomeID then
lastBiomeID = bu.biomeID
local biomeData = BiomeUtils.GetData(lastBiomeID)
treeInfo = biomeData.treeInfo
styles = treeInfo.styles
styleCount = styles.count
end
if treeInfo ~= nil and styles.count > 0 then
local rate = treeInfo.density * sampleStep
local curRate = abs(noise:GetDoubleFromInt1D(xi * 32 + yi * 128))
if curRate < rate then
local styleIndex = noise:GetByteFromInt2D(xi, xi * 32, styleCount) + 1
local blockID = styles[styleIndex]
buffer:GenerateTree(xi, yi, blockID)
end
end
end
end
end
function ChunkGenerator:generatePlaceable()
local buffer = self.buffer
if self.isGenSurface then
buffer:CreateAllPlaceableByBiomeType(
0, 0, 1024, 1024,
BiomeType_Surface, self.surfaceBoundaryID)
end
if self.isGenUnderground then
buffer:CreateAllPlaceableByBiomeType(
0, 0, 1024, 1024,
BiomeType_Underground)
end
if self.isGenNether then
buffer:CreateAllPlaceableByBiomeType(
0, 0, 1024, 1024,
BiomeType_Nether
)
end
end
function ChunkGenerator:getRandomTimes(rawTimes, randomKey)
local times = 0
if rawTimes < 1 then
if self:inChance(rawTimes, randomKey) then
times = 1
end
else
times = math.ceil(rawTimes)
end
return times
end
function ChunkGenerator:inChance(rate, randomKey)
return math.abs(self.noise:GetDoubleFromInt1D(randomKey)) < rate
end
function ChunkGenerator:_ranGenSurfaceSpecialTerrains(randomKey, rawTimes, size, height, cb, ignoreAreas, notAllowPaintSubBiome, currentBiomeID, biomeIDArray)
if notAllowPaintSubBiome == nil then
notAllowPaintSubBiome = false
end
local times = self:getRandomTimes(rawTimes, self.chunkXi * 223 + size + height * 7 + randomKey, 77)
for t = 1, times do
for k = 1, 5 do
local xi = math.floor(1024 * math.abs(self.noise:GetDoubleFromInt2D(self.chunkXi * 19 + size + t + 123 + k, self.chunkXi * 223 + t * 2 + randomKey + k * 53)))
local x1 = math.max(0, xi - size / 2)
local x2 = math.min(1024, xi + size / 2)
local ignore = false
if ignoreAreas ~= nil then
for _, area in ipairs(ignoreAreas) do
if x1 >= area[1] and x2 <= area[2] then
ignore = true
break
end
end
end
if not ignore and notAllowPaintSubBiome and biomeIDArray ~= nil then
for _xi = x1, x2 - 1 do
if biomeIDArray[_xi + 1] ~= currentBiomeID then
ignore = true
break
end
end
end
if not ignore then
cb(x1, x2)
break
end
end
end
end
function ChunkGenerator:_randGenSurfaceLake(rawTimes, size, height, liquidID, ignoreAreas)
local function cb(x1, x2)
self.specialTerrainProxies:createSurfaceLake(x1, x2, liquidID, height)
end
self:_ranGenSurfaceSpecialTerrains(self.chunkXi * 3 + 114, rawTimes, size, height, cb, ignoreAreas, true, self.surfaceBiomeID, self.surfaceBiomeIDArray)
end
function ChunkGenerator:_randGenSurfaceCave(rawTimes, size, ignoreAreas)
local function cb(x1, x2)
self.specialTerrainProxies:createSurfaceCave(x1, x2)
end
self:_ranGenSurfaceSpecialTerrains(self.chunkXi * 7 + 514, rawTimes, size, 0, cb, ignoreAreas, true, self.surfaceBiomeID, self.surfaceBiomeIDArray)
end
function ChunkGenerator:createSubBiomes(boundaryTop, x1, x2, depth, subBiomeID, maskedBiomeType, maskedBiomeID, biomeIDArray)
x1 = math.max(0, x1)
x2 = math.min(1024, x2)
local size = (x2 - x1)
local halfSize = math.floor(size / 2)
if size <= 0 or halfSize <= 0 then
return
end
local buffer = self.buffer
local chunkYiInMap = self.chunkYiInMap
local centerXi = math.ceil((x1 + x2) / 2)
local sampleIf = buffer:GetSample(1)
local maskIf = buffer:GetMask(1)
sampleIf.biomeType = maskedBiomeType
sampleIf.biomeID = maskedBiomeID
maskIf.biomeType = true
maskIf.biomeID = true
local sampleApply = buffer:GetSample(2)
local maskApply = buffer:GetMask(2)
sampleApply.biomeID = subBiomeID
maskApply.biomeID = true
for xi = x1, x2 - 1 do
local offsetX = 0
if xi < centerXi then
offsetX = xi - x1
else
offsetX = x2 - xi
end
local depthRate = offsetX / halfSize
local currentDepth = math.ceil(depth * depthRate)
if currentDepth > 0 then
local topYi = boundaryTop[xi + 1] - chunkYiInMap
buffer:ApplySampleByMaskByCondition(xi, topYi, 1, currentDepth, 2, 2, 1, 1)
end
biomeIDArray[xi + 1] = subBiomeID
end
buffer:ClearSample(1)
buffer:ClearSample(2)
buffer:ClearMask(1)
buffer:ClearMask(2)
end
function ChunkGenerator:generateSpecialTerrains()
if self.isGenSurface then
self.specialTerrainProxies.biomeType1 = BiomeType_Surface
self.specialTerrainProxies.biomeID1 = self.surfaceBiomeID
self.specialTerrainProxies.boundary = self.surfaceBoundary
local proxy = {}
proxy[Reg.BiomeID("tc:forest")] = self.genSpecialTerrains_Forest
proxy[Reg.BiomeID("tc:jungle")] = self.genSpecialTerrains_Jungle
proxy[Reg.BiomeID("tc:desert")] = self.genSpecialTerrains_Desert
proxy[Reg.BiomeID("tc:soft_snow_land")] = self.genSpecialTerrains_SoftSnowLand
proxy[Reg.BiomeID("tc:super_volcano")] = self.genSpecialTerrains_SuperVolcano
proxy[Reg.BiomeID("tc:mushroom_fields")] = self.genSpecialTerrains_MushroomFields
local func = proxy[self.surfaceBiomeID]
if func ~= nil then
func(self)
end
end
end
function ChunkGenerator:genSpecialTerrains_Forest()
local ignoreAreas = {}
if self.chunkXi == 0 then
table.insert(ignoreAreas, { 450, 550 })
end
-- lakes
self:_randGenSurfaceLake(0.5, 60, 10, Reg.LiquidID("water"), ignoreAreas)
self:_randGenSurfaceLake(1.0, 40, 15, Reg.LiquidID("water"), ignoreAreas)
-- surface caves
self:_randGenSurfaceCave(1.0, 60, ignoreAreas)
self:_randGenSurfaceCave(3.0, 40, ignoreAreas)
end
function ChunkGenerator:genSpecialTerrains_Jungle()
-- lakes
--self:_randGenSurfaceLake(1.0, 150, 20, Reg.LiquidID("water"))
self:_randGenSurfaceLake(3.0, 60, 10, Reg.LiquidID("water"))
self:_randGenSurfaceLake(2.0, 40, 30, Reg.LiquidID("water"))
-- surface caves
--self:_randGenSurfaceCave(3.0, 50)
--self:_randGenSurfaceCave(2.0, 80)
--self:_randGenSurfaceCave(2.0, 40)
end
function ChunkGenerator:genSpecialTerrains_SoftSnowLand()
-- lakes
self:_randGenSurfaceLake(0.5, 60, 10, Reg.LiquidID("water"))
self:_randGenSurfaceLake(1.0, 40, 15, Reg.LiquidID("water"))
-- surface caves
self:_randGenSurfaceCave(1.0, 60)
self:_randGenSurfaceCave(2.0, 50)
self:_randGenSurfaceCave(4.0, 40)
end
function ChunkGenerator:genSpecialTerrains_SuperVolcano()
-- lakes
self:_randGenSurfaceLake(0.5, 60, 10, Reg.LiquidID("lava"))
self:_randGenSurfaceLake(1.0, 40, 15, Reg.LiquidID("lava"))
-- surface caves
self:_randGenSurfaceCave(1.0, 60)
self:_randGenSurfaceCave(2.0, 50)
self:_randGenSurfaceCave(3.0, 40)
end
function ChunkGenerator:genSpecialTerrains_MushroomFields()
-- lakes
self:_randGenSurfaceLake(1.5, 40, 10, Reg.LiquidID("water"))
self:_randGenSurfaceLake(2.0, 20, 10, Reg.LiquidID("water"))
-- surface caves
self:_randGenSurfaceCave(2.0, 60)
self:_randGenSurfaceCave(3.0, 50)
self:_randGenSurfaceCave(4.0, 40)
end
function ChunkGenerator:getSurfaceMainIndexAtLoop(chunkXi)
return math.abs(chunkXi) % WorldGenDefine.SURFACE_CHUNK_XI_LOOP_TOTALS
end
local SURFACE_MAIN_INDEX_TO_BIOME_MAPPINGS = {
[WorldGenDefine.SURFACE_CHUNK_XI_NEW_GUIDE_FOREST] = Reg.BiomeID("tc:forest"),
[WorldGenDefine.SURFACE_CHUNK_XI_JUNGLE] = Reg.BiomeID("tc:jungle"),
[WorldGenDefine.SURFACE_CHUNK_XI_SNOW] = Reg.BiomeID("tc:soft_snow_land"),
[WorldGenDefine.SURFACE_CHUNK_XI_DUNGEON] = Reg.BiomeID("tc:forest"),
[WorldGenDefine.SURFACE_CHUNK_XI_DESERT] = Reg.BiomeID("tc:desert"),
[WorldGenDefine.SURFACE_CHUNK_XI_TAINTED] = Reg.BiomeID("tc:tainted_land"),
[WorldGenDefine.SURFACE_CHUNK_XI_ICE_DUNGEON] = Reg.BiomeID("tc:flesh"),
[WorldGenDefine.SURFACE_CHUNK_XI_VOLCANO] = Reg.BiomeID("tc:super_volcano"),
[WorldGenDefine.SURFACE_CHUNK_XI_MUSHROOM] = Reg.BiomeID("tc:mushroom_fields"),
[WorldGenDefine.SURFACE_CHUNK_XI_OCEAN] = Reg.BiomeID("tc:ocean"),
}
function ChunkGenerator:getSurfaceMainBiomeID(chunkXi)
local mainIndex = self:getSurfaceMainIndexAtLoop(chunkXi)
local resBiome = SURFACE_MAIN_INDEX_TO_BIOME_MAPPINGS[mainIndex]
if resBiome ~= nil then
return resBiome
end
-- random pick
local maxSurfaceCount = BiomeUtils.GetBiomeCountByType(BiomeType_Surface)
local index = self.noise:GetByteFromInt2D(chunkXi * 233, chunkXi * 73, maxSurfaceCount)
return BiomeUtils.GetBiomeIDByType(BiomeType_Surface, index)
end
function ChunkGenerator:generateSpecialGroup()
if self.surfaceBiomeID == Reg.BiomeID("ocean") then
self:createOceanGroup()
end
end
function ChunkGenerator:createOceanGroup()
local chunkXiInMap = self.chunkXiInMap
local chunkYiInMap = self.chunkYiInMap
local floor = math.floor
local sin = math.sin
local max = math.max
local pi = math.pi
local buffer = self.buffer
local noise = self.noise
local surfaceBoundary = self.surfaceBoundary
local sampleIf = buffer:GetSample(1)
local maskIf = buffer:GetMask(1)
sampleIf.isFrontPreset = true
maskIf.isFrontPreset = true
local sampleApply = buffer:GetSample(2)
local maskApply = buffer:GetMask(2)
sampleApply.isFrontPreset = true
sampleApply.isWallPreset = true
maskApply.isFrontPreset = true
maskApply.isWallPreset = true
local sandID = Reg.BlockID("tc:sand")
for xi = 0, 1023 do
local sands = 15
if xi < 40 then
sands = xi
elseif xi > 1024 - 40 then
sands = 1024 - xi
end
sands = sands + floor(sin(xi / 8.0 * 3.0))
local surfaceYi = surfaceBoundary[xi + 1] - chunkYiInMap
buffer:SetTileAreaByCondition(xi, surfaceYi, 1, sands, sandID, 0, true, 1, 1)
buffer:ApplySampleByMask(xi, surfaceYi + sands, 1, 120 - sands, 2, 2)
end
local x1, x2 = 100, 900
local size, depth = 800, 80
local maxSurfaceYi = -99999999
for xi = x1, x2 - 1 do
local surfaceYi = surfaceBoundary[xi + 1] - chunkYiInMap
maxSurfaceYi = max(maxSurfaceYi, surfaceYi)
local offset = floor(sin((xi - x1) / size * pi) * depth)
buffer:ClearFrontAndWallArea(xi, surfaceYi, 1, offset)
local deepSands = 10 + floor(sin(xi / 2))
buffer:SetTileAreaByCondition(xi, surfaceYi + offset, 1, deepSands, sandID, 0, true, 1, 1)
end
buffer:ClearSample(1)
buffer:ClearMask(1)
buffer:ClearSample(2)
buffer:ClearMask(2)
-- fill water
buffer:GenerateLake((x1 + x2) / 2, maxSurfaceYi, Reg.LiquidID("tc:water"), 9999999)
for i = 0, 2 do
self:createSmallIsland(300 + i * 200 + noise:GetByteFromInt2D(chunkXiInMap, chunkYiInMap + i * 3, 50), maxSurfaceYi, 100)
end
end
function ChunkGenerator:createSmallIsland(x, y, size)
if size <= 0 then
return
end
local abs = math.abs
local floor = math.floor
local max = math.max
local sin = math.sin
local buffer = self.buffer
local noise = self.noise
local surfaceBoundary = self.surfaceBoundary
local size_2 = max(1, floor(size / 2))
local size_4 = max(1, floor(size / 4))
local size_4_3 = max(1, floor(size / 4 * 3))
local size_pi = math.pi / size
local x1 = x - size_2
local oceanY = y
local sandID = Reg.BlockID("tc:sand")
local baseID = Reg.BlockID("tc:prismarine_mud")
for i = 0, size - 1 do
local xi = x1 + i
local offsetY = abs(surfaceBoundary[xi + 1] - oceanY)
if i < size_4 then
offsetY = floor(offsetY * i / size_4)
elseif i > size_4_3 then
offsetY = floor(offsetY * (size - i) / size_4)
end
local surfaceY = oceanY - offsetY
surfaceBoundary[xi + 1] = surfaceY
local len = floor(offsetY * 2 + sin(i * size_pi) * 10)
len = len + floor(sin(i / 4.0) * 2) + noise:GetByteFromInt2D(offsetY + i, offsetY, 2)
local lineY = surfaceY + floor(len / 2)
local bottomY = surfaceY + len
buffer:ClearLiquidArea(xi, surfaceY, 1, len)
buffer:SetTileArea(xi, surfaceY, 1, lineY - surfaceY, sandID, 0, true)
buffer:SetWallArea(xi, surfaceY, 1, lineY - surfaceY, sandID, true)
buffer:SetTileArea(xi, lineY, 1, bottomY - lineY, baseID, 0, true)
buffer:SetWallArea(xi, lineY, 1, bottomY - lineY, baseID, true)
local exOffset = floor(-sin(i / 4.0) * 2) + 8
if i < size_4 then
exOffset = floor(exOffset * i / size_4)
elseif i > size_4_3 then
exOffset = floor(exOffset * (size - i) / size_4)
end
buffer:SetWallArea(xi, bottomY, 1, exOffset, baseID, true)
end
end
function ChunkGenerator:generateSubBiomes()
if self.chunkYi == 0 then
local mainIndex = self:getSurfaceMainIndexAtLoop(self.chunkXi)
if mainIndex == WorldGenDefine.SURFACE_CHUNK_XI_JUNGLE then
self:createSubBiomes(
self.surfaceBoundary,
100, 300, 150,
Reg.BiomeID("tc:desert"),
BiomeType_Surface, self.surfaceBiomeID, self.surfaceBiomeIDArray
)
elseif mainIndex == WorldGenDefine.SURFACE_CHUNK_XI_DUNGEON then
self:createSubBiomes(
self.surfaceBoundary,
120, 400, 150,
Reg.BiomeID("tc:tainted_land"),
BiomeType_Surface, self.surfaceBiomeID, self.surfaceBiomeIDArray
)
elseif mainIndex == WorldGenDefine.SURFACE_CHUNK_XI_DESERT then
self:createSubBiomes(
self.surfaceBoundary,
550, 900, 150,
Reg.BiomeID("tc:badland"),
BiomeType_Surface, self.surfaceBiomeID, self.surfaceBiomeIDArray
)
elseif mainIndex == WorldGenDefine.SURFACE_CHUNK_XI_TAINTED then
self:createSubBiomes(
self.surfaceBoundary,
300, 600, 200,
Reg.BiomeID("tc:jungle"),
BiomeType_Surface, self.surfaceBiomeID, self.surfaceBiomeIDArray
)
elseif mainIndex == WorldGenDefine.SURFACE_CHUNK_XI_ICE_DUNGEON then
self:createSubBiomes(
self.surfaceBoundary,
300, 660, 250,
Reg.BiomeID("tc:soft_snow_land"),
BiomeType_Surface, self.surfaceBiomeID, self.surfaceBiomeIDArray
)
end
end
end
function ChunkGenerator:createPendingBuildings(buildingID, xi, yi, sizeAsSortKey)
table.insert(self._pendingSortableBuildingList, {
buildingID = buildingID,
xi = xi,
yi = yi,
sizeAsSortKey = sizeAsSortKey,
})
end
function ChunkGenerator:_onGenerateBuildings()
if self.chunkYi == 0 then
local mainIndex = self:getSurfaceMainIndexAtLoop(self.chunkXi)
if mainIndex == WorldGenDefine.SURFACE_CHUNK_XI_NEW_GUIDE_FOREST then
-- new player area
for ii = 0, 1 do
-- create house for new player living
local genRightHouse = ii == 0
local houseXi = genRightHouse and 700 or 300
local houseYi = self.surfaceBoundary[houseXi + 1] - self.chunkYiInMap
self.buffer:CreateBuilding(Reg.BuildingID("tc:mini_house"), houseXi, houseYi)
-- create underground houses
local idNames = {
"tc:under_dark_oak_cabin",
"tc:under_jungle_cabin",
"tc:under_oak_cabin",
"tc:under_stone_cabin",
}
local UNDER_CABINS_START_YI = SURFACE_LINE + 100
local UNDER_CABINS_SIZE = 500
local CABINS_PRE_CNT = 8
for i, idName in ipairs(idNames) do
local buildingID = Reg.BuildingID(idName)
local mainArea = WorldGenArea.new(self.chunkXiInMap, UNDER_CABINS_START_YI, 1024, UNDER_CABINS_SIZE)
local areas = self.buffer:GetRandomAreas(self.chunkXiInMap + self.chunkYiInMap + 11233 + i * 7,
mainArea, 1, 1, 1, 1, CABINS_PRE_CNT
)
---@param area WorldGenArea
for _, area in ipairs(areas) do
local xi = area.xi - self.chunkXiInMap
local yi = area.yi - self.chunkYiInMap
self.buffer:CreateBuilding(buildingID, xi, yi)
end
end
end
elseif mainIndex == WorldGenDefine.SURFACE_CHUNK_XI_JUNGLE then
-- jungle zone
--local houseXi = 400
--local houseYi = self.surfaceBoundary[houseXi + 1] - self.chunkYiInMap
--self.buffer:CreateBuilding(Reg.BuildingID("tc:jungle_temple"), houseXi, houseYi)
elseif mainIndex == WorldGenDefine.SURFACE_CHUNK_XI_SNOW then
local houseXi = 500
local houseYi = self.surfaceBoundary[houseXi + 1] - self.chunkYiInMap
self.buffer:CreateBuilding(Reg.BuildingID("tc:aurora_palace"), houseXi, houseYi)
elseif mainIndex == WorldGenDefine.SURFACE_CHUNK_XI_OCEAN then
local houseXi = 500
local houseYi = self.surfaceBoundary[houseXi + 1] + 80
self.buffer:CreateBuilding(Reg.BuildingID("tc:monument_ocean"), houseXi, houseYi)
end
end
if self.isGenNether then
local genYi = NETHER_LAVA_LINE - 50 - self.chunkYiInMap
self.buffer:CreateBuilding(Reg.BuildingID("tc:nether_fortress"), 500, genYi)
end
if self.isGenUnderground then
-- create underground houses
local idNames = {
"tc:under_dark_oak_cabin",
"tc:under_jungle_cabin",
"tc:under_oak_cabin",
"tc:under_stone_cabin",
"tc:under_spruce_cabin",
"tc:under_tainted_cabin",
"tc:under_desert_cabin",
}
local UNDER_CABINS_START_YI = UNDERGROUND_LINE
local UNDER_CABINS_SIZE = NETHER_LINE - UNDERGROUND_LINE
local CABINS_PRE_CNT = 2
for i, idName in ipairs(idNames) do
self:_genTargetBuilding(Reg.BuildingID(idName),
UNDER_CABINS_START_YI, UNDER_CABINS_SIZE, CABINS_PRE_CNT,
self.chunkXiInMap + self.chunkYiInMap + 657 + i * 7)
end
end
-- health crystals
self:_genTargetBuilding(Reg.BuildingID("heart"),
SURFACE_LINE + 100, NETHER_LAVA_LINE - SURFACE_LINE, 30,
self.chunkXiInMap + self.chunkYiInMap + 1785)
-- fossils
self:_genTargetBuilding(Reg.BuildingID("fossils"),
SURFACE_LINE + 100, NETHER_LINE - SURFACE_LINE, 30,
self.chunkXiInMap * 2 + self.chunkYiInMap + 131)
end
function ChunkGenerator:_genTargetBuilding(buildingID, startYiInMap, height, density, randomKey)
local mainArea = WorldGenArea.new(self.chunkXiInMap, startYiInMap, 1024, height)
local areas = self.buffer:GetRandomAreas(randomKey,
mainArea, 1, 1, 1, 1, density
)
---@param area WorldGenArea
for _, area in ipairs(areas) do
local xi = area.xi - self.chunkXiInMap
local yi = area.yi - self.chunkYiInMap
self.buffer:CreateBuilding(buildingID, xi, yi)
end
end
function ChunkGenerator:_specialMakeCave()
self:makeCaveHorizontalPoly(self:getUndergroundRealPolygon(self:_getPolyJungle()), 654,
30, 250, 15, 23, 120.0,
0.01, 0.5, 8, 60.0,
0.15, 0.3, 4, 10.0,
0.3, 0.3, 4, 2.0
)
self:makeCaveHorizontalPoly(self:getUndergroundRealPolygon(self:_getPolyBlueMushroom()), 654,
30, 250, 15, 43, 290.0,
0.01, 0.5, 8, 60.0,
0.15, 0.3, 4, 10.0,
0.3, 0.3, 4, 2.0
)
self:makeCaveHorizontalPoly(self:getUndergroundRealPolygon(self:_getPolyBlueMushroom2()), 654,
30, 250, 15, 43, 290.0,
0.01, 0.5, 8, 60.0,
0.15, 0.3, 4, 10.0,
0.3, 0.3, 4, 2.0
)
self:makeCaveHorizontalPoly(self:getUndergroundRealPolygon(self:_getPolyDeepIce()), 654,
80, 180, 8, 12, 280.0,
0.01, 0.5, 8, 12.0,
0.15, 0.3, 4, 10.0,
0.3, 0.3, 4, 2.0
)
-- nether
if self.isGenNether then
self:_genNetherCave()
end
end
function ChunkGenerator:_genNetherCave()
local buffer = self.buffer
local wga = WorldGenArea.new(self.chunkXiInMap, NETHER_LAVA_LINE - NETHER_LAVE_CAVE_HEIGHT, 1024, NETHER_LAVE_CAVE_HEIGHT)
local areas = buffer:GetRandomAreas(155, wga,
130, 250,
15, 23, 320.0
)
---@param area WorldGenArea
for _, area in ipairs(areas) do
buffer:PerlinMakeCaveHorizontal(
area.xi - self.chunkXiInMap, area.yi - self.chunkYiInMap, area.wi, area.hi,
0.01, 0.5, 8, 12.0,
0.15, 0.3, 4, 10.0,
0.3, 0.3, 4, 2.0
)
end
end
function ChunkGenerator:_getPolyJungle()
return {
--400, 500,
--200, 800,
--600, 1300,
--900, 700,
1024, 500,
800, 1200,
1400, 1600,
2000, 1400,
2200, 1000,
2048, 500
}
end
function ChunkGenerator:_getPolyDeepIce()
return {
2048 + 100, 500,
2048 - 400, 1500,
3096 + 400, 1500,
3096 - 100, 500
}
end
function ChunkGenerator:_getPolyBlueMushroom()
return {
400, 600,
300, 900,
700, 1000,
800, 800
}
end
function ChunkGenerator:_getPolyBlueMushroom2()
local l, r = 1024 * 7, 1024 * 8
return {
l + 400, 600,
l + 100, 1800,
l + 700, 1900,
l + 800, 800
}
end
function ChunkGenerator:_getPolyTainted()
local l, r = 1024 * 5, 1024 * 6
return {
l, 500,
r, 1800,
r + 500, 1800,
l + 500, 500
}
end
function ChunkGenerator:_getPolyFlesh()
local l, r = 1024 * 6, 1024 * 7
return {
l + 500, 500,
l - 500, 1800,
l, 1800,
r, 500
}
end
function ChunkGenerator:getUndergroundRealPolygon(polys)
local polyDir = 0
if self.chunkXi > 0 then
polyDir = 1
elseif self.chunkXi < 0 then
polyDir = -1
end
local loopIndex = math.floor(math.abs(self.chunkXi) / WorldGenDefine.SURFACE_CHUNK_XI_LOOP_TOTALS)
local fixSideMove = loopIndex * 1024 * WorldGenDefine.SURFACE_CHUNK_XI_LOOP_TOTALS
local fixSidePolys = clone(polys)
for i = 1, #fixSidePolys, 2 do
fixSidePolys[i] = fixSidePolys[i] + fixSideMove
end
if polyDir == -1 then
for i = 1, #fixSidePolys, 2 do
fixSidePolys[i] = -fixSidePolys[i]
end
end
return fixSidePolys
end
function ChunkGenerator:writeUndergroundPolygon(polys, biomeID)
local fixSidePolys = self:getUndergroundRealPolygon(polys)
self:writeBiomeMatrixPolygon(fixSidePolys, self.undergroundBiomeIDMatrix, biomeID)
end
function ChunkGenerator:_specialGenUndergroundBiome()
self:writeUndergroundPolygon(self:_getPolyJungle(), Reg.BiomeID("tc:jungle_cave"))
self:writeUndergroundPolygon(self:_getPolyDeepIce(), Reg.BiomeID("tc:deep_ice_cave"))
self:writeUndergroundPolygon(self:_getPolyBlueMushroom(), Reg.BiomeID("tc:blue_mushroom_cave"))
self:writeUndergroundPolygon(self:_getPolyBlueMushroom2(), Reg.BiomeID("tc:blue_mushroom_cave"))
self:writeUndergroundPolygon(self:_getPolyTainted(), Reg.BiomeID("tc:tainted_cave"))
self:writeUndergroundPolygon(self:_getPolyFlesh(), Reg.BiomeID("tc:flesh_cave"))
end
return ChunkGenerator
================================================
FILE: world_gen/ModChunkGenerator.lua
================================================
---@class TC.ModChunkGenerator
local ModChunkGenerator = class("ModChunkGenerator")
local s_proxy = {}
---__init
---@param generator TC.ChunkGenerator
function ModChunkGenerator:__init(generator)
---@type TC.ChunkGenerator
self._generator = generator
end
function ModChunkGenerator.getProxy()
return s_proxy
end
function ModChunkGenerator.register(modChunkGeneratorClass)
table.insert(s_proxy, modChunkGeneratorClass)
end
function ModChunkGenerator.destroy()
s_proxy = {}
end
function ModChunkGenerator:onInitLayer()
end
function ModChunkGenerator:onGenerateUndergroundMatrix()
end
function ModChunkGenerator:onGenerateBuildings()
end
function ModChunkGenerator:onPostGenerateCaves()
end
return ModChunkGenerator
================================================
FILE: world_gen/SpecialTerrainProxies.lua
================================================
---@class TC.SpecialTerrainProxies
---Store all calculation about how to modify the map.
---
---维护所有通用改变地形的算法。
local SpecialTerrainProxies = class("SpecialTerrainProxies")
---@param buffer WorldGenChunkBuffer
---@param noise WorldGenNoise
---@param chunkYiInMap int
function SpecialTerrainProxies:__init(buffer, noise, chunkYiInMap)
self._proxies = {
SurfaceCave = SpecialTerrainProxies.createSurfaceCave,
}
self.chunkYiInMap = chunkYiInMap
self.boundary = nil
self.boundary2 = nil
self.boundary3 = nil
self.biomeType1 = 0
self.biomeType2 = 0
self.biomeType3 = 0
self.biomeID1 = 0
self.biomeID2 = 0
self.biomeID3 = 0
self._buffer = buffer
self._noise = noise
end
function SpecialTerrainProxies.checkXArea(x1, x2)
x1 = math.max(0, x1)
x2 = math.min(1023, x2)
if x1 >= x2 then
return x1, x2, false
end
return x1, x2, true
end
function SpecialTerrainProxies:createSurfaceCave(x1, x2)
local valid = true
x1, x2, valid = SpecialTerrainProxies.checkXArea(x1, x2)
if not valid then
return
end
local boundary = self.boundary
local noise = self._noise
local buffer = self._buffer
local chunkYiInMap = self.chunkYiInMap
local sample1 = buffer:GetSample(1)
sample1.isFrontPreset = true
sample1.isWallPreset = true
sample1.biomeType = self.biomeType1
sample1.biomeID = self.biomeID1
local mask1 = buffer:GetMask(1)
mask1.isFrontPreset = true
mask1.isWallPreset = true
mask1.biomeType = true
mask1.biomeID = true
local sample2 = buffer:GetSample(2)
sample2.isWallPreset = true
sample2.biomeType = self.biomeType1
sample2.biomeID = self.biomeID1
local mask2 = buffer:GetMask(2)
mask2.isWallPreset = true
mask2.biomeType = true
mask2.biomeID = true
for xi = x1, x2 - 1 do
local surfaceYi = boundary[xi + 1] - chunkYiInMap
local offset = math.floor(10 + math.sin((xi + surfaceYi) * 0.125) * 2)
local length = 5
offset = offset + noise:GetByteFromInt2D(xi, offset, 1)
length = length + noise:GetByteFromInt2D(xi + 2, length, 1)
if xi < x1 + 6 then
length = math.floor(length * (1 - (x1 + 6 - xi) / 6.0))
end
if xi > x2 - 6 then
length = math.floor(length * (1 - (xi - (x2 - 6)) / 6.0))
end
local backLength = offset
if xi < x1 + 4 then
backLength = math.floor(backLength * (1 - (x1 + 4 - xi) / 4.0))
end
if xi > x2 - 4 then
backLength = math.floor(backLength * (1 - (xi - (x2 - 4)) / 4.0))
end
local y0 = surfaceYi - offset
-- fill solid
buffer:ApplySampleByMask(xi, y0 - length, 1, length, 1, 1)
-- fill wall
buffer:ApplySampleByMask(xi, y0, 1, backLength, 2, 2)
boundary[xi + 1] = y0 - length
end
buffer:ClearSample(1)
buffer:ClearMask(1)
buffer:ClearSample(2)
buffer:ClearMask(2)
end
function SpecialTerrainProxies:createSurfaceLake(x1, x2, liquidID, depth)
local valid = true
x1, x2, valid = SpecialTerrainProxies.checkXArea(x1, x2)
if not valid then
return
end
local size = x2 - x1
local boundary = self.boundary
local noise = self._noise
local buffer = self._buffer
local chunkYiInMap = self.chunkYiInMap
local sample1 = buffer:GetSample(1)
sample1.isLiquidPreset = true
local mask1 = buffer:GetMask(1)
mask1.isLiquidPreset = true
local failed = false
for xi = x1, x2 - 1 do
local surfaceYi = boundary[xi + 1] - chunkYiInMap
if buffer:HasAreaSameSampleByMask(xi, surfaceYi - 1, 1, depth + 1, 1, 1) then
failed = true
break
end
end
if not failed then
local maxSurfaceYi = -999999999
for xi = x1, x2 - 1 do
local surfaceYi = boundary[xi + 1] - chunkYiInMap
maxSurfaceYi = math.max(maxSurfaceYi, surfaceYi)
local offset = math.floor(math.sin((xi - x1) / size * math.pi) * depth)
buffer:ClearFrontAndWallArea(xi, surfaceYi, 1, offset)
boundary[xi + 1] = surfaceYi + offset
end
buffer:GenerateLake((x1 + x2) / 2, maxSurfaceYi, liquidID, 10000)
end
buffer:ClearSample(1)
buffer:ClearMask(1)
end
return SpecialTerrainProxies
================================================
FILE: world_gen/TerrainProxies.lua
================================================
---@class TC.TerrainProxies
---Store all calculation about how to modify a boundary array.
---
---维护所有可以改变边界数组的算法。
local TerrainProxies = class("TerrainProxies")
function TerrainProxies:__init()
self._proxies = {
FlatTerrain = TerrainProxies.calculateBoundary_FlatTerrain,
MountainTerrain = TerrainProxies.calculateBoundary_MountainTerrain,
HillTerrain = TerrainProxies.calculateBoundary_HillTerrain,
BasinTerrain = TerrainProxies.calculateBoundary_BasinTerrain,
PlateauTerrain = TerrainProxies.calculateBoundary_PlateauTerrain,
}
end
--- Modify the boundary array by specify terrain function.
---@param terrainName string
---@param boundary double[]
---@param xi int
---@param size int
---@param height int
function TerrainProxies:calculateBoundaryFromTerrain(terrainName, boundary, xi, size, height)
if size > 1010 then
-- too big, do nothing.
return
end
local func = self._proxies[terrainName]
if func == nil then
return
end
local x1, x2 = xi - math.floor(size / 2), xi + math.floor(size / 2)
if x1 < 0 then
x1 = 0
x2 = x1 + size
end
if x2 >= 1024 then
x2 = 1023
x1 = x2 - size
end
if x2 > x1 then
func(self, boundary, x1, x2, height)
end
end
--- Flat, do nothing.
---
--- 平坦,什么都不做
function TerrainProxies:calculateBoundary_FlatTerrain(boundary, x1, x2, height)
return
end
--- Mountain, a SIN function.
---
--- 大山(坟包),长得像三角函数的样子
function TerrainProxies:calculateBoundary_MountainTerrain(boundary, x1, x2, height)
local sin = math.sin
local size = x2 - x1
local c = math.pi / size
for x = x1, x2 - 1 do
local res = sin((x - x1) * c) * height
boundary[x + 1] = boundary[x + 1] - res
end
end
--- 丘陵
function TerrainProxies:calculateBoundary_HillTerrain(boundary, x1, x2, height)
local sin = math.sin
local size = x2 - x1
local c = math.pi / 64
local offset = math.floor(size / 4)
local invOffset = 1.0 / offset
for x = x1, x2 - 1 do
local res = sin((x - x1) * c) * height
if x < x1 + offset then
res = res * (1 - (x1 + offset - x) * invOffset)
end
if x > x2 - offset then
res = res * (1 - (x - x2 + offset) * invOffset)
end
boundary[x + 1] = boundary[x + 1] - res
end
end
--- 盆地
function TerrainProxies:calculateBoundary_BasinTerrain(boundary, x1, x2, height)
local sin = math.sin
local size = x2 - x1
local c = math.pi / size
for x = x1, x2 - 1 do
local res = sin((x - x1) * c) * height
boundary[x + 1] = boundary[x + 1] + res
end
end
--- 高原
function TerrainProxies:calculateBoundary_PlateauTerrain(boundary, x1, x2, height)
local size = x2 - x1
local d = math.floor(size / 32)
if d == 0 then
return
end
local sin = math.sin
local side = math.floor(size / 16)
local halfSide = math.floor(size / 32)
local leftSide = x1 + side
local halfLeftSide = x1 + halfSide
local rightSide = x2 - side
local halfRightSide = x2 - halfSide
local halfHeight = height * 0.5
local c = math.pi * 0.5 / d
for x = x1, leftSide - 1 do
local res = sin((x - halfLeftSide) * c) * halfHeight + halfHeight
boundary[x + 1] = boundary[x + 1] - res
end
for x = leftSide, rightSide - 1 do
boundary[x + 1] = boundary[x + 1] - height
end
for x = rightSide, x2 - 1 do
local res = sin((halfRightSide - x) * c) * halfHeight + halfHeight
boundary[x + 1] = boundary[x + 1] - res
end
end
return TerrainProxies
================================================
FILE: world_gen/TransitionProxies.lua
================================================
---@class TC.SurfaceTransitionProxies
---Store all algorithms of how to transition between surface biomes.
---
---维护地表结构的群系过渡算法。
local SurfaceTransitionProxies = class("TransitionProxies")
---__init
---@param chunkXi int
---@param chunkYi int
---@param noise WorldGenNoise
---@param buffer WorldGenChunkBuffer
function SurfaceTransitionProxies:__init(chunkXi, chunkYi, noise, buffer)
-- TODO:DiscreteTransition
self._noise = noise
self._buffer = buffer
self._chunkXi = chunkXi
self._chunkYi = chunkYi
self._levelProxies = {
LinerTransition = SurfaceTransitionProxies.getTransitionLevel_Liner,
ParabolaTransition = SurfaceTransitionProxies.getTransitionLevel_Parabola,
DiscreteTransition = SurfaceTransitionProxies.getTransitionLevel_Discrete,
}
end
---doTransition
---@param leftTransitionName string
---@param rightTransitionName string
---@param x1 int
---@param x2 int
---@param topBoundary int[]
---@param bottomBoundary int[]
---@param biomeInfo table
---@param checkFromChunkTop boolean
---@param checkFromChunkBottom boolean
function SurfaceTransitionProxies:doTransition(leftTransitionName, rightTransitionName, x1, x2, topBoundary, bottomBoundary,
biomeInfo, checkFromChunkTop, checkFromChunkBottom)
if not (x1 >= 0 and x2 <= 1024 and x2 > x1) then
return
end
local isLeftTransiting = (leftTransitionName ~= nil)
local isRightTransiting = (rightTransitionName ~= nil)
if not isLeftTransiting and not isRightTransiting then
return
end
local leftFunc
local rightFunc
if isLeftTransiting then
leftFunc = self._levelProxies[leftTransitionName]
if leftFunc == nil then
return
end
end
if isRightTransiting then
rightFunc = self._levelProxies[rightTransitionName]
if rightFunc == nil then
return
end
end
local max = math.max
local min = math.min
local floor = math.floor
local buffer = self._buffer
local noise = self._noise
local chunkXiInMap = self._chunkXi * 1024
local chunkYiInMap = self._chunkYi * 1024
local leftBiomeType = biomeInfo[1][1]
local leftBiomeID = biomeInfo[1][2]
local rightBiomeType = biomeInfo[3][1]
local rightBiomeID = biomeInfo[3][2]
local currentBiomeType = biomeInfo[2][1]
local currentBiomeID = biomeInfo[2][2]
local centerXi = floor((x1 + x2) / 2)
if currentBiomeType ~= leftBiomeType or currentBiomeType ~= rightBiomeType then
return
end
for xi = x1, x2 - 1 do
local mapXi = chunkXiInMap + xi
local usingLevelFlag = 0
local level = 0
local adjBiomeID = currentBiomeID
local inLeftSide = xi < centerXi
if inLeftSide then
if isLeftTransiting then
usingLevelFlag = 1
level = leftFunc(noise, mapXi, xi - x1)
adjBiomeID = leftBiomeID
end
else
if isRightTransiting then
usingLevelFlag = 2
level = rightFunc(noise, mapXi, x2 - xi)
adjBiomeID = rightBiomeID
end
end
local top = 0
local bottom = 1024
local topBoundaryValue = topBoundary[xi + 1]
local bottomBoundaryValue = bottomBoundary[xi + 1]
if not checkFromChunkTop then
top = max(topBoundaryValue - chunkYiInMap, 0)
end
if not checkFromChunkBottom then
bottom = min(bottomBoundaryValue - chunkYiInMap, 1024)
end
if usingLevelFlag ~= 0 then
local splitYi = math.max(0, topBoundaryValue - chunkYiInMap + level)
buffer:SetBiomeIDAreaByBiomeType(xi, top, 1, splitYi, currentBiomeType, currentBiomeID)
buffer:SetBiomeIDAreaByBiomeType(xi, splitYi, 1, bottom - splitYi, currentBiomeType, adjBiomeID)
else
buffer:SetBiomeIDAreaByBiomeType(xi, top, 1, bottom - top, currentBiomeType, currentBiomeID)
end
end
end
---y=x
function SurfaceTransitionProxies.getTransitionLevel_Liner(noise, mapXi, d)
return noise:GetDoubleFromInt1D(mapXi) * 2 + d
end
---y=x^2
function SurfaceTransitionProxies.getTransitionLevel_Parabola(noise, mapXi, d)
return noise:GetDoubleFromInt1D(mapXi) * 2 + d * d * 0.01
end
---y=x
function SurfaceTransitionProxies.getTransitionLevel_Discrete(noise, mapXi, d)
return SurfaceTransitionProxies.getTransitionLevel_Liner(noise, mapXi, d)
end
return SurfaceTransitionProxies
================================================
FILE: world_gen/WorldGenDefine.lua
================================================
---@class TC.WorldGenDefine
local WorldGenDefine = {
SURFACE_LINE = 400, -- line between surface layer and air layer
UNDERGROUND_LINE = 600, -- line between surface layer and underground layer
NETHER_LINE = 2560, -- line between underground layer and nether layer
NETHER_LAVA_LINE = 2700, -- line to start generating nether large lava lake
NETHER_LAVE_CAVE_HEIGHT = 60, -- the height of nether large cave
UNDERGROUND_LAKE_LINE = 1536, -- line to start generating lava lake
BEDROCK_CHUNK_YI = 3, -- bedrock layer chunk y index
SURFACE_CHUNK_XI_NEW_GUIDE_FOREST = 0, -- new player's forest
SURFACE_CHUNK_XI_JUNGLE = 1, -- jungle with small desert and ghost house
SURFACE_CHUNK_XI_SNOW = 2, -- snow land with palace and danger caves
SURFACE_CHUNK_XI_DUNGEON = 3, -- a terraria style dungeon area
SURFACE_CHUNK_XI_DESERT = 4, -- a large desert area with pyramid dungeon and wasteland
SURFACE_CHUNK_XI_TAINTED = 5, -- a large tainted area
SURFACE_CHUNK_XI_ICE_DUNGEON = 6, -- snow land with ice dungeon
SURFACE_CHUNK_XI_VOLCANO = 7, -- volcano with castle
SURFACE_CHUNK_XI_MUSHROOM = 8, -- peaceful mushroom island
SURFACE_CHUNK_XI_OCEAN = 9, -- ocean
SURFACE_CHUNK_XI_LOOP_TOTALS = 10
}
return WorldGenDefine
================================================
FILE: world_gen_init.lua
================================================
local TCWorldGen = class("TCWorldGen")
local ChunkGenerator = require("world_gen.ChunkGenerator")
local ModChunkGenerator = require("world_gen.ModChunkGenerator")
function TCWorldGen:init()
self.noise = nil ---@type WorldGenNoise
end
function TCWorldGen:exit()
ModChunkGenerator.destroy()
end
function TCWorldGen:startGenChunk(chunkXi, chunkYi, noise, buffer)
self.noise = noise
local chunkGenerator = ChunkGenerator.new(chunkXi, chunkYi, noise, buffer)
chunkGenerator:start()
chunkGenerator:destroy()
collectgarbage()
end
function TCWorldGen:onSetBlockEntityFormat(formatId, data, xi, yi)
local function _randomIndices(totals)
local arr = {}
local out = {}
for i = 1, totals do
arr[i] = i
end
for i = 1, totals do
local pickIndex = self.noise:GetByteFromInt2D(xi + 451 * i, yi + 23, #arr) + 1
table.insert(out, arr[pickIndex])
table.remove(arr, pickIndex)
end
return out
end
if formatId == "tc:common_rewards" then
local res = {}
local inventoryData = {
slotCount = 30,
stacks = {}
}
local index = 0
local function addReward(i, itemID, cnt)
local out = { index = i, stack = {
id = itemID, stackSize = cnt
} }
return out
end
local totalRares = #data.rares
local ranIndices = _randomIndices(totalRares)
for i = 1, math.min(#ranIndices, data.rareGenCount) do
local rare = data.rares[ranIndices[i]]
local out = addReward(index, rare.itemId, rare.count)
table.insert(inventoryData.stacks, out)
index = index + 1
end
for i = 1, #data.normals do
local normal = data.normals[i]
local testRate = math.abs(self.noise:GetDoubleFromInt2D(xi + 33 * i, yi + 77))
if testRate < normal.rate then
local cnt = normal.min + self.noise:GetByteFromInt2D(xi * 13, yi + 57, normal.max - normal.min)
local itemID = normal.itemIds[
self.noise:GetByteFromInt2D(xi + 62, yi + 98, #normal.itemIds) + 1
]
local out = addReward(index, itemID, cnt)
table.insert(inventoryData.stacks, out)
index = index + 1
end
end
res = {
inventory = inventoryData
}
return res
elseif formatId == "tc:rewards" then
return data
elseif formatId == "tc:empty_furnace" then
return {}
end
return data
end
return TCWorldGen