extends Spatial class_name SmartObject # Declare member variables here. Examples: # var a = 2 # var b = "text" # Called when the node enters the scene tree for the first time. # Called every frame. 'delta' is the elapsed time since the previous frame. #func _process(delta): # pass var first var second var script1 var script2 var state = -1 var _state class SmartObjectState: var first var second var script1 var script2 var active = false var next_cond var exit_cond var stage_name func init(n, p1, s1, p2, s2): stage_name = n first = p1 second = p2 script1 = s1 script2 = s2 first.set_meta("smart_object", true) second.set_meta("smart_object", true) func activate(): second.add_collision_exception_with(first) second.global_transform = first.global_transform first.smart_obj(script1) second.smart_obj(script2) active = true func leave(): active = false func process(): if active: second.global_transform = first.global_transform func finalize(): second.remove_collision_exception_with(first) first.do_stop() second.do_stop() first.set_meta("smart_object", false) second.set_meta("smart_object", false) func parse(sc: String): var stages = {} var init_stage var cur_stage var cur_character for k in sc.split("\n"): var sc_line: String = k sc_line = sc_line.strip_edges() if sc_line.substr(0, 1) == "#": continue var words: = Array(sc_line.split(" ")) if words[0] == "stage": cur_stage = words[1] if !init_stage: init_stage = cur_stage elif words[0] == "init:": init_stage = cur_stage elif words[0] == "first:": cur_character = "first" elif words[0] == "second:": cur_character = "second" elif words[0] == "next_cond": assert(cur_stage) if !stages.has(cur_stage): stages[cur_stage] = {} stages[cur_stage].next_cond = words.slice(1, words.size() - 1) elif words[0] == "exit_cond": assert(cur_stage) if !stages.has(cur_stage): stages[cur_stage] = {} stages[cur_stage].exit_cond = words.slice(1, words.size() - 1) elif words[0] == "next_stage": assert(cur_stage) if !stages.has(cur_stage): stages[cur_stage] = {} stages[cur_stage].next_stage = words[1] elif words[0] == "mod_stat": assert(cur_stage) assert(cur_character) if !stages.has(cur_stage): stages[cur_stage] = {} if !stages[cur_stage].has(cur_character): stages[cur_stage][cur_character] = [] if !stages[cur_stage].has("mod_stats"): stages[cur_stage].mod_stats = {} if !stages[cur_stage].mod_stats.has(cur_character): stages[cur_stage].mod_stats[cur_character] = {} stages[cur_stage].mod_stats[cur_character][words[1]] = float(words[2]) else: assert(cur_stage) assert(cur_character) if !stages.has(cur_stage): stages[cur_stage] = {} if !stages[cur_stage].has(cur_character): stages[cur_stage][cur_character] = [] stages[cur_stage][cur_character].push_back(words) for k in stages: for e in stages[k]: if e == "mod_stats": continue if !stages[k].has("mod_stats"): stages[k].mod_stats = {} if !stages[k].mod_stats.has(e): stages[k].mod_stats[e] = {} stages.init_stage = init_stage print(stages) return stages func activate(npc, m_script, s, s_script): main.init(npc, m_script, s, s_script) _state = main main.activate() var _stages var _exit_cond var npcs = {} func activate2(npc, s, script): npcs.first = npc npcs.second = s _stages = parse(script) for k in _stages.keys(): if k == "init_stage": continue var st = SmartObjectState.new() _stages[k].obj = st _stages[k].obj.init(k, npc, _stages[k].first, s, _stages[k].second) if _stages[k].has("next_cond"): _stages[k].obj.next_cond = _stages[k].next_cond if _stages[k].has("exit_cond"): _stages[k].obj.exit_cond = _stages[k].exit_cond if k == _stages.init_stage: _state = st _state.activate() func cond_stat_morethan(which, stat, val): if npcs[which].get_meta(stat) > float(val): return true return false func cond_stat_lessthan(which, stat, val): if npcs[which].get_meta(stat) < float(val): return true return false func _physics_process(delta): if _state: _state.process() var nextc = false var leave = false for k in _stages[_state.stage_name]: if k in ["mod_stats", "next_stage", "next_cond", "obj"]: continue var mod_stats = _stages[_state.stage_name].mod_stats[k] for l in mod_stats.keys(): if npcs.has(k): var sval = npcs[k].get_meta(l) sval += mod_stats[l] * delta npcs[k].set_meta(l, sval) if _state.next_cond: var c = _state.next_cond if c.size() > 1: nextc = callv(c[0], c.slice(1, c.size() - 1)) else: nextc = callv(c[0], []) if _state.exit_cond: var c = _state.exit_cond if c.size() > 1: leave = callv(c[0], c.slice(1, c.size() - 1)) else: leave = callv(c[0], []) if nextc: _state.leave() if _stages[_state.stage_name].has("next_stage"): var next = _stages[_state.stage_name].next_stage _state = _stages[next].obj _state.activate() else: _state.finalize() _state = null queue_free() if leave: _state.finalize() _state = null queue_free() var main func _ready(): main = SmartObjectState.new()