extends Node # class member variables go here, for example: # var a = 2 # var b = "textvar" var command_registry = Dictionary(); var command_history = [] export(bool) var debug = false export(NodePath) var level_path = 'res://levels/sample/level.tscn' var level = null export(float) var turn_max_length = 60.0 # Seconds var turn_time_left = -1.0 export(int) var population_start = 10 export(int) var jobs_start = 0 export(int) var food_start = 20 export(int) var resources_start = 0 export(int) var effort_start = 20 export(int) var goods_start = 0 var game_resources = { 'population': population_start, 'jobs': jobs_start, 'food': food_start, 'resources': resources_start, 'effort': effort_start, 'goods': goods_start, } var turns = 0 var build_regex = RegEx.new() var set_resource_regex = RegEx.new() # Game rules ish export(bool) var advance_turn_on_successful_command = true var game_object_registry = { # TileMap ID. this is a crap way. but hey. do it fast. 2: { "name": 'road', }, 3: { "name": 'road', }, 4: { 'name': 'road', }, 5: { 'name': 'road', }, 6: { 'name': 'bridge', }, 7: { 'name': 'house' }, 8: { "name": 'farm', "node_path": 'N/A', } } func _ready(): # Called every time the node is added to the scene. # Initialization here self.register_command('help', funcref(self, "command_help")) self.build_regex.compile("build (?[a-z_]*) (?\\d+),(?\\d+)") self.register_command('build', funcref(self, "command_build")) self.register_command('skip', funcref(self, 'command_skip')) self.set_level(self.level_path) if not self.debug: get_node('ui/left sidebar/toggleWorldButton').hide() if self.debug: self.register_command('set_resource', funcref(self, 'command_set_resource')) self.set_resource_regex.compile('set_resource (?[a-z_]*) (?\\d+)') get_node('ui/right sidebar/resources').update_resources(self.game_resources) func set_level(path): self.level = load(self.level_path).instance() self.level.hide() # Display? get_node('world').add_child(self.level) get_node('ui/right sidebar/MapSizeContainer').set_level_size(self.level.get_level_size()) # Set objects / simulation parameters. # Start time self.turn_time_left = self.turn_max_length get_node('ui/right sidebar/timer').set_time_max(self.turn_max_length) self.update_timer() func _process(delta): # # Called every frame. Delta is time since last frame. # # Update game logic here. self.turn_time_left -= delta if self.turn_time_left <= 0.0: self.advance_turn() self.update_timer() func advance_turn(): self.turn_time_left = self.turn_max_length # Find people who can't get to jobs # Find unfilled jobs # Report unconnected buildings # Update stats: consume food, word, etc. self.turns += 1 func update_timer(): get_node('ui/right sidebar/timer').set_time_left(self.turn_time_left) # A player has hit enter func _on_prompt_text_entered(new_text): history_append(new_text) if new_text: run_command(new_text) # @TODO Run the command get_node('ui/prompt').clear() func history_append(text, is_command_result = false, return_code = 0): var n = get_node('ui/ViewportContainer/history') if not n: return if is_command_result: if return_code != 0: n.push_color(Color(1.0, 0.0, 0.0, 1.0)) n.add_text(' > (%d) %s' %[return_code, text]) if return_code != 0: n.pop() else: n.add_text("$ " + text) n.newline() func history_search(): pass func run_command(text): var result; var callback = parse_command(text) if not callback[1]: result = [-1, 'Command "%s" not found' % callback[0]] else: result = callback[1].call_func(text) self.history_append(result[1], true, result[0]) # Possibly advance the turn depending on the game rule. if self.advance_turn_on_successful_command && result[0] == 0: self.advance_turn() func parse_command(text): var a = text.split(' ') if self.command_registry.has(a[0]): return [a[0], self.command_registry[a[0]]] return [a[0], false] func register_command(name, callback): self.command_registry[name] = callback; func remove_command(name): if self.command_registry.has(name): self.command_registry.erase(name); func command_help(text): print("received command: '%s'" % text) return [0, 'no!'] func command_set_resource(text): var r = self.set_resource_regex.search(text) if r == null: return [-1, 'set_resource command could not match arguments. Format: set_resource '] var resource_name = r.get_string(1) if ! self.game_resources.has(resource_name): return [-2, 'Resource "%s" does not exist' %resource_name] var value = int(r.get_string(2)) self.set_game_resource(resource_name, value) return [0, 'Set resource "%s" to %d' %[resource_name, value]] func set_game_resource(name, value): self.game_resources[name] = value get_node('ui/right sidebar/resources').update_resources(self.game_resources) func command_build(text): var r = self.build_regex.search(text) if r == null: return [-1, 'Build command could not match arguments. Format: build ,'] var object_id = _get_obj_id_by_name(r.get_string(1)) if object_id == null: return [-3, "Object with id '%s' is not registered" % r.get_string(1)] var p = Vector2(int(r.get_string(2)), int(r.get_string(3))) if not _is_in_level(p): return [-4, "Point %d,%d is not in current level" %[p.x, p.y]] var obj_exists = _obj_exists_in_level(p) if obj_exists: var obj_name = self.game_object_registry[_obj_in_level(p)]['name'] return [-5, "Object %s already exists at %d, %d" % [obj_name, p.x, p.y]] # Check if base terrain is valid. var terrain_object_id = self.level.get_node('terrain').get_cellv(p) if terrain_object_id == -1: return [-6, "No terrain underneath point at %d,%d" %[p.x, p.y]] # grass if terrain_object_id == 0 && object_id == 6: return [-7, "Can not build over water at %d,%d" %[p.x, p.y]] if terrain_object_id == 1 && object_id != 6: return [-8, "Can not build over grass at %d,%d" %[p.x, p.y]] # (optional) check resources # Build self.level.get_node('objects').set_cellv(p, object_id) # (optional) spend resources return [0, 'Built %s at %d,%d' % [self.game_object_registry[object_id]['name'], p.x, p.y]] func _is_in_level(v): if v.x >= self.level.origin.x and v.x <= self.level.origin.x + self.level.width and \ v.y >= self.level.origin.y and v.y <= self.level.origin.y + self.level.height: return true return false func _get_obj_id_by_name(n): for i in self.game_object_registry.keys(): if self.game_object_registry[i]['name'] == n: return i return null func _obj_in_level(v): var c = self.level.get_node('objects').get_cellv(v) if c == -1: return null return c func _obj_exists_in_level(v): if _obj_in_level(v) != null: return true return false func _on_toggleWorldButton_toggled(button_pressed): print(button_pressed) if self.level.is_visible_in_tree(): self.level.hide() else: self.level.show() func command_skip(t): self.advance_turn() return [0, 'OK'] func _on_timer_skip_presssed(): print('a') self.advance_turn()