@@ -25,11 +25,13 @@ public class IndustrialApiaryLogic extends RecipeLogicEnergy {
2525 private static final int BASE_EU_PER_TICK = 80 ;
2626 private static final int PROGRESS_SYNC_TICKS = 20 ;
2727 private static final int BREEDING_TIME_TICKS = 100 ;
28+
2829 private IBeeRoot beeRoot ;
2930 private IBeekeepingLogic beekeepingLogic ;
3031 private boolean needsMovePrincess ;
3132 private int lastSyncedHealth = -1 ;
3233 private int progressSyncCounter ;
34+ private int fxTickCounter ;
3335
3436 public IndustrialApiaryLogic (@ NotNull MetaTileEntity metaTileEntity , RecipeMap <?> recipeMap ,
3537 Supplier <IEnergyContainer > energyContainer ) {
@@ -97,6 +99,8 @@ public void updateModifiers() {
9799 }
98100 }
99101
102+ // ---- Energy & timing ----
103+
100104 public int getEUPerTick () {
101105 ApiaryModifiers mods = getApiary ().getModifiers ();
102106 float energyMod = (mods != null ) ? mods .energy : 1.0F ;
@@ -117,29 +121,36 @@ public int getCycleTickCounter() {
117121
118122 // ---- Core tick logic ----
119123
120- private int fxTickCounter ;
121-
122124 @ Override
123125 public void update () {
124126 if (metaTileEntity .getWorld () == null ) return ;
125127
128+ initBeekeepingLogic ();
129+
126130 // Client-side: bee particle FX
127131 if (metaTileEntity .getWorld ().isRemote ) {
128- if (wasActiveAndNeedsUpdate ) {
129- wasActiveAndNeedsUpdate = false ;
130- setActive (false );
131- }
132- initBeekeepingLogic ();
133- if (beekeepingLogic != null && isActive ) {
134- fxTickCounter ++;
135- if (fxTickCounter % 2 == 0 && beekeepingLogic .canDoBeeFX ()) {
136- beekeepingLogic .doBeeFX ();
137- }
138- }
132+ updateClient ();
139133 return ;
140134 }
141135
142- initBeekeepingLogic ();
136+ // Server-side: bee processing
137+ updateServer ();
138+ }
139+
140+ private void updateClient () {
141+ if (wasActiveAndNeedsUpdate ) {
142+ wasActiveAndNeedsUpdate = false ;
143+ setActive (false );
144+ }
145+ if (beekeepingLogic != null && isActive ) {
146+ fxTickCounter ++;
147+ if (fxTickCounter % 2 == 0 && beekeepingLogic .canDoBeeFX ()) {
148+ beekeepingLogic .doBeeFX ();
149+ }
150+ }
151+ }
152+
153+ private void updateServer () {
143154 if (beekeepingLogic == null ) {
144155 if (isActive ) setActive (false );
145156 return ;
@@ -174,41 +185,40 @@ public void update() {
174185 hasNotEnoughEnergy = false ;
175186 }
176187
188+ // Auto-move princess
177189 if (needsMovePrincess && apiary .getQueen ().isEmpty ()) {
178- doMovePrincess ();
190+ movePrincessToQueenSlot ();
179191 }
180192
181- // Active state
193+ // Active state + FX sync
182194 if (isActive != isWorking ) {
183195 setActive (isWorking );
184- // Sync bee data to client when active state changes (for FX)
185- if (isWorking ) {
186- apiary .syncBeeLogicToClient ();
187- }
196+ apiary .syncBeeLogicToClient ();
188197 }
189198 if (wasActiveAndNeedsUpdate ) {
190199 wasActiveAndNeedsUpdate = false ;
191200 setActive (false );
192201 }
193202
194- // Progress (smooth tick counter)
195203 updateProgress (isWorking , apiary );
196204 }
197205
206+ // ---- Progress tracking ----
207+
198208 private void updateProgress (boolean isWorking , MetaTileEntityIndustrialApiary apiary ) {
199209 if (isWorking && !apiary .getQueen ().isEmpty ()) {
200210 // Reset when progress completes (handles princess→queen transition)
201211 if (maxProgressTime > 0 && progressTime >= maxProgressTime ) {
202212 progressTime = 0 ;
203213 maxProgressTime = 0 ;
204214 lastSyncedHealth = -1 ;
215+ apiary .syncBeeLogicToClient ();
205216 }
206217 if (maxProgressTime <= 0 ) {
207218 syncProgressFromBee (apiary );
208219 }
209220
210- // Periodic resync with actual health (every 20 ticks)
211- // Forestry's aging is probabilistic, so progress can drift
221+ // Periodic resync with actual health
212222 progressSyncCounter ++;
213223 if (progressSyncCounter >= PROGRESS_SYNC_TICKS && maxProgressTime > 0 ) {
214224 progressSyncCounter = 0 ;
@@ -234,9 +244,7 @@ private void syncProgressFromBee(MetaTileEntityIndustrialApiary apiary) {
234244 if (type == EnumBeeType .QUEEN ) {
235245 IBee bee = root .getMember (apiary .getQueen ());
236246 if (bee != null && bee .getMaxHealth () > 0 && bee .getHealth () > 0 ) {
237- // TOP shows 1 cycle (Next Product) duration, not total lifespan
238- int effectiveTicks = getEffectiveTicksPerHealth ();
239- maxProgressTime = effectiveTicks ;
247+ maxProgressTime = getEffectiveTicksPerHealth ();
240248 progressTime = 0 ;
241249 lastSyncedHealth = bee .getHealth ();
242250 }
@@ -247,7 +255,6 @@ private void syncProgressFromBee(MetaTileEntityIndustrialApiary apiary) {
247255 }
248256 }
249257
250- /** Re-read actual bee health; reset cycle progress when health changes. */
251258 private void resyncIfHealthChanged (MetaTileEntityIndustrialApiary apiary ) {
252259 IBeeRoot root = getBeeRoot ();
253260 if (root == null || lastSyncedHealth < 0 ) return ;
@@ -258,7 +265,8 @@ private void resyncIfHealthChanged(MetaTileEntityIndustrialApiary apiary) {
258265 int currentHealth = bee .getHealth ();
259266 if (currentHealth != lastSyncedHealth ) {
260267 lastSyncedHealth = currentHealth ;
261- progressTime = 0 ; // New cycle started
268+ progressTime = 0 ;
269+ apiary .syncBeeLogicToClient ();
262270 }
263271 }
264272
@@ -273,19 +281,16 @@ public void setNeedsMovePrincess() {
273281 needsMovePrincess = true ;
274282 }
275283
276- /** Immediately attempt to move a princess from output to queen slot. */
277- public void tryMovePrincess () {
278- doMovePrincess ();
279- }
280-
281- private void doMovePrincess () {
282- if (beeRoot == null ) return ;
284+ public void movePrincessToQueenSlot () {
285+ IBeeRoot root = getBeeRoot ();
286+ if (root == null ) return ;
283287 MetaTileEntityIndustrialApiary apiary = getApiary ();
284- for (int i = 0 ; i < apiary .getExportItems ().getSlots (); i ++) {
285- ItemStack stack = apiary .getExportItems ().getStackInSlot (i );
286- if (!stack .isEmpty () && beeRoot .isMember (stack , EnumBeeType .PRINCESS )) {
288+ var output = getOutputInventory ();
289+ for (int i = 0 ; i < output .getSlots (); i ++) {
290+ ItemStack stack = output .getStackInSlot (i );
291+ if (!stack .isEmpty () && root .isMember (stack , EnumBeeType .PRINCESS )) {
287292 apiary .setQueen (stack );
288- apiary . getExportItems () .setStackInSlot (i , ItemStack .EMPTY );
293+ output .setStackInSlot (i , ItemStack .EMPTY );
289294 return ;
290295 }
291296 }
0 commit comments