200 lines
5.1 KiB
GDScript3
200 lines
5.1 KiB
GDScript3
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()
|