22
33import crafttweaker .annotations .ZenRegister ;
44import github .kasuminova .mmce .common .event .client .ControllerGUIRenderEvent ;
5+ import github .kasuminova .mmce .common .event .machine .MachineStructureUpdateEvent ;
6+ import github .kasuminova .mmce .common .helper .IMachineController ;
57import github .kasuminova .novaeng .common .util .FixedSizeDeque ;
68import hellfirepvp .modularmachinery .ModularMachinery ;
9+ import hellfirepvp .modularmachinery .common .integration .crafttweaker .RecipeBuilder ;
10+ import hellfirepvp .modularmachinery .common .integration .crafttweaker .RecipeModifierBuilder ;
711import hellfirepvp .modularmachinery .common .machine .DynamicMachine ;
12+ import hellfirepvp .modularmachinery .common .machine .factory .FactoryRecipeThread ;
813import hellfirepvp .modularmachinery .common .tiles .base .TileMultiblockMachineController ;
14+ import net .minecraft .nbt .NBTTagCompound ;
915import net .minecraft .util .ResourceLocation ;
1016import net .minecraft .util .math .BlockPos ;
1117import net .minecraft .world .World ;
1521import stanhebben .zenscript .annotations .ZenMethod ;
1622
1723import java .math .BigInteger ;
24+ import java .util .HashMap ;
1825import java .util .Map ;
1926import java .util .concurrent .ConcurrentHashMap ;
2027
2330@ ZenRegister
2431@ ZenClass ("novaeng.DreamEnergyCore" )
2532public class DreamEnergyCore implements MachineSpecial {
26- public static final ResourceLocation REGISTRY_NAME = new ResourceLocation (ModularMachinery .MODID , "dream_energy_core" );
33+ private static final String MachineID = "dream_energy_core" ;
34+ private static final ResourceLocation REGISTRY_NAME = new ResourceLocation (ModularMachinery .MODID , MachineID );
2735 public static final DreamEnergyCore INSTANCE = new DreamEnergyCore ();
28- public static long defaultTransferAmount = 10000000 ;
2936 private static final Map <World ,Map <BlockPos , FixedSizeDeque <String >>> map = new ConcurrentHashMap <>();
37+ private static final ThreadLocal <Map <String , BigInteger >> ENERGY_STORED_CACHE =
38+ ThreadLocal .withInitial (HashMap ::new );
39+
3040 private static final int MinuteScale = 30 ;
41+ //最小传输速度,按倍计。
42+ private static float minSpeed = 0.01f ;
43+ //最大传输速度,按倍计。
44+ private static int maxSpeed = 40000 ;
45+ //基础输入输出速度。能量输入输出速度计算方法为:defaultTransferAmount * speed,其中 speed 可由玩家控制。
46+ private static long defaultTransferAmount = 10000000 ;
3147
3248 @ ZenMethod
33- public static long setDefaultTransferAmount (long value ){
34- defaultTransferAmount = value ;
49+ public static long setDefaultTransferAmount (long varue ){
50+ defaultTransferAmount = varue ;
3551 return defaultTransferAmount ;
3652 }
3753
54+ @ ZenMethod
55+ public static float setMinSpeed (float varue ){
56+ minSpeed = varue ;
57+ return minSpeed ;
58+ }
59+
60+ @ ZenMethod
61+ public static int setMaxSpeed (int varue ){
62+ maxSpeed = varue ;
63+ return maxSpeed ;
64+ }
65+
3866 @ Override
3967 public ResourceLocation getRegistryName () {
4068 return REGISTRY_NAME ;
@@ -53,11 +81,82 @@ public void onClientTick(final TileMultiblockMachineController ctrl) {
5381
5482 @ Override
5583 public void init (DynamicMachine machine ) {
84+ SInit (machine );
5685 if (isClient ) {
5786 CInit (machine );
5887 }
5988 }
6089
90+ public void SInit (DynamicMachine machine ){
91+ machine .addMachineEventHandler (MachineStructureUpdateEvent .class , event -> {
92+ TileMultiblockMachineController controller = event .getController ();
93+ controller .setWorkMode (TileMultiblockMachineController .WorkMode .SEMI_SYNC );
94+ });
95+ var inputThreadName = "梦之收集者" ;
96+ machine .addCoreThread (FactoryRecipeThread .createCoreThread (inputThreadName ));
97+ var outputThreadName = "梦之释放者" ;
98+ machine .addCoreThread (FactoryRecipeThread .createCoreThread (outputThreadName ));
99+ var fairyCraftingThreadName = "梦之同步者" ;
100+ machine .addCoreThread (FactoryRecipeThread .createCoreThread (fairyCraftingThreadName ));
101+ var manaCraftingThreadName = "梦之聚合者" ;
102+ machine .addCoreThread (FactoryRecipeThread .createCoreThread (manaCraftingThreadName ));
103+
104+ // 输出配方
105+ RecipeBuilder .newBuilder ("extract" , MachineID , 1 , 1 , true )
106+ .addEnergyPerTickOutput (defaultTransferAmount )
107+ .addPreCheckHandler (event -> {
108+ var ctrl = event .getController ();
109+ var data = ctrl .getCustomDataTag ();
110+ var speed = Math .max (1.0f ,data .getFloat ("speed" ));
111+ var energy = data .hasKey ("energyStored" ) ? "0" : data .getString ("energyStored" );
112+ if (!canExtract (data , speed )) {
113+ event .setFailed ("内部能量储量不足!" );
114+ return ;
115+ }
116+ ctrl .addPermanentModifier ("extract" , RecipeModifierBuilder .create ("modularmachinery:energy" , "output" , speed , 1 , false ).build ());
117+ })
118+ .addFactoryFinishHandler (event -> {
119+ var ctrl = event .getController ();
120+ var thread = event .getFactoryRecipeThread ();
121+ var data = ctrl .getCustomDataTag ();
122+ var speed = Math .max (1.0f ,data .getFloat ("speed" ));
123+ extractEnergy (data , speed , defaultTransferAmount );
124+ })
125+ .setParallelized (false )
126+ .addRecipeTooltip ("由梦之收集者运行。" , "在智能数据接口处修改速度。" )
127+ .addSmartInterfaceDataInput ("speed" , minSpeed , maxSpeed )
128+ .setThreadName (outputThreadName )
129+ .build ();
130+
131+ // 输入配方
132+ RecipeBuilder .newBuilder ("receive" , MachineID , 1 , 2 , true )
133+ .addEnergyPerTickInput (defaultTransferAmount )
134+ .addFactoryPreTickHandler (event -> {
135+ var ctrl = event .getController ();
136+ var data = ctrl .getCustomDataTag ();
137+ var speed = Math .max (1.0f ,data .getFloat ("speed" ));
138+ ctrl .addPermanentModifier ("receive" , RecipeModifierBuilder .create ("modularmachinery:energy" , "input" , speed , 1 , false ).build ());
139+ })
140+ .addPreCheckHandler (event -> {
141+ var ctrl = event .getController ();
142+ var data = ctrl .getCustomDataTag ();
143+ var speed = Math .max (1.0f ,data .getFloat ("speed" ));
144+ ctrl .addPermanentModifier ("receive" , RecipeModifierBuilder .create ("modularmachinery:energy" , "input" , speed , 1 , false ).build ());
145+ })
146+ .addFactoryPostTickHandler (event -> {
147+ var ctrl = event .getController ();
148+ var thread = event .getFactoryRecipeThread ();
149+ var data = ctrl .getCustomDataTag ();
150+ var speed = Math .max (1.0f ,data .getFloat ("speed" ));
151+ receiveEnergy (data , speed );
152+ })
153+ .setParallelized (false )
154+ .addRecipeTooltip ("由梦之释放者运行。" , "在智能数据接口处修改速度。" )
155+ .addSmartInterfaceDataInput ("speed" , minSpeed , maxSpeed )
156+ .setThreadName (inputThreadName )
157+ .build ();
158+ }
159+
61160 @ SideOnly (Side .CLIENT )
62161 public void CInit (DynamicMachine machine ){
63162 machine .addMachineEventHandler (ControllerGUIRenderEvent .class , event -> {
@@ -78,15 +177,77 @@ public void CInit(DynamicMachine machine){
78177 });
79178 }
80179
180+ /**
181+ * 能否提取能量。
182+ */
183+ private static boolean canExtract (NBTTagCompound nbt ,float speed ){
184+ if (nbt .hasKey ("energyStored" )) {
185+ var energyStored = getBigInt (nbt .getString ("energyStored" ));
186+ var sz = (long ) (speed * defaultTransferAmount );
187+ if (energyStored .compareTo (BigLongMax ) >= 0 ) {
188+ if (ENERGY_STORED_CACHE .get ().size () > 800 ) {
189+ ENERGY_STORED_CACHE .get ().clear ();
190+ }
191+ return true ;
192+ }
193+ return energyStored .longValue () >= sz ;
194+ }
195+ return false ;
196+ }
197+
198+ /**
199+ * 将能量存储进控制器内部。
200+ */
201+ private static void receiveEnergy (NBTTagCompound nbt ,float speed ) {
202+ var energyStored = nbt .hasKey ("energyStored" ) ? getBigInt (nbt .getString ("energyStored" )) : BigInteger .ZERO ;
203+ var sz = BigInteger .valueOf ((long ) (speed * defaultTransferAmount ));
204+
205+ nbt .setString ("energyStored" ,energyStored .add (sz ).toString ());
206+ if (ENERGY_STORED_CACHE .get ().size () > 800 ) {
207+ ENERGY_STORED_CACHE .get ().clear ();
208+ }
209+ }
210+
211+ /**
212+ * 提取控制器内部能量至能量输出仓。
213+ */
214+ private static void extractEnergy (NBTTagCompound nbt ,float speed ,long defaultTransferAmount ) {
215+ var energyStored = nbt .hasKey ("energyStored" ) ? getBigInt (nbt .getString ("energyStored" )) : BigInteger .ZERO ;
216+ var sz = BigInteger .valueOf ((long ) (speed * defaultTransferAmount ));
217+
218+ nbt .setString ("energyStored" ,energyStored .subtract (sz ).toString ());
219+ if (ENERGY_STORED_CACHE .get ().size () > 800 ) {
220+ ENERGY_STORED_CACHE .get ().clear ();
221+ }
222+ }
223+
224+ /**
225+ * 额外的crt方法复用方法作为能量消耗方法
226+ * @param ctrl 控制器
227+ * @param speed 倍率
228+ * @param amount 每倍率消耗
229+ */
230+ @ ZenMethod
231+ public static void extractEnergy (IMachineController ctrl ,float speed ,long amount ){
232+ extractEnergy (ctrl .getController ().getCustomDataTag (),speed ,amount );
233+ }
234+
235+ @ ZenMethod
236+ public static BigInteger getBigInt (String num ){
237+ return ENERGY_STORED_CACHE .get ().computeIfAbsent (num , BigInteger ::new );
238+ }
239+
240+ private static final String longmax = Long .toString (Long .MAX_VALUE );
241+
81242 private String change (TileMultiblockMachineController ctrl ){
82243 FixedSizeDeque <String > energy = getEnergyInfo (ctrl .getWorld (),ctrl .getPos ());
83244 var newtime = energy .getFirst ();
84245 var oldtime = energy .getLast ();
85- var newbig = new BigInteger (newtime );
86- var oldbig = new BigInteger (oldtime );
246+ var newbig = getBigInt (newtime );
247+ var oldbig = getBigInt (oldtime );
87248 var changel = newbig .subtract (oldbig );
88249
89- return formatNumber (changel .compareTo (BigLongMax ) >= 0 ? Long . MAX_VALUE : changel .longValue () / (1200L / MinuteScale * energy .size ()));
250+ return formatNumber (changel .compareTo (BigLongMax ) >= 0 ? longmax : Long . toString ( changel .longValue () / (1200L / MinuteScale * energy .size () )));
90251 }
91252
92253 private static FixedSizeDeque <String > getEnergyInfo (World world ,BlockPos pos ) {
0 commit comments