5151import net .minecraft .network .chat .Component ;
5252import net .minecraft .network .chat .MutableComponent ;
5353import net .minecraft .resources .ResourceLocation ;
54+ import net .minecraft .server .level .ServerPlayer ;
5455import net .minecraft .world .entity .LivingEntity ;
5556import net .minecraft .world .entity .player .Player ;
5657import net .minecraft .world .level .Level ;
@@ -157,28 +158,80 @@ public WeaponTypes getWeapon(LivingEntity en) {
157158 }
158159
159160 public final void onCastingTick (SpellCastContext ctx ) {
160- int timesToCast = (int ) ctx .spell .getConfig ().times_to_cast ;
161- if (timesToCast > 1 ) {
162- int castTimeTicks = (int ) getCastTimeTicks (ctx );
163- // if i didnt do this then cast time reduction would reduce amount of spell hits.
164- int castEveryXTicks = castTimeTicks / timesToCast ;
165- if (timesToCast > 1 ) {
161+
162+ int timesToCast = ctx .spell .getConfig ().times_to_cast ;
163+ if (timesToCast > 1 ){
164+
165+
166+ if (ctx .caster instanceof ServerPlayer player ){
167+
168+ if (ctx .ticksInUse > 0 ){
169+ //do more precise time calculation here, so we don't miss each single cast.
170+ SpellCastingData spellCastingData = Load .player (player ).spellCastingData ;
171+ //already done all casts
172+ if (spellCastingData .castTimesDone >= timesToCast ) {
173+ return ;
174+ }
175+
176+ //don't invoke getCastTimeTicks(ctx) to get the imprecise tick!
177+ //for internal calc, use the precise one
178+ float allCastsTime = ctx .event .data .getNumber (EventData .CAST_TICKS ).number ;
179+ float singleCastTime = allCastsTime / timesToCast ;
180+ float usedCastedTime = spellCastingData .castTimesDone * singleCastTime ;
181+
182+
183+
184+ //when it's last tick but there are still casts not finished
185+ if (ctx .isLastCastTick && spellCastingData .castTimesDone < timesToCast ) {
186+ int leftTimes = timesToCast - spellCastingData .castTimesDone ;
187+ for (int i = 0 ; i < leftTimes ; i ++) {
188+ this .cast (ctx );
189+ spellCastingData .castTimesDone ++;
190+ }
191+ return ;
192+ }
193+
194+
195+ int hitTime = 0 ;
196+ while (ctx .ticksInUse - usedCastedTime >= singleCastTime ) {
197+ hitTime ++;
198+ usedCastedTime += singleCastTime ;
199+ }
200+ for (int time = hitTime ; time > 0 ; time --) {
201+ this .cast (ctx );
202+ spellCastingData .castTimesDone ++;
203+ }
204+
205+
206+ }
207+
208+ } else {
209+ int castTimeTicks = (int ) getCastTimeTicks (ctx );
210+
211+
212+ // if i didnt do this then cast time reduction would reduce amount of spell hits.
213+ int castEveryXTicks = castTimeTicks / timesToCast ;
214+
166215 if (castEveryXTicks < 1 ) {
167216 castEveryXTicks = 1 ;
168217 }
169- }
170- if (ctx .ticksInUse > 0 && ctx .ticksInUse % castEveryXTicks == 0 ) {
171- this .cast (ctx );
218+
219+ if (ctx .ticksInUse > 0 && ctx .ticksInUse % castEveryXTicks == 0 ) {
220+ this .cast (ctx );
221+ }
222+
172223 }
173224 } else if (timesToCast < 1 ) {
174225 ExileLog .get ().warn ("Times to cast spell is: " + timesToCast + " . this seems like a bug." );
175226 }
227+
228+ ctx .castedThisTick = true ;
176229 }
177230
178231 public void cast (SpellCastContext ctx ) {
179232 LivingEntity caster = ctx .caster ;
180- ctx . castedThisTick = true ;
181- /*
233+
234+ /*
182235 if (MMORPG.RUN_DEV_TOOLS_REMOVE_WHEN_DONE && this.config.swing_arm) {
183236 // caster.swingTime = -1; // this makes sure hand swings
184237 // caster.swing(InteractionHand.MAIN_HAND);
@@ -195,9 +248,10 @@ public final int getChargeCooldownTicks(SpellCastContext ctx) {
195248 return (int ) ctx .event .data .getNumber (EventData .CHARGE_COOLDOWN_TICKS ).number ;
196249 }
197250
198- public final int getCastTimeTicks (SpellCastContext ctx ) {
251+ public int getCastTimeTicks (SpellCastContext ctx ) {
199252 // if it casts 5 times a cast, it should take at least 5 ticks to cast it
200- return MathHelper .clamp ((int ) ctx .event .data .getNumber (EventData .CAST_TICKS ).number , config .times_to_cast , 10000 );
253+ //Clefal: we can actually allow multiple cast on 1 tick. But we at least need to let the cast time a little longer than the real cast time.
254+ return ((int ) Math .ceil (ctx .event .data .getNumber (EventData .CAST_TICKS ).number ));
201255 }
202256
203257 @ Override
@@ -277,7 +331,7 @@ public final List<Component> GetTooltipString(StatRangeInfo info) {
277331 if (casttime == 0 ) {
278332 list .add (Words .INSTANT_CAST .locName ().withStyle (ChatFormatting .GREEN ));
279333 } else {
280- list .add (Words .CAST_TIME .locName (casttime / 20 ).withStyle (ChatFormatting .GREEN ));
334+ list .add (Words .CAST_TIME .locName (Math . round ( casttime / 20.0f * 100f ) / 100f ).withStyle (ChatFormatting .GREEN ));
281335 }
282336
283337 Set <String > radiuses = new LinkedHashSet <>();
0 commit comments