2 Commits

Author SHA1 Message Date
  Non0w 325e7aa0d4 add draft crate push 4 years ago
  Non0w b59b2109ab remove old yarn files 4 years ago
15 changed files with 115 additions and 428 deletions
Split View
  1. +5
    -1
      jrpg/scenes/TestLVL.tscn
  2. +32
    -0
      jrpg/scenes/entities/Crate.tscn
  3. +0
    -1
      jrpg/scenes/entities/Enemy.tscn
  4. +0
    -1
      jrpg/scenes/entities/Switch.tscn
  5. +8
    -0
      jrpg/scripts/entities/crate.gd
  6. +1
    -1
      jrpg/scripts/entities/npc.gd
  7. +3
    -3
      jrpg/scripts/entities/pickup.gd
  8. +48
    -11
      jrpg/scripts/entities/player.gd
  9. +1
    -1
      jrpg/scripts/entities/switch.gd
  10. +17
    -3
      jrpg/scripts/entities/utils/trigger_relay.gd
  11. +0
    -6
      project.godot
  12. +0
    -1
      yarn/onivim2-crash.log
  13. +0
    -19
      yarn/scenes/YarnSpinner.tscn
  14. +0
    -25
      yarn/scripts/YarnSpinner.gd
  15. +0
    -355
      yarn/scripts/yarn-importer.gd

+ 5
- 1
jrpg/scenes/TestLVL.tscn View File

@@ -1,4 +1,4 @@
[gd_scene load_steps=32 format=2]
[gd_scene load_steps=33 format=2]

[ext_resource path="res://jrpg/scripts/levels/spawner.gd" type="Script" id=1]
[ext_resource path="res://jrpg/yarn_scripts/test_start.yarn" type="Resource" id=2]
@@ -17,6 +17,7 @@
[ext_resource path="res://jrpg/scripts/misc/test_level.gd" type="Script" id=15]
[ext_resource path="res://jrpg/models/nature/river/water.tres" type="Material" id=16]
[ext_resource path="res://jrpg/scenes/entities/Switch.tscn" type="PackedScene" id=17]
[ext_resource path="res://jrpg/scenes/entities/Crate.tscn" type="PackedScene" id=18]

[sub_resource type="PlaneMesh" id=1]
size = Vector2( 600, 600 )
@@ -418,4 +419,7 @@ shape = SubResource( 14 )

[node name="Switch" parent="." instance=ExtResource( 17 )]
transform = Transform( 1, 0, 0, 0, 0.0600904, 0.998193, 0, -0.998193, 0.0600904, 7.74067, -0.485543, -28.5048 )

[node name="Crate" parent="." instance=ExtResource( 18 )]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 8.32558, -1.44783, 0 )
[connection signal="switch" from="Switch" to="." method="_on_Switch_switch"]

+ 32
- 0
jrpg/scenes/entities/Crate.tscn View File

@@ -0,0 +1,32 @@
[gd_scene load_steps=6 format=2]

[ext_resource path="res://jrpg/scripts/entities/crate.gd" type="Script" id=1]
[ext_resource path="res://jrpg/scripts/entities/utils/trigger_relay.gd" type="Script" id=2]

[sub_resource type="CubeMesh" id=1]
size = Vector3( 1.5, 1.5, 1.5 )

[sub_resource type="BoxShape" id=2]
extents = Vector3( 0.75, 0.75, 0.75 )

[sub_resource type="BoxShape" id=3]
extents = Vector3( 0.75, 0.75, 0.75 )

[node name="Crate" type="KinematicBody"]
script = ExtResource( 1 )

[node name="MeshInstance" type="MeshInstance" parent="."]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.75, 0 )
mesh = SubResource( 1 )
material/0 = null

[node name="CollisionShape" type="CollisionShape" parent="."]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.75, 0 )
shape = SubResource( 2 )

[node name="InteractableArea" type="Area" parent="."]
script = ExtResource( 2 )

[node name="CollisionShape" type="CollisionShape" parent="InteractableArea"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.75, 0 )
shape = SubResource( 3 )

+ 0
- 1
jrpg/scenes/entities/Enemy.tscn View File

@@ -30,4 +30,3 @@ script = ExtResource( 3 )
transform = Transform( 1, 0, 0, 0, -1.62921e-07, 1, 0, -1, -1.62921e-07, 0, 1, 0 )
shape = SubResource( 2 )
[connection signal="timeout" from="Timer" to="." method="_on_Timer_timeout"]
[connection signal="on_interact" from="InteractableArea" to="." method="on_interact"]

+ 0
- 1
jrpg/scenes/entities/Switch.tscn View File

@@ -98,4 +98,3 @@ script = ExtResource( 2 )
[node name="CollisionShape" type="CollisionShape" parent="InteractableArea"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.35, 0 )
shape = SubResource( 7 )
[connection signal="on_interact" from="InteractableArea" to="." method="on_interact"]

+ 8
- 0
jrpg/scripts/entities/crate.gd View File

@@ -0,0 +1,8 @@
extends KinematicBody

func on_interact_pressed(interactor):
interactor.start_pushing(self)
func on_interact_released(interactor):
interactor.stop_pushing(self)

+ 1
- 1
jrpg/scripts/entities/npc.gd View File

@@ -4,5 +4,5 @@ class_name NPC

var yarn_script : Resource

func on_interact():
func on_interact_pressed(interactor):
EventDispatcher.emit_signal("trigger_script", yarn_script)

+ 3
- 3
jrpg/scripts/entities/pickup.gd View File

@@ -10,9 +10,9 @@ func _process (delta):
# rotate along the Y axis
rotate_y(rotateSpeed * delta)

func on_touch(body : KinematicBody):
func on_touch(interactor : KinematicBody):
# is this the player? If so give them gold
if body.is_in_group("Player"):
body.give_gold(goldToGive)
if interactor.is_in_group("Player"):
interactor.give_gold(goldToGive)
emit_signal("picked_up")
queue_free()

+ 48
- 11
jrpg/scripts/entities/player.gd View File

@@ -19,10 +19,19 @@ onready var camera = get_node("CameraOrbit")
onready var interactCast = get_node("InteractRayCast")
onready var anim = get_node("Casual2_Female/AnimationPlayer")

# internal

var interactables := []
var pushed_object

func _process(delta):
# attack input
if Controller.player_input_enabled and is_on_floor() and Input.is_action_just_pressed("interact"):
try_interact()
if Controller.player_input_enabled and is_on_floor():
if Input.is_action_just_pressed("interact"):
try_interact_pressed()
if Input.is_action_just_released("interact"):
try_interact_released()
for area in $TouchableArea.get_overlapping_areas():
try_touch(area)
@@ -62,7 +71,7 @@ func _physics_process (delta):
vel.z = dir.z * walkSpeed
# jump input
if Input.is_action_pressed("jump") and is_on_floor():
if can_jump():
vel.y = jumpForce
else:
vel.x = 0
@@ -80,8 +89,14 @@ func _physics_process (delta):
else:
anim.play("RecieveHit")
# move along the current velocity
var previous_vel = vel
# move pushed object first if there is one
if pushed_object:
var object_vel = pushed_object.move_and_slide(vel, Vector3.UP, true, 1, deg2rad(30))
vel.x = object_vel.x
vel.z = object_vel.z
# move along the current velocity
vel = move_and_slide(vel, Vector3.UP, true, 4, deg2rad(30))
"debug for water"
@@ -116,11 +131,33 @@ func try_touch(area):
area.on_touch(self)

# called when we press the interact button
func try_interact():
# is the ray cast colliding with an enemy?
func try_interact_pressed():
# play the animation
anim.stop()
anim.play("Idle")
for area in $InteractorArea.get_overlapping_areas():
# play the animation
anim.stop()
anim.play("Idle")
if area.has_method("on_interact"):
area.on_interact()
if area.has_method("on_interact_pressed"):
interactables.push_back(area)
area.on_interact_pressed(self)

# called when we release the interact button
func try_interact_released():
# play the animation
anim.stop()
anim.play("Idle")
for interactable in interactables:
if interactable.has_method("on_interact_released"):
interactable.on_interact_released(self)
interactables.clear()

func start_pushing(body):
pushed_object = body
func stop_pushing(body):
pushed_object = null

func can_jump():
return pushed_object == null and Input.is_action_pressed("jump") and is_on_floor()

+ 1
- 1
jrpg/scripts/entities/switch.gd View File

@@ -11,7 +11,7 @@ func _ready():
update_view()
emit_signal("switch", activated)

func on_interact():
func on_interact_pressed(interactor):
activated = !activated
update_view()
emit_signal("switch", activated)


+ 17
- 3
jrpg/scripts/entities/utils/trigger_relay.gd View File

@@ -1,6 +1,20 @@
extends Node

signal on_interact()
export var target_path : NodePath = ".."

func on_interact():
emit_signal("on_interact")
signal on_interact_pressed
signal on_interact_released

func _ready():
if target_path:
var target_node = get_node(target_path)
if target_node != null and target_node.has_method("on_interact_pressed"):
self.connect("on_interact_pressed", target_node, "on_interact_pressed")
if target_node != null and target_node.has_method("on_interact_released"):
self.connect("on_interact_released", target_node, "on_interact_released")

func on_interact_pressed(interactor):
emit_signal("on_interact_pressed", interactor)
func on_interact_released(interactor):
emit_signal("on_interact_released", interactor)

+ 0
- 6
project.godot View File

@@ -59,11 +59,6 @@ _global_script_classes=[ {
"language": "GDScript",
"path": "res://jrpg/scripts/misc/test_level.gd"
}, {
"base": "Node",
"class": "YarnImporter",
"language": "GDScript",
"path": "res://yarn/scripts/yarn-importer.gd"
}, {
"base": "Object",
"class": "YarnRunner",
"language": "GDScript",
@@ -90,7 +85,6 @@ _global_script_class_icons={
"SpeechPanel": "",
"SpeechText": "",
"TestLevel": "",
"YarnImporter": "",
"YarnRunner": "",
"YarnRunnerNode": "",
"YarnScript": ""


+ 0
- 1
yarn/onivim2-crash.log View File

@@ -1 +0,0 @@
Yojson.Json_error("Line 100, bytes 20-53:\nInvalid escape sequence 'Users\\Arnaud\\scoop\\apps\\godot\\cur'"):

+ 0
- 19
yarn/scenes/YarnSpinner.tscn View File

@@ -1,19 +0,0 @@
[gd_scene load_steps=4 format=2]

[ext_resource path="res://jrpg/scenes/ui/ChoicesBox.tscn" type="PackedScene" id=1]
[ext_resource path="res://main/scenes/LogPanel.tscn" type="PackedScene" id=2]
[ext_resource path="res://yarn/scripts/YarnSpinner.gd" type="Script" id=3]



[node name="YarnSpinner" type="Control"]
anchor_right = 1.0
anchor_bottom = 1.0
script = ExtResource( 3 )
__meta__ = {
"_edit_use_anchors_": false
}

[node name="ChoicesBox" parent="." instance=ExtResource( 1 )]

[node name="LogPanel" parent="." instance=ExtResource( 2 )]

+ 0
- 25
yarn/scripts/YarnSpinner.gd View File

@@ -1,25 +0,0 @@
extends YarnImporter

export var yarn_file = ""

func _ready():
$ChoicesBox.hide()
$LogPanel.hide()

func on_dialogue_start():
yield(.on_dialogue_start(), "completed")
$LogPanel.show()
$ChoicesBox.show()
$LogPanel.clear()
$ChoicesBox.clear()

func on_new_line(line):
yield($LogPanel.on_new_line(line), "completed")
func on_choices(choices_list):
return yield($ChoicesBox.on_choices(choices_list), "completed")

func on_dialogue_end():
yield(.on_dialogue_end(), "completed")
$ChoicesBox.hide()
$LogPanel.hide()

+ 0
- 355
yarn/scripts/yarn-importer.gd View File

@@ -1,355 +0,0 @@
extends Node
class_name YarnImporter

#
# A YARN Importer for Godot
#
# Credits:
# - Dave Kerr (http://www.naturallyintelligent.com)
#
# Latest: https://github.com/naturally-intelligent/godot-yarn-importer
#
# Yarn: https://github.com/InfiniteAmmoInc/Yarn
# Twine: http://twinery.org
#
# Yarn: a ball of threads (Yarn file)
# Thread: a series of fibres (Yarn node)
# Fibre: a text or choice or logic (Yarn line)

var yarn = {}

# OVERRIDE METHODS
#
# called to request new dialog
func on_new_line(text):
pass
# called to request new choice button
func on_choices(choices_list):
pass

# called to request internal logic handling
func logic(instruction, command):
pass
# called for each line of text
func yarn_text_variables(text):
return text
# called when "settings" node parsed
func story_setting(setting, value):
pass
# called for each node name
func on_node_start(to):
pass
yield(get_tree(), "idle_frame")

# called for each node name (after)
func on_node_end(to):
pass
yield(get_tree(), "idle_frame")

# START SPINNING YOUR YARN
#
func spin_yarn(file, start_thread = false):
yarn = load_yarn(file)
# Find the starting thread...
if not start_thread:
start_thread = yarn['start']
# Load any scene-specific settings
# (Not part of official Yarn standard)
if 'settings' in yarn['threads']:
var settings = yarn['threads']['settings']
for fibre in settings['fibres']:
var line = fibre['text']
var split = line.split('=')
var setting = split[0].strip_edges(true, true)
var value = split[1].strip_edges(true, true)
story_setting(setting, value)
# First thread unravel...
yield(on_dialogue_start(), "completed")
yield(yarn_unravel(start_thread), "completed")

# Internally create a new thread (during loading)
func new_yarn_thread():
var thread = {}
thread['title'] = ''
thread['kind'] = 'branch' # 'branch' for standard dialog, 'code' for gdscript
thread['tags'] = [] # unused
thread['fibres'] = []
return thread

func exec(stri):
var expr := Expression.new()
print("input : " + stri)
var err := expr.parse(stri)
if err == OK:
var res = expr.execute()
print("res : " + str(res))
else:
print("err : " + str(err))

func jajoujaj():
print("jaaaja")
# Internally create a new fibre (during loading)
func new_yarn_fibre(line:String):
# choice fibre
if line.substr(0,2) == '[[':
if line.find('|') != -1:
var fibre = {}
fibre['kind'] = 'choice'
line = line.replace('[[', '')
line = line.replace(']]', '')
var split = line.split('|')
fibre['text'] = split[0]
fibre['marker'] = split[1]
return fibre
else:
var fibre = {}
fibre['kind'] = 'jump'
line = line.replace('[[', '')
line = line.replace(']]', '')
fibre['marker'] = line
return fibre
# logic instruction (not part of official Yarn standard)
elif line.substr(0,2) == '<<':
line = line.replace('<<', '')
line = line.replace('>>', '')
var line_split = line.split(' ')
print (line_split)
var command = line.substr(line.find(' '))
exec(command)
# if line.find(':') != -1:
# fibre['kind'] = 'logic'
# line = line.replace('<<', '')
# line = line.replace('>>', '')
# var split = line.split(':')
# fibre['instruction'] = split[0]
# fibre['command'] = split[1]
# #print(line, split[0], split[1])
# return fibre
# text fibre
var fibre = {}
fibre['kind'] = 'text'
fibre['text'] = line
return fibre

# Create Yarn data structure from file (must be *.yarn.txt Yarn format)
func load_yarn(path):
var yarn = {}
yarn['threads'] = {}
yarn['start'] = false
yarn['file'] = path
var file = File.new()
file.open(path, file.READ)
if file.is_open():
# yarn reading flags
var start = false
var header = true
var thread = new_yarn_thread()
# loop
while !file.eof_reached():
# read a line
var line = file.get_line()
# header read mode
if header:
if line == '---':
header = false
else:
var split = line.split(': ')
if split[0] == 'title':
var title_split = split[1].split(':')
var thread_title = ''
var thread_kind = 'branch'
if len(title_split) == 1:
thread_title = split[1]
else:
thread_title = title_split[1]
thread_kind = title_split[0]
thread['title'] = thread_title
thread['kind'] = thread_kind
if not yarn['start']:
yarn['start'] = thread_title
# end of thread
elif line == '===':
header = true
yarn['threads'][thread['title']] = thread
thread = new_yarn_thread()
# fibre read mode
else:
var fibre = new_yarn_fibre(line)
if fibre:
thread['fibres'].append(fibre)
else:
print('ERROR: Yarn file missing: ', filename)
return yarn

# Main logic for node handling
#
func yarn_unravel(to, from=false):
if not to in yarn['threads']:
print('WARNING: Missing Yarn thread: ', to, ' in file ',yarn['file'])
return
while to != null and to in yarn['threads']:
yield (on_node_start(to), "completed")
if to in yarn['threads']:
var thread = yarn['threads'][to]
to = null
match thread['kind']:
'branch':
var i = 0
while i < thread['fibres'].size():
match thread['fibres'][i]['kind']:
'text':
var fibre = thread['fibres'][i]
var text = yarn_text_variables(fibre['text'])
yield(on_new_line(text), "completed")
'choice':
var choices = []
while i < thread['fibres'].size() and thread['fibres'][i]['kind'] == 'choice' :
var fibre = thread['fibres'][i]
var text = yarn_text_variables(fibre['text'])
choices.push_back({"text": text, "marker": fibre['marker']})
i += 1
to = yield(on_choices(choices), "completed")
break
'logic':
var fibre = thread['fibres'][i]
var instruction = fibre['instruction']
var command = fibre['command']
yield(logic(instruction, command), "completed")
'jump':
var fibre = thread['fibres'][i]
to = fibre['marker']
break
i += 1
'code':
yarn_code(to)
yield(on_node_end(to), "completed")
yield (on_dialogue_end(), "completed")

func on_dialogue_start():
pass
yield(get_tree(), "idle_frame")

func on_dialogue_end():
pass
yield(get_tree(), "idle_frame")

#
# RUN GDSCRIPT CODE FROM YARN NODE - Special node = code:title
# - Not part of official Yarn standard
#
func yarn_code(title, run=true, parent='parent.', tabs="\t", next_func="yarn_unravel"):
if title in yarn['threads']:
var thread = yarn['threads'][title]
var code = ''
for fibre in thread['fibres']:
match fibre['kind']:
'text':
var line = yarn_text_variables(fibre['text'])
line = yarn_code_replace(line, parent, next_func)
code += tabs + line + "\n"
'choice':
var line = parent+next_func+"('"+fibre['marker']+"')"
print(line)
code += tabs + line + "\n"
if run:
run_yarn_code(code)
else:
return code
else:
print('WARNING: Title missing in yarn ball: ', title)

# override to replace convenience variables
func yarn_code_replace(code, parent='parent.', next_func="yarn_unravel"):
if code.find("[[") != -1:
code = code.replace("[[", parent+next_func+"('")
code = code.replace("]]", "')")
code = code.replace("say(", parent+"say(")
code = code.replace("choice(", parent+"choice(")
return code

func run_yarn_code(code):
var front = "extends Node\n"
front += "func dynamic_code():\n"
front += "\tvar parent = get_parent()\n\n"
code = front + code
#print("CODE BLOCK: \n", code)

var script = GDScript.new()
script.set_source_code(code)
script.reload()

#print("Executing code...")
var node = Node.new()
node.set_script(script)
add_child(node)
var result = node.dynamic_code()
remove_child(node)

return result

# EXPORTING TO GDSCRIPT
#
# This code may not be directly usable
# Use if you need an exit from Yarn

func export_to_gdscript():
var script = ''
script += "func start_story():\n\n"
if 'settings' in yarn['threads']:
var settings = yarn['threads']['settings']
for fibre in settings['fibres']:
var line = fibre['text']
var split = line.split('=')
var setting = split[0].strip_edges(true, true)
var value = split[1].strip_edges(true, true)
script += "\t" + 'story_setting("' + setting + '", "' + value + '")' + "\n"
script += "\tstory_logic('" + yarn['start'] + "')\n\n"
# story logic choice/press event
script += "func story_logic(marker):\n\n"
script += "\tmatch marker:\n"
for title in yarn['threads']:
var thread = yarn['threads'][title]
match thread['kind']:
'branch':
var code = "\n\t\t'" + thread['title'] + "':"
var tabs = "\n\t\t\t"
for fibre in thread['fibres']:
match fibre['kind']:
'text':
code += tabs + 'say("' + fibre['text'] + '")'
'choice':
code += tabs + 'choice("' + fibre['text'] + '", "' + fibre['marker'] + '")'
'logic':
code += tabs + 'logic("' + fibre['instruction'] + '", "' + fibre['command'] + '")'
script += code + "\n"
'code':
var code = "\n\t\t'" + thread['title'] + "':"
var tabs = "\n\t\t\t"
code += "\n"
code += yarn_code(thread['title'], false, '', "\t\t\t", "story_logic")
script += code + "\n"
# done
return script

func print_gdscript_to_console():
print(export_to_gdscript())

func save_to_gdscript(filename):
var script = export_to_gdscript()
# write to file
var file = File.new()
file.open(filename, file.WRITE)
if not file.is_open():
print('ERROR: Cant open file ', filename)
return false
file.store_string(script)
file.close()


Loading…
Cancel
Save