1- import { ButtonState , EffectTypes , EntityInventoryComponent , EquipmentSlot , InputButton , ItemLockMode , ItemStack , Player , StartupEvent , system , Vector3 , world } from "@minecraft/server" ;
1+ import { ButtonState , EffectTypes , EntityHealthComponent , EntityInventoryComponent , EquipmentSlot , InputButton , InputPermissionCategory , ItemLockMode , ItemStack , MolangVariableMap , Player , StartupEvent , system , Vector3 , world } from "@minecraft/server" ;
22import { MinecraftEffectTypes } from "@minecraft/vanilla-data" ;
33import { directionVector , entityGetSlot , entityHasSlotTag } from "../../utility" ;
44import { V3 } from "../../math/vectorUtils" ;
5- import { deg2Rad } from "../../math/general" ;
5+ import { deg2Rad , remap } from "../../math/general" ;
66
77let light : ItemStack
88const fCooldownTime = 80
@@ -13,6 +13,9 @@ enum States {
1313}
1414const flyTurnCooldownTime : number = 10
1515const flyTurnCooldown : Map < string , number > = new Map ( )
16+ const flySoundCooldown : Map < string , number > = new Map ( )
17+ const airTime : Map < string , number > = new Map ( )
18+ const airJumps : Map < string , number > = new Map ( )
1619const flyingAngles : Map < string , Vector3 > = new Map ( )
1720// Defining setters for ability cooldowns
1821Object . defineProperties ( Player . prototype , {
@@ -71,12 +74,37 @@ export function main() {
7174 if ( ! entityHasSlotTag ( player , EquipmentSlot . Mainhand , "whynot:light" ) ) return ;
7275
7376 if ( button != InputButton . Jump ) return
74- if ( ! player . isOnGround && pressed && player . state == States . NORMAL && player . fCooldown <= 0 ) {
75- player . state = States . FLYING
76- flyingAngles . set ( player . id , player . getViewDirection ( ) ) ;
77+ // Activate fly
78+ if ( ( ( airTime . get ( player . id ) ?? 0 ) > 2 ) && pressed && player . state == States . NORMAL ) {
79+ if ( player . fCooldown <= 0 && player . isSneaking ) {
80+ player . state = States . FLYING
81+ flyingAngles . set ( player . id , player . getViewDirection ( ) ) ;
82+ player . addEffect ( MinecraftEffectTypes . SlowFalling , 20000000 , { showParticles : false } )
83+ player . playSound ( "light_dash" )
84+ player . playSound ( "light_beam_start" )
85+
86+ flySoundCooldown . set ( player . id , 0 )
87+ flyTurnCooldown . set ( player . id , 0 )
88+ player . inputPermissions . setPermissionCategory ( InputPermissionCategory . Movement , false )
89+ } else if ( ( airJumps . get ( player . id ) ?? 0 ) > 0 ) {
90+ player . applyImpulse ( V3 . make ( 0 , - player . getVelocity ( ) . y + 0.75 , 0 ) )
91+ let molangSize1 = new MolangVariableMap ( ) ; molangSize1 . setFloat ( "size" , 1.0 / 2.0 )
92+ let molangSize2 = new MolangVariableMap ( ) ; molangSize2 . setFloat ( "size" , 1.3 / 2.0 )
93+ let molangSize3 = new MolangVariableMap ( ) ; molangSize3 . setFloat ( "size" , 1.5 / 2.0 )
94+ player . spawnParticle ( "whynot:moon_jump" , V3 . add ( player . location , V3 . make ( 0 , 0 , 0 ) ) , molangSize1 )
95+ player . spawnParticle ( "whynot:moon_jump" , V3 . add ( player . location , V3 . make ( 0 , - 0.2 , 0 ) ) , molangSize2 )
96+ player . spawnParticle ( "whynot:moon_jump" , V3 . add ( player . location , V3 . make ( 0 , - 0.4 , 0 ) ) , molangSize3 )
97+ player . playSound ( "moon_jump" )
98+ airJumps . set ( player . id , ( airJumps . get ( player . id ) ?? 0 ) - 1 )
99+ }
77100 }
101+ // Deactivate fly
78102 if ( ! pressed && player . state == States . FLYING ) {
103+ player . inputPermissions . setPermissionCategory ( InputPermissionCategory . Movement , true )
79104 player . state = States . NORMAL
105+ player . removeEffect ( MinecraftEffectTypes . SlowFalling ) ;
106+ player . addEffect ( MinecraftEffectTypes . SlowFalling , 25 , { showParticles : false } )
107+
80108 player . removeEffect ( MinecraftEffectTypes . Invisibility )
81109 }
82110 } )
@@ -88,36 +116,71 @@ export function main() {
88116 system . runInterval ( mainTick )
89117}
90118
119+
91120function mainTick ( ) {
92121 world . getAllPlayers ( ) . forEach ( player => {
122+ // Set Airtime
123+ if ( player . isOnGround ) {
124+ if ( player . state != States . FLYING ) {
125+ player . removeEffect ( MinecraftEffectTypes . SlowFalling ) ;
126+ airJumps . set ( player . id , 10 )
127+
128+
129+ }
130+ airTime . set ( player . id , 0 )
131+ }
132+ else airTime . set ( player . id , ( airTime . get ( player . id ) ?? 0 ) + 1 )
133+
93134 if ( player . state == States . FLYING ) {
135+
94136 player . addEffect ( MinecraftEffectTypes . Invisibility , 20000000 , { showParticles : false } )
95137 player . fCooldown = fCooldownTime
138+
139+ // If viewing angle change is significant change direction
96140 const viewDir = player . getViewDirection ( ) ;
97141 const addVel = V3 . normalize ( flyingAngles . get ( player . id ) ?? viewDir ) ;
98142 if ( V3 . dot ( viewDir , addVel ) < flyTurnThreshold && ( flyTurnCooldown . get ( player . id ) ?? 0 ) <= 0 ) {
99143 flyingAngles . set ( player . id , viewDir ) ;
144+ player . playSound ( "light_dash" )
100145 }
146+
147+ // Scale speed from health
148+ const health = player . getComponent ( EntityHealthComponent . componentId ) as EntityHealthComponent ;
149+ const speed = remap ( health . currentValue , health . effectiveMin , health . effectiveMax , 0.1 , 1.0 ) ;
150+ const vel = V3 . scale ( addVel , speed )
101151 player . clearVelocity ( ) ;
102- player . applyImpulse ( addVel ) ;
152+ player . applyImpulse ( vel ) ;
103153
104- const vel = player . getVelocity ( ) ;
105- const blockHit = player . dimension . getBlockFromRay ( player . location , vel , { maxDistance : 1 , includeLiquidBlocks :false , includePassableBlocks : false } )
106- if ( ( flyTurnCooldown . get ( player . id ) ?? 0 ) > 0 ) {
107- flyTurnCooldown . set ( player . id , ( flyTurnCooldown . get ( player . id ) ?? 0 ) - 1 )
108- }
154+ // Get block in path and bounce if needed
155+ const blockHit = player . dimension . getBlockFromRay ( player . location , vel , { maxDistance : 2 , includeLiquidBlocks :false , includePassableBlocks : false } )
109156 if ( blockHit && blockHit . block . isSolid ) {
110157 const bounced = V3 . reflect ( vel , directionVector ( blockHit . face ) ) ;
111158 flyingAngles . set ( player . id , bounced ) ;
112159 flyTurnCooldown . set ( player . id , flyTurnCooldownTime )
160+ player . playSound ( "light_dash" )
161+ }
162+
163+ // Reduce fly turn cooldown
164+ let currFlyTurnCooldown = flyTurnCooldown . get ( player . id ) ?? 0 ;
165+ if ( currFlyTurnCooldown > 0 ) flyTurnCooldown . set ( player . id , currFlyTurnCooldown - 1 ) ;
166+
167+ let currSoundCooldon = flySoundCooldown . get ( player . id ) ?? 0 ;
168+ if ( currSoundCooldon > 0 ) flySoundCooldown . set ( player . id , currSoundCooldon - 1 ) ;
169+ else {
170+ player . playSound ( "light_beam_loop" , { volume : 10 } )
171+ // player.playSound("light_beam_loop", {volume: 10})
172+ flySoundCooldown . set ( player . id , 7 ) //8.58
113173 }
114174 }
175+
176+ // Reduce all cooldowns
115177 if ( player . zCooldown > 0 ) player . zCooldown -- ;
116178 if ( player . xCooldown > 0 ) player . xCooldown -- ;
117179 if ( player . cCooldown > 0 ) player . cCooldown -- ;
118180 if ( player . vCooldown > 0 ) player . vCooldown -- ;
119181 if ( player . fCooldown > 0 ) player . fCooldown -- ;
120182
183+ // If player is holding light display cooldowns
121184 if ( ! entityHasSlotTag ( player , EquipmentSlot . Mainhand , "whynot:light" ) ) return
122185 player . onScreenDisplay . setActionBar ( `Z: ${ player . zCooldown } X: ${ player . xCooldown } C: ${ player . cCooldown } V: ${ player . vCooldown } F: ${ player . fCooldown } ` )
123186 } )
0 commit comments