1+ package com .mewo .hbmenhanced .entity .projectile ;
2+
3+ import net .minecraft .entity .Entity ;
4+ import net .minecraft .entity .EntityLivingBase ;
5+ import net .minecraft .entity .player .EntityPlayer ;
6+ import net .minecraft .nbt .NBTTagCompound ;
7+ import net .minecraft .util .MovingObjectPosition ;
8+ import net .minecraft .util .Vec3 ;
9+ import net .minecraft .world .World ;
10+
11+ public class EntityStalinBeam extends Entity {
12+
13+ private EntityLivingBase shooter ;
14+ private int beamLifetime = 20 ; // 1 second beam duration
15+
16+ public EntityStalinBeam (World world ) {
17+ super (world );
18+ this .setSize (0.5F , 0.5F );
19+ }
20+
21+ public EntityStalinBeam (World world , EntityLivingBase shooter ) {
22+ this (world );
23+ this .shooter = shooter ;
24+ this .setLocationAndAngles (shooter .posX , shooter .posY + shooter .getEyeHeight (), shooter .posZ , shooter .rotationYaw , shooter .rotationPitch );
25+
26+ // Calculate beam direction
27+ double distance = 16.0D ; // Maximum beam reach
28+ this .motionX = -Math .sin (Math .toRadians (shooter .rotationYaw )) * Math .cos (Math .toRadians (shooter .rotationPitch )) * distance ;
29+ this .motionY = -Math .sin (Math .toRadians (shooter .rotationPitch )) * distance ;
30+ this .motionZ = Math .cos (Math .toRadians (shooter .rotationYaw )) * Math .cos (Math .toRadians (shooter .rotationPitch )) * distance ;
31+ }
32+
33+ @ Override
34+ public void onUpdate () {
35+ if (this .ticksExisted > beamLifetime ) {
36+ this .setDead ();
37+ return ;
38+ }
39+
40+ // Create beacon-like beam effect
41+ if (shooter != null ) {
42+ Vec3 start = Vec3 .createVectorHelper (shooter .posX , shooter .posY + shooter .getEyeHeight (), shooter .posZ );
43+ Vec3 end = Vec3 .createVectorHelper (
44+ shooter .posX + this .motionX ,
45+ shooter .posY + shooter .getEyeHeight () + this .motionY ,
46+ shooter .posZ + this .motionZ
47+ );
48+
49+ // Spawn particles along the beam
50+ for (int i = 0 ; i < 20 ; i ++) {
51+ double progress = i / 20.0D ;
52+ double px = start .xCoord + (end .xCoord - start .xCoord ) * progress ;
53+ double py = start .yCoord + (end .yCoord - start .yCoord ) * progress ;
54+ double pz = start .zCoord + (end .zCoord - start .zCoord ) * progress ;
55+
56+ this .worldObj .spawnParticle ("reddust" , px , py , pz , 0.0D , 0.0D , 0.0D );
57+ }
58+
59+ // Check for players in beam path
60+ MovingObjectPosition hit = this .worldObj .rayTraceBlocks (start , end );
61+ if (hit != null ) {
62+ this .checkBeamCollision (start , Vec3 .createVectorHelper (hit .hitVec .xCoord , hit .hitVec .yCoord , hit .hitVec .zCoord ));
63+ } else {
64+ this .checkBeamCollision (start , end );
65+ }
66+ }
67+
68+ // Play beam sound
69+ if (this .ticksExisted == 1 ) {
70+ this .worldObj .playSoundEffect (this .posX , this .posY , this .posZ , "mob.wither.shoot" , 1.0F , 1.0F );
71+ }
72+ }
73+
74+ private void checkBeamCollision (Vec3 start , Vec3 end ) {
75+ double range = 1.0D ; // Beam thickness
76+ for (Object obj : this .worldObj .getEntitiesWithinAABB (EntityPlayer .class , this .boundingBox .expand (range , range , range ))) {
77+ EntityPlayer player = (EntityPlayer ) obj ;
78+ if (!player .capabilities .isCreativeMode ) {
79+ player .getFoodStats ().addExhaustion (1.0F );
80+ }
81+ }
82+ }
83+
84+ @ Override
85+ protected void entityInit () {}
86+
87+ @ Override
88+ protected void readEntityFromNBT (NBTTagCompound tag ) {}
89+
90+ @ Override
91+ protected void writeEntityToNBT (NBTTagCompound tag ) {}
92+ }
0 commit comments