#Timing the hours a player has spent without an Elytra equipped
60 messages · Page 1 of 1 (latest)
Once your ticket has been resolved, please close it with </ticket close:1054771505520717835> command!
so like, if a player has a specific game stage, start timing the player. The timer needs to persist until the player no longer has that game stage
this is easy with persistent data
PlayerEvents.loggedIn(event => {
const {player} = event
//Only runs one time when a new player joins the game
if (!player.stages.has('new_join')) {
player.stages.add('new_join')
player.stages.add('no_elytra')
player.persistentData.age = 1
player.persistentData.elytratimer = 1
}
})
PlayerEvents.tick(event => {
const {player} = event
let pData = player.persistentData
//Timer that only runs once every 20 ticks(1 second interval)
if(!(player.age % 20 == 0)) return
if(player.chestArmorItem.id == 'minecraft:elytra') {player.stages.remove('no_elytra')}
//Adds a point of persistent data to the player every second if they've not yet worn an elytra
if (player.stages.has('no_elytra')) {
++pData.elytratimer
}
//An example of what you can do in other events with this persistent data(not limited to player tick event!)
if (pData.elytratimer >= 100) {
player.tell('Wow you made it a whole 100 seconds before going into creative mode and equipping an elytra. Not bad.')
}
//Debugging
//player.tell(pData.elytratimer)
})```
let me know if you have any issues with the script
i dont get what player.persistentData.age is really doing here
and thank you for helping me here! i really appreciate it man
this is exactly what i wanted
but yeah like, what is if(!(player.age % 20 == 0)) return? im a new programmer, so to me this just seems like "if player.age modulo 20 is not 0, return.. nothing"
oh as well, i have a curio elytra mod. How would i check for an elytra on the back curio item slot?
hmm
sec
i mean do you want it to fire when they have it in their inventory?
or just when they wear it
this checks for curios slots as well ```js
PlayerEvents.loggedIn(event => {
const {player} = event
//Only runs one time when a new player joins the game
if (!player.stages.has('new_join')) {
player.stages.add('new_join')
player.stages.add('no_elytra')
player.persistentData.elytratimer = 1
}
})
PlayerEvents.tick(event => {
const {player} = event
let pData = player.persistentData
let curios = player.nbt.ForgeCaps['curios:inventory']
//Timer that only runs once every 20 ticks(1 second interval)
if(!(player.age % 20 == 0)) return
if(player.chestArmorItem.id == 'minecraft:elytra') {player.stages.remove('no_elytra')}
if (curios.toString().contains('minecraft:elytra')) {player.stages.remove('no_elytra')}
//Adds a point of persistent data to the player every second if they've not yet worn an elytra
if (player.stages.has('no_elytra')) {
++pData.elytratimer
}
//An example of what you can do in other events with this persistent data(not limited to player tick event!)
if (pData.elytratimer >= 100) {
player.tell('Wow you made it a whole 100 seconds before going into creative mode and equipping an elytra. Not bad.')
}
//Debugging
//player.tell(pData.elytratimer)
})```
Why do you have a player.persistentdata.age you don't seem to do anythig with it
where
you mean this? js player.persistentData.age = 1
oh youre right, i think i added that while i was debugging cause it wasnt working at first when i tested it and forgot to remove lol nice catch
just wearing
you try it out yet?
so i wasnt too clear on what i exactly wanted, so this is the code i landed on given what you provided:
PlayerEvents.loggedIn(event => {
const { player } = event
if (player.stages.has('elytra_challenge')) {
player.persistentData.elytratimer = 1 // time in seconds since elytra has been equipped
}
})
PlayerEvents.tick(event => {
const { player } = event
let pData = player.persistentData
let curios = player.nbt.ForgeCaps['curios:inventory']
let hours = Math.floor(pData.elytratimer / 3600)
let remainingSecondsAfterHours = pData.elytratimer % 3600
let minutes = Math.floor(remainingSecondsAfterHours / 60)
let remainingSeconds = remainingSecondsAfterHours % 60
// timer that only runs once every 20 ticks (1 second interval)
if (!(player.age % 20 == 0)) return
if (player.stages.has('elytra_challenge')) {
if (elytraChallengeItems.includes(player.chestArmorItem.id) || curios.toString().contains('minecraft:elytra')) {
player.tell(Text.red("You've abandoned the No Elytra Challenge! Your progress has been reset and you must opt back in once you're truly ready.\n"))
player.tell([
Text.red('You survived: '),
Text.gold(hours), Text.gold(' hours, '),
Text.gold(minutes), Text.gold(' minutes, and '),
Text.gold(remainingSeconds), Text.gold(' seconds.')
])
pData.elytratimer = 1
player.stages.remove('elytra_challenge')
} else ++pData.elytratimer
// debug
player.tell(pData.elytratimer)
}
})
and it works great!
im just slightly concerned about running something every tick though
well its actually running every second
and it shouldnt have much of an impact since its just maths
I'm more concerned for like
checking curio and chestplate slots
idk how efficient that is
the if statement?
yeah
why would that be resource intensive
idk i just wanna be sure haha
im thinking that with a lot of people online it could? but yeah im not knowledgeable on that stuff at all
you could technically(not recommended) have 100 of those if statements and you probably wouldnt notice a difference in performance barely at all
tho at that point theres a much better way of doing it with a function
yeah true
a mob with ai being loaded into the world would still take more resources than that as well
one last thing: not sure if you noticed but im not doing this after someone logs in. It's more of like an "opt-in" thing, so is it fine to do player.persistentData.elytratimer = 1 every time someone gets the stage? I'm not familiar with persistentdata at all
im gonna register a command that just runs /kubejs stages
you would just give them the pdata elytratimer 1(this is needed to initiate the pdata on the player) with the command
the 'first_join' tag is only so it doesnt run every time someone logs in
PlayerEvents.loggedIn(event => {
const { player } = event
if (player.stages.has('elytra_challenge')) {
player.persistentData.elytratimer = 1 // time in seconds since elytra has been equipped
}
})``` btw
doing it like this will reset people's timers on relog
hence the first join tag
oh shoot whoops
though it doesnt really matter if youre making a command anyways tbh
all you really have to do with the command is give people the elytratimer pdata to have it start adding it to their character data
alright lemme try to figure out how to do commands lol
Please close your ticket (with </ticket close:1054771505520717835> or the button atop this thread) once you resolved your issue! This also helps others that would like to help out, as they don't have to look into this thread to check if it has been resolved by now.
Do you have any other questions regarding your issue? Feel free to ask!
Note: You generally should create a new post for unrelated issues.
i might still need help with running the playerevent in a command