Made tools an enum

Renamed key mode to god mode
Fixed sign visibility
Exposed selected tool to scripts
Exposed flying state to scripts
This commit is contained in:
Scott Wadden 2022-05-27 01:38:36 -03:00
parent 58885a8a74
commit 34f229988d
20 changed files with 147 additions and 140 deletions

View File

@ -332,6 +332,14 @@ proc new_markdown_sign_impl(self: ScriptController,
self.map_unit(result, pnode)
unit.units.add(result)
proc reset(self: Unit, clear: bool) =
if clear:
if self of Build: Build(self).reset()
elif self of Bot: Bot(self).reset()
else:
if self of Build: Build(self).reset_state()
elif self of Bot: Bot(self).reset_state()
# Bot bindings
proc play(self: Bot, animation_name: string) =
@ -372,12 +380,6 @@ proc save(self: Build, name: string) =
proc restore(self: Build, name: string) =
(self.draw_transform, self.color.value, self.drawing) = self.save_points[name]
proc reset(self: Build, clear: bool) =
if clear:
self.reset()
else:
self.reset_state()
# Player binding
proc playing(self: Unit): bool =
@ -386,11 +388,23 @@ proc playing(self: Unit): bool =
proc `playing=`*(self: Unit, value: bool) =
state.set_flag Playing, value
proc key(self: Unit): bool =
Key in state.flags
proc god(self: Unit): bool =
God in state.flags
proc `key=`*(self: Unit, value: bool) =
state.set_flag Key, value
proc `god=`*(self: Unit, value: bool) =
state.set_flag God, value
proc flying(self: Unit): bool =
Flying in state.flags
proc `flying=`*(self: Unit, value: bool) =
state.set_flag Flying, value
proc tool(self: Unit): int =
int(state.tool.value)
proc `tool=`(self: Unit, value: int) =
state.tool.value = Tools(value)
# Sign bindings
proc title(self: Sign): string =
@ -691,7 +705,7 @@ proc init*(T: type ScriptController): ScriptController =
global, `global=`, position, local_position, rotation, `rotation=`, id,
glow, `glow=`, speed, `speed=`, scale, `scale=`, velocity, `velocity=`,
active_unit, color, `color=`, seen, start_position, wake, frame_count,
write_stack_trace, show, `show=`, frame_created, lock, `lock=`
write_stack_trace, show, `show=`, frame_created, lock, `lock=`, reset
result.bind_procs "base_bridge_private",
link_dependency_impl, action_running, `action_running=`, yield_script,
@ -701,14 +715,14 @@ proc init*(T: type ScriptController): ScriptController =
play, all_bots
result.bind_procs "builds",
drawing, `drawing=`, initial_position, save, restore, reset, all_builds
drawing, `drawing=`, initial_position, save, restore, all_builds
result.bind_procs "signs",
markdown, `markdown=`, title, `title=`, height, `height=`, width, `width=`,
size, `size=`, open, `open=`
result.bind_procs "players",
playing, `playing=`, key, `key=`
playing, `playing=`, god, `god=`, flying, `flying=`, tool, `tool=`
when is_main_module:
state.config.lib_dir = current_source_path().parent_dir / ".." / ".." / "vmlib"

View File

@ -1,5 +1,5 @@
import std / [monotimes, times, os, jsonutils, json, math]
import pkg / [godot, model_citizen]
import pkg / [godot, model_citizen, zippy / ziparchives]
import godotapi / [input, input_event, gd_os, node, scene_tree,
packed_scene, sprite, control, viewport, viewport_texture,
performance, label, theme, dynamic_font, resource_loader, main_loop,
@ -13,7 +13,7 @@ type
dock_icon_size: Option[float]
world: Option[string]
show_stats: Option[bool]
key: Option[bool]
god_mode: Option[bool]
mega_pixels: Option[float]
start_full_screen: Option[bool]
semicolon_as_colon: Option[bool]
@ -30,7 +30,7 @@ gdobj Game of Node:
triggered = false
saved_mouse_captured_state = false
stats: Label
last_index = 1
last_tool = state.tool.value
saved_mouse_position: Vector2
scale_factor* = 0.0
rescale_at = get_mono_time()
@ -144,7 +144,7 @@ gdobj Game of Node:
semicolon_as_colon = uc.semicolon_as_colon ||= false
lib_dir = join_path(get_executable_path().parent_dir(), "..", "..", "..", "vmlib")
state.set_flag(Key, uc.key ||= false)
state.set_flag(God, uc.god_mode ||= false)
self.prepare_to_load_world()
set_window_fullscreen config.start_full_screen
@ -223,18 +223,13 @@ gdobj Game of Node:
state.push_flag MouseCaptured
proc update_action_index*(change: int) =
state.action_index += change
if state.action_index < 0:
state.action_index = state.action_count
self.obj_mode(state.action_index)
if state.action_index == 0:
self.code_mode()
elif state.action_index == state.action_count:
self.obj_mode(state.action_index)
elif state.action_index > state.action_count:
self.code_mode()
else:
self.block_mode(state.action_index)
var index = int(state.tool.value) + change
if index < 0:
index = int Tools.high
elif index > int Tools.high:
index = int Tools.low
state.tool.value = Tools(index)
proc next_action*() =
self.update_action_index(1)
@ -242,28 +237,6 @@ gdobj Game of Node:
proc prev_action*() =
self.update_action_index(-1)
proc code_mode*(update_actionbar = true, restore = false) =
if restore and state.action_index == 0:
self.block_mode(self.last_index)
else:
state.tool.value = Code
state.action_index = 0
if update_actionbar:
self.trigger("update_actionbar", 0)
proc block_mode*(index: int, update_actionbar = true) =
self.last_index = index
state.tool.value = Block
state.action_index = index
if update_actionbar:
self.trigger("update_actionbar", index)
proc obj_mode*(index: int, update_actionbar = true) =
state.tool.value = Place
state.action_index = index
if update_actionbar:
self.trigger("update_actionbar", index)
method on_size_changed() =
self.rescale_at = get_mono_time()
@ -339,22 +312,26 @@ gdobj Game of Node:
self.get_tree().set_input_as_handled()
if event.is_action_pressed("toggle_code_mode"):
self.code_mode(restore = true)
if state.tool.value != CodeMode:
self.last_tool = state.tool.value
state.tool.value = CodeMode
else:
state.tool.value = self.last_tool
elif event.is_action_pressed("mode_1"):
self.code_mode()
state.tool.value = CodeMode
elif event.is_action_pressed("mode_2"):
self.block_mode(1)
state.tool.value = BlueBlock
elif event.is_action_pressed("mode_3"):
self.block_mode(2)
state.tool.value = RedBlock
elif event.is_action_pressed("mode_4"):
self.block_mode(3)
state.tool.value = GreenBlock
elif event.is_action_pressed("mode_5"):
self.block_mode(4)
state.tool.value = BlackBlock
elif event.is_action_pressed("mode_6"):
self.block_mode(5)
state.tool.value = WhiteBlock
elif event.is_action_pressed("mode_7"):
self.block_mode(6)
state.tool.value = BrownBlock
elif event.is_action_pressed("mode_8"):
self.obj_mode(7)
state.tool.value = PlaceBot
proc get_game*(): Game = Game(state.nodes.game)

View File

@ -45,8 +45,11 @@ proc bot_at*(state: GameState, position: Vector3): Bot =
if unit of Bot and unit.transform.origin == position:
return Bot(unit)
method reset*(self: Bot) =
proc reset_state*(self: Bot) =
self.transform.value = self.start_transform
method reset*(self: Bot) =
self.reset_state
self.speed = 1
self.color.value = self.start_color
self.animation.value = "auto"
@ -82,7 +85,7 @@ proc init*(_: type Bot, id = "bot_" & generate_id(), transform = Transform.init,
self.flags.changes:
if Hover.added:
state.push_flag ReticleVisible
if state.tool.value != Block:
if state.tool.value in {CodeMode, PlaceBot}:
let root = self.find_root(true)
root.walk_tree proc(unit: Unit) = unit.flags += Highlight
elif Hover.removed:
@ -93,10 +96,10 @@ proc init*(_: type Bot, id = "bot_" & generate_id(), transform = Transform.init,
self.state_zids.add:
state.flags.changes:
if Hover in self.flags:
if PrimaryDown.added and state.tool.value == Code:
if PrimaryDown.added and state.tool.value == CodeMode:
let root = self.find_root(true)
state.open_unit.value = root
if SecondaryDown.added and state.tool.value == Place:
if SecondaryDown.added and state.tool.value == PlaceBot:
if self.parent.is_nil:
state.units -= self
else:

View File

@ -177,7 +177,7 @@ proc drop_block(self: Build) =
self.draw(p, (Computed, self.color.value))
proc remove(self: Build) =
if state.tool.value == Block:
if state.tool.value notin {CodeMode, PlaceBot}:
state.skip_block_paint = true
draw_normal = self.target_normal
let point = self.target_point - self.target_normal - (self.target_normal.inverse_normalized * 0.5)
@ -193,19 +193,19 @@ proc remove(self: Build) =
proc fire(self: Build) =
let global_point = self.node.to_global(self.target_point)
if state.tool.value == Block:
if state.tool.value notin {CodeMode, PlaceBot}:
state.skip_block_paint = true
draw_normal = self.target_normal
let point = (self.target_point + (self.target_normal * 0.5)).floor
skip_point = self.target_point + self.target_normal
last_point = self.target_point
self.draw(point, (Manual, state.selected_color))
elif state.tool.value == Place and EditorVisible in state.flags and
elif state.tool.value == PlaceBot and EditorVisible in state.flags and
state.bot_at(global_point).is_nil:
let transform = Transform.init(origin = global_point)
state.units += Bot.init(transform = transform)
elif state.tool.value == Code:
elif state.tool.value == CodeMode:
let root = self.find_root(true)
state.open_unit.value = root
@ -346,7 +346,7 @@ proc init*(_: type Build, id = "build_" & generate_id(), transform = Transform.i
self.flags += Visible
self.reset()
self.flags.changes:
if Hover.added and state.tool.value == Code:
if Hover.added and state.tool.value == CodeMode:
if Playing notin state.flags:
let root = self.find_root(true)
root.walk_tree proc(unit: Unit) = unit.flags += Highlight
@ -365,7 +365,7 @@ proc init*(_: type Build, id = "build_" & generate_id(), transform = Transform.i
elif PrimaryDown in state.flags:
self.fire
if change.item in {TargetMoved, Hover} and state.tool.value == Place:
if change.item in {TargetMoved, Hover} and state.tool.value == PlaceBot:
if self.target_normal == UP:
state.push_flag BlockTargetVisible
else:

View File

@ -9,7 +9,7 @@ proc fire(self: Ground, append = false) =
state.draw_unit_id = "ground"
var add_to {.global.}: Build
let point = (self.target_point - vec3(0.5, 0, 0.5)).trunc
if state.tool.value == Block:
if state.tool.value notin {CodeMode, PlaceBot}:
if not append:
add_to = state.units.find_first(point.surrounding)
if add_to:
@ -19,7 +19,7 @@ proc fire(self: Ground, append = false) =
add_to = Build.init(transform = Transform.init(origin = point), global = true, color = state.selected_color)
state.units += add_to
elif state.tool.value == Place and state.bot_at(self.target_point).is_nil:
elif state.tool.value == PlaceBot and state.bot_at(self.target_point).is_nil:
var t = Transform.init(origin = self.target_point)
state.units += Bot.init(transform = t)

View File

@ -18,7 +18,7 @@ proc resolve_flags(self: GameState) =
result.excl f
result.incl flag
if self.tool.value == Code:
if self.tool.value == CodeMode:
for flag in groups[1]:
result.excl(flag)
result.incl(ReticleVisible)
@ -81,7 +81,7 @@ proc `-=`*(self: ZenSet[StateFlags], flag: StateFlags) {.error:
"Use `push_flag`, `pop_flag` and `replace_flag`".}
proc selected_color*(self: GameState): Color =
action_colors[Colors(self.action_index)]
action_colors[Colors(ord self.tool.value)]
proc debug*(self: GameState, args: varargs[string, `$`]) =
self.logger("debug", args.join)
@ -92,15 +92,13 @@ proc info*(self: GameState, args: varargs[string, `$`]) =
proc err*(self: GameState, args: varargs[string, `$`]) =
self.logger "err", args.join
proc init*(_: type GameState, action_count = 0, action_index = 0): GameState =
proc init*(_: type GameState): GameState =
let self = GameState(
flags: Zen.init(set[StateFlags]),
units: Zen.init(seq[Unit]),
action_count: action_count,
action_index: action_index,
open_unit: ZenValue[Unit].init,
config: Config(font_size: Zen.init(0)),
tool: Zen.init(Block),
tool: Zen.init(BlueBlock),
gravity: -80.0,
console: ConsoleModel(log: Zen.init(seq[string])),
open_sign: ZenValue[Sign].init
@ -125,9 +123,9 @@ proc init*(_: type GameState, action_count = 0, action_index = 0): GameState =
result = self
proc active*(_: type GameState, new_state = false): GameState =
var instance {.global.} = GameState.init(action_count = 7, action_index = 1)
var instance {.global.} = GameState.init
if new_state:
instance = GameState.init(action_count = 7, action_index = 1)
instance = GameState.init
result = instance
when is_main_module:

View File

@ -15,14 +15,15 @@ type
CommandMode, EditorVisible, ConsoleVisible,
BlockTargetVisible, ReticleVisible, DocsVisible, MouseCaptured,
PrimaryDown, SecondaryDown, EditorFocused, ConsoleFocused, DocsFocused,
Playing, Flying, Key
Playing, Flying, God
Tools* = enum
CodeMode, BlueBlock, RedBlock, GreenBlock, BlackBlock, WhiteBlock,
BrownBlock, PlaceBot
ModelFlags* = enum
Hover, TargetMoved, Highlight, Global, Visible, Lock
Tools* = enum
Code, Block, Place
ConsoleModel* = ref object
log*: ZenSeq[string]
@ -31,8 +32,6 @@ type
wants*: OrderedSet[StateFlags]
config*: Config
open_unit*: ZenValue[Unit]
action_index*: int
action_count*: int
tool*: ZenValue[Tools]
gravity*: float
nodes*: tuple[

View File

@ -40,7 +40,7 @@ gdobj AimTarget of Sprite3D:
self.target_model.flags -= Hover
state.pop_flag BlockTargetVisible
self.target_model = unit
if unit != nil and (Key in state.flags or Lock notin unit.flags):
if unit != nil and (God in state.flags or Lock notin unit.flags):
state.push_flag BlockTargetVisible
unit.flags += Hover

View File

@ -54,7 +54,7 @@ gdobj BotNode of KinematicBody:
if Visible in self.model.flags:
self.visible = true
self.set_color(color)
elif Visible notin self.model.flags and Key in state.flags:
elif Visible notin self.model.flags and God in state.flags:
self.visible = true
color.a = 0.0
SpatialMaterial(self.material).albedo_color = color
@ -79,7 +79,7 @@ gdobj BotNode of KinematicBody:
self.model.state_zids.add:
state.flags.changes:
if change.item == Key:
if change.item == God:
self.set_visibility
var velocity_zid: ZID

View File

@ -88,7 +88,7 @@ gdobj BuildNode of VoxelTerrain:
for material in self.model.shared.materials:
material.shader = shader
elif Visible notin self.model.flags and Key in state.flags:
elif Visible notin self.model.flags and God in state.flags:
self.visible = true
for material in self.model.shared.materials:
@ -124,7 +124,7 @@ gdobj BuildNode of VoxelTerrain:
self.model.state_zids.add:
state.flags.changes:
if change.item == Key:
if change.item == God:
self.set_visibility
self.model.scale.changes:

View File

@ -22,10 +22,8 @@ proc handle_collisions(self: Player, collisions: seq[KinematicCollision]) {.inli
model.off_collision(self)
self.colliders = colliders
let
state = GameState.active
config = state.config
angle_x_min = -PI / 2.25
angle_x_max = PI / 2.25
max_speed = 100.0
@ -161,7 +159,7 @@ gdobj PlayerNode of KinematicBody:
self.camera_rig.rotation = r
self.unit.rotation.pause(self.rotation_zid):
self.unit.rotation.value = rad_to_deg r.y
let ray_length = if state.tool.value == Code: 200.0 else: 100.0
let ray_length = if state.tool.value == CodeMode: 200.0 else: 100.0
if MouseCaptured notin state.flags:
let
mouse_pos = self.get_viewport().
@ -299,7 +297,9 @@ gdobj PlayerNode of KinematicBody:
elif event.is_action_released("run"):
self.running = self.always_run
if event of InputEventPanGesture and state.tool.value == Block:
if event of InputEventPanGesture and
state.tool.value notin {CodeMode, PlaceBot}:
let pan = event as InputEventPanGesture
self.pan_delta += pan.delta.y
if self.pan_delta > 2:

View File

@ -1,6 +1,7 @@
import pkg / [godot, model_citizen]
import godotapi / [spatial, resource_loader, packed_scene, collision_shape,
mesh_instance, quad_mesh, spatial_material, viewport]
mesh_instance, quad_mesh, spatial_material, viewport,
style_box_flat]
import ui / markdown_label, models / [types, signs]
import core, models / [states]
@ -9,12 +10,17 @@ let state = GameState.active
gdobj SignNode of Spatial:
var model*: Sign
var zid: ZID
var material: SpatialMaterial
proc process*(delta: float) =
if self.model and Visible notin self.model.flags and Key in state.flags and
(not self.visible or state.frame_count mod 3 == 0):
self.visible = not self.visible
proc set_visibility =
if Visible in self.model.flags:
self.visible = true
self.material.params_blend_mode = spatial_material.BLEND_MODE_MIX
elif Visible notin self.model.flags and God in state.flags:
self.visible = true
self.material.params_blend_mode = spatial_material.BLEND_MODE_ADD
else:
self.visible = false
proc setup* =
var
@ -23,7 +29,7 @@ gdobj SignNode of Spatial:
mesh = self.find_node("MeshInstance") as MeshInstance
viewport = self.find_node("Viewport") as Viewport
quad = mesh.mesh as QuadMesh
material = mesh.get_active_material(0) as SpatialMaterial
self.material = mesh.get_active_material(0) as SpatialMaterial
proc resize =
var
@ -36,14 +42,16 @@ gdobj SignNode of Spatial:
t.origin.x = self.model.width / -2 + 0.5
t.origin.y = self.model.height / -2 + 0.5
mesh.transform = t
viewport.size = size
label.rect_size = size
label.size = self.model.size
var stylebox = label.og_label.get_stylebox("normal") as StyleBoxFlat
stylebox.content_margin_left = 80 / self.model.width
label.size = int(float(self.model.size) / self.model.width)
resize()
material.params_billboard_mode =
self.material.params_billboard_mode =
if self.model.billboard:
BILLBOARD_FIXED_Y
else:
@ -60,7 +68,7 @@ gdobj SignNode of Spatial:
self.model.glow.changes:
if added:
material.emission_energy = change.item
self.material.emission_energy = change.item
self.transform = self.model.transform.value
self.model.transform.changes:
@ -68,15 +76,14 @@ gdobj SignNode of Spatial:
self.transform = change.item
self.model.flags.changes:
if Visible.added:
self.visible = true
elif Visible.removed:
self.visible = false
if change.item == Visible:
self.set_visibility
self.model.state_zids.add:
state.flags.changes:
if Key.removed:
self.visible = Visible in self.model.flags
if God.removed:
self.set_visibility
let sign_scene = load("res://components/SignNode.tscn") as PackedScene
proc init*(_: type SignNode): SignNode =

View File

@ -26,7 +26,7 @@ gdobj MarkdownLabel of ScrollContainer:
current_label: RichTextLabel
container: Node
og_text_edit: TextEdit
og_label: RichTextLabel
og_label*: RichTextLabel
og_text_edit_color: Color
og_label_color: Color
needs_margin = false

View File

@ -15,10 +15,10 @@ gdobj Toolbar of HBoxContainer:
objects = @["bot"]
preview_result: Option[PreviewResult]
waiting = false
zid: ZID
method ready*() =
self.bind_signals self, "action_changed"
self.bind_signals "update_actionbar"
self.preview_maker = self.get_node("../PreviewMaker") as PreviewMaker
assert not self.preview_maker.is_nil
@ -28,6 +28,11 @@ gdobj Toolbar of HBoxContainer:
if Playing.removed:
self.visible = true
self.zid = state.tool.changes:
if added:
let b = self.get_child(int(change.item)) as Button
b.set_pressed true
method process*(delta: float) =
if self.preview_result.is_some:
let
@ -50,17 +55,14 @@ gdobj Toolbar of HBoxContainer:
self.preview_maker.generate_object_preview obj, proc(preview: Image) =
self.preview_result = some (color: obj, preview: preview)
method on_update_actionbar(index: int) =
let b = self.get_child(index) as Button
b.set_pressed true
method on_action_changed*(button_name: string) =
case button_name[7..^1]:
of "code": get_game().code_mode(update_actionbar = false)
of "blue": get_game().block_mode(1, update_actionbar = false)
of "red": get_game().block_mode(2, update_actionbar = false)
of "green": get_game().block_mode(3, update_actionbar = false)
of "black": get_game().block_mode(4, update_actionbar = false)
of "white": get_game().block_mode(5, update_actionbar = false)
of "brown": get_game().block_mode(6, update_actionbar = false)
of "bot": get_game().obj_mode(7, update_actionbar = false)
state.tool.pause(self.zid):
case button_name[7..^1]:
of "code": state.tool.value = CodeMode
of "blue": state.tool.value = BlueBlock
of "red": state.tool.value = RedBlock
of "green": state.tool.value = GreenBlock
of "black": state.tool.value = BlackBlock
of "white": state.tool.value = WhiteBlock
of "brown": state.tool.value = BrownBlock
of "bot": state.tool.value = PlaceBot

View File

@ -169,7 +169,7 @@ type NegativeNode = ref object
proc `-`*(node: Unit): NegativeNode =
NegativeNode(node: node)
proc angle_to(self: Unit, enu_target: Unit): float =
proc angle_to*(self: Unit, enu_target: Unit): float =
let
p1 = self.position
p2 = enu_target.position
@ -417,7 +417,6 @@ proc go*(unit: Unit) =
proc even*(self: int): bool = self mod 2 == 0
proc odd*(self: int): bool = not self.even
proc md*(self: Unit,
markdown: string, title = "", width = 1.0, height = 1.0, size = 32,
zoomable = true, billboard = false): Sign {.discardable.} =
@ -426,9 +425,11 @@ proc md*(self: Unit,
self.new_markdown_sign_impl(result, markdown, title, width, height, size,
zoomable, billboard)
template md*(
markdown: string, title = "", height = 1.0, width = 1.0, size = 32,
zoomable = true, billboard = false
): Sign =
template md*(markdown: string,
title = "", height = 1.0, width = 1.0, size = 32, zoomable = true,
billboard = false): Sign =
enu_target.md(markdown, title, width, height, size, zoomable, billboard)
template reset*(clear = false) =
enu_target.reset(clear)

View File

@ -32,6 +32,7 @@ proc `show=`*(self: Unit, value: bool) = discard
proc frame_created*(self: Unit): int = discard
proc lock*(self: Unit): bool = discard
proc `lock=`*(self: Unit, value: bool) = discard
proc reset*(self: Unit, clear = false) = discard
# TODO: These should be in base_bridge_private, but are currently needed outside of base_api.
proc echo_console*(msg: string) = discard

View File

@ -26,5 +26,3 @@ proc fill_square*(self: Build, length = 1) =
proc save*(self: Build, name = "default") = discard
proc restore*(self: Build, name = "default") = discard
proc reset*(self: Build, clear = false) = discard

View File

@ -8,6 +8,3 @@ proc save*(name = "default") =
proc restore*(name = "default") =
Build(active_unit()).restore(name)
proc reset*(clear = false) =
Build(active_unit()).reset(clear)

View File

@ -3,8 +3,14 @@ import types, base_api
let player* = PlayerType()
register_active(player)
proc tool*(self: PlayerType): Tools = discard
proc `tool=`*(self: PlayerType, value: Tools) = discard
proc playing*(self: PlayerType): bool = discard
proc `playing=`*(self: PlayerType, value: bool) = discard
proc key*(self: PlayerType): bool = discard
proc `key=`*(self: PlayerType, value: bool) = discard
proc flying*(self: PlayerType): bool = discard
proc `flying=`*(self: PlayerType, value: bool) = discard
proc god*(self: PlayerType): bool = discard
proc `god=`*(self: PlayerType, value: bool) = discard

View File

@ -48,6 +48,10 @@ type
states*: Table[string, NimNode]
from_states*: seq[(string, NimNode)]
Tools* = enum
CodeMode, BlueBlock, RedBlock, GreenBlock, BlackBlock, WhiteBlock,
BrownBlock, PlaceBot
proc vec3*(x, y, z: float): Vector3 {.inline.} = (x:x, y:y, z:z)
const