0

Ok, i'm really bad at coding. I'm especially new to GODOT and am trying to make a 2d game. I've been able to set cant_move to false when dialog is playing, the problem I'm having is making cant_move true again. I don't even know where to put done = true on the dialog script (I kinda just put it in a random place and hoped it would work). Here is my dog-shit code. (the solution is probably easy im just really dumb)

npc script

`extends Area2D
var done = true


func _ready(): 
    Global.npc1 = self
func _exit_tree():
    Global.npc1 = null


var can_interact = false
const DIALOG = preload("res://dialoguebox.tscn")

func _physics_process(delta):
    $AnimatedSprite.play()

func diaplay():
    if done == false:
        Global.player.can_move = false
        print("test")

    if done == true:
        print("test2")
        can_interact = false
        Global.player.can_move = true

func _on_Area2D_body_entered(body):
    if body.name == "player":
        $Label.visible = true
        can_interact = true

func _on_Area2D_body_exited(body):
    if body.name == "player":
        $Label.visible = false
        can_interact = false

func _input(event):
    if Input.is_key_pressed(KEY_E) and can_interact == true:
        done = false
        diaplay()
        $Label.visible = false
        var dialog = DIALOG.instance()
        get_parent().add_child(dialog)
        dialog.position = $Position2D.global_position

dialog script

extends Control
var dialog = [
    'sampletext',
    'sampletext2',
]
var done = false
var dialog_index = 0
var finished = false


func _ready():
    load_dialog() 
    Global.DialogBox = self
    
func _exit_tree():
    Global.DialogBox = null

func _physics_process(delta):
    $"Ind".visible = finished
    if Input.is_action_just_pressed("ui_accept"):
        load_dialog()

func load_dialog():
    if dialog_index < dialog.size():
        finished = false
        $RichTextLabel.bbcode_text = dialog[dialog_index]
        $RichTextLabel.percent_visible = 0
        $Tween.interpolate_property(
            $RichTextLabel, "percent_visible",  0, 1, 1,
            Tween.TRANS_LINEAR, Tween.EASE_IN_OUT
        )
        $Tween.start()
    if dialog_index >= 0:
        Global.npc1.done = true
    else:
        queue_free()
        done = true
    dialog_index += 1
    
func _on_Tween_tween_completed(object, key):
    finished = true
Ajajajaj
  • 49
  • 9

2 Answers2

1

If I understand correctly, you are opening the UI with this code:

var dialog = DIALOG.instance()
get_parent().add_child(dialog)
dialog.position = $Position2D.global_position

So add the instruction to make can_move false there (Global.player.can_move = false).

And apparently it is all done here:

queue_free()

That is, the UI is removing it self. When the UI removes itself, it exits the scene tree, we are going to take advantage of that. Connect the tree_exited of the UI to a func that sets can_move true again:

    Global.player.can_move = false
    var dialog = DIALOG.instance()
    dialog.position = $Position2D.global_position
    dialog.connect("tree_exited", self, "dialog_exited")
    get_parent().add_child(dialog)

func dialog_exited() -> void:
    Global.player.can_move = true

That should do.

Alternatively you could create and emit a signal to notify when the player can move again. Refer to the documentation about signals.


Addendum

I think I got what else is not working. Look at load_dialog:

func load_dialog():
    if dialog_index < dialog.size():
        # ... some code ...
    if dialog_index >= 0:
        Global.npc1.done = true
    else:
        queue_free()
        done = true
    dialog_index += 1

The first check (dialog_index < dialog.size()) is if there is more dialog text. If there isn't then it is done. So change it to this:

func load_dialog():
    if dialog_index < dialog.size():
        # … some code …
    else:
        Global.npc1.done = true
        queue_free()
        done = true
    dialog_index += 1

I hope that makes sense.


You also mention you got an error in Global.player.can_move = true, I suppose that happened with closing the game, that code ran, and Global.player was no longer valid.

Regardless of the situation, you can check if the player is valid:

    var player = Global.player
    if is_instance_valid(player):
        player.can_move = true
Theraot
  • 31,890
  • 5
  • 57
  • 86
  • this doesn't seem to work for me. It removes movement when the player interacts, but it still wont move when the dialog is finished. I added exactly what you told me to add, but when the dialog is finished it still wont allow me to move again – Ajajajaj Nov 28 '21 at 14:48
  • i get the error `Invalid set index 'can_move' (on base: 'Nil') with value of type 'bool'.` Which i dont know why im getting cuz im dumb and don't know code that well – Ajajajaj Nov 28 '21 at 15:06
  • @JacobWhisenand see addendum. – Theraot Nov 28 '21 at 15:28
  • Thank You! I got it working – Ajajajaj Nov 28 '21 at 18:03
0

I don't have enough rep to comment but I just want to add that you have two different done variables. One in NPC and another in Dialog. You set them true here:

if dialog_index >= 0:
        Global.npc1.done = true
    else:
        queue_free()
        done = true

I think the problem might also be that dialog's done is never set true again. But I'm a noob too and Theraot always give good advice so check his answer again.

In fact he already solved this problem:

if dialog_index < dialog.size():
    # … some code …
else:
    Global.npc1.done = true
    queue_free()
    done = true
dialog_index += 1

For clarity i would try to use only one done variable, probably connecting the scrips with signals also as Theraot said.

uberflut
  • 120
  • 1
  • 7