1
0
mirror of https://github.com/chylex/Hardcore-Ender-Expansion-2.git synced 2025-09-15 14:32:09 +02:00

2 Commits

Author SHA1 Message Date
32ea34fa0c SHELF 2021-01-15 18:42:49 +01:00
2ab4659da5 [WIP] Tomb Dungeon 2021-01-15 18:40:13 +01:00
94 changed files with 3073 additions and 672 deletions

1
.gitignore vendored
View File

@@ -14,6 +14,7 @@ out
!.idea/kotlinc.xml
!.idea/statistic.xml
!.idea/vcs.xml
!.idea/shelf
# eclipse
bin

4
.idea/shelf/Datagen_Recipes.xml generated Normal file
View File

@@ -0,0 +1,4 @@
<changelist name="Datagen_Recipes" date="1601734824200" recycled="true">
<option name="PATH" value="$PROJECT_DIR$/.idea/shelf/Datagen_Recipes/shelved.patch" />
<option name="DESCRIPTION" value="Datagen Recipes" />
</changelist>

View File

@@ -0,0 +1,79 @@
Index: data/src/main/java/chylex/hee/datagen/DataGen.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.BaseRevisionTextPatchEP
<+>package chylex.hee.datagen\nimport chylex.hee.HEE\nimport chylex.hee.datagen.client.BlockItemModels\nimport chylex.hee.datagen.client.BlockModels\nimport chylex.hee.datagen.client.BlockStates\nimport chylex.hee.datagen.client.ItemModels\nimport chylex.hee.system.forge.SubscribeAllEvents\nimport chylex.hee.system.forge.SubscribeEvent\nimport net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus.MOD\nimport net.minecraftforge.fml.event.lifecycle.GatherDataEvent\n\n@SubscribeAllEvents(modid = HEE.ID, bus = MOD)\nobject DataGen{\n\t@SubscribeEvent\n\tfun register(e: GatherDataEvent){\n\t\tval modid = HEE.ID\n\t\tval helper = e.existingFileHelper\n\t\t\n\t\twith(e.generator){\n\t\t\tif (e.includeClient()){\n\t\t\t\taddProvider(BlockStates(this, modid, helper))\n\t\t\t\taddProvider(BlockModels(this, modid, helper))\n\t\t\t\taddProvider(BlockItemModels(this, modid, helper))\n\t\t\t\taddProvider(ItemModels(this, modid, helper))\n\t\t\t}\n\t\t}\n\t}\n}\n
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- a/data/src/main/java/chylex/hee/datagen/DataGen.kt (revision f8888e0a3b33898551301124a0879cea12fc1f06)
+++ b/data/src/main/java/chylex/hee/datagen/DataGen.kt (date 1601732788951)
@@ -4,6 +4,7 @@
import chylex.hee.datagen.client.BlockModels
import chylex.hee.datagen.client.BlockStates
import chylex.hee.datagen.client.ItemModels
+import chylex.hee.datagen.server.Recipes
import chylex.hee.system.forge.SubscribeAllEvents
import chylex.hee.system.forge.SubscribeEvent
import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus.MOD
@@ -23,6 +24,10 @@
addProvider(BlockItemModels(this, modid, helper))
addProvider(ItemModels(this, modid, helper))
}
+
+ if (e.includeServer()){
+ addProvider(Recipes(this))
+ }
}
}
}
Index: data/src/main/java/chylex/hee/datagen/server/Recipes.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- /dev/null (date 1601733265753)
+++ b/data/src/main/java/chylex/hee/datagen/server/Recipes.kt (date 1601733265753)
@@ -0,0 +1,15 @@
+package chylex.hee.datagen.server
+import chylex.hee.datagen.server.util.ingredients
+import chylex.hee.datagen.server.util.shapeless
+import chylex.hee.init.ModItems
+import net.minecraft.data.DataGenerator
+import net.minecraft.data.IFinishedRecipe
+import net.minecraft.data.RecipeProvider
+import net.minecraft.item.Items
+import java.util.function.Consumer
+
+class Recipes(generator: DataGenerator) : RecipeProvider(generator){
+ override fun registerRecipes(consumer: Consumer<IFinishedRecipe>) = with(consumer){
+ shapeless(ModItems.ALTERATION_NEXUS, 1){ ingredients(Items.DIAMOND, Items.ENDER_EYE, ModItems.ANCIENT_DUST, ModItems.ETHEREUM) }
+ }
+}
Index: data/src/main/java/chylex/hee/datagen/server/util/RecipeProviderExt.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- /dev/null (date 1601733249382)
+++ b/data/src/main/java/chylex/hee/datagen/server/util/RecipeProviderExt.kt (date 1601733249382)
@@ -0,0 +1,20 @@
+package chylex.hee.datagen.server.util
+import net.minecraft.data.IFinishedRecipe
+import net.minecraft.data.ShapedRecipeBuilder
+import net.minecraft.data.ShapelessRecipeBuilder
+import net.minecraft.util.IItemProvider
+import java.util.function.Consumer
+
+fun Consumer<IFinishedRecipe>.shaped(result: IItemProvider, amount: Int, callback: ShapedRecipeBuilder.() -> Unit){
+ ShapedRecipeBuilder(result, amount).apply(callback).build(this)
+}
+
+fun Consumer<IFinishedRecipe>.shapeless(result: IItemProvider, amount: Int, callback: ShapelessRecipeBuilder.() -> Unit){
+ ShapelessRecipeBuilder(result, amount).apply(callback).build(this)
+}
+
+fun ShapelessRecipeBuilder.ingredients(vararg ingredients: IItemProvider){
+ for(ingredient in ingredients){
+ this.addIngredient(ingredient)
+ }
+}

4
.idea/shelf/Development3.xml generated Normal file
View File

@@ -0,0 +1,4 @@
<changelist name="Development3" date="1601983889370" recycled="true">
<option name="PATH" value="$PROJECT_DIR$/.idea/shelf/Development3/shelved.patch" />
<option name="DESCRIPTION" value="Development" />
</changelist>

18
.idea/shelf/Development3/shelved.patch generated Normal file

File diff suppressed because one or more lines are too long

4
.idea/shelf/Dust.xml generated Normal file
View File

@@ -0,0 +1,4 @@
<changelist name="Dust" date="1590783410567" recycled="false">
<option name="PATH" value="$PROJECT_DIR$/.idea/shelf/Dust/shelved.patch" />
<option name="DESCRIPTION" value="Dust" />
</changelist>

210
.idea/shelf/Dust/shelved.patch generated Normal file

File diff suppressed because one or more lines are too long

4
.idea/shelf/EnderEyeAttack_kt.xml generated Normal file
View File

@@ -0,0 +1,4 @@
<changelist name="EnderEyeAttack_kt" date="1601761992769" recycled="true">
<option name="PATH" value="$PROJECT_DIR$/.idea/shelf/EnderEyeAttack_kt/shelved.patch" />
<option name="DESCRIPTION" value="EnderEyeAttack.kt" />
</changelist>

File diff suppressed because one or more lines are too long

4
.idea/shelf/Ender_Eye.xml generated Normal file
View File

@@ -0,0 +1,4 @@
<changelist name="Ender_Eye" date="1595119986895" recycled="true">
<option name="PATH" value="$PROJECT_DIR$/.idea/shelf/Ender_Eye/shelved.patch" />
<option name="DESCRIPTION" value="Ender Eye" />
</changelist>

69
.idea/shelf/Ender_Eye/shelved.patch generated Normal file

File diff suppressed because one or more lines are too long

4
.idea/shelf/Ender_Eye_Stuff.xml generated Normal file
View File

@@ -0,0 +1,4 @@
<changelist name="Ender_Eye_Stuff" date="1601351827334" recycled="true">
<option name="PATH" value="$PROJECT_DIR$/.idea/shelf/Ender_Eye_Stuff/shelved.patch" />
<option name="DESCRIPTION" value="Ender Eye Stuff" />
</changelist>

172
.idea/shelf/Ender_Eye_Stuff/shelved.patch generated Normal file

File diff suppressed because one or more lines are too long

4
.idea/shelf/Eye.xml generated Normal file
View File

@@ -0,0 +1,4 @@
<changelist name="Eye" date="1605472809585" recycled="true">
<option name="PATH" value="$PROJECT_DIR$/.idea/shelf/Eye/shelved.patch" />
<option name="DESCRIPTION" value="Eye" />
</changelist>

723
.idea/shelf/Eye/shelved.patch generated Normal file

File diff suppressed because one or more lines are too long

4
.idea/shelf/Ideas.xml generated Normal file
View File

@@ -0,0 +1,4 @@
<changelist name="Ideas" date="1595089578362" recycled="false">
<option name="PATH" value="$PROJECT_DIR$/.idea/shelf/Ideas/shelved.patch" />
<option name="DESCRIPTION" value="Ideas" />
</changelist>

54
.idea/shelf/Ideas/shelved.patch generated Normal file

File diff suppressed because one or more lines are too long

4
.idea/shelf/Later.xml generated Normal file
View File

@@ -0,0 +1,4 @@
<changelist name="Later" date="1579750352473" recycled="false">
<option name="PATH" value="$PROJECT_DIR$/.idea/shelf/Later/shelved.patch" />
<option name="DESCRIPTION" value="Later" />
</changelist>

36
.idea/shelf/Later/shelved.patch generated Normal file

File diff suppressed because one or more lines are too long

4
.idea/shelf/Later1.xml generated Normal file
View File

@@ -0,0 +1,4 @@
<changelist name="Later1" date="1607753523089" recycled="true">
<option name="PATH" value="$PROJECT_DIR$/.idea/shelf/Later1/shelved.patch" />
<option name="DESCRIPTION" value="Later" />
</changelist>

81
.idea/shelf/Later1/shelved.patch generated Normal file

File diff suppressed because one or more lines are too long

4
.idea/shelf/Later2.xml generated Normal file
View File

@@ -0,0 +1,4 @@
<changelist name="Later2" date="1610732422264" recycled="false">
<option name="PATH" value="$PROJECT_DIR$/.idea/shelf/Later2/shelved.patch" />
<option name="DESCRIPTION" value="Later" />
</changelist>

19
.idea/shelf/Later2/shelved.patch generated Normal file
View File

@@ -0,0 +1,19 @@
Index: src/system/src/main/java/chylex/hee/game/entity/EntitySelector.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.BaseRevisionTextPatchEP
<+>package chylex.hee.game.entity\n\nimport chylex.hee.system.math.square\nimport net.minecraft.entity.Entity\nimport net.minecraft.util.math.AxisAlignedBB\nimport net.minecraft.util.math.Vec3d\nimport net.minecraft.world.IEntityReader\nimport java.util.function.Predicate\n\n@Suppress(\"NOTHING_TO_INLINE\")\nclass EntitySelector(private val world: IEntityReader, private val predicate: Predicate<in Entity>) {\n\tfun <T : Entity> inBox(cls: Class<T>, aabb: AxisAlignedBB): List<T> {\n\t\treturn world.getEntitiesWithinAABB(cls, aabb, predicate)\n\t}\n\t\n\tfun <T : Entity> inRange(cls: Class<T>, point: Vec3d, range: Double): List<T> {\n\t\tval aabb = AxisAlignedBB(point.x - range, point.y - range, point.z - range, point.x + range, point.y + range, point.z + range)\n\t\tval rangeSq = square(range)\n\t\t\n\t\treturn world.getEntitiesWithinAABB(cls, aabb) { predicate.test(it) && it!!.posVec.squareDistanceTo(point) <= rangeSq }\n\t}\n\t\n\t// Reified\n\t\n\tinline fun <reified T : Entity> inBox(aabb: AxisAlignedBB) = inBox(T::class.java, aabb)\n\tinline fun <reified T : Entity> inRange(point: Vec3d, range: Double) = inRange(T::class.java, point, range)\n\t\n\t// General\n\t\n\tinline fun allInBox(aabb: AxisAlignedBB) = inBox(Entity::class.java, aabb)\n\tinline fun allInRange(point: Vec3d, range: Double) = inRange(Entity::class.java, point, range)\n}\n
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/src/system/src/main/java/chylex/hee/game/entity/EntitySelector.kt b/src/system/src/main/java/chylex/hee/game/entity/EntitySelector.kt
--- a/src/system/src/main/java/chylex/hee/game/entity/EntitySelector.kt (revision 276df769798cbd4fd8154c5ebca0001dd8639545)
+++ b/src/system/src/main/java/chylex/hee/game/entity/EntitySelector.kt (date 1609259090000)
@@ -20,6 +20,8 @@
return world.getEntitiesWithinAABB(cls, aabb) { predicate.test(it) && it!!.posVec.squareDistanceTo(point) <= rangeSq }
}
+ // TODO only loaded? fuck
+
// Reified
inline fun <reified T : Entity> inBox(aabb: AxisAlignedBB) = inBox(T::class.java, aabb)

4
.idea/shelf/Recipe_Datagen.xml generated Normal file
View File

@@ -0,0 +1,4 @@
<changelist name="Recipe_Datagen" date="1601740449134" recycled="false">
<option name="PATH" value="$PROJECT_DIR$/.idea/shelf/Recipe_Datagen/shelved.patch" />
<option name="DESCRIPTION" value="Recipe Datagen" />
</changelist>

47
.idea/shelf/Recipe_Datagen/shelved.patch generated Normal file
View File

@@ -0,0 +1,47 @@
Index: data/src/main/java/chylex/hee/datagen/server/Recipes.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- /dev/null (date 1601740133630)
+++ b/data/src/main/java/chylex/hee/datagen/server/Recipes.kt (date 1601740133630)
@@ -0,0 +1,11 @@
+package chylex.hee.datagen.server
+import net.minecraft.data.DataGenerator
+import net.minecraft.data.IFinishedRecipe
+import net.minecraft.data.RecipeProvider
+import java.util.function.Consumer
+
+class Recipes(generator: DataGenerator) : RecipeProvider(generator){
+ override fun registerRecipes(consumer: Consumer<IFinishedRecipe>) = with(consumer){
+ // shapeless(ModItems.ALTERATION_NEXUS, 1){ ingredients(Items.DIAMOND, Items.ENDER_EYE, ModItems.ANCIENT_DUST, ModItems.ETHEREUM) }
+ }
+}
Index: data/src/main/java/chylex/hee/datagen/server/util/RecipeProviderExt.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- /dev/null (date 1601734823610)
+++ b/data/src/main/java/chylex/hee/datagen/server/util/RecipeProviderExt.kt (date 1601734823610)
@@ -0,0 +1,20 @@
+package chylex.hee.datagen.server.util
+import net.minecraft.data.IFinishedRecipe
+import net.minecraft.data.ShapedRecipeBuilder
+import net.minecraft.data.ShapelessRecipeBuilder
+import net.minecraft.util.IItemProvider
+import java.util.function.Consumer
+
+fun Consumer<IFinishedRecipe>.shaped(result: IItemProvider, amount: Int, callback: ShapedRecipeBuilder.() -> Unit){
+ ShapedRecipeBuilder(result, amount).apply(callback).build(this)
+}
+
+fun Consumer<IFinishedRecipe>.shapeless(result: IItemProvider, amount: Int, callback: ShapelessRecipeBuilder.() -> Unit){
+ ShapelessRecipeBuilder(result, amount).apply(callback).build(this)
+}
+
+fun ShapelessRecipeBuilder.ingredients(vararg ingredients: IItemProvider){
+ for(ingredient in ingredients){
+ this.addIngredient(ingredient)
+ }
+}

4
.idea/shelf/Shulker_Box_Animation.xml generated Normal file
View File

@@ -0,0 +1,4 @@
<changelist name="Shulker_Box_Animation" date="1590248312609" recycled="false">
<option name="PATH" value="$PROJECT_DIR$/.idea/shelf/Shulker_Box_Animation/shelved.patch" />
<option name="DESCRIPTION" value="Shulker Box Animation" />
</changelist>

File diff suppressed because one or more lines are too long

4
.idea/shelf/StructureFile.xml generated Normal file
View File

@@ -0,0 +1,4 @@
<changelist name="StructureFile" date="1601888541958" recycled="true">
<option name="PATH" value="$PROJECT_DIR$/.idea/shelf/StructureFile/shelved.patch" />
<option name="DESCRIPTION" value="StructureFile" />
</changelist>

19
.idea/shelf/StructureFile/shelved.patch generated Normal file

File diff suppressed because one or more lines are too long

4
.idea/shelf/TODO.xml generated Normal file
View File

@@ -0,0 +1,4 @@
<changelist name="TODO" date="1601072216412" recycled="false">
<option name="PATH" value="$PROJECT_DIR$/.idea/shelf/TODO/shelved.patch" />
<option name="DESCRIPTION" value="TODO" />
</changelist>

124
.idea/shelf/TODO/shelved.patch generated Normal file

File diff suppressed because one or more lines are too long

14
.idea/shelf/Territories.xml generated Normal file
View File

@@ -0,0 +1,14 @@
<changelist name="Territories" date="1593174807954" recycled="false">
<option name="PATH" value="$PROJECT_DIR$/.idea/shelf/Territories/shelved.patch" />
<option name="DESCRIPTION" value="Territories" />
<binary>
<option name="BEFORE_PATH" />
<option name="AFTER_PATH" value="src/main/resources/assets/hee/textures/environment/end_sky_blurry.png" />
<option name="SHELVED_PATH" value="$PROJECT_DIR$/.idea/shelf/Territories/end_sky_blurry.png" />
</binary>
<binary>
<option name="BEFORE_PATH" />
<option name="AFTER_PATH" value="src/main/resources/assets/hee/textures/environment/end_sky_smooth.png" />
<option name="SHELVED_PATH" value="$PROJECT_DIR$/.idea/shelf/Territories/end_sky_smooth.png" />
</binary>
</changelist>

BIN
.idea/shelf/Territories/end_sky_blurry.png generated Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
.idea/shelf/Territories/end_sky_smooth.png generated Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

24
.idea/shelf/Territories/shelved.patch generated Normal file
View File

@@ -0,0 +1,24 @@
Index: src/main/java/chylex/hee/game/block/BlockDustyStoneUnstable.kt
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- a/src/main/java/chylex/hee/game/block/BlockDustyStoneUnstable.kt (revision f6f631f6f3dc9b347b19db913cf2be4535813fc7)
+++ b/src/main/java/chylex/hee/game/block/BlockDustyStoneUnstable.kt (date 1590584304217)
@@ -26,7 +26,6 @@
import net.minecraft.util.math.shapes.EntitySelectionContext
import net.minecraft.util.math.shapes.ISelectionContext
import net.minecraft.util.math.shapes.VoxelShape
-import net.minecraft.util.math.shapes.VoxelShapes
import net.minecraft.world.IBlockReader
import net.minecraft.world.World
import java.util.Random
@@ -68,7 +67,7 @@
return if (context is EntitySelectionContext && context.entity is EntityLivingBase)
MagicValues.BLOCK_COLLISION_SHRINK_SHAPE
else
- VoxelShapes.fullCube()
+ MagicValues.BLOCK_COLLISION_SHRINK_SHAPE //VoxelShapes.fullCube()
}
override fun causesSuffocation(state: BlockState, world: IBlockReader, pos: BlockPos): Boolean{

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

119
.idea/shelf/Territories1/shelved.patch generated Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,4 @@
<changelist name="Work_on_Ender_Eye_spawn_animation,_movement,_and_attack_logic" date="1601092950910" recycled="true">
<option name="PATH" value="$PROJECT_DIR$/.idea/shelf/Work_on_Ender_Eye_spawn_animation,_movement,_and_attack_logic/shelved.patch" />
<option name="DESCRIPTION" value="Work on Ender Eye spawn animation, movement, and attack logic" />
</changelist>

4
.idea/shelf/thing.xml generated Normal file
View File

@@ -0,0 +1,4 @@
<changelist name="thing" date="1608060366436" recycled="false">
<option name="PATH" value="$PROJECT_DIR$/.idea/shelf/thing/shelved.patch" />
<option name="DESCRIPTION" value="thing" />
</changelist>

74
.idea/shelf/thing/shelved.patch generated Normal file
View File

@@ -0,0 +1,74 @@
Index: src/main/resources/hee.mixins.json
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.BaseRevisionTextPatchEP
<+>{\n \"required\": true,\n \"minVersion\": \"0.8\",\n \"package\": \"chylex.hee.mixin\",\n \"compatibilityLevel\": \"JAVA_8\",\n \"mixins\": [\n \"HookAnvilRepair\",\n \"HookBlockDrops\",\n \"HookChorusFlowerSoil\",\n \"HookChorusPlantSoil\",\n \"HookEffectCorruption\",\n \"HookEffectInstanceCorruption\",\n \"HookEndBiome\",\n \"HookEndermanParticles\",\n \"HookEndermiteParticles\",\n \"HookEntityHelmetBreaking\",\n \"HookEntityPotionCorruption\",\n \"HookFireSpread\",\n \"HookItemEntityLavaCheck\",\n \"HookLightMapColors\",\n \"HookPlayerInventoryArmorBreaking\",\n \"HookPotionCreativeMenu\",\n \"HookThornsArmorBreaking\"\n ],\n \"injectors\": {\n \"defaultRequire\": 1\n }\n}\n
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/src/main/resources/hee.mixins.json b/src/main/resources/hee.mixins.json
--- a/src/main/resources/hee.mixins.json (revision 7f9202bceb9aa7b8fac24437a2190a87857573a7)
+++ b/src/main/resources/hee.mixins.json (date 1608060366293)
@@ -3,25 +3,7 @@
"minVersion": "0.8",
"package": "chylex.hee.mixin",
"compatibilityLevel": "JAVA_8",
- "mixins": [
- "HookAnvilRepair",
- "HookBlockDrops",
- "HookChorusFlowerSoil",
- "HookChorusPlantSoil",
- "HookEffectCorruption",
- "HookEffectInstanceCorruption",
- "HookEndBiome",
- "HookEndermanParticles",
- "HookEndermiteParticles",
- "HookEntityHelmetBreaking",
- "HookEntityPotionCorruption",
- "HookFireSpread",
- "HookItemEntityLavaCheck",
- "HookLightMapColors",
- "HookPlayerInventoryArmorBreaking",
- "HookPotionCreativeMenu",
- "HookThornsArmorBreaking"
- ],
+ "mixins": [ "HookAnvilRepair", "HookBlockDrops", "HookChorusFlowerSoil", "HookChorusPlantSoil", "HookEffectCorruption", "HookEffectInstanceCorruption", "HookElytraBreaking", "HookEndBiome", "HookEndermanParticles", "HookEndermiteParticles", "HookEntityHelmetBreaking", "HookEntityPotionCorruption", "HookFireSpread", "HookItemEntityLavaCheck", "HookLightMapColors", "HookPlayerInventoryArmorBreaking", "HookPotionCreativeMenu", "HookThornsArmorBreaking" ],
"injectors": {
"defaultRequire": 1
}
Index: src/main/java/chylex/hee/mixin/HookElytraBreaking.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/src/main/java/chylex/hee/mixin/HookElytraBreaking.java b/src/main/java/chylex/hee/mixin/HookElytraBreaking.java
new file mode 100644
--- /dev/null (date 1608060322378)
+++ b/src/main/java/chylex/hee/mixin/HookElytraBreaking.java (date 1608060322378)
@@ -0,0 +1,27 @@
+package chylex.hee.mixin;
+
+import chylex.hee.init.ModItems;
+import net.minecraft.entity.LivingEntity;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.item.ElytraItem;
+import net.minecraft.item.ItemStack;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Redirect;
+import java.util.function.Consumer;
+
+@Mixin(ElytraItem.class)
+public abstract class HookElytraBreaking{
+ @Redirect(
+ method = "elytraFlightTick",
+ at = @At(value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;damageItem(ILnet/minecraft/entity/LivingEntity;Ljava/util/function/Consumer;)V")
+ )
+ public void damageItem(final ItemStack stack, final int amount, final LivingEntity entity, final Consumer<LivingEntity> onBroken){
+ final ItemStack originalStack = stack.copy();
+ stack.damageItem(amount, entity, onBroken);
+
+ if (ElytraItem.isUsable(originalStack) && !ElytraItem.isUsable(stack) && entity instanceof PlayerEntity){
+ ModItems.RING_OF_PRESERVATION.onArmorDestroyed((PlayerEntity)entity, originalStack, stack);
+ }
+ }
+}

4
.idea/shelf/todo1.xml generated Normal file
View File

@@ -0,0 +1,4 @@
<changelist name="todo1" date="1601711471885" recycled="true">
<option name="PATH" value="$PROJECT_DIR$/.idea/shelf/todo1/shelved.patch" />
<option name="DESCRIPTION" value="todo" />
</changelist>

182
.idea/shelf/todo1/shelved.patch generated Normal file

File diff suppressed because one or more lines are too long

View File

@@ -22,6 +22,7 @@ import net.minecraft.block.BlockState
import net.minecraft.enchantment.EnchantmentHelper
import net.minecraft.enchantment.Enchantments
import net.minecraft.entity.Entity
import net.minecraft.entity.EntitySpawnPlacementRegistry.PlacementType
import net.minecraft.entity.EntityType
import net.minecraft.util.math.BlockPos
import net.minecraft.world.IBlockReader
@@ -47,14 +48,6 @@ class BlockDustyStoneUnstable(builder: BlockBuilder) : BlockDustyStone(builder),
return null
}
private fun isNonCreative(entity: Entity): Boolean {
return entity !is EntityPlayer || !entity.isCreative
}
private fun isLightMob(entity: Entity): Boolean {
return entity.height <= 0.5F || (entity.height <= 1F && entity.width <= 0.5F)
}
}
override fun canHarvestBlock(state: BlockState, world: IBlockReader, pos: BlockPos, player: EntityPlayer): Boolean {
@@ -94,7 +87,7 @@ class BlockDustyStoneUnstable(builder: BlockBuilder) : BlockDustyStone(builder),
}
override fun onEntityCollisionAbove(world: World, pos: BlockPos, entity: Entity) {
if (!world.isRemote && world.totalTime % 4L == 0L && !isLightMob(entity) && isNonCreative(entity)) {
if (!world.isRemote && world.totalTime % 4L == 0L && !(entity.height <= 0.5F || (entity.height <= 1F && entity.width <= 0.5F)) && isNonCreative(entity)) {
if (!doCrumbleTest(world, pos)) {
return
}
@@ -110,7 +103,7 @@ class BlockDustyStoneUnstable(builder: BlockBuilder) : BlockDustyStone(builder),
}
override fun onFallenUpon(world: World, pos: BlockPos, entity: Entity, fallDistance: Float) {
if (!world.isRemote && entity is EntityLivingBase && fallDistance > (if (isLightMob(entity)) 3.3F else 1.3F) && isNonCreative(entity)) {
if (!world.isRemote && entity is EntityLivingBase && fallDistance > 1.3F && isNonCreative(entity)) {
val rand = world.rand
val aabb = entity.boundingBox
val y = pos.y
@@ -142,8 +135,12 @@ class BlockDustyStoneUnstable(builder: BlockBuilder) : BlockDustyStone(builder),
super.onFallenUpon(world, pos, entity, fallDistance)
}
override fun canEntitySpawn(state: BlockState, world: IBlockReader, pos: BlockPos, entityType: EntityType<*>): Boolean {
return super.canEntitySpawn(state, world, pos, entityType) && getCrumbleStartPos(world, pos) == null
override fun canCreatureSpawn(state: BlockState, world: IBlockReader, pos: BlockPos, placementType: PlacementType, entityType: EntityType<*>?): Boolean {
return super.canCreatureSpawn(state, world, pos, placementType, entityType) && getCrumbleStartPos(world, pos) == null
}
private fun isNonCreative(entity: Entity): Boolean {
return entity !is EntityPlayer || !entity.isCreative
}
private fun doCrumbleTest(world: World, pos: BlockPos): Boolean {

View File

@@ -9,13 +9,14 @@ import chylex.hee.game.entity.technical.EntityTechnicalTrigger.Types.ENERGY_SHRI
import chylex.hee.game.world.center
import chylex.hee.game.world.feature.energyshrine.EnergyShrinePieces
import net.minecraft.block.BlockState
import net.minecraft.entity.EntitySpawnPlacementRegistry.PlacementType
import net.minecraft.entity.EntityType
import net.minecraft.util.math.BlockPos
import net.minecraft.world.IBlockReader
import net.minecraft.world.IEntityReader
class BlockGloomrock(builder: BlockBuilder) : BlockSimple(builder) {
override fun canEntitySpawn(state: BlockState, world: IBlockReader, pos: BlockPos, entityType: EntityType<*>?): Boolean {
override fun canCreatureSpawn(state: BlockState, world: IBlockReader, pos: BlockPos, type: PlacementType, entityType: EntityType<*>?): Boolean {
if (world !is IEntityReader) {
HEE.log.warn("[BlockGloomrock] attempted to check spawn on a world != IEntityReader (${world.javaClass})")
return false

View File

@@ -25,7 +25,6 @@ import chylex.hee.system.random.nextFloat
import chylex.hee.system.random.nextInt
import net.minecraft.block.Block
import net.minecraft.block.BlockState
import net.minecraft.entity.EntityType
import net.minecraft.item.BlockItemUseContext
import net.minecraft.item.ItemStack
import net.minecraft.state.StateContainer.Builder
@@ -89,12 +88,6 @@ open class BlockGraveDirt(builder: BlockBuilder) : BlockSimpleShaped(builder, Ax
super.getShape(state, source, pos, context)
}
// Mobs
override fun canEntitySpawn(state: BlockState, worldIn: IBlockReader, pos: BlockPos, type: EntityType<*>): Boolean {
return true
}
// Explosions
override fun canDropFromExplosion(explosion: Explosion): Boolean {

View File

@@ -76,8 +76,8 @@ class EntityMobAngryEnderman(type: EntityType<EntityMobAngryEnderman>, world: Wo
}
override fun updateAITasks() {
teleportHandler.tickServer()
waterHandler.tickServer()
teleportHandler.update()
waterHandler.update()
val currentTarget = attackTarget

View File

@@ -26,10 +26,6 @@ import chylex.hee.game.mechanics.causatum.events.CausatumEventEndermanKill
import chylex.hee.game.world.playServer
import chylex.hee.init.ModEntities
import chylex.hee.init.ModSounds
import chylex.hee.system.component.EntityComponents
import chylex.hee.system.component.general.deserializeFrom
import chylex.hee.system.component.general.serializeTo
import chylex.hee.system.component.general.tick
import chylex.hee.system.facades.Resource
import chylex.hee.system.forge.SubscribeAllEvents
import chylex.hee.system.forge.SubscribeEvent
@@ -80,6 +76,8 @@ class EntityMobEnderman(type: EntityType<EntityMobEnderman>, world: World) : Ent
@SubscribeAllEvents(modid = HEE.ID)
companion object {
private const val TELEPORT_HANDLER_TAG = "Teleport"
private const val WATER_HANDLER_TAG = "Water"
private const val CAN_PICK_UP_BLOCKS_TAG = "CanPickUpBlocks"
private const val HELD_BLOCK_TIMER_TAG = "HeldBlockTimer"
private const val HELD_BLOCK_DESPAWNS_TAG = "HeldBlockDespawns"
@@ -204,9 +202,8 @@ class EntityMobEnderman(type: EntityType<EntityMobEnderman>, world: World) : Ent
// Instance
private lateinit var components: EntityComponents
private lateinit var teleportHandler: EndermanTeleportHandler
private lateinit var waterHandler: EndermanWaterHandler
private lateinit var blockHandler: EndermanBlockHandler
private lateinit var aiAttackTarget: AIToggle
@@ -230,13 +227,6 @@ class EntityMobEnderman(type: EntityType<EntityMobEnderman>, world: World) : Ent
// Initialization
override fun registerData() {
super.registerData()
components = EntityComponents()
components.attach(EndermanWaterHandler(this, takeDamageAfterWetTicks = 80))
}
override fun registerAttributes() {
super.registerAttributes()
@@ -248,7 +238,8 @@ class EntityMobEnderman(type: EntityType<EntityMobEnderman>, world: World) : Ent
}
override fun registerGoals() {
teleportHandler = EndermanTeleportHandler(this).also(components::attach)
teleportHandler = EndermanTeleportHandler(this)
waterHandler = EndermanWaterHandler(this, takeDamageAfterWetTicks = 80)
blockHandler = EndermanBlockHandler(this)
aiWatchTargetInShock = AIWatchTargetInShock(this, maxDistance = 72.0)
@@ -274,9 +265,10 @@ class EntityMobEnderman(type: EntityType<EntityMobEnderman>, world: World) : Ent
override fun livingTick() {
super.livingTick()
components.tick(this)
if (!world.isRemote) {
teleportHandler.update()
waterHandler.update()
if (heldBlockTimer > 0 && --heldBlockTimer == 0.toShort()) {
if (heldBlockDespawns || !blockHandler.tryPlaceBlock(allowPlayerProximity = false)) {
teleportHandler.teleportOutOfWorld(force = rand.nextBoolean())
@@ -544,7 +536,8 @@ class EntityMobEnderman(type: EntityType<EntityMobEnderman>, world: World) : Ent
override fun writeAdditional(nbt: TagCompound) = nbt.heeTag.use {
super.writeAdditional(nbt)
components.serializeTo(this)
put(TELEPORT_HANDLER_TAG, teleportHandler.serializeNBT())
put(WATER_HANDLER_TAG, waterHandler.serializeNBT())
putBoolean(CAN_PICK_UP_BLOCKS_TAG, aiPickUpBlocks.enabled)
putShort(HELD_BLOCK_TIMER_TAG, heldBlockTimer)
@@ -554,7 +547,8 @@ class EntityMobEnderman(type: EntityType<EntityMobEnderman>, world: World) : Ent
override fun readAdditional(nbt: TagCompound) = nbt.heeTag.use {
super.readAdditional(nbt)
components.deserializeFrom(this)
teleportHandler.deserializeNBT(getCompound(TELEPORT_HANDLER_TAG))
waterHandler.deserializeNBT(getCompound(WATER_HANDLER_TAG))
aiPickUpBlocks.enabled = getBoolean(CAN_PICK_UP_BLOCKS_TAG)
heldBlockTimer = getShort(HELD_BLOCK_TIMER_TAG)

View File

@@ -56,15 +56,11 @@ import net.minecraft.block.BlockState
import net.minecraft.entity.CreatureAttribute
import net.minecraft.entity.Entity
import net.minecraft.entity.EntityType
import net.minecraft.entity.ILivingEntityData
import net.minecraft.entity.SharedMonsterAttributes.ATTACK_DAMAGE
import net.minecraft.entity.SharedMonsterAttributes.FOLLOW_RANGE
import net.minecraft.entity.SharedMonsterAttributes.MAX_HEALTH
import net.minecraft.entity.SharedMonsterAttributes.MOVEMENT_SPEED
import net.minecraft.entity.SpawnReason
import net.minecraft.entity.SpawnReason.SPAWNER
import net.minecraft.entity.ai.attributes.AttributeModifier
import net.minecraft.nbt.CompoundNBT
import net.minecraft.network.IPacket
import net.minecraft.network.datasync.DataSerializers
import net.minecraft.pathfinding.PathNavigator
@@ -80,8 +76,6 @@ import net.minecraft.util.math.RayTraceResult.Type
import net.minecraft.util.math.Vec3d
import net.minecraft.world.Difficulty.HARD
import net.minecraft.world.Difficulty.NORMAL
import net.minecraft.world.DifficultyInstance
import net.minecraft.world.IWorld
import net.minecraft.world.IWorldReader
import net.minecraft.world.LightType.BLOCK
import net.minecraft.world.LightType.SKY
@@ -219,7 +213,7 @@ class EntityMobSpiderling(type: EntityType<EntityMobSpiderling>, world: World) :
}
else if (wakeUpTimer > 0) {
if (--wakeUpTimer == 0) {
wakeUp(preventSleep = false)
wakeUp(instant = false, preventSleep = false)
}
}
else if (ticksExisted % 4 == 0) {
@@ -297,18 +291,10 @@ class EntityMobSpiderling(type: EntityType<EntityMobSpiderling>, world: World) :
}
}
fun wakeUpInstantly(preventSleep: Boolean) {
wakeUp(preventSleep, aiDelayTicks = 1)
}
fun wakeUp(preventSleep: Boolean) {
wakeUp(preventSleep, aiDelayTicks = rand.nextInt(25, 40))
}
fun wakeUp(preventSleep: Boolean, aiDelayTicks: Int) {
private fun wakeUp(instant: Boolean, preventSleep: Boolean) {
if (isSleeping) {
isSleepingProp = false
wakeUpDelayAI = aiDelayTicks
wakeUpDelayAI = if (instant) 1 else rand.nextInt(25, 40)
if (preventSleep) {
canSleepAgain = false
@@ -317,7 +303,7 @@ class EntityMobSpiderling(type: EntityType<EntityMobSpiderling>, world: World) :
}
override fun setFire(seconds: Int) {
wakeUpInstantly(preventSleep = true)
wakeUp(instant = true, preventSleep = true)
super.setFire(seconds)
}
@@ -328,7 +314,7 @@ class EntityMobSpiderling(type: EntityType<EntityMobSpiderling>, world: World) :
// Behavior (Light)
override fun onLightStartled(): Boolean {
wakeUp(preventSleep = true)
wakeUp(instant = false, preventSleep = true)
if (world.totalTime < lightStartleResetTime) {
return false
@@ -415,7 +401,7 @@ class EntityMobSpiderling(type: EntityType<EntityMobSpiderling>, world: World) :
return false
}
wakeUpInstantly(preventSleep = true)
wakeUp(instant = true, preventSleep = true)
if (!super.attackEntityFrom(source, if (source.isFireDamage) amount * 1.25F else amount)) {
return false
@@ -459,16 +445,6 @@ class EntityMobSpiderling(type: EntityType<EntityMobSpiderling>, world: World) :
return true
}
// Spawning
override fun onInitialSpawn(world: IWorld, difficulty: DifficultyInstance, reason: SpawnReason, data: ILivingEntityData?, nbt: CompoundNBT?): ILivingEntityData? {
if (reason == SPAWNER) {
wakeUpInstantly(preventSleep = true)
}
return super.onInitialSpawn(world, difficulty, reason, data, nbt)
}
// Despawning
override fun isDespawnPeaceful(): Boolean {
@@ -539,7 +515,7 @@ class EntityMobSpiderling(type: EntityType<EntityMobSpiderling>, world: World) :
val sleepState = getInt(SLEEP_STATE_TAG)
if (sleepState != 2) {
wakeUpInstantly(preventSleep = sleepState != 1)
wakeUp(instant = true, preventSleep = sleepState != 1)
}
lightStartleResetTime = getLong(LIGHT_STARTLE_RESET_TIME_TAG)

View File

@@ -137,19 +137,19 @@ class EntityMobUndread(type: EntityType<EntityMobUndread>, world: World) : Entit
super.onDeathUpdate()
}
public override fun playStepSound(pos: BlockPos, state: BlockState) {
override fun playStepSound(pos: BlockPos, state: BlockState) {
playSound(Sounds.ENTITY_ZOMBIE_STEP, rand.nextFloat(0.4F, 0.5F), rand.nextFloat(0.9F, 1F))
}
public override fun getHurtSound(source: DamageSource): SoundEvent {
override fun getHurtSound(source: DamageSource): SoundEvent {
return ModSounds.MOB_UNDREAD_HURT
}
public override fun getDeathSound(): SoundEvent {
override fun getDeathSound(): SoundEvent {
return ModSounds.MOB_UNDREAD_DEATH
}
public override fun getSoundPitch(): Float {
override fun getSoundPitch(): Float {
return rand.nextFloat(0.8F, 1F)
}
}

View File

@@ -7,8 +7,8 @@ import chylex.hee.game.particle.spawner.ParticleSpawnerCustom
import chylex.hee.game.particle.spawner.properties.IShape.Point
import chylex.hee.game.world.bottomCenter
import chylex.hee.network.client.PacketClientFX
import chylex.hee.network.fx.FxVecData
import chylex.hee.network.fx.FxVecHandler
import chylex.hee.network.fx.IFxData
import chylex.hee.network.fx.IFxHandler
import chylex.hee.system.color.IntColor.Companion.RGB
import chylex.hee.system.math.Vec
import chylex.hee.system.math.Vec3
@@ -21,7 +21,10 @@ import chylex.hee.system.serialization.NBTList.Companion.putList
import chylex.hee.system.serialization.NBTObjectList
import chylex.hee.system.serialization.TagCompound
import chylex.hee.system.serialization.getListOfCompounds
import chylex.hee.system.serialization.readVec
import chylex.hee.system.serialization.use
import chylex.hee.system.serialization.writeVec
import net.minecraft.network.PacketBuffer
import net.minecraft.util.math.BlockPos
import net.minecraft.util.math.Vec3d
import net.minecraft.world.World
@@ -47,9 +50,15 @@ class EnderEyeSpawnerParticles(private val entity: EntityBossEnderEye) : INBTSer
hideOnMinimalSetting = false
)
val FX_PARTICLE = object : FxVecHandler() {
override fun handle(world: World, rand: Random, vec: Vec3d) {
PARTICLE_TICK.spawn(Point(vec, 2), rand)
class ParticleData(private val point: Vec3d) : IFxData {
override fun write(buffer: PacketBuffer) = buffer.use {
writeVec(point)
}
}
val FX_PARTICLE = object : IFxHandler<ParticleData> {
override fun handle(buffer: PacketBuffer, world: World, rand: Random) = buffer.use {
PARTICLE_TICK.spawn(Point(readVec(), 2), rand)
}
}
}
@@ -86,7 +95,7 @@ class EnderEyeSpawnerParticles(private val entity: EntityBossEnderEye) : INBTSer
else -> 1.0
}
PacketClientFX(FX_PARTICLE, FxVecData(pos.addY(sqrt(progressCurvePoint) * 6.0))).sendToAllAround(entity.world, pos, 256.0)
PacketClientFX(FX_PARTICLE, ParticleData(pos.addY(sqrt(progressCurvePoint) * 6.0))).sendToAllAround(entity.world, pos, 256.0)
}
if (distSq > prevDistSq || distSq < square(0.15)) {

View File

@@ -29,8 +29,6 @@ import chylex.hee.network.client.PacketClientFX
import chylex.hee.network.fx.FxEntityData
import chylex.hee.network.fx.FxEntityHandler
import chylex.hee.system.color.IntColor.Companion.RGB
import chylex.hee.system.component.general.SerializableComponent
import chylex.hee.system.component.general.TickableComponent
import chylex.hee.system.math.Vec
import chylex.hee.system.math.Vec3
import chylex.hee.system.math.addY
@@ -55,12 +53,13 @@ import net.minecraft.util.SoundCategory
import net.minecraft.util.math.AxisAlignedBB
import net.minecraft.util.math.BlockPos
import net.minecraft.util.math.Vec3d
import net.minecraftforge.common.util.INBTSerializable
import java.util.Random
import java.util.UUID
import kotlin.math.min
import kotlin.math.sqrt
class EndermanTeleportHandler(private val enderman: EntityMobAbstractEnderman) : TickableComponent, SerializableComponent {
class EndermanTeleportHandler(private val enderman: EntityMobAbstractEnderman) : INBTSerializable<TagCompound> {
companion object {
private const val DEFAULT_RESTORE_Y = -256.0
@@ -118,9 +117,6 @@ class EndermanTeleportHandler(private val enderman: EntityMobAbstractEnderman) :
}
}
override val serializationKey
get() = "Teleport"
val preventDespawn
get() = tpDelayTicks > 0
@@ -137,7 +133,7 @@ class EndermanTeleportHandler(private val enderman: EntityMobAbstractEnderman) :
private var lastDodged: UUID? = null
override fun tickServer() {
fun update() {
if (tpCooldown > 0) {
--tpCooldown
}

View File

@@ -4,16 +4,15 @@ import chylex.hee.game.entity.OPERATION_MUL_INCR_INDIVIDUAL
import chylex.hee.game.entity.living.EntityMobAbstractEnderman
import chylex.hee.game.entity.tryApplyModifier
import chylex.hee.game.entity.tryRemoveModifier
import chylex.hee.system.component.general.SerializableComponent
import chylex.hee.system.component.general.TickableComponent
import chylex.hee.system.random.nextInt
import chylex.hee.system.serialization.TagCompound
import chylex.hee.system.serialization.use
import net.minecraft.entity.SharedMonsterAttributes.ATTACK_DAMAGE
import net.minecraft.entity.ai.attributes.AttributeModifier
import net.minecraft.util.DamageSource
import net.minecraftforge.common.util.INBTSerializable
class EndermanWaterHandler(private val enderman: EntityMobAbstractEnderman, private val takeDamageAfterWetTicks: Int) : TickableComponent, SerializableComponent {
class EndermanWaterHandler(private val enderman: EntityMobAbstractEnderman, private val takeDamageAfterWetTicks: Int) : INBTSerializable<TagCompound> {
private companion object {
private val DEBUFF_WEAKNESS = AttributeModifier("Water weakness", -0.5, OPERATION_MUL_INCR_INDIVIDUAL)
@@ -21,13 +20,10 @@ class EndermanWaterHandler(private val enderman: EntityMobAbstractEnderman, priv
private const val DEBUFF_TICKS_TAG = "DebuffTicks"
}
override val serializationKey
get() = "Water"
private var wetCounter = 0
private var debuffTicks = 0
override fun tickServer() {
fun update() {
val isWet = enderman.isWet
if (isWet) {

View File

@@ -67,7 +67,7 @@ class EntityTechnicalTrigger(type: EntityType<EntityTechnicalTrigger>, world: Wo
STRONGHOLD_TRAP_TALL_INTERSECTION({ StrongholdRoom_Trap_TallIntersection.Trigger }),
ENERGY_SHRINE_GENERATOR({ EnergyShrineGenerator.GeneratorTrigger }),
ENERGY_SHRINE_GLOBAL({ EnergyShrineRoom_Main_Start.Particles }),
TOMB_DUNGEON_UNDREAD_SPAWNER(TombDungeonRoom_Tomb::MobSpawnerTrigger),
TOMB_DUNGEON_UNDREAD_SPAWNER(TombDungeonRoom_Tomb::UndreadSpawnerTrigger),
OBSIDIAN_TOWER_TOP_GLOWSTONE(ObsidianTowerLevel_Top::GlowstoneTrigger),
OBSIDIAN_TOWER_DEATH_ANIMATION(ObsidianTowerLevel_Top::DeathAnimationTrigger)
}

View File

@@ -3,7 +3,6 @@ package chylex.hee.game.item
import chylex.hee.game.block.entity.TileEntityEnergyCluster
import chylex.hee.game.inventory.heeTag
import chylex.hee.game.inventory.heeTagOrNull
import chylex.hee.game.item.components.UseOnBlockComponent
import chylex.hee.game.mechanics.energy.IEnergyQuantity
import chylex.hee.game.mechanics.energy.IEnergyQuantity.Units
import chylex.hee.game.particle.ParticleEnergyTransferToPlayer
@@ -37,11 +36,11 @@ import chylex.hee.system.serialization.use
import chylex.hee.system.serialization.writePos
import net.minecraft.client.util.ITooltipFlag
import net.minecraft.entity.Entity
import net.minecraft.item.Item
import net.minecraft.item.ItemStack
import net.minecraft.item.ItemUseContext
import net.minecraft.network.PacketBuffer
import net.minecraft.util.ActionResultType
import net.minecraft.util.math.BlockPos
import net.minecraft.util.math.MathHelper
import net.minecraft.util.text.ITextComponent
import net.minecraft.util.text.TranslationTextComponent
@@ -51,7 +50,7 @@ import java.util.Random
import kotlin.math.max
import kotlin.math.pow
abstract class ItemAbstractEnergyUser(properties: Properties) : ItemWithComponents(properties), UseOnBlockComponent {
abstract class ItemAbstractEnergyUser(properties: Properties) : Item(properties) {
companion object {
private const val ENERGY_LEVEL_TAG = "EnergyLevel"
@@ -101,8 +100,6 @@ abstract class ItemAbstractEnergyUser(properties: Properties) : ItemWithComponen
init {
@Suppress("DEPRECATION")
require(maxStackSize == 1) { "energy item must have a maximum stack size of 1" }
components.attach(this)
}
protected abstract fun getEnergyCapacity(stack: ItemStack): Units
@@ -166,11 +163,15 @@ abstract class ItemAbstractEnergyUser(properties: Properties) : ItemWithComponen
// Energy charging
override fun useOnBlock(world: World, pos: BlockPos, player: EntityPlayer, item: ItemStack, ctx: ItemUseContext): ActionResultType? {
val tile = pos.getTile<TileEntityEnergyCluster>(world)
val stack = player.getHeldItem(ctx.hand)
override fun onItemUse(context: ItemUseContext): ActionResultType {
val player = context.player ?: return FAIL
val world = context.world
val pos = context.pos
if (tile == null || !player.canPlayerEdit(pos, ctx.face, stack)) {
val tile = pos.getTile<TileEntityEnergyCluster>(world)
val stack = player.getHeldItem(context.hand)
if (tile == null || !player.canPlayerEdit(pos, context.face, stack)) {
return FAIL
}
else if (world.isRemote) {

View File

@@ -13,7 +13,7 @@ import net.minecraft.util.text.StringTextComponent
import net.minecraft.util.text.TranslationTextComponent
import net.minecraft.world.World
abstract class ItemAbstractInfusable(properties: Properties) : ItemWithComponents(properties), IInfusableItem {
abstract class ItemAbstractInfusable(properties: Properties) : Item(properties), IInfusableItem {
companion object {
fun onCanApplyInfusion(item: Item, infusion: Infusion): Boolean {
return infusion.targetItems.contains(item)

View File

@@ -1,7 +1,6 @@
package chylex.hee.game.item
import chylex.hee.game.inventory.size
import chylex.hee.game.item.components.UseOnBlockComponent
import chylex.hee.game.world.BlockEditor
import chylex.hee.init.ModItems
import chylex.hee.network.client.PacketClientFX
@@ -16,6 +15,7 @@ import chylex.hee.system.migration.ItemBoneMeal
import net.minecraft.block.DispenserBlock.FACING
import net.minecraft.dispenser.IBlockSource
import net.minecraft.dispenser.OptionalDispenseBehavior
import net.minecraft.item.Item
import net.minecraft.item.ItemStack
import net.minecraft.item.ItemUseContext
import net.minecraft.util.ActionResultType
@@ -25,7 +25,7 @@ import net.minecraft.world.server.ServerWorld
import net.minecraftforge.common.util.FakePlayerFactory
import java.util.Random
class ItemCompost(properties: Properties) : ItemWithComponents(properties) {
class ItemCompost(properties: Properties) : Item(properties) {
companion object {
private const val BONE_MEAL_EQUIVALENT = 2
@@ -61,24 +61,6 @@ class ItemCompost(properties: Properties) : ItemWithComponents(properties) {
}
init {
components.attach(object : UseOnBlockComponent {
override fun useOnBlock(world: World, pos: BlockPos, player: EntityPlayer, item: ItemStack, ctx: ItemUseContext): ActionResultType {
if (!BlockEditor.canEdit(pos, player, item)) {
return FAIL
}
else if (world.isRemote) {
return SUCCESS
}
if (applyCompost(world, pos, player)) {
item.shrink(1)
return SUCCESS
}
return PASS
}
})
BlockDispenser.registerDispenseBehavior(this, object : OptionalDispenseBehavior() {
override fun dispenseStack(source: IBlockSource, stack: ItemStack): ItemStack {
val world = source.world
@@ -95,4 +77,26 @@ class ItemCompost(properties: Properties) : ItemWithComponents(properties) {
}
})
}
override fun onItemUse(context: ItemUseContext): ActionResultType {
val player = context.player ?: return FAIL
val world = context.world
val pos = context.pos
val heldItem = player.getHeldItem(context.hand)
if (!BlockEditor.canEdit(pos, player, heldItem)) {
return FAIL
}
else if (world.isRemote) {
return SUCCESS
}
if (applyCompost(world, pos, player)) {
heldItem.shrink(1)
return SUCCESS
}
return PASS
}
}

View File

@@ -2,27 +2,27 @@ package chylex.hee.game.item
import chylex.hee.game.block.IBlockDeathFlowerDecaying
import chylex.hee.game.entity.item.EntityItemCauldronTrigger
import chylex.hee.game.item.components.UseOnBlockComponent
import chylex.hee.game.world.BlockEditor
import chylex.hee.game.world.getBlock
import chylex.hee.system.migration.ActionResult.FAIL
import chylex.hee.system.migration.ActionResult.PASS
import chylex.hee.system.migration.ActionResult.SUCCESS
import chylex.hee.system.migration.EntityPlayer
import net.minecraft.entity.Entity
import net.minecraft.item.Item
import net.minecraft.item.ItemStack
import net.minecraft.item.ItemUseContext
import net.minecraft.util.ActionResultType
import net.minecraft.util.math.BlockPos
import net.minecraft.world.World
class ItemEndPowder(properties: Properties) : ItemWithComponents(properties), UseOnBlockComponent {
init {
components.attach(this)
}
override fun useOnBlock(world: World, pos: BlockPos, player: EntityPlayer, item: ItemStack, ctx: ItemUseContext): ActionResultType? {
if (!BlockEditor.canEdit(pos, player, item)) {
class ItemEndPowder(properties: Properties) : Item(properties) {
override fun onItemUse(context: ItemUseContext): ActionResultType {
val player = context.player ?: return FAIL
val world = context.world
val pos = context.pos
val heldItem = player.getHeldItem(context.hand)
if (!BlockEditor.canEdit(pos, player, heldItem)) {
return FAIL
}
@@ -33,7 +33,7 @@ class ItemEndPowder(properties: Properties) : ItemWithComponents(properties), Us
block.healDeathFlower(world, pos)
}
item.shrink(1)
heldItem.shrink(1)
return SUCCESS
}

View File

@@ -28,6 +28,7 @@ import chylex.hee.system.math.angleBetween
import chylex.hee.system.math.floorToInt
import chylex.hee.system.math.over
import chylex.hee.system.math.toDegrees
import chylex.hee.system.migration.ActionResult.FAIL
import chylex.hee.system.migration.ActionResult.SUCCESS
import chylex.hee.system.migration.EntityLivingBase
import chylex.hee.system.migration.EntityPlayer
@@ -149,13 +150,17 @@ class ItemEnergyOracle(properties: Properties) : ItemAbstractEnergyUser(properti
return ItemAbstractInfusable.onCanApplyInfusion(this, infusion)
}
override fun useOnBlock(world: World, pos: BlockPos, player: EntityPlayer, item: ItemStack, ctx: ItemUseContext): ActionResultType? {
override fun onItemUse(context: ItemUseContext): ActionResultType {
val player = context.player ?: return FAIL
val world = context.world
val pos = context.pos
if (player.isSneaking && pos.getTile<TileEntityEnergyCluster>(world) != null) {
if (world.isRemote) {
return SUCCESS
}
val heldItem = player.getHeldItem(ctx.hand)
val heldItem = player.getHeldItem(context.hand)
val entry = pos.toLong()
with(heldItem.heeTag) {
@@ -171,7 +176,7 @@ class ItemEnergyOracle(properties: Properties) : ItemAbstractEnergyUser(properti
return SUCCESS
}
return super.useOnBlock(world, pos, player, item, ctx)
return super.onItemUse(context)
}
override fun inventoryTick(stack: ItemStack, world: World, entity: Entity, itemSlot: Int, isSelected: Boolean) {

View File

@@ -4,7 +4,6 @@ import chylex.hee.client.color.NO_TINT
import chylex.hee.game.block.entity.TileEntityEnergyCluster
import chylex.hee.game.inventory.heeTag
import chylex.hee.game.inventory.heeTagOrNull
import chylex.hee.game.item.components.UseOnBlockComponent
import chylex.hee.game.item.infusion.Infusion.SAFETY
import chylex.hee.game.item.infusion.Infusion.STABILITY
import chylex.hee.game.item.infusion.InfusionList
@@ -28,10 +27,10 @@ import chylex.hee.system.forge.Side
import chylex.hee.system.forge.Sided
import chylex.hee.system.migration.ActionResult.FAIL
import chylex.hee.system.migration.ActionResult.SUCCESS
import chylex.hee.system.migration.EntityPlayer
import chylex.hee.system.serialization.TagCompound
import chylex.hee.system.serialization.getIntegerOrNull
import chylex.hee.system.serialization.hasKey
import chylex.hee.system.serialization.use
import net.minecraft.client.renderer.color.IItemColor
import net.minecraft.client.util.ITooltipFlag
import net.minecraft.entity.Entity
@@ -44,7 +43,7 @@ import net.minecraft.util.text.TranslationTextComponent
import net.minecraft.world.World
import kotlin.math.pow
class ItemEnergyReceptacle(properties: Properties) : ItemAbstractInfusable(properties), UseOnBlockComponent {
class ItemEnergyReceptacle(properties: Properties) : ItemAbstractInfusable(properties) {
private companion object {
private const val CLUSTER_SNAPSHOT_TAG = "Cluster"
private const val UPDATE_TIME_TAG = "UpdateTime"
@@ -106,14 +105,18 @@ class ItemEnergyReceptacle(properties: Properties) : ItemAbstractInfusable(prope
}
// POLISH tweak animation
components.attach(this)
}
override fun useOnBlock(world: World, pos: BlockPos, player: EntityPlayer, item: ItemStack, ctx: ItemUseContext): ActionResultType? {
with(item.heeTag) {
override fun onItemUse(context: ItemUseContext): ActionResultType {
val player = context.player ?: return FAIL
val world = context.world
val pos = context.pos
val stack = player.getHeldItem(context.hand)
stack.heeTag.use {
if (hasKey(CLUSTER_SNAPSHOT_TAG)) {
val finalPos = BlockEditor.place(ModBlocks.ENERGY_CLUSTER, player, item, ctx)
val finalPos = BlockEditor.place(ModBlocks.ENERGY_CLUSTER, player, stack, context)
if (world.isRemote) {
return SUCCESS
@@ -123,7 +126,7 @@ class ItemEnergyReceptacle(properties: Properties) : ItemAbstractInfusable(prope
finalPos.getTile<TileEntityEnergyCluster>(world)?.let {
it.loadClusterSnapshot(ClusterSnapshot(getCompound(CLUSTER_SNAPSHOT_TAG)), inactive = false)
if (shouldLoseHealth(it, this, InfusionTag.getList(item))) {
if (shouldLoseHealth(it, this, InfusionTag.getList(stack))) {
it.deteriorateHealth()
}
}
@@ -138,7 +141,7 @@ class ItemEnergyReceptacle(properties: Properties) : ItemAbstractInfusable(prope
return SUCCESS
}
}
else if (BlockEditor.canEdit(pos, player, item)) {
else if (BlockEditor.canEdit(pos, player, stack)) {
if (world.isRemote) {
return SUCCESS
}

View File

@@ -6,7 +6,6 @@ import chylex.hee.game.entity.heeTag
import chylex.hee.game.entity.heeTagOrNull
import chylex.hee.game.entity.posVec
import chylex.hee.game.inventory.doDamage
import chylex.hee.game.item.components.UseOnBlockComponent
import chylex.hee.game.world.BlockEditor
import chylex.hee.game.world.FLAG_NONE
import chylex.hee.game.world.getBlock
@@ -15,6 +14,7 @@ import chylex.hee.game.world.playServer
import chylex.hee.game.world.removeBlock
import chylex.hee.game.world.setBlock
import chylex.hee.init.ModBlocks
import chylex.hee.system.compatibility.MinecraftForgeEventBus
import chylex.hee.system.forge.EventPriority
import chylex.hee.system.forge.SubscribeAllEvents
import chylex.hee.system.forge.SubscribeEvent
@@ -26,6 +26,7 @@ import chylex.hee.system.migration.EntityPlayer
import chylex.hee.system.migration.Sounds
import chylex.hee.system.random.nextFloat
import net.minecraft.block.Blocks
import net.minecraft.item.Item
import net.minecraft.item.ItemStack
import net.minecraft.item.ItemUseContext
import net.minecraft.util.ActionResultType
@@ -35,7 +36,7 @@ import net.minecraft.util.math.BlockPos
import net.minecraft.world.World
import net.minecraftforge.event.world.ExplosionEvent
class ItemFlintAndInfernium(properties: Properties) : ItemWithComponents(properties), UseOnBlockComponent {
class ItemFlintAndInfernium(properties: Properties) : Item(properties) {
@SubscribeAllEvents(modid = HEE.ID)
companion object {
private const val CREEPER_INFERNIUM_TAG = "Infernium"
@@ -54,7 +55,7 @@ class ItemFlintAndInfernium(properties: Properties) : ItemWithComponents(propert
}
init {
components.attach(this)
MinecraftForgeEventBus.register(this)
}
fun igniteTNT(world: World, pos: BlockPos, player: EntityPlayer?, ignoreTrap: Boolean) {
@@ -66,8 +67,14 @@ class ItemFlintAndInfernium(properties: Properties) : ItemWithComponents(propert
pos.removeBlock(world)
}
override fun useOnBlock(world: World, pos: BlockPos, player: EntityPlayer, item: ItemStack, ctx: ItemUseContext): ActionResultType? {
if (!BlockEditor.canEdit(pos, player, item)) {
override fun onItemUse(context: ItemUseContext): ActionResultType {
val player = context.player ?: return FAIL
val world = context.world
val pos = context.pos
val heldItem = player.getHeldItem(context.hand)
if (!BlockEditor.canEdit(pos, player, heldItem)) {
return FAIL
}
@@ -78,11 +85,11 @@ class ItemFlintAndInfernium(properties: Properties) : ItemWithComponents(propert
igniteTNT(world, pos, player, ignoreTrap = false)
}
else {
BlockEditor.place(ModBlocks.ETERNAL_FIRE, player, item, ctx) ?: return FAIL
BlockEditor.place(ModBlocks.ETERNAL_FIRE, player, heldItem, context) ?: return FAIL
}
Sounds.ITEM_FLINTANDSTEEL_USE.playServer(world, pos, SoundCategory.BLOCKS, volume = 1.1F, pitch = world.rand.nextFloat(0.4F, 0.5F))
item.doDamage(1, player, ctx.hand)
heldItem.doDamage(1, player, context.hand)
}
return SUCCESS

View File

@@ -9,7 +9,6 @@ import chylex.hee.game.entity.item.EntityTokenHolder
import chylex.hee.game.entity.selectExistingEntities
import chylex.hee.game.inventory.heeTag
import chylex.hee.game.inventory.heeTagOrNull
import chylex.hee.game.item.components.UseOnBlockComponent
import chylex.hee.game.mechanics.portal.DimensionTeleporter
import chylex.hee.game.mechanics.portal.EntityPortalContact
import chylex.hee.game.world.BlockEditor
@@ -35,6 +34,7 @@ import chylex.hee.system.serialization.putEnum
import net.minecraft.client.renderer.color.IItemColor
import net.minecraft.client.util.ITooltipFlag
import net.minecraft.entity.Entity
import net.minecraft.item.Item
import net.minecraft.item.ItemGroup
import net.minecraft.item.ItemStack
import net.minecraft.item.ItemUseContext
@@ -43,14 +43,13 @@ import net.minecraft.util.ActionResultType
import net.minecraft.util.Hand
import net.minecraft.util.NonNullList
import net.minecraft.util.math.AxisAlignedBB
import net.minecraft.util.math.BlockPos
import net.minecraft.util.text.ITextComponent
import net.minecraft.util.text.StringTextComponent
import net.minecraft.util.text.TranslationTextComponent
import net.minecraft.world.World
import net.minecraft.world.dimension.DimensionType
class ItemPortalToken(properties: Properties) : ItemWithComponents(properties), UseOnBlockComponent {
class ItemPortalToken(properties: Properties) : Item(properties) {
companion object {
private const val TYPE_TAG = "Type"
private const val TERRITORY_TYPE_TAG = "Territory"
@@ -73,8 +72,6 @@ class ItemPortalToken(properties: Properties) : ItemWithComponents(properties),
}
init {
components.attach(this)
addPropertyOverride(Resource.Custom("token_type")) { stack, _, _ ->
getTokenType(stack).propertyValue + (if (stack.heeTagOrNull.hasKey(IS_CORRUPTED_TAG)) 0.5F else 0F)
}
@@ -181,7 +178,10 @@ class ItemPortalToken(properties: Properties) : ItemWithComponents(properties),
return ActionResult(SUCCESS, heldItem)
}
override fun useOnBlock(world: World, pos: BlockPos, player: EntityPlayer, item: ItemStack, ctx: ItemUseContext): ActionResultType {
override fun onItemUse(context: ItemUseContext): ActionResultType {
val player = context.player ?: return FAIL
val world = context.world
if (!player.isCreative || player.isSneaking) {
return PASS
}
@@ -190,14 +190,16 @@ class ItemPortalToken(properties: Properties) : ItemWithComponents(properties),
return SUCCESS
}
val targetPos = pos.up()
val territoryType = getTerritoryType(item)
val targetPos = context.pos.up()
if (territoryType == null || ctx.face != UP || !BlockEditor.canEdit(targetPos, player, item) || world.selectExistingEntities.inBox<EntityTokenHolder>(AxisAlignedBB(targetPos)).any()) {
val heldItem = player.getHeldItem(context.hand)
val territoryType = getTerritoryType(heldItem)
if (territoryType == null || context.face != UP || !BlockEditor.canEdit(targetPos, player, heldItem) || world.selectExistingEntities.inBox<EntityTokenHolder>(AxisAlignedBB(targetPos)).any()) {
return FAIL
}
world.addEntity(EntityTokenHolder(world, targetPos, getTokenType(item), territoryType))
world.addEntity(EntityTokenHolder(world, targetPos, getTokenType(heldItem), territoryType))
return SUCCESS
}

View File

@@ -1,7 +1,6 @@
package chylex.hee.game.item
import chylex.hee.game.block.entity.TileEntityMinersBurialAltar
import chylex.hee.game.item.components.UseOnBlockComponent
import chylex.hee.game.world.BlockEditor
import chylex.hee.game.world.getTile
import chylex.hee.game.world.playUniversal
@@ -9,34 +8,33 @@ import chylex.hee.init.ModSounds
import chylex.hee.system.migration.ActionResult.FAIL
import chylex.hee.system.migration.ActionResult.PASS
import chylex.hee.system.migration.ActionResult.SUCCESS
import chylex.hee.system.migration.EntityPlayer
import net.minecraft.item.ItemStack
import net.minecraft.item.Item
import net.minecraft.item.ItemUseContext
import net.minecraft.util.ActionResultType
import net.minecraft.util.SoundCategory
import net.minecraft.util.math.BlockPos
import net.minecraft.world.World
class ItemPuzzleMedallion(properties: Properties) : ItemWithComponents(properties) {
init {
components.attach(object : UseOnBlockComponent {
override fun useOnBlock(world: World, pos: BlockPos, player: EntityPlayer, item: ItemStack, ctx: ItemUseContext): ActionResultType {
if (!BlockEditor.canEdit(pos, player, item)) {
return FAIL
}
val tile = pos.getTile<TileEntityMinersBurialAltar>(world)
if (tile != null && !tile.hasMedallion) {
tile.hasMedallion = true
item.shrink(1)
ModSounds.ITEM_PUZZLE_MEDALLION_INSERT.playUniversal(player, pos, SoundCategory.BLOCKS, volume = 2F, pitch = 0.8F)
return SUCCESS
}
return PASS
}
})
class ItemPuzzleMedallion(properties: Properties) : Item(properties) {
override fun onItemUse(context: ItemUseContext): ActionResultType {
val player = context.player ?: return FAIL
val world = context.world
val pos = context.pos
val heldItem = player.getHeldItem(context.hand)
if (!BlockEditor.canEdit(pos, player, heldItem)) {
return FAIL
}
val tile = pos.getTile<TileEntityMinersBurialAltar>(world)
if (tile != null && !tile.hasMedallion) {
tile.hasMedallion = true
heldItem.shrink(1)
ModSounds.ITEM_PUZZLE_MEDALLION_INSERT.playUniversal(player, pos, SoundCategory.BLOCKS, volume = 2F, pitch = 0.8F)
return SUCCESS
}
return PASS
}
}

View File

@@ -3,7 +3,6 @@ package chylex.hee.game.item
import chylex.hee.client.model.ModelHelper
import chylex.hee.game.block.entity.TileEntityEnergyCluster
import chylex.hee.game.entity.item.EntityItemRevitalizationSubstance
import chylex.hee.game.item.components.UseOnBlockComponent
import chylex.hee.game.mechanics.energy.IClusterHealth.HealthOverride.REVITALIZING
import chylex.hee.game.particle.ParticleSmokeCustom
import chylex.hee.game.particle.spawner.ParticleSpawnerCustom
@@ -27,6 +26,7 @@ import chylex.hee.system.serialization.readPos
import chylex.hee.system.serialization.use
import chylex.hee.system.serialization.writePos
import net.minecraft.entity.Entity
import net.minecraft.item.Item
import net.minecraft.item.ItemStack
import net.minecraft.item.ItemUseContext
import net.minecraft.network.PacketBuffer
@@ -37,7 +37,7 @@ import net.minecraft.util.math.BlockPos
import net.minecraft.world.World
import java.util.Random
class ItemRevitalizationSubstance(properties: Properties) : ItemWithComponents(properties), UseOnBlockComponent {
class ItemRevitalizationSubstance(properties: Properties) : Item(properties) {
companion object {
private val PARTICLE_FAIL = ParticleSpawnerCustom(
type = ParticleSmokeCustom,
@@ -70,11 +70,11 @@ class ItemRevitalizationSubstance(properties: Properties) : ItemWithComponents(p
}
}
init {
components.attach(this)
}
override fun useOnBlock(world: World, pos: BlockPos, player: EntityPlayer, item: ItemStack, ctx: ItemUseContext): ActionResultType? {
override fun onItemUse(context: ItemUseContext): ActionResultType {
val player = context.player ?: return FAIL
val world = context.world
val pos = context.pos
if (world.isRemote) {
return FAIL // disable animation
}
@@ -83,11 +83,11 @@ class ItemRevitalizationSubstance(properties: Properties) : ItemWithComponents(p
if (cluster.currentHealth != REVITALIZING) {
if (cluster.addRevitalizationSubstance()) {
player.getHeldItem(ctx.hand).shrink(1)
player.getHeldItem(context.hand).shrink(1)
ModSounds.ITEM_REVITALIZATION_SUBSTANCE_USE_SUCCESS.playServer(world, pos, SoundCategory.BLOCKS, volume = 0.5F)
}
else {
PacketClientFX(FX_FAIL, FxUseData(pos, player, ctx.hand)).sendToAllAround(player, 24.0)
PacketClientFX(FX_FAIL, FxUseData(pos, player, context.hand)).sendToAllAround(player, 24.0)
}
}

View File

@@ -2,33 +2,33 @@ package chylex.hee.game.item
import chylex.hee.game.block.BlockAbstractTableTile
import chylex.hee.game.block.BlockTableBase
import chylex.hee.game.item.components.UseOnBlockComponent
import chylex.hee.game.world.BlockEditor
import chylex.hee.game.world.breakBlock
import chylex.hee.game.world.getBlock
import chylex.hee.game.world.setBlock
import chylex.hee.system.forge.Side
import chylex.hee.system.forge.Sided
import chylex.hee.system.migration.EntityPlayer
import net.minecraft.client.util.ITooltipFlag
import net.minecraft.item.Item
import net.minecraft.item.ItemStack
import net.minecraft.item.ItemUseContext
import net.minecraft.util.ActionResultType
import net.minecraft.util.ActionResultType.FAIL
import net.minecraft.util.ActionResultType.PASS
import net.minecraft.util.ActionResultType.SUCCESS
import net.minecraft.util.math.BlockPos
import net.minecraft.util.text.ITextComponent
import net.minecraft.util.text.TranslationTextComponent
import net.minecraft.world.World
class ItemTableCore(private val tableBlocks: Array<BlockAbstractTableTile<*>>, properties: Properties) : ItemWithComponents(properties), UseOnBlockComponent {
init {
components.attach(this)
}
override fun useOnBlock(world: World, pos: BlockPos, player: EntityPlayer, item: ItemStack, ctx: ItemUseContext): ActionResultType {
if (!BlockEditor.canEdit(pos, player, item)) {
class ItemTableCore(private val tableBlocks: Array<BlockAbstractTableTile<*>>, properties: Properties) : Item(properties) {
override fun onItemUse(context: ItemUseContext): ActionResultType {
val player = context.player ?: return FAIL
val world = context.world
val pos = context.pos
val heldItem = player.getHeldItem(context.hand)
if (!BlockEditor.canEdit(pos, player, heldItem)) {
return FAIL
}
@@ -42,7 +42,7 @@ class ItemTableCore(private val tableBlocks: Array<BlockAbstractTableTile<*>>, p
pos.setBlock(world, table)
}
item.shrink(1)
heldItem.shrink(1)
return SUCCESS
}

View File

@@ -12,7 +12,6 @@ import chylex.hee.game.item.ItemTableLink.Companion.SoundType.LINK_FAIL
import chylex.hee.game.item.ItemTableLink.Companion.SoundType.LINK_OUTPUT
import chylex.hee.game.item.ItemTableLink.Companion.SoundType.LINK_RESTART
import chylex.hee.game.item.ItemTableLink.Companion.SoundType.LINK_SUCCESS
import chylex.hee.game.item.components.UseOnBlockComponent
import chylex.hee.game.world.getBlock
import chylex.hee.game.world.getTile
import chylex.hee.game.world.playClient
@@ -27,7 +26,6 @@ import chylex.hee.system.forge.Sided
import chylex.hee.system.migration.ActionResult.FAIL
import chylex.hee.system.migration.ActionResult.SUCCESS
import chylex.hee.system.migration.EntityItem
import chylex.hee.system.migration.EntityPlayer
import chylex.hee.system.random.nextFloat
import chylex.hee.system.serialization.getPos
import chylex.hee.system.serialization.hasKey
@@ -36,6 +34,7 @@ import chylex.hee.system.serialization.readPos
import chylex.hee.system.serialization.use
import chylex.hee.system.serialization.writePos
import net.minecraft.entity.Entity
import net.minecraft.item.Item
import net.minecraft.item.ItemStack
import net.minecraft.item.ItemUseContext
import net.minecraft.network.PacketBuffer
@@ -45,7 +44,7 @@ import net.minecraft.util.math.BlockPos
import net.minecraft.world.World
import java.util.Random
class ItemTableLink(properties: Properties) : ItemWithComponents(properties), UseOnBlockComponent {
class ItemTableLink(properties: Properties) : Item(properties) {
companion object {
private const val POS_TAG = "StoredPos"
private const val TIME_TAG = "StoredTime"
@@ -107,11 +106,11 @@ class ItemTableLink(properties: Properties) : ItemWithComponents(properties), Us
}
}
init {
components.attach(this)
}
override fun useOnBlock(world: World, pos: BlockPos, player: EntityPlayer, item: ItemStack, ctx: ItemUseContext): ActionResultType? {
override fun onItemUse(context: ItemUseContext): ActionResultType {
val player = context.player ?: return FAIL
val world = context.world
val pos = context.pos
if (!player.isSneaking || !isValidTarget(world, pos)) {
val pedestal = pos.getTile<TileEntityTablePedestal>(world)
@@ -132,7 +131,7 @@ class ItemTableLink(properties: Properties) : ItemWithComponents(properties), Us
return SUCCESS
}
val heldItem = player.getHeldItem(ctx.hand)
val heldItem = player.getHeldItem(context.hand)
var newStoredPos = pos
var soundType = LINK_RESTART

View File

@@ -21,7 +21,6 @@ import chylex.hee.game.world.structure.trigger.EntityStructureTrigger
import chylex.hee.game.world.territory.TerritoryType
import chylex.hee.init.ModBlocks
import chylex.hee.network.client.PacketClientFX
import chylex.hee.network.fx.FxVecData
import chylex.hee.system.facades.Facing4
import chylex.hee.system.math.addY
import chylex.hee.system.math.offsetTowards
@@ -146,8 +145,9 @@ abstract class ObsidianTowerLevel_Top(file: String) : ObsidianTowerLevel_General
val offsetProgress = chargeAnim.pow(0.8F).toDouble()
val particlePos = start.center.offsetTowards(tokenHolder.posVec.addY(tokenHolder.height * 0.5), offsetProgress).addY(progressCurvePoint * 6.0)
val particleData = EnderEyeSpawnerParticles.Companion.ParticleData(particlePos)
PacketClientFX(EnderEyeSpawnerParticles.FX_PARTICLE, FxVecData(particlePos)).sendToAllAround(entity.world, pos, 256.0)
PacketClientFX(EnderEyeSpawnerParticles.FX_PARTICLE, particleData).sendToAllAround(entity.world, pos, 256.0)
}
if (chargeAnim == 1F) {

View File

@@ -21,7 +21,6 @@ import chylex.hee.game.world.feature.tombdungeon.piece.TombDungeonAbstractPiece
import chylex.hee.system.math.floorToInt
import chylex.hee.system.random.nextFloat
import chylex.hee.system.random.nextInt
import chylex.hee.system.random.nextRounded
import java.util.Random
import kotlin.math.max
import kotlin.math.min
@@ -111,34 +110,49 @@ enum class TombDungeonLevel(val isFancy: Boolean, private val corridorFactor: In
return when(this) {
FIRST -> when(rand.nextInt(0, 3)) {
0 -> MOBS(undreads = rand.nextRounded(0.2F), spiderlings = 1 + m + rand.nextInt(0, h))
1 -> MOBS(undreads = rand.nextRounded(0.3F * m), spiderlings = 1 + h + rand.nextInt(0, m))
2 -> MOBS(undreads = rand.nextRounded(0.3F * h), spiderlings = 2 + m)
else -> MOBS(undreads = 0, spiderlings = 1 + rand.nextInt(0, 1 + m))
0 -> MOBS(undreads = rand.nextInt(0, h), spiderlings = 1 + m)
1 -> MOBS(undreads = rand.nextInt(0, h), spiderlings = 2 + m)
2 -> MOBS(undreads = 1 + h, spiderlings = 0 + rand.nextInt(0, m))
else -> MOBS(undreads = 1 + h, spiderlings = 1 + rand.nextInt(0, m))
}
SECOND -> when(rand.nextInt(0, 3)) {
0 -> MOBS(undreads = rand.nextRounded(0.3F), spiderlings = 1 + m + rand.nextInt(0, h))
1 -> MOBS(undreads = rand.nextRounded(0.4F * m), spiderlings = 1 + rand.nextInt(0, 2 * m))
else -> MOBS(undreads = 0, spiderlings = rand.nextRounded(1.8F + (m * 0.55F) + (h * 0.55F)))
0 -> MOBS(undreads = rand.nextInt(0, m + h), spiderlings = 1 + rand.nextInt(0, m + h))
1 -> MOBS(undreads = 1 + rand.nextInt(0, m + h), spiderlings = rand.nextInt(0, m + h))
2 -> MOBS(undreads = 1 + m + rand.nextInt(h, h * 2), spiderlings = 0)
else -> MOBS(undreads = 1 + h, spiderlings = 1 + m + rand.nextInt(h, h * 3))
}
THIRD -> when(rand.nextInt(0, 2)) {
0 -> MOBS(undreads = rand.nextInt(0, 1 + h), spiderlings = rand.nextRounded(1.4F + (m * 0.5F)) + rand.nextInt(0, m))
1 -> MOBS(undreads = rand.nextInt(0, 1 + m), spiderlings = rand.nextRounded(1.2F) + rand.nextInt(0, 2 * h))
else -> MOBS(undreads = rand.nextInt(0, 1 + m), spiderlings = 2 + rand.nextInt(0, m + h))
}
// TODO
FOURTH -> when(rand.nextInt(0, 5)) {
in 0..1 -> MOBS(undreads = 1 + rand.nextInt(h, 3 + h), spiderlings = rand.nextRounded(0.4F * m) + rand.nextInt(0, m + h))
else -> MOBS(undreads = 2 + rand.nextInt(m, 2 * m), spiderlings = rand.nextRounded(0.3F + (m * 0.1F) + (h * 0.3F)))
}
else -> when(rand.nextInt(0, 2)) {
0 -> MOBS(undreads = 1 + h + rand.nextInt(m, 1 + (m * 2)) + rand.nextInt(h, 1 + h), spiderlings = rand.nextInt(0, m))
else -> MOBS(undreads = 2 + h + rand.nextInt(m, 2 * m), spiderlings = rand.nextRounded(0.2F + (m * 0.2F)))
}
else -> 0 to 0
}
/*
import chylex.hee.game.world.feature.tombdungeon.TombDungeonLevel
import chylex.hee.game.world.feature.tombdungeon.TombDungeonLevel.MobAmount
import chylex.hee.system.math.floorToInt
import com.google.common.collect.Comparators
import java.util.Random
val rand = Random()
val level = TombDungeonLevel.FIRST
val reps = 100000
MobAmount.values().map { amount ->
"\n\n" + amount.name + "\n" + "-".repeat(amount.name.length) + "\n" + (1..reps)
.map { level.pickUndreadAndSpiderlingSpawns(rand, amount) }
.groupingBy { it }
.eachCount()
.entries
.map { ((it.value * 100.0) / reps).floorToInt() to it.key }
.sortedWith(compareBy({ it.first }, { it.second.first }, { it.second.second }))
.map { "U = ${it.second.first}, S = ${it.second.second} ... ${it.first} %" }
.joinToString("\n")
}.joinToString("\n")
*/
}
private fun MOBS(undreads: Int, spiderlings: Int) = undreads to spiderlings

View File

@@ -1,56 +1,38 @@
package chylex.hee.game.world.feature.tombdungeon.piece
import chylex.hee.game.block.BlockGraveDirt
import chylex.hee.game.entity.living.EntityMobSpiderling
import chylex.hee.game.entity.living.EntityMobUndread
import chylex.hee.game.entity.posVec
import chylex.hee.game.entity.selectExistingEntities
import chylex.hee.game.entity.selectVulnerableEntities
import chylex.hee.game.entity.technical.EntityTechnicalTrigger
import chylex.hee.game.entity.technical.EntityTechnicalTrigger.ITriggerHandler
import chylex.hee.game.entity.technical.EntityTechnicalTrigger.Types.TOMB_DUNGEON_UNDREAD_SPAWNER
import chylex.hee.game.world.Pos
import chylex.hee.game.world.distanceSqTo
import chylex.hee.game.world.feature.tombdungeon.TombDungeonLevel
import chylex.hee.game.world.feature.tombdungeon.TombDungeonLevel.MobAmount
import chylex.hee.game.world.feature.tombdungeon.connection.TombDungeonConnection
import chylex.hee.game.world.feature.tombdungeon.connection.TombDungeonConnectionType.TOMB_ENTRANCE_INSIDE
import chylex.hee.game.world.getBlock
import chylex.hee.game.world.getState
import chylex.hee.game.world.isAir
import chylex.hee.game.world.offsetWhile
import chylex.hee.game.world.playClient
import chylex.hee.game.world.structure.IStructureWorld
import chylex.hee.game.world.structure.piece.IStructurePieceConnection
import chylex.hee.game.world.structure.trigger.EntityStructureTrigger
import chylex.hee.init.ModEntities
import chylex.hee.network.client.PacketClientFX
import chylex.hee.network.fx.FxVecData
import chylex.hee.network.fx.FxVecHandler
import chylex.hee.system.math.Vec
import chylex.hee.system.math.Vec3
import chylex.hee.system.math.addY
import chylex.hee.system.math.directionTowards
import chylex.hee.system.math.square
import chylex.hee.system.math.toYaw
import chylex.hee.system.migration.BlockWeb
import chylex.hee.system.migration.EntityLivingBase
import chylex.hee.system.migration.EntityPlayer
import chylex.hee.system.migration.Facing.DOWN
import chylex.hee.system.migration.Facing.NORTH
import chylex.hee.system.migration.Facing.SOUTH
import chylex.hee.system.random.nextFloat
import chylex.hee.system.random.nextInt
import chylex.hee.system.random.nextItem
import chylex.hee.system.serialization.TagCompound
import chylex.hee.system.serialization.use
import net.minecraft.entity.EntitySpawnPlacementRegistry
import net.minecraft.entity.SpawnReason.STRUCTURE
import net.minecraft.util.Direction.Axis
import net.minecraft.entity.SpawnReason.SPAWNER
import net.minecraft.particles.RedstoneParticleData
import net.minecraft.util.Direction.EAST
import net.minecraft.util.Direction.WEST
import net.minecraft.util.math.AxisAlignedBB
import net.minecraft.util.math.BlockPos
import net.minecraft.util.math.Vec3d
import net.minecraft.world.World
import net.minecraft.world.server.ServerWorld
import java.util.Random
abstract class TombDungeonRoom_Tomb(file: String, entranceY: Int, allowSecrets: Boolean, isFancy: Boolean) : TombDungeonRoom(file, isFancy) {
@@ -61,6 +43,8 @@ abstract class TombDungeonRoom_Tomb(file: String, entranceY: Int, allowSecrets:
TombDungeonConnection(TOMB_ENTRANCE_INSIDE, Pos(centerX, entranceY, maxZ), SOUTH)
)
protected abstract val mobAmount: MobAmount?
override fun generate(world: IStructureWorld, instance: Instance) {
super.generate(world, instance)
generateSpawnerTrigger(world, instance)
@@ -68,16 +52,19 @@ abstract class TombDungeonRoom_Tomb(file: String, entranceY: Int, allowSecrets:
protected open fun generateSpawnerTrigger(world: IStructureWorld, instance: Instance) {
val rand = world.rand
val level = instance.context ?: return
val mobAmount = getSpawnerTriggerMobAmount(rand, level) ?: return
val level = instance.context
val (undreads, spiderlings) = level.pickUndreadAndSpiderlingSpawns(rand, mobAmount)
MobSpawnerTrigger.place(world, entrance = connections.first().offset, width = maxX, depth = maxZ, undreads, spiderlings)
if (rand.nextInt(3) == 0 && level != null) {
val mobAmount = mobAmount
if (mobAmount != null) {
val (undreads, spiderlings) = level.pickUndreadAndSpiderlingSpawns(rand, mobAmount)
UndreadSpawnerTrigger.place(world, entrance = connections.first().offset, width = maxX, depth = maxZ, undreads, spiderlings)
}
}
}
protected abstract fun getSpawnerTriggerMobAmount(rand: Random, level: TombDungeonLevel): MobAmount?
class MobSpawnerTrigger() : ITriggerHandler {
class UndreadSpawnerTrigger() : ITriggerHandler {
companion object {
private const val WIDTH_TAG = "Width"
private const val DEPTH_TAG = "Depth"
@@ -85,32 +72,12 @@ abstract class TombDungeonRoom_Tomb(file: String, entranceY: Int, allowSecrets:
private const val SPIDERLINGS_TAG = "Spiderlings"
fun place(world: IStructureWorld, entrance: BlockPos, width: Int, depth: Int, undreads: Int, spiderlings: Int) {
val nbt = MobSpawnerTrigger(width - 1.0, depth - 1.0, undreads, spiderlings).serializeNBT()
val nbt = UndreadSpawnerTrigger(width - 1.0, depth - 1.0, undreads, spiderlings).serializeNBT()
world.addTrigger(entrance, EntityStructureTrigger({ wrld ->
EntityTechnicalTrigger(wrld, TOMB_DUNGEON_UNDREAD_SPAWNER, nbt).apply { rotationYaw = NORTH.horizontalAngle }
}, yOffset = 0.5))
}
val FX_SPAWN_UNDREAD = object : FxVecHandler() {
override fun handle(world: World, rand: Random, vec: Vec3d) {
EntityMobUndread(world).apply {
setLocationAndAngles(vec.x, vec.y, vec.z, 0F, 0F)
spawnExplosionParticle()
deathSound.playClient(vec, soundCategory, volume = 1.2F, pitch = soundPitch * 0.7F)
}
}
}
val FX_SPAWN_SPIDERLING = object : FxVecHandler() {
override fun handle(world: World, rand: Random, vec: Vec3d) {
EntityMobSpiderling(world).apply {
setLocationAndAngles(vec.x, vec.y, vec.z, 0F, 0F)
spawnExplosionParticle()
ambientSound.playClient(vec, soundCategory, volume = 1F, pitch = soundPitch)
}
}
}
}
private var width = 0.0
@@ -141,71 +108,46 @@ abstract class TombDungeonRoom_Tomb(file: String, entranceY: Int, allowSecrets:
vecR.scale(width * 0.5).add(vecF.scale(depth)).addY(2.5)
).offset(entity.posVec)
val nearbyPlayers = world.selectVulnerableEntities.inBox<EntityPlayer>(aabb)
if (nearbyPlayers.isEmpty()) {
repeat(10) {
(world as ServerWorld).spawnParticle(RedstoneParticleData(if (facing == NORTH || facing == EAST) 1F else 0F, if (facing == SOUTH || facing == EAST) 1F else 0F, if (facing == WEST) 1F else 0F, 1F),
world.rand.nextFloat(aabb.minX, aabb.maxX),
world.rand.nextFloat(aabb.minY, aabb.maxY),
world.rand.nextFloat(aabb.minZ, aabb.maxZ),
1, 0.0, 0.0, 0.0, 0.0
)
}//TODO
if (world.players.none { aabb.contains(it.posVec) }) {
return
}
val rand = world.rand
val minPlayerDist = ((depth * 0.4) + (width * 0.16)).coerceIn(1.5, 3.5)
for((entityCount, entityType, spawnParticle) in listOf(
Triple(undreads, ModEntities.UNDREAD, FX_SPAWN_UNDREAD),
Triple(spiderlings, ModEntities.SPIDERLING, FX_SPAWN_SPIDERLING)
for((entityCount, entityType) in listOf(
undreads to ModEntities.UNDREAD,
spiderlings to ModEntities.SPIDERLING
)) {
repeat(entityCount) {
var bestPos: BlockPos? = null
for(attempt in 1..75) {
for(attempt in 1..20) {
val pos = Pos(
rand.nextFloat(aabb.minX, aabb.maxX),
rand.nextFloat(aabb.minY, aabb.maxY) + 0.5,
rand.nextFloat(aabb.minZ, aabb.maxZ),
).offsetWhile(DOWN, 1..3) {
it.isAir(world) || it.getBlock(world) is BlockWeb
it.isAir(world)
}
val collisionCheckAABB = entityType.getBoundingBoxWithSizeApplied(pos.x + 0.5, pos.y.toDouble(), pos.z + 0.5).grow(0.2, 0.0, 0.2)
if (EntitySpawnPlacementRegistry.func_223515_a(entityType, world, STRUCTURE, pos, rand) &&
world.hasNoCollisions(collisionCheckAABB) &&
world.selectExistingEntities.inBox<EntityLivingBase>(collisionCheckAABB.grow(0.4, 0.0, 0.4)).isEmpty() &&
world.players.none { pos.distanceSqTo(it) < square(minPlayerDist) }
if (EntitySpawnPlacementRegistry.func_223515_a(entityType, world, SPAWNER, pos, rand) &&
world.hasNoCollisions(entityType.getBoundingBoxWithSizeApplied(pos.x + 0.5, pos.y.toDouble(), pos.z + 0.5)) &&
world.players.none { pos.distanceSqTo(it) < square(2.75) }
) {
bestPos = pos
if (entityType === ModEntities.UNDREAD) {
if (rand.nextInt(5) == 0 || pos.down().getBlock(world) is BlockGraveDirt) {
break
}
}
else {
break
}
}
}
if (bestPos != null) {
val x = bestPos.x + rand.nextFloat(0.35, 0.65)
val y = bestPos.y + bestPos.down().getState(world).getCollisionShape(world, bestPos).getEnd(Axis.Y) - 1.0
val z = bestPos.z + rand.nextFloat(0.35, 0.65)
val vec = Vec(x, y, z)
val target = rand.nextItem(nearbyPlayers)
entityType.create(world)?.apply {
setLocationAndAngles(x, y, z, vec.directionTowards(target.posVec).toYaw(), 0F)
rotationYawHead = rotationYaw
attackTarget = target
onGround = true // allow instant pathfinding in MeleeAttackGoal
if (this is EntityMobSpiderling) {
wakeUp(preventSleep = true, aiDelayTicks = if (rand.nextInt(10) == 0) rand.nextInt(4, 6) else rand.nextInt(11, 18))
entityType.create(world)?.apply {
setLocationAndAngles(pos.x + 0.5, pos.y.toDouble(), pos.z + 0.5, rand.nextFloat(0F, 360F), 0F)
spawnExplosionParticle()
world.addEntity(this)
}
onInitialSpawn(world, world.getDifficultyForLocation(bestPos), STRUCTURE, null, null)
world.addEntity(this)
PacketClientFX(spawnParticle, FxVecData(vec)).sendToAllAround(this, 24.0)
break
}
}
}

View File

@@ -2,12 +2,11 @@ package chylex.hee.game.world.feature.tombdungeon.piece
import chylex.hee.game.block.BlockGraveDirt
import chylex.hee.game.world.Pos
import chylex.hee.game.world.feature.tombdungeon.TombDungeonLevel
import chylex.hee.game.world.feature.tombdungeon.TombDungeonLevel.MobAmount
import chylex.hee.game.world.feature.tombdungeon.TombDungeonPieces
import chylex.hee.game.world.feature.tombdungeon.connection.TombDungeonConnection
import chylex.hee.game.world.feature.tombdungeon.connection.TombDungeonConnectionType.TOMB_ENTRANCE_INSIDE
import chylex.hee.game.world.feature.tombdungeon.piece.TombDungeonRoom_Tomb.MobSpawnerTrigger
import chylex.hee.game.world.feature.tombdungeon.piece.TombDungeonRoom_Tomb.UndreadSpawnerTrigger
import chylex.hee.game.world.generation.IBlockPicker.Single
import chylex.hee.game.world.generation.IBlockPicker.Single.Air
import chylex.hee.game.world.math.Size
@@ -42,6 +41,12 @@ class TombDungeonRoom_Tomb_Mass(width: Int, depth: Int, private val border: Bool
val maxY = size.maxY
val maxZ = size.maxZ
if (rand.nextInt(3) != 0 && level != null) {
val area = (size.x - 2) * (size.z - 2)
val (undreads, spiderlings) = level.pickUndreadAndSpiderlingSpawns(rand, if (area <= 30) MobAmount.LOW else MobAmount.MEDIUM)
UndreadSpawnerTrigger.place(world, entrance = connections.first().offset, width = maxX, depth = maxZ, undreads, spiderlings)
}
val distance = if (border) 2 else 1
val palette = if (isFancy) TombDungeonPieces.PALETTE_ENTRY_FANCY_GRAVE else TombDungeonPieces.PALETTE_ENTRY_PLAIN_GRAVE
@@ -61,21 +66,8 @@ class TombDungeonRoom_Tomb_Mass(width: Int, depth: Int, private val border: Bool
if (rand.nextInt(6) == 0 && (border || split)) {
placeJars(world, instance, listOf(Pos(centerX, 2, 1)))
if (level != null && rand.nextInt(9) != 0) {
placeSpawnerTrigger(world, level)
}
}
else if (level != null && rand.nextInt(3) != 0) {
placeSpawnerTrigger(world, level)
}
placeCobwebs(world, instance)
}
private fun placeSpawnerTrigger(world: IStructureWorld, level: TombDungeonLevel) {
val area = (size.x - 2) * (size.z - 2)
val (undreads, spiderlings) = level.pickUndreadAndSpiderlingSpawns(world.rand, if (area <= 30) MobAmount.LOW else MobAmount.MEDIUM)
MobSpawnerTrigger.place(world, entrance = connections.first().offset, width = size.maxX, depth = size.maxZ, undreads, spiderlings)
}
}

View File

@@ -6,9 +6,11 @@ import chylex.hee.game.world.feature.tombdungeon.TombDungeonLevel.MobAmount
import chylex.hee.game.world.structure.IStructureWorld
import chylex.hee.system.migration.Facing.NORTH
import chylex.hee.system.random.nextInt
import java.util.Random
class TombDungeonRoom_Tomb_MassSpacious(file: String, entranceY: Int, isFancy: Boolean) : TombDungeonRoom_Tomb(file, entranceY, allowSecrets = false, isFancy) {
override val mobAmount
get() = MobAmount.MEDIUM
override fun generate(world: IStructureWorld, instance: Instance) {
super.generate(world, instance)
@@ -34,8 +36,4 @@ class TombDungeonRoom_Tomb_MassSpacious(file: String, entranceY: Int, isFancy: B
placeJars(world, instance, listOf(Pos(jarX, 3, maxZ - 2)))
}
}
override fun getSpawnerTriggerMobAmount(rand: Random, level: TombDungeonLevel): MobAmount? {
return MobAmount.HIGH.takeIf { rand.nextInt(11) < (if (level <= TombDungeonLevel.SECOND) 7 else 4) }
}
}

View File

@@ -2,16 +2,21 @@ package chylex.hee.game.world.feature.tombdungeon.piece
import chylex.hee.game.block.BlockGraveDirt
import chylex.hee.game.world.Pos
import chylex.hee.game.world.feature.tombdungeon.TombDungeonLevel
import chylex.hee.game.world.feature.tombdungeon.TombDungeonLevel.MobAmount
import chylex.hee.game.world.structure.IStructureWorld
import chylex.hee.system.migration.Facing.EAST
import chylex.hee.system.migration.Facing.WEST
import chylex.hee.system.random.nextInt
import chylex.hee.system.random.nextRounded
import java.util.Random
class TombDungeonRoom_Tomb_MultiDeep(file: String, private val tombsPerColumn: Int, entranceY: Int, isFancy: Boolean) : TombDungeonRoom_Tomb(file, entranceY, allowSecrets = false, isFancy) {
override val mobAmount
get() = when {
tombsPerColumn <= 5 -> MobAmount.LOW
tombsPerColumn <= 7 -> MobAmount.MEDIUM
else -> MobAmount.HIGH
}
override fun generate(world: IStructureWorld, instance: Instance) {
super.generate(world, instance)
@@ -40,15 +45,4 @@ class TombDungeonRoom_Tomb_MultiDeep(file: String, private val tombsPerColumn: I
})
}
}
override fun getSpawnerTriggerMobAmount(rand: Random, level: TombDungeonLevel): MobAmount? {
if (rand.nextBoolean()) {
return null
}
return when {
tombsPerColumn <= 6 -> MobAmount.MEDIUM
else -> MobAmount.HIGH
}
}
}

View File

@@ -1,12 +1,17 @@
package chylex.hee.game.world.feature.tombdungeon.piece
import chylex.hee.game.world.Pos
import chylex.hee.game.world.feature.tombdungeon.TombDungeonLevel
import chylex.hee.game.world.feature.tombdungeon.TombDungeonLevel.MobAmount
import chylex.hee.game.world.structure.IStructureWorld
import java.util.Random
class TombDungeonRoom_Tomb_MultiNarrow(file: String, private val tombsPerColumn: Int, entranceY: Int, isFancy: Boolean) : TombDungeonRoom_Tomb(file, entranceY, allowSecrets = false, isFancy) {
override val mobAmount
get() = when {
tombsPerColumn <= 5 -> MobAmount.LOW
tombsPerColumn <= 7 -> MobAmount.MEDIUM
else -> MobAmount.HIGH
}
override fun generate(world: IStructureWorld, instance: Instance) {
super.generate(world, instance)
@@ -21,16 +26,4 @@ class TombDungeonRoom_Tomb_MultiNarrow(file: String, private val tombsPerColumn:
})
}
}
override fun getSpawnerTriggerMobAmount(rand: Random, level: TombDungeonLevel): MobAmount? {
if (rand.nextInt(10) >= if (level.isFancy) 3 else 5) {
return null
}
return when {
tombsPerColumn <= 4 -> MobAmount.LOW
tombsPerColumn <= 6 -> MobAmount.MEDIUM
else -> MobAmount.HIGH
}
}
}

View File

@@ -2,16 +2,21 @@ package chylex.hee.game.world.feature.tombdungeon.piece
import chylex.hee.game.block.BlockGraveDirt
import chylex.hee.game.world.Pos
import chylex.hee.game.world.feature.tombdungeon.TombDungeonLevel
import chylex.hee.game.world.feature.tombdungeon.TombDungeonLevel.MobAmount
import chylex.hee.game.world.structure.IStructureWorld
import chylex.hee.system.migration.Facing.EAST
import chylex.hee.system.migration.Facing.WEST
import chylex.hee.system.random.nextInt
import chylex.hee.system.random.nextRounded
import java.util.Random
class TombDungeonRoom_Tomb_MultiSpacious(file: String, private val tombsPerColumn: Int, entranceY: Int, isFancy: Boolean) : TombDungeonRoom_Tomb(file, entranceY, allowSecrets = false, isFancy) {
override val mobAmount
get() = when {
tombsPerColumn <= 5 -> MobAmount.LOW
tombsPerColumn <= 7 -> MobAmount.MEDIUM
else -> MobAmount.HIGH
}
override fun generate(world: IStructureWorld, instance: Instance) {
super.generate(world, instance)
@@ -40,15 +45,4 @@ class TombDungeonRoom_Tomb_MultiSpacious(file: String, private val tombsPerColum
})
}
}
override fun getSpawnerTriggerMobAmount(rand: Random, level: TombDungeonLevel): MobAmount? {
if (rand.nextInt(10) >= 6) {
return null
}
return when {
tombsPerColumn <= 6 -> MobAmount.MEDIUM
else -> MobAmount.HIGH
}
}
}

View File

@@ -1,26 +0,0 @@
package chylex.hee.game.world.feature.tombdungeon.piece
import chylex.hee.game.world.Pos
import chylex.hee.game.world.feature.tombdungeon.TombDungeonLevel
import chylex.hee.game.world.feature.tombdungeon.TombDungeonLevel.MobAmount
import chylex.hee.game.world.structure.IStructureWorld
import chylex.hee.system.migration.Facing.SOUTH
import java.util.Random
abstract class TombDungeonRoom_Tomb_Single(file: String, entranceY: Int, isFancy: Boolean) : TombDungeonRoom_Tomb(file, entranceY, allowSecrets = false, isFancy) {
override fun generate(world: IStructureWorld, instance: Instance) {
super.generate(world, instance)
if (world.rand.nextInt(10) < 3) {
placeChest(world, instance, Pos(centerX, 1, maxZ - 4), SOUTH)
}
}
final override fun getSpawnerTriggerMobAmount(rand: Random, level: TombDungeonLevel): MobAmount? {
return null
}
protected fun placeSingleTombUndreadSpawner(world: IStructureWorld) {
MobSpawnerTrigger.place(world, entrance = connections.first().offset, width = maxX, depth = maxZ, undreads = 1, spiderlings = 0)
}
}

View File

@@ -1,13 +1,19 @@
package chylex.hee.game.world.feature.tombdungeon.piece
import chylex.hee.game.world.Pos
import chylex.hee.game.world.feature.tombdungeon.TombDungeonLevel.MobAmount
import chylex.hee.game.world.structure.IStructureWorld
import chylex.hee.system.migration.Facing.SOUTH
class TombDungeonRoom_Tomb_SingleNarrow(file: String, entranceY: Int, isFancy: Boolean) : TombDungeonRoom_Tomb_Single(file, entranceY, isFancy) {
open class TombDungeonRoom_Tomb_SingleNarrow(file: String, entranceY: Int, isFancy: Boolean) : TombDungeonRoom_Tomb(file, entranceY, allowSecrets = false, isFancy) {
override val mobAmount: MobAmount?
get() = null
override fun generate(world: IStructureWorld, instance: Instance) {
super.generate(world, instance)
if (world.rand.nextInt(5) == 0) {
placeSingleTombUndreadSpawner(world)
if (world.rand.nextInt(10) < 3) {
placeChest(world, instance, Pos(centerX, 1, maxZ - 4), SOUTH)
}
}
}

View File

@@ -1,9 +1,13 @@
package chylex.hee.game.world.feature.tombdungeon.piece
import chylex.hee.game.world.Pos
import chylex.hee.game.world.feature.tombdungeon.TombDungeonLevel.MobAmount
import chylex.hee.game.world.structure.IStructureWorld
class TombDungeonRoom_Tomb_SingleSpacious(file: String, entranceY: Int, isFancy: Boolean) : TombDungeonRoom_Tomb_Single(file, entranceY, isFancy) {
class TombDungeonRoom_Tomb_SingleSpacious(file: String, entranceY: Int, isFancy: Boolean) : TombDungeonRoom_Tomb_SingleNarrow(file, entranceY, isFancy) {
override val mobAmount: MobAmount?
get() = null
override fun generate(world: IStructureWorld, instance: Instance) {
super.generate(world, instance)
@@ -14,11 +18,6 @@ class TombDungeonRoom_Tomb_SingleSpacious(file: String, entranceY: Int, isFancy:
Pos(centerX - 2, 4, if (rand.nextBoolean()) maxZ - 3 else maxZ - 4),
Pos(centerX + 2, 4, if (rand.nextBoolean()) maxZ - 3 else maxZ - 4),
))
placeSingleTombUndreadSpawner(world)
}
else if (rand.nextInt(10) < 4) {
placeSingleTombUndreadSpawner(world)
}
}
}

View File

@@ -28,7 +28,6 @@ import chylex.hee.game.item.ItemTableLink
import chylex.hee.game.mechanics.scorching.ScorchingHelper
import chylex.hee.game.mechanics.table.TableParticleHandler
import chylex.hee.game.potion.PotionBanishment
import chylex.hee.game.world.feature.tombdungeon.piece.TombDungeonRoom_Tomb
import chylex.hee.network.BaseClientPacket
import chylex.hee.network.fx.IFxData
import chylex.hee.network.fx.IFxHandler
@@ -80,9 +79,7 @@ class PacketClientFX<T : IFxData>() : BaseClientPacket() {
EnderEyeSpawnerParticles.FX_PARTICLE,
EndermanTeleportHandler.FX_TELEPORT_FAIL,
EndermanTeleportHandler.FX_TELEPORT_OUT_OF_WORLD,
PotionBanishment.FX_BANISH,
TombDungeonRoom_Tomb.MobSpawnerTrigger.FX_SPAWN_UNDREAD,
TombDungeonRoom_Tomb.MobSpawnerTrigger.FX_SPAWN_SPIDERLING,
PotionBanishment.FX_BANISH
)
}

View File

@@ -1,18 +0,0 @@
package chylex.hee.game.item
import chylex.hee.game.item.components.UseOnBlockComponent
import chylex.hee.system.component.EntityComponents
import net.minecraft.item.Item
import net.minecraft.item.ItemUseContext
import net.minecraft.util.ActionResultType
import net.minecraft.util.ActionResultType.FAIL
import net.minecraft.util.ActionResultType.PASS
open class ItemWithComponents(properties: Properties) : Item(properties) {
val components = EntityComponents()
final override fun onItemUse(context: ItemUseContext): ActionResultType {
val player = context.player ?: return FAIL
return components.handle<UseOnBlockComponent, ActionResultType> { useOnBlock(context.world, context.pos, player, context.item, context) } ?: PASS
}
}

View File

@@ -1,12 +0,0 @@
package chylex.hee.game.item.components
import chylex.hee.system.migration.EntityPlayer
import net.minecraft.item.ItemStack
import net.minecraft.item.ItemUseContext
import net.minecraft.util.ActionResultType
import net.minecraft.util.math.BlockPos
import net.minecraft.world.World
interface UseOnBlockComponent { // TODO use as objects instead of inheriting the interface on Item
fun useOnBlock(world: World, pos: BlockPos, player: EntityPlayer, item: ItemStack, ctx: ItemUseContext): ActionResultType?
}

View File

@@ -10,6 +10,24 @@ class RandomBiasedValueRange(range: ClosedFloatingPointRange<Float>, private val
require(highestChanceValue in min..max) { "highestChanceValue must be between min and max" }
}
/*
import java.util.Random
import chylex.hee.system.random.nextBiasedFloat
import kotlin.math.roundToInt
val rand = Random()
(1..100000).map {
val min = 3F
val max = 10F
val highestChanceValue = 6.5F
val biasSoftener = 3F
(highestChanceValue + (rand.nextBiasedFloat(biasSoftener) * (0.5F + max - highestChanceValue)) - (rand.nextBiasedFloat(biasSoftener) * (0.5F + highestChanceValue - min))).roundToInt()
}.groupBy { it }.mapValues { it.value.size }.toList().sortedBy { it.first }
*/
override fun generateInt(rand: Random): Int {
return (highestChanceValue + (rand.nextBiasedFloat(biasSoftener) * (0.5F + max - highestChanceValue)) - (rand.nextBiasedFloat(biasSoftener) * (0.5F + highestChanceValue - min))).roundToInt()
}

View File

@@ -1,12 +0,0 @@
package chylex.hee.network.fx
import chylex.hee.system.serialization.use
import chylex.hee.system.serialization.writeVec
import net.minecraft.network.PacketBuffer
import net.minecraft.util.math.Vec3d
class FxVecData(private val vec: Vec3d) : IFxData {
override fun write(buffer: PacketBuffer) = buffer.use {
writeVec(vec)
}
}

View File

@@ -1,16 +0,0 @@
package chylex.hee.network.fx
import chylex.hee.system.serialization.readVec
import chylex.hee.system.serialization.use
import net.minecraft.network.PacketBuffer
import net.minecraft.util.math.Vec3d
import net.minecraft.world.World
import java.util.Random
abstract class FxVecHandler : IFxHandler<FxVecData> {
override fun handle(buffer: PacketBuffer, world: World, rand: Random) = buffer.use {
handle(world, rand, readVec())
}
abstract fun handle(world: World, rand: Random, vec: Vec3d)
}

View File

@@ -1,8 +0,0 @@
package chylex.hee.system.component
abstract class AbstractAwareComponent {
var entityComponents: EntityComponents? = null
open fun onComponentAttached() {}
open fun onComponentDetached() {}
}

View File

@@ -1,56 +0,0 @@
package chylex.hee.system.component
class EntityComponents {
private val mutableComponents = mutableListOf<Any>()
val components: List<Any>
get() = mutableComponents
fun attach(component: Any) {
require(!mutableComponents.contains(component)) { "[EntityComponents] component must not be registered twice" }
mutableComponents.add(component)
if (component is AbstractAwareComponent) {
require(component.entityComponents === null) { "[EntityComponents] component must not be registered in two entities" }
component.entityComponents = this
component.onComponentAttached()
}
}
fun detach(component: Any) {
if (!mutableComponents.remove(component)) {
return
}
if (component is AbstractAwareComponent) {
require(component.entityComponents === this) { "[EntityComponents] component was not registered correctly" }
component.onComponentDetached()
component.entityComponents = null
}
}
inline fun <reified T> on(f: T.() -> Unit) {
for(component in components) {
if (component is T) {
f(component)
}
}
}
inline fun <reified T, U> handle(f: T.() -> U?): U? {
for(component in components) {
if (component is T) {
val result = f(component)
if (result != null) {
return result
}
}
}
return null
}
inline fun <reified T> list(): List<T> {
return components.filterIsInstance<T>()
}
}

View File

@@ -1,20 +0,0 @@
package chylex.hee.system.component.general
import chylex.hee.system.component.EntityComponents
import chylex.hee.system.serialization.TagCompound
import net.minecraftforge.common.util.INBTSerializable
interface SerializableComponent : INBTSerializable<TagCompound> {
val serializationKey: String
}
fun EntityComponents.serializeTo(tag: TagCompound) {
this.on<SerializableComponent> {
require(!tag.contains(serializationKey)) { "[SerializableComponent] cannot serialize duplicate key: $serializationKey" }
tag.put(serializationKey, serializeNBT())
}
}
fun EntityComponents.deserializeFrom(tag: TagCompound) {
this.on<SerializableComponent> { deserializeNBT(tag.getCompound(serializationKey)) }
}

View File

@@ -1,19 +0,0 @@
package chylex.hee.system.component.general
import chylex.hee.system.component.EntityComponents
import net.minecraft.entity.Entity
interface TickableComponent {
@JvmDefault fun tickClient() {}
@JvmDefault fun tickServer() {}
}
@JvmName("tickEntity")
fun <T : Entity> EntityComponents.tick(entity: T) {
if (entity.world.isRemote) {
this.on(TickableComponent::tickClient)
}
else {
this.on(TickableComponent::tickServer)
}
}

View File

@@ -1,28 +0,0 @@
package chylex.hee.test.main
import chylex.hee.game.loot.rng.RandomBiasedValueRange
import java.util.Random
import kotlin.math.roundToInt
fun main() {
val min = 3F
val max = 10F
val highestChanceValue = 6.5F
val biasSoftener = 3F
val rand = Random()
val generator = RandomBiasedValueRange(min..max, highestChanceValue, biasSoftener)
val reps = 100000
val results = (1..reps).map { generator.generateInt(rand) }
.groupBy { it }
.mapValues { it.value.size }
.toList()
.sortedBy { it.first }
val pad1 = results.maxOf { it.first.toString().length }
val pad2 = results.maxOf { it.second.toString().length }
println(results.joinToString("\n") {
"${it.first.toString().padStart(pad1)} | ${it.second.toString().padStart(pad2)} | ${((it.second * 100.0) / reps).roundToInt().toString().padStart(2)} %"
})
}

View File

@@ -1,35 +0,0 @@
package chylex.hee.test.main
import chylex.hee.game.world.feature.tombdungeon.TombDungeonLevel
import chylex.hee.game.world.feature.tombdungeon.TombDungeonLevel.MobAmount
import java.util.Locale.ROOT
import java.util.Random
import kotlin.math.roundToInt
fun main() {
val rand = Random()
for(level in TombDungeonLevel.values()) {
val reps = 100000
println()
println("== ${level.name} ${"=".repeat(24 - level.name.length)}")
for(amount in MobAmount.values()) {
println()
println(" ${amount.name}")
println()
val results = (1..reps)
.map { level.pickUndreadAndSpiderlingSpawns(rand, amount) }
.groupingBy { it }
.eachCount()
.entries
.map { ((it.value * 100.0) / reps).roundToInt() to it.key }
.sortedWith(compareBy({ -it.first }, { -it.second.first }, { -it.second.second }))
println(results.joinToString("\n") { " U = ${it.second.first} S = ${it.second.second} ${it.first.toString().padStart(2)} %" })
println(" U ~ ${"%.1f".format(ROOT, results.sumBy { it.second.first * it.first } * 0.01)} S ~ ${"%.1f".format(ROOT, results.sumBy { it.second.second * it.first } * 0.01)}")
}
}
}

View File

@@ -1,4 +1,4 @@
package chylex.hee.test.unit.mechanics.damage
package chylex.hee.test.mechanics.damage
import chylex.hee.game.mechanics.damage.DamageProperties
import chylex.hee.game.mechanics.damage.DamageType

View File

@@ -1,4 +1,4 @@
package chylex.hee.test.unit.mechanics.energy
package chylex.hee.test.mechanics.energy
import chylex.hee.game.mechanics.energy.IEnergyQuantity.Floating
import chylex.hee.game.mechanics.energy.IEnergyQuantity.Internal

View File

@@ -1,4 +1,4 @@
package chylex.hee.test.unit.system
package chylex.hee.test.system.util
import chylex.hee.game.world.Pos
import chylex.hee.system.math.Vec

View File

@@ -1,4 +1,4 @@
package chylex.hee.test.unit.system
package chylex.hee.test.system.util
import chylex.hee.game.inventory.cleanupNBT
import chylex.hee.game.inventory.heeTag