2019-10-27 15:45:44 +00:00
package me.rigamortis.seppuku.impl.module.combat ;
2021-10-30 01:59:20 +00:00
import com.google.common.collect.Lists ;
2021-10-30 00:17:08 +00:00
import com.google.common.collect.Maps ;
2019-10-27 15:45:44 +00:00
import me.rigamortis.seppuku.Seppuku ;
import me.rigamortis.seppuku.api.event.EventStageable ;
import me.rigamortis.seppuku.api.event.network.EventReceivePacket ;
import me.rigamortis.seppuku.api.event.player.EventUpdateWalkingPlayer ;
import me.rigamortis.seppuku.api.event.render.EventRender3D ;
2021-10-30 00:17:08 +00:00
import me.rigamortis.seppuku.api.event.world.EventAddEntity ;
2019-10-27 15:45:44 +00:00
import me.rigamortis.seppuku.api.module.Module ;
2021-01-08 06:32:44 +00:00
import me.rigamortis.seppuku.api.task.rotation.RotationTask ;
2019-10-27 15:45:44 +00:00
import me.rigamortis.seppuku.api.util.ColorUtil ;
import me.rigamortis.seppuku.api.util.MathUtil ;
import me.rigamortis.seppuku.api.util.RenderUtil ;
import me.rigamortis.seppuku.api.util.Timer ;
2019-11-30 00:54:21 +00:00
import me.rigamortis.seppuku.api.value.Value ;
2019-10-27 15:45:44 +00:00
import me.rigamortis.seppuku.impl.module.player.GodModeModule ;
import net.minecraft.block.Block ;
import net.minecraft.client.Minecraft ;
2019-11-06 23:54:45 +00:00
import net.minecraft.client.renderer.GlStateManager ;
2019-10-27 15:45:44 +00:00
import net.minecraft.enchantment.EnchantmentHelper ;
import net.minecraft.entity.Entity ;
import net.minecraft.entity.EntityLivingBase ;
import net.minecraft.entity.SharedMonsterAttributes ;
import net.minecraft.entity.item.EntityEnderCrystal ;
import net.minecraft.entity.player.EntityPlayer ;
import net.minecraft.init.Blocks ;
import net.minecraft.init.Items ;
2021-10-06 21:23:22 +00:00
import net.minecraft.init.SoundEvents ;
2019-10-27 15:45:44 +00:00
import net.minecraft.network.play.client.CPacketPlayerTryUseItemOnBlock ;
2021-10-06 21:23:22 +00:00
import net.minecraft.network.play.server.SPacketSoundEffect ;
2019-10-27 15:45:44 +00:00
import net.minecraft.network.play.server.SPacketSpawnObject ;
2021-10-06 21:23:22 +00:00
import net.minecraft.util.* ;
2019-10-27 15:45:44 +00:00
import net.minecraft.util.math.* ;
import net.minecraft.world.Explosion ;
import team.stiff.pomelo.impl.annotated.handler.annotation.Listener ;
import java.util.List ;
2021-10-30 00:17:08 +00:00
import java.util.Map ;
2019-10-27 15:45:44 +00:00
/ * *
2021-10-30 00:17:08 +00:00
* @author noil
* @author Seth ( riga )
2019-10-27 15:45:44 +00:00
* /
public final class CrystalAuraModule extends Module {
2021-10-09 01:11:38 +00:00
public final Value < Boolean > attack = new Value < Boolean > ( " Attack " , new String [ ] { " AutoAttack " } , " Automatically attack crystals " , true ) ;
public final Value < Boolean > attackRapid = new Value < Boolean > ( " AttackRapid " , new String [ ] { " RapidAttack " } , " Remove attack delay " , true ) ;
public final Value < Float > attackDelay = new Value < Float > ( " AttackDelay " , new String [ ] { " AttackDelay " , " AttackDel " , " Del " } , " The delay to attack in milliseconds " , 50 . 0f , 0 . 0f , 500 . 0f , 1 . 0f ) ;
2021-10-30 00:17:08 +00:00
public final Value < Float > attackRadius = new Value < Float > ( " AttackRadius " , new String [ ] { " ARange " , " HitRange " , " AttackDistance " , " AttackRange " , " ARadius " } , " The maximum range to attack crystals " , 4 . 0f , 0 . 0f , 7 . 0f , 0 . 1f ) ;
public final Value < Float > attackMaxDistance = new Value < Float > ( " AttackMaxDistance " , new String [ ] { " AMaxRange " , " MaxAttackRange " , " AMaxRadius " , " AMD " , " AMR " } , " Range around the enemy crystals will be attacked " , 8 . 0f , 1 . 0f , 20 . 0f , 1 . 0f ) ;
2021-10-09 01:11:38 +00:00
public final Value < Boolean > place = new Value < Boolean > ( " Place " , new String [ ] { " AutoPlace " } , " Automatically place crystals " , true ) ;
public final Value < Boolean > placeRapid = new Value < Boolean > ( " PlaceRapid " , new String [ ] { " RapidPlace " } , " Remove place delay " , true ) ;
2021-10-30 01:59:20 +00:00
public final Value < Boolean > placeSpread = new Value < Boolean > ( " PlaceSpread " , new String [ ] { " SpreadPlace " } , " Spread crystals around target by swapping place positions each time (toggle on if target is running) " , false ) ;
2021-10-09 01:11:38 +00:00
public final Value < Float > placeSpreadDistance = new Value < Float > ( " PlaceSpreadDistance " , new String [ ] { " SpreadPlaceDistance " , " SpreadDistance " } , " Distance (in blocks) to spread the crystals around the target " , 1 . 0f , 0 . 0f , 3 . 0f , 0 . 1f ) ;
2021-10-30 00:17:08 +00:00
public final Value < Float > placeDelay = new Value < Float > ( " PlaceDelay " , new String [ ] { " PlaceDelay " , " PlaceDel " } , " The delay to place crystals " , 15 . 0f , 0 . 0f , 500 . 0f , 1 . 0f ) ;
2021-10-09 01:11:38 +00:00
public final Value < Float > placeRadius = new Value < Float > ( " PlaceRadius " , new String [ ] { " Radius " , " PR " , " PlaceRange " , " Range " } , " The radius in blocks around the player to attempt placing in " , 5 . 5f , 1 . 0f , 7 . 0f , 0 . 5f ) ;
2021-10-31 01:37:36 +00:00
public final Value < Float > placeMaxDistance = new Value < Float > ( " PlaceMaxDistance " , new String [ ] { " BlockDistance " , " MaxBlockDistance " , " PMBD " , " MBD " , " PBD " , " BD " } , " Range around the enemy crystals will be placed (1.3 - 2.5 for feet place) " , 1 . 3f , 1 . 3f , 16 . 0f , 0 . 1f ) ;
2021-10-30 00:17:08 +00:00
public final Value < Float > placeLocalDistance = new Value < Float > ( " PlaceLocalDistance " , new String [ ] { " LocalDistance " , " PLD " , " LD " } , " Enemy must be within this range to start placing " , 8 . 0f , 1 . 0f , 20 . 0f , 0 . 5f ) ;
2021-10-09 01:11:38 +00:00
public final Value < Float > minDamage = new Value < Float > ( " MinDamage " , new String [ ] { " MinDamage " , " Min " , " MinDmg " } , " The minimum explosion damage calculated to place down a crystal " , 1 . 5f , 0 . 0f , 20 . 0f , 0 . 5f ) ;
2021-10-30 00:17:08 +00:00
public final Value < Boolean > offHand = new Value < Boolean > ( " Offhand " , new String [ ] { " Hand " , " otherhand " , " off " } , " Use crystals in the off-hand instead of holding them with the main-hand " , false ) ;
public final Value < Boolean > predict = new Value < Boolean > ( " Predict " , new String [ ] { " P " , " Pre " } , " Predict crystal spawns to attack faster. " , true ) ;
public final Value < Boolean > rotate = new Value < Boolean > ( " Rotate " , new String [ ] { " Rot " , " Ro " } , " Send packets to rotate the players head. " , true ) ;
public final Value < Boolean > swing = new Value < Boolean > ( " Swing " , new String [ ] { " Swi " , " S " } , " Send packets to swing the players hand. " , true ) ;
2021-10-09 01:11:38 +00:00
public final Value < Boolean > ignore = new Value < Boolean > ( " Ignore " , new String [ ] { " Ig " } , " Ignore self damage checks " , false ) ;
public final Value < Boolean > render = new Value < Boolean > ( " Render " , new String [ ] { " R " } , " Draws information about recently placed crystals from your player " , true ) ;
public final Value < Boolean > renderDamage = new Value < Boolean > ( " RenderDamage " , new String [ ] { " RD " , " RenderDamage " , " ShowDamage " } , " Draws calculated explosion damage on recently placed crystals from your player " , true ) ;
public final Value < Boolean > fixDesync = new Value < Boolean > ( " FixDesync " , new String [ ] { " Desync " , " DesyncFix " , " df " } , " Forces crystals to be dead client-side when sound effect is played " , true ) ;
public final Value < Float > fixDesyncRadius = new Value < Float > ( " FixDesyncRadius " , new String [ ] { " DesyncRadius " , " FixDesyncRange " , " DesyncRange " , " DesyncFixRadius " , " dfr " } , " The radius (in blocks) around the explosion sound effect to force crystals to be dead " , 10 . 0f , 1 . 0f , 40 . 0f , 1 . 0f ) ;
2019-10-27 15:45:44 +00:00
2020-12-06 04:59:32 +00:00
private final Timer attackTimer = new Timer ( ) ;
private final Timer placeTimer = new Timer ( ) ;
2019-10-27 15:45:44 +00:00
2021-10-30 00:17:08 +00:00
private final Map < Integer , EntityEnderCrystal > predictedCrystals = Maps . newConcurrentMap ( ) ;
2021-10-30 01:59:20 +00:00
private final List < PlaceLocation > placeLocations = Lists . newArrayList ( ) ;
2019-10-27 15:45:44 +00:00
2021-01-08 06:32:44 +00:00
private final RotationTask placeRotationTask = new RotationTask ( " CrystalAuraPlaceTask " , 6 ) ;
private final RotationTask attackRotationTask = new RotationTask ( " CrystalAuraAttackTask " , 7 ) ;
private BlockPos currentPlacePosition = null ;
2021-10-06 02:01:15 +00:00
private BlockPos lastPlacePosition = null ;
2021-10-30 00:17:08 +00:00
private Entity lastAttackEntity = null ;
2021-01-08 06:32:44 +00:00
private Entity currentAttackEntity = null ;
2021-10-09 01:08:51 +00:00
private Entity currentAttackPlayer = null ;
2021-01-08 06:32:44 +00:00
2019-10-27 15:45:44 +00:00
public CrystalAuraModule ( ) {
super ( " CrystalAura " , new String [ ] { " AutoCrystal " , " Crystal " } , " Automatically places crystals near enemies and detonates them " , " NONE " , - 1 , ModuleType . COMBAT ) ;
}
2021-01-08 06:32:44 +00:00
@Override
public void onDisable ( ) {
super . onDisable ( ) ;
Seppuku . INSTANCE . getRotationManager ( ) . finishTask ( this . placeRotationTask ) ;
Seppuku . INSTANCE . getRotationManager ( ) . finishTask ( this . attackRotationTask ) ;
2021-10-30 00:17:08 +00:00
this . currentPlacePosition = null ;
this . lastPlacePosition = null ;
2021-10-09 01:08:51 +00:00
this . currentAttackEntity = null ;
2021-10-30 00:17:08 +00:00
this . lastAttackEntity = null ;
2021-10-09 01:08:51 +00:00
this . currentAttackPlayer = null ;
2021-10-30 00:17:08 +00:00
this . predictedCrystals . clear ( ) ;
this . placeLocations . clear ( ) ;
2021-01-08 06:32:44 +00:00
}
2019-10-27 15:45:44 +00:00
@Listener
public void onWalkingUpdate ( EventUpdateWalkingPlayer event ) {
2021-01-08 06:32:44 +00:00
final Minecraft mc = Minecraft . getMinecraft ( ) ;
if ( mc . player = = null | | mc . world = = null )
return ;
switch ( event . getStage ( ) ) {
case PRE :
2021-10-31 01:57:39 +00:00
// place position reset
2021-10-31 01:58:41 +00:00
if ( mc . player . getDistance ( this . currentPlacePosition . getX ( ) , this . currentPlacePosition . getY ( ) , this . currentPlacePosition . getZ ( ) ) > this . placeRadius . getValue ( ) )
2021-10-31 01:54:33 +00:00
this . currentPlacePosition = null ;
2021-10-31 01:57:39 +00:00
// crystal reset
if ( ( mc . player . getDistance ( this . currentAttackEntity ) > this . attackRadius . getValue ( ) ) | | ! this . currentAttackEntity . isEntityAlive ( ) )
2021-10-31 01:54:33 +00:00
this . currentAttackEntity = null ;
2021-10-31 01:57:39 +00:00
// target reset
if ( ( mc . player . getDistance ( this . currentAttackPlayer ) > this . attackMaxDistance . getValue ( ) ) | | ! this . currentAttackPlayer . isEntityAlive ( ) )
this . currentAttackPlayer = null ;
2021-10-31 01:37:36 +00:00
//this.currentPlacePosition = null;
//this.currentAttackEntity = null;
2021-01-08 06:32:44 +00:00
2021-10-30 00:17:08 +00:00
if ( this . predict . getValue ( ) ) {
this . predictedCrystals . forEach ( ( i , entityEnderCrystal ) - > {
if ( ! entityEnderCrystal . isEntityAlive ( ) | | mc . player . getDistance ( entityEnderCrystal ) > this . attackRadius . getValue ( ) ) {
this . predictedCrystals . remove ( i ) ;
}
} ) ;
}
2021-01-08 06:32:44 +00:00
if ( mc . player . getHeldItem ( this . offHand . getValue ( ) ? EnumHand . OFF_HAND : EnumHand . MAIN_HAND ) . getItem ( ) = = Items . END_CRYSTAL ) {
if ( this . place . getValue ( ) ) {
2021-10-06 02:01:15 +00:00
final float radius = this . placeRadius . getValue ( ) ;
float damage = 0 ;
double maxDistanceToLocal = this . placeLocalDistance . getValue ( ) ;
EntityLivingBase targetPlayer = null ;
if ( this . placeRapid . getValue ( ) ) {
this . doPlaceLogic ( mc , radius , damage , maxDistanceToLocal , targetPlayer ) ;
} else {
if ( this . placeTimer . passed ( this . placeDelay . getValue ( ) ) ) {
this . doPlaceLogic ( mc , radius , damage , maxDistanceToLocal , targetPlayer ) ;
this . placeTimer . reset ( ) ;
2019-10-27 15:45:44 +00:00
}
2021-01-08 06:32:44 +00:00
}
2019-10-27 15:45:44 +00:00
}
2019-11-06 23:54:45 +00:00
2021-01-08 06:32:44 +00:00
if ( this . attack . getValue ( ) ) {
2021-10-30 00:17:08 +00:00
if ( this . predict . getValue ( ) ) {
this . predictedCrystals . forEach ( ( i , entityEnderCrystal ) - > {
if ( mc . player . getDistance ( entityEnderCrystal ) < = this . attackRadius . getValue ( ) ) {
for ( Entity ent : mc . world . loadedEntityList ) {
if ( ent ! = null & & ent ! = mc . player & & ( ent . getDistance ( entityEnderCrystal ) < = this . attackMaxDistance . getValue ( ) ) & & ent instanceof EntityPlayer ) {
final EntityPlayer player = ( EntityPlayer ) ent ;
float currentDamage = calculateExplosionDamage ( player , 6 . 0f , ( float ) entityEnderCrystal . posX , ( float ) entityEnderCrystal . posY , ( float ) entityEnderCrystal . posZ ) / 2 . 0f ;
float localDamage = calculateExplosionDamage ( mc . player , 6 . 0f , ( float ) entityEnderCrystal . posX , ( float ) entityEnderCrystal . posY , ( float ) entityEnderCrystal . posZ ) / 2 . 0f ;
if ( this . isLocalImmune ( ) ) {
localDamage = - 1 ;
}
if ( localDamage < = currentDamage & & currentDamage > = this . minDamage . getValue ( ) ) {
final float [ ] angle = MathUtil . calcAngle ( mc . player . getPositionEyes ( mc . getRenderPartialTicks ( ) ) , entityEnderCrystal . getPositionVector ( ) ) ;
Seppuku . INSTANCE . getRotationManager ( ) . startTask ( this . attackRotationTask ) ;
if ( this . attackRotationTask . isOnline ( ) | | this . attackRapid . getValue ( ) ) {
Seppuku . INSTANCE . getRotationManager ( ) . setPlayerRotations ( angle [ 0 ] , angle [ 1 ] ) ;
this . currentAttackEntity = entityEnderCrystal ;
}
}
}
}
}
} ) ;
}
2021-01-08 06:32:44 +00:00
for ( Entity entity : mc . world . loadedEntityList ) {
if ( entity instanceof EntityEnderCrystal ) {
2021-01-25 23:39:10 +00:00
if ( mc . player . getDistance ( entity ) < = this . attackRadius . getValue ( ) ) {
2021-01-08 06:32:44 +00:00
for ( Entity ent : mc . world . loadedEntityList ) {
2021-01-25 23:39:10 +00:00
if ( ent ! = null & & ent ! = mc . player & & ( ent . getDistance ( entity ) < = this . attackMaxDistance . getValue ( ) ) & & ent ! = entity & & ent instanceof EntityPlayer ) {
2021-01-08 06:32:44 +00:00
final EntityPlayer player = ( EntityPlayer ) ent ;
float currentDamage = calculateExplosionDamage ( player , 6 . 0f , ( float ) entity . posX , ( float ) entity . posY , ( float ) entity . posZ ) / 2 . 0f ;
float localDamage = calculateExplosionDamage ( mc . player , 6 . 0f , ( float ) entity . posX , ( float ) entity . posY , ( float ) entity . posZ ) / 2 . 0f ;
if ( this . isLocalImmune ( ) ) {
localDamage = - 1 ;
}
2019-10-27 15:45:44 +00:00
2021-01-08 06:32:44 +00:00
if ( localDamage < = currentDamage & & currentDamage > = this . minDamage . getValue ( ) ) {
final float [ ] angle = MathUtil . calcAngle ( mc . player . getPositionEyes ( mc . getRenderPartialTicks ( ) ) , entity . getPositionVector ( ) ) ;
2019-10-27 15:45:44 +00:00
2021-01-08 06:32:44 +00:00
Seppuku . INSTANCE . getRotationManager ( ) . startTask ( this . attackRotationTask ) ;
2021-10-06 21:23:22 +00:00
if ( this . attackRotationTask . isOnline ( ) | | this . attackRapid . getValue ( ) ) {
2021-10-30 00:17:08 +00:00
if ( this . rotate . getValue ( ) ) {
Seppuku . INSTANCE . getRotationManager ( ) . setPlayerRotations ( angle [ 0 ] , angle [ 1 ] ) ;
}
2021-01-08 06:32:44 +00:00
this . currentAttackEntity = entity ;
}
}
}
2019-10-27 15:45:44 +00:00
}
}
}
}
}
}
2021-01-08 06:32:44 +00:00
break ;
case POST :
if ( this . currentPlacePosition ! = null ) {
2021-10-06 21:23:22 +00:00
if ( this . placeRotationTask . isOnline ( ) | | this . placeRapid . getValue ( ) ) {
2021-01-08 06:32:44 +00:00
mc . player . connection . sendPacket ( new CPacketPlayerTryUseItemOnBlock ( this . currentPlacePosition , EnumFacing . UP , this . offHand . getValue ( ) ? EnumHand . OFF_HAND : EnumHand . MAIN_HAND , 0 , 0 , 0 ) ) ;
this . placeLocations . add ( new PlaceLocation ( this . currentPlacePosition . getX ( ) , this . currentPlacePosition . getY ( ) , this . currentPlacePosition . getZ ( ) ) ) ;
2021-10-06 02:01:15 +00:00
this . lastPlacePosition = this . currentPlacePosition ;
2021-10-31 01:37:36 +00:00
Seppuku . INSTANCE . getRotationManager ( ) . finishTask ( this . placeRotationTask ) ;
2021-01-08 06:32:44 +00:00
}
} else {
Seppuku . INSTANCE . getRotationManager ( ) . finishTask ( this . placeRotationTask ) ;
}
if ( this . currentAttackEntity ! = null ) {
2021-10-06 21:23:22 +00:00
if ( this . attackRotationTask . isOnline ( ) | | this . attackRapid . getValue ( ) ) {
2021-10-06 02:01:15 +00:00
if ( this . attackRapid . getValue ( ) ) {
2021-10-30 00:17:08 +00:00
if ( this . swing . getValue ( ) ) {
mc . player . swingArm ( this . offHand . getValue ( ) ? EnumHand . OFF_HAND : EnumHand . MAIN_HAND ) ;
}
2021-10-06 02:01:15 +00:00
mc . playerController . attackEntity ( mc . player , this . currentAttackEntity ) ;
} else {
if ( this . attackTimer . passed ( this . attackDelay . getValue ( ) ) ) {
2021-10-30 00:17:08 +00:00
if ( this . swing . getValue ( ) ) {
mc . player . swingArm ( this . offHand . getValue ( ) ? EnumHand . OFF_HAND : EnumHand . MAIN_HAND ) ;
}
2021-10-06 02:01:15 +00:00
mc . playerController . attackEntity ( mc . player , this . currentAttackEntity ) ;
this . attackTimer . reset ( ) ;
}
}
2021-01-08 06:32:44 +00:00
}
2021-10-30 00:17:08 +00:00
this . lastAttackEntity = this . currentAttackEntity ;
2021-10-31 01:37:36 +00:00
Seppuku . INSTANCE . getRotationManager ( ) . finishTask ( this . attackRotationTask ) ;
2021-01-08 06:32:44 +00:00
} else {
Seppuku . INSTANCE . getRotationManager ( ) . finishTask ( this . attackRotationTask ) ;
}
break ;
2019-10-27 15:45:44 +00:00
}
}
2021-10-30 00:17:08 +00:00
@Listener
public void onEntityAdd ( EventAddEntity eventAddEntity ) {
if ( eventAddEntity . getEntity ( ) ! = null ) {
if ( eventAddEntity . getEntity ( ) instanceof EntityEnderCrystal ) {
final EntityEnderCrystal entityEnderCrystal = ( EntityEnderCrystal ) eventAddEntity . getEntity ( ) ;
this . predictedCrystals . put ( eventAddEntity . getEntity ( ) . getEntityId ( ) , entityEnderCrystal ) ;
}
}
}
2019-10-27 15:45:44 +00:00
@Listener
public void onReceivePacket ( EventReceivePacket event ) {
if ( event . getStage ( ) = = EventStageable . EventStage . POST ) {
if ( event . getPacket ( ) instanceof SPacketSpawnObject ) {
final SPacketSpawnObject packetSpawnObject = ( SPacketSpawnObject ) event . getPacket ( ) ;
if ( packetSpawnObject . getType ( ) = = 51 ) {
2021-10-30 01:59:20 +00:00
for ( int i = this . placeLocations . size ( ) - 1 ; i > = 0 ; i - - ) {
final PlaceLocation placeLocation = this . placeLocations . get ( i ) ;
2019-10-27 15:45:44 +00:00
if ( placeLocation . getDistance ( ( int ) packetSpawnObject . getX ( ) , ( int ) packetSpawnObject . getY ( ) - 1 , ( int ) packetSpawnObject . getZ ( ) ) < = 1 ) {
placeLocation . placed = true ;
}
}
}
}
2021-10-06 21:23:22 +00:00
if ( this . fixDesync . getValue ( ) ) {
if ( event . getPacket ( ) instanceof SPacketSoundEffect ) {
final SPacketSoundEffect packetSoundEffect = ( SPacketSoundEffect ) event . getPacket ( ) ;
if ( packetSoundEffect . getCategory ( ) = = SoundCategory . BLOCKS & & packetSoundEffect . getSound ( ) = = SoundEvents . ENTITY_GENERIC_EXPLODE ) {
final Minecraft mc = Minecraft . getMinecraft ( ) ;
if ( mc . world ! = null ) {
for ( int i = mc . world . loadedEntityList . size ( ) - 1 ; i > 0 ; i - - ) {
Entity entity = mc . world . loadedEntityList . get ( i ) ;
if ( entity ! = null ) {
if ( entity . isEntityAlive ( ) & & entity instanceof EntityEnderCrystal ) {
if ( entity . getDistance ( packetSoundEffect . getX ( ) , packetSoundEffect . getY ( ) , packetSoundEffect . getZ ( ) ) < = this . fixDesyncRadius . getValue ( ) ) {
entity . setDead ( ) ;
}
}
}
}
}
}
}
}
2019-10-27 15:45:44 +00:00
}
}
@Listener
public void onRender ( EventRender3D event ) {
2019-11-30 00:54:21 +00:00
if ( ! this . render . getValue ( ) )
2019-10-27 15:45:44 +00:00
return ;
final Minecraft mc = Minecraft . getMinecraft ( ) ;
2020-12-07 04:04:36 +00:00
RenderUtil . begin3D ( ) ;
2021-10-30 01:59:20 +00:00
for ( int i = this . placeLocations . size ( ) - 1 ; i > = 0 ; i - - ) {
final PlaceLocation placeLocation = this . placeLocations . get ( i ) ;
2019-10-27 15:45:44 +00:00
if ( placeLocation . alpha < = 0 ) {
this . placeLocations . remove ( placeLocation ) ;
continue ;
}
placeLocation . update ( ) ;
if ( placeLocation . placed ) {
final AxisAlignedBB bb = new AxisAlignedBB (
placeLocation . getX ( ) - mc . getRenderManager ( ) . viewerPosX ,
placeLocation . getY ( ) - mc . getRenderManager ( ) . viewerPosY ,
placeLocation . getZ ( ) - mc . getRenderManager ( ) . viewerPosZ ,
placeLocation . getX ( ) + 1 - mc . getRenderManager ( ) . viewerPosX ,
placeLocation . getY ( ) + 1 - mc . getRenderManager ( ) . viewerPosY ,
placeLocation . getZ ( ) + 1 - mc . getRenderManager ( ) . viewerPosZ ) ;
2021-10-30 03:06:41 +00:00
float crystalAlpha = placeLocation . alpha / 2 . 0f ;
int crystalColorRounded = Math . round ( 255 . 0f - ( crystalAlpha * 255 . 0f / ( 255 . 0f / 2 ) ) ) ;
int crystalColorHex = 255 - crystalColorRounded < < 8 | crystalColorRounded < < 16 ;
RenderUtil . drawFilledBox ( bb , ColorUtil . changeAlpha ( crystalColorHex , placeLocation . alpha / 2 ) ) ;
RenderUtil . drawBoundingBox ( bb , 1 , ColorUtil . changeAlpha ( crystalColorHex , placeLocation . alpha ) ) ;
// if (this.renderDamage.getValue()) {
// GlStateManager.pushMatrix();
// RenderUtil.glBillboardDistanceScaled((float) placeLocation.getX() + 0.5f, (float) placeLocation.getY() + 0.5f, (float) placeLocation.getZ() + 0.5f, mc.player, 1);
// final float damage = placeLocation.damage;
// if (damage != -1) {
// final String damageText = (Math.floor(damage) == damage ? (int) damage : String.format("%.1f", damage)) + "";
// //GlStateManager.disableDepth();
// GlStateManager.translate(-(mc.fontRenderer.getStringWidth(damageText) / 2.0d), 0, 0);
// mc.fontRenderer.drawStringWithShadow(damageText, 0, 0, 0xFFAAAAAA);
// }
// GlStateManager.popMatrix();
// }
2019-10-27 15:45:44 +00:00
}
}
2020-12-07 04:04:36 +00:00
RenderUtil . end3D ( ) ;
2019-10-27 15:45:44 +00:00
}
2021-10-06 02:01:15 +00:00
private void doPlaceLogic ( final Minecraft mc , final float radius , float damage , double maxDistanceToLocal , EntityLivingBase targetPlayer ) {
for ( float x = radius ; x > = - radius ; x - - ) {
for ( float y = radius ; y > = - radius ; y - - ) {
for ( float z = radius ; z > = - radius ; z - - ) {
final BlockPos blockPos = new BlockPos ( mc . player . posX + x , mc . player . posY + y , mc . player . posZ + z ) ;
2021-10-06 21:23:22 +00:00
if ( this . canPlaceCrystal ( blockPos ) ) {
2021-10-06 02:01:15 +00:00
for ( Entity entity : mc . world . loadedEntityList ) {
if ( entity instanceof EntityPlayer ) {
final EntityPlayer player = ( EntityPlayer ) entity ;
if ( player ! = mc . player & & ! player . getName ( ) . equals ( mc . player . getName ( ) ) & & player . getHealth ( ) > 0 & & Seppuku . INSTANCE . getFriendManager ( ) . isFriend ( player ) = = null ) {
2021-10-30 03:06:41 +00:00
final double distToBlock = entity . getDistance ( blockPos . getX ( ) , blockPos . getY ( ) , blockPos . getZ ( ) ) ;
2021-10-06 02:01:15 +00:00
final double distToLocal = entity . getDistance ( mc . player . posX , mc . player . posY , mc . player . posZ ) ;
2021-10-30 03:06:41 +00:00
if ( distToBlock < this . placeMaxDistance . getValue ( ) & & distToLocal < = maxDistanceToLocal ) {
2021-10-06 02:01:15 +00:00
targetPlayer = player ;
maxDistanceToLocal = distToLocal ;
}
}
}
}
if ( targetPlayer ! = null ) {
2021-10-09 01:08:51 +00:00
this . currentAttackPlayer = targetPlayer ;
2021-10-30 03:06:41 +00:00
if ( this . currentAttackPlayer . getDistance ( blockPos . getX ( ) , blockPos . getY ( ) , blockPos . getZ ( ) ) > this . placeMaxDistance . getValue ( ) )
continue ;
2021-10-06 02:01:15 +00:00
final float currentDamage = calculateExplosionDamage ( targetPlayer , 6 . 0f , blockPos . getX ( ) + 0 . 5f , blockPos . getY ( ) + 1 . 0f , blockPos . getZ ( ) + 0 . 5f ) / 2 . 0f ;
float localDamage = calculateExplosionDamage ( mc . player , 6 . 0f , blockPos . getX ( ) + 0 . 5f , blockPos . getY ( ) + 1 . 0f , blockPos . getZ ( ) + 0 . 5f ) / 2 . 0f ;
if ( this . isLocalImmune ( ) ) {
localDamage = - 1 ;
}
if ( currentDamage > damage & & currentDamage > = this . minDamage . getValue ( ) & & localDamage < = currentDamage ) {
damage = currentDamage ;
this . currentPlacePosition = blockPos ;
}
}
}
}
}
}
if ( this . currentPlacePosition ! = null & & damage > 0 ) {
final float [ ] angle = MathUtil . calcAngle ( mc . player . getPositionEyes ( mc . getRenderPartialTicks ( ) ) , new Vec3d ( this . currentPlacePosition . getX ( ) + 0 . 5f , this . currentPlacePosition . getY ( ) + 0 . 5f , this . currentPlacePosition . getZ ( ) + 0 . 5f ) ) ;
Seppuku . INSTANCE . getRotationManager ( ) . startTask ( this . placeRotationTask ) ;
2021-10-06 21:23:22 +00:00
if ( this . placeRotationTask . isOnline ( ) | | this . placeRapid . getValue ( ) ) {
2021-10-06 02:01:15 +00:00
Seppuku . INSTANCE . getRotationManager ( ) . setPlayerRotations ( angle [ 0 ] , angle [ 1 ] ) ;
}
}
}
2020-12-06 04:59:32 +00:00
private boolean isLocalImmune ( ) {
2019-10-27 15:45:44 +00:00
final Minecraft mc = Minecraft . getMinecraft ( ) ;
2021-10-06 21:25:20 +00:00
if ( mc . player . capabilities . isCreativeMode ) {
2020-12-06 04:59:32 +00:00
return true ;
2021-10-06 21:25:20 +00:00
}
2019-10-27 15:45:44 +00:00
final GodModeModule mod = ( GodModeModule ) Seppuku . INSTANCE . getModuleManager ( ) . find ( GodModeModule . class ) ;
2021-10-06 21:25:20 +00:00
if ( mod ! = null & & mod . isEnabled ( ) ) {
2020-12-06 04:59:32 +00:00
return true ;
2021-10-06 21:25:20 +00:00
}
if ( this . ignore . getValue ( ) ) {
return true ;
}
2019-10-27 15:45:44 +00:00
2021-10-06 21:25:20 +00:00
return false ;
2019-10-27 15:45:44 +00:00
}
private boolean canPlaceCrystal ( BlockPos pos ) {
final Minecraft mc = Minecraft . getMinecraft ( ) ;
final Block block = mc . world . getBlockState ( pos ) . getBlock ( ) ;
2021-10-06 02:01:15 +00:00
if ( this . placeSpread . getValue ( ) ) {
if ( this . lastPlacePosition ! = null )
if ( pos . getDistance ( this . lastPlacePosition . getX ( ) , this . lastPlacePosition . getY ( ) , this . lastPlacePosition . getZ ( ) ) < = this . placeSpreadDistance . getValue ( ) )
return false ;
}
2019-10-27 15:45:44 +00:00
if ( block = = Blocks . OBSIDIAN | | block = = Blocks . BEDROCK ) {
final Block floor = mc . world . getBlockState ( pos . add ( 0 , 1 , 0 ) ) . getBlock ( ) ;
final Block ceil = mc . world . getBlockState ( pos . add ( 0 , 2 , 0 ) ) . getBlock ( ) ;
if ( floor = = Blocks . AIR & & ceil = = Blocks . AIR ) {
if ( mc . world . getEntitiesWithinAABBExcludingEntity ( null , new AxisAlignedBB ( pos . add ( 0 , 1 , 0 ) ) ) . isEmpty ( ) ) {
2021-01-25 23:39:10 +00:00
return mc . player . getDistance ( pos . getX ( ) , pos . getY ( ) , pos . getZ ( ) ) < = this . placeRadius . getValue ( ) ;
2019-10-27 15:45:44 +00:00
}
}
}
return false ;
}
private float calculateExplosionDamage ( EntityLivingBase entity , float size , float x , float y , float z ) {
final Minecraft mc = Minecraft . getMinecraft ( ) ;
final float scale = size * 2 . 0F ;
final Vec3d pos = MathUtil . interpolateEntity ( entity , mc . getRenderPartialTicks ( ) ) ;
final double dist = MathUtil . getDistance ( pos , x , y , z ) / ( double ) scale ;
//final double dist = entity.getDistance(x, y, z) / (double) scale;
final Vec3d vec3d = new Vec3d ( x , y , z ) ;
2021-10-06 21:23:22 +00:00
final double density = entity . world . getBlockDensity ( vec3d , entity . getEntityBoundingBox ( ) ) ;
2019-10-27 15:45:44 +00:00
final double densityScale = ( 1 . 0D - dist ) * density ;
float unscaledDamage = ( float ) ( ( int ) ( ( densityScale * densityScale + densityScale ) / 2 . 0d * 7 . 0d * ( double ) scale + 1 . 0d ) ) ;
2019-11-04 21:51:45 +00:00
unscaledDamage * = 0 . 5f * mc . world . getDifficulty ( ) . getId ( ) ;
2019-10-27 15:45:44 +00:00
2021-10-31 01:37:36 +00:00
return scaleExplosionDamage ( entity , new Explosion ( mc . world , entity , x , y , z , size , false , true ) , unscaledDamage ) ;
2019-10-27 15:45:44 +00:00
}
private float scaleExplosionDamage ( EntityLivingBase entity , Explosion explosion , float damage ) {
damage = CombatRules . getDamageAfterAbsorb ( damage , ( float ) entity . getTotalArmorValue ( ) , ( float ) entity . getEntityAttribute ( SharedMonsterAttributes . ARMOR_TOUGHNESS ) . getAttributeValue ( ) ) ;
damage * = ( 1 . 0F - MathHelper . clamp ( EnchantmentHelper . getEnchantmentModifierDamage ( entity . getArmorInventoryList ( ) , DamageSource . causeExplosionDamage ( explosion ) ) , 0 . 0F , 20 . 0F ) / 25 . 0F ) ;
return damage ;
}
2020-12-06 04:59:32 +00:00
private static final class PlaceLocation extends Vec3i {
2019-10-27 15:45:44 +00:00
private int alpha = 0xAA ;
private boolean placed = false ;
2021-01-08 06:32:44 +00:00
private float damage = - 1 ;
2019-10-27 15:45:44 +00:00
2019-11-06 23:54:45 +00:00
private PlaceLocation ( int xIn , int yIn , int zIn , float damage ) {
2019-10-27 15:45:44 +00:00
super ( xIn , yIn , zIn ) ;
2019-11-06 23:54:45 +00:00
this . damage = damage ;
2019-10-27 15:45:44 +00:00
}
2021-01-08 06:32:44 +00:00
private PlaceLocation ( int xIn , int yIn , int zIn ) {
super ( xIn , yIn , zIn ) ;
}
2019-10-27 15:45:44 +00:00
private void update ( ) {
if ( this . alpha > 0 )
2021-10-30 03:06:41 +00:00
this . alpha - = 2 ;
2019-10-27 15:45:44 +00:00
}
}
2021-10-09 01:08:51 +00:00
public Timer getAttackTimer ( ) {
return attackTimer ;
}
public Timer getPlaceTimer ( ) {
return placeTimer ;
}
public List < PlaceLocation > getPlaceLocations ( ) {
return placeLocations ;
}
public RotationTask getPlaceRotationTask ( ) {
return placeRotationTask ;
}
public RotationTask getAttackRotationTask ( ) {
return attackRotationTask ;
}
public BlockPos getCurrentPlacePosition ( ) {
return currentPlacePosition ;
}
public void setCurrentPlacePosition ( BlockPos currentPlacePosition ) {
this . currentPlacePosition = currentPlacePosition ;
}
public BlockPos getLastPlacePosition ( ) {
return lastPlacePosition ;
}
public void setLastPlacePosition ( BlockPos lastPlacePosition ) {
this . lastPlacePosition = lastPlacePosition ;
}
public Entity getCurrentAttackEntity ( ) {
return currentAttackEntity ;
}
public Entity getCurrentAttackPlayer ( ) {
return currentAttackPlayer ;
}
public void setCurrentAttackEntity ( Entity currentAttackEntity ) {
this . currentAttackEntity = currentAttackEntity ;
}
2019-10-27 15:45:44 +00:00
}