Skip to content

Commit

Permalink
alpha 1
Browse files Browse the repository at this point in the history
  • Loading branch information
NeumimTo committed Apr 23, 2022
1 parent fe7b542 commit 7d4f21a
Show file tree
Hide file tree
Showing 23 changed files with 445 additions and 97 deletions.
42 changes: 41 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,41 @@
# TownyColonies
# TownyColonies

Towny addon that adds automated farms, factories and administrative buildings into towny town & nation system

The plugin forces players to build houses from predefine block palletes

**Alphabuilds are not suitable for production env.**

For any questions ping NeumimTo at the towny discord

## Requirements ##

Tested on:

- paper 1.18.x (might work on 1.17, wont work with anything below 1.16)
- towny 0.98.1.0 (might or might not work with older versions)

## Building from source

- `gradlew shadowJar`
- The jar is then located in path `build/libs/townycolonies-{version}-all.jar`

## Installation

- drop the jar into plugins folder
- default configs might not be balanced to suit yours server economy
- Towny must use mysql database
- Append sql database connection flags by `&allowMultiQueries=true`

## Gameplay

- Permission: `townycolonies.administrative`
- Buys new blueprints

- Permission: `townycolonies.architect`
- Chooses blueprint location
- Can toggle edit mode for structure

- Players
- Build structure according to the blueprint block requirements
- Once the build is finished they need to call the architect to toggle edit mode
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ plugins {
}

group = 'cz.neumimto.towny'
version = '1.0-SNAPSHOT'
version = 'ALPHA-1.0.0'

repositories {
mavenCentral()
Expand Down
60 changes: 43 additions & 17 deletions src/main/java/cz/neumimto/towny/townycolonies/ItemService.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.bukkit.NamespacedKey;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.ShapedRecipe;
import org.bukkit.inventory.ShapelessRecipe;
import org.bukkit.inventory.meta.ItemMeta;

import javax.inject.Singleton;
Expand All @@ -23,29 +24,54 @@ public void registerRecipes() {
meta.setCustomModelData(3077);
meta.displayName(Component.text("Town administration"));
});
ShapedRecipe shapedRecipe = new ShapedRecipe(recipe, itemStack);
shapedRecipe.shape(
"-S-",
"SPS",
"-S-"
);
shapedRecipe.setIngredient('P', Material.BOOK);
shapedRecipe.setIngredient('S', Material.GOLD_NUGGET);
Bukkit.getServer().addRecipe(shapedRecipe);
ShapelessRecipe shapelessRecipe = new ShapelessRecipe(recipe, itemStack);
shapelessRecipe.addIngredient(Material.BOOK);
shapelessRecipe.addIngredient(Material.EMERALD);

Bukkit.getServer().addRecipe(shapelessRecipe);

recipe = NamespacedKey.fromString("townycolonies:structure_tool");
if (Bukkit.getServer().getRecipe(recipe) != null) {
Bukkit.getServer().removeRecipe(recipe);
}
itemStack = new ItemStack(Material.PAPER);
itemStack.editMeta(meta -> {
meta.setCustomModelData(3078);
meta.displayName(Component.text("Structure Edit Tool"));
});
ShapelessRecipe editTool = new ShapelessRecipe(recipe, itemStack);
editTool.addIngredient(Material.PAPER);
editTool.addIngredient(Material.WOODEN_SHOVEL);
Bukkit.getServer().addRecipe(editTool);
}

public boolean isTownBook(ItemStack itemInUse) {
public StructureTool getItemType(ItemStack itemInUse) {
if (itemInUse == null) {
return false;
return null;
}
if (itemInUse.getType() != Material.ENCHANTED_BOOK) {
return false;

if (itemInUse.getType() == Material.ENCHANTED_BOOK) {
ItemMeta itemMeta = itemInUse.getItemMeta();
if (itemMeta.hasCustomModelData()) {
if (itemMeta.getCustomModelData() == 3077) {
return StructureTool.TOWN_TOOL;
}
}
}
ItemMeta itemMeta = itemInUse.getItemMeta();
if (itemMeta.hasCustomModelData()) {
return itemMeta.getCustomModelData() == 3077;

if (itemInUse.getType() == Material.PAPER) {
ItemMeta itemMeta = itemInUse.getItemMeta();
if (itemMeta.hasCustomModelData()) {
if (itemMeta.getCustomModelData() == 3078) {
return StructureTool.EDIT_TOOL;
}
}
}
return false;

return null;
}

public static enum StructureTool {
EDIT_TOOL, TOWN_TOOL
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import cz.neumimto.towny.townycolonies.model.EditSession;
import cz.neumimto.towny.townycolonies.model.LoadedStructure;
import cz.neumimto.towny.townycolonies.model.Region;
import net.kyori.adventure.text.minimessage.MiniMessage;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
Expand Down Expand Up @@ -36,6 +37,8 @@ public EditSession startNewEditSession(Player player, Structure structure, Locat
var es = new EditSession(structure, location);
es.structure = structure;
editSessions.put(player.getUniqueId(), es);
MiniMessage miniMessage = MiniMessage.miniMessage();
player.sendMessage(miniMessage.deserialize("<gold>[TownyColonies]</gold> <green>Right click again to change blueprint location, Left click to confirm selection and place blueprint</green>"));
return es;
}

Expand All @@ -59,7 +62,8 @@ public boolean moveTo(Player player, Location location) {
if (overlaps.isPresent()) {
Region region1 = overlaps.get();
Structure overlapingStruct = configurationService.findStructureById(region1.structureId).get();
player.sendMessage(editSession.structure.name + " region overlaps with " + overlapingStruct.name);
MiniMessage miniMessage = MiniMessage.miniMessage();
player.sendMessage(miniMessage.deserialize("<gold>[TownyColonies]</gold> <red>"+editSession.structure.name + " region overlaps with " + overlapingStruct.name+"</red>"));
isOk = false;

if (editSession.overlappintStructureBorder != null) {
Expand All @@ -76,7 +80,8 @@ public boolean moveTo(Player player, Location location) {

Town town = TownyAPI.getInstance().getResident(player).getTownOrNull();
if (subclaimService.isOutsideTownClaim(region, town)) {
player.sendMessage(editSession.structure.name + " is outside town claim");
MiniMessage miniMessage = MiniMessage.miniMessage();
player.sendMessage(miniMessage.deserialize("<gold>[TownyColonies]</gold> <red>"+editSession.structure.name + " is outside town claim"+"</red>"));
isOk = false;
}

Expand All @@ -101,7 +106,7 @@ public void endSessionWithoutPlacement(Player player) {
}

public void endSession(Player player, Location location) {
if (editSessions.containsKey(player.getUniqueId())) {
if (editSessions.containsKey(player.getUniqueId())) {
EditSession editSession = editSessions.get(player.getUniqueId());
editSession.center = location;
if (moveTo(player, editSession.center)) {
Expand Down Expand Up @@ -184,14 +189,16 @@ public void placeBlueprint(Player player, Location location, Structure structure
loadedStructure.strucutureId = structure.id;
loadedStructure.center = center;

loadedStructure.town = town.getUUID();
loadedStructure.structure = structure;

loadedStructure.editMode = true;
structureService.addToTown(town, loadedStructure);

Region lreg = subclaimService.createRegion(loadedStructure).get();
subclaimService.registerRegion(lreg);
subclaimService.registerRegion(lreg, loadedStructure);

TownyMessaging.sendPrefixedTownMessage(town, player.getName() + " placed " + structure.name + " at " + location.getBlockX() + ", " + location.getBlockY() + ", " + location.getBlockZ());
structureService.save(loadedStructure);
}

private void sendBlockChange(Player player, Set<Location> locations, Material mat) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
package cz.neumimto.towny.townycolonies;

import com.palmergames.bukkit.towny.TownyAPI;
import com.palmergames.bukkit.towny.TownyMessaging;
import com.palmergames.bukkit.towny.object.Town;
import cz.neumimto.towny.townycolonies.config.ConfigurationService;
import cz.neumimto.towny.townycolonies.config.Structure;
import cz.neumimto.towny.townycolonies.db.Database;
import cz.neumimto.towny.townycolonies.mechanics.RequirementMechanic;
import cz.neumimto.towny.townycolonies.mechanics.TownContext;
import cz.neumimto.towny.townycolonies.model.LoadedStructure;
import cz.neumimto.towny.townycolonies.model.Region;
import cz.neumimto.towny.townycolonies.model.StructureAndCount;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.MiniMessage;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;

Expand Down Expand Up @@ -48,15 +51,15 @@ public void addToTown(Structure structure, Town town, Location location) {

}

public ItemStack toItemStack(Structure structure, Town context, int count) {
public ItemStack toItemStack(Structure structure, int count) {
ItemStack itemStack = new ItemStack(structure.material);
ItemMeta itemMeta = itemStack.getItemMeta();

var mm = MiniMessage.miniMessage();
itemMeta.displayName(mm.deserialize(structure.name));
itemMeta.setCustomModelData(structure.customModelData);

List<Component> lore = configurationService.buildStructureLore(structure, count, structure.maxCount, context);
List<Component> lore = configurationService.buildStructureLore(structure, count, structure.maxCount);
itemMeta.lore(lore);
itemStack.setItemMeta(itemMeta);
return itemStack;
Expand Down Expand Up @@ -141,7 +144,10 @@ public boolean canBuy(TownContext context) {
}

public void addToTown(Town town, LoadedStructure loadedStructure) {

structures.put(loadedStructure.uuid, loadedStructure);
loadedStructure.town = town.getUUID();
Set<LoadedStructure> loadedStructures = byTown.computeIfAbsent(town.getUUID(), k -> new HashSet<>());
loadedStructures.add(loadedStructure);
}

public void loadAll() {
Expand All @@ -154,6 +160,11 @@ public void loadAll() {
.filter(a -> a.structure != null)
.filter(a->towns.contains(a.town))
.peek(a -> structures.put(a.uuid, a))
.peek(a-> {
Set<LoadedStructure> loadedStructures = byTown.computeIfAbsent(a.town, k -> new HashSet<>());
loadedStructures.add(a);
})
.peek(a-> subclaimService.createRegion(a).ifPresent(b->subclaimService.registerRegion(b,a)))
.forEach(a -> {
Set<LoadedStructure> set = new HashSet<>();
set.add(a);
Expand All @@ -167,4 +178,26 @@ public void loadAll() {
public void saveAll() {
Database.saveAll(structures.values());
}

public void save(LoadedStructure loadedStructure) {
Database.scheduleSave(loadedStructure);
}

public void delete(Region region, Player player) {
subclaimService.delete(region);
LoadedStructure l = region.loadedStructure;
structures.remove(l.uuid);
Set<LoadedStructure> loadedStructures = byTown.get(l.town);
Iterator<LoadedStructure> iterator = loadedStructures.iterator();
while (iterator.hasNext()) {
LoadedStructure next = iterator.next();
if (next == l) {
iterator.remove();
Town town = TownyAPI.getInstance().getTown(l.town);
TownyMessaging.sendPrefixedTownMessage(town, player.getName() + " deleted structure " + l.structure.name);
break;
}
}
}

}
27 changes: 23 additions & 4 deletions src/main/java/cz/neumimto/towny/townycolonies/SubclaimService.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@

import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import java.util.*;

@Singleton
public class SubclaimService {
Expand All @@ -40,7 +38,8 @@ public Region createRegion(Structure def, Location center) {
return new Region(def.id, of, center.getWorld().getName());
}

public void registerRegion(Region value) {
public void registerRegion(Region value, LoadedStructure loadedStructure) {
value.loadedStructure = loadedStructure;
subclaims.add(value);
}

Expand Down Expand Up @@ -111,4 +110,24 @@ public Optional<Structure> getStructureAt(Location location) {
}
return Optional.empty();
}

public Region getRegion(UUID fromString) {
for (Region subclaim : subclaims) {
if (subclaim.uuid.equals(fromString)) {
return subclaim;
}
}
return null;
}

public void delete(Region region) {
Iterator<Region> iterator = subclaims.iterator();
while (iterator.hasNext()) {
Region next = iterator.next();
if (next == region) {
iterator.remove();
break;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public class StructureCommands extends BaseCommand {
private ConfigurationService configurationService;

@CommandPermission("townycolonies.admin")
@Subcommand("reload")
public void reload() {
TownyColonies.INSTANCE.onEnable();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,7 @@ public void copy(Path structures, String file) {

public List<Component> buildStructureLore(Structure structure,
int townCount,
int maxCount,
Town town) {
int maxCount) {
var mm = MiniMessage.miniMessage();

List<Component> list = new ArrayList<>();
Expand Down Expand Up @@ -175,4 +174,8 @@ public List<Component> buildBlueprintLore(Structure structure) {
}
return list;
}

public Collection<Material> getBlockGroup(String group) {
return config.blockdb.getOrDefault(group, Collections.emptyList());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,17 @@ public Map<String, List<Material>> convertToField(Config value) {
for (Config.Entry entry : value.entrySet()) {
String key = entry.getKey();
String v = entry.getValue();
String[] split = v.split(",");
String[] split = v.split(" ");
List<Material> materials = new ArrayList<>();
for (String s : split) {
s = s.trim();
Material material = Material.matchMaterial(s);
if (material == null) {
Set<String> mats = Wildcards.substract(s.toUpperCase(Locale.ENGLISH), allNames);
materials.addAll(mats.stream().map(Material::matchMaterial).toList());
} else {
materials.add(material);
}
materials.add(material);
}
map.put(key, materials);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,12 @@ public static class Blocks implements Converter<Map, Config> {
public Map convertToField(Config value) {
Map map = new HashMap();

if (value != null) {
Map<String, Object> stringObjectMap = value.valueMap();
for (Map.Entry<String, Object> e : stringObjectMap.entrySet()) {
map.put(e.getKey(), Integer.parseInt(e.getValue().toString()));
}
}

return map;
}
Expand Down
Loading

0 comments on commit 7d4f21a

Please sign in to comment.