diff --git a/src/ica-admin.sc b/src/ica-admin.sc new file mode 100644 index 0000000..463634f --- /dev/null +++ b/src/ica-admin.sc @@ -0,0 +1,231 @@ +__config() -> { + 'scope' -> 'global', + 'command_permission' -> 'ops', + 'commands' -> { + '' -> 'cmdList', + 'list' -> 'cmdList', + 'confirm' -> 'cmdStart', + 'reset clear' -> 'cmdResetClear', + 'reset schedule' -> 'cmdReschedule' + }, +}; + +clearBossbars() -> ( + run('bossbar remove ica:prepare_counter'); + run('bossbar remove ica:time_counter'); + run('bossbar remove ica:collected'); +); + +createBossbar(nid, name, val, sty) -> ( + bossbar(nid); + bossbar(nid, 'max', val); + bossbar(nid, 'value', val); + bossbar(nid, 'name', name); + bossbar(nid, 'players', player('all')); + + if(sty != null, bossbar(nid, 'style', sty)); +); + + +__on_player_dies(p) -> ( + if(nbt_storage('ica:data'):'Started' + && !nbt_storage('ica:data'):'Preparing', ( + modify(p, 'gamemode', 'spectator'); + )); +); + +tm_prepare() -> ( + 12000 +); + +tm_total() -> ( + 72000 +); + +tm_per_goal() -> ( + 12000 +); + +getPigPlayers() -> ( + entity_selector('@a[tag=!ica.wolf]') +); + +getWolfPlayers() -> ( + entity_selector('@a[tag=ica.wolf]') +); + +endGameTitle(p, m, s) -> ( + display_title(p, 'title', m, 10, 200, 10); + display_title(p, 'subtitle', s, 10, 200, 10); +); + +endTimeout(iv) -> ( + clearBossbars(); + put(nbt_storage('ica:data'):'Started', '0b'); + endGameTitle(getPigPlayers(), 'Timeout!' + , str('You didn\'t complete %d goals in time.', iv)); + endGameTitle(getWolfPlayers(), 'You won!' + , str('Those fools have failed, haha.', iv)); +); + +endFinish() -> ( + clearBossbars(); + put(nbt_storage('ica:data'):'Started', '0b'); + endGameTitle(getPigPlayers(), 'Congratulations!', 'You have completed all the goals.'); + endGameTitle(getWolfPlayers(), 'Oh no!' + , str('They have completed all the goals.', iv)); +); + +getFirstUnsetGoal() -> ( + c_for(i = 0, i <= 5, i = i + 1, ( + p = nbt_storage('ica:data'):str('Goals[{Slot: %db}]', i); + if(p == null, ( + return(i); + )) + )); + return(6); +); + +warnDeadline(dt) -> ( + if (dt == 1200, ( + print(player('all'), '[WARN] Submission deadline in 1 minute.'); + )); + if (dt == 600, ( + print(player('all'), '[WARN] Submission deadline in 30 seconds.'); + )); + if (dt == 300, ( + print(player('all'), '[WARN] Submission deadline in 15 seconds.'); + )); + if (dt <= 200 && dt % 20 == 0, ( + print(player('all'), str('[WARN] Submission deadline in %d second%s!' + , dt / 20, if(dt > 20, 's', ''))); + )); +); + +runUpdateCollect() -> ( + if(!nbt_storage('ica:data'):'Started', return()); + tm = bossbar('ica:time_counter', 'value') - 20; + bossbar('ica:time_counter', 'value', tm); + iv = bossbar('ica:collected', 'value') + 1; + if(iv == 7, endFinish()); + dt = tm - (6 - iv) * tm_per_goal(); + if(dt <= 0, ( + endTimeout(iv); + ), ( + warnDeadline(dt); + schedule(20, 'runUpdateCollect'); + )) +); + +startCollectStage() -> ( + schedule(20, 'runUpdateCollect'); + + clearBossbars(); + createBossbar('ica:time_counter', 'Time Left', tm_total(), 'notched_6'); + createBossbar('ica:collected', 'Collected', 6, 'notched_6'); + bossbar('ica:collected', 'value', 0); + + for(player('all'), ( + if(query(_, 'has_scoreboard_tag', 'ica.spyglasser'), ( + modify(_, 'tag', 'ica.spyglass_fireball'); + )); + )); + + put(nbt_storage('ica:data'):'Preparing', '0b'); +); + +setElytra(p) -> ( + // 38 is where the player's elytra should be at. + inventory_set(p, 8, 64, 'minecraft:firework_rocket'); + inventory_set(p, 38, 1, 'minecraft:elytra', '{Unbreakable: 1b}'); +); + +clearExp(p) -> ( + modify(p, 'xp_level', 0); + modify(p, 'xp_progress', 0); + modify(p, 'xp_score', 0); +); + +playerInit(p) -> ( + modify(p, 'gamemode', 'survival'); + if(query(p, 'has_scoreboard_tag', 'ica.flyer'), setElytra(p)); + clearExp(p); + inventory_set(p, 2, 1, 'minecraft:spyglass'); +); + +__on_start() -> ( + if(nbt_storage('ica:data'):'Goals' == null, ( + nbt_storage('ica:data', '{Goals: [], Started: 0b, Preparing: 0b}') + )) +); + +cmdResetClear() -> ( + clearBossbars(); + put(nbt_storage('ica:data'):'Started', '0b'); + put(nbt_storage('ica:data'):'Preparing', '0b'); +); + +cmdReschedule() -> ( + if(!nbt_storage('ica:data'):'Started', ( + print('Not started. use /ica-admin confirm to start.'); + return(false) + )); + schedule('runUpdateCollect', 20); +); + +runUpdatePrepare() -> ( + if(!nbt_storage('ica:data'):'Started', return()); + if(!nbt_storage('ica:data'):'Preparing', return()); + tm = bossbar('ica:prepare_counter', 'value') - 20; + bossbar('ica:prepare_counter', 'value', tm); + if(tm <= 0, ( + startCollectStage(); + ), ( + schedule(20, 'runUpdatePrepare'); + )) +); + +cmdStart() -> ( + missing_goal = getFirstUnsetGoal(); + if(missing_goal <= 5, ( + print(str('Goal #%d is unset.', missing_goal)); + return(false) + )); + + if(nbt_storage('ica:data'):'Started', ( + print('Already started, use /ica-admin reset clear to cancel.'); + return(false) + )); + put(nbt_storage('ica:data'):'Started', '1b'); + put(nbt_storage('ica:data'):'Preparing', '1b'); + put(nbt_storage('ica:data'):'Goals[].Completed', '0b'); + + createBossbar('ica:prepare_counter', 'Preparing', tm_prepare(), null); + + schedule(20, 'runUpdatePrepare'); + + for(player('all'), modify(_, 'clear_tag', ['ica.piggy' + , 'ica.wolf', 'ica.hunter', 'ica.spyglasser', 'ica.spyglass_fireball' + , 'ica.voter', 'ica.flyer'])); + + player_n = length(player('all')); + wolf_id = floor(rand(player_n)); + for(player('all'), ( + modify(_, 'tag', ['ica.voter', 'ica.flyer']); + modify(_, 'tag', if(_i == wolf_id, ['ica.wolf', 'ica.spyglasser'], 'ica.piggy')); + )); + + run('execute as @a run clear'); + for(player('all'), playerInit(_)); + + run('ica-effect-applier enable'); + run('time set day'); + run('gamerule keepInventory false'); + run('gamerule playersSleepingPercentage 0'); + run('worldborder set 10000'); +); + +cmdList() -> ( + print('please use /ica instead'); + run('/ica'); +); diff --git a/src/ica-effect-applier.sc b/src/ica-effect-applier.sc new file mode 100644 index 0000000..6be11e1 --- /dev/null +++ b/src/ica-effect-applier.sc @@ -0,0 +1,34 @@ +global_enabled = false; +global_effects = ['regeneration', 'resistance']; + +__config() -> { + 'command_permission' -> 'ops', + 'scope' -> 'global', + 'commands' -> { + '' -> 'getStatus', + 'enable' -> _() -> global_enabled = true, + 'disable' -> _() -> global_enabled = false, + }, +}; + +getStatus() -> ( + if(global_enabled, ( + print('effect-applier: on') + ), ( + print('effect-applier: off') + )) +); + +updateEffects() -> ( + if(global_enabled, ( + for(global_effects, ( + e = _; + for(player('all'), modify(_, 'effect', e, 300, 1, false, true)); + )); + )); + schedule(200, 'updateEffects'); +); + +__on_start() -> ( + schedule(1, 'updateEffects') +); \ No newline at end of file diff --git a/src/ica-fireball.sc b/src/ica-fireball.sc new file mode 100644 index 0000000..0a36f1c --- /dev/null +++ b/src/ica-fireball.sc @@ -0,0 +1,30 @@ +shoot_fireball(myself, rm) -> ( + playerPos = query(myself, 'pos') + l(0, query(myself, 'eye_height'), 0); // Set the position where the fireball will spawn + playerM = query(myself, 'motion'); + + v = query(myself, 'look'); + fbv = v * 0.3; + fireball = spawn('fireball', playerPos + v * 2 + , nbt(str('{ExplosionPower: 4b, power: [%fd,%fd,%fd], Motion: [%fd,%fd,%fd]}' + , fbv:0, fbv:1, fbv:2, playerM:0, playerM:1, playerM:2))); + gamemode = myself ~ 'gamemode'; + if(rm && (gamemode == 'survival' || gamemode == 'adventure'), + inventory_remove(myself, 'fire_charge'); + ); + return(true); +); + +__on_player_uses_item(myself, item_tuple, hand) -> ( + if(item_tuple:0 == 'fire_charge', + shoot_fireball(myself, true); + ); +); + +__on_player_releases_item(myself, item_tuple, hand) -> ( + if(!query(myself, 'has_scoreboard_tag', 'ica.spyglass_fireball'), ( + return(); + )); + if(item_tuple:0 == 'spyglass', + shoot_fireball(myself, false); + ); +); diff --git a/src/ica-goal.sc b/src/ica-goal.sc new file mode 100644 index 0000000..b5c14f1 --- /dev/null +++ b/src/ica-goal.sc @@ -0,0 +1,52 @@ +__config() -> { + 'scope' -> 'global', + 'command_permission' -> 'ops', + 'commands' -> { + '' -> 'cmdList', + 'list' -> 'cmdList', + 'set ' -> 'cmdSet', + 'add ' -> 'cmdSetAppend', + }, + 'arguments' -> { + 'slot' -> { 'type' -> 'int', 'min' -> 0, 'max' -> 5 + , 'suggest' -> [0, 1, 2, 3, 4, 5] }, + 'item' -> { 'type' -> 'item' } + } +}; + +getFirstUnsetGoal() -> ( + c_for(i = 0, i <= 5, i = i + 1, ( + p = nbt_storage('ica:data'):str('Goals[{Slot: %db}]', i); + if(p == null, ( + return(i); + )) + )); + return(6); +); + +cmdList() -> ( + print('please use /ica instead'); + run('/ica'); +); + +cmdSet(slot_id, goal_item_tuple) -> ( + if(nbt_storage('ica:data'):'Started', ( + print('Already started, use /ica-admin reset clear to cancel.'); + return(false) + )); + pkey = str('Goals[{Slot: %db}]', slot_id); + etag = nbt(str('{Slot: %db, Item: "%s"}', slot_id, goal_item_tuple:0)); + + if(nbt_storage('ica:data'):pkey != null, delete(nbt_storage('ica:data'):pkey)); + put(nbt_storage('ica:data'), 'Goals', etag, -1); + print(str('Goal #%d set to %s.', slot_id, goal_item_tuple:0)) +); + +cmdSetAppend(goal_item_tuple) -> ( + missing_goal = getFirstUnsetGoal(); + if(missing_goal <= 5, ( + cmdSet(missing_goal, goal_item_tuple) + ), ( + print('All are goals set, please specify slot.') + )); +); diff --git a/src/ica-settings.sc b/src/ica-settings.sc new file mode 100644 index 0000000..b5c14f1 --- /dev/null +++ b/src/ica-settings.sc @@ -0,0 +1,52 @@ +__config() -> { + 'scope' -> 'global', + 'command_permission' -> 'ops', + 'commands' -> { + '' -> 'cmdList', + 'list' -> 'cmdList', + 'set ' -> 'cmdSet', + 'add ' -> 'cmdSetAppend', + }, + 'arguments' -> { + 'slot' -> { 'type' -> 'int', 'min' -> 0, 'max' -> 5 + , 'suggest' -> [0, 1, 2, 3, 4, 5] }, + 'item' -> { 'type' -> 'item' } + } +}; + +getFirstUnsetGoal() -> ( + c_for(i = 0, i <= 5, i = i + 1, ( + p = nbt_storage('ica:data'):str('Goals[{Slot: %db}]', i); + if(p == null, ( + return(i); + )) + )); + return(6); +); + +cmdList() -> ( + print('please use /ica instead'); + run('/ica'); +); + +cmdSet(slot_id, goal_item_tuple) -> ( + if(nbt_storage('ica:data'):'Started', ( + print('Already started, use /ica-admin reset clear to cancel.'); + return(false) + )); + pkey = str('Goals[{Slot: %db}]', slot_id); + etag = nbt(str('{Slot: %db, Item: "%s"}', slot_id, goal_item_tuple:0)); + + if(nbt_storage('ica:data'):pkey != null, delete(nbt_storage('ica:data'):pkey)); + put(nbt_storage('ica:data'), 'Goals', etag, -1); + print(str('Goal #%d set to %s.', slot_id, goal_item_tuple:0)) +); + +cmdSetAppend(goal_item_tuple) -> ( + missing_goal = getFirstUnsetGoal(); + if(missing_goal <= 5, ( + cmdSet(missing_goal, goal_item_tuple) + ), ( + print('All are goals set, please specify slot.') + )); +); diff --git a/src/ica.sc b/src/ica.sc new file mode 100644 index 0000000..6d9477f --- /dev/null +++ b/src/ica.sc @@ -0,0 +1,133 @@ +__config() -> { + 'command_permission' -> 'ops', + 'commands' -> { + '' -> 'cmdList', + 'list' -> 'cmdList', + 'submit ' -> 'cmdSubmit', + 'refill' -> 'cmdRefill', + 'seed' -> 'cmdSeed', + 'me' -> 'cmdMe', + }, + 'arguments' -> { + 'slot' -> { 'type' -> 'int', 'min' -> 0, 'max' -> 5 + , 'suggest' -> [0, 1, 2, 3, 4, 5] }, + 'item' -> { 'type' -> 'item' } + } +}; + +tm_total() -> ( + 72000 +); + +tm_per_goal() -> ( + 12000 +); + +cmdSeed() -> ( + print(str('%s: %d', system_info('world_name'), system_info('world_seed'))); +); + +cmdRefill() -> ( + if(!nbt_storage('ica:data'):'Started', ( + print('Not started. use /ica-admin confirm to start.'); + return(false) + )); + if(!query(p, 'has_scoreboard_tag', 'ica.flyer'), ( + print('You cannot fly.'); + return(false) + )); + run('give @s minecraft:firework_rocket 64'); +); + +cmdList() -> ( + if(nbt_storage('ica:data'):'Started', ( + if(!nbt_storage('ica:data'):'Preparing', ( + print(str('Collecting, %d seconds left, %d are goals done:', + bossbar('ica:time_counter', 'value') / 20, + bossbar('ica:collected', 'value'))); + ), ( + print(str('Perparing, %d seconds to collect:' + , bossbar('ica:prepare_counter', 'value') / 20)); + )); + ), ( + print('Pending:'); + )); + + c_for(i = 0, i <= 5, i = i + 1, ( + p = nbt_storage('ica:data'):str('Goals[{Slot: %db}]', i); + if(p == null, ( + print(str('- #%d: unset', i)); + ), ( + print(str('%s #%d: %s(%s)', if(nbt_storage('ica:data'):'Started' && p:'Completed', '+', '-') + , i, item_display_name(p:'Item'), p:'Item')) + )) + )); +); + +cmdMe() -> ( + if(!nbt_storage('ica:data'):'Started', ( + print('Not started. use /ica-admin confirm to start.'); + return(false) + )); + myself = player(); + career_hints = { + 'Bystander' -> 'You have nothing to do, just watch.', + 'Piggy' -> 'Complete all goals in time to win!', + 'Hunter' -> 'Protect piggies and kill the wolf.', + 'Wolf' -> 'Stop them complete the goals!', + }; + career = 'Bystander'; + + if(query(myself, 'has_scoreboard_tag', 'ica.piggy'), ( + career = 'Piggy'; + )); + if(query(myself, 'has_scoreboard_tag', 'ica.hunter'), ( + career = 'Hunter'; + )); + if(query(myself, 'has_scoreboard_tag', 'ica.wolf'), ( + career = 'Wolf'; + )); + print(str('You are "%s": %s', career, career_hints:career)); + + if(query(myself, 'has_scoreboard_tag', 'ica.voter'), ( + print('[ability] voter: you can vote.'); + )); + if(query(myself, 'has_scoreboard_tag', 'ica.flyer'), ( + print('[ability] flyer: you can fly with an elt.'); + )); + if(query(myself, 'has_scoreboard_tag', 'ica.spyglasser'), ( + print('[ability] spyglasser: You can shoot fireballs with a spyglass(except in prepare stage).'); + )); + // if(query(myself, 'has_scoreboard_tag', 'ica.kungfu_master'), ( + // print('[ability] kungfu master: You can get a temporary slow-falling effect by using a feather.'); + // )); +); + +cmdSubmit(slot_id) -> ( + if(!nbt_storage('ica:data'):'Started', ( + print('Not started. use /ica-admin confirm to start.'); + return(false) + )); + if(nbt_storage('ica:data'):'Preparing', ( + print('Currently preparing, please submit later.'); + return(false) + )); + + pkey = str('Goals[{Slot: %db}]', slot_id); + if(nbt_storage('ica:data'):pkey:'Completed', ( + print(str('%s has already been collected.', item_display_name( + nbt_storage('ica:data'):pkey:'Item'))); + return() + )); + me = player(); + if(inventory_remove(me, nbt_storage('ica:data'):pkey:'Item', 1) == 0, ( + print(str('%s not found.', item_display_name( + nbt_storage('ica:data'):pkey:'Item'))); + return() + )); + put(nbt_storage('ica:data'):(pkey+'.Completed'), '1b'); + iv = bossbar('ica:collected', 'value') + 1; + print(iv); + bossbar('ica:collected', 'value', iv); + print('OK.'); +);