Share your ideas or bug discoveries with us !
https://github.com/GCJOJO/WorldsColliding/issues
-## Developping with this mod
+## Developing with this mod
__How to build__:
1) Install Java JDK 17
2) Open command prompt or any IDE and run :
@@ -21,13 +21,16 @@ https://github.com/GCJOJO/WorldsColliding/issues
3) Enjoy !
__How to use the dialogue system__:
-First create a datapack using this folder structure
+First create a resource pack using this folder structure
```
- datapack-namespace/
- lang/
- en_us.json
- any other language files...
- dialogues.json
+ resourcepacks/
+ my_resourcepack/
+ assets/
+ lang/
+ en_us.json
+ any other language files...
+ dialogues.json
+ pack.mcmeta
```
Inside dialogues.json define the different speakers that may speak in your dialogues.
@@ -64,21 +67,32 @@ Here is how you define a dialogue, there are multiple actions that can be define
{ "action": "wait", "time": 20 },
- // clears any non blocking actions,
+ // clears every actions,
{ "action": "clear" },
-
//you may specify which action type to clear
{ "action": "clear", "cleared_action": "fade" },
// displays an image on the screen, the width and height are the original size of the image, the image should be properly resized once shown to the player
{ "action": "image", "id": 0, "image": "my_resourcepack:textures/gui/my_cool_texture.png", "width": 64, "height": 64},
+
+ // This actions move the image with id 0 with a duration of 80 ticks.
+ // The image starts at a position of 10% of the screen and ends at 90% of the screen and blends from 0% transparency to 100%
+ { "action": "move_image", "id": 0, "start_x": 10, "start_y": 10, "end_x": 90, "end_y": 90, "alpha_start": 0, "alpha_end": 255, "time": 80 }
+
+ // This actions executes a command as the player reading the dialogue.
+ // The text will be replaced by the player's name.
+ { "action": "command", "command": "say hello from !" }
+
+ // The command is execute as if the player typed it without needing permisions, you don't need to do /execute positioned as ... for any positioned command
+ // You can simply do :
+ { "action": "command", "command": "tp @s ~ ~10 ~" }
]
}
```
When defining text such as message or speaker names, you may use localized keys and translate them inside of `en_us.json` or any other language files.
You may display you dialogues using the following commands :
-``/dialogue set my_datapack:dialogue_1``
+``/dialogue set my_resourcepack:dialogue_1``
``/dialogue play``
__What are blocking and non-blocking actions ?__
@@ -90,12 +104,13 @@ Non-blocking actions can be stacked on top of each others and stack on top of on
Here is a table of Blocking and Non-Blocking Actions
-| Blocking | Non-Blocking |
-|:----------------:|:---------------:|
-| MessageAction | FadeAction |
-| ChoiceAction | ImageAction |
-| WaitAction | NextAction |
-| | CreditAction |
-| | ClearAction |
+| Blocking | Non-Blocking |
+|:---------------------:|:---------------------:|
+| MessageAction | FadeAction |
+| ChoiceAction | ImageAction |
+| WaitAction | NextAction |
+| ExecuteCommandAction | CreditAction |
+| | ClearAction |
+| | MoveImageAction |
_This project is currently in active development_
diff --git a/TODO.md b/TODO.md
index a64eab4..f8090d0 100644
--- a/TODO.md
+++ b/TODO.md
@@ -3,10 +3,10 @@
- [x] Not using `speaker` field for DialogueAction types
- [x] Asynchronous actions
- [X] Rendering of images
-- [ ] Positioning of images
-- [ ] Loading dialogues.json from other namespaces
+- [X] Positioning of images
+- [X] Loading dialogues.json from other namespaces
- [X] Loading speakers from dialogues.json and not being hardcoded
- [X] Change how Story Dimension's data is saved and use `player.getPersistentData()` instead
- [ ] Images in scourge lore
-- [ ] Ban message when The One gets ban
-- [ ] If dark end -> after boss defeated, small scourge elevates and disappear and dialogue with The One
\ No newline at end of file
+- [X] Ban message when The One gets ban
+- [X] If dark end -> after boss defeated, small scourge elevates and disappear and dialogue with The One
\ No newline at end of file
diff --git a/gradle.properties b/gradle.properties
index 49452a7..2d2607c 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -48,7 +48,7 @@ mod_name=World's Colliding
# The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default.
mod_license=All Rights Reserved
# The mod version. See https://semver.org/
-mod_version=1.1.0
+mod_version=1.1.4
# The group ID for the mod. It is only important when publishing as an artifact to a Maven repository.
# This should match the base package used for the mod sources.
# See https://maven.apache.org/guides/mini/guide-naming-conventions.html
diff --git a/src/main/java/fr/gcjojo/worldscolliding/ModEntry.java b/src/main/java/fr/gcjojo/worldscolliding/ModEntry.java
index 280b7fc..cf8ff55 100644
--- a/src/main/java/fr/gcjojo/worldscolliding/ModEntry.java
+++ b/src/main/java/fr/gcjojo/worldscolliding/ModEntry.java
@@ -66,38 +66,7 @@ public ModEntry(FMLJavaModLoadingContext context)
public static Logger getLogger() { return LOGGER; }
- private static void placeScourgeDenStructure(ServerLevel level, BlockPos pos)
- {
- ResourceLocation structureID = ResourceLocation.tryParse(Config.storyStructure);
- StructureTemplateManager manager = level.getStructureManager();
- if(structureID == null) {
- LOGGER.error("Structure ID {} is not a valid structure !", Config.storyStructure);
- return;
- }
-
- Optional templateOpt = manager.get(structureID);
-
- if (templateOpt.isEmpty()) {
- LOGGER.error("Unable to find structure : {}", structureID);
- return;
- }
- StructureTemplate template = templateOpt.get();
-
- StructurePlaceSettings settings = new StructurePlaceSettings()
- .setIgnoreEntities(false)
- .setRotation(Rotation.NONE)
- .setMirror(Mirror.NONE);
-
- template.placeInWorld(
- level,
- pos,
- pos,
- settings,
- level.random,
- 2
- );
- }
private void registerAttributes(EntityAttributeCreationEvent event) {
event.put(ModEntities.SCOURGE.get(), ScourgeEntity.createAttributes().build());
@@ -110,81 +79,6 @@ public void onServerStarted(ServerStartedEvent event)
StoryDimensionData.read(event.getServer().overworld());
}
- @SubscribeEvent
- public void onPlayerChangedDimension(PlayerEvent.PlayerChangedDimensionEvent event)
- {
- Player player = event.getEntity();
- //LOGGER.info("Player {} changed dimension {}", player.getName().getString(), event.getTo().toString());
-
- if(event.getTo() == ModDimensions.STORY_DIM_LEVEL_KEY)
- {
- //LOGGER.info("Player {} joined STORY Dimension", player.getName().getString());
- String dimension = event.getFrom().location().getPath();
- Vec3 playerPosition = player.getPosition(1.0f);
- CompoundTag playerPersistentData = player.getPersistentData();
-
- if(playerPersistentData.contains("StoryDimension")){
- PlayerStoryDimensionData playerData = PlayerStoryDimensionData.load(playerPersistentData.getCompound("StoryDimension"));
- if(playerData.scourgeDenPlaced) {
- playerData.playerDimension = dimension;
- playerData.playerPos = playerPosition;
- playerPersistentData.put("StoryDimension", playerData.save());
- player.teleportTo(playerData.storyDimensionSpawnpoint.x, playerData.storyDimensionSpawnpoint.y, playerData.storyDimensionSpawnpoint.z);
-
- if(playerPersistentData.contains("RespawnsScourge") && playerPersistentData.getBoolean("RespawnsScourge"))
- {
- CompoundTag respawnPosTag = playerPersistentData.getCompound("ScourgeRespawnPosition");
-
- int x = respawnPosTag.getInt("x");
- int y = respawnPosTag.getInt("y");
- int z = respawnPosTag.getInt("z");
-
- BlockPos respawnPos = new BlockPos(x, y, z);
-
- ScourgeEntity newScourge = new ScourgeEntity(ModEntities.SCOURGE.get(), player.level());
- newScourge.setPos(respawnPos.getX() + 0.5d, respawnPos.getY() - 2.0d, respawnPos.getZ() + 0.5d);
- player.level().addFreshEntity(newScourge);
- playerPersistentData.remove("ScourgeRespawnPosition");
- playerPersistentData.remove("RespawnsScourge");
- playerPersistentData.putString("CurrentChapter", "new_game_plus_choice");
- }
- return;
- }
- }
-
- Vec3 newPlayerSpot = StoryDimensionData.getNextAvailableSpot();
- Vec3 newPlayerSpawnpoint = StoryDimensionData.getNextAvailableSpawnpoint();
- PlayerStoryDimensionData playerData = new PlayerStoryDimensionData(newPlayerSpawnpoint, dimension, playerPosition);
- playerData.scourgeDenPlaced = true;
- playerPersistentData.put("StoryDimension", playerData.save());
-
- BlockPos blockPos = new BlockPos((int)newPlayerSpot.x, (int)newPlayerSpot.y, (int)newPlayerSpot.z);
-
- MinecraftServer server = player.getServer();
- assert server != null;
- ServerLevel storyLevel = server.getLevel(ModDimensions.STORY_DIM_LEVEL_KEY);
- assert storyLevel != null;
- placeScourgeDenStructure(storyLevel, blockPos);
-
- player.teleportTo(newPlayerSpawnpoint.x, newPlayerSpawnpoint.y, newPlayerSpawnpoint.z);
- StoryDimensionData.setLastSpot(newPlayerSpot);
- StoryDimensionData.save(server.overworld());
- }
-
- if (event.getFrom() == ModDimensions.STORY_DIM_LEVEL_KEY){
- if(event.getEntity().level().isClientSide() && !(player instanceof ServerPlayer))
- return;
-
- if(player.getPersistentData().contains("ShowCredits") && player.getPersistentData().getBoolean("ShowCredits")) {
- ModNetwork.sendToPlayer(new ModNetwork.OpenDialoguePacket("credits"), (ServerPlayer) player);
- player.getPersistentData().putBoolean("ShowCredits", false);
-
- if(player.getPersistentData().contains("ScourgeRespawnPosition"))
- player.getPersistentData().putBoolean("RespawnsScourge", true);
- }
- }
- }
-
private void commonSetup(final FMLCommonSetupEvent event)
{
event.enqueueWork(fr.gcjojo.worldscolliding.network.ModNetwork::register);
diff --git a/src/main/java/fr/gcjojo/worldscolliding/StoryDimensionData.java b/src/main/java/fr/gcjojo/worldscolliding/StoryDimensionData.java
index 59bb6d5..7e0c507 100644
--- a/src/main/java/fr/gcjojo/worldscolliding/StoryDimensionData.java
+++ b/src/main/java/fr/gcjojo/worldscolliding/StoryDimensionData.java
@@ -31,7 +31,7 @@ public static Vec3 getNextAvailableSpawnpoint()
public static class StoryDimensionSavedData extends SavedData
{
- public Vec3 savedLastSpot;
+ public Vec3 savedLastSpot = new Vec3(0, 100, 0);
private static StoryDimensionSavedData create() {
return new StoryDimensionSavedData();
diff --git a/src/main/java/fr/gcjojo/worldscolliding/blocks/custom/StoryPortalBlock.java b/src/main/java/fr/gcjojo/worldscolliding/blocks/custom/StoryPortalBlock.java
index ae6c854..a8909f8 100644
--- a/src/main/java/fr/gcjojo/worldscolliding/blocks/custom/StoryPortalBlock.java
+++ b/src/main/java/fr/gcjojo/worldscolliding/blocks/custom/StoryPortalBlock.java
@@ -14,6 +14,7 @@
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape;
+import java.util.Objects;
import java.util.Set;
public class StoryPortalBlock extends Block {
@@ -35,21 +36,12 @@ public void entityInside(BlockState state, Level level, BlockPos blockPos, Entit
if(playerPersistentData.contains("StoryDimension"))
{
PlayerStoryDimensionData playerData = PlayerStoryDimensionData.load(playerPersistentData.getCompound("StoryDimension"));
- ServerLevel toLevel;
- switch(playerData.playerDimension)
- {
- case "the_end":
- toLevel = entity.getServer().getLevel(Level.END);
- break;
- case "nether":
- toLevel = entity.getServer().getLevel(Level.NETHER);
- break;
- case "overworld":
- default:
- toLevel = entity.getServer().getLevel(Level.OVERWORLD);
- break;
- }
+ ServerLevel toLevel = switch (playerData.playerDimension) {
+ case "the_end" -> Objects.requireNonNull(entity.getServer()).getLevel(Level.END);
+ case "nether" -> Objects.requireNonNull(entity.getServer()).getLevel(Level.NETHER);
+ default -> Objects.requireNonNull(entity.getServer()).getLevel(Level.OVERWORLD);
+ };
entity.teleportTo(toLevel, playerData.playerPos.x, playerData.playerPos.y, playerData.playerPos.z, Set.of(), 0.0f, 0.0f);
return;
diff --git a/src/main/java/fr/gcjojo/worldscolliding/client/gui/DialogueScreen.java b/src/main/java/fr/gcjojo/worldscolliding/client/gui/DialogueScreen.java
index 96a57ca..ef38207 100644
--- a/src/main/java/fr/gcjojo/worldscolliding/client/gui/DialogueScreen.java
+++ b/src/main/java/fr/gcjojo/worldscolliding/client/gui/DialogueScreen.java
@@ -33,6 +33,8 @@ public class DialogueScreen extends Screen {
private float currentFadingTime = -1.0f;
private static float endFade = 7.5f;
+ private boolean guiVisible = true;
+
private List