Skip to content

Commit 24d6fec

Browse files
committed
Reworked Wishing Well implementation with persistency and performance enhancements.
1 parent 1af101a commit 24d6fec

File tree

22 files changed

+715
-22
lines changed

22 files changed

+715
-22
lines changed

README.md

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ Craft a Marketplace hut. Using the build tool, choose the "Economics" style from
1414

1515
Marketplace Hut - Supports the Marketplace building and the Shopkeeper job.
1616
Advanced Clipboard - Just like the regular clipboard but with a button that filters the outstanding needs down to only those expected to be fulfilled by a player.
17-
Trade Coin - These coins can be minted from the marketplace by sneak-right-clicking your advanced clipboard on the Marketplace hut. The hut must be upgraded, first! Trade Coins will (eventually) be used as the basis for triggering most Trade Post mod features.
17+
Trade Coin - These coins can be minted from the marketplace by sneak-right-clicking your advanced clipboard on the Marketplace hut. The hut must be upgraded, first! Trade Coins will (eventually) be used as the basis for triggering most Trade Post mod features. Coins can be used at a Wishing Well to trigger certain effects.
1818

1919
### Custom Blocks
2020

@@ -24,6 +24,13 @@ Marketplace Hut Block - Block implementation of the item above.
2424
The value of a Trade Coin can be configured.
2525
The level of the marketplace required to mint coins can be configured.
2626

27+
### Making Wishes
28+
When you throw a coin into a wishing well with another object, your wish might come true!
29+
Currently implemented or in-progress:
30+
- Kill all zombies nearby (1 Coin + Zombie Flesh)
31+
- Terminate an in progress raid (1 Coin + 1 Iron Sword) NOT YET FULLY IMPLEMENTED
32+
33+
2734
## Installation
2835

2936
Download the appropriate mctradepost-x.y.z.jar file from Github at the root project directory.
@@ -32,28 +39,32 @@ Note that MineColonies and its dependencies must be present to work.
3239

3340
### Compatibility Reference
3441

35-
mctradepost-0.1.003 -> MineColonies 1.1.950 (Minecraft 1.21.1)
42+
mctradepost-0.2.001 -> MineColonies 1.1.950 (Minecraft 1.21.1)
3643

3744
## Building Design Reference
3845
### Marketplace
3946
The marketplace building should have two item frames or glowing item frames for each level of the building.
4047
These frames should be mounted in empty (air) blocks tagged with the "display_shelf" tag. (Apply the tag to a placeholder item, then remove that placeholder and put the frame in.)
4148

49+
### Wishing Well
50+
A wishing well can be created by surrounding a 2x2 puddle of water (depth 1) with stone bricks. (Future designs will be more aesthetically pleasing.)
4251

4352
## Current Status
4453

4554
This mod can best be described as a "pre-alpha" state. It functionality may change rapidly and without warning.
55+
"Wishing Well" Interface for spending earned income (IN PROGRESS)
4656

4757
### Roadmap (Roughly Prioritized)
4858

49-
Interface for spending earned income.
59+
Implement Coin Usage
5060
- Unlock subsequent levels of the merchant building
5161
- Summon traders
5262
- Add trader recipes
5363
Happiness based on colony wealth per citizen
5464
Leisure time / resorts / vacations (Resort hut w/custom needs items; travel agency hut)
5565
Huts to allow skill-up in non-primary/secondary stats.
5666
Pet shops, pet functions, pet-related colony roles.
67+
In-Game Instructions
5768
Assembling colonies into collections (empire, state, etc.)
5869
Express shipping (intracolony and inter-colony) - faster item transport. Faster people transport.
5970

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ mod_name=MC Trade Post
3232
# The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default.
3333
mod_license=All Rights Reserved
3434
# The mod version. See https://semver.org/
35-
mod_version=0.1.003
35+
mod_version=0.2.001
3636
# The group ID for the mod. It is only important when publishing as an artifact to a Maven repository.
3737
# This should match the base package used for the mod sources.
3838
# See https://maven.apache.org/guides/mini/guide-naming-conventions.html

src/main/java/com/deathfrog/mctradepost/MCTradePostMod.java

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.deathfrog.mctradepost;
22

3+
import java.util.function.Supplier;
4+
35
import org.slf4j.Logger;
46

57
import com.deathfrog.mctradepost.api.sounds.ModSoundEvents;
@@ -26,12 +28,16 @@
2628
import net.minecraft.client.renderer.entity.EntityRendererProvider;
2729
import net.minecraft.core.Registry;
2830
import net.minecraft.core.registries.Registries;
31+
import net.minecraft.resources.ResourceLocation;
2932
import net.minecraft.server.level.ServerPlayer;
33+
import net.minecraft.world.entity.EntityType;
34+
import net.minecraft.world.entity.MobCategory;
3035
import net.minecraft.world.item.CreativeModeTab;
3136
import net.minecraft.world.item.CreativeModeTabs;
3237
import net.minecraft.world.item.Item;
3338
import net.minecraft.world.item.Rarity;
3439
import net.minecraft.world.level.block.Block;
40+
import net.minecraft.world.level.block.entity.BlockEntityType;
3541
import net.neoforged.api.distmarker.Dist;
3642
import net.neoforged.api.distmarker.OnlyIn;
3743
import net.neoforged.bus.api.IEventBus;
@@ -53,11 +59,14 @@
5359
import net.neoforged.neoforge.network.event.RegisterPayloadHandlersEvent;
5460
import net.neoforged.neoforge.network.handling.DirectionalPayloadHandler;
5561
import net.neoforged.neoforge.network.registration.PayloadRegistrar;
62+
import net.neoforged.neoforge.registries.DeferredHolder;
5663
import net.neoforged.neoforge.registries.DeferredItem;
5764
import net.neoforged.neoforge.registries.DeferredRegister;
5865
import net.neoforged.neoforge.registries.RegisterEvent;
66+
import com.deathfrog.mctradepost.core.entity.CoinEntity;
5967
/*
6068
*/
69+
import com.deathfrog.mctradepost.core.entity.CoinRenderer;
6170

6271
// TODO: To register a sound in Minecraft, you'll need to add a sound event to the game's sounds.json file. You can do this by adding your custom sound events within the assets/minecraft/sounds.json file of your resource pack or mod. You'll also need to place the audio file (usually in .ogg format) in the correct directory (e.g., resources/assets/mod-id/sounds).
6372
/* MISSING SOUNDS:
@@ -348,26 +357,31 @@ public class MCTradePostMod
348357

349358
// Create a Deferred Register to hold Items which will all be registered under the "mctradepost" namespace
350359
public static final DeferredRegister.Items ITEMS = DeferredRegister.createItems(MODID);
360+
361+
// Create a Deferred Register to hold Entities which will all be registered under the "mctradepost" namespace
362+
public static final DeferredRegister<EntityType<?>> ENTITIES = DeferredRegister.create(Registries.ENTITY_TYPE, MCTradePostMod.MODID);
351363

364+
352365
public static final DeferredItem<AdvancedClipboardItem> ADVANCED_CLIPBOARD = ITEMS.register("advanced_clipboard",
353366
() -> new AdvancedClipboardItem(new Item.Properties().stacksTo(1)));
367+
368+
public static final DeferredHolder<EntityType<?>, EntityType<CoinEntity>> COIN_ENTITY_TYPE =
369+
ENTITIES.register("coin_entity", () ->
370+
EntityType.Builder.<CoinEntity>of(CoinEntity::new, MobCategory.MISC)
371+
.sized(0.25f, 0.25f) // Size of the entity (like an ItemEntity)
372+
.clientTrackingRange(8) // Reasonable for item-like entities
373+
.updateInterval(10) // Sync rate
374+
.build(ResourceLocation.fromNamespaceAndPath(MCTradePostMod.MODID, "coin_entity").toString())
375+
);
354376

355-
public static final DeferredItem<CoinItem> MCTP_COIN = ITEMS.register("mctp_coin",
377+
public static final DeferredItem<CoinItem> MCTP_COIN_ITEM = ITEMS.register("mctp_coin",
356378
() -> new CoinItem(new Item.Properties().stacksTo(64).rarity(Rarity.UNCOMMON)));
357379

358380
public static MCTPBaseBlockHut blockHutMarketplace;
359381

360382
// Create a Deferred Register to hold CreativeModeTabs which will all be registered under the "examplemod" namespace
361383
public static final DeferredRegister<CreativeModeTab> CREATIVE_MODE_TABS = DeferredRegister.create(Registries.CREATIVE_MODE_TAB, MODID);
362384

363-
// Creates a new Block with the id "examplemod:example_block", combining the namespace and path
364-
// public static final DeferredBlock<Block> EXAMPLE_BLOCK = BLOCKS.registerSimpleBlock("example_block", BlockBehaviour.Properties.of().mapColor(MapColor.STONE));
365-
366-
// Creates a new BlockItem with the id "examplemod:example_block", combining the namespace and path
367-
// public static final DeferredItem<BlockItem> EXAMPLE_BLOCK_ITEM = ITEMS.registerSimpleBlockItem("example_block", EXAMPLE_BLOCK);
368-
369-
// Creates a new food item with the id "examplemod:example_id", nutrition 1 and saturation 2
370-
// public static final DeferredItem<Item> EXAMPLE_ITEM = ITEMS.registerSimpleItem("example_item", new Item.Properties().food(new FoodProperties.Builder().alwaysEdible().nutrition(1).saturationModifier(2f).build()));
371385

372386
// Creates a creative tab with the id "examplemod:example_tab" for the example item, that is placed after the combat tab
373387
/*
@@ -389,8 +403,13 @@ public MCTradePostMod(IEventBus modEventBus, ModContainer modContainer)
389403

390404
// Register the Deferred Register to the mod event bus so blocks get registered
391405
BLOCKS.register(modEventBus);
406+
392407
// Register the Deferred Register to the mod event bus so items get registered
393408
ITEMS.register(modEventBus);
409+
410+
// Register the Deferred Register to the mod event bus so entities get registered
411+
ENTITIES.register(modEventBus);
412+
394413
// Register the Deferred Register to the mod event bus so tabs get registered
395414
CREATIVE_MODE_TABS.register(modEventBus);
396415

@@ -535,6 +554,12 @@ public static void registerLayerDefinitions(EntityRenderersEvent.RegisterLayerDe
535554
event.registerLayerDefinition(ClientRegistryHandler.FEMALE_SHOPKEEPER, FemaleShopkeeperModel::createMesh);
536555
}
537556

557+
@OnlyIn(Dist.CLIENT)
558+
@SubscribeEvent
559+
public static void onRegisterRenderers(EntityRenderersEvent.RegisterRenderers event) {
560+
event.registerEntityRenderer(MCTradePostMod.COIN_ENTITY_TYPE.get(), CoinRenderer::new);
561+
}
562+
538563
@SubscribeEvent
539564
public static void onAddLayers(EntityRenderersEvent.AddLayers event) {
540565
LOGGER.info("Handling model initialization");

src/main/java/com/deathfrog/mctradepost/api/tileentities/MCTradePostTileEntities.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@ public class MCTradePostTileEntities
88

99
public static DeferredHolder<BlockEntityType<?>, BlockEntityType<MCTPTileEntityColonyBuilding>> BUILDING;
1010

11+
public static DeferredHolder<BlockEntityType<?>, BlockEntityType<MCTPTileEntityColonyBuilding>> MARKETPLACE;
1112
}

src/main/java/com/deathfrog/mctradepost/core/blocks/huts/BlockHutMarketplace.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,8 @@ public BuildingEntry getBuildingEntry() {
2020
return ModBuildings.marketplace.get();
2121
}
2222

23+
public void handleRitual() {
24+
25+
}
26+
2327
}

src/main/java/com/deathfrog/mctradepost/core/colony/jobs/buildings/workerbuildings/BuildingMarketplace.java

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.deathfrog.mctradepost.core.colony.jobs.buildings.workerbuildings;
22

33
import com.minecolonies.api.colony.IColony;
4+
import com.minecolonies.api.colony.IColonyManager;
45
import com.minecolonies.api.colony.buildings.modules.settings.ISettingKey;
56
import com.minecolonies.api.colony.jobs.registry.JobEntry;
67
import com.minecolonies.api.crafting.IGenericRecipe;
@@ -32,10 +33,12 @@
3233
import com.deathfrog.mctradepost.core.client.gui.modules.WindowEconModule;
3334
import com.deathfrog.mctradepost.core.colony.jobs.buildings.modules.BuildingEconModule;
3435
import com.deathfrog.mctradepost.core.colony.jobs.buildings.modules.MCTPBuildingModules;
36+
import com.deathfrog.mctradepost.core.event.wishingwell.RitualData;
3537
import com.google.common.collect.ImmutableList;
3638

3739
import java.util.ArrayList;
3840
import java.util.Collections;
41+
import java.util.Comparator;
3942
import java.util.HashMap;
4043
import java.util.List;
4144
import java.util.Map;
@@ -48,6 +51,7 @@
4851
*/
4952
public class BuildingMarketplace extends AbstractBuilding
5053
{
54+
protected RitualData ritualData = new RitualData();
5155

5256
public BuildingMarketplace(@NotNull IColony colony, BlockPos pos) {
5357
super(colony, pos);
@@ -109,6 +113,14 @@ public int getMaxBuildingLevel()
109113
return CONST_DEFAULT_MAX_BUILDING_LEVEL;
110114
}
111115

116+
/**
117+
* Gets the ritual data for this marketplace, which tracks the state of wishing wells within the colony.
118+
* @return the ritual data for this marketplace.
119+
*/
120+
public RitualData getRitualData() {
121+
return ritualData;
122+
}
123+
112124
@Override
113125
public void registerBlockPosition(@NotNull final BlockState block, @NotNull final BlockPos pos, @NotNull final Level world)
114126
{
@@ -209,6 +221,8 @@ public void deserializeNBT(@NotNull final HolderLookup.Provider provider, final
209221
displayShelfContents.put(contents.getPos(), contents);
210222
}
211223

224+
ritualData.deserializeNBT(provider, compound);
225+
212226
syncDisplayFramesWithSavedItems();
213227
}
214228

@@ -227,7 +241,7 @@ public ItemStack mintCoins(Player player, int coinsToMint) {
227241

228242
BuildingEconModule econ = this.getModule(MCTPBuildingModules.ECON_MODULE);
229243
if (valueToRemove < econ.getTotalBalance()) {
230-
coinStack = new ItemStack(MCTradePostMod.MCTP_COIN.get(), coinsToMint);
244+
coinStack = new ItemStack(MCTradePostMod.MCTP_COIN_ITEM.get(), coinsToMint);
231245
econ.incrementBy(WindowEconModule.CURRENT_BALANCE, -valueToRemove);
232246
econ.markDirty();
233247
} else {
@@ -261,6 +275,33 @@ public void depositCoins(Player player, ItemStack coinsToDeposit) {
261275
}
262276
}
263277

278+
/**
279+
* Finds the nearest BuildingMarketplace to the given BlockPos in the given Level,
280+
* assuming BlockPos is located inside a colony.
281+
*
282+
* @param level the level to search in
283+
* @param pos the BlockPos to search near
284+
* @return the nearest BuildingMarketplace, or null if none is found
285+
*/
286+
public static BuildingMarketplace getMarketplaceFromPos(Level level, BlockPos pos) {
287+
// Check if inside a MineColonies colony
288+
BuildingMarketplace closestMarketplace = null;
289+
IColonyManager colonyManager = IColonyManager.getInstance();
290+
IColony colony = colonyManager.getColonyByPosFromWorld(level, pos);
291+
292+
if (colony != null) {
293+
// Find the nearest BuildingMarketplace
294+
closestMarketplace = colony.getBuildingManager()
295+
.getBuildings()
296+
.values()
297+
.stream()
298+
.filter(b -> b instanceof BuildingMarketplace)
299+
.map(b -> (BuildingMarketplace) b)
300+
.min(Comparator.comparingDouble(market -> market.getPosition().distSqr(pos)))
301+
.orElse(null);
302+
}
303+
return closestMarketplace;
304+
}
264305

265306
/**
266307
* Serializes the NBT data for the building, including the display shelf contents.
@@ -282,6 +323,9 @@ public CompoundTag serializeNBT(@NotNull final HolderLookup.Provider provider)
282323
}
283324

284325
compound.put(TAG_DISPLAYSHELVES, shelfTagList);
326+
327+
ritualData.serializeNBT(provider);
328+
285329
return compound;
286330
}
287331

0 commit comments

Comments
 (0)