Game data commit
This commit is contained in:
132
proto1/npc.gd
Normal file
132
proto1/npc.gd
Normal file
@@ -0,0 +1,132 @@
|
||||
extends KinematicBody2D
|
||||
signal arrived
|
||||
|
||||
enum {STATE_IDLE, STATE_WALKTO, STATE_DIALOGUE, STATE_FOLLOW, STATE_CONTROL}
|
||||
var destination = Vector2()
|
||||
var state = STATE_IDLE
|
||||
var velocity = Vector2()
|
||||
var next_dst = Vector2()
|
||||
var nav: Navigation2D
|
||||
var arrived = false
|
||||
var dst_node
|
||||
|
||||
func _ready():
|
||||
nav = get_node("/root/main/nav")
|
||||
add_to_group("npc")
|
||||
func calc_next_dst():
|
||||
var path = nav.get_simple_path(nav.get_closest_point(global_position), nav.get_closest_point(destination))
|
||||
if path.size() > 1:
|
||||
var ok = false
|
||||
for p in path:
|
||||
if global_position.distance_squared_to(p) >= 25.0:
|
||||
next_dst = p
|
||||
ok = true
|
||||
break
|
||||
if !ok:
|
||||
if global_position.distance_squared_to(destination) < 25.0:
|
||||
next_dst = destination
|
||||
else:
|
||||
next_dst = global_position + (destination - global_position).normalized() * 20.0 + Vector2(randf() - 0.5, randf() - 0.5) * 40.0
|
||||
else:
|
||||
next_dst = destination
|
||||
func update_destination():
|
||||
destination = dst_node.global_position
|
||||
func walkto(p: Vector2):
|
||||
arrived = false
|
||||
destination = p
|
||||
state = STATE_WALKTO
|
||||
calc_next_dst()
|
||||
func follow(n: Node2D):
|
||||
arrived = false
|
||||
state = STATE_FOLLOW
|
||||
dst_node = n
|
||||
update_destination()
|
||||
calc_next_dst()
|
||||
func avoidance(delta):
|
||||
var avdst = 800.0
|
||||
var velsum = Vector2()
|
||||
for n in get_tree().get_nodes_in_group("npc"):
|
||||
if n == self:
|
||||
continue
|
||||
var dist = n.global_position.distance_squared_to(global_position)
|
||||
if dist < avdst:
|
||||
var d = global_position - n.global_position
|
||||
velsum += d
|
||||
velocity = velocity.linear_interpolate(velsum.normalized() * velocity.length() + Vector2(randf() - 0.5, randf() - 0.5) * velocity.length() * 0.3, delta)
|
||||
func flock(delta):
|
||||
var avdst = 3600.0
|
||||
var maxdst = 10000.0
|
||||
var velsum = Vector2()
|
||||
for n in get_tree().get_nodes_in_group("npc"):
|
||||
if n == self:
|
||||
continue
|
||||
var dist = n.global_position.distance_squared_to(global_position)
|
||||
if dist > avdst && dist < maxdst:
|
||||
var d = global_position - n.global_position
|
||||
velsum += -d
|
||||
velocity = velocity.linear_interpolate(velsum.normalized() * velocity.length() + Vector2(randf() - 0.5, randf() - 0.5) * velocity.length() * 0.3, delta)
|
||||
func attack():
|
||||
var bodies = $capture.get_overlapping_bodies()
|
||||
for b in bodies:
|
||||
if b is RigidBody2D:
|
||||
var e = velocity
|
||||
if e.length() == 0:
|
||||
e = Vector2(randf() - 0.5, randf() - 0.5)
|
||||
b.apply_impulse(Vector2(), e.normalized() * (100.0 + 100.0 * randf()))
|
||||
elif b.is_in_group("npc"):
|
||||
var e = velocity * 2.0
|
||||
if e.length() == 0:
|
||||
e = Vector2(randf() - 0.5, randf() - 0.5) * 5000.0
|
||||
b.velocity = e
|
||||
b.move_and_slide(e)
|
||||
func _process(delta):
|
||||
match(state):
|
||||
STATE_IDLE:
|
||||
if randf() > 0.99:
|
||||
velocity = velocity.linear_interpolate(Vector2(randf() * 300.0 - 150.0, randf() * 300.0 - 150.0), 0.1 + delta * 0.9)
|
||||
else:
|
||||
velocity = velocity.linear_interpolate(Vector2(), delta)
|
||||
avoidance(delta)
|
||||
flock(delta)
|
||||
velocity = move_and_slide(velocity)
|
||||
STATE_WALKTO:
|
||||
var vel_base = 540.0
|
||||
if global_position.distance_squared_to(next_dst) < 25.0:
|
||||
calc_next_dst()
|
||||
if global_position.distance_squared_to(next_dst) < 900.0:
|
||||
vel_base = 160.0
|
||||
var dir = (next_dst - position).normalized()
|
||||
velocity = velocity.linear_interpolate(dir * vel_base, 0.3 * delta)
|
||||
avoidance(delta)
|
||||
flock(delta)
|
||||
if velocity.length() < 3.0:
|
||||
velocity += Vector2(randf() - 0.5, randf() - 0.5) * 6.0
|
||||
attack()
|
||||
velocity = move_and_slide(velocity)
|
||||
if global_position.distance_squared_to(destination) < 25.0:
|
||||
emit_signal("arrived", destination)
|
||||
state = STATE_IDLE
|
||||
arrived = true
|
||||
STATE_FOLLOW:
|
||||
var vel_base = 540.0
|
||||
update_destination()
|
||||
calc_next_dst()
|
||||
if global_position.distance_squared_to(next_dst) < 900.0:
|
||||
vel_base = 160.0
|
||||
var dir = (next_dst - position).normalized()
|
||||
velocity = velocity.linear_interpolate(dir * vel_base, 0.3 * delta)
|
||||
avoidance(delta)
|
||||
flock(delta)
|
||||
if velocity.length() < 3.0:
|
||||
velocity += Vector2(randf() - 0.5, randf() - 0.5) * 6.0
|
||||
attack()
|
||||
velocity = move_and_slide(velocity)
|
||||
if global_position.distance_squared_to(destination) < 25.0:
|
||||
emit_signal("arrived", destination)
|
||||
state = STATE_IDLE
|
||||
arrived = true
|
||||
STATE_DIALOGUE:
|
||||
pass
|
||||
STATE_CONTROL:
|
||||
pass
|
||||
|
||||
Reference in New Issue
Block a user