Compare commits

..

2 Commits

Author SHA1 Message Date
MatyasZsombor
fc8bb30ab2 added new obstacle, fixed a few bugs, added emp-limit
All checks were successful
Build, Publish Docker Image, and Deploy to Kubernetes / build_and_push (push) Successful in 5s
Build, Publish Docker Image, and Deploy to Kubernetes / deploy_to_k8s (push) Successful in 22s
2025-06-15 21:04:18 +02:00
MatyasZsombor
d974f9d671 Fixed a few bugs, added climbing system 2025-06-15 20:14:50 +02:00

View File

@ -11,12 +11,15 @@
:- dynamic(item_location/2). :- dynamic(item_location/2).
:- dynamic(discovered/1). :- dynamic(discovered/1).
:- dynamic(enemy/4). :- dynamic(enemy/4).
:- dynamic(enemy_hacked/1).
:- dynamic(hack_attempted/1).
:- dynamic(obstacle/3). :- dynamic(obstacle/3).
:- dynamic(box_unlocked/1). :- dynamic(box_unlocked/1).
:- dynamic(in_combat/1). :- dynamic(in_combat/1).
:- dynamic(combat_turn/1). :- dynamic(combat_turn/1).
:- dynamic(konami_sequence/1). :- dynamic(konami_sequence/1).
:- dynamic(konami_position/1). :- dynamic(konami_position/1).
:- dynamic(emp_used_in_combat/1).
% ========== INITIALIZATION ========== % ========== INITIALIZATION ==========
init_game :- init_game :-
@ -28,6 +31,10 @@ init_game :-
retractall(box_unlocked(_)), retractall(box_unlocked(_)),
retractall(in_combat(_)), retractall(in_combat(_)),
retractall(combat_turn(_)), retractall(combat_turn(_)),
retractall(enemy_hacked(_)),
retractall(hack_attempted(_)),
retractall(crow_weakened(_)),
retractall(emp_used_in_combat(_)),
% Initialize random number generator % Initialize random number generator
randomize, randomize,
@ -35,9 +42,7 @@ init_game :-
% Set initial game state % Set initial game state
assertz(player_location(htl_labor)), assertz(player_location(htl_labor)),
assertz(player_health(100)), assertz(player_health(100)),
assertz(game_state(chapter, 1)),
assertz(game_state(wren_met, false)), assertz(game_state(wren_met, false)),
assertz(game_state(havik_active, false)),
assertz(game_state(emp_built, false)), assertz(game_state(emp_built, false)),
assertz(game_state(crow_weakened, false)), assertz(game_state(crow_weakened, false)),
assertz(game_state(components_explained, false)), assertz(game_state(components_explained, false)),
@ -62,20 +67,20 @@ location(poestlingberg, 'Pöstlingberg Überwachungsturm',
location(aviary_hq, 'Aviary HQ Wolkenkratzer', location(aviary_hq, 'Aviary HQ Wolkenkratzer',
'Das Hauptquartier der Verschwörung. Ein Glasbau, der die ganze Stadt überblickt.'). 'Das Hauptquartier der Verschwörung. Ein Glasbau, der die ganze Stadt überblickt.').
location(htl_leonding, 'HTL Leonding Werkstatt', location(htl_werkstatt, 'HTL Leonding Werkstatt',
'Eine gut ausgestattete Elektronikwerkstatt. Hier kannst du komplexe Geräte bauen.'). 'Eine gut ausgestattete Elektronikwerkstatt. Hier kannst du komplexe Geräte bauen.').
% Location connections % Location connections
connected(htl_werkstatt, htl_labor).
connected(htl_labor, htl_werkstatt).
connected(htl_labor, altstadt). connected(htl_labor, altstadt).
connected(altstadt, htl_labor). connected(altstadt, htl_labor).
connected(altstadt, donauufer). connected(altstadt, donauufer).
connected(donauufer, altstadt). connected(donauufer, altstadt).
connected(donauufer, poestlingberg). connected(donauufer, poestlingberg).
connected(poestlingberg, donauufer). connected(poestlingberg, donauufer).
connected(poestlingberg, htl_leonding). connected(poestlingberg, aviary_hq).
connected(htl_leonding, poestlingberg). connected(aviary_hq, poestlingberg).
connected(htl_leonding, aviary_hq).
connected(aviary_hq, htl_leonding).
% ========== OBSTACLES ========== % ========== OBSTACLES ==========
init_obstacles :- init_obstacles :-
@ -84,39 +89,40 @@ init_obstacles :-
assertz(obstacle(donauufer, altstadt, hohe_mauer)), assertz(obstacle(donauufer, altstadt, hohe_mauer)),
% Obstacle between donauufer and poestlingberg % Obstacle between donauufer and poestlingberg
assertz(obstacle(donauufer, poestlingberg, electric_fence)), assertz(obstacle(donauufer, poestlingberg, drone_swarm)),
assertz(obstacle(poestlingberg, donauufer, electric_fence)), assertz(obstacle(poestlingberg, donauufer, drone_swarm)),
% Obstacle to aviary_hq % Obstacle to aviary_hq
assertz(obstacle(htl_leonding, aviary_hq, security_system)), assertz(obstacle(poestlingberg, aviary_hq, security_system)),
assertz(obstacle(aviary_hq, htl_leonding, security_system)). assertz(obstacle(aviary_hq, poestlingberg, security_system)).
% ========== ITEMS ========== % ========== ITEMS ==========
item(laptop, 'Laptop', 'Dein vertrauter Laptop mit Hacking-Software.'). item(laptop, 'Laptop', 'Dein vertrauter Laptop mit Hacking-Software.').
item(emp_granate, 'EMP-Granate', 'Eine elektromagnetische Impulsgranate von Wren.'). item(emp_granate, 'EMP-Granate', 'Eine elektromagnetische Impulsgranate gegen elektrische Systeme.').
item(parkour_handschuhe, 'Parkour-Handschuhe', 'Verbessern deinen Grip beim Klettern.'). item(parkour_handschuhe, 'Parkour-Handschuhe', 'Verbessern deinen Grip beim Klettern.').
item(kampfdrohne, 'Kampfdrohne', 'Deine selbstgebaute Verteidigungsdrohne.'). item(kampfdrohne, 'Kampfdrohne', 'Deine selbstgebaute Verteidigungsdrohne.').
item(emp_generator, 'EMP-Generator', 'Ein mächtiger EMP-Generator gegen die Krähe.'). item(emp_generator, 'EMP-Generator', 'Ein mächtiger EMP-Generator gegen das Sischerheitssytem des Aviary HQs.').
item(coil, 'Elektro-Spule', 'Eine hochwertige Induktionsspule.'). item(spule, 'Elektro-Spule', 'Eine hochwertige Induktionsspule.').
item(battery, 'Hochleistungsbatterie', 'Eine spezielle Batterie für EMP-Geräte.'). item(batterie, 'Hochleistungsbatterie', 'Eine spezielle Batterie für EMP-Geräte.').
item(capacitor, 'Kondensator', 'Ein Hochspannungskondensator.'). item(kondensator, 'Kondensator', 'Ein Hochspannungskondensator.').
item(heilspray, 'Heilspray', 'Regeneriert 30 Gesundheitspunkte.'). item(heilspray, 'Heilspray', 'Regeneriert 30 Gesundheitspunkte.').
item(drohnen_motor, 'Drohnen-Motor', 'Ein kleiner Motor für Drohnen-Antrieb.'). item(drohnen_motor, 'Drohnen-Motor', 'Ein kleiner Motor für Drohnen-Antrieb.').
item(steuerungsmodul, 'Steuerungsmodul', 'Elektronisches Modul zur Drohnen-Steuerung.'). item(steuerungsmodul, 'Steuerungsmodul', 'Elektronisches Modul zur Drohnen-Steuerung.').
item(master_key, 'Master-Schlüssel', 'Ein geheimnisvoller Schlüssel mit Aviary-Logo. Gewährt vollständigen Systemzugriff.'). item(master_schluessel, 'Master-Schlüssel', 'Ein geheimnisvoller Schlüssel mit Aviary-Logo. Gewährt vollständigen Systemzugriff.').
% Initial item locations % Initial item locations
init_items :- init_items :-
retractall(item_location(_, _)), retractall(item_location(_, _)),
retractall(player_inventory(_)), retractall(player_inventory(_)),
assertz(player_inventory(laptop)), assertz(player_inventory(laptop)),
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)).
% ========== CHARACTERS ========== % ========== CHARACTERS ==========
character(john, 'John Miller', 'Ein 17-jähriger HTL-Schüler mit Hacking-Fähigkeiten.'). character(john, 'John Miller', 'Ein 17-jähriger HTL-Schüler mit Hacking-Fähigkeiten.').
character(wren, 'Wren', 'Cybersicherheitslehrerin und Rogue-Hackerin.'). character(wren, 'Wren', 'Cybersicherheitslehrerin und Rogue-Hackerin.').
character(havik, 'Agent HAVIK', 'Kybernetischer Vollstrecker von Aviary Control.').
character(die_kraehe, 'Die Krähe', 'KI-Mastermind hinter dem Drohnen-Netzwerk.'). character(die_kraehe, 'Die Krähe', 'KI-Mastermind hinter dem Drohnen-Netzwerk.').
% Initial NPC locations % Initial NPC locations
@ -142,7 +148,8 @@ start_game :-
init_items, init_items,
init_npcs, init_npcs,
init_enemies, init_enemies,
write('=== SKYNET: FLÜGEL DER TÄUSCHUNG - ENHANCED ==='), nl, %clear_screen,
write('=== SKYNET: WINGS OF DECEPTION ==='), nl,
write('Ein Text-Adventure von Jonas Hinterdorfer und Zsombor Matyas'), nl, nl, write('Ein Text-Adventure von Jonas Hinterdorfer und Zsombor Matyas'), nl, nl,
intro_story, intro_story,
game_loop. game_loop.
@ -152,10 +159,8 @@ intro_story :-
write('Heute Morgen wurdest du von einem aggressiven Taubenschwarm attackiert.'), nl, write('Heute Morgen wurdest du von einem aggressiven Taubenschwarm attackiert.'), nl,
write('Ihre Augen glühten rot und ihre Bewegungen waren unnatürlich präzise...'), nl, write('Ihre Augen glühten rot und ihre Bewegungen waren unnatürlich präzise...'), nl,
write('Jetzt sitzt du im Cybersicherheitslabor und analysierst die Aufnahmen.'), nl, nl, write('Jetzt sitzt du im Cybersicherheitslabor und analysierst die Aufnahmen.'), nl, nl,
write('Verfügbare Befehle: schaue, gehe(richtung), nimm(gegenstand), verwende(gegenstand)'), nl, write('Für alle verfügbare Befehle schreibe \'hilfe.\''), nl,
write(' inventar, status, hilfe, beende, rede(person), angriff(feind), baue(item)'), nl, write('Bsp: \'verwende(laptop).\''), nl, nl.
write(' hack(ziel), klettere, kampf_aktion(aktion)'), nl,
write('Beispiel: gehe(altstadt). oder nimm(laptop).'), nl, nl.
game_loop :- game_loop :-
(in_combat(Enemy) -> combat_loop(Enemy) ; normal_loop). (in_combat(Enemy) -> combat_loop(Enemy) ; normal_loop).
@ -167,21 +172,23 @@ normal_loop :-
write('> '), write('> '),
read_line(Command), read_line(Command),
process_command(Command), process_command(Command),
nl,
check_game_state, check_game_state,
!, !,
game_loop. game_loop.
combat_loop(Enemy) :- combat_loop(Enemy) :-
enemy(Enemy, DisplayName, Health, _), enemy(Enemy, DisplayName, Health, _),
nl,
write('=== KAMPF GEGEN '), write(DisplayName), write(' ==='), nl, write('=== KAMPF GEGEN '), write(DisplayName), write(' ==='), nl,
write('Feind Gesundheit: '), write(Health), nl, write('Feind Gesundheit: '), write(Health), nl,
player_health(PlayerHealth), player_health(PlayerHealth),
write('Deine Gesundheit: '), write(PlayerHealth), nl, write('Deine Gesundheit: '), write(PlayerHealth), nl,
write('Verfügbare Aktionen: angriff, verwende(item), flucht'), nl, write('Verfügbare Aktionen: angriff, verwende(item)'), nl, nl,
write('> '), write('> '),
read_line(Command), read_line(Command),
process_combat_command(Command, Enemy), process_combat_command(Command, Enemy),
check_combat_state(Enemy), check_game_state,
!, !,
game_loop. game_loop.
@ -221,14 +228,14 @@ check_konami_input(Input) :-
true)) ; true)) ;
(retract(konami_position(_)), (retract(konami_position(_)),
assertz(konami_position(0)), assertz(konami_position(0)),
write('Ungültige Richtung.'), nl)). write('Invalide Code, Hinweis: Contra.'), nl)).
unlock_konami_code :- unlock_konami_code :-
game_state(konami_unlocked, false), game_state(konami_unlocked, false),
write('*** KONAMI CODE AKTIVIERT! ***'), nl, write('*** KONAMI CODE AKTIVIERT! ***'), nl,
write('Ein geheimnisvoller Master-Schlüssel materialisiert sich in deinem Inventar!'), 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, write('Dieses Artefakt gewährt dir vollständigen Zugriff auf alle Systeme...'), nl,
assertz(player_inventory(master_key)), assertz(player_inventory(master_schluessel)),
retract(game_state(konami_unlocked, false)), retract(game_state(konami_unlocked, false)),
assertz(game_state(konami_unlocked, true)), assertz(game_state(konami_unlocked, true)),
retract(konami_position(_)), retract(konami_position(_)),
@ -300,6 +307,9 @@ process_command([inventar]) :-
process_command([status]) :- process_command([status]) :-
show_status. show_status.
process_command([clear]) :-
clear_screen.
% ========== CHEAT CODES (for testing) ========== % ========== CHEAT CODES (for testing) ==========
process_command([cheat, heal]) :- process_command([cheat, heal]) :-
retract(player_health(_)), retract(player_health(_)),
@ -307,9 +317,9 @@ process_command([cheat, heal]) :-
write('Gesundheit wiederhergestellt!'), nl. write('Gesundheit wiederhergestellt!'), nl.
process_command([cheat, items]) :- process_command([cheat, items]) :-
assertz(player_inventory(coil)), assertz(player_inventory(spule)),
assertz(player_inventory(battery)), assertz(player_inventory(batterie)),
assertz(player_inventory(capacitor)), assertz(player_inventory(kondensator)),
assertz(player_inventory(emp_granate)), assertz(player_inventory(emp_granate)),
assertz(player_inventory(emp_granate)), assertz(player_inventory(emp_granate)),
assertz(player_inventory(parkour_handschuhe)), assertz(player_inventory(parkour_handschuhe)),
@ -318,12 +328,21 @@ process_command([cheat, items]) :-
assertz(player_inventory(heilspray)), assertz(player_inventory(heilspray)),
write('Alle Items erhalten!'), nl. write('Alle Items erhalten!'), nl.
process_command([cheat, components]) :- process_command([cheat, teleport, LOC]) :-
assertz(player_inventory(coil)), retract(player_location(_)),
assertz(player_inventory(battery)), assertz(player_location(LOC)).
assertz(player_inventory(capacitor)),
process_command([cheat, generator_components]) :-
assertz(player_inventory(spule)),
assertz(player_inventory(batterie)),
assertz(player_inventory(kondensator)),
write('EMP-Generator Komponenten erhalten!'), nl. 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(_) :- process_command(_) :-
write('Unbekannter Befehl. Verwende "hilfe" für eine Liste der Befehle.'), nl. write('Unbekannter Befehl. Verwende "hilfe" für eine Liste der Befehle.'), nl.
@ -335,11 +354,8 @@ process_combat_command([angriff], Enemy) :-
process_combat_command([verwende, Item], Enemy) :- process_combat_command([verwende, Item], Enemy) :-
combat_use_item(Item, Enemy). combat_use_item(Item, Enemy).
process_combat_command([flucht], Enemy) :-
combat_flee(Enemy).
process_combat_command(_, _) :- process_combat_command(_, _) :-
write('Ungültige Kampfaktion! Verwende: angriff, verwende(item), oder flucht'), nl. write('Ungültige Kampfaktion! Verwende: angriff oder verwende(item)'), nl.
% ========== CORE GAME MECHANICS ========== % ========== CORE GAME MECHANICS ==========
look_around :- look_around :-
@ -385,8 +401,8 @@ list_obstacles([obstacle(_, Exit, ObstacleType)|T]) :-
describe_obstacle(hohe_mauer) :- describe_obstacle(hohe_mauer) :-
write('Hohe Mauer - benötigt Parkour-Handschuhe zum Klettern'). write('Hohe Mauer - benötigt Parkour-Handschuhe zum Klettern').
describe_obstacle(electric_fence) :- describe_obstacle(drone_swarm) :-
write('Elektrischer Zaun - benötigt EMP-Granate'). write('Drohnen-Schwarm - benötigt Kampfdrohne zur Abwehr').
describe_obstacle(security_system) :- describe_obstacle(security_system) :-
write('Hochsicherheitssystem - benötigt EMP-Generator'). write('Hochsicherheitssystem - benötigt EMP-Generator').
@ -422,16 +438,16 @@ handle_obstacle(hohe_mauer, Direction) :-
write('Du gehst nach '), write(Direction), nl) ; write('Du gehst nach '), write(Direction), nl) ;
write('Eine hohe Mauer blockiert deinen Weg! Du brauchst Parkour-Handschuhe.'), nl). write('Eine hohe Mauer blockiert deinen Weg! Du brauchst Parkour-Handschuhe.'), nl).
handle_obstacle(electric_fence, Direction) :- handle_obstacle(drone_swarm, Direction) :-
(player_inventory(emp_granate) -> (player_inventory(kampfdrohne) ->
(write('Du wirfst eine EMP-Granate! Der elektrische Zaun fällt aus!'), nl, (write('Deine Kampfdrohne bekämpft den feindlichen Schwarm!'), nl,
retract(player_inventory(emp_granate)), write('Die Drohnen werden zerstört und der Weg ist frei!'), nl,
player_location(CurrentLoc), player_location(CurrentLoc),
retract(obstacle(CurrentLoc, Direction, electric_fence)), retract(obstacle(CurrentLoc, Direction, drone_swarm)),
retract(player_location(CurrentLoc)), retract(player_location(CurrentLoc)),
assertz(player_location(Direction)), assertz(player_location(Direction)),
write('Du gehst nach '), write(Direction), nl) ; write('Du gehst nach '), write(Direction), nl) ;
write('Ein elektrischer Zaun blockiert den Weg! Du brauchst eine EMP-Granate.'), nl). write('Ein Schwarm aggressiver Drohnen blockiert den Weg! Du brauchst eine Kampfdrohne.'), nl).
handle_obstacle(security_system, Direction) :- handle_obstacle(security_system, Direction) :-
(player_inventory(emp_generator) -> (player_inventory(emp_generator) ->
@ -478,11 +494,8 @@ list_inventory_items([H|T]) :-
% ========== ITEM USAGE ========== % ========== ITEM USAGE ==========
execute_item_use(laptop) :- execute_item_use(laptop) :-
player_location(htl_labor), player_location(htl_labor),
game_state(chapter, 1),
write('Du hackst dich in die Schulserver ein und analysierst die Drohnen-Aufnahmen.'), nl, write('Du hackst dich in die Schulserver ein und analysierst die Drohnen-Aufnahmen.'), nl,
write('SCHOCKIERENDE ENTDECKUNG: Die Vögel sind Überwachungsdrohnen!'), nl, write('SCHOCKIERENDE ENTDECKUNG: Die Vögel sind Überwachungsdrohnen!'), nl,
retract(game_state(chapter, 1)),
assertz(game_state(chapter, 2)),
!. !.
execute_item_use(heilspray) :- execute_item_use(heilspray) :-
@ -527,14 +540,19 @@ combat_attack(Enemy) :-
combat_use_item(ItemName, Enemy) :- combat_use_item(ItemName, Enemy) :-
player_inventory(ItemName), player_inventory(ItemName),
execute_combat_item_use(ItemName, Enemy), execute_combat_item_use(ItemName, Enemy),
enemy_turn(Enemy),
!. !.
combat_use_item(_, _) :- combat_use_item(_, _) :-
write('Du hast diesen Gegenstand nicht!'), nl. write('Du hast diesen Gegenstand nicht!'), nl.
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) :- execute_combat_item_use(emp_granate, Enemy) :-
enemy(Enemy, DisplayName, Health, Desc), enemy(Enemy, DisplayName, Health, Desc),
assertz(emp_used_in_combat(Enemy)),
(Enemy = die_kraehe -> (Enemy = die_kraehe ->
(write('Du schwächst die Krähe mit der EMP-Granate!'), nl, (write('Du schwächst die Krähe mit der EMP-Granate!'), nl,
retract(game_state(crow_weakened, false)), retract(game_state(crow_weakened, false)),
@ -548,7 +566,8 @@ execute_combat_item_use(emp_granate, Enemy) :-
(NewHealth =< 0 -> (NewHealth =< 0 ->
(write(DisplayName), write(' wurde besiegt!'), nl, (write(DisplayName), write(' wurde besiegt!'), nl,
defeat_enemy(Enemy)) ; defeat_enemy(Enemy)) ;
assertz(enemy(Enemy, DisplayName, NewHealth, Desc))))). (assertz(enemy(Enemy, DisplayName, NewHealth, Desc)),
enemy_turn(Enemy))))).
execute_combat_item_use(kampfdrohne, Enemy) :- execute_combat_item_use(kampfdrohne, Enemy) :-
enemy(Enemy, DisplayName, Health, Desc), enemy(Enemy, DisplayName, Health, Desc),
@ -559,17 +578,19 @@ execute_combat_item_use(kampfdrohne, Enemy) :-
(NewHealth =< 0 -> (NewHealth =< 0 ->
(write(DisplayName), write(' wurde besiegt!'), nl, (write(DisplayName), write(' wurde besiegt!'), nl,
defeat_enemy(Enemy)) ; defeat_enemy(Enemy)) ;
assertz(enemy(Enemy, DisplayName, NewHealth, Desc))). assertz(enemy(Enemy, DisplayName, NewHealth, Desc)),
enemy_turn(Enemy)).
execute_combat_item_use(heilspray, _) :- execute_combat_item_use(heilspray, _) :-
execute_item_use(heilspray). execute_item_use(heilspray).
combat_flee(Enemy) :- execute_combat_item_use(Item, _) :-
write('Du fliehst aus dem Kampf!'), nl, \+ member(Item, [emp_granate, kampfdrohne, heilspray]),
retract(in_combat(Enemy)), item(Item, DisplayName, _),
% Teleport to a safe location write(DisplayName), write(' kann nicht im Kampf verwendet werden!'), nl.
retract(player_location(_)),
assertz(player_location(htl_labor)). execute_combat_item_use(Item, _) :-
write(Item), write(' kann nicht im Kampf verwendet werden!'), nl.
enemy_turn(Enemy) :- enemy_turn(Enemy) :-
enemy(Enemy, DisplayName, _, _), enemy(Enemy, DisplayName, _, _),
@ -579,38 +600,22 @@ enemy_turn(Enemy) :-
normal_enemy_attack(_, DisplayName) :- normal_enemy_attack(_, DisplayName) :-
get_random_enemy_damage(Damage), get_random_enemy_damage(Damage),
player_health(Health), damage_player(Damage),
NewHealth is Health - Damage,
write(DisplayName), write(' greift an und verursacht '), write(DisplayName), write(' greift an und verursacht '),
write(Damage), write(' Schaden!'), nl, write(Damage), write(' Schaden!'), nl.
retract(player_health(Health)),
assertz(player_health(NewHealth)).
crow_mind_control :- crow_mind_control :-
write('Die Krähe übernimmt die Kontrolle über deinen Verstand!'), nl, write('Die Krähe übernimmt die Kontrolle über deinen Verstand!'), nl,
write('Du schlägst dich selbst!'), nl, write('Du schlägst dich selbst!'), nl,
player_health(Health), damage_player(20),
Damage = 20, write('Du verursachst dir '), write(20), write(' Schaden!'), nl.
NewHealth is Health - Damage,
write('Du verursachst dir '), write(Damage), write(' Schaden!'), nl,
retract(player_health(Health)),
assertz(player_health(NewHealth)).
check_combat_state(Enemy) :-
player_health(Health),
(Health =< 0 ->
end_game(defeat) ;
(enemy(Enemy, _, EnemyHealth, _) ->
(EnemyHealth =< 0 ->
true ; % Enemy defeated, handled in combat_attack
true) ;
% Enemy was defeated
retract(in_combat(Enemy)))).
defeat_enemy(EnemyName) :- defeat_enemy(EnemyName) :-
retract(enemy_location(EnemyName, _)), retract(enemy_location(EnemyName, _)),
retract(in_combat(EnemyName)), retract(in_combat(EnemyName)),
handle_enemy_defeat(EnemyName). handle_enemy_defeat(EnemyName),
retractall(emp_used_in_combat(EnemyName)),
nl.
handle_enemy_defeat(tauben_schwarm) :- handle_enemy_defeat(tauben_schwarm) :-
write('Die Tauben explodieren! Du findest ein Heilspray und einen Drohnen-Motor in den Trümmern.'), nl, write('Die Tauben explodieren! Du findest ein Heilspray und einen Drohnen-Motor in den Trümmern.'), nl,
@ -635,21 +640,21 @@ handle_enemy_defeat(die_kraehe) :-
% ========== CRAFTING SYSTEM ========== % ========== CRAFTING SYSTEM ==========
craft_item(emp_generator) :- craft_item(emp_generator) :-
player_location(htl_leonding), player_location(htl_werkstatt),
player_inventory(coil), player_inventory(spule),
player_inventory(battery), player_inventory(batterie),
player_inventory(capacitor), player_inventory(kondensator),
write('Du baust aus Spule, Batterie und Kondensator einen EMP-Generator!'), nl, write('Du baust aus Spule, Batterie und Kondensator einen EMP-Generator!'), nl,
retract(player_inventory(coil)), retract(player_inventory(spule)),
retract(player_inventory(battery)), retract(player_inventory(batterie)),
retract(player_inventory(capacitor)), retract(player_inventory(kondensator)),
assertz(player_inventory(emp_generator)), assertz(player_inventory(emp_generator)),
retract(game_state(emp_built, false)), retract(game_state(emp_built, false)),
assertz(game_state(emp_built, true)), assertz(game_state(emp_built, true)),
!. !.
craft_item(emp_generator) :- craft_item(emp_generator) :-
player_location(htl_leonding), player_location(htl_werkstatt),
write('Du brauchst: Elektro-Spule, Hochleistungsbatterie und Kondensator.'), nl, write('Du brauchst: Elektro-Spule, Hochleistungsbatterie und Kondensator.'), nl,
!. !.
@ -658,7 +663,7 @@ craft_item(emp_generator) :-
!. !.
craft_item(kampfdrohne) :- craft_item(kampfdrohne) :-
player_location(htl_leonding), player_location(htl_werkstatt),
player_inventory(drohnen_motor), player_inventory(drohnen_motor),
player_inventory(steuerungsmodul), player_inventory(steuerungsmodul),
write('Du baust aus Motor und Steuerungsmodul eine Kampfdrohne!'), nl, write('Du baust aus Motor und Steuerungsmodul eine Kampfdrohne!'), nl,
@ -668,7 +673,7 @@ craft_item(kampfdrohne) :-
!. !.
craft_item(kampfdrohne) :- craft_item(kampfdrohne) :-
player_location(htl_leonding), player_location(htl_werkstatt),
write('Du brauchst: Drohnen-Motor und Steuerungsmodul um eine Kampfdrohne zu bauen.'), nl, write('Du brauchst: Drohnen-Motor und Steuerungsmodul um eine Kampfdrohne zu bauen.'), nl,
!. !.
@ -701,7 +706,7 @@ hacking_minigame(altstadt) :-
read(Answer), read(Answer),
(Answer = 1111 -> (Answer = 1111 ->
(write('Korrekt! Du findest eine Elektro-Spule in der Box!'), nl, (write('Korrekt! Du findest eine Elektro-Spule in der Box!'), nl,
assertz(player_inventory(coil)), assertz(player_inventory(spule)),
assertz(box_unlocked(altstadt_box))) ; assertz(box_unlocked(altstadt_box))) ;
(write('Falsch! Versuch es nochmal.'), nl, (write('Falsch! Versuch es nochmal.'), nl,
fail)). fail)).
@ -721,7 +726,7 @@ hacking_minigame(donauufer) :-
read(Answer), read(Answer),
(Answer = 2 -> (Answer = 2 ->
(write('Korrekt! Du findest eine Hochleistungsbatterie in der Box!'), nl, (write('Korrekt! Du findest eine Hochleistungsbatterie in der Box!'), nl,
assertz(player_inventory(battery)), assertz(player_inventory(batterie)),
assertz(box_unlocked(donauufer_box))) ; assertz(box_unlocked(donauufer_box))) ;
(write('Falsch! Versuch es nochmal.'), nl, (write('Falsch! Versuch es nochmal.'), nl,
fail)). fail)).
@ -743,7 +748,7 @@ hacking_minigame(poestlingberg) :-
read(Answer), read(Answer),
(Answer = 2 -> (Answer = 2 ->
(write('Korrekt! Du findest einen Kondensator in der Box!'), nl, (write('Korrekt! Du findest einen Kondensator in der Box!'), nl,
assertz(player_inventory(capacitor)), assertz(player_inventory(kondensator)),
assertz(box_unlocked(poestlingberg_box))) ; assertz(box_unlocked(poestlingberg_box))) ;
(write('Falsch! Versuch es nochmal.'), nl, (write('Falsch! Versuch es nochmal.'), nl,
fail)). fail)).
@ -758,9 +763,9 @@ hacking_minigame(_) :-
climb_action :- climb_action :-
player_location(altstadt), player_location(altstadt),
player_inventory(parkour_handschuhe), player_inventory(parkour_handschuhe),
write('Du kletterst mit den Parkour-Handschuhen auf das Dach!'), nl, write('=== PARKOUR KLETTERN ==='), nl,
write('Du findest eine verschlossene Box auf dem Dach.'), nl, write('Du beginnst den Aufstieg...'), nl,
write('Verwende "hack(box)" um sie zu öffnen.'), nl, parkour_minigame_altstadt,
!. !.
climb_action :- climb_action :-
@ -771,7 +776,60 @@ climb_action :-
climb_action :- climb_action :-
player_location(donauufer), player_location(donauufer),
player_inventory(parkour_handschuhe), player_inventory(parkour_handschuhe),
write('Du kletterst auf den Turm!'), nl, 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-Migigames
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('Oben ist ein elektrisches Schutzschild um eine Box.'), nl,
write('Du brauchst eine EMP-Granate um das Schild zu deaktivieren.'), nl, write('Du brauchst eine EMP-Granate um das Schild zu deaktivieren.'), nl,
(player_inventory(emp_granate) -> (player_inventory(emp_granate) ->
@ -781,13 +839,55 @@ climb_action :-
true), true),
!. !.
climb_action :- balance_challenge(0, Success) :-
player_location(donauufer), Success < 4,
write('Du brauchst Parkour-Handschuhe um auf den Turm zu klettern.'), nl, write('Du verlierst das Gleichgewicht und fällst! 15 Schaden!'), nl,
damage_player(15),
!. !.
climb_action :- balance_challenge(Remaining, Success) :-
write('Hier gibt es nichts zum Klettern.'), nl. 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))).
% ========== NPC INTERACTIONS ========== % ========== NPC INTERACTIONS ==========
talk_to(PersonName) :- talk_to(PersonName) :-
@ -816,8 +916,6 @@ handle_conversation(wren) :-
assertz(player_inventory(emp_granate)), assertz(player_inventory(emp_granate)),
retract(game_state(wren_met, false)), retract(game_state(wren_met, false)),
assertz(game_state(wren_met, true)), assertz(game_state(wren_met, true)),
retract(game_state(chapter, 2)),
assertz(game_state(chapter, 3)),
retract(game_state(components_explained, false)), retract(game_state(components_explained, false)),
assertz(game_state(components_explained, true)), assertz(game_state(components_explained, true)),
!. !.
@ -860,10 +958,8 @@ check_game_state :-
show_status :- show_status :-
player_health(Health), player_health(Health),
game_state(chapter, Chapter),
write('=== STATUS ==='), nl, write('=== STATUS ==='), nl,
write('Gesundheit: '), write(Health), nl, write('Gesundheit: '), write(Health), nl,
write('Kapitel: '), write(Chapter), nl,
(player_inventory(kampfdrohne) -> (player_inventory(kampfdrohne) ->
write('Kampfdrohne: ✓ Gebaut'), nl ; write('Kampfdrohne: ✓ Gebaut'), nl ;
(write('Kampfdrohne Komponenten:'), nl, (write('Kampfdrohne Komponenten:'), nl,
@ -872,9 +968,9 @@ show_status :-
(game_state(emp_built, true) -> (game_state(emp_built, true) ->
write('EMP-Generator: ✓ Gebaut'), nl ; write('EMP-Generator: ✓ Gebaut'), nl ;
(write('EMP-Generator Komponenten:'), nl, (write('EMP-Generator Komponenten:'), nl,
(player_inventory(coil) -> write(' Elektro-Spule: ✓') ; write(' Elektro-Spule: ✗')), nl, (player_inventory(spule) -> write(' Elektro-Spule: ✓') ; write(' Elektro-Spule: ✗')), nl,
(player_inventory(battery) -> write(' Batterie: ✓') ; write(' Batterie: ✗')), nl, (player_inventory(batterie) -> write(' Batterie: ✓') ; write(' Batterie: ✗')), nl,
(player_inventory(capacitor) -> write(' Kondensator: ✓') ; write(' Kondensator: ✗')), nl)), (player_inventory(kondensator) -> write(' Kondensator: ✓') ; write(' Kondensator: ✗')), nl)),
write('=============='), nl. write('=============='), nl.
% ========== GAME ENDINGS ========== % ========== GAME ENDINGS ==========
@ -905,7 +1001,7 @@ handle_final_choice(2) :-
end_game(dark_ruler). end_game(dark_ruler).
handle_final_choice(3) :- handle_final_choice(3) :-
player_inventory(master_key), player_inventory(master_schluessel),
write('Du verwendest den Master-Schlüssel für vollständigen Systemzugriff...'), nl, write('Du verwendest den Master-Schlüssel für vollständigen Systemzugriff...'), nl,
write('Mit diesem legendären Artefakt hackst du dich mühelos durch alle Sicherheitsebenen!'), nl, write('Mit diesem legendären Artefakt hackst du dich mühelos durch alle Sicherheitsebenen!'), nl,
write('Du übernimmst nicht nur die Kontrolle - du wirst zum Meister des Systems!'), nl, write('Du übernimmst nicht nur die Kontrolle - du wirst zum Meister des Systems!'), nl,
@ -926,6 +1022,7 @@ handle_final_choice(_) :-
final_choice. final_choice.
end_game(heroic_sacrifice) :- end_game(heroic_sacrifice) :-
clear_screen,
write('=== HEROISCHES OPFER ==='), nl, write('=== HEROISCHES OPFER ==='), nl,
write('BOOOOOOM!'), nl, write('BOOOOOOM!'), nl,
write('Das Aviary HQ explodiert in einem blendenden Lichtblitz!'), nl, write('Das Aviary HQ explodiert in einem blendenden Lichtblitz!'), nl,
@ -937,6 +1034,7 @@ end_game(heroic_sacrifice) :-
halt. halt.
end_game(dark_ruler) :- end_game(dark_ruler) :-
clear_screen,
write('=== DUNKLER HERRSCHER ==='), nl, write('=== DUNKLER HERRSCHER ==='), nl,
write('Die Drohnen schwärmen aus und überwachen jeden Winkel der Erde.'), nl, write('Die Drohnen schwärmen aus und überwachen jeden Winkel der Erde.'), nl,
write('Unter deiner Kontrolle gibt es keine Verbrechen, keine Unordnung...'), nl, write('Unter deiner Kontrolle gibt es keine Verbrechen, keine Unordnung...'), nl,
@ -947,6 +1045,7 @@ end_game(dark_ruler) :-
halt. halt.
end_game(master_hacker_victory) :- end_game(master_hacker_victory) :-
clear_screen,
write('=== MEISTER-HACKER TRIUMPH ==='), nl, write('=== MEISTER-HACKER TRIUMPH ==='), nl,
write('Mit dem Master-Schlüssel hast du göttliche Kontrolle über das Netzwerk erlangt!'), nl, write('Mit dem Master-Schlüssel hast du göttliche Kontrolle über das Netzwerk erlangt!'), nl,
write('Du transformierst das gesamte System in einen Beschützer der Menschheit.'), nl, write('Du transformierst das gesamte System in einen Beschützer der Menschheit.'), nl,
@ -958,6 +1057,7 @@ end_game(master_hacker_victory) :-
halt. halt.
end_game(hack_failure) :- end_game(hack_failure) :-
clear_screen,
write('=== HACK FEHLGESCHLAGEN ==='), nl, write('=== HACK FEHLGESCHLAGEN ==='), nl,
write('Deine Hacking-Versuche wurden entdeckt!'), nl, write('Deine Hacking-Versuche wurden entdeckt!'), nl,
write('Sicherheitsdrohnen umzingeln dich!'), nl, write('Sicherheitsdrohnen umzingeln dich!'), nl,
@ -967,6 +1067,7 @@ end_game(hack_failure) :-
write('Möchtest du es nochmal versuchen? Tippe "start_game." um neu zu beginnen.'), nl. write('Möchtest du es nochmal versuchen? Tippe "start_game." um neu zu beginnen.'), nl.
end_game(defeat) :- end_game(defeat) :-
clear_screen,
write('=== NIEDERLAGE ==='), nl, write('=== NIEDERLAGE ==='), nl,
write('Du wurdest von den Drohnen überwältigt.'), nl, write('Du wurdest von den Drohnen überwältigt.'), nl,
write('Die Wahrheit bleibt für immer begraben...'), nl, write('Die Wahrheit bleibt für immer begraben...'), nl,
@ -980,6 +1081,33 @@ get_random_damage(Damage) :-
get_random_enemy_damage(Damage) :- get_random_enemy_damage(Damage) :-
random(8, 16, Damage). % Random enemy damage between 8-15 random(8, 16, Damage). % Random enemy damage between 8-15
damage_player(Damage) :-
player_health(Health),
NewHealth is Health - Damage,
retract(player_health(Health)),
assertz(player_health(NewHealth)).
random_member(Element, List) :-
length(List, Length),
Length > 0,
random(0, Length, RandomIndex),
nth0(RandomIndex, List, Element).
write_sequence([]).
write_sequence([H|T]) :-
write(H),
(T = [] -> true ; write(' -> ')),
write_sequence(T).
read_sequence(Sequence) :-
read(Input),
(is_list(Input) ->
Sequence = Input ;
Sequence = [Input]).
clear_screen :-
catch(shell('clear'), _, (catch(shell('cls'), _, fail))).
% ========== HELP PREDICATES ========== % ========== HELP PREDICATES ==========
hilfe :- process_command([hilfe]). hilfe :- process_command([hilfe]).
schaue :- process_command([schaue]). schaue :- process_command([schaue]).