├── src └── main │ └── java │ └── me │ └── adversing │ └── engine │ ├── obj │ ├── entities │ │ ├── gameobject │ │ │ ├── properties │ │ │ │ ├── Ingestible.java │ │ │ │ └── Interactable.java │ │ │ ├── type │ │ │ │ └── ObjectType.java │ │ │ ├── GameObject.java │ │ │ └── info │ │ │ │ └── ObjectInformation.java │ │ └── character │ │ │ ├── status │ │ │ └── CharacterStatus.java │ │ │ ├── relationships │ │ │ ├── Feeling.java │ │ │ └── RelationShipStatus.java │ │ │ ├── inv │ │ │ └── Inventory.java │ │ │ ├── info │ │ │ └── CharacterInformation.java │ │ │ └── Character.java │ ├── map │ │ ├── properties │ │ │ └── Accessible.java │ │ ├── GameMap.java │ │ ├── location │ │ │ ├── Location.java │ │ │ └── info │ │ │ │ └── LocationInformation.java │ │ ├── info │ │ │ └── GameMapInformation.java │ │ └── area │ │ │ ├── info │ │ │ └── GameAreaInformation.java │ │ │ └── GameArea.java │ └── items │ │ └── Item.java │ ├── utils │ └── time │ │ └── countdown │ │ ├── action │ │ └── CountdownAction.java │ │ └── Countdown.java │ ├── core │ ├── AudaxEngine.java │ └── handlers │ │ └── StoryHandler.java │ ├── logic │ ├── info │ │ └── ChoiceInformation.java │ └── Choice.java │ ├── story │ ├── structure │ │ ├── chapter │ │ │ ├── info │ │ │ │ └── ChapterInformation.java │ │ │ └── Chapter.java │ │ └── episode │ │ │ ├── info │ │ │ └── EpisodeInformation.java │ │ │ └── Episode.java │ ├── info │ │ └── StoryInformation.java │ └── Story.java │ └── dialogue │ ├── Dialogue.java │ ├── info │ └── DialogueInformation.java │ └── section │ ├── DialogueSection.java │ └── info │ └── DialogueSectionInformation.java └── README.md /src/main/java/me/adversing/engine/obj/entities/gameobject/properties/Ingestible.java: -------------------------------------------------------------------------------- 1 | package me.adversing.engine.obj.entities.gameobject.properties; 2 | 3 | /** 4 | * This interface represents an ingestible object. 5 | */ 6 | public interface Ingestible { 7 | void onIngest(); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/me/adversing/engine/obj/entities/character/status/CharacterStatus.java: -------------------------------------------------------------------------------- 1 | package me.adversing.engine.obj.entities.character.status; 2 | 3 | /** 4 | * This enum represents the status of a character. 5 | */ 6 | public enum CharacterStatus { 7 | ALIVE, 8 | HURT, 9 | DEAD; 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/me/adversing/engine/utils/time/countdown/action/CountdownAction.java: -------------------------------------------------------------------------------- 1 | package me.adversing.engine.utils.time.countdown.action; 2 | 3 | /** 4 | * This interface represents a countdown action. 5 | */ 6 | public interface CountdownAction { 7 | /** 8 | * Executes the action. 9 | */ 10 | void execute(); 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/me/adversing/engine/obj/map/properties/Accessible.java: -------------------------------------------------------------------------------- 1 | package me.adversing.engine.obj.map.properties; 2 | 3 | /** 4 | * This interface represents an accessible location. You can implement this interface to create your own accessible locations. 5 | */ 6 | public interface Accessible { 7 | void onEnter(); 8 | void onExit(); 9 | } 10 | -------------------------------------------------------------------------------- /src/main/java/me/adversing/engine/obj/entities/gameobject/type/ObjectType.java: -------------------------------------------------------------------------------- 1 | package me.adversing.engine.obj.entities.gameobject.type; 2 | 3 | public enum ObjectType { 4 | LIVING_ENTITY, 5 | ITEM, 6 | WEAPON, 7 | ARMOR, 8 | PROJECTILE, 9 | CONSUMABLE, 10 | CONTAINER, 11 | FURNITURE, 12 | DOOR, 13 | KEY, 14 | LOCK, 15 | TRAP, 16 | TRIGGER, 17 | SPELL, 18 | EFFECT 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/me/adversing/engine/obj/entities/gameobject/properties/Interactable.java: -------------------------------------------------------------------------------- 1 | package me.adversing.engine.obj.entities.gameobject.properties; 2 | 3 | import me.adversing.engine.obj.entities.character.Character; 4 | import me.adversing.engine.obj.entities.gameobject.GameObject; 5 | 6 | /** 7 | * This interface represents an interactable object. You can implement this interface to create your own interactable objects or characters. 8 | */ 9 | public interface Interactable { 10 | void onInteract(Character character); 11 | void onInteract(GameObject gameObject); 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/me/adversing/engine/core/AudaxEngine.java: -------------------------------------------------------------------------------- 1 | package me.adversing.engine.core; 2 | 3 | import lombok.Getter; 4 | import me.adversing.engine.core.handlers.StoryHandler; 5 | 6 | /** 7 | * This class represents the Audax Engine Main class. 8 | */ 9 | public class AudaxEngine { 10 | @Getter private static AudaxEngine instance; 11 | @Getter private final StoryHandler storyHandler; 12 | 13 | /** 14 | * Creates a new Audax Engine instance. 15 | */ 16 | public AudaxEngine() { 17 | instance = this; 18 | storyHandler = new StoryHandler(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/me/adversing/engine/logic/info/ChoiceInformation.java: -------------------------------------------------------------------------------- 1 | package me.adversing.engine.logic.info; 2 | 3 | import lombok.Getter; 4 | import lombok.NonNull; 5 | import lombok.Setter; 6 | 7 | import java.util.StringJoiner; 8 | 9 | /** 10 | * This class represents the information of a choice. 11 | */ 12 | @Getter 13 | @Setter 14 | public class ChoiceInformation { 15 | private String choiceId; 16 | 17 | /** 18 | * Creates a new choice information. 19 | * 20 | * @param choiceId The choice id. 21 | */ 22 | public ChoiceInformation(@NonNull String choiceId) { 23 | this.choiceId = choiceId; 24 | } 25 | 26 | @Override 27 | public String toString() { 28 | return new StringJoiner(", ", ChoiceInformation.class.getSimpleName() + "[", "]") 29 | .add("choiceId='" + choiceId + "'") 30 | .toString(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/me/adversing/engine/obj/entities/character/relationships/Feeling.java: -------------------------------------------------------------------------------- 1 | package me.adversing.engine.obj.entities.character.relationships; 2 | 3 | /** 4 | * This enum represents the feeling of a character. 5 | */ 6 | public enum Feeling { 7 | 8 | // positive 9 | CURIOSITY, 10 | EMPATHY, 11 | EXCITEMENT, 12 | HOPE, 13 | HAPPINESS, 14 | LOYALTY, 15 | LOVE, 16 | RELIEF, 17 | SATISFACTION, 18 | SURPRISE_POS, 19 | TRUST, // in case someone takes a trust breaking decision, you need to increase betrayal rather than decrease trust 20 | 21 | 22 | // neutral 23 | BOREDOM, 24 | CONFUSION, 25 | RESPECT, 26 | 27 | // negative 28 | ANXIETY, 29 | ANGER, 30 | BETRAYAL, 31 | DISGUST, 32 | ENVY, 33 | FEAR, 34 | GUILT, 35 | HATRED, 36 | JEALOUSY, 37 | LONELINESS, 38 | PRIDE, 39 | REGRET, 40 | SADNESS, 41 | SHAME, 42 | SURPRISE_NEG; 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/me/adversing/engine/obj/map/GameMap.java: -------------------------------------------------------------------------------- 1 | package me.adversing.engine.obj.map; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import me.adversing.engine.obj.map.info.GameMapInformation; 6 | 7 | import java.util.StringJoiner; 8 | 9 | /** 10 | * This class represents a game map. You can extend this class to create your own game maps. You can also implement the {@link me.adversing.engine.obj.map.properties.Accessible} interface to create your own accessible locations. 11 | */ 12 | @Getter 13 | @Setter 14 | public abstract class GameMap { 15 | private GameMapInformation information; 16 | 17 | public GameMap(GameMapInformation information) { 18 | this.information = information; 19 | } 20 | 21 | @Override 22 | public String toString() { 23 | return new StringJoiner(", ", GameMap.class.getSimpleName() + "[", "]") 24 | .add("information=" + information) 25 | .toString(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/me/adversing/engine/story/structure/chapter/info/ChapterInformation.java: -------------------------------------------------------------------------------- 1 | package me.adversing.engine.story.structure.chapter.info; 2 | 3 | import lombok.Getter; 4 | import lombok.NonNull; 5 | import lombok.Setter; 6 | 7 | import java.util.StringJoiner; 8 | 9 | @Getter 10 | @Setter 11 | public class ChapterInformation { 12 | private String id; 13 | private String title; 14 | private String description; 15 | 16 | public ChapterInformation(@NonNull String id, @NonNull String title, @NonNull String description) { 17 | this.id = id; 18 | this.title = title; 19 | this.description = description; 20 | } 21 | 22 | @Override 23 | public String toString() { 24 | return new StringJoiner(", ", ChapterInformation.class.getSimpleName() + "[", "]") 25 | .add("id='" + id + "'") 26 | .add("title='" + title + "'") 27 | .add("description='" + description + "'") 28 | .toString(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/me/adversing/engine/story/structure/episode/info/EpisodeInformation.java: -------------------------------------------------------------------------------- 1 | package me.adversing.engine.story.structure.episode.info; 2 | 3 | import lombok.Getter; 4 | import lombok.NonNull; 5 | import lombok.Setter; 6 | 7 | import java.util.StringJoiner; 8 | 9 | @Getter 10 | @Setter 11 | public class EpisodeInformation { 12 | private String id; 13 | private String title; 14 | private String description; 15 | 16 | public EpisodeInformation(@NonNull String id,@NonNull String title, @NonNull String description) { 17 | this.id = id; 18 | this.title = title; 19 | this.description = description; 20 | } 21 | 22 | @Override 23 | public String toString() { 24 | return new StringJoiner(", ", EpisodeInformation.class.getSimpleName() + "[", "]") 25 | .add("id='" + id + "'") 26 | .add("title='" + title + "'") 27 | .add("description='" + description + "'") 28 | .toString(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/me/adversing/engine/story/structure/episode/Episode.java: -------------------------------------------------------------------------------- 1 | package me.adversing.engine.story.structure.episode; 2 | 3 | import lombok.Getter; 4 | import lombok.NonNull; 5 | import lombok.Setter; 6 | import me.adversing.engine.dialogue.Dialogue; 7 | import me.adversing.engine.story.structure.episode.info.EpisodeInformation; 8 | 9 | import java.util.List; 10 | import java.util.StringJoiner; 11 | 12 | @Getter 13 | @Setter 14 | public abstract class Episode { 15 | private EpisodeInformation information; 16 | private List dialogues; 17 | private boolean isCompleted; 18 | 19 | public Episode(@NonNull EpisodeInformation information, @NonNull List dialogues) { 20 | this.information = information; 21 | this.dialogues = dialogues; 22 | } 23 | 24 | public abstract void onStart(); 25 | 26 | public abstract void onEnd(); 27 | 28 | @Override 29 | public String toString() { 30 | return new StringJoiner(", ", Episode.class.getSimpleName() + "[", "]") 31 | .add("information=" + information) 32 | .add("isCompleted=" + isCompleted) 33 | .toString(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/me/adversing/engine/story/structure/chapter/Chapter.java: -------------------------------------------------------------------------------- 1 | package me.adversing.engine.story.structure.chapter; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | import me.adversing.engine.story.structure.chapter.info.ChapterInformation; 6 | import me.adversing.engine.story.structure.episode.Episode; 7 | 8 | import java.util.List; 9 | import java.util.StringJoiner; 10 | 11 | @Getter 12 | @Setter 13 | public abstract class Chapter { 14 | 15 | private ChapterInformation information; 16 | private List episodes; 17 | private boolean isCompleted; 18 | 19 | public Chapter(ChapterInformation information, List episodes) { 20 | this.information = information; 21 | this.episodes = episodes; 22 | } 23 | 24 | public abstract void onStart(); 25 | 26 | public abstract void onEnd(); 27 | 28 | @Override 29 | public String toString() { 30 | return new StringJoiner(", ", Chapter.class.getSimpleName() + "[", "]") 31 | .add("information=" + information) 32 | .add("episodes=" + episodes) 33 | .add("isCompleted=" + isCompleted) 34 | .toString(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/me/adversing/engine/story/info/StoryInformation.java: -------------------------------------------------------------------------------- 1 | package me.adversing.engine.story.info; 2 | 3 | import lombok.Getter; 4 | import lombok.NonNull; 5 | import lombok.Setter; 6 | 7 | import java.util.StringJoiner; 8 | 9 | @Getter 10 | @Setter 11 | public class StoryInformation { 12 | 13 | private String storyId; 14 | private String title; 15 | private String description; 16 | private int chapterAmount; 17 | 18 | public StoryInformation(@NonNull String storyId, @NonNull String title, @NonNull String description, int chapterAmount) { 19 | assert chapterAmount > 0 : "The chapter amount must be greater than 0."; 20 | this.storyId = storyId; 21 | this.title = title; 22 | this.description = description; 23 | this.chapterAmount = chapterAmount; 24 | } 25 | 26 | @Override 27 | public String toString() { 28 | return new StringJoiner(", ", StoryInformation.class.getSimpleName() + "[", "]") 29 | .add("storyId='" + storyId + "'") 30 | .add("title='" + title + "'") 31 | .add("description='" + description + "'") 32 | .add("chapterAmount=" + chapterAmount) 33 | .toString(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/me/adversing/engine/dialogue/Dialogue.java: -------------------------------------------------------------------------------- 1 | package me.adversing.engine.dialogue; 2 | 3 | import lombok.Getter; 4 | import lombok.NonNull; 5 | import lombok.Setter; 6 | import me.adversing.engine.dialogue.info.DialogueInformation; 7 | import me.adversing.engine.dialogue.section.DialogueSection; 8 | import me.adversing.engine.logic.Choice; 9 | import me.adversing.engine.obj.entities.character.Character; 10 | 11 | import java.util.List; 12 | 13 | /** 14 | * This class represents a dialogue. 15 | */ 16 | @Getter 17 | @Setter 18 | public abstract class Dialogue { 19 | 20 | private DialogueInformation information; 21 | private List sections; 22 | 23 | /** 24 | * Creates a new dialogue. 25 | * 26 | * @param information The dialogue information. 27 | * @param sections The dialogue sections. This is a list because there can be multiple sections in a dialogue. 28 | * @see DialogueInformation 29 | * @see DialogueSection 30 | * @see Character 31 | * @see Choice 32 | */ 33 | public Dialogue(@NonNull DialogueInformation information, @NonNull List sections) { 34 | this.information = information; 35 | this.sections = sections; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/me/adversing/engine/obj/entities/character/inv/Inventory.java: -------------------------------------------------------------------------------- 1 | package me.adversing.engine.obj.entities.character.inv; 2 | 3 | import lombok.Getter; 4 | import lombok.NonNull; 5 | import lombok.Setter; 6 | import me.adversing.engine.obj.items.Item; 7 | import me.adversing.engine.obj.map.area.GameArea; 8 | 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | import java.util.StringJoiner; 12 | 13 | /** 14 | * This class represents an inventory. 15 | */ 16 | @Getter 17 | @Setter 18 | public class Inventory extends GameArea { 19 | private int size; 20 | private List items; 21 | 22 | /** 23 | * Creates a new inventory. 24 | * @param size The size of the inventory. 25 | * @param items The items of the inventory. This is a list because there can be multiple items in an inventory. 26 | */ 27 | public Inventory(int size, @NonNull List items) { 28 | super(); 29 | assert size > 0 : "The size of the inventory must be greater than 0."; 30 | this.size = size; 31 | this.items = new ArrayList<>(size); 32 | this.items.addAll(items); 33 | } 34 | 35 | @Override 36 | public String toString() { 37 | return new StringJoiner(", ", Inventory.class.getSimpleName() + "[", "]") 38 | .add("size=" + size) 39 | .add("items=" + items) 40 | .toString(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/me/adversing/engine/obj/map/location/Location.java: -------------------------------------------------------------------------------- 1 | package me.adversing.engine.obj.map.location; 2 | 3 | import lombok.Getter; 4 | import lombok.NonNull; 5 | import lombok.Setter; 6 | import me.adversing.engine.obj.items.Item; 7 | import me.adversing.engine.obj.map.location.info.LocationInformation; 8 | 9 | import java.util.HashMap; 10 | import java.util.List; 11 | import java.util.StringJoiner; 12 | 13 | /** 14 | * This class represents a location. 15 | */ 16 | @Getter 17 | @Setter 18 | public class Location { 19 | 20 | private LocationInformation information; 21 | private List> itemsThatCanUnlockThisLocation; 22 | 23 | /** 24 | * Creates a new location. 25 | * 26 | * @param information The information of the location. 27 | * @param itemsThatCanUnlockThisLocation The items that can unlock this location. If the list is empty, then the location is unlocked. 28 | * @see LocationInformation 29 | */ 30 | public Location(@NonNull LocationInformation information, @NonNull List> itemsThatCanUnlockThisLocation) { 31 | this.information = information; 32 | this.itemsThatCanUnlockThisLocation = itemsThatCanUnlockThisLocation; 33 | } 34 | 35 | @Override 36 | public String toString() { 37 | return new StringJoiner(", ", Location.class.getSimpleName() + "[", "]") 38 | .add("information=" + information) 39 | .add("itemsThatCanUnlockThisLocation=" + itemsThatCanUnlockThisLocation) 40 | .toString(); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/me/adversing/engine/dialogue/info/DialogueInformation.java: -------------------------------------------------------------------------------- 1 | package me.adversing.engine.dialogue.info; 2 | 3 | import lombok.Getter; 4 | import lombok.NonNull; 5 | import lombok.Setter; 6 | import me.adversing.engine.obj.entities.character.Character; 7 | 8 | import java.util.List; 9 | import java.util.StringJoiner; 10 | 11 | /** 12 | * This class represents the information of a dialogue. 13 | */ 14 | @Getter 15 | @Setter 16 | public class DialogueInformation { 17 | private String dialogueId; 18 | private String dialogueDescription; 19 | private List characters; 20 | 21 | /** 22 | * Creates a new dialogue information. 23 | * 24 | * @param dialogueId The dialogue id. 25 | * @param dialogueDescription The dialogue description. 26 | * @param characters The characters in the dialogue. This is a list because there can be multiple characters in a dialogue. 27 | * @see Character 28 | */ 29 | public DialogueInformation(@NonNull String dialogueId, @NonNull String dialogueDescription, @NonNull List characters) { 30 | this.dialogueId = dialogueId; 31 | this.dialogueDescription = dialogueDescription; 32 | this.characters = characters; 33 | } 34 | 35 | @Override 36 | public String toString() { 37 | return new StringJoiner(", ", DialogueInformation.class.getSimpleName() + "[", "]") 38 | .add("dialogueId='" + dialogueId + "'") 39 | .add("dialogueDescription='" + dialogueDescription + "'") 40 | .add("characters=" + characters) 41 | .toString(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/me/adversing/engine/obj/map/info/GameMapInformation.java: -------------------------------------------------------------------------------- 1 | package me.adversing.engine.obj.map.info; 2 | 3 | import lombok.Getter; 4 | import lombok.NonNull; 5 | import lombok.Setter; 6 | import me.adversing.engine.obj.map.area.info.GameAreaInformation; 7 | import me.adversing.engine.obj.map.location.Location; 8 | import me.adversing.engine.obj.map.location.info.LocationInformation; 9 | import me.adversing.engine.obj.map.area.GameArea; 10 | 11 | import java.util.List; 12 | import java.util.StringJoiner; 13 | 14 | /** 15 | * This class represents the information of a game map. 16 | */ 17 | @Getter 18 | @Setter 19 | public class GameMapInformation { 20 | private String id; 21 | private String name; 22 | private String description; 23 | private List locations; 24 | 25 | /** 26 | * Creates a new game map information. 27 | * 28 | * @param name The name of the game map. 29 | * @param description The description of the game map. 30 | * @see Location 31 | * @see LocationInformation 32 | * @see GameArea 33 | * @see GameAreaInformation 34 | */ 35 | public GameMapInformation(@NonNull String id, @NonNull String name, @NonNull String description) { 36 | this.id = id; 37 | this.name = name; 38 | this.description = description; 39 | } 40 | 41 | @Override 42 | public String toString() { 43 | return new StringJoiner(", ", GameMapInformation.class.getSimpleName() + "[", "]") 44 | .add("id='" + id + "'") 45 | .add("name='" + name + "'") 46 | .add("description='" + description + "'") 47 | .add("locations=" + locations) 48 | .toString(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/me/adversing/engine/utils/time/countdown/Countdown.java: -------------------------------------------------------------------------------- 1 | package me.adversing.engine.utils.time.countdown; 2 | 3 | import lombok.NonNull; 4 | import me.adversing.engine.utils.time.countdown.action.CountdownAction; 5 | 6 | import java.util.StringJoiner; 7 | import java.util.Timer; 8 | import java.util.TimerTask; 9 | 10 | /** 11 | * This class represents a countdown. It uses the {@link Timer} class to countdown. It is used in the {@link me.adversing.engine.logic.Choice} class. 12 | */ 13 | public class Countdown { 14 | 15 | private final Timer timer; 16 | private final CountdownAction action; 17 | 18 | /** 19 | * Creates a new countdown. 20 | * 21 | * @param seconds The seconds to countdown. 22 | * @param action The action to execute when the countdown is over. This is an interface because the action can be anything. 23 | */ 24 | public Countdown(int seconds, @NonNull CountdownAction action) { 25 | assert seconds > 0 : "The seconds must be greater than 0."; 26 | this.action = action; 27 | timer = new Timer(); 28 | timer.schedule(new CountdownTask(), seconds * 1000L); 29 | } 30 | 31 | class CountdownTask extends TimerTask { 32 | 33 | @Override 34 | public void run() { 35 | timer.cancel(); 36 | action.execute(); 37 | } 38 | 39 | @Override 40 | public String toString() { 41 | return super.toString(); 42 | } 43 | } 44 | 45 | @Override 46 | public String toString() { 47 | return new StringJoiner(", ", Countdown.class.getSimpleName() + "[", "]") 48 | .add("timer=" + timer) 49 | .add("action=" + action) 50 | .toString(); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/me/adversing/engine/dialogue/section/DialogueSection.java: -------------------------------------------------------------------------------- 1 | package me.adversing.engine.dialogue.section; 2 | 3 | import lombok.Getter; 4 | import lombok.NonNull; 5 | import lombok.Setter; 6 | import me.adversing.engine.dialogue.section.info.DialogueSectionInformation; 7 | import me.adversing.engine.logic.Choice; 8 | import me.adversing.engine.obj.entities.character.Character; 9 | 10 | import java.util.HashMap; 11 | import java.util.List; 12 | import java.util.StringJoiner; 13 | 14 | /** 15 | * This class represents a dialogue section. 16 | */ 17 | @Getter 18 | @Setter 19 | public class DialogueSection { 20 | private DialogueSectionInformation information; 21 | private List choices; 22 | private List> speeches; 23 | 24 | /** 25 | * Creates a new dialogue section. 26 | * 27 | * @param information The dialogue section information. 28 | * @param choices The choices. 29 | * @param speeches The speeches. This is a list because there can be multiple speeches in a dialogue section. 30 | * @see DialogueSectionInformation 31 | * @see Choice 32 | * @see Character 33 | */ 34 | public DialogueSection(@NonNull DialogueSectionInformation information, @NonNull List choices, @NonNull List> speeches) { 35 | this.information = information; 36 | this.choices = choices; 37 | this.speeches = speeches; 38 | } 39 | 40 | @Override 41 | public String toString() { 42 | return new StringJoiner(", ", DialogueSection.class.getSimpleName() + "[", "]") 43 | .add("information=" + information) 44 | .add("choices=" + choices) 45 | .add("speeches=" + speeches) 46 | .toString(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ⚔️ AudaxEngine 2 | 3 | `AudaxEngine` Java game engine that can be used to create interactive dialogue-based games with choices. The API provides a set of classes and methods to manage the game's story, characters, dialogue sections, and choices. 4 | 5 | ## Requirements 6 | 7 | - Java 17 or later 8 | - Basic knowledge of the Java programming language 9 | 10 | ## Code Structure 11 | 12 | The source code is organized into several packages, each containing specific classes for different functionalities of the game engine. Here's an overview of the main packages: 13 | 14 | - `me.adversing.engine.core.handlers`: Contains the `StoryHandler` class to manage game stories. 15 | - `me.adversing.engine.dialogue`: Contains the abstract `Dialogue` class and other related classes to handle game dialogues. 16 | - `me.adversing.engine.dialogue.section`: Contains the `DialogueSection` class and other related classes to manage dialogue sections. 17 | - `me.adversing.engine.logic`: Contains the `Choice` class and other related classes to handle game choices. 18 | - `me.adversing.engine.obj.entities.character`: Contains the abstract `Character` class and other related classes to manage game characters. 19 | - `me.adversing.engine.obj.entities.gameobject`: Contains the `GameObject` class and other related classes to manage game objects. 20 | 21 | ## Using the API 22 | 23 | To create a game using this game engine, you need to follow a few steps: 24 | 25 | 1. Create stories and define dialogue sections. 26 | 2. Create characters and define their information and relationships with other characters. 27 | 3. Create choices and associate them with dialogue sections. 28 | 4. Create game objects, if necessary. 29 | 5. Use the game engine classes to handle the interaction between characters, objects, and the player. 30 | 31 | You may find the documentation [here](https://github.com/Adversing/AudaxEngine/wiki/) (W.I.P). 32 | -------------------------------------------------------------------------------- /src/main/java/me/adversing/engine/obj/map/area/info/GameAreaInformation.java: -------------------------------------------------------------------------------- 1 | package me.adversing.engine.obj.map.area.info; 2 | 3 | import lombok.Getter; 4 | import lombok.NonNull; 5 | import lombok.Setter; 6 | import me.adversing.engine.obj.entities.character.Character; 7 | import me.adversing.engine.obj.entities.gameobject.GameObject; 8 | 9 | import java.util.List; 10 | import java.util.StringJoiner; 11 | 12 | /** 13 | * This class represents the information of a game area. 14 | */ 15 | @Getter 16 | @Setter 17 | public class GameAreaInformation { 18 | private String id; 19 | private String name; 20 | private String description; 21 | private List objects; 22 | private List characters; 23 | 24 | /** 25 | * Creates a new game area information. 26 | * 27 | * @param name The name of the game area. 28 | * @param description The description of the game area. 29 | * @param objects The objects of the game area. 30 | * @param characters The characters of the game area. 31 | */ 32 | public GameAreaInformation(@NonNull String id, @NonNull String name, @NonNull String description, List objects, List characters) { 33 | this.id = id; 34 | this.name = name; 35 | this.description = description; 36 | this.objects = objects; 37 | this.characters = characters; 38 | } 39 | 40 | @Override 41 | public String toString() { 42 | return new StringJoiner(", ", GameAreaInformation.class.getSimpleName() + "[", "]") 43 | .add("id='" + id + "'") 44 | .add("name='" + name + "'") 45 | .add("description='" + description + "'") 46 | .add("objects=" + objects) 47 | .add("characters=" + characters) 48 | .toString(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/me/adversing/engine/dialogue/section/info/DialogueSectionInformation.java: -------------------------------------------------------------------------------- 1 | package me.adversing.engine.dialogue.section.info; 2 | 3 | import lombok.Getter; 4 | import lombok.NonNull; 5 | import lombok.Setter; 6 | import me.adversing.engine.dialogue.section.DialogueSection; 7 | import me.adversing.engine.obj.entities.character.Character; 8 | 9 | import java.util.List; 10 | import java.util.StringJoiner; 11 | 12 | /** 13 | * This class represents the information of a dialogue section. 14 | */ 15 | @Getter 16 | @Setter 17 | public class DialogueSectionInformation { 18 | 19 | private String dialogueSectionId; 20 | private String dialogueSectionDescription; 21 | private List characters; 22 | 23 | /** 24 | * Creates a new dialogue section information. 25 | * 26 | * @param dialogueSectionId The dialogue section id. 27 | * @param dialogueSectionDescription The dialogue section description. 28 | * @param characters The characters in the dialogue section. This is a list because there can be multiple characters in a dialogue section. 29 | * @see Character 30 | * @see DialogueSection 31 | */ 32 | public DialogueSectionInformation(@NonNull String dialogueSectionId, @NonNull String dialogueSectionDescription, @NonNull List characters) { 33 | this.dialogueSectionId = dialogueSectionId; 34 | this.dialogueSectionDescription = dialogueSectionDescription; 35 | this.characters = characters; 36 | } 37 | 38 | @Override 39 | public String toString() { 40 | return new StringJoiner(", ", DialogueSectionInformation.class.getSimpleName() + "[", "]") 41 | .add("dialogueSectionId='" + dialogueSectionId + "'") 42 | .add("dialogueSectionDescription='" + dialogueSectionDescription + "'") 43 | .add("characters=" + characters) 44 | .toString(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/me/adversing/engine/obj/items/Item.java: -------------------------------------------------------------------------------- 1 | package me.adversing.engine.obj.items; 2 | 3 | import lombok.Getter; 4 | import lombok.NonNull; 5 | import lombok.Setter; 6 | import me.adversing.engine.obj.entities.character.Character; 7 | import me.adversing.engine.obj.entities.gameobject.GameObject; 8 | import me.adversing.engine.obj.entities.gameobject.info.ObjectInformation; 9 | 10 | import java.util.StringJoiner; 11 | 12 | /** 13 | * This class represents an item. 14 | */ 15 | public class Item extends GameObject { 16 | 17 | @Getter 18 | @Setter 19 | private int damage; 20 | 21 | /** 22 | * Creates a new item. 23 | * 24 | * @param information The information of the item. 25 | * @param canBeInteractedWith If the item can be interacted with. 26 | * @param owner The owner of the item. 27 | * @param damage The damage of the item. 28 | */ 29 | public Item(@NonNull ObjectInformation information, boolean canBeInteractedWith, Character owner, int damage) { 30 | super(information, canBeInteractedWith, owner); 31 | assert damage >= 0 : "The damage of the item must be greater or equal than 0."; 32 | this.damage = damage; 33 | } 34 | 35 | /** 36 | * Adds the item to the inventory of the character. 37 | * 38 | * @param character The character. 39 | * @see Character 40 | */ 41 | public void addToInventoryOf(Character character) { 42 | if (!character.getInventory().getItems().contains(this)) { 43 | character.getInventory().getItems().add(this); 44 | getInformation().setGameArea(character.getInventory()); 45 | } 46 | } 47 | 48 | @Override 49 | public String toString() { 50 | return new StringJoiner(", ", Item.class.getSimpleName() + "[", "]") 51 | .add("information=" + getInformation()) 52 | .add("damage=" + damage) 53 | .toString(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/me/adversing/engine/obj/map/location/info/LocationInformation.java: -------------------------------------------------------------------------------- 1 | package me.adversing.engine.obj.map.location.info; 2 | 3 | import lombok.Getter; 4 | import lombok.NonNull; 5 | import lombok.Setter; 6 | import me.adversing.engine.obj.entities.character.Character; 7 | import me.adversing.engine.obj.entities.gameobject.GameObject; 8 | import me.adversing.engine.obj.map.area.GameArea; 9 | 10 | import java.util.List; 11 | import java.util.StringJoiner; 12 | 13 | /** 14 | * This class represents the information of a location. 15 | */ 16 | @Getter 17 | @Setter 18 | public class LocationInformation { 19 | private String id; 20 | private String name; 21 | private String description; 22 | private List areas; 23 | private List objects; 24 | private List characters; 25 | 26 | /** 27 | * Creates a new location information. 28 | * 29 | * @param name The name of the location. 30 | * @param description The description of the location. 31 | * @param areas The areas of the location. 32 | * @param objects The objects of the location. 33 | * @param characters The characters of the location. 34 | */ 35 | public LocationInformation(@NonNull String id, @NonNull String name, @NonNull String description, @NonNull List areas, @NonNull List objects, @NonNull List characters) { 36 | this.id = id; 37 | this.name = name; 38 | this.description = description; 39 | this.areas = areas; 40 | this.objects = objects; 41 | this.characters = characters; 42 | } 43 | 44 | @Override 45 | public String toString() { 46 | return new StringJoiner(", ", LocationInformation.class.getSimpleName() + "[", "]") 47 | .add("id='" + id + "'") 48 | .add("name='" + name + "'") 49 | .add("description='" + description + "'") 50 | .add("areas=" + areas) 51 | .add("objects=" + objects) 52 | .add("characters=" + characters) 53 | .toString(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/me/adversing/engine/obj/entities/gameobject/GameObject.java: -------------------------------------------------------------------------------- 1 | package me.adversing.engine.obj.entities.gameobject; 2 | 3 | import lombok.Getter; 4 | import lombok.NonNull; 5 | import lombok.Setter; 6 | import me.adversing.engine.obj.entities.character.Character; 7 | import me.adversing.engine.obj.entities.gameobject.info.ObjectInformation; 8 | import me.adversing.engine.obj.entities.gameobject.properties.Interactable; 9 | 10 | import java.util.StringJoiner; 11 | 12 | /** 13 | * This class represents a game object. You can extend this class to create your own game objects. 14 | */ 15 | @Getter 16 | @Setter 17 | public abstract class GameObject { 18 | 19 | private ObjectInformation information; 20 | private boolean canBeInteractedWith; 21 | private Character owner; 22 | 23 | /** 24 | * Creates a new game object. 25 | * 26 | * @param information The information of the game object. 27 | * @param canBeInteractedWith If the game object can be interacted with. 28 | * @param owner The owner of the game object. 29 | */ 30 | public GameObject(@NonNull ObjectInformation information, boolean canBeInteractedWith, Character owner) { 31 | this.information = information; 32 | this.canBeInteractedWith = canBeInteractedWith; 33 | this.owner = owner; 34 | } 35 | 36 | /** 37 | * Interacts with the game object. 38 | * 39 | * @param interactable The interactable object. It can be a character or a game object. 40 | */ 41 | public void interactedBy(@NonNull Interactable interactable) { 42 | if (!canBeInteractedWith) { 43 | throw new UnsupportedOperationException("You should change the canBeInteractedWith boolean to true if you want to interact with this object."); 44 | } 45 | } 46 | 47 | @Override 48 | public String toString() { 49 | return new StringJoiner(", ", GameObject.class.getSimpleName() + "[", "]") 50 | .add("information=" + information) 51 | .add("canBeInteractedWith=" + canBeInteractedWith) 52 | .add("owner=" + owner) 53 | .toString(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/me/adversing/engine/obj/entities/character/info/CharacterInformation.java: -------------------------------------------------------------------------------- 1 | package me.adversing.engine.obj.entities.character.info; 2 | 3 | import lombok.Getter; 4 | import lombok.NonNull; 5 | import lombok.Setter; 6 | import me.adversing.engine.obj.entities.character.Character; 7 | import me.adversing.engine.obj.entities.character.relationships.RelationShipStatus; 8 | 9 | import java.util.HashMap; 10 | import java.util.List; 11 | import java.util.StringJoiner; 12 | 13 | /** 14 | * This class represents the information of a character. 15 | */ 16 | @Getter 17 | @Setter 18 | public class CharacterInformation { 19 | private final String id; 20 | private String name, surname; 21 | private int age; 22 | private String biography; 23 | private List> relationships; 24 | 25 | /** 26 | * Creates a new character information. 27 | * 28 | * @param id The id of the character. 29 | * @param name The name of the character. 30 | * @param surname The surname of the character. 31 | * @param age The age of the character. 32 | * @param biography The biography of the character. 33 | * @param relationships The relationships of the character. This is a list because there can be multiple relationships in a character. 34 | * @see Character 35 | * @see RelationShipStatus 36 | */ 37 | public CharacterInformation(@NonNull String id, @NonNull String name, @NonNull String surname, int age, @NonNull String biography, @NonNull List> relationships) { 38 | assert age > 0 : "The age must be greater than 0."; 39 | this.id = id; 40 | this.name = name; 41 | this.surname = surname; 42 | this.age = age; 43 | this.biography = biography; 44 | this.relationships = relationships; 45 | } 46 | 47 | @Override 48 | public String toString() { 49 | return new StringJoiner(", ", CharacterInformation.class.getSimpleName() + "[", "]") 50 | .add("id='" + id + "'") 51 | .add("name='" + name + "'") 52 | .add("surname='" + surname + "'") 53 | .add("age=" + age) 54 | .add("biography='" + biography + "'") 55 | .add("relationships=" + relationships) 56 | .toString(); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/me/adversing/engine/core/handlers/StoryHandler.java: -------------------------------------------------------------------------------- 1 | package me.adversing.engine.core.handlers; 2 | 3 | import lombok.Getter; 4 | import lombok.NonNull; 5 | import lombok.Setter; 6 | import me.adversing.engine.story.Story; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | import java.util.stream.Collectors; 11 | 12 | /** 13 | * This class represents a story handler. From here you can get, add and remove stories. 14 | */ 15 | @Getter 16 | @Setter 17 | public class StoryHandler { 18 | private List stories; 19 | 20 | /** 21 | * Creates a new story handler. 22 | * 23 | * @see Story 24 | */ 25 | public StoryHandler() { 26 | this.stories = new ArrayList<>(); 27 | } 28 | 29 | /** 30 | * Creates a new story handler. This constructor is used when you want to load stories from a List. 31 | * 32 | * @param stories The stories to load. 33 | * @see Story 34 | */ 35 | public StoryHandler(@NonNull List stories) { 36 | this.stories = stories; 37 | } 38 | 39 | /** 40 | * Adds a story to the story handler. 41 | * 42 | * @param story The story to add. 43 | * @see Story 44 | */ 45 | public void addStory(@NonNull Story story) { 46 | if (!this.stories.contains(story)) { 47 | this.stories.add(story); 48 | } 49 | } 50 | 51 | /** 52 | * Removes a story from the story handler. 53 | * 54 | * @param story The story to remove. 55 | * @see Story 56 | */ 57 | public void removeStory(@NonNull Story story) { 58 | if (this.stories.contains(story)) { 59 | this.stories.remove(story); 60 | } 61 | } 62 | 63 | /** 64 | * Clears the list containing all the stories. 65 | * 66 | * @see Story 67 | */ 68 | public void clearStories() { 69 | this.stories.clear(); 70 | } 71 | 72 | /** 73 | * Gets all the stories from the story handler filtering the inactive ones. 74 | * 75 | * @return The filtered stories. 76 | * @see Story 77 | */ 78 | public List getActiveStories() { 79 | return this.stories.stream().filter(Story::isActive).collect(Collectors.toList()); 80 | } 81 | 82 | /** 83 | * Gets a story from the story handler. 84 | * 85 | * @param storyId The story id. 86 | * @return The story or null if the story doesn't exist. 87 | * @see Story 88 | */ 89 | public Story getStory(@NonNull String storyId) { 90 | return this.stories.stream().filter(story -> story.getInformation().getStoryId().equals(storyId)).findFirst().orElse(null); 91 | } 92 | 93 | } -------------------------------------------------------------------------------- /src/main/java/me/adversing/engine/logic/Choice.java: -------------------------------------------------------------------------------- 1 | package me.adversing.engine.logic; 2 | 3 | import lombok.Getter; 4 | import lombok.NonNull; 5 | import lombok.Setter; 6 | import me.adversing.engine.dialogue.section.DialogueSection; 7 | import me.adversing.engine.logic.info.ChoiceInformation; 8 | import me.adversing.engine.utils.time.countdown.Countdown; 9 | 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | import java.util.StringJoiner; 13 | 14 | /** 15 | * This class represents a choice. 16 | */ 17 | @Getter 18 | @Setter 19 | public class Choice { 20 | private final ChoiceInformation information; 21 | private final String headTitle; 22 | private DialogueSection dialogueSection; 23 | private final int maxChoices; 24 | private List choices; 25 | private final Countdown countdown; 26 | 27 | /** 28 | * Creates a new choice. 29 | * 30 | * @param information The choice information. 31 | * @param dialogueSection The dialogue section. 32 | * @param maxChoices The maximum amount of choices. 33 | * @param choices The choices. 34 | * @param countdown The countdown. 35 | * @see ChoiceInformation 36 | * @see DialogueSection 37 | */ 38 | public Choice(@NonNull ChoiceInformation information, @NonNull String headTitle, @NonNull DialogueSection dialogueSection, int maxChoices, @NonNull List choices,@NonNull Countdown countdown) { 39 | assert maxChoices == choices.size() : "The maximum amount of choices must be equal to the amount of choices."; 40 | assert maxChoices > 0 : "The maximum amount of choices must be greater than 0."; 41 | this.information = information; 42 | this.headTitle = headTitle; 43 | this.dialogueSection = dialogueSection; 44 | this.maxChoices = maxChoices; 45 | this.choices = new ArrayList<>(maxChoices); 46 | this.choices.addAll(choices); 47 | this.countdown = countdown; 48 | } 49 | 50 | /** 51 | * Selects a choice. 52 | * @param choiceText The choice text. 53 | * @return The choice. 54 | */ 55 | public String selectChoice(String choiceText) { 56 | return choices.stream().filter(choice -> choice.equals(choiceText)).findFirst().orElse(null); 57 | } 58 | 59 | @Override 60 | public String toString() { 61 | return new StringJoiner(", ", Choice.class.getSimpleName() + "[", "]") 62 | .add("information=" + information) 63 | .add("headTitle='" + headTitle + "'") 64 | .add("dialogueSection=" + dialogueSection) 65 | .add("maxChoices=" + maxChoices) 66 | .add("choices=" + choices) 67 | .add("countdown=" + countdown) 68 | .toString(); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/main/java/me/adversing/engine/story/Story.java: -------------------------------------------------------------------------------- 1 | package me.adversing.engine.story; 2 | 3 | import lombok.Getter; 4 | import lombok.NonNull; 5 | import lombok.Setter; 6 | import me.adversing.engine.obj.entities.character.Character; 7 | import me.adversing.engine.obj.map.GameMap; 8 | import me.adversing.engine.story.info.StoryInformation; 9 | import me.adversing.engine.story.structure.chapter.Chapter; 10 | 11 | import java.util.List; 12 | import java.util.StringJoiner; 13 | 14 | /** 15 | * This class represents a story. 16 | */ 17 | @Getter 18 | @Setter 19 | public abstract class Story { 20 | 21 | private StoryInformation information; 22 | private List chapters; 23 | private List characters; 24 | private GameMap map; 25 | private boolean isCompleted; 26 | private boolean isActive; 27 | 28 | /** 29 | * Creates a new story. 30 | * 31 | * @param storyId The story id. 32 | * @param title The story title. 33 | * @param description The story description. 34 | * @param chapters The story chapters. 35 | * @param characters The story characters. 36 | * @param map The story map. 37 | * @param isCompleted The story completion status. This is used to determine if the story is completed or not. 38 | * @param isActive The story activity status. This is used to determine if the story is active or not. 39 | * @see StoryInformation 40 | * @see Chapter 41 | * @see Character 42 | * @see GameMap 43 | */ 44 | public Story(@NonNull String storyId, @NonNull String title, @NonNull String description, @NonNull List chapters, @NonNull List characters, @NonNull GameMap map, boolean isCompleted, boolean isActive) { 45 | this.information = new StoryInformation(storyId, title, description, chapters.size()); 46 | this.chapters = chapters; 47 | this.characters = characters; 48 | this.map = map; 49 | this.isCompleted = isCompleted; 50 | this.isActive = isActive; 51 | } 52 | 53 | public abstract void onStart(); 54 | 55 | public abstract void onEnd(); 56 | 57 | public Character getCharacterById(String id) { 58 | return characters.stream().filter(character -> character.getCharacterInformation().getId().equals(id)).findFirst().orElse(null); 59 | } 60 | 61 | public Chapter getChapterById(String id) { 62 | return chapters.stream().filter(chapter -> chapter.getInformation().getId().equals(id)).findFirst().orElse(null); 63 | } 64 | 65 | @Override 66 | public String toString() { 67 | return new StringJoiner(", ", Story.class.getSimpleName() + "[", "]") 68 | .add("information=" + information) 69 | .add("chapters=" + chapters) 70 | .add("isCompleted=" + isCompleted) 71 | .toString(); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/me/adversing/engine/obj/map/area/GameArea.java: -------------------------------------------------------------------------------- 1 | package me.adversing.engine.obj.map.area; 2 | 3 | import lombok.Getter; 4 | import lombok.NonNull; 5 | import lombok.Setter; 6 | import me.adversing.engine.obj.entities.character.inv.Inventory; 7 | import me.adversing.engine.obj.items.Item; 8 | import me.adversing.engine.obj.map.area.info.GameAreaInformation; 9 | import me.adversing.engine.obj.map.location.info.LocationInformation; 10 | 11 | import java.util.HashMap; 12 | import java.util.List; 13 | import java.util.StringJoiner; 14 | import java.util.UUID; 15 | 16 | /** 17 | * This class represents a game area. 18 | */ 19 | @Getter 20 | @Setter 21 | public abstract class GameArea { 22 | 23 | private GameAreaInformation information; 24 | private List> itemsThatCanUnlockThisArea; 25 | private final boolean isInventory; 26 | 27 | /** 28 | * This constructor is used for the game areas. Don't use this constructor for the inventory. 29 | * 30 | * @param information The information of the game area. 31 | * @param itemsThatCanUnlockThisArea The items that can unlock this area. 32 | * @see GameAreaInformation 33 | * @see LocationInformation 34 | * @see Item 35 | */ 36 | public GameArea(@NonNull GameAreaInformation information, @NonNull List> itemsThatCanUnlockThisArea) { 37 | this.isInventory = false; 38 | this.information = information; 39 | this.itemsThatCanUnlockThisArea = itemsThatCanUnlockThisArea; 40 | } 41 | 42 | /** 43 | * This constructor is used for the inventory. Don't use this constructor for the game areas. 44 | * 45 | * @see Inventory 46 | */ 47 | protected GameArea() { 48 | this.isInventory = true; 49 | this.information = new GameAreaInformation("inventory#%s".formatted(UUID.randomUUID()), "Inventory", "The inventory of the character.", null, null); 50 | this.itemsThatCanUnlockThisArea = null; 51 | } 52 | 53 | /** 54 | * Tests if the item can unlock this area. 55 | * 56 | * @param item The item to test. 57 | * @return True if the item can unlock this area, false otherwise. 58 | */ 59 | public boolean testFor(@NonNull Item item) { 60 | if (this.isInventory) return false; 61 | if (this.itemsThatCanUnlockThisArea.isEmpty()) return true; 62 | for (HashMap itemHashMap : itemsThatCanUnlockThisArea) { 63 | if (itemHashMap.containsKey(item)) { 64 | return itemHashMap.get(item); 65 | } 66 | } 67 | return false; 68 | } 69 | 70 | 71 | @Override 72 | public String toString() { 73 | return new StringJoiner(", ", GameArea.class.getSimpleName() + "[", "]") 74 | .add("information=" + information) 75 | .add("itemsThatCanUnlockThisArea=" + itemsThatCanUnlockThisArea) 76 | .add("isInventory=" + isInventory) 77 | .toString(); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/main/java/me/adversing/engine/obj/entities/gameobject/info/ObjectInformation.java: -------------------------------------------------------------------------------- 1 | package me.adversing.engine.obj.entities.gameobject.info; 2 | 3 | import lombok.Getter; 4 | import lombok.NonNull; 5 | import lombok.Setter; 6 | import me.adversing.engine.obj.entities.character.inv.Inventory; 7 | import me.adversing.engine.obj.entities.gameobject.type.ObjectType; 8 | import me.adversing.engine.obj.map.area.GameArea; 9 | 10 | import java.util.StringJoiner; 11 | 12 | /** 13 | * This class represents the information of an object. 14 | */ 15 | @Getter 16 | @Setter 17 | public class ObjectInformation { 18 | 19 | private String id; 20 | private String name; 21 | private ObjectType type; 22 | private int durability; 23 | private int maxDurability; 24 | private String description; 25 | private GameArea gameArea; 26 | 27 | /** 28 | * Creates a new object information. 29 | * 30 | * @param name The name of the object. 31 | * @param type The type of the object. 32 | * @param durability The durability of the object. 33 | * @param maxDurability The maximum durability of the object. 34 | * @param description The description of the object. 35 | * @param gameArea The game area of the object. 36 | * @see ObjectType 37 | * @see GameArea 38 | */ 39 | public ObjectInformation(@NonNull String id, @NonNull String name, @NonNull ObjectType type, int durability, int maxDurability, @NonNull String description, @NonNull GameArea gameArea) { 40 | assert durability <= maxDurability : "The durability cannot be greater than the maximum durability."; 41 | assert durability >= 0 : "The durability cannot be less than 0."; 42 | this.id = id; 43 | this.name = name; 44 | this.type = type; 45 | this.durability = durability; 46 | this.maxDurability = maxDurability; 47 | this.description = description; 48 | this.gameArea = gameArea; 49 | } 50 | 51 | /** 52 | * Sets the game area of the object. 53 | * 54 | * @param area The game area of the object. This can be an instance of GameArea or Inventory. If it's an instance of Inventory, it will be cast to GameArea. 55 | */ 56 | public void setGameArea(Object area) { 57 | if (!(area instanceof Inventory)) 58 | if (!(area instanceof GameArea)) { 59 | throw new IllegalArgumentException("The area must be an instance of GameArea OR Inventory."); 60 | } 61 | this.gameArea = (GameArea) area; 62 | } 63 | 64 | @Override 65 | public String toString() { 66 | return new StringJoiner(", ", ObjectInformation.class.getSimpleName() + "[", "]") 67 | .add("name='" + name + "'") 68 | .add("type=" + type) 69 | .add("durability=" + durability) 70 | .add("maxDurability=" + maxDurability) 71 | .add("description='" + description + "'") 72 | .add("gameArea=" + gameArea) 73 | .toString(); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/me/adversing/engine/obj/entities/character/relationships/RelationShipStatus.java: -------------------------------------------------------------------------------- 1 | package me.adversing.engine.obj.entities.character.relationships; 2 | 3 | import lombok.Getter; 4 | import me.adversing.engine.obj.entities.character.Character; 5 | import me.adversing.engine.obj.entities.character.info.CharacterInformation; 6 | import me.adversing.engine.dialogue.section.DialogueSection; 7 | 8 | import java.util.Arrays; 9 | import java.util.StringJoiner; 10 | 11 | /** 12 | * This enum represents the relationship status of a character. 13 | */ 14 | public enum RelationShipStatus { 15 | ACQUAINTANCE("Acquaintance"), // Casual acquaintances 16 | ALLY("Ally"), // Strong alliance or partnership 17 | BEST_FRIEND("Best Friend"), // Strongest friendship 18 | BETRAYED("Betrayed"), // One NPC has betrayed the other 19 | BROKEN("Broken") , // Relationship has been broken or severed 20 | ENEMY("Enemy"), // Hostile relationship 21 | FAMILY("Family"), // Family relationship 22 | FRIEND("Friend"), // Friendship 23 | LOVER("Lover"), // Romantic involvement, specifically as lovers 24 | MENTOR("Mentor"), // Mentor or mentee relationship 25 | NEUTRAL("Neutral"), // Neutral or indifferent relationship 26 | NONE("None"), // No relationship or unknown 27 | RESCUED("Rescued"), // One NPC has rescued the other 28 | RIVAL("Rival"), // Competitive relationship 29 | ROMANTIC_PARTNER("Romantic Partner"), // Romantic involvement 30 | SUSPICIOUS("Suspicious"), // Suspicion or doubt in the relationship 31 | TRUSTWORTHY("Trustworthy"); // High level of trust between NPCs 32 | 33 | 34 | 35 | @Getter 36 | private final String readableName; 37 | 38 | /** 39 | * Creates a new relationship status. 40 | * 41 | * @param readableName The readable name of the relationship status. This is used to display the relationship status in the game. 42 | * @see RelationShipStatus 43 | * @see Character 44 | * @see CharacterInformation 45 | * @see DialogueSection 46 | */ 47 | RelationShipStatus(String readableName) { 48 | this.readableName = readableName; 49 | } 50 | 51 | /** 52 | * Gets the relationship status by its readable name. 53 | * 54 | * @param readableName The readable name of the relationship status. 55 | * @return The relationship status. 56 | */ 57 | public static RelationShipStatus getRelationShipStatus(String readableName) { 58 | return Arrays.stream(values()).filter(relationShipStatus -> relationShipStatus.getReadableName().equalsIgnoreCase(readableName)).findFirst().orElse(null); 59 | } 60 | 61 | @Override 62 | public String toString() { 63 | return new StringJoiner(", ", RelationShipStatus.class.getSimpleName() + "[", "]") 64 | .add("readableName='" + readableName + "'") 65 | .toString(); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/me/adversing/engine/obj/entities/character/Character.java: -------------------------------------------------------------------------------- 1 | package me.adversing.engine.obj.entities.character; 2 | 3 | import lombok.Getter; 4 | import lombok.NonNull; 5 | import lombok.Setter; 6 | import me.adversing.engine.dialogue.section.DialogueSection; 7 | import me.adversing.engine.logic.Choice; 8 | import me.adversing.engine.obj.entities.character.info.CharacterInformation; 9 | import me.adversing.engine.obj.entities.character.inv.Inventory; 10 | import me.adversing.engine.obj.entities.character.relationships.Feeling; 11 | import me.adversing.engine.obj.entities.character.status.CharacterStatus; 12 | import me.adversing.engine.obj.entities.gameobject.GameObject; 13 | import me.adversing.engine.obj.entities.gameobject.properties.Interactable; 14 | import me.adversing.engine.obj.map.area.GameArea; 15 | 16 | import java.util.*; 17 | 18 | 19 | /** 20 | * This class represents a character. A character is an entity that can interact with other entities and objects in the game world and has a status, an inventory, choices, and feelings. A character can be a player or an NPC. 21 | */ 22 | @Getter 23 | @Setter 24 | public abstract class Character implements Interactable { 25 | 26 | private CharacterInformation characterInformation; 27 | private CharacterStatus characterStatus; 28 | private Inventory inventory; 29 | private List totalChoices; 30 | private List> choices; 31 | private List> feelings; 32 | private GameArea gameArea; 33 | 34 | /** 35 | * Creates a new character. 36 | * 37 | * @param characterInformation The character information. 38 | * @param characterStatus The character status. 39 | * @param inventory The inventory of the character. 40 | * @param choices The choices of the character. 41 | * @param gameArea The game area of the character. 42 | */ 43 | public Character(@NonNull CharacterInformation characterInformation, @NonNull CharacterStatus characterStatus, @NonNull Inventory inventory, @NonNull List choices, @NonNull GameArea gameArea) { 44 | this.characterInformation = characterInformation; 45 | this.characterStatus = characterStatus; 46 | this.inventory = inventory; 47 | this.totalChoices = choices; 48 | this.gameArea = gameArea; 49 | } 50 | 51 | /** 52 | * This method is called when the character is interacted by another interactable. 53 | * 54 | * @param interactable The interactable that interacted with the character. 55 | */ 56 | public void interactedBy(Interactable interactable) { 57 | } 58 | 59 | /** 60 | * This method is called when the character interacts with a Character. 61 | * 62 | * @param character Target character. 63 | */ 64 | public abstract void onInteract(Character character); 65 | 66 | /** 67 | * This method is called when the character interacts with a GameObject. 68 | * 69 | * @param gameObject Target game object. 70 | */ 71 | public abstract void onInteract(GameObject gameObject); 72 | 73 | /** 74 | * This method is called when you have to add a choice to the character. 75 | * 76 | * @param c The choice. 77 | */ 78 | public void addChoice(Choice c) { 79 | if (!totalChoices.contains(c)) totalChoices.add(c); 80 | } 81 | 82 | /** 83 | * This method is called when you have to add a choice related to a dialogue section to the character. 84 | * 85 | * @param c The choice. 86 | * @param d The dialogue section. 87 | */ 88 | public void addChoiceRelatedToDialogue(Choice c, DialogueSection d) { 89 | HashMap newChoice = new HashMap<>(); 90 | newChoice.put(c, d); 91 | if (!totalChoices.contains(c) && !choices.contains(newChoice)) { 92 | totalChoices.add(c); 93 | choices.add(newChoice); 94 | } 95 | } 96 | 97 | /** 98 | * This method is called when you have to add a choice related to a feeling to the character. 99 | * 100 | * @param c The choice. 101 | * @param f The feeling. 102 | */ 103 | public void addFeeling(Choice c, Feeling f) { 104 | HashMap newFeeling = new HashMap<>(); 105 | newFeeling.put(c, f); 106 | if (!totalChoices.contains(c) && !feelings.contains(newFeeling)) { 107 | totalChoices.add(c); 108 | feelings.add(newFeeling); 109 | } 110 | } 111 | 112 | /** 113 | * This method returns the main feeling of the character. 114 | * 115 | * @return The main feeling of the character, expressed as Feeling or null. 116 | */ 117 | public Optional getDominantFeeling() { 118 | HashMap feelingsCount = new HashMap<>(); 119 | for (HashMap feeling : feelings) { 120 | for (Feeling f : feeling.values()) { 121 | feelingsCount.put(f, feelingsCount.getOrDefault(f, 0) + 1); 122 | } 123 | } 124 | return feelingsCount.entrySet().stream() 125 | .max(Map.Entry.comparingByValue()) 126 | .map(Map.Entry::getKey); 127 | } 128 | 129 | 130 | @Override 131 | public String toString() { 132 | return new StringJoiner(", ", Character.class.getSimpleName() + "[", "]") 133 | .add("characterInformation=" + characterInformation) 134 | .add("characterStatus=" + characterStatus) 135 | .add("inventory=" + inventory) 136 | .add("totalChoices=" + totalChoices) 137 | .add("choices=" + choices) 138 | .add("feelings=" + feelings) 139 | .add("gameArea=" + gameArea) 140 | .toString(); 141 | } 142 | } 143 | --------------------------------------------------------------------------------