Finished code decoupling

This commit is contained in:
MatyasZsombor 2025-06-15 23:40:57 +02:00
parent 9c4657a6ae
commit 142e2f3f2a
15 changed files with 833 additions and 832 deletions

View File

@ -1,33 +1,24 @@
% SkyNet: The Wings of Deception % SkyNet: The Wings of Deception
% Von Zsombor Matyas und Jonas Hinterdorfer % Von Zsombor Matyas und Jonas Hinterdorfer
:- include('game_assets/locations.pl'). % ========== INCLUDES ==========
:- include('game_assets/climbing_system.pl').
:- include('game_assets/combat_system.pl').
:- include('game_assets/command_processing.pl').
:- include('game_assets/commands.pl').
:- include('game_assets/crafting_system.pl').
:- include('game_assets/endings.pl').
:- include('game_assets/game_state.pl').
:- include('game_assets/hacking_system.pl').
:- include('game_assets/inventory.pl').
:- include('game_assets/items.pl'). :- include('game_assets/items.pl').
:- include('game_assets/konami_code.pl').
:- include('game_assets/locations.pl').
:- include('game_assets/npcs.pl'). :- include('game_assets/npcs.pl').
:- include('game_assets/obstacles.pl').
:- include('game_assets/parkour_minigames.pl').
:- include('game_assets/utilities.pl'). :- include('game_assets/utilities.pl').
% ========== GAME STATE ==========
:- dynamic(player_location/1).
:- dynamic(player_health/1).
:- dynamic(player_inventory/1).
:- dynamic(game_state/2).
:- dynamic(npc_location/2).
:- dynamic(enemy_location/2).
:- dynamic(item_location/2).
:- dynamic(discovered/1).
:- dynamic(enemy/4).
:- dynamic(enemy_hacked/1).
:- dynamic(hack_attempted/1).
:- dynamic(obstacle/3).
:- dynamic(box_unlocked/1).
:- dynamic(in_combat/1).
:- dynamic(combat_turn/1).
:- dynamic(konami_sequence/1).
:- dynamic(konami_position/1).
:- dynamic(emp_used_in_combat/1).
:- dynamic(drone_cooldown/2).
:- dynamic(health_recovery_used/2).
% ========== INITIALIZATION ========== % ========== INITIALIZATION ==========
init_game :- init_game :-
% Clear any existing state % Clear any existing state
@ -96,785 +87,5 @@ normal_loop :-
!, !,
game_loop. game_loop.
combat_loop(Enemy) :-
enemy(Enemy, DisplayName, Health, _),
nl,
write('=== KAMPF GEGEN '), write(DisplayName), write(' ==='), nl,
write('Feind Gesundheit: '), write(Health), nl,
player_health(PlayerHealth),
write('Deine Gesundheit: '), write(PlayerHealth), nl,
health_recovery_used(Enemy, RecoveryUsed),
RemainingRecovery is 2 - RecoveryUsed,
write('Heilungen übrig: '), write(RemainingRecovery), write('/2'), nl,
write('Verfügbare Aktionen: angriff, verwende(item), heile'), nl, nl,
write('> '),
read_line(Command),
process_combat_command(Command, Enemy),
check_game_state,
!,
game_loop.
init_konami :-
retractall(konami_sequence(_)),
retractall(konami_position(_)),
assertz(konami_sequence([oben, oben, unten, unten, links, rechts, links, rechts, b, a])),
assertz(konami_position(0)).
% ========== INPUT PROCESSING ==========
read_line(Command) :-
read(Input),
parse_input(Input, Command).
parse_input(Input, [Input]) :-
atom(Input), !.
parse_input(Input, Command) :-
compound(Input),
Input =.. Command, !.
parse_input(_, [unknown]).
% ========== COMMAND PROCESSING ==========
check_konami_input(Input) :-
(konami_position(_) -> true ; init_konami),
konami_position(Pos),
konami_sequence(Sequence),
nth0(Pos, Sequence, Expected),
(Input = Expected ->
(NewPos is Pos + 1,
retract(konami_position(Pos)),
assertz(konami_position(NewPos)),
length(Sequence, SeqLength),
(NewPos >= SeqLength ->
unlock_konami_code ;
true)) ;
(retract(konami_position(_)),
assertz(konami_position(0)),
write('Invalide Code, Hinweis: Contra.'), nl)).
unlock_konami_code :-
game_state(konami_unlocked, false),
write('*** KONAMI CODE AKTIVIERT! ***'), nl,
write('Ein geheimnisvoller Master-Schlüssel materialisiert sich in deinem Inventar!'), nl,
write('Dieses Artefakt gewährt dir vollständigen Zugriff auf alle Systeme...'), nl,
assertz(player_inventory(master_schluessel)),
retract(game_state(konami_unlocked, false)),
assertz(game_state(konami_unlocked, true)),
retract(konami_position(_)),
assertz(konami_position(0)),
!.
unlock_konami_code :-
write('Der Konami Code wurde bereits aktiviert!'), nl,
retract(konami_position(_)),
assertz(konami_position(0)).
process_command([oben]) :- check_konami_input(oben).
process_command([unten]) :- check_konami_input(unten).
process_command([links]) :- check_konami_input(links).
process_command([rechts]) :- check_konami_input(rechts).
process_command([a]) :- check_konami_input(a).
process_command([b]) :- check_konami_input(b).
process_command([beende]) :-
end_game.
process_command([hilfe]) :-
write('Verfügbare Befehle:'), nl,
write('- schaue: Beschreibung des aktuellen Ortes'), nl,
write('- gehe(richtung): Bewege dich zu einem anderen Ort'), nl,
write('- nimm(gegenstand): Nimm einen Gegenstand auf'), nl,
write('- verwende(gegenstand): Verwende einen Gegenstand'), nl,
write('- rede(person): Spreche mit einer Person'), nl,
write('- angriff(feind): Beginne Kampf gegen einen Feind'), nl,
write('- baue(item): Baue einen Gegenstand (nur in Werkstatt)'), nl,
write('- hack(ziel): Hacke ein Ziel'), nl,
write('- klettere: Klettere auf Dächer/Türme'), nl,
write('- inventar: Zeige dein Inventar'), nl,
write('- status: Zeige deinen Status'), nl,
write('- Richtungsbefehle: oben, unten, links, rechts, a, b'), nl,
write(' (Könnte für etwas Besonderes nützlich sein...)'), nl.
process_command([schaue]) :-
look_around.
process_command([gehe, Direction]) :-
move_player(Direction).
process_command([nimm, Item]) :-
take_item(Item).
process_command([verwende, Item]) :-
use_item(Item).
process_command([rede, Person]) :-
talk_to(Person).
process_command([angriff, Enemy]) :-
start_combat(Enemy).
process_command([baue, Item]) :-
craft_item(Item).
process_command([hack, Target]) :-
hack_target(Target).
process_command([klettere]) :-
climb_action.
process_command([inventar]) :-
show_inventory.
process_command([status]) :-
show_status.
process_command([clear]) :-
clear_screen.
% ========== CHEAT CODES (for testing) ==========
process_command([cheat, heal]) :-
retract(player_health(_)),
assertz(player_health(100)),
write('Gesundheit wiederhergestellt!'), nl.
process_command([cheat, items]) :-
assertz(player_inventory(spule)),
assertz(player_inventory(batterie)),
assertz(player_inventory(kondensator)),
assertz(player_inventory(emp_granate)),
assertz(player_inventory(emp_granate)),
assertz(player_inventory(parkour_handschuhe)),
assertz(player_inventory(drohnen_motor)),
assertz(player_inventory(steuerungsmodul)),
assertz(player_inventory(heilspray)),
write('Alle Items erhalten!'), nl.
process_command([cheat, teleport, LOC]) :-
retract(player_location(_)),
assertz(player_location(LOC)).
process_command([cheat, generator_components]) :-
assertz(player_inventory(spule)),
assertz(player_inventory(batterie)),
assertz(player_inventory(kondensator)),
write('EMP-Generator Komponenten erhalten!'), nl.
process_command([cheat, generator_components]) :-
assertz(player_inventory(spule)),
assertz(player_inventory(batterie)),
assertz(player_inventory(kondensator)),
write('EMP-Generator Komponenten erhalten!'), nl.
process_command(_) :-
write('Unbekannter Befehl. Verwende "hilfe" für eine Liste der Befehle.'), nl.
% ========== COMBAT COMMANDS ==========
process_combat_command([angriff], Enemy) :-
combat_attack(Enemy).
process_combat_command([verwende, Item], Enemy) :-
combat_use_item(Item, Enemy).
process_combat_command([heile], Enemy) :-
combat_heal(Enemy).
process_combat_command(_, _) :-
write('Ungültige Kampfaktion! Verwende: angriff oder verwende(item)'), nl.
% ========== CORE GAME MECHANICS ==========
look_around :-
player_location(Loc),
location(Loc, Name, Desc),
write(Name), nl,
write(Desc), nl,
list_items_here(Loc),
list_npcs_here(Loc),
list_enemies_here(Loc),
list_exits(Loc),
check_obstacles_here(Loc).
list_items_here(Loc) :-
findall(Item, item_location(Item, Loc), Items),
(Items = [] -> true ;
(write('Gegenstände hier: '), write_list(Items), nl)).
list_npcs_here(Loc) :-
findall(NPC, npc_location(NPC, Loc), NPCs),
(NPCs = [] -> true ;
(write('Personen hier: '), write_list(NPCs), nl)).
list_enemies_here(Loc) :-
findall(Enemy, enemy_location(Enemy, Loc), Enemies),
(Enemies = [] -> true ;
(write('Feinde hier: '), write_list(Enemies), nl)).
list_exits(Loc) :-
findall(Exit, connected(Loc, Exit), Exits),
(Exits = [] -> write('Keine Ausgänge.') ;
(write('Ausgänge: '), write_list(Exits))), nl.
check_obstacles_here(Loc) :-
findall(obstacle(Loc, Exit, ObstacleType), obstacle(Loc, Exit, ObstacleType), Obstacles),
(Obstacles = [] -> true ; list_obstacles(Obstacles)).
% ========== MOVEMENT WITH OBSTACLES ==========
move_player(Direction) :-
player_location(CurrentLoc),
connected(CurrentLoc, Direction),
(obstacle(CurrentLoc, Direction, ObstacleType) ->
handle_obstacle(ObstacleType, Direction) ;
(retract(player_location(CurrentLoc)),
assertz(player_location(Direction)),
write('Du gehst nach '), write(Direction), nl,
trigger_location_event(Direction))),
!.
move_player(_) :-
write('Du kannst nicht dorthin gehen.'), nl.
handle_obstacle(hohe_mauer, Direction) :-
(player_inventory(parkour_handschuhe) ->
(write('Du kletterst mit den Parkour-Handschuhen über die hohe Mauer!'), nl,
player_location(CurrentLoc),
retract(obstacle(CurrentLoc, Direction, hohe_mauer)),
retract(player_location(CurrentLoc)),
assertz(player_location(Direction)),
write('Du gehst nach '), write(Direction), nl) ;
write('Eine hohe Mauer blockiert deinen Weg! Du brauchst Parkour-Handschuhe.'), nl).
handle_obstacle(drone_swarm, Direction) :-
(player_inventory(kampfdrohne) ->
(write('Deine Kampfdrohne bekämpft den feindlichen Schwarm!'), nl,
write('Die Drohnen werden zerstört und der Weg ist frei!'), nl,
player_location(CurrentLoc),
retract(obstacle(CurrentLoc, Direction, drone_swarm)),
retract(player_location(CurrentLoc)),
assertz(player_location(Direction)),
write('Du gehst nach '), write(Direction), nl) ;
write('Ein Schwarm aggressiver Drohnen blockiert den Weg! Du brauchst eine Kampfdrohne.'), nl).
handle_obstacle(security_system, Direction) :-
(player_inventory(emp_generator) ->
(write('Du aktivierst den EMP-Generator! Das Sicherheitssystem bricht zusammen!'), nl,
player_location(CurrentLoc),
retract(obstacle(CurrentLoc, Direction, security_system)),
retract(player_location(CurrentLoc)),
assertz(player_location(Direction)),
write('Du gehst nach '), write(Direction), nl) ;
write('Ein Hochsicherheitssystem blockiert den Zugang! Du brauchst einen EMP-Generator.'), nl).
% ========== INVENTORY MANAGEMENT ==========
take_item(ItemName) :-
player_location(Loc),
item_location(ItemName, Loc),
retract(item_location(ItemName, Loc)),
assertz(player_inventory(ItemName)),
item(ItemName, DisplayName, _),
write('Du nimmst '), write(DisplayName), write(' auf.'), nl,
!.
take_item(_) :-
write('Diesen Gegenstand kannst du hier nicht finden.'), nl.
use_item(ItemName) :-
player_inventory(ItemName),
execute_item_use(ItemName),
!.
use_item(_) :-
write('Du hast diesen Gegenstand nicht oder kannst ihn nicht verwenden.'), nl.
show_inventory :-
write('Dein Inventar:'), nl,
findall(Item, player_inventory(Item), Items),
(Items = [] -> write('Dein Inventar ist leer.') ; list_inventory_items(Items)), nl.
list_inventory_items([]).
list_inventory_items([H|T]) :-
item(H, DisplayName, Desc),
write('- '), write(DisplayName), write(': '), write(Desc), nl,
list_inventory_items(T).
% ========== ITEM USAGE ==========
execute_item_use(laptop) :-
player_location(htl_labor),
write('Du hackst dich in die Schulserver ein und analysierst die Drohnen-Aufnahmen.'), nl,
write('SCHOCKIERENDE ENTDECKUNG: Die Vögel sind Überwachungsdrohnen!'), nl,
!.
execute_item_use(heilspray) :-
player_health(Health),
(Health >= 100 ->
write('Du hast bereits volle Gesundheit!'), nl ;
(NewHealth is min(100, Health + 30),
retract(player_health(Health)),
assertz(player_health(NewHealth)),
write('Du verwendest das Heilspray und gewinnst 30 Gesundheitspunkte!'), nl,
retract(player_inventory(heilspray)))),
!.
execute_item_use(_) :-
write('Du kannst diesen Gegenstand hier nicht verwenden.'), nl.
% ========== TURN-BASED COMBAT SYSTEM ==========
start_combat(EnemyName) :-
player_location(Loc),
enemy_location(EnemyName, Loc),
assertz(drone_cooldown(EnemyName, 0)),
assertz(health_recovery_used(EnemyName, 0)),
write('Du beginnst den Kampf gegen '), enemy(EnemyName, DisplayName, _, _),
write(DisplayName), write('!'), nl,
assertz(in_combat(EnemyName)),
!.
start_combat(_) :-
write('Hier ist kein Feind zum Angreifen.'), nl.
combat_attack(Enemy) :-
get_random_damage(Damage),
enemy(Enemy, DisplayName, Health, Desc),
NewHealth is Health - Damage,
write('Du greifst '), write(DisplayName), write(' an und verursachst '),
write(Damage), write(' Schaden!'), nl,
retract(enemy(Enemy, DisplayName, Health, Desc)),
(NewHealth =< 0 ->
(write(DisplayName), write(' wurde besiegt!'), nl,
defeat_enemy(Enemy)) ;
(assertz(enemy(Enemy, DisplayName, NewHealth, Desc)),
enemy_turn(Enemy))).
combat_use_item(ItemName, Enemy) :-
player_inventory(ItemName),
execute_combat_item_use(ItemName, Enemy),
!.
combat_use_item(_, _) :-
write('Du hast diesen Gegenstand nicht!'), nl.
combat_heal(Enemy) :-
health_recovery_used(Enemy, Used),
Used >= 2,
write('Du hast bereits alle Heilungen in diesem Kampf verbraucht!'), nl,
!.
combat_heal(_) :-
player_health(CurrentHealth),
CurrentHealth >= 100,
write('Du hast bereits volle Gesundheit!'), nl,
!.
combat_heal(Enemy) :-
health_recovery_used(Enemy, Used),
Used < 2,
random(19, 31, HealAmount),
player_health(CurrentHealth),
NewHealth is min(100, CurrentHealth + HealAmount),
HealedAmount is NewHealth - CurrentHealth,
retract(player_health(CurrentHealth)),
assertz(player_health(NewHealth)),
NewUsed is Used + 1,
retract(health_recovery_used(Enemy, Used)),
assertz(health_recovery_used(Enemy, NewUsed)),
write('Du heilst dich selbst und gewinnst '), write(HealedAmount),
write(' Gesundheitspunkte!'), nl,
RemainingUses is 2 - NewUsed,
write('Verbleibende Heilungen: '), write(RemainingUses), nl,
enemy_turn(Enemy).
execute_combat_item_use(emp_granate, Enemy) :-
emp_used_in_combat(Enemy),
write('Du hast bereits eine EMP-Granate in diesem Kampf verwendet!'), nl,
!.
execute_combat_item_use(emp_granate, Enemy) :-
enemy(Enemy, DisplayName, Health, Desc),
assertz(emp_used_in_combat(Enemy)),
(Enemy = die_kraehe ->
(write('Du schwächst die Krähe mit der EMP-Granate!'), nl,
retract(game_state(crow_weakened, false)),
assertz(game_state(crow_weakened, true)),
retract(player_inventory(emp_granate))) ;
(Damage = 40,
NewHealth is Health - Damage,
write('Die EMP-Granate verursacht '), write(Damage), write(' Schaden!'), nl,
retract(enemy(Enemy, DisplayName, Health, Desc)),
retract(player_inventory(emp_granate)),
(NewHealth =< 0 ->
(write(DisplayName), write(' wurde besiegt!'), nl,
defeat_enemy(Enemy)) ;
(assertz(enemy(Enemy, DisplayName, NewHealth, Desc)),
enemy_turn(Enemy))))).
execute_combat_item_use(kampfdrohne, Enemy) :-
drone_cooldown(Enemy, Cooldown),
Cooldown > 0,
write('Deine Kampfdrohne lädt noch auf! Cooldown: '), write(Cooldown), write(' Runden.'), nl,
!.
execute_combat_item_use(kampfdrohne, Enemy) :-
enemy(Enemy, DisplayName, Health, Desc),
Damage = 25,
NewHealth is Health - Damage,
write('Deine Kampfdrohne greift an und verursacht '), write(Damage), write(' Schaden!'), nl,
write('Die Drohne muss sich jetzt 2 Runden lang aufladen.'), nl,
% Set cooldown to 2 turns
retract(drone_cooldown(Enemy, _)),
assertz(drone_cooldown(Enemy, 2)),
retract(enemy(Enemy, DisplayName, Health, Desc)),
(NewHealth =< 0 ->
(write(DisplayName), write(' wurde besiegt!'), nl,
defeat_enemy(Enemy)) ;
(assertz(enemy(Enemy, DisplayName, NewHealth, Desc)),
enemy_turn(Enemy))).
execute_combat_item_use(heilspray, _) :-
execute_item_use(heilspray).
execute_combat_item_use(Item, _) :-
\+ member(Item, [emp_granate, kampfdrohne, heilspray]),
item(Item, DisplayName, _),
write(DisplayName), write(' kann nicht im Kampf verwendet werden!'), nl.
execute_combat_item_use(Item, _) :-
write(Item), write(' kann nicht im Kampf verwendet werden!'), nl.
enemy_turn(Enemy) :-
drone_cooldown(Enemy, Cooldown),
(Cooldown > 0 ->
(NewCooldown is Cooldown - 1,
retract(drone_cooldown(Enemy, Cooldown)),
assertz(drone_cooldown(Enemy, NewCooldown))) ;
true),
enemy(Enemy, DisplayName, _, _),
(Enemy = die_kraehe, game_state(crow_weakened, false) ->
crow_mind_control ;
normal_enemy_attack(Enemy, DisplayName)).
normal_enemy_attack(_, DisplayName) :-
get_random_enemy_damage(Damage),
damage_player(Damage),
write(DisplayName), write(' greift an und verursacht '),
write(Damage), write(' Schaden!'), nl.
crow_mind_control :-
write('Die Krähe übernimmt die Kontrolle über deinen Verstand!'), nl,
write('Du schlägst dich selbst!'), nl,
damage_player(20),
write('Du verursachst dir '), write(20), write(' Schaden!'), nl.
defeat_enemy(EnemyName) :-
retract(enemy_location(EnemyName, _)),
retract(in_combat(EnemyName)),
handle_enemy_defeat(EnemyName),
retractall(emp_used_in_combat(EnemyName)),
retractall(drone_cooldown(EnemyName, _)),
retractall(health_recovery_used(EnemyName, _)),
nl.
handle_enemy_defeat(tauben_schwarm) :-
write('Die Tauben explodieren! Du findest ein Heilspray und einen Drohnen-Motor in den Trümmern.'), nl,
player_location(Loc),
assertz(item_location(drohnen_motor, Loc)),
assertz(item_location(heilspray, Loc)).
handle_enemy_defeat(storch_drohne) :-
write('Die Storch-Drohne lässt ein Steuerungsmodul und EMP-Granaten fallen!'), nl,
player_location(Loc),
assertz(item_location(steuerungsmodul, Loc)),
assertz(item_location(emp_granate, Loc)).
handle_enemy_defeat(die_kraehe) :-
write('Die Krähe ist besiegt! Das Drohnen-Netzwerk wankt...'), nl,
write('Du stehst vor der Hauptkonsole von Aviary Control.'), nl,
write('Plötzlich erscheint eine Nachricht auf dem Bildschirm:'), nl,
write('"Beeindruckend, John. Du hast es bis hierher geschafft."'), nl,
write('"Aber jetzt musst du eine Wahl treffen..."'), nl,
final_choice.
% ========== CRAFTING SYSTEM ==========
craft_item(emp_generator) :-
player_location(htl_werkstatt),
player_inventory(spule),
player_inventory(batterie),
player_inventory(kondensator),
write('Du baust aus Spule, Batterie und Kondensator einen EMP-Generator!'), nl,
retract(player_inventory(spule)),
retract(player_inventory(batterie)),
retract(player_inventory(kondensator)),
assertz(player_inventory(emp_generator)),
retract(game_state(emp_built, false)),
assertz(game_state(emp_built, true)),
!.
craft_item(emp_generator) :-
player_location(htl_werkstatt),
write('Du brauchst: Elektro-Spule, Hochleistungsbatterie und Kondensator.'), nl,
!.
craft_item(emp_generator) :-
write('Du kannst nur in der HTL Leonding Werkstatt bauen.'), nl,
!.
craft_item(kampfdrohne) :-
player_location(htl_werkstatt),
player_inventory(drohnen_motor),
player_inventory(steuerungsmodul),
write('Du baust aus Motor und Steuerungsmodul eine Kampfdrohne!'), nl,
retract(player_inventory(drohnen_motor)),
retract(player_inventory(steuerungsmodul)),
assertz(player_inventory(kampfdrohne)),
!.
craft_item(kampfdrohne) :-
player_location(htl_werkstatt),
write('Du brauchst: Drohnen-Motor und Steuerungsmodul um eine Kampfdrohne zu bauen.'), nl,
!.
craft_item(kampfdrohne) :-
write('Du kannst nur in der HTL Leonding Werkstatt bauen.'), nl,
!.
craft_item(_) :-
write('Du kannst diesen Gegenstand nicht bauen.'), nl.
% ========== HACKING MINI-GAMES ==========
hack_target(box) :-
player_location(Loc),
player_inventory(laptop),
hacking_minigame(Loc),
!.
hack_target(_) :-
write('Du kannst dieses Ziel nicht hacken oder hast keinen Laptop.'), nl.
hacking_minigame(altstadt) :-
box_unlocked(altstadt_box),
write('Diese Box wurde bereits gehackt.'), nl,
!.
hacking_minigame(altstadt) :-
write('=== HACKING MINI-GAME ==='), nl,
write('Entschlüssele den Code: 1001 + 0110 = ?'), nl,
write('Gib das Ergebnis in binär ein: '),
read(Answer),
(Answer = 1111 ->
(write('Korrekt! Du findest eine Elektro-Spule in der Box!'), nl,
assertz(player_inventory(spule)),
assertz(box_unlocked(altstadt_box))) ;
(write('Falsch! Versuch es nochmal.'), nl,
fail)).
hacking_minigame(donauufer) :-
box_unlocked(donauufer_box),
write('Diese Box wurde bereits gehackt.'), nl,
!.
hacking_minigame(donauufer) :-
write('=== HACKING MINI-GAME ==='), nl,
write('SQL Injection: Welcher Befehl umgeht die Passwort-Abfrage?'), nl,
write('1) DROP TABLE users'), nl,
write('2) \' OR \'1\'=\'1'), nl,
write('3) SELECT * FROM passwords'), nl,
write('Deine Wahl (1-3): '),
read(Answer),
(Answer = 2 ->
(write('Korrekt! Du findest eine Hochleistungsbatterie in der Box!'), nl,
assertz(player_inventory(batterie)),
assertz(box_unlocked(donauufer_box))) ;
(write('Falsch! Versuch es nochmal.'), nl,
fail)).
hacking_minigame(poestlingberg) :-
box_unlocked(poestlingberg_box),
write('Diese Box wurde bereits gehackt.'), nl,
!.
hacking_minigame(poestlingberg) :-
player_inventory(kampfdrohne),
write('=== DROHNEN-HACKING ==='), nl,
write('Deine Kampfdrohne verbindet sich mit der Box...'), nl,
write('Netzwerk-Port-Scan: Welcher Port ist für SSH Standard?'), nl,
write('1) Port 80'), nl,
write('2) Port 22'), nl,
write('3) Port 443'), nl,
write('Deine Wahl (1-3): '),
read(Answer),
(Answer = 2 ->
(write('Korrekt! Du findest einen Kondensator in der Box!'), nl,
assertz(player_inventory(kondensator)),
assertz(box_unlocked(poestlingberg_box))) ;
(write('Falsch! Versuch es nochmal.'), nl,
fail)).
hacking_minigame(poestlingberg) :-
write('Du brauchst eine Kampfdrohne um diese Box zu hacken.'), nl.
hacking_minigame(_) :-
write('Hier gibt es nichts zu hacken.'), nl.
% ========== CLIMBING SYSTEM ==========
climb_action :-
player_location(altstadt),
player_inventory(parkour_handschuhe),
write('=== PARKOUR KLETTERN ==='), nl,
write('Du beginnst den Aufstieg...'), nl,
parkour_minigame_altstadt,
!.
climb_action :-
player_location(altstadt),
write('Du brauchst Parkour-Handschuhe um auf das Dach zu klettern.'), nl,
!.
climb_action :-
player_location(donauufer),
player_inventory(parkour_handschuhe),
write('=== TURM KLETTERN ==='), nl,
write('Du kletterst den hohen Industrieturm hinauf...'), nl,
climbing_minigame_donauufer,
!.
climb_action :-
player_location(donauufer),
write('Du brauchst Parkour-Handschuhe um auf den Turm zu klettern.'), nl,
!.
climb_action :-
player_location(poestlingberg),
player_inventory(parkour_handschuhe),
write('=== ÜBERWACHUNGSTURM KLETTERN ==='), nl,
write('Du kletterst den gefährlichen Überwachungsturm hinauf...'), nl,
climbing_minigame_poestlingberg,
!.
climb_action :-
player_location(poestlingberg),
write('Du brauchst Parkour-Handschuhe um auf den Überwachungsturm zu klettern.'), nl,
!.
climb_action :-
write('Hier gibt es nichts zum Klettern.'), nl.
% ========== PARKOUR-MINIGAMES ==========
parkour_minigame_altstadt :-
write('Sequenz-Challenge: Wiederhole die Bewegungsfolge!'), nl,
random_member(Sequence, [[sprung, rolle, kletter], [rolle, sprung, balance], [kletter, sprung, rolle]]),
write('Merke dir: '), write_sequence(Sequence), nl,
write('Warte...'), nl, sleep(2),
clear_screen,
write('Jetzt wiederhole die Sequenz:'), nl,
write('Gib die Sequenz als Liste ein, z.B. [sprung, rolle, kletter].'), nl,
write('Verfügbare Bewegungen: sprung, rolle, kletter, balance'), nl,
write('> '),
read_sequence(UserSequence),
(UserSequence = Sequence ->
(write('Perfekte Ausführung! Du erreichst das Dach sicher!'), nl,
write('Du findest eine verschlossene Box auf dem Dach.'), nl,
write('Verwende "hack(box)" um sie zu öffnen.'), nl) ;
(write('Falsche Sequenz! Du rutschst ab und verlierst 10 Gesundheit.'), nl,
damage_player(10))).
climbing_minigame_donauufer :-
write('Balance-Challenge: Halte das Gleichgewicht!'), nl,
write('Drücke abwechselnd "links" und "rechts" um das Gleichgewicht zu halten.'), nl,
write('Du musst 5 mal korrekt reagieren!'), nl,
balance_challenge(5, 0).
balance_challenge(0, Success) :-
Success >= 4,
write('Excellent! Du hast den Turm erfolgreich erklommen!'), nl,
write('Oben ist ein elektrisches Schutzschild um eine Box.'), nl,
write('Du brauchst eine EMP-Granate um das Schild zu deaktivieren.'), nl,
(player_inventory(emp_granate) ->
(write('Du verwendest die EMP-Granate! Das Schild fällt aus!'), nl,
retract(player_inventory(emp_granate)),
write('Verwende "hack(box)" um die Box zu öffnen.'), nl) ;
true),
!.
balance_challenge(0, Success) :-
Success < 4,
write('Du verlierst das Gleichgewicht und fällst! 15 Schaden!'), nl,
damage_player(15),
!.
balance_challenge(Remaining, Success) :-
Remaining > 0,
random_member(Direction, [links, rechts]),
write('Das Gebäude schwankt nach '), write(Direction), write('! Schnell reagieren:'), nl,
write('> '),
read(Response),
NewRemaining is Remaining - 1,
(Response = Direction ->
(write('Gut! Gleichgewicht gehalten.'), nl,
NewSuccess is Success + 1) ;
(write('Falsch! Du wackelst gefährlich.'), nl,
NewSuccess = Success)),
balance_challenge(NewRemaining, NewSuccess).
climbing_minigame_poestlingberg :-
write('Stealth-Klettern: Vermeide die Überwachungskameras!'), nl,
write('Du musst die richtige Route wählen um unentdeckt zu bleiben.'), nl,
stealth_climbing_challenge.
stealth_climbing_challenge :-
write('Stufe 1: Kamera schwenkt von links nach rechts. Wann bewegst du dich?'), nl,
write('1) Wenn die Kamera nach links schaut'), nl,
write('2) Wenn die Kamera nach rechts schaut'), nl,
write('3) Wenn die Kamera geradeaus schaut'), nl,
write('> '),
read(Choice1),
(Choice1 = 1 ->
(write('Richtig! Du nutzt den toten Winkel.'), nl,
write('Stufe 2: Zwei Kameras kreuzen sich. Wann bewegst du dich?'), nl,
write('1) Gleichzeitig mit beiden'), nl,
write('2) Zwischen den Schwenkbewegungen'), nl,
write('3) Wenn eine Kamera defekt ist'), nl,
write('> '),
read(Choice2),
(Choice2 = 2 ->
(write('Perfekt! Du erreichst die Spitze unentdeckt!'), nl,
write('Du findest eine schwer gesicherte Box.'), nl,
write('Diese Box benötigt eine Kampfdrohne zum Hacken.'), nl) ;
(write('Entdeckt! Alarm! Du verlierst 20 Gesundheit beim hastigen Rückzug.'), nl,
damage_player(20)))) ;
(write('Entdeckt! Du musst schnell fliehen und verlierst 15 Gesundheit.'), nl,
damage_player(15))).
% ========== GAME STATE MANAGEMENT ==========
check_game_state :-
player_health(Health),
(Health =< 0 ->
(retractall(in_combat(_)),
end_game(defeat),
!, fail) ;
true).
show_status :-
player_health(Health),
write('=== STATUS ==='), nl,
write('Gesundheit: '), write(Health), nl,
(player_inventory(kampfdrohne) ->
write('Kampfdrohne: ✓ Gebaut'), nl ;
(write('Kampfdrohne Komponenten:'), nl,
(player_inventory(drohnen_motor) -> write(' Drohnen-Motor: ✓') ; write(' Drohnen-Motor: ✗')), nl,
(player_inventory(steuerungsmodul) -> write(' Steuerungsmodul: ✓') ; write(' Steuerungsmodul: ✗')), nl)),
(game_state(emp_built, true) ->
write('EMP-Generator: ✓ Gebaut'), nl ;
(write('EMP-Generator Komponenten:'), nl,
(player_inventory(spule) -> write(' Elektro-Spule: ✓') ; write(' Elektro-Spule: ✗')), nl,
(player_inventory(batterie) -> write(' Batterie: ✓') ; write(' Batterie: ✗')), nl,
(player_inventory(kondensator) -> write(' Kondensator: ✓') ; write(' Kondensator: ✗')), nl)),
write('=============='), nl.
% ========== HELP PREDICATES ==========
hilfe :- process_command([hilfe]).
schaue :- process_command([schaue]).
inventar :- process_command([inventar]).
status :- process_command([status]).
% Start predicate to begin the game % Start predicate to begin the game
:- initialization(start_game). :- initialization(start_game).

View File

@ -0,0 +1,42 @@
% ========== CLIMBING SYSTEM ==========
climb_action :-
player_location(altstadt),
player_inventory(parkour_handschuhe),
write('=== PARKOUR KLETTERN ==='), nl,
write('Du beginnst den Aufstieg...'), nl,
parkour_minigame_altstadt,
!.
climb_action :-
player_location(altstadt),
write('Du brauchst Parkour-Handschuhe um auf das Dach zu klettern.'), nl,
!.
climb_action :-
player_location(donauufer),
player_inventory(parkour_handschuhe),
write('=== TURM KLETTERN ==='), nl,
write('Du kletterst den hohen Industrieturm hinauf...'), nl,
climbing_minigame_donauufer,
!.
climb_action :-
player_location(donauufer),
write('Du brauchst Parkour-Handschuhe um auf den Turm zu klettern.'), nl,
!.
climb_action :-
player_location(poestlingberg),
player_inventory(parkour_handschuhe),
write('=== ÜBERWACHUNGSTURM KLETTERN ==='), nl,
write('Du kletterst den gefährlichen Überwachungsturm hinauf...'), nl,
climbing_minigame_poestlingberg,
!.
climb_action :-
player_location(poestlingberg),
write('Du brauchst Parkour-Handschuhe um auf den Überwachungsturm zu klettern.'), nl,
!.
climb_action :-
write('Hier gibt es nichts zum Klettern.'), nl.

View File

@ -0,0 +1,188 @@
% ========== MAIN COMBAT LOOP ==========
combat_loop(Enemy) :-
enemy(Enemy, DisplayName, Health, _),
nl,
write('=== KAMPF GEGEN '), write(DisplayName), write(' ==='), nl,
write('Feind Gesundheit: '), write(Health), nl,
player_health(PlayerHealth),
write('Deine Gesundheit: '), write(PlayerHealth), nl,
health_recovery_used(Enemy, RecoveryUsed),
RemainingRecovery is 2 - RecoveryUsed,
write('Heilungen übrig: '), write(RemainingRecovery), write('/2'), nl,
write('Verfügbare Aktionen: angriff, heile, verwende(item)'), nl, nl,
write('> '),
read_line(Command),
process_combat_command(Command, Enemy),
check_game_state,
!,
game_loop.
% ========== COMBAT COMMANDS ==========
process_combat_command([angriff], Enemy) :-
combat_attack(Enemy).
process_combat_command([verwende, Item], Enemy) :-
combat_use_item(Item, Enemy).
process_combat_command([heile], Enemy) :-
combat_heal(Enemy).
process_combat_command(_, _) :-
write('Ungültige Kampfaktion! Verwende: angriff, heile oder verwende(item)'), nl.
% ========== TURN-BASED COMBAT SYSTEM ==========
start_combat(EnemyName) :-
player_location(Loc),
enemy_location(EnemyName, Loc),
assertz(drone_cooldown(EnemyName, 0)),
assertz(health_recovery_used(EnemyName, 0)),
write('Du beginnst den Kampf gegen '), enemy(EnemyName, DisplayName, _, _),
write(DisplayName), write('!'), nl,
assertz(in_combat(EnemyName)),
!.
start_combat(_) :-
write('Hier ist kein Feind zum Angreifen.'), nl.
combat_attack(Enemy) :-
get_random_damage(Damage),
enemy(Enemy, DisplayName, Health, Desc),
NewHealth is Health - Damage,
write('Du greifst '), write(DisplayName), write(' an und verursachst '),
write(Damage), write(' Schaden!'), nl,
retract(enemy(Enemy, DisplayName, Health, Desc)),
(NewHealth =< 0 ->
(write(DisplayName), write(' wurde besiegt!'), nl,
defeat_enemy(Enemy)) ;
(assertz(enemy(Enemy, DisplayName, NewHealth, Desc)),
enemy_turn(Enemy))).
combat_use_item(ItemName, Enemy) :-
player_inventory(ItemName),
execute_combat_item_use(ItemName, Enemy),
!.
combat_use_item(_, _) :-
write('Du hast diesen Gegenstand nicht!'), nl.
combat_heal(Enemy) :-
health_recovery_used(Enemy, Used),
Used >= 2,
write('Du hast bereits alle Heilungen in diesem Kampf verbraucht!'), nl,
!.
combat_heal(_) :-
player_health(CurrentHealth),
CurrentHealth >= 100,
write('Du hast bereits volle Gesundheit!'), nl,
!.
combat_heal(Enemy) :-
health_recovery_used(Enemy, Used),
Used < 2,
random(19, 31, HealAmount),
player_health(CurrentHealth),
NewHealth is min(100, CurrentHealth + HealAmount),
HealedAmount is NewHealth - CurrentHealth,
retract(player_health(CurrentHealth)),
assertz(player_health(NewHealth)),
NewUsed is Used + 1,
retract(health_recovery_used(Enemy, Used)),
assertz(health_recovery_used(Enemy, NewUsed)),
write('Du heilst dich selbst und gewinnst '), write(HealedAmount),
write(' Gesundheitspunkte!'), nl,
RemainingUses is 2 - NewUsed,
write('Verbleibende Heilungen: '), write(RemainingUses), nl,
enemy_turn(Enemy).
% ========== COMBAT ITEMS ==========
execute_combat_item_use(emp_granate, Enemy) :-
emp_used_in_combat(Enemy),
write('Du hast bereits eine EMP-Granate in diesem Kampf verwendet!'), nl,
!.
execute_combat_item_use(emp_granate, Enemy) :-
enemy(Enemy, DisplayName, Health, Desc),
assertz(emp_used_in_combat(Enemy)),
(Enemy = die_kraehe ->
(write('Du schwächst die Krähe mit der EMP-Granate!'), nl,
retract(game_state(crow_weakened, false)),
assertz(game_state(crow_weakened, true)),
retract(player_inventory(emp_granate))) ;
(Damage = 40,
NewHealth is Health - Damage,
write('Die EMP-Granate verursacht '), write(Damage), write(' Schaden!'), nl,
retract(enemy(Enemy, DisplayName, Health, Desc)),
retract(player_inventory(emp_granate)),
(NewHealth =< 0 ->
(write(DisplayName), write(' wurde besiegt!'), nl,
defeat_enemy(Enemy)) ;
(assertz(enemy(Enemy, DisplayName, NewHealth, Desc)),
enemy_turn(Enemy))))).
execute_combat_item_use(kampfdrohne, Enemy) :-
drone_cooldown(Enemy, Cooldown),
Cooldown > 0,
write('Deine Kampfdrohne lädt noch auf! Cooldown: '), write(Cooldown), write(' Runden.'), nl,
!.
execute_combat_item_use(kampfdrohne, Enemy) :-
enemy(Enemy, DisplayName, Health, Desc),
Damage = 25,
NewHealth is Health - Damage,
write('Deine Kampfdrohne greift an und verursacht '), write(Damage), write(' Schaden!'), nl,
write('Die Drohne muss sich jetzt 2 Runden lang aufladen.'), nl,
% Set cooldown to 2 turns
retract(drone_cooldown(Enemy, _)),
assertz(drone_cooldown(Enemy, 2)),
retract(enemy(Enemy, DisplayName, Health, Desc)),
(NewHealth =< 0 ->
(write(DisplayName), write(' wurde besiegt!'), nl,
defeat_enemy(Enemy)) ;
(assertz(enemy(Enemy, DisplayName, NewHealth, Desc)),
enemy_turn(Enemy))).
execute_combat_item_use(heilspray, _) :-
execute_item_use(heilspray).
execute_combat_item_use(Item, _) :-
\+ member(Item, [emp_granate, kampfdrohne, heilspray]),
item(Item, DisplayName, _),
write(DisplayName), write(' kann nicht im Kampf verwendet werden!'), nl.
execute_combat_item_use(Item, _) :-
write(Item), write(' kann nicht im Kampf verwendet werden!'), nl.
% ========== ENEMY-ATTACKS/DEFEAT ==========
enemy_turn(Enemy) :-
drone_cooldown(Enemy, Cooldown),
(Cooldown > 0 ->
(NewCooldown is Cooldown - 1,
retract(drone_cooldown(Enemy, Cooldown)),
assertz(drone_cooldown(Enemy, NewCooldown))) ;
true),
enemy(Enemy, DisplayName, _, _),
(Enemy = die_kraehe, game_state(crow_weakened, false) ->
crow_mind_control ;
normal_enemy_attack(Enemy, DisplayName)).
normal_enemy_attack(_, DisplayName) :-
get_random_enemy_damage(Damage),
damage_player(Damage),
write(DisplayName), write(' greift an und verursacht '),
write(Damage), write(' Schaden!'), nl.
crow_mind_control :-
write('Die Krähe übernimmt die Kontrolle über deinen Verstand!'), nl,
write('Du schlägst dich selbst!'), nl,
damage_player(20),
write('Du verursachst dir '), write(20), write(' Schaden!'), nl.
defeat_enemy(EnemyName) :-
retract(enemy_location(EnemyName, _)),
retract(in_combat(EnemyName)),
handle_enemy_defeat(EnemyName),
retractall(emp_used_in_combat(EnemyName)),
retractall(drone_cooldown(EnemyName, _)),
retractall(health_recovery_used(EnemyName, _)),
nl.

View File

@ -0,0 +1,99 @@
% ========== INPUT PROCESSING ==========
read_line(Command) :-
read(Input),
parse_input(Input, Command).
parse_input(Input, [Input]) :-
atom(Input), !.
parse_input(Input, Command) :-
compound(Input),
Input =.. Command, !.
parse_input(_, [unknown]).
% ========== COMMAND PROCESSING ==========
process_command([oben]) :- check_konami_input(oben).
process_command([unten]) :- check_konami_input(unten).
process_command([links]) :- check_konami_input(links).
process_command([rechts]) :- check_konami_input(rechts).
process_command([a]) :- check_konami_input(a).
process_command([b]) :- check_konami_input(b).
process_command([beende]) :-
end_game.
process_command([hilfe]) :-
help.
process_command([schaue]) :-
look_around.
process_command([gehe, Direction]) :-
move_player(Direction).
process_command([nimm, Item]) :-
take_item(Item).
process_command([verwende, Item]) :-
use_item(Item).
process_command([rede, Person]) :-
talk_to(Person).
process_command([angriff, Enemy]) :-
start_combat(Enemy).
process_command([baue, Item]) :-
craft_item(Item).
process_command([hack, Target]) :-
hack_target(Target).
process_command([klettere]) :-
climb_action.
process_command([inventar]) :-
show_inventory.
process_command([status]) :-
show_status.
process_command([clear]) :-
clear_screen.
% ========== CHEAT CODES (FOR TESTING) ==========
process_command([cheat, heal]) :-
retract(player_health(_)),
assertz(player_health(100)),
write('Gesundheit wiederhergestellt!'), nl.
process_command([cheat, items]) :-
assertz(player_inventory(spule)),
assertz(player_inventory(batterie)),
assertz(player_inventory(kondensator)),
assertz(player_inventory(emp_granate)),
assertz(player_inventory(emp_granate)),
assertz(player_inventory(parkour_handschuhe)),
assertz(player_inventory(drohnen_motor)),
assertz(player_inventory(steuerungsmodul)),
assertz(player_inventory(heilspray)),
write('Alle Items erhalten!'), nl.
process_command([cheat, teleport, LOC]) :-
retract(player_location(_)),
assertz(player_location(LOC)).
process_command([cheat, generator_components]) :-
assertz(player_inventory(spule)),
assertz(player_inventory(batterie)),
assertz(player_inventory(kondensator)),
write('EMP-Generator Komponenten erhalten!'), nl.
process_command([cheat, generator_components]) :-
assertz(player_inventory(drohnen_motor)),
assertz(player_inventory(steuerungsmodul)),
write('Kampfdrone Komponenten erhalten!'), nl.
process_command(_) :-
write('Unbekannter Befehl. Verwende "hilfe" für eine Liste der Befehle.'), nl.

68
game_assets/commands.pl Normal file
View File

@ -0,0 +1,68 @@
% ========== MOVEMENT ==========
move_player(Direction) :-
player_location(CurrentLoc),
connected(CurrentLoc, Direction),
(obstacle(CurrentLoc, Direction, ObstacleType) ->
handle_obstacle(ObstacleType, Direction) ;
(retract(player_location(CurrentLoc)),
assertz(player_location(Direction)),
write('Du gehst nach '), write(Direction), nl
)),
!.
move_player(_) :-
write('Du kannst nicht dorthin gehen.'), nl.
% ========== LOOKING ==========
look_around :-
player_location(Loc),
location(Loc, Name, Desc),
write(Name), nl,
write(Desc), nl,
list_items_here(Loc),
list_npcs_here(Loc),
list_enemies_here(Loc),
list_exits(Loc),
list_obstacles_here(Loc).
list_items_here(Loc) :-
findall(Item, item_location(Item, Loc), Items),
(Items = [] -> true ;
(write('Gegenstände hier: '), write_list(Items), nl)).
list_npcs_here(Loc) :-
findall(NPC, npc_location(NPC, Loc), NPCs),
(NPCs = [] -> true ;
(write('Personen hier: '), write_list(NPCs), nl)).
list_enemies_here(Loc) :-
findall(Enemy, enemy_location(Enemy, Loc), Enemies),
(Enemies = [] -> true ;
(write('Feinde hier: '), write_list(Enemies), nl)).
list_exits(Loc) :-
findall(Exit, connected(Loc, Exit), Exits),
(Exits = [] -> write('Keine Ausgänge.') ;
(write('Ausgänge: '), write_list(Exits))), nl.
list_obstacles_here(Loc) :-
findall(obstacle(Loc, Exit, ObstacleType), obstacle(Loc, Exit, ObstacleType), Obstacles),
(Obstacles = [] -> true ; list_obstacles(Obstacles)).
% ========== HELP ==========
help :- write('Verfügbare Befehle:'), nl,
write('- schaue: Beschreibung des aktuellen Ortes'), nl,
write('- gehe(richtung): Bewege dich zu einem anderen Ort'), nl,
write('- nimm(gegenstand): Nimm einen Gegenstand auf'), nl,
write('- verwende(gegenstand): Verwende einen Gegenstand'), nl,
write('- rede(person): Spreche mit einer Person'), nl,
write('- angriff(feind): Beginne Kampf gegen einen Feind'), nl,
write('- baue(item): Baue einen Gegenstand (nur in Werkstatt)'), nl,
write('- hack(ziel): Hacke ein Ziel'), nl,
write('- klettere: Klettere auf Dächer/Türme'), nl,
write('- inventar: Zeige dein Inventar'), nl,
write('- status: Zeige deinen Status'), nl,
write('- beende: Schließt das Spiel'), nl,
write('- clear: Löscht den Terminalbildschirm'), nl,
write('- Richtungsbefehle: oben, unten, links, rechts, a, b'), nl,
write(' (Könnte für etwas Besonderes nützlich sein...)'), nl.

View File

@ -0,0 +1,45 @@
% ========== CRAFTING SYSTEM ==========
craft_item(emp_generator) :-
player_location(htl_werkstatt),
player_inventory(spule),
player_inventory(batterie),
player_inventory(kondensator),
write('Du baust aus Spule, Batterie und Kondensator einen EMP-Generator!'), nl,
retract(player_inventory(spule)),
retract(player_inventory(batterie)),
retract(player_inventory(kondensator)),
assertz(player_inventory(emp_generator)),
retract(game_state(emp_built, false)),
assertz(game_state(emp_built, true)),
!.
craft_item(emp_generator) :-
player_location(htl_werkstatt),
write('Du brauchst: Elektro-Spule, Hochleistungsbatterie und Kondensator.'), nl,
!.
craft_item(emp_generator) :-
write('Du kannst nur in der HTL Leonding Werkstatt bauen.'), nl,
!.
craft_item(kampfdrohne) :-
player_location(htl_werkstatt),
player_inventory(drohnen_motor),
player_inventory(steuerungsmodul),
write('Du baust aus Motor und Steuerungsmodul eine Kampfdrohne!'), nl,
retract(player_inventory(drohnen_motor)),
retract(player_inventory(steuerungsmodul)),
assertz(player_inventory(kampfdrohne)),
!.
craft_item(kampfdrohne) :-
player_location(htl_werkstatt),
write('Du brauchst: Drohnen-Motor und Steuerungsmodul um eine Kampfdrohne zu bauen.'), nl,
!.
craft_item(kampfdrohne) :-
write('Du kannst nur in der HTL Leonding Werkstatt bauen.'), nl,
!.
craft_item(_) :-
write('Du kannst diesen Gegenstand nicht bauen.'), nl.

46
game_assets/game_state.pl Normal file
View File

@ -0,0 +1,46 @@
% ========== GAME STATE ==========
:- dynamic(player_location/1).
:- dynamic(player_health/1).
:- dynamic(player_inventory/1).
:- dynamic(game_state/2).
:- dynamic(npc_location/2).
:- dynamic(enemy_location/2).
:- dynamic(item_location/2).
:- dynamic(enemy/4).
:- dynamic(enemy_hacked/1).
:- dynamic(hack_attempted/1).
:- dynamic(obstacle/3).
:- dynamic(box_unlocked/1).
:- dynamic(in_combat/1).
:- dynamic(combat_turn/1).
:- dynamic(emp_used_in_combat/1).
:- dynamic(drone_cooldown/2).
:- dynamic(health_recovery_used/2).
:- dynamic(konami_sequence/1).
:- dynamic(konami_position/1).
% ========== GAME STATE MANAGEMENT ==========
check_game_state :-
player_health(Health),
(Health =< 0 ->
(retractall(in_combat(_)),
end_game(defeat),
!, fail) ;
true).
show_status :-
player_health(Health),
write('=== STATUS ==='), nl,
write('Gesundheit: '), write(Health), nl,
(player_inventory(kampfdrohne) ->
write('Kampfdrohne: ✓ Gebaut'), nl ;
(write('Kampfdrohne Komponenten:'), nl,
(player_inventory(drohnen_motor) -> write(' Drohnen-Motor: ✓') ; write(' Drohnen-Motor: ✗')), nl,
(player_inventory(steuerungsmodul) -> write(' Steuerungsmodul: ✓') ; write(' Steuerungsmodul: ✗')), nl)),
(game_state(emp_built, true) ->
write('EMP-Generator: ✓ Gebaut'), nl ;
(write('EMP-Generator Komponenten:'), nl,
(player_inventory(spule) -> write(' Elektro-Spule: ✓') ; write(' Elektro-Spule: ✗')), nl,
(player_inventory(batterie) -> write(' Batterie: ✓') ; write(' Batterie: ✗')), nl,
(player_inventory(kondensator) -> write(' Kondensator: ✓') ; write(' Kondensator: ✗')), nl)),
write('=============='), nl.

View File

@ -0,0 +1,75 @@
% ========== HACKING SYSTEM ==========
hack_target(box) :-
player_location(Loc),
player_inventory(laptop),
hacking_minigame(Loc),
!.
hack_target(_) :-
write('Du kannst dieses Ziel nicht hacken oder hast keinen Laptop.'), nl.
% ========== HACKING MINI-GAMES ==========
hacking_minigame(altstadt) :-
box_unlocked(altstadt_box),
write('Diese Box wurde bereits gehackt.'), nl,
!.
hacking_minigame(altstadt) :-
write('=== HACKING MINI-GAME ==='), nl,
write('Entschlüssele den Code: 1001 + 0110 = ?'), nl,
write('Gib das Ergebnis in binär ein: '),
read(Answer),
(Answer = 1111 ->
(write('Korrekt! Du findest eine Elektro-Spule in der Box!'), nl,
assertz(player_inventory(spule)),
assertz(box_unlocked(altstadt_box))) ;
(write('Falsch! Versuch es nochmal.'), nl,
fail)).
hacking_minigame(donauufer) :-
box_unlocked(donauufer_box),
write('Diese Box wurde bereits gehackt.'), nl,
!.
hacking_minigame(donauufer) :-
write('=== HACKING MINI-GAME ==='), nl,
write('SQL Injection: Welcher Befehl umgeht die Passwort-Abfrage?'), nl,
write('1) DROP TABLE users'), nl,
write('2) \' OR \'1\'=\'1'), nl,
write('3) SELECT * FROM passwords'), nl,
write('Deine Wahl (1-3): '),
read(Answer),
(Answer = 2 ->
(write('Korrekt! Du findest eine Hochleistungsbatterie in der Box!'), nl,
assertz(player_inventory(batterie)),
assertz(box_unlocked(donauufer_box))) ;
(write('Falsch! Versuch es nochmal.'), nl,
fail)).
hacking_minigame(poestlingberg) :-
box_unlocked(poestlingberg_box),
write('Diese Box wurde bereits gehackt.'), nl,
!.
hacking_minigame(poestlingberg) :-
player_inventory(kampfdrohne),
write('=== DROHNEN-HACKING ==='), nl,
write('Deine Kampfdrohne verbindet sich mit der Box...'), nl,
write('Netzwerk-Port-Scan: Welcher Port ist für SSH Standard?'), nl,
write('1) Port 80'), nl,
write('2) Port 22'), nl,
write('3) Port 443'), nl,
write('Deine Wahl (1-3): '),
read(Answer),
(Answer = 2 ->
(write('Korrekt! Du findest einen Kondensator in der Box!'), nl,
assertz(player_inventory(kondensator)),
assertz(box_unlocked(poestlingberg_box))) ;
(write('Falsch! Versuch es nochmal.'), nl,
fail)).
hacking_minigame(poestlingberg) :-
write('Du brauchst eine Kampfdrohne um diese Box zu hacken.'), nl.
hacking_minigame(_) :-
write('Hier gibt es nichts zu hacken.'), nl.

31
game_assets/inventory.pl Normal file
View File

@ -0,0 +1,31 @@
% ========== INVENTORY MANAGEMENT ==========
take_item(ItemName) :-
player_location(Loc),
item_location(ItemName, Loc),
retract(item_location(ItemName, Loc)),
assertz(player_inventory(ItemName)),
item(ItemName, DisplayName, _),
write('Du nimmst '), write(DisplayName), write(' auf.'), nl,
!.
take_item(_) :-
write('Diesen Gegenstand kannst du hier nicht finden.'), nl.
use_item(ItemName) :-
player_inventory(ItemName),
execute_item_use(ItemName),
!.
use_item(_) :-
write('Du hast diesen Gegenstand nicht oder kannst ihn nicht verwenden.'), nl.
show_inventory :-
write('Dein Inventar:'), nl,
findall(Item, player_inventory(Item), Items),
(Items = [] -> write('Dein Inventar ist leer.') ; list_inventory_items(Items)), nl.
list_inventory_items([]).
list_inventory_items([H|T]) :-
item(H, DisplayName, Desc),
write('- '), write(DisplayName), write(': '), write(Desc), nl,
list_inventory_items(T).

View File

@ -21,3 +21,24 @@ init_items :-
assertz(item_location(emp_granate, htl_werkstatt)), assertz(item_location(emp_granate, htl_werkstatt)),
assertz(item_location(parkour_handschuhe, altstadt)), assertz(item_location(parkour_handschuhe, altstadt)),
assertz(item_location(heilspray, htl_labor)). assertz(item_location(heilspray, htl_labor)).
% ========== ITEM USAGE ==========
execute_item_use(laptop) :-
player_location(htl_labor),
write('Du hackst dich in die Schulserver ein und analysierst die Drohnen-Aufnahmen.'), nl,
write('SCHOCKIERENDE ENTDECKUNG: Die Vögel sind Überwachungsdrohnen!'), nl,
!.
execute_item_use(heilspray) :-
player_health(Health),
(Health >= 100 ->
write('Du hast bereits volle Gesundheit!'), nl ;
(NewHealth is min(100, Health + 30),
retract(player_health(Health)),
assertz(player_health(NewHealth)),
write('Du verwendest das Heilspray und gewinnst 30 Gesundheitspunkte!'), nl,
retract(player_inventory(heilspray)))),
!.
execute_item_use(_) :-
write('Du kannst diesen Gegenstand hier nicht verwenden.'), nl.

View File

@ -0,0 +1,40 @@
% ========== KONAMI CODE ==========
check_konami_input(Input) :-
(konami_position(_) -> true ; init_konami),
konami_position(Pos),
konami_sequence(Sequence),
nth0(Pos, Sequence, Expected),
(Input = Expected ->
(NewPos is Pos + 1,
retract(konami_position(Pos)),
assertz(konami_position(NewPos)),
length(Sequence, SeqLength),
(NewPos >= SeqLength ->
unlock_konami_code ;
true)) ;
(retract(konami_position(_)),
assertz(konami_position(0)),
write('Invalide Code, Hinweis: Contra.'), nl)).
init_konami :-
retractall(konami_sequence(_)),
retractall(konami_position(_)),
assertz(konami_sequence([oben, oben, unten, unten, links, rechts, links, rechts, b, a])),
assertz(konami_position(0)).
unlock_konami_code :-
game_state(konami_unlocked, false),
write('*** KONAMI CODE AKTIVIERT! ***'), nl,
write('Ein geheimnisvoller Master-Schlüssel materialisiert sich in deinem Inventar!'), nl,
write('Dieses Artefakt gewährt dir vollständigen Zugriff auf alle Systeme...'), nl,
assertz(player_inventory(master_schluessel)),
retract(game_state(konami_unlocked, false)),
assertz(game_state(konami_unlocked, true)),
retract(konami_position(_)),
assertz(konami_position(0)),
!.
unlock_konami_code :-
write('Der Konami Code wurde bereits aktiviert!'), nl,
retract(konami_position(_)),
assertz(konami_position(0)).

View File

@ -27,31 +27,4 @@ connected(donauufer, altstadt).
connected(donauufer, poestlingberg). connected(donauufer, poestlingberg).
connected(poestlingberg, donauufer). connected(poestlingberg, donauufer).
connected(poestlingberg, aviary_hq). connected(poestlingberg, aviary_hq).
connected(aviary_hq, poestlingberg). connected(aviary_hq, poestlingberg).
% ========== OBSTACLES ==========
init_obstacles :-
% Obstacle between altstadt and donauufer
assertz(obstacle(altstadt, donauufer, hohe_mauer)),
assertz(obstacle(donauufer, altstadt, hohe_mauer)),
% Obstacle between donauufer and poestlingberg
assertz(obstacle(donauufer, poestlingberg, drone_swarm)),
assertz(obstacle(poestlingberg, donauufer, drone_swarm)),
% Obstacle to aviary_hq
assertz(obstacle(poestlingberg, aviary_hq, security_system)),
assertz(obstacle(aviary_hq, poestlingberg, security_system)).
list_obstacles([]).
list_obstacles([obstacle(_, Exit, ObstacleType)|T]) :-
write('HINDERNIS nach '), write(Exit), write(': '),
describe_obstacle(ObstacleType), nl,
list_obstacles(T).
describe_obstacle(hohe_mauer) :-
write('Hohe Mauer - benötigt Parkour-Handschuhe zum Klettern').
describe_obstacle(drone_swarm) :-
write('Drohnen-Schwarm - benötigt Kampfdrohne zur Abwehr').
describe_obstacle(security_system) :-
write('Hochsicherheitssystem - benötigt EMP-Generator').

View File

@ -66,4 +66,24 @@ init_enemies :-
assertz(enemy_location(tauben_schwarm, altstadt)), assertz(enemy_location(tauben_schwarm, altstadt)),
assertz(enemy_location(storch_drohne, donauufer)), assertz(enemy_location(storch_drohne, donauufer)),
assertz(enemy_location(die_kraehe, aviary_hq)). assertz(enemy_location(die_kraehe, aviary_hq)).
handle_enemy_defeat(tauben_schwarm) :-
write('Die Tauben explodieren! Du findest ein Heilspray und einen Drohnen-Motor in den Trümmern.'), nl,
player_location(Loc),
assertz(item_location(drohnen_motor, Loc)),
assertz(item_location(heilspray, Loc)).
handle_enemy_defeat(storch_drohne) :-
write('Die Storch-Drohne lässt ein Steuerungsmodul und EMP-Granaten fallen!'), nl,
player_location(Loc),
assertz(item_location(steuerungsmodul, Loc)),
assertz(item_location(emp_granate, Loc)).
handle_enemy_defeat(die_kraehe) :-
write('Die Krähe ist besiegt! Das Drohnen-Netzwerk wankt...'), nl,
write('Du stehst vor der Hauptkonsole von Aviary Control.'), nl,
write('Plötzlich erscheint eine Nachricht auf dem Bildschirm:'), nl,
write('"Beeindruckend, John. Du hast es bis hierher geschafft."'), nl,
write('"Aber jetzt musst du eine Wahl treffen..."'), nl,
final_choice.

57
game_assets/obstacles.pl Normal file
View File

@ -0,0 +1,57 @@
% ========== OBSTACLES ==========
init_obstacles :-
% Obstacle between altstadt and donauufer
assertz(obstacle(altstadt, donauufer, hohe_mauer)),
assertz(obstacle(donauufer, altstadt, hohe_mauer)),
% Obstacle between donauufer and poestlingberg
assertz(obstacle(donauufer, poestlingberg, drone_swarm)),
assertz(obstacle(poestlingberg, donauufer, drone_swarm)),
% Obstacle to aviary_hq
assertz(obstacle(poestlingberg, aviary_hq, security_system)),
assertz(obstacle(aviary_hq, poestlingberg, security_system)).
describe_obstacle(hohe_mauer) :-
write('Hohe Mauer - benötigt Parkour-Handschuhe zum Klettern').
describe_obstacle(drone_swarm) :-
write('Drohnen-Schwarm - benötigt Kampfdrohne zur Abwehr').
describe_obstacle(security_system) :-
write('Hochsicherheitssystem - benötigt EMP-Generator').
list_obstacles([]).
list_obstacles([obstacle(_, Exit, ObstacleType)|T]) :-
write('HINDERNIS nach '), write(Exit), write(': '),
describe_obstacle(ObstacleType), nl,
list_obstacles(T).
handle_obstacle(hohe_mauer, Direction) :-
(player_inventory(parkour_handschuhe) ->
(write('Du kletterst mit den Parkour-Handschuhen über die hohe Mauer!'), nl,
player_location(CurrentLoc),
retract(obstacle(CurrentLoc, Direction, hohe_mauer)),
retract(player_location(CurrentLoc)),
assertz(player_location(Direction)),
write('Du gehst nach '), write(Direction), nl) ;
write('Eine hohe Mauer blockiert deinen Weg! Du brauchst Parkour-Handschuhe.'), nl).
handle_obstacle(drone_swarm, Direction) :-
(player_inventory(kampfdrohne) ->
(write('Deine Kampfdrohne bekämpft den feindlichen Schwarm!'), nl,
write('Die Drohnen werden zerstört und der Weg ist frei!'), nl,
player_location(CurrentLoc),
retract(obstacle(CurrentLoc, Direction, drone_swarm)),
retract(player_location(CurrentLoc)),
assertz(player_location(Direction)),
write('Du gehst nach '), write(Direction), nl) ;
write('Ein Schwarm aggressiver Drohnen blockiert den Weg! Du brauchst eine Kampfdrohne.'), nl).
handle_obstacle(security_system, Direction) :-
(player_inventory(emp_generator) ->
(write('Du aktivierst den EMP-Generator! Das Sicherheitssystem bricht zusammen!'), nl,
player_location(CurrentLoc),
retract(obstacle(CurrentLoc, Direction, security_system)),
retract(player_location(CurrentLoc)),
assertz(player_location(Direction)),
write('Du gehst nach '), write(Direction), nl) ;
write('Ein Hochsicherheitssystem blockiert den Zugang! Du brauchst einen EMP-Generator.'), nl).

View File

@ -0,0 +1,85 @@
% ========== PARKOUR-MINIGAMES ==========
parkour_minigame_altstadt :-
write('Sequenz-Challenge: Wiederhole die Bewegungsfolge!'), nl,
random_member(Sequence, [[sprung, rolle, kletter], [rolle, sprung, balance], [kletter, sprung, rolle]]),
write('Merke dir: '), write_sequence(Sequence), nl,
write('Warte...'), nl, sleep(2),
clear_screen,
write('Jetzt wiederhole die Sequenz:'), nl,
write('Gib die Sequenz als Liste ein, z.B. [sprung, rolle, kletter].'), nl,
write('Verfügbare Bewegungen: sprung, rolle, kletter, balance'), nl,
write('> '),
read_sequence(UserSequence),
(UserSequence = Sequence ->
(write('Perfekte Ausführung! Du erreichst das Dach sicher!'), nl,
write('Du findest eine verschlossene Box auf dem Dach.'), nl,
write('Verwende "hack(box)" um sie zu öffnen.'), nl) ;
(write('Falsche Sequenz! Du rutschst ab und verlierst 10 Gesundheit.'), nl,
damage_player(10))).
climbing_minigame_donauufer :-
write('Balance-Challenge: Halte das Gleichgewicht!'), nl,
write('Drücke abwechselnd "links" und "rechts" um das Gleichgewicht zu halten.'), nl,
write('Du musst 5 mal korrekt reagieren!'), nl,
balance_challenge(5, 0).
balance_challenge(0, Success) :-
Success >= 4,
write('Excellent! Du hast den Turm erfolgreich erklommen!'), nl,
write('Oben ist ein elektrisches Schutzschild um eine Box.'), nl,
write('Du brauchst eine EMP-Granate um das Schild zu deaktivieren.'), nl,
(player_inventory(emp_granate) ->
(write('Du verwendest die EMP-Granate! Das Schild fällt aus!'), nl,
retract(player_inventory(emp_granate)),
write('Verwende "hack(box)" um die Box zu öffnen.'), nl) ;
true),
!.
balance_challenge(0, Success) :-
Success < 4,
write('Du verlierst das Gleichgewicht und fällst! 15 Schaden!'), nl,
damage_player(15),
!.
balance_challenge(Remaining, Success) :-
Remaining > 0,
random_member(Direction, [links, rechts]),
write('Das Gebäude schwankt nach '), write(Direction), write('! Schnell reagieren:'), nl,
write('> '),
read(Response),
NewRemaining is Remaining - 1,
(Response = Direction ->
(write('Gut! Gleichgewicht gehalten.'), nl,
NewSuccess is Success + 1) ;
(write('Falsch! Du wackelst gefährlich.'), nl,
NewSuccess = Success)),
balance_challenge(NewRemaining, NewSuccess).
climbing_minigame_poestlingberg :-
write('Stealth-Klettern: Vermeide die Überwachungskameras!'), nl,
write('Du musst die richtige Route wählen um unentdeckt zu bleiben.'), nl,
stealth_climbing_challenge.
stealth_climbing_challenge :-
write('Stufe 1: Kamera schwenkt von links nach rechts. Wann bewegst du dich?'), nl,
write('1) Wenn die Kamera nach links schaut'), nl,
write('2) Wenn die Kamera nach rechts schaut'), nl,
write('3) Wenn die Kamera geradeaus schaut'), nl,
write('> '),
read(Choice1),
(Choice1 = 1 ->
(write('Richtig! Du nutzt den toten Winkel.'), nl,
write('Stufe 2: Zwei Kameras kreuzen sich. Wann bewegst du dich?'), nl,
write('1) Gleichzeitig mit beiden'), nl,
write('2) Zwischen den Schwenkbewegungen'), nl,
write('3) Wenn eine Kamera defekt ist'), nl,
write('> '),
read(Choice2),
(Choice2 = 2 ->
(write('Perfekt! Du erreichst die Spitze unentdeckt!'), nl,
write('Du findest eine schwer gesicherte Box.'), nl,
write('Diese Box benötigt eine Kampfdrohne zum Hacken.'), nl) ;
(write('Entdeckt! Alarm! Du verlierst 20 Gesundheit beim hastigen Rückzug.'), nl,
damage_player(20)))) ;
(write('Entdeckt! Du musst schnell fliehen und verlierst 15 Gesundheit.'), nl,
damage_player(15))).