proto3 initial commit

This commit is contained in:
Segey Lapin
2020-04-13 12:45:25 +03:00
parent 69410badf6
commit 1084b6d5c3
1588 changed files with 368852 additions and 23 deletions

View File

@@ -0,0 +1,83 @@
extends Node
var projectile: = preload("res://scenes/weapons/projectile.tscn")
func _ready():
pass # Replace with function body.
var handles = {}
func body_enter(obj, pj):
# if !obj is StaticBody:
# print("body enter: ", obj.name)
if obj.is_in_group("characters"):
rpg.projectile_attack(pj, obj)
rpg.add_agression(obj, 1.3)
# else:
# if obj is StaticBody:
# pj.queue_free()
func register(obj):
assert(obj.is_in_group("characters"))
var obj_path = get_path_to(obj)
var skel = obj.get_skeleton()
var att: = BoneAttachment.new()
att.bone_name = "grabber_R"
skel.add_child(att)
var att_path = get_path_to(att)
handles[obj_path] = att_path
var anim:AnimationPlayer = obj.get_anim_player()
var throw_anim: Animation = anim.get_animation("throw").duplicate()
var track = throw_anim.add_track(Animation.TYPE_METHOD)
throw_anim.track_set_path(track, "/root/combat")
# throw_anim.track_insert_key(track, 0.05, {"method": "shoot", "args": [obj]})
throw_anim.track_insert_key(track, throw_anim.length - 0.02, {"method": "shoot", "args": [obj]})
anim.remove_animation("throw")
var ret = anim.add_animation("throw", throw_anim)
assert(ret == OK)
func shoot(from):
assert(from.is_in_group("characters"))
# print(from.name, " shoots projectile")
var obj_path = get_path_to(from)
var handle_path = handles[obj_path]
var handle = get_node(handle_path)
var from_pos = handle.global_transform.origin
var from_dir = -from.global_transform.basis[2]
# top impulse 6000
# ok = 100
# so-so = 50
var stamina = from.get_meta("stamina")
if stamina > 5:
var impulse = from_dir * (10.0 + clamp(from.get_meta("strength") / 4.0, 0, 10) + randi() % int(clamp((1 + from.get_meta("strength") / 4.0), 0, 5)))
var pj = projectile.instance()
pj.connect("body_entered", self, "body_enter", [pj])
get_node("/root").add_child(pj)
pj.set_meta("owner", from)
pj.global_transform.origin = from_pos
pj.add_collision_exception_with(from)
pj.apply_impulse(Vector3(), impulse)
stamina -= 5 + impulse.length() / (1 + from.get_meta("strength") * 0.1)
if stamina < 0:
stamina = 0
from.set_meta("stamina", stamina)
# print("set stamina to: ", from.name)
func player_nearby(obj, dst):
assert(obj.is_in_group("characters"))
var ppos = global.player.global_transform.origin
var opos = obj.global_transform.origin
if opos.distance_to(ppos) < dst:
return true
return false
func enemy_nearby(obj, dst):
if !obj.is_in_group("npc"):
return false
var bb = obj.get_node("blackboard")
var enemy = bb.get("last_enemy")
if enemy:
var ppos = enemy.global_transform.origin
var opos = obj.global_transform.origin
if opos.distance_to(ppos) < dst:
return true
return false

View File

@@ -0,0 +1,54 @@
extends Node
var raycasts_count = 100
var raycast_queue = []
func _ready():
set_save_slot(0)
func visibility_check(ch1, ch2):
var direction: Vector3 = -ch1.global_transform.basis[2].normalized()
var to_ch2: Vector3 = (ch2.global_transform.origin - ch1.global_transform.origin).normalized()
var angle = direction.angle_to(to_ch2)
if abs(angle) < PI / 2.0:
var space_state = ch1.get_world().direct_space_state
var ch1_pos = ch1.global_transform.origin
var ch2_pos = ch2.global_transform.origin
var up = Vector3(0, 0.6, 0)
var front_result = space_state.intersect_ray(ch1_pos + up, ch2_pos + up,
[ch1, ch2], 0xffff)
if !front_result.has("collider"):
return true
return false
var player = null
var smart_object = []
const save_slot_base = "user://save"
var save_slot = ""
func set_save_slot(id: int):
save_slot = save_slot_base + str(id)
var save_data: Dictionary = {}
func save_characters():
for k in get_tree().get_nodes_in_group("characters"):
var spawner = k.get_meta("spawner")
var stats = {}
for s in rpg.save_stats:
stats[s] = k.get_meta(s)
spawner.set_meta("stats", stats)
func save_game():
assert(save_slot.length() > 0)
var fd = File.new()
fd.open(save_slot, File.WRITE)
var data = JSON.print(save_data, "\t", true)
fd.store_string(data)
fd.close()
func load_game():
assert(save_slot.length() > 0)
var fd = File.new()
if fd.open(save_slot, File.READ) == OK:
var data = fd.get_as_text()
var parse: = JSON.parse(data)
save_data = parse.result
fd.close()

View File

@@ -0,0 +1,123 @@
extends Node
var grab_queue = []
var ungrab_queue = []
func _ready():
pass # Replace with function body.
func grab_character(gch, ch):
if !ch.get_meta("grabbed"):
ch.set_meta("grabbed", true)
ch.set_meta("grabbed_time", 20.0)
if !ch in grab_queue:
grab_queue.push_back([gch, ch])
gch.set_meta("grabbing", true)
gch.do_grab()
func ungrab_character(gch, finisher = null):
if !grab_data.has(gch):
return
var ch = grab_data[gch].item
ch.set_meta("grabbed", false)
ch.set_meta("grabbed_time", 0.0)
if !ch in ungrab_queue:
if finisher:
ungrab_queue.push_back([gch, ch, finisher])
else:
ungrab_queue.push_back([gch, ch])
gch.set_meta("grabbing", false)
gch.do_ungrab()
var grab_data = {}
func get_grabbed(gch):
if grab_data.has(gch):
return grab_data[gch].item
else:
return null
func get_bone_xform(ch, b):
var skel = ch.get_skeleton()
var bone_id = skel.find_bone(b)
assert(bone_id >= 0)
var xform = skel.get_bone_global_pose(bone_id)
return ch.global_transform * xform
func left_arm_ik_enable(m: Spatial, _s: Spatial, target: Spatial):
# var item_skel = s.get_skeleton()
var main_skel = m.get_skeleton()
var ik: = SkeletonIK.new()
# var xf = get_bone_xform(m, "wrist_L")
var conv = target
ik.root_bone = "upperarm01_L"
ik.tip_bone = "wrist_L"
main_skel.add_child(ik)
var tpath = ik.get_path_to(conv)
ik.target_node = tpath
ik.min_distance = 0.01
ik.magnet = Vector3(-8, -10, 0)
ik.use_magnet = true
ik.start()
m.set_meta("left_arm_ik", m.get_path_to(ik))
func left_arm_ik_disable(m):
if m.has_meta("left_arm_ik"):
var ik = m.get_node(m.get_meta("left_arm_ik"))
# print("ik stopped")
ik.interpolation = 0.0
ik.use_magnet = false
ik.stop()
ik.queue_free()
func left_arm_front_neck_ik_enable(m, s):
var target = s.get_front_neck_target()
left_arm_ik_enable(m, s, target)
func left_arm_front_neck_ik_disable(m):
left_arm_ik_disable(m)
func _physics_process(_delta):
while grab_queue.size() > 0:
var characters = grab_queue.pop_front()
var item: KinematicBody = characters[1]
var gch = characters[0]
if grab_data.has(gch):
continue
grab_data[gch] = {}
item.do_stop()
item.do_grabbed()
gch.add_collision_exception_with(item)
item.add_collision_exception_with(gch)
# item.do_disable_collision()
item.global_transform = gch.global_transform
# var grab_xform = Transform()
# grab_xform.origin = gch.calc_offset(item, "neck02")
grab_data[gch].item = item
# grab_data[gch].grab_attachment = gch.add_attachment(gch.grab_bone, grab_xform)
grab_data[gch].grabbed_mask = item.collision_mask
grab_data[gch].grabbed_parent = item.get_parent()
item.collision_mask = 0
item.get_parent().remove_child(item)
# grab_data[gch].grab_attachment.add_child(item)
gch.add_child(item)
item.transform = Transform()
item.orientation.basis = Basis()
var ik_enable = true
if ik_enable:
left_arm_front_neck_ik_enable(gch, item)
while ungrab_queue.size() > 0:
var characters = ungrab_queue.pop_front()
var item: KinematicBody = characters[1]
var gch = characters[0]
var finisher = null
if characters.size() >= 3:
finisher = characters[2]
var tf = item.global_transform
# print("ik disable")
left_arm_front_neck_ik_disable(gch)
# grab_data[gch].grab_attachment.remove_child(item)
gch.remove_child(item)
grab_data[gch].grabbed_parent.add_child(item)
gch.remove_collision_exception_with(item)
item.remove_collision_exception_with(gch)
item.collision_mask = grab_data[gch].grabbed_mask
item.global_transform = tf
if !finisher:
item.do_stop()
item.do_ungrabbed()
else:
# print("finisher: ", finisher)
item.smart_obj(finisher)
item.set_meta("grabbed", false)
grab_data.erase(gch)
for k in grab_data.keys():
grab_data[k].item.transform = Transform()

View File

@@ -0,0 +1,39 @@
extends Node
enum {STATE_INIT, STATE_SIM, STATE_PAUSE}
var state = STATE_INIT
func _ready():
pass # Replace with function body.
var bone_ids = []
#func _physics_process(delta):
# match(state):
# STATE_INIT:
# for k in get_tree().get_nodes_in_group("female"):
# if !k.is_in_group("characters"):
# continue
# var sk: Skeleton = k.get_skeleton()
# if bone_ids.size() == 0:
# for c in range(sk.get_bone_count()):
# var bn = sk.get_bone_name(c)
# if bn.begins_with("skirt"):
# var pose = sk.get_bone_global_pose(c)
# sk.set_bone_global_pose_override(c, pose, 1.0)
# bone_ids.push_back(c)
# if bone_ids.size() > 0:
# state = STATE_SIM
# STATE_SIM:
# for k in get_tree().get_nodes_in_group("female"):
# if !k.is_in_group("characters"):
# continue
# var sk: Skeleton = k.get_skeleton()
# for c in bone_ids:
# var pose = sk.get_bone_global_pose(c)
# pose.origin.y -= 200.0 * delta
# sk.set_bone_global_pose_override(c, pose,1.0)
# state = STATE_PAUSE
# STATE_PAUSE:
# yield(get_tree().create_timer(0.1), "timeout")
# state = STATE_SIM

View File

@@ -0,0 +1,286 @@
extends Node
func _ready():
pass # Replace with function body.
var stats = {
"health": {"rise": 0.0005, "base": 100, "random": 1000, "bonus": 10000},
"stamina": {"rise": 0.0012, "base": 100, "random": 1000, "bonus": 10000},
"strength": {"rise": 0.0, "base": 100, "random": 1000, "bonus": 10000},
"agility": {"rise": 0.0, "base": 100, "random": 1000, "bonus": 10000},
"intelligence": {"rise": 0.0, "base": 100, "random": 1000, "bonus": 10000},
}
var needs = {
"hunger": {
"stat": "max_health",
"mul": 0.001
},
"thirst": {
"stat": "max_health",
"mul": 0.001
},
"lust": {
"stat": "strength",
"mul": 0.002
}
}
func create_stats(obj):
assert(obj.is_in_group("characters"))
for k in stats.keys():
var kmax = "max_" + k
var val = stats[k].base + randi() % stats[k].random
obj.set_meta(k, val)
obj.set_meta(kmax, val)
obj.set_meta("submission", 0)
obj.set_meta("agression", 0)
obj.set_meta("panic", 0)
obj.set_meta("xp", 0)
obj.set_meta("next_xp", 100)
obj.set_meta("level", 1)
for k in needs.keys():
obj.set_meta(k, 0.0)
if obj.is_in_group("guard"):
var st = obj.get_meta("max_strength")
if st < 1000.0:
obj.set_meta("strength", st)
obj.set_meta("max_strength", st)
var sm = obj.get_meta("max_stamina")
if sm < 2000.0:
obj.set_meta("stamina", sm)
obj.set_meta("max_stamina", sm)
if obj.is_in_group("maid"):
var subm = obj.get_meta("submission")
if subm < 1000.0:
obj.set_meta("submission", subm)
var save_stats = [
"health",
"stamina",
"strength",
"agility",
"intelligence",
"submission",
"xp",
"next_xp",
"level"]
func update_needs(obj):
for k in needs.keys():
var s = needs[k].stat
var m = needs[k].mul
var nval = obj.get_meta(k)
nval += obj.get_meta(s) * m * get_process_delta_time()
obj.set_meta(k, nval)
func update_stats(obj):
assert(obj.is_in_group("characters"))
if obj.get_meta("grabbing"):
return
if obj.get_meta("smart_object"):
return
for k in stats.keys():
var val = obj.get_meta(k)
var max_val = obj.get_meta("max_" + k)
var incr = stats[k].rise * max_val * get_process_delta_time()
# print("incr: ", obj.name, " ", incr)
if val < 0.1 * max_val:
val += 0.3 * incr
else:
val += incr
# print("stat: ", k, " incr: ", incr, " val: ", val)
obj.set_meta(k, clamp(val, 0, max_val))
var sub = get_submission(obj)
var aggr = get_agression(obj)
var pnc = get_panic(obj)
var pnc_inc = 0.0
var aggr_inc = 0.0
if combat.enemy_nearby(obj, 4.0):
pnc_inc += 1.0 / (1.0 + sub * 2.0)
aggr_inc += get_strength(obj) / (1.0 + pnc + sub)
if obj.is_in_group("maid"):
pnc_inc *= 0.1
elif obj.is_in_group("guard"):
pnc_inc = 0.0
else:
pnc_inc -= 0.5 * (get_strength(obj) + (1.0 + sub))
if obj.is_in_group("maid"):
pnc_inc *= 100.0
if obj.is_in_group("guard"):
pnc_inc *= 200.0
if obj.is_in_group("maid"):
pnc_inc *= 0.1
aggr += aggr_inc * get_process_delta_time()
pnc += pnc_inc * get_process_delta_time()
aggr = clamp(aggr, 0.0, 100000.0)
pnc = clamp(pnc, 0.0, 100000.0)
obj.set_meta("panic", pnc)
obj.set_meta("agression", aggr)
func level_up(obj):
assert(obj.is_in_group("characters"))
var level = obj.get_meta("level")
var next_xp = obj.get_meta("next_xp")
for k in stats.keys():
var kmax = "max_" + k
if level < 100:
var val = obj.get_meta(kmax) + stats[k].bonus / (100 - level)
obj.set_meta(kmax, val)
obj.set_meta(k, val)
else:
var val = obj.get_meta(kmax) + stats[k].bonus
obj.set_meta(kmax, val)
obj.set_meta(k, val)
if level < 100:
next_xp += int(clamp(level * next_xp / 5, 50, next_xp * 2))
else:
next_xp += int(next_xp * 1.5)
level += 1
dump_stats(obj)
func update_xp(obj, xp):
assert(obj.is_in_group("characters"))
var cur_xp = obj.get_meta("xp")
var next_xp = obj.get_meta("next_xp")
cur_xp += xp
if cur_xp >= next_xp:
level_up(obj)
cur_xp -= next_xp
obj.set_meta("xp", cur_xp)
func can_attack(obj):
assert(obj.is_in_group("characters"))
if obj.get_meta("grabbed"):
return false
if obj.get_meta("smart_object"):
return false
if obj.get_meta("health") <= 0:
return false
if obj.get_meta("stamina") <= 0:
return false
return true
func melee_attack(attacker, enemy):
assert(attacker.is_in_group("characters"))
assert(enemy.is_in_group("characters"))
if !can_attack(attacker):
return
var attack_base = int(attacker.get_meta("strength"))
var attack_bonus = int(attacker.get_meta("agility"))
var attack_val = attack_base + randi() % (1 + attack_bonus)
var defence = enemy.get_meta("agility") + randi() % (1 + int(enemy.get_meta("strength")))
var damage = int(clamp(attack_val - defence, 0, attack_val))
var enemy_health = int(enemy.get_meta("health"))
enemy_health = int(clamp(enemy_health - damage, 0, enemy_health))
enemy.set_meta("health", enemy_health)
var stamina = attacker.get_meta("stamina")
stamina -= damage / (2 + attacker.get_meta("agility"))
attacker.set_meta("stamina", stamina)
if enemy_health == 0:
update_xp(attacker, int(enemy.get_meta("max_health") * 0.1))
else:
update_xp(attacker, int(damage * 0.1))
# dump_stats(enemy)
func projectile_attack(pj, enemy):
var damage = pj.get_mass() * pj.get_linear_velocity().length() * 3.0
# print("DAMAGE: ", damage)
if pj.has_meta("owner"):
var attacker = pj.get_meta("owner")
update_xp(attacker, int(10 + damage))
var enemy_health = int(enemy.get_meta("health"))
enemy_health = int(clamp(enemy_health - damage, 0, enemy_health))
enemy.set_meta("health", enemy_health)
# dump_stats(enemy)
func submission_check(attacker, enemy):
assert(attacker.is_in_group("characters"))
assert(enemy.is_in_group("characters"))
var astrength = attacker.get_meta("strength")
var estrength = enemy.get_meta("strength")
var esub = enemy.get_meta("submission")
if astrength > estrength + esub:
return true
return false
func strength_check(attacker, enemy):
assert(attacker.is_in_group("characters"))
assert(enemy.is_in_group("characters"))
var astrength = attacker.get_meta("strength")
var estrength = attacker.get_meta("strength")
if astrength * 0.5 > estrength:
return true
return false
func dump_stats(obj):
assert(obj.is_in_group("characters"))
# print(stats.keys())
for k in stats.keys():
assert(obj.get_meta(k))
print(k + ": ", obj.get_meta(k))
print("submission: ", obj.get_meta("submission"))
print("xp: ", obj.get_meta("xp"))
print("next_xp: ", obj.get_meta("next_xp"))
print("level: ", obj.get_meta("level"))
func damage_stamina(obj, val):
assert(obj.is_in_group("characters"))
var stamina = obj.get_meta("stamina")
var max_stamina = obj.get_meta("max_stamina")
stamina -= val
obj.set_meta("stamina", clamp(stamina, 0.0, max_stamina))
func get_health(obj):
assert(obj.is_in_group("characters"))
var health = obj.get_meta("health")
return health
func get_stamina(obj):
assert(obj.is_in_group("characters"))
var stamina = obj.get_meta("stamina")
return stamina
func get_strength(obj):
assert(obj.is_in_group("characters"))
var strength = obj.get_meta("strength")
return strength
func get_agression(obj):
assert(obj.is_in_group("characters"))
var agression = obj.get_meta("agression")
return agression
func get_submission(obj):
assert(obj.is_in_group("characters"))
var submission = obj.get_meta("submission")
return submission
func get_panic(obj):
assert(obj.is_in_group("characters"))
var panic = obj.get_meta("panic")
return panic
func get_lust(obj):
assert(obj.is_in_group("characters"))
var lust = obj.get_meta("lust")
return lust
func add_panic(obj, val):
assert(obj.is_in_group("characters"))
var panic = get_panic(obj)
panic += val
obj.set_meta("panic", panic)
func add_agression(obj, val):
assert(obj.is_in_group("characters"))
var agression = get_agression(obj)
agression += val
obj.set_meta("panic", agression)
func is_enemy(ch1, ch2):
var versus = [
["player", "player", false],
["player", "guard", false],
["player", "maid", false],
["player", "captive", true],
["guard", "guard", false],
["guard", "player", false],
["guard", "maid", false],
["guard", "captive", true],
["maid", "maid", false],
["maid", "player", false],
["maid", "guard", true],
["maid", "captive", true],
["captive", "player", true],
["captive", "guard", true],
["captive", "maid", true],
["captive", "captive", false]
]
for e in versus:
if ch1.is_in_group(e[0]) && ch2.is_in_group(e[1]):
return e[2]
return false