Files
kicking-high/proto3/godot/scenes/characters/smart_object.gd
2020-04-13 12:45:25 +03:00

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()