# State System Examples

## Overview
The StateManager handles two types of variables:
- **Loop State**: Resets every time loop (NPCs talked to, items collected, doors unlocked, flags)
- **Persistent State**: Survives across loops (knowledge, unlocks, story flags, achievements)

## Basic Usage

### Setting and Checking Flags (Loop State)

```gdscript
# In an NPC script
func interact():
    if StateManager.has_flag("beach_door_opened"):
        show_dialogue("You already opened the door this loop!")
    else:
        StateManager.set_flag("beach_door_opened")
        show_dialogue("You opened the door!")
        # Door opens...
```

### Tracking NPC Conversations (Loop State)

```gdscript
# In NPC script
func talk():
    var npc_id = "fisherman_bob"
    
    if StateManager.has_talked_to_npc(npc_id):
        show_dialogue("We already talked this loop.")
    else:
        StateManager.add_npc_talked(npc_id)
        show_dialogue("First time talking this loop!")
```

### Persistent Knowledge (Survives Loops)

```gdscript
# Player learns a secret code
func discover_code():
    StateManager.add_knowledge("safe_code_1234")
    show_dialogue("You memorize the code: 1234")

# Later, even in a different loop:
func try_open_safe():
    if StateManager.has_knowledge("safe_code_1234"):
        show_dialogue("You remember the code!")
        open_safe()
    else:
        show_dialogue("You don't know the code.")
```

### Permanent Unlocks (Survives Loops)

```gdscript
# Unlock a shortcut
func find_shortcut():
    StateManager.add_unlock("beach_to_cave_shortcut")
    show_dialogue("You found a shortcut! It will remain open in future loops.")

# Check if unlocked
func _ready():
    if StateManager.has_unlock("beach_to_cave_shortcut"):
        $ShortcutDoor.visible = true
```

## Time-Based Events

```gdscript
# In a level script
func _process(_delta):
    var time = TimeManager.get_current_time()
    
    # Event at 15:00
    if time.hours == 15 and time.minutes == 0:
        if not StateManager.has_flag("3pm_event_triggered"):
            StateManager.set_flag("3pm_event_triggered")
            trigger_special_event()
    
    # Event between 16:30 and 17:00
    if time.hours == 16 and time.minutes >= 30:
        if not StateManager.has_flag("late_afternoon_warning"):
            StateManager.set_flag("late_afternoon_warning")
            show_warning("Time is running out!")
```

## Quest System

```gdscript
# Quest: Talk to 3 NPCs
func check_quest_progress():
    var npcs_needed = ["bob", "alice", "charlie"]
    var talked_count = 0
    
    for npc in npcs_needed:
        if StateManager.has_talked_to_npc(npc):
            talked_count += 1
    
    if talked_count >= 3:
        if not StateManager.is_quest_completed("talk_to_everyone"):
            StateManager.complete_quest("talk_to_everyone")
            # Give reward
            StateManager.add_knowledge("village_secret")
```

## Conditional Dialogue Based on State

```gdscript
# NPC with different dialogue based on knowledge
func get_dialogue() -> String:
    if StateManager.has_knowledge("village_secret"):
        return "Ah, you know the secret now!"
    elif StateManager.has_talked_to_npc("mayor"):
        return "Did you talk to the mayor?"
    elif StateManager.persistent_state.total_loops > 5:
        return "You look familiar... have we met before?"
    else:
        return "Hello, stranger!"
```

## Item Collection

```gdscript
# Collectible item
func _on_item_picked_up():
    var item_id = "beach_key"
    
    if StateManager.has_collected_item(item_id):
        return  # Already collected this loop
    
    StateManager.add_item_collected(item_id)
    add_to_inventory(item_id)
    
    # Check if this unlocks knowledge
    if item_id == "ancient_scroll":
        StateManager.add_knowledge("ancient_language")
```

## Door/Lock System

```gdscript
# Door that requires a key
func try_open_door():
    var door_id = "mansion_front_door"
    
    if StateManager.is_door_unlocked(door_id):
        open_door()
    elif StateManager.has_collected_item("mansion_key"):
        StateManager.unlock_door(door_id)
        show_dialogue("You unlock the door with the key!")
        open_door()
    else:
        show_dialogue("The door is locked.")
```

## Listening to State Changes

```gdscript
# In a manager or UI script
func _ready():
    StateManager.state_changed.connect(_on_state_changed)
    StateManager.flag_set.connect(_on_flag_set)
    TimeManager.loop_completed.connect(_on_loop_completed)

func _on_state_changed(key: String, value: Variant):
    print("State changed: ", key, " = ", value)
    
    if key == "item_collected":
        update_inventory_ui()
    elif key == "knowledge_gained":
        show_notification("New knowledge: " + str(value))

func _on_flag_set(flag: String):
    print("Flag set: ", flag)
    
    # Trigger events based on flags
    if flag == "all_npcs_met":
        trigger_special_cutscene()

func _on_loop_completed():
    show_message("The loop has reset!")
    # Maybe show what knowledge persisted
```

## Story Progression (Persistent)

```gdscript
# Major story beats that persist
func complete_chapter_1():
    StateManager.set_story_flag("chapter_1_complete")
    StateManager.add_achievement("first_loop_survivor")

func _ready():
    if StateManager.has_story_flag("chapter_1_complete"):
        # Skip intro, show different content
        load_chapter_2()
    else:
        load_chapter_1()
```

## Achievement System

```gdscript
# Check for achievement conditions
func check_achievements():
    # Speed run achievement
    if TimeManager.elapsed_real_time < 600:  # 10 minutes
        if StateManager.is_quest_completed("main_quest"):
            StateManager.add_achievement("speed_runner")
    
    # Knowledge hoarder
    if StateManager.persistent_state.knowledge.size() >= 10:
        StateManager.add_achievement("knowledge_seeker")
    
    # Loop master
    if StateManager.persistent_state.total_loops >= 100:
        StateManager.add_achievement("time_master")
```

## Complex Event Example

```gdscript
# Event that requires multiple conditions
func check_secret_ending():
    var time = TimeManager.get_current_time()
    
    # Must be at exactly 16:45
    if time.hours != 16 or time.minutes != 45:
        return
    
    # Must have specific knowledge
    if not StateManager.has_knowledge("ritual_time"):
        return
    
    # Must have talked to specific NPCs this loop
    var required_npcs = ["priest", "elder", "witch"]
    for npc in required_npcs:
        if not StateManager.has_talked_to_npc(npc):
            return
    
    # Must have collected specific items this loop
    if not StateManager.has_collected_item("ritual_candle"):
        return
    
    # All conditions met!
    if not StateManager.has_flag("secret_ending_triggered"):
        StateManager.set_flag("secret_ending_triggered")
        StateManager.add_achievement("secret_ending")
        trigger_secret_ending()
```

## Debugging

```gdscript
# Print current state (useful for debugging)
func debug_print_state():
    print("=== Loop State ===")
    print("NPCs talked to: ", StateManager.loop_state.npcs_talked_to)
    print("Items collected: ", StateManager.loop_state.items_collected)
    print("Flags: ", StateManager.loop_state.flags)
    
    print("\n=== Persistent State ===")
    print("Total loops: ", StateManager.persistent_state.total_loops)
    print("Knowledge: ", StateManager.persistent_state.knowledge)
    print("Unlocks: ", StateManager.persistent_state.unlocks)
    print("Story flags: ", StateManager.persistent_state.story_flags)
```
