Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add SiegeCamp object, created when a Siege is about to start. #404

Merged
merged 9 commits into from
Nov 18, 2021
49 changes: 49 additions & 0 deletions src/main/java/com/gmail/goosius/siegewar/SiegeController.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import com.gmail.goosius.siegewar.settings.SiegeWarSettings;
import com.gmail.goosius.siegewar.settings.Translation;
import com.gmail.goosius.siegewar.utils.CosmeticUtil;
import com.gmail.goosius.siegewar.utils.SiegeCampUtil;
import com.gmail.goosius.siegewar.utils.SiegeWarDistanceUtil;
import com.palmergames.bukkit.towny.TownyEconomyHandler;
import com.palmergames.bukkit.towny.TownyMessaging;
Expand All @@ -33,11 +34,13 @@
import com.gmail.goosius.siegewar.enums.SiegeSide;
import com.gmail.goosius.siegewar.metadata.SiegeMetaDataController;
import com.gmail.goosius.siegewar.objects.Siege;
import com.gmail.goosius.siegewar.objects.SiegeCamp;
import com.gmail.goosius.siegewar.utils.SiegeWarMoneyUtil;
import com.gmail.goosius.siegewar.utils.SiegeWarImmunityUtil;
import com.gmail.goosius.siegewar.utils.SiegeWarTownUtil;
import com.palmergames.bukkit.towny.TownyAPI;
import com.palmergames.bukkit.towny.TownyUniverse;
import com.palmergames.bukkit.towny.exceptions.TownyException;
import com.palmergames.bukkit.towny.object.Nation;
import com.palmergames.bukkit.towny.object.Town;

Expand All @@ -53,6 +56,7 @@ public class SiegeController {
private static Map<UUID, Siege> townSiegeMap = new ConcurrentHashMap<>();
private static List<Town> siegedTowns = new ArrayList<>();
private static List<String> siegedTownNames = new ArrayList<>();
private static List<SiegeCamp> siegeCamps = new ArrayList<>();

public static void newSiege(Town town) {
Siege siege = new Siege(town);
Expand Down Expand Up @@ -569,4 +573,49 @@ public static boolean doesNationHaveAnyHomeDefenceContributionsInActiveSieges(Na
}
return false;
}

/**
* List of {@link SiegeCamp}s, objects which precede a Siege.
*/
public static List<SiegeCamp> getSiegeCamps() {
return Collections.unmodifiableList(siegeCamps);
}

/**
* Add a {@link SiegeCamp} to the SiegeCamp list.
* @param camp {@link SiegeCamp} to add.
*/
public static void addSiegeCamp(SiegeCamp camp) {
siegeCamps.add(camp);
}

/**
* Remove a {@link SiegeCamp} from the SiegeCamp list.
* @param camp {@link SiegeCamp} to remove.
*/
public static void removeSiegeCamp(SiegeCamp camp) {
siegeCamps.remove(camp);
}

/**
* Initiates a {@link SiegeCamp}, leads to a {@link Siege} if successfully camped.
* @param camp {@link SiegeCamp} to begin.
* @throws TownyException if SiegeCamp is denied.
*/
public static void beginSiegeCamp(SiegeCamp camp) throws TownyException {
// Another SiegeCamp is already present.
if (SiegeWarDistanceUtil.campTooClose(camp.getBannerBlock().getLocation()))
throw new TownyException(Translation.of("msg_err_siegecamp_too_close_to_another_siegecamp"));

// Town initiating the SiegeCamp has a failed SiegeCamp on this
// town and not enough time has passed.
if (SiegeCampUtil.hasFailedCamp(camp.getTargetTown(), camp.getTownOfSiegeStarter()))
throw new TownyException(Translation.of("msg_err_too_soon_since_your_last_siegecamp"));

// Broadcast a message
Messaging.sendGlobalMessage(Translation.of("attacker_has_begun_a_siegecamp_session", camp.getTownOfSiegeStarter(), camp.getTargetTown(), SiegeWarSettings.getSiegeCampPointsForSuccess(), SiegeWarSettings.getSiegeCampDurationInMinutes()));
// Add to SiegeCamp list and begin Evaluating this SiegeCamp for success.
addSiegeCamp(camp);
Bukkit.getScheduler().runTask(SiegeWar.getSiegeWar(), ()-> SiegeCampUtil.evaluateCamp(camp, true));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ public void onBlockBreak(TownyDestroyEvent event) {
event.setCancelled(true);
return;
}
if (SiegeWarBlockUtil.isBlockNearAnActiveSiegeBanner(event.getBlock())) {
if (SiegeWarBlockUtil.isBlockNearAnActiveSiegeBanner(event.getBlock())
|| SiegeWarBlockUtil.isBlockNearAnActiveSiegeCampBanner(event.getBlock())) {
event.setMessage(Translation.of("msg_err_siege_war_cannot_destroy_siege_banner"));
event.setCancelled(true);
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,34 @@ public class TownMetaDataController {
private static StringDataField occupyingNationUUID = new StringDataField("siegewar_occupyingNationUUID", "");
//The nation who was the occupier prior to peacefulness confirmation
private static StringDataField prePeacefulOccupierUUID = new StringDataField("siegewar_prePeacefulOccupierUUID", "");
//List of failed SiegeCamps on the town.
private static StringDataField failedCampList = new StringDataField("siegewar_failedCampList", "");

public TownMetaDataController(SiegeWar plugin) {
this.plugin = plugin;
}

@Nullable
public static String getFailedSiegeCampList(Town town) {
StringDataField sdf = (StringDataField) failedCampList.clone();
if (town.hasMeta(sdf.getKey())) {
return MetaDataUtil.getString(town, sdf);
}
return null;
}

public static void setFailedCampSiegeList(Town town, String campList) {
StringDataField sdf = (StringDataField) failedCampList.clone();
if (town.hasMeta(sdf.getKey()))
MetaDataUtil.setString(town, sdf, campList, true);
else
town.addMetaData(new StringDataField("siegewar_failedCampList", campList));
}

public static void removeFailedCampSiegeList(Town town) {
town.removeMetaData((StringDataField) failedCampList.clone());
}

public static int getPeacefulnessChangeConfirmationCounterDays(Town town) {
IntegerDataField idf = (IntegerDataField) peacefulnessChangeConfirmationCounterDays.clone();
if (town.hasMeta(idf.getKey())) {
Expand Down
149 changes: 149 additions & 0 deletions src/main/java/com/gmail/goosius/siegewar/objects/SiegeCamp.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
package com.gmail.goosius.siegewar.objects;

import org.bukkit.Bukkit;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;

import com.gmail.goosius.siegewar.Messaging;
import com.gmail.goosius.siegewar.SiegeController;
import com.gmail.goosius.siegewar.enums.SiegeType;
import com.gmail.goosius.siegewar.events.PreSiegeWarStartEvent;
import com.gmail.goosius.siegewar.settings.SiegeWarSettings;
import com.gmail.goosius.siegewar.settings.Translation;
import com.gmail.goosius.siegewar.utils.SiegeWarMoneyUtil;
import com.palmergames.bukkit.towny.TownyEconomyHandler;
import com.palmergames.bukkit.towny.TownyMessaging;
import com.palmergames.bukkit.towny.object.Government;
import com.palmergames.bukkit.towny.object.Nation;
import com.palmergames.bukkit.towny.object.Town;
import com.palmergames.bukkit.towny.object.TownBlock;
import com.palmergames.util.TimeTools;

public class SiegeCamp {
private final Player player;
private final Block bannerBlock;
private final SiegeType siegeType;
private final Town targetTown;
private final Government attacker;
private final Government defender;
private final Town townOfSiegeStarter;
private TownBlock townBlock;
private int attackerPoints = 0;
private final long endTime;

public SiegeCamp(Player player, Block bannerBlock, SiegeType siegeType, Town targetTown, Government attacker,
Government defender, Town townOfSiegeStarter,TownBlock townBlock) {
this.player = player;
this.bannerBlock = bannerBlock;
this.siegeType = siegeType;
this.targetTown = targetTown;
this.attacker = attacker;
this.defender = defender;
this.townOfSiegeStarter = townOfSiegeStarter;
this.townBlock = townBlock;
this.endTime = System.currentTimeMillis() + TimeTools.getMillis(SiegeWarSettings.getSiegeCampDurationInMinutes() + "m");
}

/**
* @return the player
*/
public Player getPlayer() {
return player;
}

/**
* @return the bannerBlock
*/
public Block getBannerBlock() {
return bannerBlock;
}

/**
* @return the siegeType
*/
public SiegeType getSiegeType() {
return siegeType;
}

/**
* @return the targetTown
*/
public Town getTargetTown() {
return targetTown;
}

/**
* @return the attacker
*/
public Government getAttacker() {
return attacker;
}

/**
* @return the defender
*/
public Government getDefender() {
return defender;
}

/**
* @return the townOfSiegeStarter
*/
public Town getTownOfSiegeStarter() {
return townOfSiegeStarter;
}

/**
* @return the endTime
*/
public long getEndTime() {
return endTime;
}

/**
* @return the attackerPoints
*/
public int getAttackerPoints() {
return attackerPoints;
}

/**
* @param attackerPoints the attackerPoints to set
*/
public void setAttackerPoints(int attackerPoints) {
this.attackerPoints = attackerPoints;
}

/**
* Starts the Siege after the success of the SiegeCamp.
*/
public void startSiege() {

// Retest that the nation can still pay the warchest.
if (!siegeType.equals(SiegeType.REVOLT) && TownyEconomyHandler.isActive() && !attacker.getAccount().canPayFromHoldings(SiegeWarMoneyUtil.calculateSiegeCost(targetTown))) {
TownyMessaging.sendPrefixedNationMessage((Nation)attacker, Translation.of("msg_err_no_money"));
return;
}


Nation eventNation = siegeType.equals(SiegeType.REVOLT) ? (Nation) defender : (Nation) attacker;
// Call event
PreSiegeWarStartEvent preSiegeWarStartEvent = new PreSiegeWarStartEvent(siegeType, targetTown, eventNation, townOfSiegeStarter, bannerBlock, townBlock);
Bukkit.getPluginManager().callEvent(preSiegeWarStartEvent);

// Setup attack
if (!preSiegeWarStartEvent.isCancelled()) {
SiegeController.startSiege(
bannerBlock,
siegeType,
targetTown,
attacker,
defender,
townOfSiegeStarter,
!siegeType.equals(SiegeType.REVOLT));
} else {
Messaging.sendErrorMsg(player, preSiegeWarStartEvent.getCancellationMsg());
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ public static void evaluatePlaceColouredBannerNearTown(Player player,

//Check whether nearby town has a current or recent siege
if (SiegeController.hasSiege(nearbyTown)) {
//If there is no siege, it is an attempt to invade the town
//If there is a siege, it is an attempt to invade the town
Siege siege = SiegeController.getSiege(nearbyTown);
InvadeTown.processInvadeTownRequest(player, residentsNation, nearbyTown, siege);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import com.gmail.goosius.siegewar.SiegeController;
import com.gmail.goosius.siegewar.enums.SiegeType;
import com.gmail.goosius.siegewar.enums.SiegeWarPermissionNodes;
import com.gmail.goosius.siegewar.events.PreSiegeWarStartEvent;
import com.gmail.goosius.siegewar.objects.SiegeCamp;
import com.gmail.goosius.siegewar.settings.SiegeWarSettings;
import com.gmail.goosius.siegewar.settings.Translation;
import com.palmergames.bukkit.towny.TownySettings;
Expand All @@ -14,7 +14,6 @@
import com.palmergames.bukkit.towny.object.Nation;
import com.palmergames.bukkit.towny.object.Town;
import com.palmergames.bukkit.towny.object.TownBlock;
import org.bukkit.Bukkit;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;

Expand Down Expand Up @@ -78,22 +77,12 @@ public static void processStartSiegeRequest(Player player,
}
}

//Call event
PreSiegeWarStartEvent preSiegeWarStartEvent = new PreSiegeWarStartEvent(SiegeType.CONQUEST, targetTown, nationOfSiegeStarter, townOfSiegeStarter, bannerBlock, townBlock);
Bukkit.getPluginManager().callEvent(preSiegeWarStartEvent);

//Setup attack
if (!preSiegeWarStartEvent.isCancelled()){
SiegeController.startSiege(
bannerBlock,
SiegeType.CONQUEST,
targetTown,
nationOfSiegeStarter,
targetTown,
townOfSiegeStarter,
true);
} else {
throw new TownyException(preSiegeWarStartEvent.getCancellationMsg());
}
SiegeCamp camp = new SiegeCamp(player, bannerBlock, SiegeType.CONQUEST, targetTown, nationOfSiegeStarter, targetTown, townOfSiegeStarter, townBlock);
if (SiegeWarSettings.areSiegeCampsEnabled())
// Launch a SiegeCamp, a (by default) 10 minute minigame. If successful the Siege will be initiated in ernest.
SiegeController.beginSiegeCamp(camp);
else
// SiegeCamps are disabled, just do the Siege.
camp.startSiege();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import com.gmail.goosius.siegewar.TownOccupationController;
import com.gmail.goosius.siegewar.enums.SiegeType;
import com.gmail.goosius.siegewar.enums.SiegeWarPermissionNodes;
import com.gmail.goosius.siegewar.events.PreSiegeWarStartEvent;
import com.gmail.goosius.siegewar.objects.SiegeCamp;
import com.gmail.goosius.siegewar.settings.SiegeWarSettings;
import com.gmail.goosius.siegewar.settings.Translation;
import com.palmergames.bukkit.towny.TownySettings;
Expand All @@ -14,7 +14,6 @@
import com.palmergames.bukkit.towny.object.Nation;
import com.palmergames.bukkit.towny.object.Town;
import com.palmergames.bukkit.towny.object.TownBlock;
import org.bukkit.Bukkit;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;

Expand Down Expand Up @@ -73,22 +72,12 @@ public static void processStartSiegeRequest(Player player,
}
}

//Call event
PreSiegeWarStartEvent preSiegeWarStartEvent = new PreSiegeWarStartEvent(SiegeType.LIBERATION, targetTown, nationOfSiegeStarter, townOfSiegeStarter, bannerBlock, townBlock);
Bukkit.getPluginManager().callEvent(preSiegeWarStartEvent);

//Setup attack
if (!preSiegeWarStartEvent.isCancelled()) {
SiegeController.startSiege(
bannerBlock,
SiegeType.LIBERATION,
targetTown,
nationOfSiegeStarter,
occupierNation,
townOfSiegeStarter,
true);
} else {
throw new TownyException(preSiegeWarStartEvent.getCancellationMsg());
}
SiegeCamp camp = new SiegeCamp(player, bannerBlock, SiegeType.LIBERATION, targetTown, nationOfSiegeStarter, occupierNation, townOfSiegeStarter, townBlock);
if (SiegeWarSettings.areSiegeCampsEnabled())
// Launch a SiegeCamp, a (by default) 10 minute minigame. If successful the Siege will be initiated in ernest.
SiegeController.beginSiegeCamp(camp);
else
// SiegeCamps are disabled, just do the Siege.
camp.startSiege();
}
}
Loading