33import java .util .List ;
44
55import org .jetbrains .annotations .UnknownNullability ;
6+ import org .joml .Matrix3d ;
67
78import net .minecraft .core .BlockPos ;
89import net .minecraft .core .Direction ;
10+ import net .minecraft .core .HolderLookup ;
11+ import net .minecraft .nbt .CompoundTag ;
912import net .minecraft .sounds .SoundSource ;
1013import net .minecraft .util .FastColor ;
1114import net .minecraft .util .Mth ;
15+ import net .minecraft .world .entity .player .Player ;
1216import net .minecraft .world .level .Level ;
17+ import net .minecraft .world .phys .BlockHitResult ;
1318import net .minecraft .world .phys .Vec3 ;
1419
1520import appbot .AppliedBotanics ;
2025
2126import appeng .api .config .Actionable ;
2227import appeng .api .config .PowerMultiplier ;
28+ import appeng .api .orientation .BlockOrientation ;
2329import appeng .api .parts .IPartItem ;
2430import appeng .api .parts .IPartModel ;
2531import appeng .core .AEConfig ;
2632import appeng .parts .AEBasePart ;
2733import appeng .parts .p2p .P2PModels ;
2834import appeng .parts .p2p .P2PTunnelPart ;
35+ import appeng .util .InteractionUtil ;
2936
30- public class ManaP2PTunnelPart extends P2PTunnelPart <ManaP2PTunnelPart > implements ManaReceiver {
37+ public class ManaP2PTunnelPart extends P2PTunnelPart <ManaP2PTunnelPart > implements ManaReceiver , SafeMana {
3138
3239 private static final double MANA_RETAINED = 0.95 ;
3340 private static final int EXTRA_TICKS_EXISTED = 1 ;
3441
35- private static final float [] ROTX , ROTY ;
3642 private static final P2PModels MODELS = new P2PModels (AppliedBotanics .id ("part/mana_p2p_tunnel" ));
3743
38- static {
39- ROTX = new float [6 ];
40- ROTY = new float [6 ];
41-
42- ROTY [Direction .DOWN .get3DDataValue ()] = -90 ;
43- ROTY [Direction .UP .get3DDataValue ()] = 90 ;
44-
45- ROTX [Direction .DOWN .get3DDataValue ()] = -90 ;
46- ROTX [Direction .UP .get3DDataValue ()] = -90 ;
47- ROTX [Direction .NORTH .get3DDataValue ()] = 0 ;
48- ROTX [Direction .SOUTH .get3DDataValue ()] = -180 ;
49- ROTX [Direction .WEST .get3DDataValue ()] = -90 ;
50- ROTX [Direction .EAST .get3DDataValue ()] = -270 ;
51- }
44+ private byte spin ;
5245
5346 public ManaP2PTunnelPart (IPartItem <?> partItem ) {
5447 super (partItem );
@@ -68,6 +61,41 @@ public IPartModel getStaticModels() {
6861 return MODELS .getModel (this .isPowered (), this .isActive ());
6962 }
7063
64+ @ Override
65+ public void readFromNBT (CompoundTag data , HolderLookup .Provider registries ) {
66+ super .readFromNBT (data , registries );
67+ spin = data .getByte ("spin" );
68+ }
69+
70+ @ Override
71+ public void writeToNBT (CompoundTag data , HolderLookup .Provider registries ) {
72+ super .writeToNBT (data , registries );
73+ data .putByte ("spin" , spin );
74+ }
75+
76+ @ Override
77+ public boolean onUseWithoutItem (Player player , Vec3 pos ) {
78+ if (InteractionUtil .canWrenchRotate (player .getInventory ().getSelected ())) {
79+ if (!isClientSide ()) {
80+ this .spin = (byte ) ((this .spin + 1 ) % 4 );
81+ this .getHost ().markForUpdate ();
82+ this .getHost ().markForSave ();
83+ }
84+ return true ;
85+ } else {
86+ return super .onUseWithoutItem (player , pos );
87+ }
88+ }
89+
90+ @ Override
91+ public void onPlacement (Player player ) {
92+ super .onPlacement (player );
93+
94+ if (getSide ().getAxis () == Direction .Axis .Y ) {
95+ this .spin = (byte ) (Mth .floor (player .getYRot () * 4F / 360F + 2.5D ) & 3 );
96+ }
97+ }
98+
7199 // <editor-fold desc="Fake ManaReceiver">
72100 @ Override
73101 public @ UnknownNullability Level getManaReceiverLevel () {
@@ -98,11 +126,21 @@ public void receiveMana(int mana) {
98126 public boolean canReceiveManaFromBursts () {
99127 return !isFull ();
100128 }
129+
130+ @ Override
131+ public int insert (int amount , Actionable mode ) {
132+ return 0 ;
133+ }
134+
135+ @ Override
136+ public int extract (int amount , Actionable mode ) {
137+ return 0 ;
138+ }
101139 // </editor-fold>
102140
103- public void receiveManaFromBurst (ManaBurstEntity burst ) {
141+ public void receiveManaFromBurst (ManaBurstEntity burst , BlockHitResult hit ) {
104142 var node = getMainNode ().getNode ();
105- int mana = burst .getMana ();
143+ var mana = burst .getMana ();
106144
107145 if (node == null || isFull () || mana <= 0 ) {
108146 return ;
@@ -112,8 +150,32 @@ public void receiveManaFromBurst(ManaBurstEntity burst) {
112150 if (outputs .isEmpty ())
113151 return ;
114152
153+ var input = this ;
115154 var output = outputs .get (getLevel ().getRandom ().nextInt (outputs .size ()));
116155
156+ Vec3 moveTo , directionTo ;
157+ float xrot , yrot ;
158+
159+ {
160+ var sideInput = input .getSide ();
161+ var sideOutput = output .getSide ();
162+
163+ var originInput = Vec3 .atCenterOf (input .getBlockEntity ().getBlockPos ())
164+ .add (Vec3 .atLowerCornerOf (sideInput .getNormal ()).scale (0.5 )).toVector3f ();
165+ var originOutput = Vec3 .atCenterOf (output .getBlockEntity ().getBlockPos ())
166+ .add (Vec3 .atLowerCornerOf (sideOutput .getNormal ()).scale (0.5 )).toVector3f ();
167+
168+ var r = onb (sideOutput , output .getOrientation ())
169+ .mul (onb (sideInput , input .getOrientation ()).transpose ());
170+
171+ moveTo = new Vec3 (hit .getLocation ().toVector3f ().sub (originInput ).mul (r ).add (originOutput ));
172+ directionTo = new Vec3 (burst .getDeltaMovement ().toVector3f ().mul (r )).scale (-1 );
173+
174+ var xz = Math .sqrt (directionTo .x * directionTo .x + directionTo .z * directionTo .z );
175+ xrot = Mth .wrapDegrees ((float ) -(Mth .atan2 (directionTo .y , xz ) * Mth .RAD_TO_DEG ));
176+ yrot = Mth .wrapDegrees ((float ) (Mth .atan2 (directionTo .z , directionTo .x ) * Mth .RAD_TO_DEG ) - 90.0F );
177+ }
178+
117179 var costFactor = AEConfig .instance ().getP2PTunnelTransportTax ();
118180
119181 if (costFactor > 0 ) {
@@ -129,17 +191,14 @@ public void receiveManaFromBurst(ManaBurstEntity burst) {
129191 }
130192
131193 var level = output .getLevel ();
132- var dir = output .getSide ();
133- var pos = output .getBlockEntity ().getBlockPos ();
134194
135- int old = burst .getColor ();
136- int rainbow = Mth .hsvToRgb (level .getGameTime () * 2 % 360 / 360F , 1F , 1F );
137- int newColor = FastColor .ARGB32 .lerp (0.4f , old , rainbow );
195+ var old = burst .getColor ();
196+ var rainbow = Mth .hsvToRgb (level .getGameTime () * 2 % 360 / 360F , 1F , 1F );
197+ var newColor = FastColor .ARGB32 .lerp (0.4f , old , rainbow );
138198
139199 var newBurst = new ManaBurstEntity (BotaniaEntities .MANA_BURST , level );
140- var at = Vec3 .atCenterOf (pos ).add (Vec3 .atLowerCornerOf (dir .getNormal ()).scale (0.5 ));
141- newBurst .moveTo (at .x , at .y , at .z , ROTX [dir .get3DDataValue ()], ROTY [dir .get3DDataValue ()]);
142- newBurst .setDeltaMovement (ManaBurstEntity .calculateBurstVelocity (newBurst .getXRot (), newBurst .getYRot ()));
200+ newBurst .moveTo (moveTo .x , moveTo .y , moveTo .z , yrot , xrot );
201+ newBurst .setDeltaMovement (directionTo );
143202 newBurst .setColor (newColor );
144203 newBurst .setMana (mana );
145204 newBurst .setStartingMana (burst .getStartingMana ());
@@ -151,7 +210,28 @@ public void receiveManaFromBurst(ManaBurstEntity burst) {
151210 newBurst .setTicksExisted (burst .getTicksExisted () + ManaP2PTunnelPart .EXTRA_TICKS_EXISTED );
152211
153212 level .addFreshEntity (newBurst );
154- level .playSound (null , pos , BotaniaSounds .spreaderFire , SoundSource .BLOCKS , 0.05F ,
213+ level .playSound (null , moveTo . x , moveTo . y , moveTo . z , BotaniaSounds .spreaderFire , SoundSource .BLOCKS , 0.05F ,
155214 0.7F + 0.3F * (float ) Math .random ());
156215 }
216+
217+ private static Matrix3d onb (Direction a , Direction b ) {
218+ var m = new Matrix3d ();
219+ var va = a .getNormal ();
220+ var vb = b .getNormal ();
221+ var vc = va .cross (vb );
222+ m .m00 = va .getX ();
223+ m .m01 = va .getY ();
224+ m .m02 = va .getZ ();
225+ m .m10 = vb .getX ();
226+ m .m11 = vb .getY ();
227+ m .m12 = vb .getZ ();
228+ m .m20 = vc .getX ();
229+ m .m21 = vc .getY ();
230+ m .m22 = vc .getZ ();
231+ return m ;
232+ }
233+
234+ private Direction getOrientation () {
235+ return BlockOrientation .get (getSide (), spin ).rotate (Direction .UP );
236+ }
157237}
0 commit comments