-
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor 20250113 - Class Refactorization
Another refactorization commit to properly structure the classes of projectiles. Also, parabolic trajectory is currently being experimented on for potential future implementation of such turrets like mortars. [CHANGELOG] 🟢 Added the Explosive Projectile interface. This interface will handle all explosive projectiles similar to how Explosive Projectile Entity class is. This interface will soon replace the said superclass in Cannonball entity class. 🟢 Added Kinetic Projectile base class for all kinetic-base projectiles such as the Ballista Arrow and even (WIP) Cannonball. 🟢 Added several new properties for Turret Projectile, allowing its subclasses to let their damage be affected by their speed. 🟢 Added new damage and pierce level static constants to the Ballista Turret entity class. 🟢 Added new damage static constants to the Cannon Turret entity class. 🟢 Implemented the two new additional abstract methods from Turret Entity base class to all its subclasses. 🟢 Added a default (base) level to Turret Entity base class's level property. 🟢 Added a new method that returns the current barrel the turret is using. 🟢 Added safety clamps to some data to prevent any error from happening. 🟢 Added an overridable method "getMaxLevel" which dictates the maximum level a turret can be. 🟢 Refactored the Turret Projectile Velocity class to allow recalculation of velocity when some attributes are changed. 🟢 Began experimentation for the implementation of parabolic projectiles. If successful, implementations of turrets like mortars may proceed. 🟡 Updated Ballista Arrow and Cannonball entity's superclass to Kinetic Projectile, allowing it to remove some redundant codes. 🟡 Moved some repeating logics and codes from the projectile entities towards the Turret Projectile entity base class. 🟡 Updated Cannon Turret's max attack and follow range from 16 to 24. 🟡 Updated the public method "getMaxAttackRange" which previously limits the range of the turrets to 16.625. It now uses the subclass's "FOLLOW_RANGE" attribute as its maximum attack range + its eye height. 🟡 Updated the Turret Projectile Velocity class to normalize its values and allow developers to easily comprehend some values such as power and upward velocity multiplier.
- Loading branch information
Showing
11 changed files
with
489 additions
and
135 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
145 changes: 145 additions & 0 deletions
145
...ain/java/com/virus5600/defensive_measures/entity/projectiles/KineticProjectileEntity.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
package com.virus5600.defensive_measures.entity.projectiles; | ||
|
||
import net.minecraft.entity.Entity; | ||
import net.minecraft.entity.LivingEntity; | ||
import net.minecraft.entity.data.DataTracker.Builder; | ||
import net.minecraft.entity.EntityType; | ||
import net.minecraft.util.hit.EntityHitResult; | ||
import net.minecraft.world.World; | ||
|
||
public abstract class KineticProjectileEntity extends TurretProjectileEntity { | ||
|
||
// ///////////// // | ||
// CONSTRUCTORS // | ||
// ///////////// // | ||
public KineticProjectileEntity(EntityType<? extends TurretProjectileEntity> entityType, World world) { | ||
super(entityType, world); | ||
this.setDamage(4); | ||
this.setPierceLevel(this.getMaxPierceLevel()); | ||
this.setSpeedAffectsDamage(false); | ||
} | ||
|
||
// /////////////// // | ||
// PROCESS METHODS // | ||
// /////////////// // | ||
// PROTECTED | ||
@Override | ||
protected void initDataTracker(Builder builder) { | ||
super.initDataTracker(builder); | ||
} | ||
|
||
/** | ||
* {@inheritDoc} | ||
* <hr> | ||
* <h2>{@link KineticProjectileEntity}</h2> | ||
* <br><br> | ||
* The method in {@code KineticProjectileEntity} reduces the speed of the arrow | ||
* along with the pierce level based on the amount of armor points the entity has. | ||
* <br><br> | ||
* In this implementation, the projectile will have the following behavior | ||
* (assuming the projectile is affected by armor points): | ||
* <table> | ||
* <tr> | ||
* <th>Armor Points</th> | ||
* <th>Pierce Level Reduction</th> | ||
* <th>Velocity Reduction</th> | ||
* <th>Base Damage Reduction</th> | ||
* </tr> | ||
* <tr> | ||
* <td>Heavy Armor</td> | ||
* <td>2</td> | ||
* <td>50%</td> | ||
* <td>50%</td> | ||
* </tr> | ||
* <tr> | ||
* <td>Light Armor</td> | ||
* <td>1</td> | ||
* <td>25%</td> | ||
* <td>20%</td> | ||
* </tr> | ||
* <tr> | ||
* <td>No Armor</td> | ||
* <td>N/A</td> | ||
* <td>12.5%</td> | ||
* <td>5%</td> | ||
* </tr> | ||
* </table> | ||
* | ||
* @param entityHitResult {@inheritDoc EntityHitResult} | ||
*/ | ||
@Override | ||
protected void onEntityHit(EntityHitResult entityHitResult) { | ||
super.onEntityHit(entityHitResult); | ||
|
||
if (this.armorAffectsPiercing()) { | ||
// Reduces the speed of the arrow when it hits an entity | ||
Entity entity = entityHitResult.getEntity(); | ||
// For reference, max armor points is 30 | ||
int armor = entity instanceof LivingEntity livingEntity ? livingEntity.getArmor() : 0; | ||
double dmgReduction = 0.05; | ||
boolean hasHeavyArmor = armor > 15, | ||
hasLightArmor = armor <= 15 && armor > 0; | ||
|
||
if (entity instanceof LivingEntity livingEntity) { | ||
double targetH = livingEntity.getHeight(), | ||
arrowH = this.getHeight(), | ||
variance = arrowH * 0.125; // 12.5% of the arrow's height | ||
|
||
double arrowMin = arrowH - variance, | ||
arrowMax = arrowH + variance, | ||
reducedVelocity = 0.125; | ||
|
||
// Reduce velocity and pierce level based on the side of the entity hit | ||
if (this.getPierceLevel() > 0) { | ||
// If the arrow is smaller than the target or has heavy armor, reduce the pierce level by 2, velocity by 50%, and base damage by 50% | ||
if (targetH > arrowMax || hasHeavyArmor) { | ||
this.setPierceLevel((byte) (this.getPierceLevel() - 2)); | ||
reducedVelocity = 0.5; | ||
dmgReduction = 0.5; | ||
} | ||
// If the arrow is almost the same size as the target or has a light armor, reduce the pierce level by 1, velocity by 25%, and base damage by 20% | ||
else if ((targetH < arrowMax && arrowMin < targetH) || hasLightArmor) { | ||
this.setPierceLevel((byte) (this.getPierceLevel() - 1)); | ||
reducedVelocity = 0.25; | ||
dmgReduction = 0.2; | ||
} | ||
// Otherwise, just reduce the velocity by 12.5% and base damage by 5% without reducing the pierce level | ||
} | ||
|
||
// Apply reduced velocity | ||
this.addVelocity( | ||
this.getVelocity() | ||
.multiply(reducedVelocity) | ||
.negate() | ||
); | ||
|
||
// Apply reduced damage | ||
this.setDamage(this.getDamage() * (1 - dmgReduction)); | ||
} | ||
|
||
this.addVelocity( | ||
this.getVelocity() | ||
.negate() | ||
.multiply(0.1) | ||
); | ||
} | ||
} | ||
|
||
// /////////////////////////////// // | ||
// GETTERS, SETTERS, AND QUESTIONS // | ||
// /////////////////////////////// // | ||
|
||
// PUBLIC | ||
/** | ||
* An overridable method that determines whether an armor point affects the | ||
* piercing of the projectile. | ||
* <br><br> | ||
* By default, this method returns {@code true}. | ||
* | ||
* @return {@code true} if the armor point affects the piercing of the projectile, | ||
* {@code false} otherwise. | ||
*/ | ||
public boolean armorAffectsPiercing() { | ||
return true; | ||
} | ||
} |
Oops, something went wrong.