mirror of https://github.com/dsrw/enu.git
Added `?` operator to convert to bool.
Moved types file to project root.
This commit is contained in:
parent
c38ac7e72d
commit
2cacc78442
|
@ -0,0 +1,11 @@
|
|||
type
|
||||
type ScriptController = ref object
|
||||
retry_failures*: bool
|
||||
interpreter: Interpreter
|
||||
module_names: HashSet[string]
|
||||
active_unit: Unit
|
||||
unit_map: Table[PNode, Unit]
|
||||
node_map: Table[Unit, PNode]
|
||||
failed: seq[tuple[unit: Unit, e: ref VMQuit]]
|
||||
|
||||
NodeController* = ref object
|
|
@ -1,11 +1,8 @@
|
|||
import std / [strutils, os, tables]
|
||||
import pkg / [model_citizen, print]
|
||||
import pkg / [print]
|
||||
import pkg/godot except print
|
||||
import godotapi / [node, spatial]
|
||||
import models, nodes / [bot_node, build_node, sign_node]
|
||||
|
||||
type
|
||||
NodeController* = ref object
|
||||
import core, models, nodes / [bot_node, build_node, sign_node]
|
||||
|
||||
let state = GameState.active
|
||||
|
||||
|
@ -23,9 +20,9 @@ proc remove_from_scene(unit: Unit) =
|
|||
if unit of Build: Build(unit).untrack_all
|
||||
elif unit of Bot: Bot(unit).untrack_all
|
||||
elif unit of Sign: Sign(unit).untrack_all
|
||||
if unit.script_ctx:
|
||||
if ?unit.script_ctx:
|
||||
unit.script_ctx.callback = nil
|
||||
if not state.reloading and not unit.clone_of:
|
||||
if not state.reloading and not ?unit.clone_of:
|
||||
remove_file unit.script_file
|
||||
remove_dir unit.data_dir
|
||||
for child in unit.units:
|
||||
|
|
|
@ -1,25 +1,21 @@
|
|||
import std /
|
||||
import std /
|
||||
[os, macros, sugar, sets, strutils, times, monotimes, sequtils, importutils,
|
||||
tables, options, math, re]
|
||||
import pkg / [print, model_citizen, godot]
|
||||
import pkg / [print, godot]
|
||||
import pkg / compiler / vm except get_int
|
||||
import pkg / compiler / ast except new_node
|
||||
import pkg / compiler / [vmdef, lineinfos, astalgo, renderer, msgs]
|
||||
import godotapi / [spatial, ray_cast, voxel_terrain]
|
||||
import core, models /
|
||||
[types, states, bots, builds, units, colors, signs, serializers]
|
||||
import core, models /
|
||||
[states, bots, builds, units, colors, signs]
|
||||
import libs / [interpreters, eval]
|
||||
import nodes / [helpers, build_node]
|
||||
import nodes / [build_node]
|
||||
|
||||
from pkg/compiler/vm {.all.} import stack_trace_aux
|
||||
|
||||
type ScriptController* = ref object
|
||||
interpreter: Interpreter
|
||||
module_names: HashSet[string]
|
||||
active_unit: Unit
|
||||
unit_map: Table[PNode, Unit]
|
||||
node_map: Table[Unit, PNode]
|
||||
retry_failures*: bool
|
||||
failed: seq[tuple[unit: Unit, e: ref VMQuit]]
|
||||
proc retry_failed_scripts*(self: ScriptController)
|
||||
|
||||
import models / serializers
|
||||
|
||||
include script_controllers/bindings
|
||||
|
||||
|
@ -30,6 +26,9 @@ const
|
|||
|
||||
let state = GameState.active
|
||||
|
||||
private_access ScriptController
|
||||
private_access ScriptCtx
|
||||
|
||||
proc map_unit(self: ScriptController, unit: Unit, pnode: PNode) =
|
||||
self.unit_map[pnode] = unit
|
||||
self.node_map[unit] = pnode
|
||||
|
@ -50,7 +49,6 @@ template info: untyped =
|
|||
instantiationInfo(-2, fullPaths = true)
|
||||
|
||||
proc write_stack_trace(self: ScriptController) =
|
||||
private_access ScriptCtx
|
||||
let ctx = self.active_unit.script_ctx
|
||||
msg_writeln(ctx.ctx.config, "stack trace: (most recent call last)", {msgNoUnitSep})
|
||||
stack_trace_aux(ctx.ctx, ctx.tos, ctx.pc)
|
||||
|
@ -75,7 +73,7 @@ proc get_sign(self: ScriptController, a: VmArgs, pos: int): Sign =
|
|||
Sign(unit)
|
||||
|
||||
proc to_node(self: ScriptController, unit: Unit): PNode =
|
||||
if unit:
|
||||
if ?unit:
|
||||
self.node_map[unit]
|
||||
else:
|
||||
ast.new_node(nkNilLit)
|
||||
|
@ -136,7 +134,7 @@ proc sleep_impl(ctx: ScriptCtx, seconds: float) =
|
|||
if seconds > 0 and duration < seconds:
|
||||
Running
|
||||
elif seconds <= 0 and duration <= 0.5 and ctx.timer > get_mono_time():
|
||||
Running
|
||||
Running
|
||||
else:
|
||||
Done
|
||||
ctx.pause()
|
||||
|
@ -331,11 +329,11 @@ proc drop_transform(unit: Unit): Transform =
|
|||
raise ObjectConversionDefect.init("Unknown unit type")
|
||||
|
||||
proc new_markdown_sign_impl(self: ScriptController,
|
||||
unit: Unit, pnode: PNode, markdown: string, title: string, width: float,
|
||||
unit: Unit, pnode: PNode, markdown: string, title: string, width: float,
|
||||
height: float, size: int, zoomable: bool, billboard: bool): Unit =
|
||||
|
||||
result = Sign.init(
|
||||
markdown, title = title, owner = self.active_unit,
|
||||
markdown, title = title, owner = self.active_unit,
|
||||
transform = drop_transform(unit), width = width, height = height,
|
||||
size = size, zoomable = zoomable, billboard = billboard)
|
||||
|
||||
|
@ -417,33 +415,33 @@ proc `tool=`(self: Unit, value: int) =
|
|||
state.tool.value = Tools(value)
|
||||
|
||||
# Sign bindings
|
||||
proc title(self: Sign): string =
|
||||
proc title(self: Sign): string =
|
||||
self.title.value
|
||||
|
||||
proc `title=`(self: Sign, value: string) =
|
||||
proc `title=`(self: Sign, value: string) =
|
||||
self.title.value = value
|
||||
|
||||
proc markdown(self: Sign): string =
|
||||
proc markdown(self: Sign): string =
|
||||
self.markdown.value
|
||||
|
||||
proc `markdown=`(self: Sign, value: string) =
|
||||
proc `markdown=`(self: Sign, value: string) =
|
||||
self.markdown.value = value
|
||||
|
||||
proc width(self: Sign): float =
|
||||
proc width(self: Sign): float =
|
||||
self.width
|
||||
|
||||
proc `width=`(self: Sign, value: float) =
|
||||
self.width = value
|
||||
self.title.touch self.title.value
|
||||
|
||||
proc height(self: Sign): float =
|
||||
proc height(self: Sign): float =
|
||||
self.height
|
||||
|
||||
proc `height=`(self: Sign, value: float) =
|
||||
self.height = value
|
||||
self.title.touch self.title.value
|
||||
|
||||
proc size(self: Sign): int =
|
||||
proc size(self: Sign): int =
|
||||
self.size
|
||||
|
||||
proc `size=`(self: Sign, value: int) =
|
||||
|
@ -474,7 +472,7 @@ proc script_error(self: ScriptController, unit: Unit, e: ref VMQuit) =
|
|||
|
||||
proc advance_unit(self: ScriptController, unit: Unit, delta: float) =
|
||||
let ctx = unit.script_ctx
|
||||
if ctx and ctx.running:
|
||||
if ?ctx and ctx.running:
|
||||
let now = get_mono_time()
|
||||
|
||||
if unit of Build:
|
||||
|
@ -487,14 +485,14 @@ proc advance_unit(self: ScriptController, unit: Unit, delta: float) =
|
|||
while resume_script and not state.paused:
|
||||
resume_script = false
|
||||
|
||||
if ctx.callback == nil or
|
||||
if ctx.callback == nil or
|
||||
(task_state = ctx.callback(delta); task_state in {Done, NextTask}):
|
||||
ctx.timer = MonoTime.high
|
||||
ctx.action_running = false
|
||||
self.active_unit = unit
|
||||
ctx.timeout_at = get_mono_time() + script_timeout
|
||||
ctx.running = ctx.resume()
|
||||
if not ctx.running and not unit.clone_of:
|
||||
if not ctx.running and not ?unit.clone_of:
|
||||
unit.collect_garbage
|
||||
unit.ensure_visible
|
||||
if ctx.running and task_state == NextTask:
|
||||
|
@ -536,7 +534,7 @@ proc load_script(self: ScriptController, unit: Unit, timeout = script_timeout) =
|
|||
if not state.paused:
|
||||
ctx.timeout_at = get_mono_time() + timeout
|
||||
ctx.running = ctx.run()
|
||||
if not ctx.running and not unit.clone_of:
|
||||
if not ctx.running and not ?unit.clone_of:
|
||||
unit.collect_garbage
|
||||
unit.ensure_visible
|
||||
|
||||
|
@ -575,7 +573,7 @@ proc load_script_and_dependants(self: ScriptController, unit: Unit) =
|
|||
self.retry_failures = true
|
||||
|
||||
for other in state.units.value:
|
||||
if other.script_ctx:
|
||||
if ?other.script_ctx:
|
||||
units_by_module[other.script_ctx.module_name] = other
|
||||
|
||||
while units_to_reload != previous:
|
||||
|
@ -602,7 +600,7 @@ proc load_script_and_dependants(self: ScriptController, unit: Unit) =
|
|||
state.dirty_units.clear
|
||||
|
||||
proc change_code(self: ScriptController, unit: Unit, code: string) =
|
||||
if unit.script_ctx and unit.script_ctx.running and not unit.clone_of:
|
||||
if ?unit.script_ctx and unit.script_ctx.running and not ?unit.clone_of:
|
||||
unit.collect_garbage
|
||||
|
||||
var all_edits = unit.shared.edits
|
||||
|
@ -645,11 +643,11 @@ proc watch_units(self: ScriptController, units: ZenSeq[Unit]) =
|
|||
self.watch_code unit
|
||||
self.watch_units unit.units
|
||||
|
||||
if not unit.clone_of and file_exists(unit.script_file):
|
||||
if not ?unit.clone_of and file_exists(unit.script_file):
|
||||
unit.code.value = read_file(unit.script_file)
|
||||
if removed:
|
||||
self.unmap_unit(unit)
|
||||
if not unit.clone_of and unit.script_ctx:
|
||||
if not ?unit.clone_of and ?unit.script_ctx:
|
||||
self.module_names.excl unit.script_ctx.module_name
|
||||
|
||||
proc load_player*(self: ScriptController) =
|
||||
|
@ -677,6 +675,7 @@ proc eval*(self: ScriptController, code: string) =
|
|||
|
||||
proc init*(T: type ScriptController): ScriptController =
|
||||
private_access ScriptCtx
|
||||
private_access ScriptController
|
||||
|
||||
let interpreter = Interpreter.init(state.config.script_dir, state.config.lib_dir)
|
||||
interpreter.config.spell_suggest_max = 0
|
||||
|
@ -699,9 +698,9 @@ proc init*(T: type ScriptController): ScriptController =
|
|||
raise (ref VMQuit)(info: info, msg: msg, location: loc)
|
||||
|
||||
interpreter.register_enter_hook proc(c, pc, tos, instr: auto) =
|
||||
assert controller
|
||||
assert controller.active_unit
|
||||
assert controller.active_unit.script_ctx
|
||||
assert ?controller
|
||||
assert ?controller.active_unit
|
||||
assert ?controller.active_unit.script_ctx
|
||||
|
||||
let ctx = controller.active_unit.script_ctx
|
||||
let info = c.debug[pc]
|
||||
|
@ -731,15 +730,15 @@ proc init*(T: type ScriptController): ScriptController =
|
|||
result.watch_units state.units
|
||||
|
||||
result.bind_procs "base_bridge",
|
||||
register_active, echo_console, new_instance, exec_instance, hit, exit,
|
||||
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,
|
||||
register_active, echo_console, new_instance, exec_instance, hit, exit,
|
||||
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=`, reset,
|
||||
press_action
|
||||
|
||||
result.bind_procs "base_bridge_private",
|
||||
link_dependency_impl, action_running, `action_running=`, yield_script,
|
||||
link_dependency_impl, action_running, `action_running=`, yield_script,
|
||||
begin_turn, begin_move, sleep_impl, `position=impl`, new_markdown_sign_impl
|
||||
|
||||
result.bind_procs "bots",
|
||||
|
|
60
src/core.nim
60
src/core.nim
|
@ -1,3 +1,6 @@
|
|||
import types
|
||||
export types
|
||||
|
||||
const enu_version* = static_exec("git describe --tags HEAD")
|
||||
|
||||
### Sugar ###
|
||||
|
@ -62,15 +65,15 @@ proc `+`*(time: MonoTime, interval: TimeInterval): MonoTime =
|
|||
proc `-`*(time: MonoTime, interval: TimeInterval): MonoTime =
|
||||
time - interval.to_duration
|
||||
|
||||
### ref ###
|
||||
converter to_bool*(self: ref): bool = not self.is_nil
|
||||
|
||||
### options ###
|
||||
import options
|
||||
export options
|
||||
|
||||
# converter to_option*[T](val: T): Option[T] =
|
||||
# some(val)
|
||||
proc `?`*(self: ref): bool = not self.is_nil
|
||||
proc `?`*[T](option: Option[T]): bool = option.is_some
|
||||
proc `?`*(self: SomeNumber): bool = self > 0
|
||||
proc `?`*(self: string): bool = self != ""
|
||||
proc `?`*[T](self: open_array[T]): bool = self.len > 0
|
||||
|
||||
proc `||=`*[T](opt: var Option[T], val: T): T {.discardable.} =
|
||||
if not opt.is_some:
|
||||
|
@ -82,9 +85,6 @@ proc `||=`*[T](opt: var Option[T], val: T): T {.discardable.} =
|
|||
converter from_option*[T](val: Option[T]): T =
|
||||
val.get()
|
||||
|
||||
converter to_bool*[T](option: Option[T]): bool =
|
||||
option.is_some
|
||||
|
||||
proc optional_get*[T](self: var HashSet[T], key: T): Option[T] =
|
||||
if key in self:
|
||||
result = some(self[key])
|
||||
|
@ -185,3 +185,47 @@ when true: # do something here for tests. Godot print crashes without godot.
|
|||
proc p*(args: varargs[string, `$`]) =
|
||||
let msg = args.join
|
||||
godot.print msg
|
||||
|
||||
# misc
|
||||
import pkg / core / transforms
|
||||
export transforms
|
||||
|
||||
import godotapi / [spatial]
|
||||
import pkg / model_citizen
|
||||
export model_citizen except `%`
|
||||
|
||||
proc local_to*(self: Vector3, unit: Unit): Vector3 =
|
||||
result = self
|
||||
var unit = unit
|
||||
while unit != nil:
|
||||
result -= unit.node.transform.origin
|
||||
unit = unit.parent
|
||||
|
||||
proc global_from*(self: Vector3, unit: Unit): Vector3 =
|
||||
result = -self.local_to(unit)
|
||||
|
||||
proc init*(_: type Transform, origin = vec3()): Transform =
|
||||
result = init_transform()
|
||||
result.origin = origin
|
||||
|
||||
proc `+=`*(self: ZenValue[string], str: string) =
|
||||
self.value = self.value & str
|
||||
|
||||
proc origin*(self: ZenValue[Transform]): Vector3 =
|
||||
self.value.origin
|
||||
|
||||
proc `origin=`*(self: ZenValue[Transform], value: Vector3) =
|
||||
var transform = self.value
|
||||
transform.origin = value
|
||||
self.value = transform
|
||||
|
||||
proc basis*(self: ZenValue[Transform]): Basis =
|
||||
self.value.basis
|
||||
|
||||
proc `basis=`*(self: ZenValue[Transform], value: Basis) =
|
||||
var transform = self.value
|
||||
transform.basis = value
|
||||
self.value = transform
|
||||
|
||||
proc init*(_: type Basis): Basis = init_basis()
|
||||
|
||||
|
|
10
src/game.nim
10
src/game.nim
|
@ -1,11 +1,11 @@
|
|||
import std / [monotimes, times, os, jsonutils, json, math]
|
||||
import pkg / [godot, model_citizen, zippy / ziparchives]
|
||||
import pkg / [godot, 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,
|
||||
project_settings, input_map, input_event_action, input_event_key, global_constants,
|
||||
scroll_container]
|
||||
import core, globals, controllers / [node_controllers, script_controllers], models / serializers
|
||||
import core, types, globals, controllers / [node_controllers, script_controllers], models / serializers
|
||||
|
||||
type
|
||||
UserConfig = object
|
||||
|
@ -282,12 +282,12 @@ gdobj Game of Node:
|
|||
if event.is_action_pressed("previous"):
|
||||
self.prev_action()
|
||||
# NOTE: alt+enter isn't being picked up on windows if the editor is open. Needs investigation.
|
||||
if event.is_action_pressed("toggle_fullscreen") or (host_os == "windows" and
|
||||
CommandMode in state.flags and EditorVisible in state.flags and
|
||||
if event.is_action_pressed("toggle_fullscreen") or (host_os == "windows" and
|
||||
CommandMode in state.flags and EditorVisible in state.flags and
|
||||
event of InputEventKey and event.as(InputEventKey).scancode == KEY_ENTER):
|
||||
|
||||
set_window_fullscreen not is_window_fullscreen()
|
||||
elif event.is_action_pressed("next_world"):
|
||||
elif event.is_action_pressed("next_world"):
|
||||
self.switch_world(+1)
|
||||
elif event.is_action_pressed("prev_world"):
|
||||
self.switch_world(-1)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import std / [strformat, tables]
|
||||
import pkg / [godot, model_citizen]
|
||||
import pkg / [godot]
|
||||
import godotapi / [node, scene_tree, voxel_buffer]
|
||||
import core, models / [states, types]
|
||||
import core, models / [states]
|
||||
export strformat.`&`, states, types
|
||||
|
||||
type
|
||||
|
|
|
@ -3,7 +3,6 @@ import pkg / compiler / ast except new_node
|
|||
import pkg / godot except print
|
||||
import pkg / [print], pkg / compiler / [vm, vmdef, options, lineinfos, llstream]
|
||||
import core, eval
|
||||
import models/types
|
||||
|
||||
export Interpreter, VmArgs, set_result
|
||||
|
||||
|
@ -30,12 +29,14 @@ proc load*(self: ScriptCtx, file_name, code: string) =
|
|||
self.file_name = file_name
|
||||
|
||||
proc run*(self: ScriptCtx): bool =
|
||||
private_access ScriptCtx
|
||||
self.exit_code = none(int)
|
||||
self.errors = @[]
|
||||
try:
|
||||
self.interpreter.load_module(self.file_name, self.code, self.pass_context)
|
||||
result = false
|
||||
except VMPause:
|
||||
private_access ScriptCtx
|
||||
result = self.exit_code.is_none
|
||||
except:
|
||||
self.running = false
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
import pkg / core / [transforms, godotcoretypes]
|
||||
export transforms except `==`
|
||||
|
||||
proc `==`*(self: Transform; b: Transform): bool {.inline.} =
|
||||
self.origin == b.origin and self.basis == b.basis
|
|
@ -1,6 +1,4 @@
|
|||
import pkg / [model_citizen]
|
||||
import models / [types, states, units, builds, bots, ground, colors, players,
|
||||
import models / [states, units, builds, bots, ground, colors, players,
|
||||
signs]
|
||||
|
||||
export model_citizen except `%`
|
||||
export types, states, units, builds, bots, ground, colors, players, signs
|
||||
export states, units, builds, bots, ground, colors, players, signs
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import std / [math, sugar, monotimes]
|
||||
import pkg / model_citizen
|
||||
import godotapi / spatial
|
||||
import core, models / [types, states, units, colors]
|
||||
import core, models / [states, units, colors]
|
||||
include "bot_code_template.nim.nimf"
|
||||
|
||||
let state = GameState.active
|
||||
|
@ -75,13 +74,13 @@ proc init*(_: type Bot, id = "bot_" & generate_id(), transform = Transform.init,
|
|||
scale: Zen.init(1.0),
|
||||
color: Zen.init(action_colors[black]),
|
||||
start_color: action_colors[black],
|
||||
shared: if parent: parent.shared else: Shared(),
|
||||
shared: if ?parent: parent.shared else: Shared(),
|
||||
parent: parent,
|
||||
frame_created: state.frame_count
|
||||
)
|
||||
if clone_of == nil:
|
||||
state.dirty_units.incl self
|
||||
|
||||
|
||||
if global: self.flags += Global
|
||||
self.flags += Visible
|
||||
|
||||
|
@ -96,7 +95,7 @@ proc init*(_: type Bot, id = "bot_" & generate_id(), transform = Transform.init,
|
|||
root.walk_tree proc(unit: Unit) = unit.flags -= Highlight
|
||||
state.pop_flag ReticleVisible
|
||||
|
||||
self.state_zids.add:
|
||||
self.state_zids.add:
|
||||
state.flags.changes:
|
||||
if Hover in self.flags:
|
||||
if PrimaryDown.added and state.tool.value == CodeMode:
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import std / [hashes, tables, sets, options, sequtils, math, wrapnils, monotimes, sugar, deques]
|
||||
import pkg / [model_citizen, print]
|
||||
import pkg / [print]
|
||||
import godotapi / spatial
|
||||
import core, models / [types, states, bots, colors, units]
|
||||
import core, models / [states, bots, colors, units]
|
||||
const ChunkSize = vec3(16, 16, 16)
|
||||
|
||||
include "build_code_template.nim.nimf"
|
||||
|
@ -50,7 +50,7 @@ proc find_first*(units: ZenSeq[Unit], positions: open_array[Vector3]): Build =
|
|||
if info.kind != Hole and info.color != action_colors[eraser]:
|
||||
return unit
|
||||
let first = unit.units.find_first(positions)
|
||||
if first:
|
||||
if ?first:
|
||||
return first
|
||||
|
||||
proc add_build(self, source: Build) =
|
||||
|
@ -72,7 +72,7 @@ proc maybe_join_previous_build(self: Build, position: Vector3, voxel: VoxelInfo)
|
|||
previous_build = current_build
|
||||
current_build = self
|
||||
|
||||
if previous_build and previous_build != self:
|
||||
if ?previous_build and previous_build != self:
|
||||
var partner = previous_build
|
||||
let root = previous_build.find_root
|
||||
if root of Build:
|
||||
|
@ -89,7 +89,7 @@ proc maybe_join_previous_build(self: Build, position: Vector3, voxel: VoxelInfo)
|
|||
source = self
|
||||
dest = partner
|
||||
|
||||
if source and dest:
|
||||
if ?source and ?dest:
|
||||
dest.add_build(source)
|
||||
current_build = dest
|
||||
return
|
||||
|
@ -147,7 +147,7 @@ proc draw*(self: Build, position: Vector3, voxel: VoxelInfo) =
|
|||
return
|
||||
elif edit.kind == Manual and edit.color == voxel.color:
|
||||
self.shared.edits[self.id].del position
|
||||
elif self.clone_of and position in self.clone_of.shared.edits[self.clone_of.id] and
|
||||
elif ?self.clone_of and position in self.clone_of.shared.edits[self.clone_of.id] and
|
||||
self.clone_of.shared.edits[self.clone_of.id][position].kind == Hole:
|
||||
return
|
||||
else:
|
||||
|
@ -201,7 +201,7 @@ proc fire(self: Build) =
|
|||
skip_point = self.target_point + self.target_normal
|
||||
last_point = self.target_point
|
||||
self.draw(point, (Manual, state.selected_color))
|
||||
elif state.tool.value == PlaceBot 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)
|
||||
|
@ -238,7 +238,7 @@ method on_begin_move*(self: Build, direction: Vector3, steps: float, move_mode:
|
|||
self.voxels_remaining_this_frame = self.speed
|
||||
self.voxels_per_frame = self.speed
|
||||
var count = 0
|
||||
|
||||
|
||||
result = proc(delta: float): TaskStates =
|
||||
while count.float < steps and self.voxels_remaining_this_frame >= 1 and
|
||||
get_mono_time() < state.timeout_frame_at:
|
||||
|
@ -340,10 +340,10 @@ proc init*(_: type Build, id = "build_" & generate_id(), transform = Transform.i
|
|||
bot_collisions: bot_collisions,
|
||||
frame_delta: ZenValue[float].init,
|
||||
scale: Zen.init(1.0),
|
||||
shared: if parent: parent.shared else: Shared(),
|
||||
shared: if ?parent: parent.shared else: Shared(),
|
||||
frame_created: state.frame_count
|
||||
)
|
||||
|
||||
|
||||
if clone_of == nil:
|
||||
state.dirty_units.incl self
|
||||
|
||||
|
@ -361,12 +361,12 @@ proc init*(_: type Build, id = "build_" & generate_id(), transform = Transform.i
|
|||
let root = self.find_root(true)
|
||||
root.walk_tree proc(unit: Unit) = unit.flags -= Highlight
|
||||
if TargetMoved.touched:
|
||||
let length = (self.target_point * self.target_normal - last_point * self.target_normal).length
|
||||
let length = (self.target_point * self.target_normal - last_point * self.target_normal).length
|
||||
if state.skip_block_paint:
|
||||
state.skip_block_paint = false
|
||||
elif state.draw_unit_id == self.id and self.target_normal == draw_normal and
|
||||
length <= 5 and self.target_point != skip_point:
|
||||
|
||||
|
||||
if SecondaryDown in state.flags:
|
||||
self.remove
|
||||
elif PrimaryDown in state.flags:
|
||||
|
@ -395,7 +395,7 @@ proc init*(_: type Build, id = "build_" & generate_id(), transform = Transform.i
|
|||
|
||||
method on_collision*(self: Build, partner: Model, normal: Vector3) =
|
||||
self.collisions.add (partner, normal)
|
||||
if self.script_ctx:
|
||||
if ?self.script_ctx:
|
||||
self.script_ctx.timer = get_mono_time()
|
||||
|
||||
method off_collision*(self: Build, partner: Model) =
|
||||
|
@ -404,7 +404,7 @@ method off_collision*(self: Build, partner: Model) =
|
|||
if collision.model != partner:
|
||||
collision
|
||||
|
||||
if self.script_ctx:
|
||||
if ?self.script_ctx:
|
||||
self.script_ctx.timer = get_mono_time()
|
||||
|
||||
method clone*(self: Build, clone_to: Unit, id: string): Unit =
|
||||
|
@ -414,7 +414,7 @@ method clone*(self: Build, clone_to: Unit, id: string): Unit =
|
|||
transform = Build(clone_to).draw_transform
|
||||
global = false
|
||||
|
||||
# we need this off for Potato Zombies, but on for the
|
||||
# we need this off for Potato Zombies, but on for the
|
||||
# tutorials. Make it configurable somehow.
|
||||
let bot_collisions = true #not (clone_to of Bot)
|
||||
let clone = Build.init(id = id, transform = transform, clone_of = self, global = global, parent = clone_to,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import std / [sugar]
|
||||
import pkg / [model_citizen, print]
|
||||
import pkg / [print]
|
||||
import godotapi / spatial
|
||||
import core, types, states, bots, builds
|
||||
import core, states, bots, builds
|
||||
|
||||
let state = GameState.active
|
||||
|
||||
|
@ -12,7 +12,7 @@ proc fire(self: Ground, append = false) =
|
|||
if state.tool.value notin {CodeMode, PlaceBot}:
|
||||
if not append:
|
||||
add_to = state.units.find_first(point.surrounding)
|
||||
if add_to:
|
||||
if ?add_to:
|
||||
let local = point.local_to(add_to)
|
||||
add_to.draw(local, (Manual, state.selected_color))
|
||||
else:
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
import std / math
|
||||
import pkg / model_citizen
|
||||
import godotapi / spatial
|
||||
import models / [types]
|
||||
import core
|
||||
|
||||
proc init*(_: type Player, node: Spatial): Player =
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
import system except write_file
|
||||
import std / [json, jsonutils, sugar, tables, strutils, os]
|
||||
import pkg / print
|
||||
|
||||
proc save_world*()
|
||||
|
||||
import core, models, controllers / script_controllers
|
||||
import core, models
|
||||
import controllers / script_controllers
|
||||
|
||||
let state = GameState.active
|
||||
var load_chunks = false
|
||||
|
@ -115,8 +113,8 @@ proc from_json_hook(self: var Bot, json: JsonNode) =
|
|||
self.shared.edits.from_json(json["edits"])
|
||||
|
||||
proc save*(unit: Unit) =
|
||||
if not unit.clone_of:
|
||||
let data =
|
||||
if not ?unit.clone_of:
|
||||
let data =
|
||||
if unit of Build:
|
||||
Build(unit).to_json.pretty
|
||||
elif unit of Bot:
|
||||
|
@ -139,10 +137,11 @@ proc save_world*() =
|
|||
|
||||
proc load_units(parent: Unit) =
|
||||
let opts = JOptions(allow_missing_keys: true)
|
||||
let path = if parent:
|
||||
parent.data_dir
|
||||
else:
|
||||
state.config.data_dir
|
||||
let path =
|
||||
if ?parent:
|
||||
parent.data_dir
|
||||
else:
|
||||
state.config.data_dir
|
||||
for dir in walk_dirs(path / "*"):
|
||||
let unit_id = dir.split_path.tail
|
||||
let data_file = read_file(dir / unit_id & ".json").parse_json
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import std / [sugar]
|
||||
import pkg / [model_citizen, print]
|
||||
import pkg / [print]
|
||||
import godotapi / spatial
|
||||
import core, types, states, bots, builds, models / colors
|
||||
import core, states, bots, builds, models / colors
|
||||
|
||||
let state = GameState.active
|
||||
|
||||
proc init*(_: type Sign,
|
||||
markdown: string, title = "", owner: Unit, transform = Transform.init,
|
||||
width = 1.0, height = 1.0, size = 32, billboard = false,
|
||||
proc init*(_: type Sign,
|
||||
markdown: string, title = "", owner: Unit, transform = Transform.init,
|
||||
width = 1.0, height = 1.0, size = 32, billboard = false,
|
||||
zoomable = true): Sign =
|
||||
|
||||
let title = if title == "": markdown else: title
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import std / [tables, strutils, sequtils, algorithm, sets, sugar]
|
||||
import pkg / [model_citizen, print]
|
||||
import models / [types, colors]
|
||||
import pkg / [print]
|
||||
import core, models / [colors]
|
||||
|
||||
# only one flag from the group is active at a time
|
||||
const groups = @[
|
||||
|
@ -25,7 +25,7 @@ proc resolve_flags(self: GameState) =
|
|||
|
||||
if not groups[1].any_it(it in result):
|
||||
result.incl ReticleVisible
|
||||
|
||||
|
||||
if CommandMode in result:
|
||||
result.incl(MouseCaptured)
|
||||
for flag in groups[0]:
|
||||
|
@ -36,7 +36,7 @@ proc resolve_flags(self: GameState) =
|
|||
|
||||
if MouseCaptured notin result:
|
||||
result.excl(ReticleVisible)
|
||||
|
||||
|
||||
self.flags.value = result
|
||||
|
||||
proc replace_flags*(self: GameState, flags: varargs[StateFlags]) =
|
||||
|
@ -55,7 +55,7 @@ proc push_flags*(self: GameState, flags: varargs[StateFlags]) =
|
|||
for flag in flags:
|
||||
self.wants.incl flag
|
||||
self.resolve_flags
|
||||
|
||||
|
||||
proc push_flag*(self: GameState, flag: StateFlags) =
|
||||
self.push_flags flag
|
||||
|
||||
|
@ -74,10 +74,10 @@ proc set_flag*(self: GameState, flag: StateFlags, value: bool) =
|
|||
else:
|
||||
self.pop_flag flag
|
||||
|
||||
proc `+=`*(self: ZenSet[StateFlags], flag: StateFlags) {.error:
|
||||
proc `+=`*(self: ZenSet[StateFlags], flag: StateFlags) {.error:
|
||||
"Use `push_flag`, `pop_flag` and `replace_flag`".}
|
||||
|
||||
proc `-=`*(self: ZenSet[StateFlags], flag: StateFlags) {.error:
|
||||
proc `-=`*(self: ZenSet[StateFlags], flag: StateFlags) {.error:
|
||||
"Use `push_flag`, `pop_flag` and `replace_flag`".}
|
||||
|
||||
proc selected_color*(self: GameState): Color =
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import std / [os, sugar]
|
||||
import pkg / model_citizen
|
||||
import godotapi / spatial
|
||||
from pkg/core/godotcoretypes import Basis
|
||||
import core, models / [types, states, colors], libs / interpreters
|
||||
import core, models / [states, colors], libs / interpreters
|
||||
|
||||
proc find_root*(self: Unit, all_clones = false): Unit =
|
||||
result = self
|
||||
|
@ -11,7 +10,7 @@ proc find_root*(self: Unit, all_clones = false): Unit =
|
|||
while parent != nil:
|
||||
result = parent
|
||||
|
||||
if (all_clones and not parent.clone_of) or (not all_clones and Global in parent.flags):
|
||||
if (all_clones and not ?parent.clone_of) or (not all_clones and Global in parent.flags):
|
||||
parent = nil
|
||||
else:
|
||||
parent = parent.parent
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import std / [strutils, wrapnils]
|
||||
import pkg / [godot, model_citizen]
|
||||
import pkg / [godot]
|
||||
import godotapi / [sprite_3d, ray_cast, spatial]
|
||||
import globals, core, nodes/helpers, models
|
||||
|
||||
|
@ -40,7 +40,7 @@ gdobj AimTarget of Sprite3D:
|
|||
self.target_model.flags -= Hover
|
||||
state.pop_flag BlockTargetVisible
|
||||
self.target_model = unit
|
||||
if not (unit == nil or (unit of Sign and not Sign(unit).zoomable) or
|
||||
if not (unit == nil or (unit of Sign and not Sign(unit).zoomable) or
|
||||
(God notin state.flags and (unit of Bot or unit of Build) and
|
||||
Lock in Unit(unit).find_root.flags)):
|
||||
|
||||
|
@ -73,7 +73,7 @@ gdobj AimTarget of Sprite3D:
|
|||
let align_normal = self.transform.origin + global_normal
|
||||
self.look_at(align_normal, self.transform.basis.x)
|
||||
|
||||
if unit:
|
||||
if ?unit:
|
||||
if (unit.target_point, unit.target_normal) != (local_point, local_normal):
|
||||
unit.target_point = local_point
|
||||
unit.target_normal = local_normal
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import std / [tables, sugar, os, math]
|
||||
import pkg/godot except print
|
||||
import pkg / [model_citizen, chroma]
|
||||
import pkg / [chroma]
|
||||
import godotapi / [scene_tree, kinematic_body, material, mesh_instance, spatial,
|
||||
input_event, animation_player, resource_loader, packed_scene,
|
||||
spatial_material]
|
||||
import globals, core, print
|
||||
import models / [types, bots, units, states, colors]
|
||||
import core, models / [bots, units, states, colors]
|
||||
|
||||
let state = GameState.active
|
||||
|
||||
|
@ -43,10 +43,10 @@ gdobj BotNode of KinematicBody:
|
|||
adjusted = color
|
||||
adjusted.a = 0.1
|
||||
else:
|
||||
var dist = (color.distance(action_colors[brown]) + 10).cbrt / 7.5
|
||||
var dist = (color.distance(action_colors[brown]) + 10).cbrt / 7.5
|
||||
adjusted = color.saturate(0.2).darken(dist - 0.15)
|
||||
adjusted.a = 0.95 - color.distance(action_colors[black]) / 100
|
||||
|
||||
|
||||
SpatialMaterial(self.material).albedo_color = adjusted
|
||||
|
||||
proc set_visibility =
|
||||
|
@ -76,7 +76,7 @@ gdobj BotNode of KinematicBody:
|
|||
self.set_default_material()
|
||||
elif change.item == Visible:
|
||||
self.set_visibility
|
||||
|
||||
|
||||
self.model.state_zids.add:
|
||||
state.flags.changes:
|
||||
if change.item == God:
|
||||
|
@ -124,7 +124,7 @@ gdobj BotNode of KinematicBody:
|
|||
self.track_changes
|
||||
|
||||
method process(delta: float) =
|
||||
if self.model:
|
||||
if ?self.model:
|
||||
self.model.frame_delta.touch delta
|
||||
self.model.transform.pause self.transform_zid:
|
||||
self.model.transform.value = self.transform
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import std / [tables, bitops]
|
||||
import pkg/godot except print, Color
|
||||
import pkg / [print, model_citizen]
|
||||
import pkg / [print]
|
||||
import godotapi / [node, voxel_terrain, voxel_mesher_blocky, voxel_tool, voxel_library, shader_material,
|
||||
resource_loader, packed_scene]
|
||||
import models / [types, builds, colors, units, states], globals
|
||||
import core, models / [builds, colors, units, states], globals
|
||||
|
||||
const
|
||||
highlight_glow = 1.0
|
||||
|
@ -140,7 +140,7 @@ gdobj BuildNode of VoxelTerrain:
|
|||
self.transform = change.item
|
||||
|
||||
method process(delta: float) =
|
||||
if self.model:
|
||||
if ?self.model:
|
||||
self.model.frame_delta.touch delta
|
||||
self.model.transform.pause self.transform_zid:
|
||||
self.model.transform.value = self.transform
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import pkg/godot
|
||||
import godotapi/node
|
||||
import models/types, bot_node, build_node, ground_node, selection_area, sign_node
|
||||
import core, bot_node, build_node, ground_node, selection_area, sign_node
|
||||
|
||||
proc model*(self: Object): Model =
|
||||
result = if self of SelectionArea:
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import std / [math, sugar]
|
||||
import pkg / godot except print
|
||||
import pkg / model_citizen
|
||||
import godotapi / [kinematic_body, spatial, input, input_event,
|
||||
input_event_mouse_motion, input_event_joypad_motion,
|
||||
ray_cast, scene_tree, input_event_pan_gesture, viewport, camera, global_constants,
|
||||
|
@ -86,7 +85,7 @@ gdobj PlayerNode of KinematicBody:
|
|||
var speed = vec3(move_speed)
|
||||
if running: speed *= vec3(2)
|
||||
if flying: speed *= vec3(3, 2, 3)
|
||||
|
||||
|
||||
result = move_direction * delta * speed
|
||||
if result.length() > max_speed:
|
||||
result = result.normalized() * max_speed
|
||||
|
@ -96,7 +95,7 @@ gdobj PlayerNode of KinematicBody:
|
|||
float_time + float_time
|
||||
else:
|
||||
float_time
|
||||
let floating = self.jump_down and self.jump_time and self.jump_time.get + float_time > now()
|
||||
let floating = self.jump_down and ?self.jump_time and self.jump_time.get + float_time > now()
|
||||
let gravity = if floating:
|
||||
state.gravity / 4
|
||||
else:
|
||||
|
@ -159,7 +158,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 == CodeMode: 200.0 else: 100.0
|
||||
if MouseCaptured notin state.flags:
|
||||
let
|
||||
|
@ -181,8 +180,8 @@ gdobj PlayerNode of KinematicBody:
|
|||
state.pop_flag CommandMode
|
||||
|
||||
const forward_rotation = deg_to_rad(-90.0)
|
||||
let
|
||||
process_input =
|
||||
let
|
||||
process_input =
|
||||
EditorVisible notin state.flags or CommandMode in state.flags
|
||||
input_direction = if process_input: self.get_input_direction()
|
||||
else: vec3()
|
||||
|
@ -250,7 +249,7 @@ gdobj PlayerNode of KinematicBody:
|
|||
self.input_relative += event.as(InputEventMouseMotion).relative()
|
||||
else:
|
||||
self.skip_next_mouse_move = false
|
||||
if EditorVisible in state.flags and not self.skip_release and
|
||||
if EditorVisible in state.flags and not self.skip_release and
|
||||
(event of InputEventJoypadButton or event of InputEventJoypadMotion):
|
||||
|
||||
let active_input = self.has_active_input(event.device.int)
|
||||
|
@ -266,7 +265,7 @@ gdobj PlayerNode of KinematicBody:
|
|||
self.jump_down = true
|
||||
let
|
||||
time = now()
|
||||
toggle = self.jump_time and time < self.jump_time.get + fly_toggle
|
||||
toggle = ?self.jump_time and time < self.jump_time.get + fly_toggle
|
||||
|
||||
if toggle:
|
||||
self.jump_time = nil_time
|
||||
|
@ -287,7 +286,7 @@ gdobj PlayerNode of KinematicBody:
|
|||
if event.is_action_pressed("run"):
|
||||
let
|
||||
time = now()
|
||||
toggle = self.run_time and time < self.run_time.get + run_toggle
|
||||
toggle = ?self.run_time and time < self.run_time.get + run_toggle
|
||||
|
||||
if toggle:
|
||||
self.run_time = nil_time
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import pkg / [godot, model_citizen]
|
||||
import pkg / [godot]
|
||||
import godotapi / [area, control]
|
||||
import core, globals, nodes/bot_node
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import pkg / [godot, model_citizen]
|
||||
import pkg / [godot]
|
||||
import godotapi / [spatial, resource_loader, packed_scene, collision_shape,
|
||||
mesh_instance, quad_mesh, spatial_material, viewport,
|
||||
style_box_flat]
|
||||
import ui / markdown_label, models / [types, signs]
|
||||
import ui / markdown_label, models / [signs]
|
||||
import core, models / [states]
|
||||
|
||||
let state = GameState.active
|
||||
|
@ -35,7 +35,7 @@ gdobj SignNode of Spatial:
|
|||
var
|
||||
ratio = self.model.width / self.model.height
|
||||
size = vec2(viewport.size.x, viewport.size.x / ratio)
|
||||
|
||||
|
||||
quad.size = vec2(self.model.width, self.model.height)
|
||||
shape.scale = vec3(self.model.width, self.model.height, 1)
|
||||
var t = mesh.transform
|
||||
|
@ -68,7 +68,7 @@ gdobj SignNode of Spatial:
|
|||
label.markdown = change.item
|
||||
resize()
|
||||
label.update
|
||||
|
||||
|
||||
self.model.markdown.changes:
|
||||
if added or touched:
|
||||
if self.model.title.value == "":
|
||||
|
@ -89,8 +89,8 @@ gdobj SignNode of Spatial:
|
|||
if change.item == Visible:
|
||||
self.set_visibility
|
||||
|
||||
|
||||
self.model.state_zids.add:
|
||||
|
||||
self.model.state_zids.add:
|
||||
state.flags.changes:
|
||||
if God.removed:
|
||||
self.set_visibility
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
import std / [tables, monotimes, sets]
|
||||
import std / [tables, monotimes, sets, options]
|
||||
import godotapi / [spatial, ray_cast]
|
||||
import pkg/model_citizen
|
||||
import pkg/core/godotcoretypes except Color
|
||||
import pkg / core / [vector3, basis, aabb, godotbase]
|
||||
import pkg / compiler / passes {.all.}
|
||||
import core, models/colors, libs / [transforms, eval]
|
||||
import pkg / compiler / ast
|
||||
import pkg / model_citizen
|
||||
import models/colors, libs / [eval]
|
||||
|
||||
export Vector3, Transform, vector3, transforms, basis, AABB, aabb
|
||||
export Vector3, Transform, vector3, basis, AABB, aabb
|
||||
export godotbase except print
|
||||
export Interpreter
|
||||
|
||||
|
@ -14,7 +15,7 @@ type
|
|||
|
||||
StateFlags* = enum
|
||||
CommandMode, EditorVisible, ConsoleVisible,
|
||||
BlockTargetVisible, ReticleVisible, DocsVisible, MouseCaptured,
|
||||
BlockTargetVisible, ReticleVisible, DocsVisible, MouseCaptured,
|
||||
PrimaryDown, SecondaryDown, EditorFocused, ConsoleFocused, DocsFocused,
|
||||
Playing, Flying, God
|
||||
|
||||
|
@ -179,38 +180,13 @@ type
|
|||
|
||||
Callback* = proc(delta: float): TaskStates
|
||||
|
||||
# TODO: this shouldn't be here
|
||||
proc local_to*(self: Vector3, unit: Unit): Vector3 =
|
||||
result = self
|
||||
var unit = unit
|
||||
while unit:
|
||||
result -= unit.node.transform.origin
|
||||
unit = unit.parent
|
||||
ScriptController* = ref object
|
||||
retry_failures*: bool
|
||||
interpreter: Interpreter
|
||||
module_names: HashSet[string]
|
||||
active_unit: Unit
|
||||
unit_map: Table[PNode, Unit]
|
||||
node_map: Table[Unit, PNode]
|
||||
failed: seq[tuple[unit: Unit, e: ref VMQuit]]
|
||||
|
||||
proc global_from*(self: Vector3, unit: Unit): Vector3 =
|
||||
result = -self.local_to(unit)
|
||||
|
||||
proc init*(_: type Transform, origin = vec3()): Transform =
|
||||
result = init_transform()
|
||||
result.origin = origin
|
||||
|
||||
proc `+=`*(self: ZenValue[string], str: string) =
|
||||
self.value = self.value & str
|
||||
|
||||
proc origin*(self: ZenValue[Transform]): Vector3 =
|
||||
self.value.origin
|
||||
|
||||
proc `origin=`*(self: ZenValue[Transform], value: Vector3) =
|
||||
var transform = self.value
|
||||
transform.origin = value
|
||||
self.value = transform
|
||||
|
||||
proc basis*(self: ZenValue[Transform]): Basis =
|
||||
self.value.basis
|
||||
|
||||
proc `basis=`*(self: ZenValue[Transform], value: Basis) =
|
||||
var transform = self.value
|
||||
transform.basis = value
|
||||
self.value = transform
|
||||
|
||||
proc init*(_: type Basis): Basis = init_basis()
|
||||
NodeController* = ref object
|
|
@ -1,6 +1,6 @@
|
|||
import godotapi / [text_edit, scene_tree, node, input_event, input_event_key,
|
||||
rich_text_label, global_constants]
|
||||
import godot, model_citizen
|
||||
import godot
|
||||
import std / strutils
|
||||
import globals, core
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import std / [strutils, tables]
|
||||
import pkg / [godot, model_citizen]
|
||||
import pkg / [godot]
|
||||
import pkg / compiler / [lineinfos]
|
||||
import godotapi / [text_edit, scene_tree, node, input_event, global_constants,
|
||||
input_event_key, style_box_flat, gd_os]
|
||||
|
@ -18,15 +18,15 @@ gdobj Editor of TextEdit:
|
|||
proc set_open_script_ctx() =
|
||||
# TODO: yuck
|
||||
var current = self.open_script_ctx
|
||||
if not state.open_unit.value.is_nil and state.open_unit.value.script_ctx:
|
||||
if ?state.open_unit.value and ?state.open_unit.value.script_ctx:
|
||||
current = state.open_unit.value.script_ctx
|
||||
if self.open_script_ctx != current:
|
||||
if self.open_script_ctx:
|
||||
if ?self.open_script_ctx:
|
||||
self.open_script_ctx.line_changed = nil
|
||||
|
||||
if not state.open_unit.value.is_nil and not state.open_unit.value.script_ctx.is_nil:
|
||||
self.open_script_ctx = state.open_unit.value.script_ctx
|
||||
if self.open_script_ctx:
|
||||
if ?self.open_script_ctx:
|
||||
self.executing_line = int self.open_script_ctx.current_line.line - 1
|
||||
self.open_script_ctx.line_changed = proc(current: TLineInfo, previous: TLineInfo) =
|
||||
self.executing_line = int current.line - 1
|
||||
|
@ -114,7 +114,7 @@ gdobj Editor of TextEdit:
|
|||
if unit.is_nil:
|
||||
self.release_focus()
|
||||
self.visible = false
|
||||
if self.open_script_ctx:
|
||||
if ?self.open_script_ctx:
|
||||
self.open_script_ctx.line_changed = nil
|
||||
self.open_script_ctx = nil
|
||||
else:
|
||||
|
@ -137,7 +137,7 @@ gdobj Editor of TextEdit:
|
|||
state.open_unit.value.code.value = self.text
|
||||
self.modulate = dimmed_alpha
|
||||
self.release_focus
|
||||
|
||||
|
||||
elif CommandMode.removed:
|
||||
if EditorVisible in state.flags:
|
||||
self.modulate = solid_alpha
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import std / [lists, algorithm, tables]
|
||||
import pkg / [godot, markdown, hmatching, print, model_citizen]
|
||||
import pkg / [godot, markdown, hmatching, print]
|
||||
import godotapi / [rich_text_label, scroll_container, text_edit, theme,
|
||||
dynamic_font, dynamic_font_data, style_box_flat, main_loop]
|
||||
import core, globals
|
||||
|
@ -9,7 +9,7 @@ export scroll_container
|
|||
|
||||
const comment_color = col"808080"
|
||||
|
||||
proc stylebox(self: Control): StyleBoxFlat =
|
||||
proc stylebox(self: Control): StyleBoxFlat =
|
||||
self.get_stylebox("normal").as(StyleBoxFlat)
|
||||
|
||||
gdobj MarkdownLabel of ScrollContainer:
|
||||
|
@ -46,7 +46,7 @@ gdobj MarkdownLabel of ScrollContainer:
|
|||
GameState.active.nodes.game.bind_signals(self.current_label, "meta_clicked")
|
||||
|
||||
proc set_font_sizes =
|
||||
var size =
|
||||
var size =
|
||||
if self.size > 0:
|
||||
self.size
|
||||
else:
|
||||
|
@ -56,7 +56,7 @@ gdobj MarkdownLabel of ScrollContainer:
|
|||
self.local_italic_font.size = size
|
||||
self.local_bold_font.size = size
|
||||
self.local_bold_italic_font.size = size
|
||||
self.local_mono_font.size = size
|
||||
self.local_mono_font.size = size
|
||||
self.local_header_font.size = size * 2
|
||||
|
||||
for i, child in self.container.get_children:
|
||||
|
@ -66,11 +66,11 @@ gdobj MarkdownLabel of ScrollContainer:
|
|||
var child = TextEdit(child)
|
||||
var height = child.get_line_count * child.get_line_height + 24
|
||||
let lines = dup child.text.split_lines.sorted_by_it(it.len)
|
||||
|
||||
|
||||
var size = child.rect_min_size
|
||||
size.y = float height
|
||||
if lines.len > 0:
|
||||
let str_size =
|
||||
let str_size =
|
||||
self.local_mono_font.get_string_size(" ".repeat(lines.len + 2))
|
||||
size.x = str_size.x
|
||||
child.rect_min_size = size
|
||||
|
@ -78,7 +78,7 @@ gdobj MarkdownLabel of ScrollContainer:
|
|||
elif child of RichTextLabel:
|
||||
var stylebox = self.current_label.stylebox
|
||||
stylebox.content_margin_bottom = 0
|
||||
|
||||
|
||||
if i > 0:
|
||||
stylebox.content_margin_top = float(size + 4)
|
||||
if i == self.container.get_children.len - 1:
|
||||
|
@ -113,7 +113,7 @@ gdobj MarkdownLabel of ScrollContainer:
|
|||
|
||||
self.og_text_edit.add_font_override("font", self.local_mono_font)
|
||||
self.og_label.add_font_override("normal_font", self.local_default_font)
|
||||
|
||||
|
||||
self.zid = GameState.active.config.font_size.changes:
|
||||
if added:
|
||||
self.set_font_sizes()
|
||||
|
@ -124,7 +124,7 @@ gdobj MarkdownLabel of ScrollContainer:
|
|||
if not self.resized:
|
||||
self.set_font_sizes()
|
||||
self.resized = true
|
||||
|
||||
|
||||
proc render_markdown(token: Token, list_position = 0, inline_blocks = false) =
|
||||
var list_position = list_position
|
||||
for t in token.children:
|
||||
|
@ -132,11 +132,11 @@ gdobj MarkdownLabel of ScrollContainer:
|
|||
if self.needs_margin and not (t of CodeBlock):
|
||||
label.newline
|
||||
self.needs_margin = false
|
||||
|
||||
|
||||
case t:
|
||||
of of Heading():
|
||||
label.with(push_font self.local_header_font,
|
||||
push_color ir_black[keyword])
|
||||
label.with(push_font self.local_header_font,
|
||||
push_color ir_black[keyword])
|
||||
self.render_markdown t
|
||||
label.with(pop, pop, newline)
|
||||
self.needs_margin = true
|
||||
|
@ -150,7 +150,7 @@ gdobj MarkdownLabel of ScrollContainer:
|
|||
label.push_font self.local_bold_font
|
||||
self.render_markdown t
|
||||
label.pop
|
||||
|
||||
|
||||
of of CodeSpan():
|
||||
label.with(push_font self.local_mono_font, push_color ir_black[number],
|
||||
add_text t.doc)
|
||||
|
@ -159,13 +159,13 @@ gdobj MarkdownLabel of ScrollContainer:
|
|||
|
||||
of of CodeBlock():
|
||||
self.needs_margin = false
|
||||
|
||||
|
||||
var editor = self.add_text_edit()
|
||||
editor.text = t.doc[0..^2]
|
||||
editor.visible = true
|
||||
self.container.add_child editor
|
||||
self.add_label()
|
||||
|
||||
|
||||
of of Paragraph():
|
||||
self.render_markdown(t, inline_blocks = inline_blocks)
|
||||
if not inline_blocks:
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import pkg / [godot, model_citizen]
|
||||
import pkg / [godot]
|
||||
import godotapi / [margin_container, input_event, scene_tree]
|
||||
import ui / markdown_label
|
||||
import models / [types, states, colors]
|
||||
import core, models / [states, colors]
|
||||
|
||||
let state = GameState.active
|
||||
|
||||
|
@ -19,7 +19,7 @@ gdobj RightPanel of MarginContainer:
|
|||
|
||||
method ready* =
|
||||
self.label = self.find_node("MarkdownLabel") as MarkdownLabel
|
||||
|
||||
|
||||
state.open_sign.changes:
|
||||
if added and change.item != nil:
|
||||
state.push_flags DocsVisible, DocsFocused
|
||||
|
@ -33,7 +33,7 @@ gdobj RightPanel of MarginContainer:
|
|||
if removed and change.item != nil:
|
||||
change.item.markdown.untrack(self.zid)
|
||||
state.pop_flags DocsFocused, DocsVisible
|
||||
|
||||
|
||||
state.flags.changes:
|
||||
if DocsVisible.added:
|
||||
self.label.visible = true
|
||||
|
@ -45,12 +45,12 @@ gdobj RightPanel of MarginContainer:
|
|||
self.modulate = dimmed_alpha
|
||||
elif CommandMode.removed:
|
||||
self.modulate = solid_alpha
|
||||
|
||||
|
||||
method unhandled_input*(event: InputEvent) =
|
||||
if DocsFocused in state.flags and event.is_action_pressed("ui_cancel"):
|
||||
if not (event of InputEventJoypadButton) or CommandMode notin state.flags:
|
||||
state.open_sign.value = nil
|
||||
self.get_tree().set_input_as_handled()
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import godotapi / [h_box_container, scene_tree, button, image_texture]
|
||||
import pkg / [godot, model_citizen]
|
||||
import models / [types, states]
|
||||
import ".." / [core, globals, game, ui/preview_maker]
|
||||
import pkg / [godot]
|
||||
import core, models / [states]
|
||||
import globals, ui/preview_maker
|
||||
|
||||
type
|
||||
PreviewResult = tuple[color: string, preview: Image]
|
||||
|
|
Loading…
Reference in New Issue