Skip to content

Commit

Permalink
lotsa changes - see todo
Browse files Browse the repository at this point in the history
  • Loading branch information
SoLegendary committed Oct 16, 2024
1 parent ec988c8 commit fdc25c4
Show file tree
Hide file tree
Showing 17 changed files with 111 additions and 37 deletions.
45 changes: 29 additions & 16 deletions TODO
Original file line number Diff line number Diff line change
@@ -1,30 +1,45 @@

1.19.2-1.0.2 - New singleplayer map
-----------------------------------
Map where player starts in the centre, surrounded by 3 static enemy bases (though no AI of course)
- Create lots of defenses and a good variety of buildings to make up for no AI

1.19.2-1.0.2
------------

Bugfixes
--------
[✔] castle upgrade issues
[✔] pillager mounting ravager upgrade missing
[✔] Fixed the castle's building upgrade not working
[✔] Fixed the pillager mounting ravager upgrade being missing
[✔] [#31] Workers returning a resource should count towards assigned number
[✔] [#32] Zombie villagers trample pumpkins (needs server test)
[✔] [#32] Farm crops can no longer be trampled
[✔] Reduced occurrence of sonic booms randomly not working (please tell me if this still happens)
Removed a duplicate line in the clock tooltip
[❌] [#29] Resources go negative after a match is done
- make sure we're removing players' resources on each end condition, including:
- defeat()
- resetRTS()

Quality of Life Features
------------------------
[❌] Pressing same control group key again will now cycle between the selected unit type
[❌] Radius indicator around monster capitol and stronghold to better indicate range of night
(can use this same code for ability range indicators too)
[❌] More shift click queue commands
- Build already-placed foundations
- Repair damaged buildings
- Move units

Balancing
---------
[Needs testing] Lower ghast range to be within tower range
[Needs testing] Raise ghast health so they can reasonably take down a garrisoned tower before dying

Reduce tower garrison limit to 3
Raise capitol-animal spawn rate to 90s
Raise wood cost of farms
Lowered ghast range from 40 to 30
Garrisoned ranged units get an additional +10 bonus range against ghasts
Raised ghast health from 30 to 60 so that groups can still reasonably take down garrisons
Lowered ghast movespeed from 25 to 22
Raised iron golem movespeed from 20 to 22
Warden sonic boom damage increased from 60 to 75. It can now 1-shot all units except iron golems, ravagers and other wardens.
Warden sonic booms now get +10 range after the target is acquired, so enemies can't run away as easily.
Reduced watchtower garrison limit from 5 to 3 and bastions from 5 to 4
Reduced all castle-type building garrison limits from 10 to 7
Reduced all repair speeds by 25%
Raised watchtower build times by 25%
Raise capitols' animal spawn interval from 60s to 90s
Raise wood cost of all farms by 50



Expand All @@ -39,8 +54,6 @@ Backlog misc improvements

Let workers gather beehives

Do a 4+ player FFA for stress testing



Limitations of save data
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ public abstract class Building {
protected float explodeRadius = 2.0f;
protected float fireThreshold = 0.75f; // if building has less %hp than this, explosions caused can make fires
protected float buildTimeModifier = 1.0f; // only affects non-built buildings, not repair times
protected float repairTimeModifier = 1.25f; // only affects built buildings
protected int highestBlockCountReached = 2; // effective max health of the building

protected ArrayList<BuildingBlock> scaffoldBlocks = new ArrayList<>();
Expand Down Expand Up @@ -603,6 +604,8 @@ public void tick(Level tickLevel) {
int msPerBuild = (2 * BASE_MS_PER_BUILD) / (builderCount + 1);
if (!isBuilt)
msPerBuild *= buildTimeModifier;
else
msPerBuild *= repairTimeModifier;

if (msToNextBuild > msPerBuild)
msToNextBuild = msPerBuild;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public DarkWatchtower(Level level, BlockPos originPos, Rotation rotation, String
this.woodCost = cost.wood;
this.oreCost = cost.ore;
this.popSupply = cost.population;
this.buildTimeModifier = 0.8f;
this.buildTimeModifier = 1.0f;

this.startingBlockTypes.add(Blocks.DEEPSLATE_BRICKS);
this.startingBlockTypes.add(Blocks.DEEPSLATE_BRICK_SLAB);
Expand All @@ -50,7 +50,7 @@ public DarkWatchtower(Level level, BlockPos originPos, Rotation rotation, String
public Faction getFaction() {return Faction.MONSTERS;}

// don't use this for abilities as it may not be balanced
public int getAttackRange() { return 25; }
public int getAttackRange() { return 24; }
// bonus for units attacking garrisoned units
public int getExternalAttackRangeBonus() { return 10; }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public class Stronghold extends ProductionBuilding implements GarrisonableBuildi
public final static ResourceCost cost = ResourceCosts.STRONGHOLD;
public final static int nightRange = 60;

private final static int MAX_OCCUPANTS = 10;
private final static int MAX_OCCUPANTS = 7;

public Stronghold(Level level, BlockPos originPos, Rotation rotation, String ownerName) {
super(level, originPos, rotation, ownerName, getAbsoluteBlockData(getRelativeBlockData(level), level, originPos, rotation), false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public class Bastion extends ProductionBuilding implements GarrisonableBuilding
public final static String structureName = "bastion";
public final static ResourceCost cost = ResourceCosts.BASTION;

private final static int MAX_OCCUPANTS = 3;
private final static int MAX_OCCUPANTS = 4;

public Bastion(Level level, BlockPos originPos, Rotation rotation, String ownerName) {
super(level, originPos, rotation, ownerName, getAbsoluteBlockData(getRelativeBlockData(level), level, originPos, rotation), false);
Expand Down Expand Up @@ -64,7 +64,7 @@ public Bastion(Level level, BlockPos originPos, Rotation rotation, String ownerN
public Faction getFaction() {return Faction.PIGLINS;}

// don't use this for abilities as it may not be balanced
public int getAttackRange() { return 25; }
public int getAttackRange() { return 24; }
// bonus for units attacking garrisoned units
public int getExternalAttackRangeBonus() { return 10; }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public class Fortress extends ProductionBuilding implements GarrisonableBuilding
public final static String structureName = "fortress";
public final static ResourceCost cost = ResourceCosts.FORTRESS;

private final static int MAX_OCCUPANTS = 10;
private final static int MAX_OCCUPANTS = 7;

public Fortress(Level level, BlockPos originPos, Rotation rotation, String ownerName) {
super(level, originPos, rotation, ownerName, getAbsoluteBlockData(getRelativeBlockData(level), level, originPos, rotation), false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public class Castle extends ProductionBuilding implements GarrisonableBuilding {
public final static String upgradedStructureName = "castle_with_flag";
public final static ResourceCost cost = ResourceCosts.CASTLE;

private final static int MAX_OCCUPANTS = 10;
private final static int MAX_OCCUPANTS = 7;

public Castle(Level level, BlockPos originPos, Rotation rotation, String ownerName) {
super(level, originPos, rotation, ownerName, getAbsoluteBlockData(getRelativeBlockData(level), level, originPos, rotation), false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public Watchtower(Level level, BlockPos originPos, Rotation rotation, String own
this.woodCost = cost.wood;
this.oreCost = cost.ore;
this.popSupply = cost.population;
this.buildTimeModifier = 0.8f;
this.buildTimeModifier = 1.0f;

this.startingBlockTypes.add(Blocks.STONE_BRICKS);
this.startingBlockTypes.add(Blocks.STONE_BRICK_SLAB);
Expand All @@ -50,7 +50,7 @@ public Watchtower(Level level, BlockPos originPos, Rotation rotation, String own
public Faction getFaction() {return Faction.VILLAGERS;}

// don't use this for abilities as it may not be balanced
public int getAttackRange() { return 25; }
public int getAttackRange() { return 24; }
// bonus for units attacking garrisoned units
public int getExternalAttackRangeBonus() { return 10; }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import net.minecraft.world.entity.player.Player;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

import static com.solegendary.reignofnether.building.BuildingClientEvents.getPlayerToBuildingRelationship;
Expand Down Expand Up @@ -45,12 +46,14 @@ public class ControlGroup {
public ControlGroup() { }

public int getKey() {
return this.keybinding.key;
return keybinding != null ? keybinding.key : -1;
}

public void clearAll() {
this.entityIds.clear();
this.buildingBps.clear();
if (HudClientEvents.lastSelCtrlGroupKey == this.getKey())
HudClientEvents.lastSelCtrlGroupKey = -1;
}

public boolean isEmpty() {
Expand Down Expand Up @@ -99,6 +102,7 @@ else if (selBuildings.size() > 0 && getPlayerToBuildingRelationship(selBuildings
}

// selects the control group's assigned entities/buildings
// if it's already selected then just cycle the hudSelectedEntity
public void loadToSelected() {
Minecraft MC = Minecraft.getInstance();
Player player = MC.player;
Expand All @@ -120,6 +124,28 @@ public void loadToSelected() {
OrthoviewClientEvents.centreCameraOnPos(entities.get(0).getX(), entities.get(0).getZ());
}
}
// press again to cycle between selected unit type in the group
if (HudClientEvents.lastSelCtrlGroupKey == this.getKey()) {
List<LivingEntity> entities = getAllUnits().stream()
.filter(e -> entityIds.contains(e.getId()) && e instanceof Unit)
.sorted(Comparator.comparing(HudClientEvents::getSimpleEntityName))
.toList();

String hudSelectedEntityName = HudClientEvents.getSimpleEntityName(hudSelectedEntity);
String lastEntityName = "";
boolean cycled = false;
for (LivingEntity entity : entities) {
String currentEntityName = HudClientEvents.getSimpleEntityName(entity);
if (lastEntityName.equals(hudSelectedEntityName) && !currentEntityName.equals(lastEntityName)) {
hudSelectedEntity = entity;
cycled = true;
break;
}
lastEntityName = currentEntityName;
}
if (!cycled)
hudSelectedEntity = entities.get(0);
}
}
else if (buildingBps.size() > 0) {
UnitClientEvents.clearSelectedUnits();
Expand All @@ -137,7 +163,9 @@ else if (buildingBps.size() > 0) {
OrthoviewClientEvents.centreCameraOnPos(building.centrePos.getX(), building.centrePos.getZ());
}
}

lastClickTime = System.currentTimeMillis();
HudClientEvents.lastSelCtrlGroupKey = this.getKey();
}

public Button getButton() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ public class HudClientEvents {
private static final int MAX_BUTTONS_PER_ROW = 6;

public static final ArrayList<ControlGroup> controlGroups = new ArrayList<>(10);
public static int lastSelCtrlGroupKey = -1;

private static final ArrayList<Button> buildingButtons = new ArrayList<>();
private static final ArrayList<Button> unitButtons = new ArrayList<>();
private static final ArrayList<Button> productionButtons = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,6 @@ public static void onDrawScreen(ScreenEvent.Render evt) {
FormattedCharSequence.forward("Time is distorted to midnight", Style.EMPTY.withBold(true)),
FormattedCharSequence.forward("Real time: " + timeStr, Style.EMPTY),
timeUntilStr,
FormattedCharSequence.forward("" + timeStr, Style.EMPTY),
gameLengthStr
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@

public abstract class AbstractCastTargetedSpellGoal extends MoveToTargetBlockGoal {

private LivingEntity targetEntity = null;
private Ability ability; // used for syncing cooldown with clientside
protected LivingEntity targetEntity = null;
protected Ability ability; // used for syncing cooldown with clientside
protected int ticksCasting = 0; // how long have we spent trying to cast this spell
public boolean isCasting() { return isCasting; }
protected final int channelTicks; // max time required to cast a spell
protected boolean isCasting = false;
private BlockPos castTarget = null; // pos that the spell will be cast at
private final int range;
protected BlockPos castTarget = null; // pos that the spell will be cast at
protected final int range;
public Consumer<LivingEntity> onEntityCast;
public Consumer<BlockPos> onGroundCast;
public Consumer<Building> onBuildingCast;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.solegendary.reignofnether.building.Building;
import com.solegendary.reignofnether.unit.interfaces.Unit;
import com.solegendary.reignofnether.unit.packets.UnitSyncClientboundPacket;
import com.solegendary.reignofnether.util.MyMath;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.Mob;

Expand Down Expand Up @@ -30,11 +31,28 @@ public void stopCasting() {
((Unit) this.mob).getCheckpoints().clear();
}

@Override
protected boolean isInRange() {
int finalRange = range;
if (isCasting())
finalRange += 10;

if (moveTarget != null && MyMath.distance(
this.mob.getX(), this.mob.getZ(),
moveTarget.getX(), moveTarget.getZ()) <= finalRange)
return true;
if (castTarget != null && MyMath.distance(
this.mob.getX(), this.mob.getZ(),
castTarget.getX(), castTarget.getZ()) <= finalRange)
return true;
return false;
}

@Override
public void stop() {
// hack fix to stop a weird bug where it gets stopped unexpectedly (serverside)
// happens when needing to move towards the target first
if (this.ticksCasting <= 3 && isInRange())
if (this.ticksCasting <= 5 && isInRange())
return;
super.stop();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ public class UnitBowAttackGoal<T extends net.minecraft.world.entity.Mob> extends
private int attackTime = -1;
private int seeTime; // how long we have seen the target for

private static final int GARRISON_BONUS_RANGE_TO_GHASTS = 10;

public UnitBowAttackGoal(T mob, int attackCooldown) {
this.mob = mob;
this.attackCooldownMax = attackCooldown;
Expand Down Expand Up @@ -123,8 +125,11 @@ public void tick() {
float attackRange = ((AttackerUnit) this.mob).getAttackRange();

if (!(this.mob instanceof GhastUnit)) {
if (isGarrisoned)
if (isGarrisoned) {
attackRange = garr.getAttackRange();
if (target instanceof GhastUnit ghastUnit)
attackRange += GARRISON_BONUS_RANGE_TO_GHASTS;
}
else if (isTargetGarrisoned)
attackRange += targetGarr.getExternalAttackRangeBonus();
else if (target instanceof GhastUnit ghastUnit)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ public class UnitCrossbowAttackGoal<T extends Monster & RangedAttackMob & Crossb
private int attackCooldown;
private int attackCooldownMax;

private static final int GARRISON_BONUS_RANGE_TO_GHASTS = 10;

public UnitCrossbowAttackGoal(T mob, int attackCooldown) {
this.mob = mob;
this.attackCooldownMax = attackCooldown;
Expand Down Expand Up @@ -139,8 +141,11 @@ public void tick() {
this.mob.getNavigation().stop();
}
}
if (isGarrisoned)
if (isGarrisoned) {
attackRange = garr.getAttackRange();
if (target instanceof GhastUnit ghastUnit)
attackRange += GARRISON_BONUS_RANGE_TO_GHASTS;
}
else if (isTargetGarrisoned)
attackRange += targetGarr.getExternalAttackRangeBonus();
else if (target instanceof GhastUnit ghastUnit)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.solegendary.reignofnether.ability.Ability;
import com.solegendary.reignofnether.ability.abilities.AttackGround;
import com.solegendary.reignofnether.building.GarrisonableBuilding;
import com.solegendary.reignofnether.fogofwar.FogOfWarClientboundPacket;
import com.solegendary.reignofnether.hud.AbilityButton;
import com.solegendary.reignofnether.keybinds.Keybindings;
Expand Down Expand Up @@ -134,9 +135,9 @@ protected void defineSynchedData() {
final static public boolean willRetaliate = true; // will attack when hurt by an enemy
final static public boolean aggressiveWhenIdle = true;

final static public float maxHealth = 50.0f;
final static public float maxHealth = 60.0f;
final static public float armorValue = 0.0f;
final static public float movementSpeed = 0.25f;
final static public float movementSpeed = 0.22f;
final static public int popCost = ResourceCosts.GHAST.population;
public int maxResources = 100;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ protected void defineSynchedData() {
final static public float attacksPerSecond = 0.4f;
final static public float maxHealth = 150.0f;
final static public float armorValue = 0.0f;
final static public float movementSpeed = 0.20f;
final static public float movementSpeed = 0.22f;
final static public float attackRange = 3; // only used by ranged units or melee building attackers
final static public float aggroRange = 10;
final static public boolean willRetaliate = true; // will attack when hurt by an enemy
Expand Down

0 comments on commit fdc25c4

Please sign in to comment.