Compare commits
57 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
cf0df54548
|
|||
|
e8cc766ded
|
|||
|
2e4459b92c
|
|||
|
d66aabd58a
|
|||
|
1e8ff04930
|
|||
|
8edbc48ff1
|
|||
|
9d42bb8ee3
|
|||
|
d08ba8eb5a
|
|||
|
990ad6519e
|
|||
|
0be7b2fa43
|
|||
|
356f792523
|
|||
|
e9ee8f7541
|
|||
|
eaa5f5d547
|
|||
|
3b99bc561a
|
|||
|
f74548713d
|
|||
|
898582fdb1
|
|||
|
6fefa32c7d
|
|||
|
1d5afb0530
|
|||
|
a8f4679ee6
|
|||
|
4357c631be
|
|||
|
c967562498
|
|||
|
181061eb64
|
|||
|
f5790df5aa
|
|||
|
b051f20bd7
|
|||
|
796c0ec9b0
|
|||
|
25c9abd427
|
|||
|
6678c352bb
|
|||
|
5d9c7e6de2
|
|||
|
8c4d114dad
|
|||
|
9bf75a8458
|
|||
|
bf19c7bcf4
|
|||
|
3cdec6b303
|
|||
|
fd5610fca0
|
|||
|
92c2f3347a
|
|||
|
9ff0d6c99d
|
|||
|
76264407f4
|
|||
|
5cf94454cf
|
|||
|
c86f042cf8
|
|||
|
18883b66c2
|
|||
|
7d909d1d52
|
|||
|
3eceb93559
|
|||
|
9ccd509b19
|
|||
|
dadb48e6d6
|
|||
|
fe828f9026
|
|||
|
1a96932bca
|
|||
|
2c1fc56a5f
|
|||
|
a8a12a022a
|
|||
|
e366f85de1
|
|||
|
8946297bd9
|
|||
|
4f7c6c6dc3
|
|||
|
b157d7bf26
|
|||
|
60acb5749d
|
|||
|
a6c0eebba2
|
|||
|
329e8a18c5
|
|||
|
933608b753
|
|||
|
1253139bfe
|
|||
|
d51a425b28
|
3
.gitignore
vendored
@@ -1,2 +1,5 @@
|
|||||||
|
.direnv
|
||||||
build/
|
build/
|
||||||
data.trace.db
|
data.trace.db
|
||||||
|
*.jar
|
||||||
|
result
|
||||||
BIN
animations/0ddac391-4086-4e9c-8310-59db649419ff.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 11 KiB |
BIN
animations/78563669-8a6c-4024-82c8-7e4da5b76edd.png
Normal file
|
After Width: | Height: | Size: 7.9 KiB |
BIN
animations/aeb17449-c342-4dab-9057-5fb05183fd03.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
animations/c8883e76-ae93-4673-8893-d2ec72c1e199.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
autotiles/04ac5ad8-4100-4016-97b3-a51a728ca49d.png
Normal file
|
After Width: | Height: | Size: 82 KiB |
BIN
autotiles/11ffee29-0262-4d17-a1ab-1091bf687f8f.png
Normal file
|
After Width: | Height: | Size: 182 KiB |
BIN
autotiles/2f472e90-f689-4898-900c-b45cf08e7010.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
autotiles/532abf4b-55bb-476d-9829-9655eb8cd8bd.png
Normal file
|
After Width: | Height: | Size: 35 KiB |
BIN
autotiles/6584a279-e937-497e-a056-b1e77bff2439.png
Normal file
|
After Width: | Height: | Size: 270 KiB |
BIN
autotiles/7190cf18-bfc3-47b4-bbd3-b867780ce340.png
Normal file
|
After Width: | Height: | Size: 21 KiB |
BIN
autotiles/88042125-4c6d-4dfa-ad1d-8e78b6df9ee9.png
Normal file
|
After Width: | Height: | Size: 182 KiB |
BIN
autotiles/8d4760d4-f0af-47ca-8811-495ef8e8516f.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
BIN
autotiles/b475367a-7bf8-44ee-b916-6e81a78f97d9.png
Normal file
|
After Width: | Height: | Size: 179 KiB |
BIN
autotiles/d128e497-d9d7-4ce8-be8d-c2f8b04b3b49.png
Normal file
|
After Width: | Height: | Size: 336 KiB |
BIN
autotiles/f6bcd0ea-f293-4864-bd13-d1c4e8b79080.png
Normal file
|
After Width: | Height: | Size: 342 KiB |
BIN
autotiles/fc294b9e-105a-4120-8caa-393d78fdf414.png
Normal file
|
After Width: | Height: | Size: 53 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 9.9 KiB |
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
BIN
charsets/35f770a6-5d94-4ddf-a132-dc3788a3adaf.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
BIN
charsets/4a636044-2dbd-4ef3-8bdf-b63501c85ae3.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
BIN
charsets/a6863639-d563-4d88-af8e-c6d087ee2ffb.png
Normal file
|
After Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 7.7 KiB After Width: | Height: | Size: 7.7 KiB |
|
Before Width: | Height: | Size: 7.8 KiB After Width: | Height: | Size: 7.8 KiB |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
BIN
charsets/f529cbfc-c29d-470b-8804-e50d6a1efc98.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.8 KiB |
BIN
data.mv.db
184
data.sql
Normal file
@@ -0,0 +1,184 @@
|
|||||||
|
SET DB_CLOSE_DELAY -1;
|
||||||
|
;
|
||||||
|
CREATE USER IF NOT EXISTS "" SALT '' HASH '' ADMIN;
|
||||||
|
CREATE SEQUENCE "PUBLIC"."SYSTEM_SEQUENCE_CE051218_6282_4D4E_BC8B_083D4B720B25" START WITH 13 BELONGS_TO_TABLE;
|
||||||
|
CREATE SEQUENCE "PUBLIC"."SYSTEM_SEQUENCE_704587BB_DC0E_44AB_A7F0_3DE0CA44FE3F" START WITH 2 BELONGS_TO_TABLE;
|
||||||
|
CREATE MEMORY TABLE "PUBLIC"."RANGED_WEAPON"(
|
||||||
|
"ID" VARCHAR NOT NULL,
|
||||||
|
"NAME" VARCHAR NOT NULL,
|
||||||
|
"TYPE" VARCHAR NOT NULL,
|
||||||
|
"COOLDOWN" INT NOT NULL,
|
||||||
|
"DAMAGE" VARCHAR NOT NULL,
|
||||||
|
"ANIMATION" VARCHAR NOT NULL,
|
||||||
|
"SOUND" VARCHAR NOT NULL,
|
||||||
|
"RANGE" VARCHAR NOT NULL,
|
||||||
|
"PUNCH_ANIMATION" VARCHAR NOT NULL,
|
||||||
|
"PUNCH_SOUND" VARCHAR NOT NULL,
|
||||||
|
"MISS_ANIMATION" VARCHAR NOT NULL,
|
||||||
|
"MISS_SOUND" VARCHAR NOT NULL,
|
||||||
|
"ICON" VARCHAR NOT NULL
|
||||||
|
);
|
||||||
|
ALTER TABLE "PUBLIC"."RANGED_WEAPON" ADD CONSTRAINT "PUBLIC"."CONSTRAINT_4" PRIMARY KEY("ID");
|
||||||
|
-- 2 +/- SELECT COUNT(*) FROM PUBLIC.RANGED_WEAPON;
|
||||||
|
INSERT INTO "PUBLIC"."RANGED_WEAPON" VALUES
|
||||||
|
('wooden_bow', 'Wooden Bow', 'bow', 1000, '1d6+1', 'Arrow', 'Arrow', '5d4', 'Punch', 'Arrow punch', 'Poof', 'Arrow punch', 'Generic,12,11'),
|
||||||
|
('iron_bow', 'Iron Bow', 'bow', 700, '2d6+2', 'Arrow', 'Arrow', '6d4', 'Punch', 'Arrow punch', 'Poof', 'Arrow punch', 'Generic,12,10');
|
||||||
|
CREATE MEMORY TABLE "PUBLIC"."AMMUNITION"(
|
||||||
|
"ID" VARCHAR NOT NULL,
|
||||||
|
"NAME" VARCHAR NOT NULL,
|
||||||
|
"APPLIES_TO" VARCHAR NOT NULL,
|
||||||
|
"DAMAGE" VARCHAR NOT NULL,
|
||||||
|
"ICON" VARCHAR NOT NULL
|
||||||
|
);
|
||||||
|
ALTER TABLE "PUBLIC"."AMMUNITION" ADD CONSTRAINT "PUBLIC"."CONSTRAINT_F" PRIMARY KEY("ID");
|
||||||
|
-- 1 +/- SELECT COUNT(*) FROM PUBLIC.AMMUNITION;
|
||||||
|
INSERT INTO "PUBLIC"."AMMUNITION" VALUES
|
||||||
|
('wooden_arrow', 'Wooden Arrow', 'bow', '1', 'Generic,8,10');
|
||||||
|
CREATE MEMORY TABLE "PUBLIC"."MELEE_WEAPON"(
|
||||||
|
"ID" VARCHAR NOT NULL,
|
||||||
|
"NAME" VARCHAR NOT NULL,
|
||||||
|
"COOLDOWN" INT NOT NULL,
|
||||||
|
"DAMAGE" VARCHAR NOT NULL,
|
||||||
|
"ANIMATION" VARCHAR NOT NULL,
|
||||||
|
"SOUND" VARCHAR,
|
||||||
|
"ICON" VARCHAR NOT NULL
|
||||||
|
);
|
||||||
|
ALTER TABLE "PUBLIC"."MELEE_WEAPON" ADD CONSTRAINT "PUBLIC"."CONSTRAINT_2" PRIMARY KEY("ID");
|
||||||
|
-- 2 +/- SELECT COUNT(*) FROM PUBLIC.MELEE_WEAPON;
|
||||||
|
INSERT INTO "PUBLIC"."MELEE_WEAPON" VALUES
|
||||||
|
('wooden_sword', 'Wooden Sword', 1000, '1d4+1', 'Slash', 'Sword slash', 'Generic,5,10'),
|
||||||
|
('wooden_dagger', 'Wooden Dagger', 300, '1d2', 'Slash', 'Sword slash', 'Generic,7,1');
|
||||||
|
CREATE MEMORY TABLE "PUBLIC"."OBJECT"(
|
||||||
|
"ID" VARCHAR NOT NULL,
|
||||||
|
"NAME" VARCHAR NOT NULL,
|
||||||
|
"CHARSET" VARCHAR NOT NULL,
|
||||||
|
"FRAME" SMALLINT,
|
||||||
|
"INTERACT_SOUND" VARCHAR
|
||||||
|
);
|
||||||
|
ALTER TABLE "PUBLIC"."OBJECT" ADD CONSTRAINT "PUBLIC"."CONSTRAINT_C" PRIMARY KEY("ID");
|
||||||
|
-- 3 +/- SELECT COUNT(*) FROM PUBLIC.OBJECT;
|
||||||
|
INSERT INTO "PUBLIC"."OBJECT" VALUES
|
||||||
|
('black_fsm_right_doors', 'Doors', 'FSM Doors', 0, 'Arrow punch'),
|
||||||
|
('enforced_chest_left', 'Enforced Chest', 'Chests', 3, 'Arrow punch'),
|
||||||
|
('plain_chest_down', 'Plain Chest', 'Chests', 0, 'Arrow punch');
|
||||||
|
CREATE MEMORY TABLE "PUBLIC"."JUNK"(
|
||||||
|
"ID" VARCHAR NOT NULL,
|
||||||
|
"NAME" VARCHAR NOT NULL,
|
||||||
|
"ICON" VARCHAR NOT NULL
|
||||||
|
);
|
||||||
|
ALTER TABLE "PUBLIC"."JUNK" ADD CONSTRAINT "PUBLIC"."CONSTRAINT_22" PRIMARY KEY("ID");
|
||||||
|
-- 4 +/- SELECT COUNT(*) FROM PUBLIC.JUNK;
|
||||||
|
INSERT INTO "PUBLIC"."JUNK" VALUES
|
||||||
|
('bone', 'Bone', 'Generic,21,2'),
|
||||||
|
('eye', 'Eye', 'Generic,21,3'),
|
||||||
|
('tooth', 'Tooth', 'Generic,21,5'),
|
||||||
|
('fur', 'Fur', 'Generic,21,6');
|
||||||
|
CREATE MEMORY TABLE "PUBLIC"."MEDICAMENTS"(
|
||||||
|
"ID" VARCHAR NOT NULL,
|
||||||
|
"NAME" VARCHAR NOT NULL,
|
||||||
|
"ICON" VARCHAR NOT NULL,
|
||||||
|
"HP" VARCHAR NOT NULL,
|
||||||
|
"ANIMATION" VARCHAR NOT NULL,
|
||||||
|
"SOUND" VARCHAR NOT NULL
|
||||||
|
);
|
||||||
|
ALTER TABLE "PUBLIC"."MEDICAMENTS" ADD CONSTRAINT "PUBLIC"."CONSTRAINT_E" PRIMARY KEY("ID");
|
||||||
|
-- 1 +/- SELECT COUNT(*) FROM PUBLIC.MEDICAMENTS;
|
||||||
|
INSERT INTO "PUBLIC"."MEDICAMENTS" VALUES
|
||||||
|
('small_life_potion', 'Small life potion', 'Generic,2,11', '2d4+2', 'Poof', 'Arrow punch');
|
||||||
|
CREATE MEMORY TABLE "PUBLIC"."ENEMY_DROP"(
|
||||||
|
"ID" INT DEFAULT NEXT VALUE FOR "PUBLIC"."SYSTEM_SEQUENCE_CE051218_6282_4D4E_BC8B_083D4B720B25" NOT NULL NULL_TO_DEFAULT SEQUENCE "PUBLIC"."SYSTEM_SEQUENCE_CE051218_6282_4D4E_BC8B_083D4B720B25",
|
||||||
|
"ENEMY" VARCHAR NOT NULL,
|
||||||
|
"ITEM" VARCHAR NOT NULL,
|
||||||
|
"CHANCE" DECIMAL NOT NULL,
|
||||||
|
"AMOUNT" VARCHAR NOT NULL
|
||||||
|
);
|
||||||
|
ALTER TABLE "PUBLIC"."ENEMY_DROP" ADD CONSTRAINT "PUBLIC"."CONSTRAINT_8" PRIMARY KEY("ID");
|
||||||
|
-- 7 +/- SELECT COUNT(*) FROM PUBLIC.ENEMY_DROP;
|
||||||
|
INSERT INTO "PUBLIC"."ENEMY_DROP" VALUES
|
||||||
|
(1, 'deku', 'throwing:deku_arrow', 0.8, '2d4+5'),
|
||||||
|
(6, 'skeleton', 'junk:bone', 0.7, '1'),
|
||||||
|
(7, 'skeleton_archer', 'junk:bone', 0.7, '1'),
|
||||||
|
(8, 'skeleton', 'melee:wooden_sword', 0.5, '1'),
|
||||||
|
(9, 'skeleton_archer', 'ranged:wooden_bow', 0.3, '1'),
|
||||||
|
(10, 'skeleton_archer', 'ammo:wooden_arrow', 0.7, '1d4+3'),
|
||||||
|
(11, 'deku', 'junk:eye', 0.7, '1d2');
|
||||||
|
CREATE MEMORY TABLE "PUBLIC"."CONFIG"(
|
||||||
|
"KEY" VARCHAR NOT NULL,
|
||||||
|
"VALUE" VARCHAR
|
||||||
|
);
|
||||||
|
ALTER TABLE "PUBLIC"."CONFIG" ADD CONSTRAINT "PUBLIC"."CONSTRAINT_7" PRIMARY KEY("KEY");
|
||||||
|
-- 5 +/- SELECT COUNT(*) FROM PUBLIC.CONFIG;
|
||||||
|
INSERT INTO "PUBLIC"."CONFIG" VALUES
|
||||||
|
('start_game', 'Hero Home,Main,Start'),
|
||||||
|
('screen', '1000x800'),
|
||||||
|
('camera_scale', '2'),
|
||||||
|
('full_day_duration', '600'),
|
||||||
|
('initial_time', '08:30');
|
||||||
|
CREATE MEMORY TABLE "PUBLIC"."LEVELS"(
|
||||||
|
"LEVEL" INT DEFAULT NEXT VALUE FOR "PUBLIC"."SYSTEM_SEQUENCE_704587BB_DC0E_44AB_A7F0_3DE0CA44FE3F" NOT NULL NULL_TO_DEFAULT SEQUENCE "PUBLIC"."SYSTEM_SEQUENCE_704587BB_DC0E_44AB_A7F0_3DE0CA44FE3F",
|
||||||
|
"MAX_HP" VARCHAR NOT NULL
|
||||||
|
);
|
||||||
|
ALTER TABLE "PUBLIC"."LEVELS" ADD CONSTRAINT "PUBLIC"."CONSTRAINT_85" PRIMARY KEY("LEVEL");
|
||||||
|
-- 1 +/- SELECT COUNT(*) FROM PUBLIC.LEVELS;
|
||||||
|
INSERT INTO "PUBLIC"."LEVELS" VALUES
|
||||||
|
(1, '3000');
|
||||||
|
CREATE MEMORY TABLE "PUBLIC"."THROWING_WEAPON"(
|
||||||
|
"ID" VARCHAR NOT NULL,
|
||||||
|
"NAME" VARCHAR NOT NULL,
|
||||||
|
"COOLDOWN" INT NOT NULL,
|
||||||
|
"DAMAGE" VARCHAR NOT NULL,
|
||||||
|
"ANIMATION" VARCHAR NOT NULL,
|
||||||
|
"SOUND" VARCHAR NOT NULL,
|
||||||
|
"RANGE" VARCHAR NOT NULL,
|
||||||
|
"PUNCH_ANIMATION" VARCHAR NOT NULL,
|
||||||
|
"PUNCH_SOUND" VARCHAR NOT NULL,
|
||||||
|
"MISS_ANIMATION" VARCHAR NOT NULL,
|
||||||
|
"MISS_SOUND" VARCHAR NOT NULL,
|
||||||
|
"ICON" VARCHAR NOT NULL
|
||||||
|
);
|
||||||
|
ALTER TABLE "PUBLIC"."THROWING_WEAPON" ADD CONSTRAINT "PUBLIC"."CONSTRAINT_40" PRIMARY KEY("ID");
|
||||||
|
-- 2 +/- SELECT COUNT(*) FROM PUBLIC.THROWING_WEAPON;
|
||||||
|
INSERT INTO "PUBLIC"."THROWING_WEAPON" VALUES
|
||||||
|
('deku_arrow', 'Deku''s arrow', 500, '2d4', 'Arrow', 'Arrow', '5d4', 'Punch', 'Arrow punch', 'Poof', 'Arrow punch', 'Generic,8,10'),
|
||||||
|
('shuriken', 'Shuriken', 100, '3d6', 'Shuriken', 'Arrow', '5d4', 'Punch', 'Arrow punch', 'Poof', 'Arrow punch', 'Generic,9,2');
|
||||||
|
CREATE MEMORY TABLE "PUBLIC"."ENEMY"(
|
||||||
|
"ID" VARCHAR NOT NULL,
|
||||||
|
"NAME" VARCHAR NOT NULL,
|
||||||
|
"CHARSET" VARCHAR NOT NULL,
|
||||||
|
"DEAD_CHARSET" VARCHAR,
|
||||||
|
"HP" VARCHAR NOT NULL,
|
||||||
|
"SPEED" VARCHAR NOT NULL,
|
||||||
|
"BLOCKING" BOOL NOT NULL,
|
||||||
|
"MELEE_WEAPON" VARCHAR,
|
||||||
|
"RANGED_WEAPON" VARCHAR,
|
||||||
|
"THROWING_WEAPON" VARCHAR,
|
||||||
|
"DIE_ANIMATION" VARCHAR NOT NULL,
|
||||||
|
"DIE_SOUND" VARCHAR NOT NULL
|
||||||
|
);
|
||||||
|
ALTER TABLE "PUBLIC"."ENEMY" ADD CONSTRAINT "PUBLIC"."CONSTRAINT_3" PRIMARY KEY("ID");
|
||||||
|
-- 8 +/- SELECT COUNT(*) FROM PUBLIC.ENEMY;
|
||||||
|
INSERT INTO "PUBLIC"."ENEMY" VALUES
|
||||||
|
('deku', 'Deku', 'Deku', 'Corpse', '2d4', '10d2', TRUE, NULL, NULL, 'deku_arrow,1d4+2', 'Poof', 'Deku death'),
|
||||||
|
('garo', 'Garo', 'Garo', 'Corpse', '7d4', '10d2', TRUE, 'wooden_sword', NULL, NULL, 'Poof', 'Deku death'),
|
||||||
|
('blanca', 'Blanca', 'Blanca', 'Corpse', '10d4', '10d2', TRUE, 'wooden_sword', NULL, NULL, 'Poof', 'Deku death'),
|
||||||
|
('turtle', 'Turtle', 'Turtle', 'Corpse', '5d4', '10d2', TRUE, 'wooden_sword', NULL, NULL, 'Poof', 'Deku death'),
|
||||||
|
('silver_bat', 'Silver Bat', 'Silver Bat', 'Corpse', '1d4+2', '10d2', TRUE, 'wooden_sword', NULL, NULL, 'Poof', 'Deku death'),
|
||||||
|
('eagle', 'Eagle', 'Eagle', 'Corpse', '2d4+2', '10d2', TRUE, 'wooden_sword', NULL, NULL, 'Poof', 'Deku death'),
|
||||||
|
('skeleton', 'Skeleton', 'Skeleton', 'Corpse', '2d6+2', '10d2', TRUE, 'wooden_sword', NULL, NULL, 'Poof', 'Deku death'),
|
||||||
|
('skeleton_archer', 'Skeleton Archer', 'Skeleton', 'Corpse', '2d6+2', '10d2', TRUE, 'wooden_dagger', 'wooden_bow,wooden_arrow,2d4+3', NULL, 'Poof', 'Deku death');
|
||||||
|
CREATE MEMORY TABLE "PUBLIC"."FRIEND"(
|
||||||
|
"ID" VARCHAR NOT NULL,
|
||||||
|
"NAME" VARCHAR NOT NULL,
|
||||||
|
"CHARSET" VARCHAR NOT NULL,
|
||||||
|
"SPEED" VARCHAR NOT NULL,
|
||||||
|
"BLOCKING" BOOLEAN DEFAULT FALSE NOT NULL,
|
||||||
|
"DIALOG_COLOR" VARCHAR DEFAULT '0xFFFFFF' NOT NULL
|
||||||
|
);
|
||||||
|
ALTER TABLE "PUBLIC"."FRIEND" ADD CONSTRAINT "PUBLIC"."CONSTRAINT_7C" PRIMARY KEY("ID");
|
||||||
|
-- 3 +/- SELECT COUNT(*) FROM PUBLIC.FRIEND;
|
||||||
|
INSERT INTO "PUBLIC"."FRIEND" VALUES
|
||||||
|
('turtle', 'Turtle', 'Turtle', '10d2', TRUE, 'AA00DD'),
|
||||||
|
('neko', 'Neko', 'Neko', '14', TRUE, 'AA00DD'),
|
||||||
|
('grandma', 'Grandma', 'Grandma', '7', TRUE, 'DD00AA');
|
||||||
|
ALTER TABLE "PUBLIC"."ENEMY_DROP" ADD CONSTRAINT "PUBLIC"."CONSTRAINT_8A" FOREIGN KEY("ENEMY") REFERENCES "PUBLIC"."ENEMY"("ID") NOCHECK;
|
||||||
|
ALTER TABLE "PUBLIC"."ENEMY" ADD CONSTRAINT "PUBLIC"."CONSTRAINT_3F" FOREIGN KEY("MELEE_WEAPON") REFERENCES "PUBLIC"."MELEE_WEAPON"("ID") NOCHECK;
|
||||||
111
flake.lock
generated
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"base": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-utils": [
|
||||||
|
"flake-utils"
|
||||||
|
],
|
||||||
|
"gradle2nix": "gradle2nix",
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1752221128,
|
||||||
|
"narHash": "sha256-dFWsRVenkLOtbBx67JfAjVD5PyiKJY4TMCbXbf7bGT4=",
|
||||||
|
"ref": "refs/heads/master",
|
||||||
|
"rev": "41cc804cc3855553587eafd13597054d93097972",
|
||||||
|
"revCount": 600,
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://git.orleander.pl/bartek/base.git"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://git.orleander.pl/bartek/base.git"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"flake-utils": {
|
||||||
|
"inputs": {
|
||||||
|
"systems": "systems"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1731533236,
|
||||||
|
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"gradle2nix": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-utils": [
|
||||||
|
"base",
|
||||||
|
"flake-utils"
|
||||||
|
],
|
||||||
|
"nixpkgs": [
|
||||||
|
"base",
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1743629487,
|
||||||
|
"narHash": "sha256-MjnEgT9MhO2HknLhrx7GvBRVxdOzSKydIJMyzawe2Fk=",
|
||||||
|
"owner": "tadfisher",
|
||||||
|
"repo": "gradle2nix",
|
||||||
|
"rev": "293ecbdc10d32d9d4bdc2d23213b9be09ce247ee",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "tadfisher",
|
||||||
|
"ref": "v2",
|
||||||
|
"repo": "gradle2nix",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1751943650,
|
||||||
|
"narHash": "sha256-7orTnNqkGGru8Je6Un6mq1T8YVVU/O5kyW4+f9C1mZQ=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "88983d4b665fb491861005137ce2b11a9f89f203",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"id": "nixpkgs",
|
||||||
|
"ref": "nixos-25.05",
|
||||||
|
"type": "indirect"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"base": "base",
|
||||||
|
"flake-utils": "flake-utils",
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"systems": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1681028828,
|
||||||
|
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
||||||
30
flake.nix
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
{
|
||||||
|
description = "The BASE engine demo game";
|
||||||
|
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.url = "nixpkgs/nixos-25.05";
|
||||||
|
|
||||||
|
flake-utils.url = "github:numtide/flake-utils";
|
||||||
|
|
||||||
|
base.url = "git+https://git.orleander.pl/bartek/base.git";
|
||||||
|
base.inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
base.inputs.flake-utils.follows = "flake-utils";
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs = inputs @ {
|
||||||
|
self,
|
||||||
|
nixpkgs,
|
||||||
|
flake-utils,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
flake-utils.lib.eachDefaultSystem (system: let
|
||||||
|
pkgs = import nixpkgs {inherit system;};
|
||||||
|
in {
|
||||||
|
packages = rec {
|
||||||
|
game = pkgs.callPackage ./game.nix (inputs // {inherit system;});
|
||||||
|
default = game;
|
||||||
|
};
|
||||||
|
|
||||||
|
devShells.default = pkgs.callPackage ./shell.nix {inherit system;};
|
||||||
|
});
|
||||||
|
}
|
||||||
44
game.nix
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
base,
|
||||||
|
lib,
|
||||||
|
stdenv,
|
||||||
|
system,
|
||||||
|
makeWrapper,
|
||||||
|
jdk17,
|
||||||
|
xorg,
|
||||||
|
openjfx17,
|
||||||
|
glib,
|
||||||
|
alsa-lib,
|
||||||
|
libGL,
|
||||||
|
gtk3,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
stdenv.mkDerivation rec {
|
||||||
|
pname = "base-demo";
|
||||||
|
version = "0.0.1";
|
||||||
|
|
||||||
|
src = ./.;
|
||||||
|
|
||||||
|
nativeBuildInputs = [base.packages.${system}.default makeWrapper];
|
||||||
|
|
||||||
|
buildPhase = ''
|
||||||
|
base-editor -bHp $src/project.json -o build
|
||||||
|
'';
|
||||||
|
|
||||||
|
installPhase = ''
|
||||||
|
mkdir -p $out/bin
|
||||||
|
mkdir -p $out/share/java
|
||||||
|
|
||||||
|
cp build/out/game.jar $out/share/java/base-demo-game.jar
|
||||||
|
|
||||||
|
makeWrapper "${jdk17}/bin/java" $out/bin/base-demo \
|
||||||
|
--add-flags "-jar $out/share/java/base-demo-game.jar" \
|
||||||
|
--prefix LD_LIBRARY_PATH : "${xorg.libXtst}/lib" \
|
||||||
|
--prefix LD_LIBRARY_PATH : "${openjfx17}/lib" \
|
||||||
|
--prefix LD_LIBRARY_PATH : "${glib.out}/lib" \
|
||||||
|
--prefix LD_LIBRARY_PATH : "${alsa-lib}/lib" \
|
||||||
|
--prefix LD_LIBRARY_PATH : "${libGL}/lib" \
|
||||||
|
--prefix LD_LIBRARY_PATH : "${gtk3}/lib"
|
||||||
|
'';
|
||||||
|
}
|
||||||
BIN
iconsets/ddc1e14f-0d1f-4291-a29d-0dc5d8e9242b.png
Normal file
|
After Width: | Height: | Size: 197 KiB |
67
maps/8fbb151f-682a-4357-ba92-157e4097898f.json
Normal file
120
maps/b602601a-e9b0-44bf-bc0d-5f31c9964ba1.json
Normal file
140
maps/d1b85d85-c52a-46f5-b81e-444847f8ddae.json
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
{
|
||||||
|
"uid": "d1b85d85-c52a-46f5-b81e-444847f8ddae",
|
||||||
|
"rows": 17,
|
||||||
|
"columns": 20,
|
||||||
|
"tileWidth": 32,
|
||||||
|
"tileHeight": 32,
|
||||||
|
"layers": [{
|
||||||
|
"name": "All Lights",
|
||||||
|
"objectLayer": {
|
||||||
|
"passageMap": ["ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW"],
|
||||||
|
"objects": [{
|
||||||
|
"x": 6,
|
||||||
|
"y": 1,
|
||||||
|
"code": "/* \n * Following final parameters are available to use:\n * here: MapPin - the composite object containing current map UID, \n * layer\u0027s index and x,y coordinates of the current tile \n * x: int - the x coordinate of the current tile\n * y: int - the y coordinate of the current tile \n * layer: ObjectLayer - current object layer\n * map: GameMap - current map \n * handler: HeroHomeHandler - current map handler\n * runner: DemoRunner - the game runner of the project\n * context: Context - the game context\n */\ntorch(here);"
|
||||||
|
}, {
|
||||||
|
"x": 5,
|
||||||
|
"y": 7,
|
||||||
|
"code": "/* \n * Following final parameters are available to use:\n * here: MapPin - the composite object containing current map UID, \n * layer\u0027s index and x,y coordinates of the current tile \n * x: int - the x coordinate of the current tile\n * y: int - the y coordinate of the current tile \n * layer: ObjectLayer - current object layer\n * map: GameMap - current map \n * handler: HeroHomeHandler - current map handler\n * runner: DemoRunner - the game runner of the project\n * context: Context - the game context\n */\ntorch(here);"
|
||||||
|
}, {
|
||||||
|
"x": 13,
|
||||||
|
"y": 12,
|
||||||
|
"code": "/* \n * Following final parameters are available to use:\n * here: MapPin - the composite object containing current map UID, \n * layer\u0027s index and x,y coordinates of the current tile \n * x: int - the x coordinate of the current tile\n * y: int - the y coordinate of the current tile \n * layer: ObjectLayer - current object layer\n * map: GameMap - current map \n * handler: HeroHomeHandler - current map handler\n * runner: DemoRunner - the game runner of the project\n * context: Context - the game context\n */\ntorch(here);"
|
||||||
|
}, {
|
||||||
|
"x": 17,
|
||||||
|
"y": 7,
|
||||||
|
"code": "/* \n * Following final parameters are available to use:\n * here: MapPin - the composite object containing current map UID, \n * layer\u0027s index and x,y coordinates of the current tile \n * x: int - the x coordinate of the current tile\n * y: int - the y coordinate of the current tile \n * layer: ObjectLayer - current object layer\n * map: GameMap - current map \n * handler: HeroHomeHandler - current map handler\n * runner: DemoRunner - the game runner of the project\n * context: Context - the game context\n */\ntorch(here);"
|
||||||
|
}, {
|
||||||
|
"x": 15,
|
||||||
|
"y": 7,
|
||||||
|
"code": "/* \n * Following final parameters are available to use:\n * here: MapPin - the composite object containing current map UID, \n * layer\u0027s index and x,y coordinates of the current tile \n * x: int - the x coordinate of the current tile\n * y: int - the y coordinate of the current tile \n * layer: ObjectLayer - current object layer\n * map: GameMap - current map \n * handler: HeroHomeHandler - current map handler\n * runner: DemoRunner - the game runner of the project\n * context: Context - the game context\n */\ntorch(here);"
|
||||||
|
}, {
|
||||||
|
"x": 10,
|
||||||
|
"y": 2,
|
||||||
|
"code": "/* \n * Following final parameters are available to use:\n * here: MapPin - the composite object containing current map UID, \n * layer\u0027s index and x,y coordinates of the current tile \n * x: int - the x coordinate of the current tile\n * y: int - the y coordinate of the current tile \n * layer: ObjectLayer - current object layer\n * map: GameMap - current map \n * handler: HeroHomeHandler - current map handler\n * runner: DemoRunner - the game runner of the project\n * context: Context - the game context\n */\nlight(here);"
|
||||||
|
}, {
|
||||||
|
"x": 11,
|
||||||
|
"y": 2,
|
||||||
|
"code": "/* \n * Following final parameters are available to use:\n * here: MapPin - the composite object containing current map UID, \n * layer\u0027s index and x,y coordinates of the current tile \n * x: int - the x coordinate of the current tile\n * y: int - the y coordinate of the current tile \n * layer: ObjectLayer - current object layer\n * map: GameMap - current map \n * handler: HeroHomeHandler - current map handler\n * runner: DemoRunner - the game runner of the project\n * context: Context - the game context\n */\ntorch(here);"
|
||||||
|
}, {
|
||||||
|
"x": 2,
|
||||||
|
"y": 1,
|
||||||
|
"code": "/* \n * Following final parameters are available to use:\n * here: MapPin - the composite object containing current map UID, \n * layer\u0027s index and x,y coordinates of the current tile \n * x: int - the x coordinate of the current tile\n * y: int - the y coordinate of the current tile \n * layer: ObjectLayer - current object layer\n * map: GameMap - current map \n * handler: HeroHomeHandler - current map handler\n * runner: DemoRunner - the game runner of the project\n * context: Context - the game context\n */\nvar light \u003d light(here);\nlight.setPositionOffset(0, 15f);"
|
||||||
|
}, {
|
||||||
|
"x": 5,
|
||||||
|
"y": 1,
|
||||||
|
"code": "/* \n * Following final parameters are available to use:\n * here: MapPin - the composite object containing current map UID, \n * layer\u0027s index and x,y coordinates of the current tile \n * x: int - the x coordinate of the current tile\n * y: int - the y coordinate of the current tile \n * layer: ObjectLayer - current object layer\n * map: GameMap - current map \n * handler: HeroHomeHandler - current map handler\n * runner: DemoRunner - the game runner of the project\n * context: Context - the game context\n */\nvar light \u003d light(here);\nlight.setPositionOffset(0, 15f);"
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
"name": "Floor",
|
||||||
|
"tileLayer": {
|
||||||
|
"tilesetUID": "eb5bbf17-efaa-4213-90c3-2785a32f3c37",
|
||||||
|
"tiles": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 33, 33, 33, 33, 33, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 33, 33, 33, 33, 33, 33, 0, 34, 34, 34, 34, 34, 0, 0, 0, 0, 0, 0, 0, 33, 33, 33, 33, 33, 33, 33, 0, 34, 34, 34, 34, 34, 0, 0, 0, 0, 0, 0, 0, 34, 34, 34, 0, 0, 0, 0, 0, 34, 34, 34, 34, 34, 0, 0, 0, 0, 0, 0, 0, 34, 34, 34, 0, 0, 0, 0, 0, 34, 34, 34, 34, 34, 0, 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, 0, 0, 0, 0, 34, 34, 34, 34, 34, 0, 0, 0, 0, 0, 0, 0, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 0, 0, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 0, 0, 0, 0, 34, 0, 0, 0, 0, 0, 34, 0, 0, 0, 34, 34, 34, 34, 34, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
"name": "Carpets",
|
||||||
|
"autoTileLayer": {
|
||||||
|
"autotileUID": "f6bcd0ea-f293-4864-bd13-d1c4e8b79080",
|
||||||
|
"tiles": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||||
|
"animated": false,
|
||||||
|
"animationDuration": 1.0,
|
||||||
|
"connect": false
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
"name": "Walls",
|
||||||
|
"autoTileLayer": {
|
||||||
|
"autotileUID": "b475367a-7bf8-44ee-b916-6e81a78f97d9",
|
||||||
|
"tiles": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 10, 10, 0, 10, 10, 10, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 10, 10, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 0, 0, 0, 10, 10, 10, 10, 10, 10, 10, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||||
|
"animated": false,
|
||||||
|
"animationDuration": 1.0,
|
||||||
|
"connect": false
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
"name": "Floor objects",
|
||||||
|
"tileLayer": {
|
||||||
|
"tilesetUID": "60362451-85ed-4bbe-8ac1-225056f48b40",
|
||||||
|
"tiles": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 37, 52, 162, 163, 52, 215, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 168, 68, 178, 179, 68, 10, 10, 0, 0, 81, 215, 141, 0, 0, 0, 0, 0, 0, 0, 0, 184, 147, 194, 195, 148, 26, 26, 0, 38, 6, 8, 45, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 132, 132, 0, 0, 0, 0, 23, 22, 24, 61, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 145, 212, 145, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0, 145, 244, 145, 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 142, 215, 0, 0, 0, 0, 0, 0, 0, 167, 0, 215, 126, 215, 0, 0, 0, 0, 12, 11, 13, 14, 13, 0, 170, 0, 0, 0, 0, 183, 0, 0, 0, 0, 168, 0, 0, 0, 28, 27, 29, 29, 29, 0, 186, 0, 0, 0, 0, 0, 0, 0, 0, 0, 184, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 139, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 155, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 157, 0, 32, 215, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 0, 0, 77, 0, 0, 0, 0, 153, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 140, 58, 0, 0, 93, 0, 0, 0, 0, 137, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
"name": "Main",
|
||||||
|
"objectLayer": {
|
||||||
|
"passageMap": ["ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "BLOCK", "ALLOW", "ALLOW", "BLOCK", "BLOCK", "ALLOW", "ALLOW", "ALLOW", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "BLOCK", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "BLOCK", "ALLOW", "ALLOW", "BLOCK", "ALLOW", "ALLOW", "BLOCK", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "BLOCK", "ALLOW", "BLOCK", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "BLOCK", "BLOCK", "ALLOW", "ALLOW", "BLOCK", "ALLOW", "ALLOW", "BLOCK", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "BLOCK", "ALLOW", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "ALLOW", "BLOCK", "ALLOW", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "ALLOW", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "ALLOW", "BLOCK", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "BLOCK", "BLOCK", "BLOCK", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "BLOCK", "ALLOW", "ALLOW", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "ALLOW", "ALLOW", "ALLOW", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "ALLOW", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "BLOCK", "ALLOW", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "ALLOW", "ALLOW", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "BLOCK", "ALLOW", "ALLOW", "ALLOW", "BLOCK", "BLOCK", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "BLOCK", "BLOCK", "ALLOW", "ALLOW", "ALLOW", "BLOCK", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "BLOCK", "BLOCK", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "BLOCK", "ALLOW", "BLOCK", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "BLOCK", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "BLOCK", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "ALLOW", "BLOCK"],
|
||||||
|
"objects": [{
|
||||||
|
"x": 3,
|
||||||
|
"y": 12,
|
||||||
|
"code": "/* \n * Following final parameters are available to use:\n * x: int - the x coordinate of tile the object has been created on\n * y: int - the y coordinate of tile the object has been created on \n * layer: ObjectLayer - current object layer\n * map: GameMap - current map\n */\nwarp(here, A.maps.hero_house.main.home);"
|
||||||
|
}, {
|
||||||
|
"x": 5,
|
||||||
|
"y": 4,
|
||||||
|
"code": "/* \n * Following final parameters are available to use:\n * here: MapPin - the composite object containing current map UID, \n * layer\u0027s index and x,y coordinates of the current tile \n * x: int - the x coordinate of the current tile\n * y: int - the y coordinate of the current tile \n * layer: ObjectLayer - current object layer\n * map: GameMap - current map\n */\nfriend(here, \"neko\")\n\t.randomMovementAI(4f)\n\t.interaction(this::triggerNekoDialog);"
|
||||||
|
}, {
|
||||||
|
"x": 7,
|
||||||
|
"y": 9,
|
||||||
|
"code": "/* \n * Following final parameters are available to use:\n * x: int - the x coordinate of tile the object has been created on\n * y: int - the y coordinate of tile the object has been created on \n * layer: ObjectLayer - current object layer\n * map: GameMap - current map\n * handler: HeroHomeHandler - current map handler\n * runner: DemoRunner - the game runner of the project\n * context: Context - the game context\n */\nchest(here, \"plain_chest_down\")\n\t.addItem(new MeleeWeapon(\"wooden_sword\"))\n\t.addItem(new Medicament(\"small_life_potion\", 4))\n\t.shuffle();"
|
||||||
|
}, {
|
||||||
|
"x": 18,
|
||||||
|
"y": 12,
|
||||||
|
"code": "/* \n * Following final parameters are available to use:\n * here: MapPin - the composite object containing current map UID, \n * layer\u0027s index and x,y coordinates of the current tile \n * x: int - the x coordinate of the current tile\n * y: int - the y coordinate of the current tile \n * layer: ObjectLayer - current object layer\n * map: GameMap - current map \n * handler: HeroHomeHandler - current map handler\n * runner: DemoRunner - the game runner of the project\n * context: Context - the game context\n */\nchest(here, \"enforced_chest_left\")\n\t.addItem(new MeleeWeapon(\"wooden_sword\"))\n\t.addItem(new Medicament(\"small_life_potion\", 4))\n\t.shuffle();"
|
||||||
|
}, {
|
||||||
|
"x": 13,
|
||||||
|
"y": 15,
|
||||||
|
"code": "/* \n * Following final parameters are available to use:\n * here: MapPin - the composite object containing current map UID, \n * layer\u0027s index and x,y coordinates of the current tile \n * x: int - the x coordinate of the current tile\n * y: int - the y coordinate of the current tile \n * layer: ObjectLayer - current object layer\n * map: GameMap - current map\n */\nfriend(here, \"grandma\")\n\t.followPath(this::grandmaPath)\n\t.interaction(this::triggerGrandmaDialog);"
|
||||||
|
}],
|
||||||
|
"labels": [{
|
||||||
|
"label": "entry",
|
||||||
|
"x": 3,
|
||||||
|
"y": 11
|
||||||
|
}, {
|
||||||
|
"label": "Start",
|
||||||
|
"x": 10,
|
||||||
|
"y": 14
|
||||||
|
}, {
|
||||||
|
"label": "Grandma Waking",
|
||||||
|
"x": 11,
|
||||||
|
"y": 14
|
||||||
|
}, {
|
||||||
|
"label": "Grandma Origin",
|
||||||
|
"x": 11,
|
||||||
|
"y": 7
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
"name": "Objects above",
|
||||||
|
"tileLayer": {
|
||||||
|
"tilesetUID": "60362451-85ed-4bbe-8ac1-225056f48b40",
|
||||||
|
"tiles": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 168, 0, 0, 0, 0, 168, 0, 0, 0, 173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 202, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, 0, 0, 13, 0, 0, 13, 13, 168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
"name": "Ceiling",
|
||||||
|
"autoTileLayer": {
|
||||||
|
"autotileUID": "6584a279-e937-497e-a056-b1e77bff2439",
|
||||||
|
"tiles": [10, 10, 10, 10, 10, 10, 10, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 10, 10, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 10, 0, 10, 10, 10, 10, 10, 10, 10, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 10, 10, 10, 10, 0, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 0, 0, 0, 0, 10, 0, 0, 10, 10, 10, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10],
|
||||||
|
"animated": false,
|
||||||
|
"animationDuration": 1.0,
|
||||||
|
"connect": false
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
"handler": "com.bartlomiejpluta.demo.map.HeroHomeHandler",
|
||||||
|
"javaImports": "import com.bartlomiejpluta.demo.world.weapon.*;\nimport com.bartlomiejpluta.demo.world.potion.*;\nimport com.bartlomiejpluta.base.lib.animation.*;"
|
||||||
|
}
|
||||||
29
project.bep
@@ -1,29 +0,0 @@
|
|||||||
|
|
||||||
BASE Demo*com.bartlomiejpluta.demo.runner.DemoRunner`
|
|
||||||
$f845355e-b9ad-4884-a217-dd3a4c18a3fa(f845355e-b9ad-4884-a217-dd3a4c18a3fa.datForrest Temple"d
|
|
||||||
$d314b030-f865-432e-a356-3845f8aac7bc(d314b030-f865-432e-a356-3845f8aac7bc.pngForrest Temple ](2Z
|
|
||||||
$815a5c5c-4979-42f5-a42a-ccbbff9a97e5(815a5c5c-4979-42f5-a42a-ccbbff9a97e5.pngLuna (2Z
|
|
||||||
$cb4c89a7-a421-49ea-8c58-571e9b215d37(cb4c89a7-a421-49ea-8c58-571e9b215d37.pngDeku (2\
|
|
||||||
$9da2c95b-45b7-49e5-957b-c1c8803cdf28(9da2c95b-45b7-49e5-957b-c1c8803cdf28.pngCorpse (2Z
|
|
||||||
$4fff029b-6c24-4c83-9dfb-51f5512a687e(4fff029b-6c24-4c83-9dfb-51f5512a687e.pngGaro (2\
|
|
||||||
$71414ffb-0e1c-4778-9a1a-0f9f53388fd0(71414ffb-0e1c-4778-9a1a-0f9f53388fd0.pngBlanca (2\
|
|
||||||
$a5c6c6eb-e6cf-4b9e-8c35-11e4c8587ce7(a5c6c6eb-e6cf-4b9e-8c35-11e4c8587ce7.pngTurtle (2\
|
|
||||||
$15415d5a-2f53-4ee0-8f8f-8e81d702ccdb(15415d5a-2f53-4ee0-8f8f-8e81d702ccdb.pngChests (2[
|
|
||||||
$a1d5baf4-d5e8-4be9-ba7b-b37ca81b59fb(a1d5baf4-d5e8-4be9-ba7b-b37ca81b59fb.pngEagle (2`
|
|
||||||
$a973f4ec-a7ad-4fd7-8002-b50a854fb733(a973f4ec-a7ad-4fd7-8002-b50a854fb733.png
|
|
||||||
Silver Bat (2^
|
|
||||||
$55a8c74b-e636-4c0a-9787-1878e672e368(55a8c74b-e636-4c0a-9787-1878e672e368.pngSkeleton (:`
|
|
||||||
$2261c04f-b02e-4486-b388-8a0fa41622e9(2261c04f-b02e-4486-b388-8a0fa41622e9.ttfRoboto RegularB\
|
|
||||||
$ab9d40b4-eb28-45d7-bff2-9432a05eb41a(ab9d40b4-eb28-45d7-bff2-9432a05eb41a.xml
|
|
||||||
Start MenuB[
|
|
||||||
$56ca6b39-f949-4212-9c23-312db25887e0(56ca6b39-f949-4212-9c23-312db25887e0.xml Game MenuBU
|
|
||||||
$00bd0625-b3b8-4abf-97b7-91f42bce28ec(00bd0625-b3b8-4abf-97b7-91f42bce28ec.xmlHUDJ[
|
|
||||||
$61e67e44-a0cd-4210-8d1e-ccddcd62c78d(61e67e44-a0cd-4210-8d1e-ccddcd62c78d.pngSlash (JZ
|
|
||||||
$e6f067f1-eba0-4e62-99c3-2fd867e6f142(e6f067f1-eba0-4e62-99c3-2fd867e6f142.pngPoof (J[
|
|
||||||
$312cc4e6-8c44-43e7-828a-e7e2a77836f3(312cc4e6-8c44-43e7-828a-e7e2a77836f3.pngArrow (J[
|
|
||||||
$54f657bd-8108-464c-9bbe-63944fc14f6b(54f657bd-8108-464c-9bbe-63944fc14f6b.pngPunch (R]
|
|
||||||
$1311327d-4b74-4252-94da-23ee4129e357(1311327d-4b74-4252-94da-23ee4129e357.oggSword slashR\
|
|
||||||
$e452e215-f581-40fe-a5cf-f555d3db83b8(e452e215-f581-40fe-a5cf-f555d3db83b8.ogg
|
|
||||||
Deku deathRW
|
|
||||||
$cd8a40f2-1e2e-4e1d-a13f-b4fe210a04df(cd8a40f2-1e2e-4e1d-a13f-b4fe210a04df.oggArrowR]
|
|
||||||
$7c33cfee-e6a8-42b8-8b1d-c801b242dcf0(7c33cfee-e6a8-42b8-8b1d-c801b242dcf0.oggArrow punch
|
|
||||||
287
project.json
Normal file
@@ -0,0 +1,287 @@
|
|||||||
|
{
|
||||||
|
"name": "BASE Demo",
|
||||||
|
"runner": "com.bartlomiejpluta.demo.runner.DemoRunner",
|
||||||
|
"maps": [{
|
||||||
|
"uid": "d1b85d85-c52a-46f5-b81e-444847f8ddae",
|
||||||
|
"source": "d1b85d85-c52a-46f5-b81e-444847f8ddae.dat",
|
||||||
|
"name": "Hero Home"
|
||||||
|
}, {
|
||||||
|
"uid": "b602601a-e9b0-44bf-bc0d-5f31c9964ba1",
|
||||||
|
"source": "b602601a-e9b0-44bf-bc0d-5f31c9964ba1.dat",
|
||||||
|
"name": "Hero House"
|
||||||
|
}, {
|
||||||
|
"uid": "8fbb151f-682a-4357-ba92-157e4097898f",
|
||||||
|
"source": "8fbb151f-682a-4357-ba92-157e4097898f.dat",
|
||||||
|
"name": "Forrest"
|
||||||
|
}],
|
||||||
|
"tileSets": [{
|
||||||
|
"uid": "eb5bbf17-efaa-4213-90c3-2785a32f3c37",
|
||||||
|
"source": "eb5bbf17-efaa-4213-90c3-2785a32f3c37.png",
|
||||||
|
"name": "FSM 1",
|
||||||
|
"rows": 16,
|
||||||
|
"columns": 8
|
||||||
|
}, {
|
||||||
|
"uid": "bf5a8b2c-4635-4433-8781-d8fed02c7197",
|
||||||
|
"source": "bf5a8b2c-4635-4433-8781-d8fed02c7197.png",
|
||||||
|
"name": "FSM 2",
|
||||||
|
"rows": 16,
|
||||||
|
"columns": 16
|
||||||
|
}, {
|
||||||
|
"uid": "fa940a9c-aa18-4037-9c20-ca660182d5f4",
|
||||||
|
"source": "fa940a9c-aa18-4037-9c20-ca660182d5f4.png",
|
||||||
|
"name": "FSM 3",
|
||||||
|
"rows": 16,
|
||||||
|
"columns": 16
|
||||||
|
}, {
|
||||||
|
"uid": "60362451-85ed-4bbe-8ac1-225056f48b40",
|
||||||
|
"source": "60362451-85ed-4bbe-8ac1-225056f48b40.png",
|
||||||
|
"name": "FSM 4",
|
||||||
|
"rows": 16,
|
||||||
|
"columns": 16
|
||||||
|
}, {
|
||||||
|
"uid": "6d5672b0-64e6-48a7-8b48-bf73d37ca7d2",
|
||||||
|
"source": "6d5672b0-64e6-48a7-8b48-bf73d37ca7d2.png",
|
||||||
|
"name": "FSM 5",
|
||||||
|
"rows": 16,
|
||||||
|
"columns": 16
|
||||||
|
}, {
|
||||||
|
"uid": "413e09cf-ba41-4fe8-ac47-9697b5ad0245",
|
||||||
|
"source": "413e09cf-ba41-4fe8-ac47-9697b5ad0245.png",
|
||||||
|
"name": "Forrest",
|
||||||
|
"rows": 35,
|
||||||
|
"columns": 16
|
||||||
|
}],
|
||||||
|
"characterSets": [{
|
||||||
|
"uid": "0dcbaf26-d634-4ca8-9691-7a8ff966f702",
|
||||||
|
"source": "0dcbaf26-d634-4ca8-9691-7a8ff966f702.png",
|
||||||
|
"name": "Garo",
|
||||||
|
"rows": 4,
|
||||||
|
"columns": 4
|
||||||
|
}, {
|
||||||
|
"uid": "61393836-8127-4277-853f-87b48022ae43",
|
||||||
|
"source": "61393836-8127-4277-853f-87b48022ae43.png",
|
||||||
|
"name": "Corpse",
|
||||||
|
"rows": 4,
|
||||||
|
"columns": 4
|
||||||
|
}, {
|
||||||
|
"uid": "e605b2b1-3cab-499f-882d-160ab65b49d8",
|
||||||
|
"source": "e605b2b1-3cab-499f-882d-160ab65b49d8.png",
|
||||||
|
"name": "Skeleton",
|
||||||
|
"rows": 4,
|
||||||
|
"columns": 4
|
||||||
|
}, {
|
||||||
|
"uid": "0ea0fe55-53b2-4eea-8fab-2011e694127b",
|
||||||
|
"source": "0ea0fe55-53b2-4eea-8fab-2011e694127b.png",
|
||||||
|
"name": "Luna",
|
||||||
|
"rows": 4,
|
||||||
|
"columns": 4
|
||||||
|
}, {
|
||||||
|
"uid": "92ac46ff-8cf2-4748-907f-873030c8e378",
|
||||||
|
"source": "92ac46ff-8cf2-4748-907f-873030c8e378.png",
|
||||||
|
"name": "Chests2",
|
||||||
|
"rows": 4,
|
||||||
|
"columns": 4
|
||||||
|
}, {
|
||||||
|
"uid": "fbea4628-e1d3-4acc-800a-ed54c1bb51b6",
|
||||||
|
"source": "fbea4628-e1d3-4acc-800a-ed54c1bb51b6.png",
|
||||||
|
"name": "Blanca",
|
||||||
|
"rows": 4,
|
||||||
|
"columns": 4
|
||||||
|
}, {
|
||||||
|
"uid": "7a723b64-e54a-4fff-852d-108349133111",
|
||||||
|
"source": "7a723b64-e54a-4fff-852d-108349133111.png",
|
||||||
|
"name": "Eagle2",
|
||||||
|
"rows": 4,
|
||||||
|
"columns": 4
|
||||||
|
}, {
|
||||||
|
"uid": "c7ec2341-e5fc-4285-9ecb-a2dfc8a0ed67",
|
||||||
|
"source": "c7ec2341-e5fc-4285-9ecb-a2dfc8a0ed67.png",
|
||||||
|
"name": "Turtle",
|
||||||
|
"rows": 4,
|
||||||
|
"columns": 4
|
||||||
|
}, {
|
||||||
|
"uid": "f1113db3-4a6c-4a07-9b64-32ba8e653e4f",
|
||||||
|
"source": "f1113db3-4a6c-4a07-9b64-32ba8e653e4f.png",
|
||||||
|
"name": "Silver Bat",
|
||||||
|
"rows": 4,
|
||||||
|
"columns": 4
|
||||||
|
}, {
|
||||||
|
"uid": "1779ae2b-474a-4599-8fc3-be34f7d66965",
|
||||||
|
"source": "1779ae2b-474a-4599-8fc3-be34f7d66965.png",
|
||||||
|
"name": "Deku",
|
||||||
|
"rows": 4,
|
||||||
|
"columns": 4
|
||||||
|
}, {
|
||||||
|
"uid": "a6863639-d563-4d88-af8e-c6d087ee2ffb",
|
||||||
|
"source": "a6863639-d563-4d88-af8e-c6d087ee2ffb.png",
|
||||||
|
"name": "FSM Doors",
|
||||||
|
"rows": 4,
|
||||||
|
"columns": 4
|
||||||
|
}, {
|
||||||
|
"uid": "35f770a6-5d94-4ddf-a132-dc3788a3adaf",
|
||||||
|
"source": "35f770a6-5d94-4ddf-a132-dc3788a3adaf.png",
|
||||||
|
"name": "Neko",
|
||||||
|
"rows": 4,
|
||||||
|
"columns": 4
|
||||||
|
}, {
|
||||||
|
"uid": "4a636044-2dbd-4ef3-8bdf-b63501c85ae3",
|
||||||
|
"source": "4a636044-2dbd-4ef3-8bdf-b63501c85ae3.png",
|
||||||
|
"name": "Grandma",
|
||||||
|
"rows": 4,
|
||||||
|
"columns": 4
|
||||||
|
}, {
|
||||||
|
"uid": "f529cbfc-c29d-470b-8804-e50d6a1efc98",
|
||||||
|
"source": "f529cbfc-c29d-470b-8804-e50d6a1efc98.png",
|
||||||
|
"name": "Chests",
|
||||||
|
"rows": 4,
|
||||||
|
"columns": 16
|
||||||
|
}],
|
||||||
|
"fonts": [{
|
||||||
|
"uid": "2261c04f-b02e-4486-b388-8a0fa41622e9",
|
||||||
|
"source": "2261c04f-b02e-4486-b388-8a0fa41622e9.ttf",
|
||||||
|
"name": "Roboto Regular"
|
||||||
|
}],
|
||||||
|
"widgets": [{
|
||||||
|
"uid": "ab9d40b4-eb28-45d7-bff2-9432a05eb41a",
|
||||||
|
"source": "ab9d40b4-eb28-45d7-bff2-9432a05eb41a.xml",
|
||||||
|
"name": "Start Menu"
|
||||||
|
}, {
|
||||||
|
"uid": "56ca6b39-f949-4212-9c23-312db25887e0",
|
||||||
|
"source": "56ca6b39-f949-4212-9c23-312db25887e0.xml",
|
||||||
|
"name": "Game Menu"
|
||||||
|
}, {
|
||||||
|
"uid": "00bd0625-b3b8-4abf-97b7-91f42bce28ec",
|
||||||
|
"source": "00bd0625-b3b8-4abf-97b7-91f42bce28ec.xml",
|
||||||
|
"name": "HUD"
|
||||||
|
}, {
|
||||||
|
"uid": "c473a91a-ff25-4e71-9bec-b35e48102aeb",
|
||||||
|
"source": "c473a91a-ff25-4e71-9bec-b35e48102aeb.xml",
|
||||||
|
"name": "Equipment"
|
||||||
|
}, {
|
||||||
|
"uid": "53ca3e54-0f8d-44fa-8281-acd9c5bba743",
|
||||||
|
"source": "53ca3e54-0f8d-44fa-8281-acd9c5bba743.xml",
|
||||||
|
"name": "Eq Item Menu"
|
||||||
|
}, {
|
||||||
|
"uid": "d78413cd-0dad-4b51-8dd1-54e33535fe53",
|
||||||
|
"source": "d78413cd-0dad-4b51-8dd1-54e33535fe53.xml",
|
||||||
|
"name": "Loot Menu"
|
||||||
|
}, {
|
||||||
|
"uid": "1c2b2ba2-66bf-40ee-97bf-6e5065b7b420",
|
||||||
|
"source": "1c2b2ba2-66bf-40ee-97bf-6e5065b7b420.xml",
|
||||||
|
"name": "Dialog"
|
||||||
|
}, {
|
||||||
|
"uid": "5a5aea0a-8c8b-4730-8e45-9ec6ccc5c4f6",
|
||||||
|
"source": "5a5aea0a-8c8b-4730-8e45-9ec6ccc5c4f6.xml",
|
||||||
|
"name": "Dialog Choice"
|
||||||
|
}],
|
||||||
|
"animations": [{
|
||||||
|
"uid": "e6f067f1-eba0-4e62-99c3-2fd867e6f142",
|
||||||
|
"source": "e6f067f1-eba0-4e62-99c3-2fd867e6f142.png",
|
||||||
|
"name": "Poof",
|
||||||
|
"rows": 4,
|
||||||
|
"columns": 5
|
||||||
|
}, {
|
||||||
|
"uid": "312cc4e6-8c44-43e7-828a-e7e2a77836f3",
|
||||||
|
"source": "312cc4e6-8c44-43e7-828a-e7e2a77836f3.png",
|
||||||
|
"name": "Arrow",
|
||||||
|
"rows": 2,
|
||||||
|
"columns": 2
|
||||||
|
}, {
|
||||||
|
"uid": "54f657bd-8108-464c-9bbe-63944fc14f6b",
|
||||||
|
"source": "54f657bd-8108-464c-9bbe-63944fc14f6b.png",
|
||||||
|
"name": "Punch",
|
||||||
|
"rows": 3,
|
||||||
|
"columns": 5
|
||||||
|
}, {
|
||||||
|
"uid": "0ddac391-4086-4e9c-8310-59db649419ff",
|
||||||
|
"source": "0ddac391-4086-4e9c-8310-59db649419ff.png",
|
||||||
|
"name": "Slash",
|
||||||
|
"rows": 2,
|
||||||
|
"columns": 5
|
||||||
|
}, {
|
||||||
|
"uid": "c8883e76-ae93-4673-8893-d2ec72c1e199",
|
||||||
|
"source": "c8883e76-ae93-4673-8893-d2ec72c1e199.png",
|
||||||
|
"name": "Shuriken",
|
||||||
|
"rows": 2,
|
||||||
|
"columns": 3
|
||||||
|
}, {
|
||||||
|
"uid": "aeb17449-c342-4dab-9057-5fb05183fd03",
|
||||||
|
"source": "aeb17449-c342-4dab-9057-5fb05183fd03.png",
|
||||||
|
"name": "Heart Emoji",
|
||||||
|
"rows": 6,
|
||||||
|
"columns": 4
|
||||||
|
}, {
|
||||||
|
"uid": "78563669-8a6c-4024-82c8-7e4da5b76edd",
|
||||||
|
"source": "78563669-8a6c-4024-82c8-7e4da5b76edd.png",
|
||||||
|
"name": "Zzz",
|
||||||
|
"rows": 7,
|
||||||
|
"columns": 4
|
||||||
|
}],
|
||||||
|
"sounds": [{
|
||||||
|
"uid": "1311327d-4b74-4252-94da-23ee4129e357",
|
||||||
|
"source": "1311327d-4b74-4252-94da-23ee4129e357.ogg",
|
||||||
|
"name": "Sword slash"
|
||||||
|
}, {
|
||||||
|
"uid": "e452e215-f581-40fe-a5cf-f555d3db83b8",
|
||||||
|
"source": "e452e215-f581-40fe-a5cf-f555d3db83b8.ogg",
|
||||||
|
"name": "Deku death"
|
||||||
|
}, {
|
||||||
|
"uid": "cd8a40f2-1e2e-4e1d-a13f-b4fe210a04df",
|
||||||
|
"source": "cd8a40f2-1e2e-4e1d-a13f-b4fe210a04df.ogg",
|
||||||
|
"name": "Arrow"
|
||||||
|
}, {
|
||||||
|
"uid": "7c33cfee-e6a8-42b8-8b1d-c801b242dcf0",
|
||||||
|
"source": "7c33cfee-e6a8-42b8-8b1d-c801b242dcf0.ogg",
|
||||||
|
"name": "Arrow punch"
|
||||||
|
}],
|
||||||
|
"iconSets": [{
|
||||||
|
"uid": "ddc1e14f-0d1f-4291-a29d-0dc5d8e9242b",
|
||||||
|
"source": "ddc1e14f-0d1f-4291-a29d-0dc5d8e9242b.png",
|
||||||
|
"name": "Generic",
|
||||||
|
"rows": 35,
|
||||||
|
"columns": 12
|
||||||
|
}],
|
||||||
|
"autoTiles": [{
|
||||||
|
"uid": "f6bcd0ea-f293-4864-bd13-d1c4e8b79080",
|
||||||
|
"source": "f6bcd0ea-f293-4864-bd13-d1c4e8b79080.png",
|
||||||
|
"name": "FSM 1",
|
||||||
|
"rows": 4,
|
||||||
|
"columns": 8,
|
||||||
|
"layout": "LAYOUT_2X3"
|
||||||
|
}, {
|
||||||
|
"uid": "88042125-4c6d-4dfa-ad1d-8e78b6df9ee9",
|
||||||
|
"source": "88042125-4c6d-4dfa-ad1d-8e78b6df9ee9.png",
|
||||||
|
"name": "FSM 2",
|
||||||
|
"rows": 4,
|
||||||
|
"columns": 8,
|
||||||
|
"layout": "LAYOUT_2X2"
|
||||||
|
}, {
|
||||||
|
"uid": "6584a279-e937-497e-a056-b1e77bff2439",
|
||||||
|
"source": "6584a279-e937-497e-a056-b1e77bff2439.png",
|
||||||
|
"name": "FSM 3",
|
||||||
|
"rows": 3,
|
||||||
|
"columns": 8,
|
||||||
|
"layout": "LAYOUT_2X3"
|
||||||
|
}, {
|
||||||
|
"uid": "b475367a-7bf8-44ee-b916-6e81a78f97d9",
|
||||||
|
"source": "b475367a-7bf8-44ee-b916-6e81a78f97d9.png",
|
||||||
|
"name": "FSM 4",
|
||||||
|
"rows": 3,
|
||||||
|
"columns": 8,
|
||||||
|
"layout": "LAYOUT_2X2"
|
||||||
|
}, {
|
||||||
|
"uid": "04ac5ad8-4100-4016-97b3-a51a728ca49d",
|
||||||
|
"source": "04ac5ad8-4100-4016-97b3-a51a728ca49d.png",
|
||||||
|
"name": "Candacis Spring 1",
|
||||||
|
"rows": 3,
|
||||||
|
"columns": 2,
|
||||||
|
"layout": "LAYOUT_2X3"
|
||||||
|
}, {
|
||||||
|
"uid": "fc294b9e-105a-4120-8caa-393d78fdf414",
|
||||||
|
"source": "fc294b9e-105a-4120-8caa-393d78fdf414.png",
|
||||||
|
"name": "Candacis Spring 2",
|
||||||
|
"rows": 1,
|
||||||
|
"columns": 3,
|
||||||
|
"layout": "LAYOUT_2X3"
|
||||||
|
}]
|
||||||
|
}
|
||||||
6
shell.nix
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{pkgs, ...}:
|
||||||
|
pkgs.mkShell {
|
||||||
|
name = "base-demo-game-development-shell";
|
||||||
|
|
||||||
|
LD_LIBRARY_PATH = with pkgs; "${xorg.libXtst}/lib:${openjfx17}/lib:${glib.out}/lib:${alsa-lib}/lib:${libGL}/lib:${gtk3}/lib";
|
||||||
|
}
|
||||||
@@ -1,38 +1,36 @@
|
|||||||
package com.bartlomiejpluta.demo.ai;
|
package com.bartlomiejpluta.demo.ai;
|
||||||
|
|
||||||
import lombok.*;
|
import com.bartlomiejpluta.base.api.ai.AI;
|
||||||
import com.bartlomiejpluta.base.api.map.layer.object.ObjectLayer;
|
import com.bartlomiejpluta.base.api.map.layer.object.ObjectLayer;
|
||||||
import com.bartlomiejpluta.base.api.ai.*;
|
import com.bartlomiejpluta.base.lib.ai.RandomMovementAI;
|
||||||
import com.bartlomiejpluta.base.api.move.Direction;
|
import com.bartlomiejpluta.base.lib.ai.RunawayAI;
|
||||||
import com.bartlomiejpluta.base.lib.ai.*;
|
import com.bartlomiejpluta.demo.entity.Creature;
|
||||||
|
|
||||||
import com.bartlomiejpluta.demo.entity.Enemy;
|
import com.bartlomiejpluta.demo.entity.Enemy;
|
||||||
import com.bartlomiejpluta.demo.entity.Character;
|
|
||||||
|
|
||||||
public class AnimalAI implements AI {
|
public class AnimalAI implements AI {
|
||||||
private final Enemy animal;
|
private final Enemy animal;
|
||||||
private final Character character;
|
private final Creature creature;
|
||||||
private final int range;
|
private final int range;
|
||||||
private final AI idleAI;
|
private final AI idleAI;
|
||||||
private final AI runawayAI;
|
private final AI runawayAI;
|
||||||
|
|
||||||
public AnimalAI(Enemy animal, Character character, int range) {
|
public AnimalAI(Enemy animal, Creature creature, int range) {
|
||||||
this.animal = animal;
|
this.animal = animal;
|
||||||
this.character = character;
|
this.creature = creature;
|
||||||
this.range = range;
|
this.range = range;
|
||||||
this.idleAI = new RandomMovementAI<>(animal, 4);
|
this.idleAI = new RandomMovementAI<>(animal, 4);
|
||||||
this.runawayAI = new RunawayAI<>(animal, character);
|
this.runawayAI = new RunawayAI<>(animal, creature);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void nextActivity(ObjectLayer layer, float dt) {
|
public void nextActivity(ObjectLayer layer, float dt) {
|
||||||
if(animal.isMoving()) {
|
if (animal.isMoving()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var distance = animal.manhattanDistance(character);
|
var distance = animal.manhattanDistance(creature);
|
||||||
|
|
||||||
if(animal.getHp() < animal.getMaxHp() && distance < range) {
|
if (animal.getHp() < animal.getMaxHp() && distance < range) {
|
||||||
runawayAI.nextActivity(layer, dt);
|
runawayAI.nextActivity(layer, dt);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,53 +1,42 @@
|
|||||||
package com.bartlomiejpluta.demo.ai;
|
package com.bartlomiejpluta.demo.ai;
|
||||||
|
|
||||||
import com.bartlomiejpluta.base.api.ai.AI;
|
import com.bartlomiejpluta.base.api.ai.AI;
|
||||||
import com.bartlomiejpluta.base.api.ai.NPC;
|
|
||||||
import com.bartlomiejpluta.base.api.entity.Entity;
|
|
||||||
import com.bartlomiejpluta.base.api.map.layer.object.ObjectLayer;
|
import com.bartlomiejpluta.base.api.map.layer.object.ObjectLayer;
|
||||||
import com.bartlomiejpluta.base.api.move.MoveEvent;
|
|
||||||
import com.bartlomiejpluta.base.lib.ai.KeepStraightDistanceAI;
|
import com.bartlomiejpluta.base.lib.ai.KeepStraightDistanceAI;
|
||||||
import com.bartlomiejpluta.base.lib.ai.RandomMovementAI;
|
import com.bartlomiejpluta.base.lib.ai.RandomMovementAI;
|
||||||
import com.bartlomiejpluta.base.util.path.MovementPath;
|
|
||||||
import com.bartlomiejpluta.base.util.path.PathExecutor;
|
|
||||||
import com.bartlomiejpluta.base.util.pathfinder.AstarPathFinder;
|
import com.bartlomiejpluta.base.util.pathfinder.AstarPathFinder;
|
||||||
import com.bartlomiejpluta.base.util.pathfinder.PathFinder;
|
import com.bartlomiejpluta.demo.entity.Creature;
|
||||||
import lombok.NonNull;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import org.joml.Vector2i;
|
|
||||||
import org.joml.Vector2ic;
|
|
||||||
|
|
||||||
import com.bartlomiejpluta.demo.entity.Enemy;
|
import com.bartlomiejpluta.demo.entity.Enemy;
|
||||||
import com.bartlomiejpluta.demo.entity.Character;
|
|
||||||
|
|
||||||
public class ArcherAI extends KeepStraightDistanceAI<Enemy, Character> {
|
public class ArcherAI extends KeepStraightDistanceAI<Enemy, Creature> {
|
||||||
private static final int ASTAR_MAX_NODES = 100;
|
private static final int ASTAR_MAX_NODES = 100;
|
||||||
private static final int IDLE_MOVEMENT_INTERVAL = 4;
|
private static final int IDLE_MOVEMENT_INTERVAL = 4;
|
||||||
private final int range;
|
private final int range;
|
||||||
private final AI idle;
|
private final AI idle;
|
||||||
|
|
||||||
public ArcherAI(Enemy enemy, Character target, int minRange, int maxRange, int range) {
|
public ArcherAI(Enemy enemy, Creature target, int minRange, int maxRange, int range) {
|
||||||
super(new AstarPathFinder(ASTAR_MAX_NODES), enemy, target, minRange, maxRange);
|
super(new AstarPathFinder(ASTAR_MAX_NODES), enemy, target, minRange, maxRange);
|
||||||
this.range = range;
|
this.range = range;
|
||||||
this.idle = new RandomMovementAI<>(enemy, IDLE_MOVEMENT_INTERVAL);
|
this.idle = new RandomMovementAI<>(enemy, IDLE_MOVEMENT_INTERVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean sees(Enemy enemy, Character target, ObjectLayer layer) {
|
protected boolean sees(Enemy enemy, Creature target, ObjectLayer layer) {
|
||||||
return enemy.manhattanDistance(target) < range;
|
return enemy.manhattanDistance(target) < range;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void interact(Enemy enemy, Character target, ObjectLayer layer, float dt) {
|
protected void interact(Enemy enemy, Creature target, ObjectLayer layer, float dt) {
|
||||||
enemy.attack();
|
enemy.attack();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void follow(Enemy enemy, Character target, ObjectLayer layer, float dt) {
|
protected void follow(Enemy enemy, Creature target, ObjectLayer layer, float dt) {
|
||||||
// noop
|
// noop
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void idle(Enemy enemy, Character target, ObjectLayer layer, float dt) {
|
protected void idle(Enemy enemy, Creature target, ObjectLayer layer, float dt) {
|
||||||
idle.nextActivity(layer, dt);
|
idle.nextActivity(layer, dt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,43 +1,42 @@
|
|||||||
package com.bartlomiejpluta.demo.ai;
|
package com.bartlomiejpluta.demo.ai;
|
||||||
|
|
||||||
|
import com.bartlomiejpluta.base.api.ai.AI;
|
||||||
import com.bartlomiejpluta.base.api.map.layer.object.ObjectLayer;
|
import com.bartlomiejpluta.base.api.map.layer.object.ObjectLayer;
|
||||||
|
import com.bartlomiejpluta.base.lib.ai.FollowObjectAI;
|
||||||
import com.bartlomiejpluta.base.util.pathfinder.*;
|
import com.bartlomiejpluta.base.lib.ai.RandomMovementAI;
|
||||||
import com.bartlomiejpluta.base.api.ai.*;
|
import com.bartlomiejpluta.base.util.pathfinder.AstarPathFinder;
|
||||||
import com.bartlomiejpluta.base.lib.ai.*;
|
import com.bartlomiejpluta.demo.entity.Creature;
|
||||||
|
|
||||||
import com.bartlomiejpluta.demo.entity.Enemy;
|
import com.bartlomiejpluta.demo.entity.Enemy;
|
||||||
import com.bartlomiejpluta.demo.entity.Character;
|
|
||||||
|
|
||||||
public class SimpleEnemyAI extends FollowEntityAI<Enemy, Character> {
|
public class SimpleEnemyAI extends FollowObjectAI<Enemy, Creature> {
|
||||||
private static final int ASTAR_MAX_NODES = 100;
|
private static final int ASTAR_MAX_NODES = 100;
|
||||||
private static final int IDLE_MOVEMENT_INTERVAL = 4;
|
private static final int IDLE_MOVEMENT_INTERVAL = 4;
|
||||||
private final AI idle;
|
private final AI idle;
|
||||||
private final int range;
|
private final int range;
|
||||||
|
|
||||||
public SimpleEnemyAI(Enemy enemy, Character target, int range) {
|
public SimpleEnemyAI(Enemy enemy, Creature target, int range) {
|
||||||
super(new AstarPathFinder(ASTAR_MAX_NODES), enemy, target);
|
super(new AstarPathFinder(ASTAR_MAX_NODES), enemy, target);
|
||||||
this.range = range;
|
this.range = range;
|
||||||
this.idle = new RandomMovementAI<>(enemy, IDLE_MOVEMENT_INTERVAL);
|
this.idle = new RandomMovementAI<>(enemy, IDLE_MOVEMENT_INTERVAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean sees(Enemy enemy, Character target, ObjectLayer layer, int distance) {
|
protected boolean sees(Enemy enemy, Creature target, ObjectLayer layer, int distance) {
|
||||||
return distance < range;
|
return distance < range;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void interact(Enemy enemy, Character target, ObjectLayer layer, float dt) {
|
protected void interact(Enemy enemy, Creature target, ObjectLayer layer, float dt) {
|
||||||
enemy.attack();
|
enemy.attack();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void follow(Enemy enemy, Character target, ObjectLayer layer, float dt) {
|
protected void follow(Enemy enemy, Creature target, ObjectLayer layer, float dt) {
|
||||||
// noop
|
// noop
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void idle(Enemy enemy, Character target, ObjectLayer layer, float dt) {
|
protected void idle(Enemy enemy, Creature target, ObjectLayer layer, float dt) {
|
||||||
idle.nextActivity(layer, dt);
|
idle.nextActivity(layer, dt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,24 +1,22 @@
|
|||||||
package com.bartlomiejpluta.demo.ai;
|
package com.bartlomiejpluta.demo.ai;
|
||||||
|
|
||||||
import lombok.*;
|
import com.bartlomiejpluta.base.api.ai.AI;
|
||||||
import com.bartlomiejpluta.base.api.map.layer.object.ObjectLayer;
|
import com.bartlomiejpluta.base.api.map.layer.object.ObjectLayer;
|
||||||
import com.bartlomiejpluta.base.api.ai.*;
|
import com.bartlomiejpluta.demo.entity.Creature;
|
||||||
import com.bartlomiejpluta.base.lib.ai.*;
|
|
||||||
|
|
||||||
import com.bartlomiejpluta.demo.entity.Enemy;
|
import com.bartlomiejpluta.demo.entity.Enemy;
|
||||||
import com.bartlomiejpluta.demo.entity.Character;
|
import lombok.AllArgsConstructor;
|
||||||
|
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class SimpleSniperAI implements AI {
|
public class SimpleSniperAI implements AI {
|
||||||
private final Enemy enemy;
|
private final Enemy enemy;
|
||||||
private Character target;
|
private Creature target;
|
||||||
private int range;
|
private int range;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void nextActivity(ObjectLayer layer, float dt) {
|
public void nextActivity(ObjectLayer layer, float dt) {
|
||||||
var enemyCoords = enemy.getCoordinates();
|
var enemyCoords = enemy.getCoordinates();
|
||||||
var targetCoords = target.getCoordinates();
|
var targetCoords = target.getCoordinates();
|
||||||
if(enemy.manhattanDistance(target) <= range && (enemyCoords.x() == targetCoords.x() || enemyCoords.y() == targetCoords.y())) {
|
if (enemy.manhattanDistance(target) <= range && (enemyCoords.x() == targetCoords.x() || enemyCoords.y() == targetCoords.y())) {
|
||||||
var direction = enemy.getDirectionTowards(target);
|
var direction = enemy.getDirectionTowards(target);
|
||||||
enemy.setFaceDirection(direction);
|
enemy.setFaceDirection(direction);
|
||||||
enemy.attack();
|
enemy.attack();
|
||||||
|
|||||||
@@ -1,26 +1,24 @@
|
|||||||
package com.bartlomiejpluta.demo.ai;
|
package com.bartlomiejpluta.demo.ai;
|
||||||
|
|
||||||
import lombok.*;
|
|
||||||
import com.bartlomiejpluta.base.api.ai.AI;
|
import com.bartlomiejpluta.base.api.ai.AI;
|
||||||
import com.bartlomiejpluta.base.api.move.MoveEvent;
|
|
||||||
import com.bartlomiejpluta.base.api.map.layer.object.ObjectLayer;
|
import com.bartlomiejpluta.base.api.map.layer.object.ObjectLayer;
|
||||||
import com.bartlomiejpluta.base.lib.ai.*;
|
import com.bartlomiejpluta.base.api.move.MoveEvent;
|
||||||
|
import com.bartlomiejpluta.base.lib.ai.RunawayAI;
|
||||||
import com.bartlomiejpluta.demo.entity.Character;
|
import com.bartlomiejpluta.demo.entity.Creature;
|
||||||
import com.bartlomiejpluta.demo.entity.Enemy;
|
import com.bartlomiejpluta.demo.entity.Enemy;
|
||||||
import com.bartlomiejpluta.demo.world.weapon.*;
|
import lombok.NonNull;
|
||||||
|
|
||||||
public class WeaponBasedAI implements AI {
|
public class WeaponBasedAI implements AI {
|
||||||
private static final int RANGE = 10;
|
private static final int RANGE = 20;
|
||||||
private static final int MIN_RANGE = 3;
|
private static final int MIN_RANGE = 3;
|
||||||
private static final int MAX_RANGE = 12;
|
private static final int MAX_RANGE = 12;
|
||||||
private final Enemy enemy;
|
private final Enemy enemy;
|
||||||
private final Character target;
|
private final Creature target;
|
||||||
private final RunawayAI runawayAI;
|
private final RunawayAI<Enemy, Creature> runawayAI;
|
||||||
private final SimpleEnemyAI meleeAI;
|
private final SimpleEnemyAI meleeAI;
|
||||||
private final ArcherAI archerAI;
|
private final ArcherAI archerAI;
|
||||||
|
|
||||||
public WeaponBasedAI(@NonNull Enemy enemy, @NonNull Character target) {
|
public WeaponBasedAI(@NonNull Enemy enemy, @NonNull Creature target) {
|
||||||
this.enemy = enemy;
|
this.enemy = enemy;
|
||||||
this.target = target;
|
this.target = target;
|
||||||
this.runawayAI = new RunawayAI<>(enemy, target);
|
this.runawayAI = new RunawayAI<>(enemy, target);
|
||||||
@@ -41,9 +39,8 @@ public class WeaponBasedAI implements AI {
|
|||||||
@Override
|
@Override
|
||||||
public void nextActivity(ObjectLayer layer, float dt) {
|
public void nextActivity(ObjectLayer layer, float dt) {
|
||||||
var lastAttacker = enemy.getLastAttacker();
|
var lastAttacker = enemy.getLastAttacker();
|
||||||
if(lastAttacker != null && lastAttacker instanceof Character) {
|
if (lastAttacker instanceof Creature attacker) {
|
||||||
var attacker = (Character) lastAttacker;
|
if (attacker.isAlive()) {
|
||||||
if(attacker.isAlive()) {
|
|
||||||
runawayAI.setDanger(attacker);
|
runawayAI.setDanger(attacker);
|
||||||
meleeAI.setTarget(attacker);
|
meleeAI.setTarget(attacker);
|
||||||
archerAI.setTarget(attacker);
|
archerAI.setTarget(attacker);
|
||||||
@@ -56,23 +53,32 @@ public class WeaponBasedAI implements AI {
|
|||||||
|
|
||||||
var meleeWeapon = enemy.getMeleeWeapon();
|
var meleeWeapon = enemy.getMeleeWeapon();
|
||||||
var rangedWeapon = enemy.getRangedWeapon();
|
var rangedWeapon = enemy.getRangedWeapon();
|
||||||
|
var throwingWeapon = enemy.getThrowingWeapon();
|
||||||
|
|
||||||
if(meleeWeapon == null && rangedWeapon == null) {
|
if (meleeWeapon == null && rangedWeapon == null && throwingWeapon == null) {
|
||||||
runawayAI.nextActivity(layer, dt);
|
runawayAI.nextActivity(layer, dt);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(rangedWeapon == null || enemy.manhattanDistance(target) == 1) {
|
if ((rangedWeapon == null && throwingWeapon == null) || (rangedWeapon != null && enemy.getAmmunition() == null && throwingWeapon == null) || enemy.manhattanDistance(target) == 1) {
|
||||||
enemy.setWeapon(meleeWeapon);
|
enemy.setWeapon(meleeWeapon);
|
||||||
meleeAI.nextActivity(layer, dt);
|
meleeAI.nextActivity(layer, dt);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(enemy.getWeapon() instanceof MeleeWeapon) {
|
if (throwingWeapon != null) {
|
||||||
meleeAI.nextActivity(layer, dt);
|
enemy.setWeapon(throwingWeapon);
|
||||||
|
archerAI.nextActivity(layer, dt);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
enemy.setWeapon(rangedWeapon);
|
enemy.setWeapon(rangedWeapon);
|
||||||
archerAI.nextActivity(layer, dt);
|
archerAI.nextActivity(layer, dt);
|
||||||
|
|
||||||
|
// if (enemy.getWeapon() instanceof MeleeWeapon) {
|
||||||
|
// meleeAI.nextActivity(layer, dt);
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,86 +0,0 @@
|
|||||||
package com.bartlomiejpluta.demo.entity;
|
|
||||||
|
|
||||||
import lombok.*;
|
|
||||||
import org.slf4j.*;
|
|
||||||
import org.joml.Vector2i;
|
|
||||||
import com.bartlomiejpluta.base.api.context.Context;
|
|
||||||
import com.bartlomiejpluta.base.api.entity.Entity;
|
|
||||||
import com.bartlomiejpluta.base.lib.animation.AnimationRunner;
|
|
||||||
|
|
||||||
import com.bartlomiejpluta.demo.runner.DemoRunner;
|
|
||||||
import com.bartlomiejpluta.demo.world.weapon.Weapon;
|
|
||||||
|
|
||||||
public abstract class Character extends NamedEntity {
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(Character.class);
|
|
||||||
protected final Context context;
|
|
||||||
protected final DemoRunner runner;
|
|
||||||
|
|
||||||
protected int attackCooldown = 0;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
protected boolean alive = true;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
protected boolean immortal = false;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
protected int maxHp;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
protected int hp;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
private Weapon weapon;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
private NamedEntity lastAttacker;
|
|
||||||
|
|
||||||
public Character(@NonNull Context context, @NonNull Entity entity) {
|
|
||||||
super(entity);
|
|
||||||
this.context = context;
|
|
||||||
this.runner = (DemoRunner) context.getGameRunner();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void attack() {
|
|
||||||
if(weapon == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(attackCooldown >= weapon.getCooldown()) {
|
|
||||||
if(weapon.attack(this)) {
|
|
||||||
attackCooldown = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void hit(NamedEntity source, int dmg) {
|
|
||||||
this.lastAttacker = source;
|
|
||||||
|
|
||||||
if(immortal) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
hp -= dmg;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void update(float dt) {
|
|
||||||
super.update(dt);
|
|
||||||
|
|
||||||
if(weapon != null && attackCooldown < weapon.getCooldown()) {
|
|
||||||
attackCooldown += (int) (dt * 1000f);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(hp <= 0 && alive && getLayer() != null) {
|
|
||||||
alive = false;
|
|
||||||
die();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void die() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract String getName();
|
|
||||||
}
|
|
||||||
61
src/main/java/com/bartlomiejpluta/demo/entity/Chest.java
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
package com.bartlomiejpluta.demo.entity;
|
||||||
|
|
||||||
|
import com.bartlomiejpluta.demo.world.item.Item;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NonNull;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
public class Chest extends MapObject {
|
||||||
|
@Getter
|
||||||
|
private final Item[] content = new Item[Enemy.MAX_LOOT];
|
||||||
|
|
||||||
|
public Chest(@NonNull String id) {
|
||||||
|
super(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected CompletableFuture<?> interact() {
|
||||||
|
return runner.getGuiManager().openChestWindow(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Chest addItem(Item item) {
|
||||||
|
for (int i = 0; i < content.length; ++i) {
|
||||||
|
if (content[i] == null) {
|
||||||
|
content[i] = item;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new IllegalStateException("Chest is full!");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Chest addItem(Item item, int slot) {
|
||||||
|
if(slot >= content.length) {
|
||||||
|
throw new IllegalStateException("The [" + slot + "] slot exceeds the chest size (" + content.length + ")!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (content[slot] != null) {
|
||||||
|
throw new IllegalStateException("The [" + slot + "] slot is already filled!");
|
||||||
|
}
|
||||||
|
|
||||||
|
content[slot] = item;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Chest shuffle() {
|
||||||
|
var random = new Random();
|
||||||
|
for(int i = content.length - 1; i > 0; --i) {
|
||||||
|
var index = random.nextInt(i + 1);
|
||||||
|
var tmp = content[index];
|
||||||
|
content[index] = content[i];
|
||||||
|
content[i] = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
156
src/main/java/com/bartlomiejpluta/demo/entity/Creature.java
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
package com.bartlomiejpluta.demo.entity;
|
||||||
|
|
||||||
|
import com.bartlomiejpluta.base.api.character.Character;
|
||||||
|
import com.bartlomiejpluta.base.api.light.Light;
|
||||||
|
import com.bartlomiejpluta.base.api.map.layer.object.ObjectLayer;
|
||||||
|
import com.bartlomiejpluta.demo.world.item.Item;
|
||||||
|
import com.bartlomiejpluta.demo.world.weapon.Ammunition;
|
||||||
|
import com.bartlomiejpluta.demo.world.weapon.RangedWeapon;
|
||||||
|
import com.bartlomiejpluta.demo.world.weapon.Weapon;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import lombok.Setter;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
public abstract class Creature extends NamedCharacter {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(Creature.class);
|
||||||
|
|
||||||
|
protected int attackCooldown = 0;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
protected boolean alive = true;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
protected boolean immortal = false;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
protected int maxHp;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
protected int hp;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
private Weapon weapon;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
private Ammunition ammunition;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private NamedCharacter lastAttacker;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
protected Light light;
|
||||||
|
|
||||||
|
public Creature(@NonNull Character entity) {
|
||||||
|
super(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void attack() {
|
||||||
|
if (weapon == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attackCooldown >= weapon.getCooldown()) {
|
||||||
|
if (weapon.attack(this)) {
|
||||||
|
if (weapon instanceof RangedWeapon) {
|
||||||
|
ammunition.decrease();
|
||||||
|
|
||||||
|
if (ammunition.getCount() == 0) {
|
||||||
|
ammunition = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
attackCooldown = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void hit(NamedCharacter source, int dmg) {
|
||||||
|
this.lastAttacker = source;
|
||||||
|
|
||||||
|
if (immortal) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
hp -= dmg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void useEquipmentItem(Item item) {
|
||||||
|
if (item instanceof Weapon weapon) {
|
||||||
|
setWeapon(weapon);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item instanceof Ammunition ammunition) {
|
||||||
|
setAmmunition(ammunition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void heal(int hp) {
|
||||||
|
this.hp = Math.min(this.hp + hp, this.maxHp);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLight(Light light) {
|
||||||
|
this.light = light;
|
||||||
|
|
||||||
|
if(getLayer() != null) {
|
||||||
|
var layer = getLayer().getMap().getLayer(0);
|
||||||
|
if(light != null) {
|
||||||
|
layer.addLight(light);
|
||||||
|
} else if (this.light != null){
|
||||||
|
layer.removeLight(this.light);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.light = light;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAdd(ObjectLayer layer) {
|
||||||
|
super.onAdd(layer);
|
||||||
|
|
||||||
|
if(light != null) {
|
||||||
|
layer.getMap().getLayer(0).addLight(light);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRemove(ObjectLayer layer) {
|
||||||
|
super.onRemove(layer);
|
||||||
|
|
||||||
|
if(light != null) {
|
||||||
|
layer.getMap().getLayer(0).removeLight(light);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(float dt) {
|
||||||
|
super.update(dt);
|
||||||
|
|
||||||
|
if (weapon != null && attackCooldown < weapon.getCooldown()) {
|
||||||
|
attackCooldown += (int) (dt * 1000f);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hp <= 0 && alive && getLayer() != null) {
|
||||||
|
alive = false;
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(light != null) {
|
||||||
|
light.setPosition(getPosition());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void die() {
|
||||||
|
if (isMoving()) {
|
||||||
|
abortMove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract String getName();
|
||||||
|
|
||||||
|
public abstract void removeItemFromEquipment(Item item);
|
||||||
|
}
|
||||||
48
src/main/java/com/bartlomiejpluta/demo/entity/Door.java
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
package com.bartlomiejpluta.demo.entity;
|
||||||
|
|
||||||
|
import A.maps;
|
||||||
|
import com.bartlomiejpluta.base.api.map.layer.object.MapPin;
|
||||||
|
import com.bartlomiejpluta.demo.runner.DemoRunner;
|
||||||
|
import lombok.NonNull;
|
||||||
|
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
public class Door extends MapObject {
|
||||||
|
private final String mapUid;
|
||||||
|
private final int targetX;
|
||||||
|
private final int targetY;
|
||||||
|
private final int layerId;
|
||||||
|
private final Player player;
|
||||||
|
|
||||||
|
public Door(@NonNull MapPin label, @NonNull String id) {
|
||||||
|
super(id);
|
||||||
|
this.mapUid = label.getMap();
|
||||||
|
this.layerId = label.getLayer();
|
||||||
|
this.targetX = label.getX();
|
||||||
|
this.targetY = label.getY();
|
||||||
|
player = DemoRunner.instance().getPlayer();
|
||||||
|
setPositionOffset(0, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Door(@NonNull String mapName, @NonNull String layerName, int targetX, int targetY, @NonNull String id) {
|
||||||
|
super(id);
|
||||||
|
var map = maps.byName(mapName);
|
||||||
|
this.mapUid = map.$;
|
||||||
|
this.targetX = targetX;
|
||||||
|
this.targetY = targetY;
|
||||||
|
this.layerId = map.layer(layerName).$;
|
||||||
|
player = DemoRunner.instance().getPlayer();
|
||||||
|
setPositionOffset(0, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected CompletableFuture<?> interact() {
|
||||||
|
context.openMap(mapUid);
|
||||||
|
context.getMap().getObjectLayer(layerId).addEntity(player);
|
||||||
|
player.setCoordinates(targetX, targetY);
|
||||||
|
|
||||||
|
reset();
|
||||||
|
|
||||||
|
return CompletableFuture.completedFuture(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,61 +1,84 @@
|
|||||||
package com.bartlomiejpluta.demo.entity;
|
package com.bartlomiejpluta.demo.entity;
|
||||||
|
|
||||||
import lombok.*;
|
|
||||||
|
|
||||||
import com.bartlomiejpluta.base.api.context.Context;
|
|
||||||
import com.bartlomiejpluta.base.api.entity.Entity;
|
|
||||||
import com.bartlomiejpluta.base.api.ai.AI;
|
import com.bartlomiejpluta.base.api.ai.AI;
|
||||||
import com.bartlomiejpluta.base.api.ai.NPC;
|
import com.bartlomiejpluta.base.api.ai.NPC;
|
||||||
|
import com.bartlomiejpluta.base.api.context.ContextHolder;
|
||||||
import com.bartlomiejpluta.base.api.move.MoveEvent;
|
import com.bartlomiejpluta.base.api.move.MoveEvent;
|
||||||
|
import com.bartlomiejpluta.base.lib.ai.NoopAI;
|
||||||
import com.bartlomiejpluta.base.lib.ai.*;
|
import com.bartlomiejpluta.base.lib.animation.AnimationRunner;
|
||||||
import com.bartlomiejpluta.base.lib.animation.*;
|
import com.bartlomiejpluta.base.lib.animation.SimpleAnimationRunner;
|
||||||
import com.bartlomiejpluta.base.util.random.DiceRoller;
|
import com.bartlomiejpluta.base.util.random.DiceRoller;
|
||||||
|
|
||||||
import com.bartlomiejpluta.demo.runner.DemoRunner;
|
|
||||||
import com.bartlomiejpluta.base.generated.db.model.EnemyModel;
|
|
||||||
import com.bartlomiejpluta.demo.world.weapon.*;
|
|
||||||
import com.bartlomiejpluta.demo.event.EnemyDiedEvent;
|
|
||||||
import com.bartlomiejpluta.demo.ai.*;
|
import com.bartlomiejpluta.demo.ai.*;
|
||||||
import com.bartlomiejpluta.demo.ai.ArcherAI;
|
import com.bartlomiejpluta.demo.event.EnemyDiedEvent;
|
||||||
|
import com.bartlomiejpluta.demo.runner.DemoRunner;
|
||||||
|
import com.bartlomiejpluta.demo.util.LootGenerator;
|
||||||
|
import com.bartlomiejpluta.demo.world.item.Item;
|
||||||
|
import com.bartlomiejpluta.demo.world.weapon.Ammunition;
|
||||||
|
import com.bartlomiejpluta.demo.world.weapon.MeleeWeapon;
|
||||||
|
import com.bartlomiejpluta.demo.world.weapon.RangedWeapon;
|
||||||
|
import com.bartlomiejpluta.demo.world.weapon.ThrowingWeapon;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
|
||||||
public class Enemy extends Character implements NPC {
|
public class Enemy extends Creature implements NPC {
|
||||||
private final EnemyModel template;
|
public static final int MAX_LOOT = 4 * 4;
|
||||||
private AI ai = NoopAI.INSTANCE;
|
|
||||||
|
private final Random random = new Random();
|
||||||
|
private final DB.model.EnemyModel template;
|
||||||
private final AnimationRunner dieAnimation;
|
private final AnimationRunner dieAnimation;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private MeleeWeapon meleeWeapon;
|
private final Item[] loot = new Item[MAX_LOOT];
|
||||||
|
|
||||||
@Getter
|
|
||||||
private RangedWeapon rangedWeapon;
|
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private final String name;
|
private final String name;
|
||||||
|
private AI ai = NoopAI.INSTANCE;
|
||||||
|
@Getter
|
||||||
|
private MeleeWeapon meleeWeapon;
|
||||||
|
@Getter
|
||||||
|
private RangedWeapon rangedWeapon;
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
private ThrowingWeapon throwingWeapon;
|
||||||
|
|
||||||
public Enemy(@NonNull Context context, @NonNull EnemyModel template) {
|
public Enemy(@NonNull String id) {
|
||||||
super(context, context.createEntity(template.getEntset()));
|
this(DB.dao.enemy.find(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Enemy(@NonNull DB.model.EnemyModel template) {
|
||||||
|
super(ContextHolder.INSTANCE.getContext().createCharacter(A.charsets.byName(template.getCharset()).$));
|
||||||
this.template = template;
|
this.template = template;
|
||||||
name = template.getName();
|
name = template.getName();
|
||||||
maxHp = DiceRoller.of(template.getHp()).roll();
|
maxHp = DiceRoller.roll(template.getHp());
|
||||||
hp = maxHp;
|
hp = maxHp;
|
||||||
setSpeed(template.getSpeed());
|
var speed = DiceRoller.roll(template.getSpeed()) / 10f;
|
||||||
setAnimationSpeed(template.getAnimationSpeed());
|
setSpeed(speed);
|
||||||
|
setAnimationSpeed(speed / 2.0f);
|
||||||
setBlocking(template.isBlocking());
|
setBlocking(template.isBlocking());
|
||||||
var runner = (DemoRunner) context.getGameRunner();
|
|
||||||
var meleeWeaponTemplate = template.getMeleeWeapon();
|
var meleeWeaponTemplate = template.getMeleeWeapon();
|
||||||
var rangedWeaponTemplate = template.getRangedWeapon();
|
var rangedWeaponTemplate = template.getRangedWeapon();
|
||||||
|
var throwingWeaponTemplate = template.getThrowingWeapon();
|
||||||
|
|
||||||
if(meleeWeaponTemplate != null) {
|
if (meleeWeaponTemplate != null) {
|
||||||
this.meleeWeapon = new MeleeWeapon(context, runner.getMeleeWeaponDAO().find(meleeWeaponTemplate));
|
this.meleeWeapon = new MeleeWeapon(meleeWeaponTemplate);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(rangedWeaponTemplate != null) {
|
if (rangedWeaponTemplate != null) {
|
||||||
this.rangedWeapon = new RangedWeapon(context, runner.getRangedWeaponDAO().find(rangedWeaponTemplate));
|
var split = rangedWeaponTemplate.split(",");
|
||||||
|
|
||||||
|
this.rangedWeapon = new RangedWeapon(split[0]);
|
||||||
|
setAmmunition(new Ammunition(split[1], DiceRoller.roll(split[2])));
|
||||||
}
|
}
|
||||||
|
|
||||||
this.dieAnimation = new SimpleAnimationRunner(template.getDieAnimation());
|
if (throwingWeaponTemplate != null) {
|
||||||
|
var split = throwingWeaponTemplate.split(",");
|
||||||
|
this.throwingWeapon = new ThrowingWeapon(split[0], DiceRoller.roll(split[1]));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.dieAnimation = new SimpleAnimationRunner(A.animations.byName(template.getDieAnimation()).$);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -63,10 +86,15 @@ public class Enemy extends Character implements NPC {
|
|||||||
return ai;
|
return ai;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeItemFromEquipment(Item item) {
|
||||||
|
// noop
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void die() {
|
public void die() {
|
||||||
super.die();
|
super.die();
|
||||||
changeEntitySet(template.getDeadEntset());
|
changeCharacterSet(A.charsets.byName(template.getDeadCharset()).$);
|
||||||
setScale(0.5f);
|
setScale(0.5f);
|
||||||
setBlocking(false);
|
setBlocking(false);
|
||||||
setZIndex(-1);
|
setZIndex(-1);
|
||||||
@@ -74,11 +102,13 @@ public class Enemy extends Character implements NPC {
|
|||||||
ai = NoopAI.INSTANCE;
|
ai = NoopAI.INSTANCE;
|
||||||
|
|
||||||
dieAnimation.run(context, getLayer(), this);
|
dieAnimation.run(context, getLayer(), this);
|
||||||
context.playSound(template.getDieSound());
|
context.playSound(A.sounds.byName(template.getDieSound()).$);
|
||||||
context.fireEvent(new EnemyDiedEvent(this));
|
context.fireEvent(new EnemyDiedEvent(this));
|
||||||
|
|
||||||
|
LootGenerator.generate(template.getId(), loot);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Enemy followAndAttack(Character target, int range) {
|
public Enemy followAndAttack(Creature target, int range) {
|
||||||
var ai = new SimpleEnemyAI(this, target, range);
|
var ai = new SimpleEnemyAI(this, target, range);
|
||||||
|
|
||||||
addEventListener(MoveEvent.TYPE, ai::recomputePath);
|
addEventListener(MoveEvent.TYPE, ai::recomputePath);
|
||||||
@@ -89,19 +119,19 @@ public class Enemy extends Character implements NPC {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Enemy campAndHunt(Character target, int range) {
|
public Enemy campAndHunt(Creature target, int range) {
|
||||||
this.ai = new SimpleSniperAI(this, target, range);
|
this.ai = new SimpleSniperAI(this, target, range);
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Enemy asAnimal(Character source, int range) {
|
public Enemy asAnimal(Creature source, int range) {
|
||||||
this.ai = new AnimalAI(this, source, range);
|
this.ai = new AnimalAI(this, source, range);
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Enemy archer(Character target, int minRange, int maxRange, int range) {
|
public Enemy archer(Creature target, int minRange, int maxRange, int range) {
|
||||||
var ai = new ArcherAI(this, target, minRange, maxRange, range);
|
var ai = new ArcherAI(this, target, minRange, maxRange, range);
|
||||||
|
|
||||||
addEventListener(MoveEvent.TYPE, ai::recomputePath);
|
addEventListener(MoveEvent.TYPE, ai::recomputePath);
|
||||||
@@ -113,7 +143,7 @@ public class Enemy extends Character implements NPC {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Enemy defaultAI() {
|
public Enemy defaultAI() {
|
||||||
var ai = new WeaponBasedAI(this, runner.getPlayer());
|
var ai = new WeaponBasedAI(this, DemoRunner.instance().getPlayer());
|
||||||
|
|
||||||
addEventListener(MoveEvent.TYPE, ai::recomputePath);
|
addEventListener(MoveEvent.TYPE, ai::recomputePath);
|
||||||
addEventListener(EnemyDiedEvent.TYPE, e -> ai.recomputePath());
|
addEventListener(EnemyDiedEvent.TYPE, e -> ai.recomputePath());
|
||||||
|
|||||||
102
src/main/java/com/bartlomiejpluta/demo/entity/Friend.java
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
package com.bartlomiejpluta.demo.entity;
|
||||||
|
|
||||||
|
import DB.model.FriendModel;
|
||||||
|
import com.bartlomiejpluta.base.api.ai.AI;
|
||||||
|
import com.bartlomiejpluta.base.api.ai.NPC;
|
||||||
|
import com.bartlomiejpluta.base.api.character.Character;
|
||||||
|
import com.bartlomiejpluta.base.api.context.ContextHolder;
|
||||||
|
import com.bartlomiejpluta.base.lib.ai.FollowPathAI;
|
||||||
|
import com.bartlomiejpluta.base.lib.ai.NoopAI;
|
||||||
|
import com.bartlomiejpluta.base.lib.ai.RandomMovementAI;
|
||||||
|
import com.bartlomiejpluta.base.util.path.Path;
|
||||||
|
import com.bartlomiejpluta.base.util.random.DiceRoller;
|
||||||
|
import com.bartlomiejpluta.demo.world.item.Item;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import org.joml.Vector2ic;
|
||||||
|
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
public class Friend extends Creature implements NPC {
|
||||||
|
@Getter
|
||||||
|
private AI strategy = NoopAI.INSTANCE;
|
||||||
|
private AI priorStrategy;
|
||||||
|
private boolean interacting;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private final int dialogNameColor;
|
||||||
|
private Function<Friend, CompletableFuture<Object>> interaction;
|
||||||
|
|
||||||
|
public Friend(@NonNull String id) {
|
||||||
|
this(DB.dao.friend.find(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Friend(@NonNull FriendModel template) {
|
||||||
|
super(ContextHolder.INSTANCE.getContext().createCharacter(A.charsets.byName(template.getCharset()).$));
|
||||||
|
name = template.getName();
|
||||||
|
setSpeed(DiceRoller.roll(template.getSpeed()) / 10f);
|
||||||
|
setBlocking(template.isBlocking());
|
||||||
|
dialogNameColor = Integer.parseInt(template.getDialogColor(), 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeItemFromEquipment(Item item) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public CompletableFuture<Object> interact(Character trigger) {
|
||||||
|
if (interaction != null && !interacting) {
|
||||||
|
setFaceDirection(getDirectionTowards(trigger));
|
||||||
|
|
||||||
|
var movement = getMovement();
|
||||||
|
if (movement != null) {
|
||||||
|
movement.abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
priorStrategy = strategy;
|
||||||
|
strategy = NoopAI.INSTANCE;
|
||||||
|
interacting = true;
|
||||||
|
|
||||||
|
return interaction.apply(this).thenApply(o -> {
|
||||||
|
strategy = priorStrategy;
|
||||||
|
interacting = false;
|
||||||
|
return o;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return CompletableFuture.completedFuture(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Friend interaction(Function<Friend, CompletableFuture<Object>> interaction) {
|
||||||
|
this.interaction = interaction;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Friend followPath(@NonNull Path<Friend> path) {
|
||||||
|
var ai = new FollowPathAI<>(this);
|
||||||
|
ai.setPath(path);
|
||||||
|
this.strategy = ai;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Friend followPath(@NonNull Function<Friend, Path<Friend>> pathSupplier) {
|
||||||
|
var ai = new FollowPathAI<>(this);
|
||||||
|
ai.setPath(pathSupplier.apply(this));
|
||||||
|
this.strategy = ai;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Friend randomMovementAI(float intervalSeconds, Vector2ic origin, int radius) {
|
||||||
|
this.strategy = new RandomMovementAI<>(this, intervalSeconds, origin, radius);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Friend randomMovementAI(float intervalSeconds) {
|
||||||
|
this.strategy = new RandomMovementAI<>(this, intervalSeconds);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,77 +1,40 @@
|
|||||||
package com.bartlomiejpluta.demo.entity;
|
package com.bartlomiejpluta.demo.entity;
|
||||||
|
|
||||||
import lombok.*;
|
|
||||||
import com.bartlomiejpluta.base.api.entity.Entity;
|
|
||||||
import com.bartlomiejpluta.base.api.context.Context;
|
import com.bartlomiejpluta.base.api.context.Context;
|
||||||
import com.bartlomiejpluta.base.api.move.*;
|
import com.bartlomiejpluta.base.api.context.ContextHolder;
|
||||||
import com.bartlomiejpluta.base.lib.entity.EntityDelegate;
|
import com.bartlomiejpluta.demo.runner.DemoRunner;
|
||||||
import com.bartlomiejpluta.base.util.path.*;
|
import lombok.Getter;
|
||||||
|
import lombok.NonNull;
|
||||||
|
|
||||||
import com.bartlomiejpluta.base.generated.db.model.MapObjectModel;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
import com.bartlomiejpluta.demo.entity.Character;
|
import static java.util.concurrent.CompletableFuture.completedFuture;
|
||||||
|
|
||||||
public class MapObject extends EntityDelegate {
|
public abstract class MapObject extends com.bartlomiejpluta.base.util.world.MapObject {
|
||||||
private final PathExecutor<MapObject> pathExecutor = new PathExecutor<>(this);
|
protected final Context context;
|
||||||
private final Context context;
|
protected final DemoRunner runner;
|
||||||
private final MapObjectModel template;
|
@Getter
|
||||||
private final Short frame;
|
private final String name;
|
||||||
private final String interactSound;
|
private final String interactSound;
|
||||||
private boolean interacting = false;
|
|
||||||
|
|
||||||
public MapObject(@NonNull Context context, @NonNull MapObjectModel template) {
|
public MapObject(@NonNull String id) {
|
||||||
super(context.createEntity(template.getEntset()));
|
this(DB.dao.object.find(id));
|
||||||
this.context = context;
|
|
||||||
this.template = template;
|
|
||||||
this.frame = template.getFrame();
|
|
||||||
this.interactSound = template.getInteractSound();
|
|
||||||
|
|
||||||
setBlocking(true);
|
|
||||||
disableAnimation();
|
|
||||||
|
|
||||||
if(frame != null) {
|
|
||||||
setAnimationFrame(frame);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pathExecutor.setPath(
|
public MapObject(@NonNull DB.model.ObjectModel template) {
|
||||||
frame != null
|
super(ContextHolder.INSTANCE.getContext().createCharacter(A.charsets.byName(template.getCharset()).$), template.getFrame());
|
||||||
? new EntityPath<MapObject>()
|
this.context = ContextHolder.INSTANCE.getContext();
|
||||||
.run(this::startInteraction)
|
this.runner = DemoRunner.instance();
|
||||||
.turn(Direction.LEFT, frame)
|
this.name = template.getName();
|
||||||
.wait(0.05f)
|
this.interactSound = A.sounds.byName(template.getInteractSound()).$;
|
||||||
.turn(Direction.RIGHT, frame)
|
|
||||||
.wait(0.05f)
|
|
||||||
.turn(Direction.UP, frame)
|
|
||||||
.wait(0.5f)
|
|
||||||
.turn(Direction.RIGHT, frame)
|
|
||||||
.wait(0.05f)
|
|
||||||
.turn(Direction.LEFT, frame)
|
|
||||||
.wait(0.05f)
|
|
||||||
.turn(Direction.DOWN, frame)
|
|
||||||
.wait(0.5f)
|
|
||||||
.run(this::finishInteraction)
|
|
||||||
: new EntityPath<MapObject>()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void interact(Character character) {
|
|
||||||
interacting = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void startInteraction() {
|
|
||||||
if(interactSound != null) {
|
|
||||||
context.playSound(interactSound);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void finishInteraction() {
|
|
||||||
interacting = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(float dt) {
|
protected @NonNull CompletableFuture<?> onInteractionBegin() {
|
||||||
if(interacting) {
|
if (interactSound != null) {
|
||||||
pathExecutor.execute(getLayer(), dt);
|
context.playSound(interactSound);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return completedFuture(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package com.bartlomiejpluta.demo.entity;
|
||||||
|
|
||||||
|
import com.bartlomiejpluta.base.api.character.Character;
|
||||||
|
import com.bartlomiejpluta.base.api.context.Context;
|
||||||
|
import com.bartlomiejpluta.base.api.context.ContextHolder;
|
||||||
|
import com.bartlomiejpluta.base.lib.animation.AnimationRunner;
|
||||||
|
import com.bartlomiejpluta.base.lib.animation.SimpleAnimationRunner;
|
||||||
|
import com.bartlomiejpluta.base.lib.character.CharacterDelegate;
|
||||||
|
import com.bartlomiejpluta.demo.runner.DemoRunner;
|
||||||
|
import lombok.NonNull;
|
||||||
|
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
public abstract class NamedCharacter extends CharacterDelegate {
|
||||||
|
protected final Context context;
|
||||||
|
protected final DemoRunner runner;
|
||||||
|
|
||||||
|
public NamedCharacter(Character character) {
|
||||||
|
super(character);
|
||||||
|
this.context = ContextHolder.INSTANCE.getContext();
|
||||||
|
this.runner = DemoRunner.instance();
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract String getName();
|
||||||
|
|
||||||
|
public int getDialogNameColor() {
|
||||||
|
return 0xFFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CompletableFuture<Void> runEmoji(@NonNull String animation) {
|
||||||
|
return runEmoji(animation, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CompletableFuture<Void> runEmoji(@NonNull String animation, Consumer<SimpleAnimationRunner> customizer) {
|
||||||
|
var runner = AnimationRunner
|
||||||
|
.simple(animation)
|
||||||
|
.scale(0.4f)
|
||||||
|
.animationSpeed(1.6f)
|
||||||
|
.offset(0, -30);
|
||||||
|
|
||||||
|
if (customizer != null) {
|
||||||
|
customizer.accept(runner);
|
||||||
|
}
|
||||||
|
|
||||||
|
return runner.run(context, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
package com.bartlomiejpluta.demo.entity;
|
|
||||||
|
|
||||||
import com.bartlomiejpluta.base.api.entity.Entity;
|
|
||||||
import com.bartlomiejpluta.base.lib.entity.EntityDelegate;
|
|
||||||
|
|
||||||
public abstract class NamedEntity extends EntityDelegate {
|
|
||||||
|
|
||||||
public NamedEntity(Entity entity) {
|
|
||||||
super(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract String getName();
|
|
||||||
}
|
|
||||||
@@ -1,26 +1,233 @@
|
|||||||
package com.bartlomiejpluta.demo.entity;
|
package com.bartlomiejpluta.demo.entity;
|
||||||
|
|
||||||
import lombok.*;
|
import com.bartlomiejpluta.base.api.character.Character;
|
||||||
|
import com.bartlomiejpluta.base.util.random.DiceRoller;
|
||||||
|
import com.bartlomiejpluta.demo.world.item.Item;
|
||||||
|
import com.bartlomiejpluta.demo.world.item.ItemStack;
|
||||||
|
import com.bartlomiejpluta.demo.world.weapon.Ammunition;
|
||||||
|
import com.bartlomiejpluta.demo.world.weapon.ThrowingWeapon;
|
||||||
|
import com.bartlomiejpluta.demo.world.weapon.Weapon;
|
||||||
|
import lombok.NonNull;
|
||||||
import org.joml.Vector2i;
|
import org.joml.Vector2i;
|
||||||
import com.bartlomiejpluta.base.api.context.Context;
|
|
||||||
import com.bartlomiejpluta.base.api.entity.Entity;
|
|
||||||
import com.bartlomiejpluta.demo.entity.MapObject;
|
|
||||||
|
|
||||||
public class Player extends Character {
|
import java.util.Arrays;
|
||||||
|
|
||||||
public Player(@NonNull Context context, @NonNull Entity entity) {
|
public class Player extends Creature {
|
||||||
super(context, entity);
|
public static final int EQUIPMENT_SIZE = 6 * 6;
|
||||||
this.hp = 500;
|
private final Item[] equipment = new Item[EQUIPMENT_SIZE];
|
||||||
this.maxHp = 500;
|
private int interactionCooldown = 0;
|
||||||
|
|
||||||
|
public Player(@NonNull Character entity) {
|
||||||
|
super(entity);
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reset() {
|
||||||
|
var data = DB.dao.levels.find(1);
|
||||||
|
this.maxHp = DiceRoller.roll(data.getMaxHp());
|
||||||
|
this.hp = this.maxHp;
|
||||||
|
|
||||||
|
alive = true;
|
||||||
|
changeCharacterSet(A.charsets.luna.$);
|
||||||
|
setScale(1f);
|
||||||
|
setSpeed(4f);
|
||||||
|
setAnimationSpeed(1f);
|
||||||
|
setBlocking(true);
|
||||||
|
|
||||||
|
var light = context.createLight();
|
||||||
|
light.setAttenuation(4f, 0, 0.001f);
|
||||||
|
light.setIntensity(1f, 1f, 1f);
|
||||||
|
setLight(light);
|
||||||
|
|
||||||
|
Arrays.fill(equipment, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void interact() {
|
public void interact() {
|
||||||
|
if (interactionCooldown > 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var coords = getCoordinates().add(getFaceDirection().vector, new Vector2i());
|
var coords = getCoordinates().add(getFaceDirection().vector, new Vector2i());
|
||||||
for(var entity : getLayer().getEntities()) {
|
var entities = getLayer().getEntities();
|
||||||
if(entity.getCoordinates().equals(coords) && entity instanceof MapObject) {
|
for (var i = 0; i < entities.size(); ++i) {
|
||||||
((MapObject) entity).interact(this);
|
var entity = entities.get(i);
|
||||||
|
|
||||||
|
if (entity.getCoordinates().equals(coords)) {
|
||||||
|
|
||||||
|
// Use some map object which player is looking at
|
||||||
|
if(entity instanceof MapObject object) {
|
||||||
|
object.triggerInteraction();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Interact with friend creature which player is looking at
|
||||||
|
if(entity instanceof Friend friend) {
|
||||||
|
friend.interact(this).thenApply(o -> interactionCooldown = INTERACTION_COOLDOWN);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (entity.getCoordinates().equals(getCoordinates())) {
|
||||||
|
|
||||||
|
// Pick some item from the ground
|
||||||
|
if (entity instanceof Item item) {
|
||||||
|
pushItemToEquipment(item);
|
||||||
|
getLayer().removeEntity(item);
|
||||||
|
interactionCooldown = INTERACTION_COOLDOWN;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search the enemy corpse
|
||||||
|
if (entity instanceof Enemy enemy && !enemy.isAlive()) {
|
||||||
|
runner.getGuiManager().openLootWindow(enemy);
|
||||||
|
interactionCooldown = INTERACTION_COOLDOWN;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean pushItemToEquipment(@NonNull Item item) {
|
||||||
|
if (item instanceof Ammunition ammo) {
|
||||||
|
if (getAmmunition() != null && ammo.getId().equals(getAmmunition().getId())) {
|
||||||
|
getAmmunition().increase(ammo.getCount());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item instanceof ThrowingWeapon weapons) {
|
||||||
|
if (getWeapon() instanceof ThrowingWeapon currentWeapons && currentWeapons.getId().equals(weapons.getId())) {
|
||||||
|
currentWeapons.increase(weapons.getCount());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item instanceof ItemStack stack) {
|
||||||
|
return pushItemStackToEquipment(stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
return pushSingleItemToEquipment(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean pushItemStackToEquipment(@NonNull ItemStack items) {
|
||||||
|
var availableSlot = -1;
|
||||||
|
for (int i = 0; i < equipment.length; ++i) {
|
||||||
|
if (equipment[i] instanceof ItemStack stack && stack.getId().equals(items.getId())) {
|
||||||
|
stack.increase(items.getCount());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (availableSlot == -1 && equipment[i] == null) {
|
||||||
|
availableSlot = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (availableSlot > -1) {
|
||||||
|
equipment[availableSlot] = items;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean pushSingleItemToEquipment(@NonNull Item item) {
|
||||||
|
for (int i = 0; i < equipment.length; ++i) {
|
||||||
|
if (equipment[i] == null) {
|
||||||
|
equipment[i] = item;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Item getEquipmentItem(int index) {
|
||||||
|
return equipment[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeItemFromEquipment(@NonNull Item item) {
|
||||||
|
for (int i = 0; i < equipment.length; ++i) {
|
||||||
|
if (equipment[i] == item) {
|
||||||
|
equipment[i] = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void dropItemFromEquipment(@NonNull Item item) {
|
||||||
|
removeItemFromEquipment(item);
|
||||||
|
item.setCoordinates(getCoordinates());
|
||||||
|
getLayer().addEntity(item);
|
||||||
|
|
||||||
|
if (item == getWeapon()) {
|
||||||
|
setWeapon(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item == getAmmunition()) {
|
||||||
|
setAmmunition(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setWeapon(Weapon newWeapon) {
|
||||||
|
var currentWeapon = getWeapon();
|
||||||
|
|
||||||
|
if (newWeapon == null) {
|
||||||
|
disarmWeapon(currentWeapon);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentWeapon instanceof ThrowingWeapon currentWeapons && newWeapon instanceof ThrowingWeapon weapons && currentWeapons.getId().equals(weapons.getId())) {
|
||||||
|
updateStackableWeapon(currentWeapons, weapons);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
changeWeaponForWeapon(currentWeapon, newWeapon);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void disarmWeapon(Weapon currentWeapon) {
|
||||||
|
if (!(currentWeapon instanceof ThrowingWeapon)) {
|
||||||
|
pushItemToEquipment(currentWeapon);
|
||||||
|
}
|
||||||
|
|
||||||
|
super.setWeapon(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateStackableWeapon(ThrowingWeapon currentWeapon, ThrowingWeapon newWeapon) {
|
||||||
|
currentWeapon.increase(newWeapon.getCount());
|
||||||
|
removeItemFromEquipment(newWeapon);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void changeWeaponForWeapon(Weapon currentWeapon, Weapon newWeapon) {
|
||||||
|
super.setWeapon(newWeapon);
|
||||||
|
removeItemFromEquipment(newWeapon);
|
||||||
|
|
||||||
|
if (currentWeapon != null) {
|
||||||
|
pushItemToEquipment(currentWeapon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAmmunition(Ammunition ammunition) {
|
||||||
|
var currentAmmo = getAmmunition();
|
||||||
|
|
||||||
|
if (currentAmmo != null && currentAmmo.getId().equals(ammunition.getId())) {
|
||||||
|
currentAmmo.increase(ammunition.getCount());
|
||||||
|
removeItemFromEquipment(ammunition);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ammunition != null) {
|
||||||
|
removeItemFromEquipment(ammunition);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentAmmo != null) {
|
||||||
|
pushItemToEquipment(currentAmmo);
|
||||||
|
}
|
||||||
|
|
||||||
|
super.setAmmunition(ammunition);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -31,6 +238,22 @@ public class Player extends Character {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return "Player";
|
return "Luna";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getDialogNameColor() {
|
||||||
|
return 0x00AA00;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(float dt) {
|
||||||
|
super.update(dt);
|
||||||
|
|
||||||
|
if (interactionCooldown > 0) {
|
||||||
|
interactionCooldown = (int) Math.max(0, interactionCooldown - dt * 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final int INTERACTION_COOLDOWN = 300;
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
package com.bartlomiejpluta.demo.event;
|
package com.bartlomiejpluta.demo.event;
|
||||||
|
|
||||||
import lombok.*;
|
import com.bartlomiejpluta.base.api.event.EventType;
|
||||||
|
import com.bartlomiejpluta.base.lib.event.BaseEvent;
|
||||||
import com.bartlomiejpluta.base.api.event.*;
|
|
||||||
import com.bartlomiejpluta.base.lib.event.*;
|
|
||||||
import com.bartlomiejpluta.demo.entity.Enemy;
|
import com.bartlomiejpluta.demo.entity.Enemy;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
package com.bartlomiejpluta.demo.event;
|
package com.bartlomiejpluta.demo.event;
|
||||||
|
|
||||||
import lombok.*;
|
import com.bartlomiejpluta.base.api.event.EventType;
|
||||||
|
import com.bartlomiejpluta.base.lib.event.BaseEvent;
|
||||||
import com.bartlomiejpluta.base.api.event.*;
|
import com.bartlomiejpluta.demo.entity.Creature;
|
||||||
import com.bartlomiejpluta.base.lib.event.*;
|
import lombok.Getter;
|
||||||
import com.bartlomiejpluta.demo.entity.Character;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class HitEvent extends BaseEvent {
|
public class HitEvent extends BaseEvent {
|
||||||
public static final EventType<HitEvent> TYPE = new EventType<>("HIT_EVENT");
|
public static final EventType<HitEvent> TYPE = new EventType<>("HIT_EVENT");
|
||||||
|
|
||||||
private final Character attacker;
|
private final Creature attacker;
|
||||||
private final Character target;
|
private final Creature target;
|
||||||
private final int damage;
|
private final int damage;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,25 +1,25 @@
|
|||||||
package com.bartlomiejpluta.demo.gui;
|
package com.bartlomiejpluta.demo.gui;
|
||||||
|
|
||||||
import lombok.*;
|
|
||||||
|
|
||||||
import com.bartlomiejpluta.base.api.gui.*;
|
|
||||||
import com.bartlomiejpluta.base.lib.gui.*;
|
|
||||||
|
|
||||||
import com.bartlomiejpluta.base.api.screen.*;
|
|
||||||
import com.bartlomiejpluta.base.api.context.Context;
|
import com.bartlomiejpluta.base.api.context.Context;
|
||||||
import com.bartlomiejpluta.base.api.input.*;
|
import com.bartlomiejpluta.base.api.gui.Color;
|
||||||
|
import com.bartlomiejpluta.base.api.gui.Component;
|
||||||
|
import com.bartlomiejpluta.base.api.gui.GUI;
|
||||||
|
import com.bartlomiejpluta.base.api.screen.Screen;
|
||||||
|
import com.bartlomiejpluta.base.lib.gui.BaseComponent;
|
||||||
|
import lombok.NonNull;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class Bar extends BaseComponent {
|
public class Bar extends BaseComponent {
|
||||||
|
|
||||||
@Setter
|
|
||||||
private float value = 1.0f;
|
|
||||||
private float actualValue = 1.0f;
|
|
||||||
private float speed = 0.05f;
|
|
||||||
private final Color stroke;
|
private final Color stroke;
|
||||||
private final Color fill;
|
private final Color fill;
|
||||||
|
private float value = 1.0f;
|
||||||
|
private float actualValue = 1.0f;
|
||||||
|
private final float speed = 0.05f;
|
||||||
|
|
||||||
public Bar(Context context, GUI gui) {
|
public Bar(Context context, GUI gui, Map<String, Component> refs) {
|
||||||
super(context, gui);
|
super(context, gui, refs);
|
||||||
|
|
||||||
this.stroke = gui.createColor();
|
this.stroke = gui.createColor();
|
||||||
this.fill = gui.createColor();
|
this.fill = gui.createColor();
|
||||||
@@ -28,6 +28,10 @@ public class Bar extends BaseComponent {
|
|||||||
fill.setAlpha(1f);
|
fill.setAlpha(1f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setValue(@NonNull Float value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
public void setStrokeColor(Integer hex) {
|
public void setStrokeColor(Integer hex) {
|
||||||
stroke.setRGB(hex);
|
stroke.setRGB(hex);
|
||||||
}
|
}
|
||||||
@@ -52,12 +56,12 @@ public class Bar extends BaseComponent {
|
|||||||
actualValue += remainingDistance * speed;
|
actualValue += remainingDistance * speed;
|
||||||
|
|
||||||
gui.beginPath();
|
gui.beginPath();
|
||||||
gui.drawRectangle(x, y, Math.max(width * actualValue, 0), height);
|
gui.drawRectangle(x + paddingLeft, y + paddingTop, Math.max(width * actualValue, 0), height);
|
||||||
gui.setFillColor(fill);
|
gui.setFillColor(fill);
|
||||||
gui.fill();
|
gui.fill();
|
||||||
gui.closePath();
|
gui.closePath();
|
||||||
gui.beginPath();
|
gui.beginPath();
|
||||||
gui.drawRectangle(x, y, width, height);
|
gui.drawRectangle(x + paddingLeft, y + paddingTop, width, height);
|
||||||
gui.setStrokeColor(stroke);
|
gui.setStrokeColor(stroke);
|
||||||
gui.stroke();
|
gui.stroke();
|
||||||
gui.closePath();
|
gui.closePath();
|
||||||
|
|||||||
@@ -1,33 +1,40 @@
|
|||||||
package com.bartlomiejpluta.demo.gui;
|
package com.bartlomiejpluta.demo.gui;
|
||||||
|
|
||||||
import lombok.*;
|
|
||||||
import com.bartlomiejpluta.base.api.context.Context;
|
import com.bartlomiejpluta.base.api.context.Context;
|
||||||
|
import com.bartlomiejpluta.base.api.gui.Color;
|
||||||
|
import com.bartlomiejpluta.base.api.gui.Component;
|
||||||
|
import com.bartlomiejpluta.base.api.gui.GUI;
|
||||||
|
import com.bartlomiejpluta.base.api.input.Key;
|
||||||
|
import com.bartlomiejpluta.base.api.input.KeyAction;
|
||||||
|
import com.bartlomiejpluta.base.api.input.KeyEvent;
|
||||||
import com.bartlomiejpluta.base.api.screen.Screen;
|
import com.bartlomiejpluta.base.api.screen.Screen;
|
||||||
import com.bartlomiejpluta.base.api.input.*;
|
import com.bartlomiejpluta.base.lib.gui.Label;
|
||||||
import com.bartlomiejpluta.base.api.gui.*;
|
import com.bartlomiejpluta.base.lib.gui.TextAlignment;
|
||||||
import com.bartlomiejpluta.base.lib.gui.*;
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class Button extends Label {
|
public class Button extends Label {
|
||||||
private Color color;
|
private final Color color;
|
||||||
|
|
||||||
@Setter
|
@Setter
|
||||||
private Runnable action;
|
private Runnable action;
|
||||||
|
|
||||||
public Button(Context context, GUI gui) {
|
public Button(Context context, GUI gui, Map<String, Component> refs) {
|
||||||
super(context, gui);
|
super(context, gui, refs);
|
||||||
this.color = gui.createColor();
|
this.color = gui.createColor();
|
||||||
this.color.setRGBA(1, 1, 1, 0);
|
this.color.setRGBA(1, 1, 1, 0);
|
||||||
|
|
||||||
setText("");
|
setText("");
|
||||||
setFontSize(17f);
|
setFontSize(17f);
|
||||||
setAlignment(GUI.ALIGN_TOP | GUI.ALIGN_CENTER);
|
setAlignment(TextAlignment.TOP, TextAlignment.CENTER);
|
||||||
setColor(0.4f, 0.7f, 0.0f, 1f);
|
setColor(0.4f, 0.7f, 0.0f, 1f);
|
||||||
setPadding(10f);
|
setPadding(10f);
|
||||||
addEventListener(KeyEvent.TYPE, this::handleKeyEvent);
|
addEventListener(KeyEvent.TYPE, this::handleKeyEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleKeyEvent(KeyEvent event) {
|
private void handleKeyEvent(KeyEvent event) {
|
||||||
if(event.getKey() == Key.KEY_ENTER && event.getAction() == KeyAction.PRESS && action != null) {
|
if (event.getKey() == Key.KEY_ENTER && event.getAction() == KeyAction.PRESS && action != null) {
|
||||||
event.consume();
|
event.consume();
|
||||||
action.run();
|
action.run();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,22 @@
|
|||||||
package com.bartlomiejpluta.demo.gui;
|
package com.bartlomiejpluta.demo.gui;
|
||||||
|
|
||||||
import com.bartlomiejpluta.base.api.context.Context;
|
import com.bartlomiejpluta.base.api.context.Context;
|
||||||
|
import com.bartlomiejpluta.base.api.gui.Color;
|
||||||
|
import com.bartlomiejpluta.base.api.gui.Component;
|
||||||
|
import com.bartlomiejpluta.base.api.gui.GUI;
|
||||||
|
import com.bartlomiejpluta.base.api.gui.Paint;
|
||||||
import com.bartlomiejpluta.base.api.screen.Screen;
|
import com.bartlomiejpluta.base.api.screen.Screen;
|
||||||
import com.bartlomiejpluta.base.api.gui.*;
|
import com.bartlomiejpluta.base.lib.gui.BaseWindow;
|
||||||
import com.bartlomiejpluta.base.lib.gui.*;
|
|
||||||
|
|
||||||
public abstract class DecoratedWindow extends BaseWindow {
|
import java.util.Map;
|
||||||
private Paint paint;
|
|
||||||
private Color inner;
|
|
||||||
private Color outer;
|
|
||||||
|
|
||||||
public DecoratedWindow(Context context, GUI gui) {
|
public class DecoratedWindow extends BaseWindow {
|
||||||
super(context, gui);
|
private final Paint paint;
|
||||||
|
private final Color inner;
|
||||||
|
private final Color outer;
|
||||||
|
|
||||||
|
public DecoratedWindow(Context context, GUI gui, Map<String, Component> refs) {
|
||||||
|
super(context, gui, refs);
|
||||||
|
|
||||||
this.inner = gui.createColor();
|
this.inner = gui.createColor();
|
||||||
this.outer = gui.createColor();
|
this.outer = gui.createColor();
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
package com.bartlomiejpluta.demo.gui;
|
||||||
|
|
||||||
|
import A.fonts;
|
||||||
|
import com.bartlomiejpluta.base.api.context.Context;
|
||||||
|
import com.bartlomiejpluta.base.api.gui.*;
|
||||||
|
import com.bartlomiejpluta.base.lib.gui.TextView;
|
||||||
|
import com.bartlomiejpluta.base.lib.gui.VOptionChoice;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class DialogChoiceWindow extends DecoratedWindow {
|
||||||
|
|
||||||
|
@Ref("speaker")
|
||||||
|
private TextView speaker;
|
||||||
|
|
||||||
|
@Ref("choice")
|
||||||
|
private VOptionChoice choice;
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public void onOpen(WindowManager manager, Object[] args) {
|
||||||
|
super.onOpen(manager, args);
|
||||||
|
|
||||||
|
speaker.setText((String) args[0]);
|
||||||
|
speaker.setColor((int) args[1]);
|
||||||
|
|
||||||
|
var index = 0;
|
||||||
|
choice.removeAllChildren();
|
||||||
|
var options = (String[]) args[2];
|
||||||
|
for(var option : options) {
|
||||||
|
var button = new Button(context, gui, Collections.emptyMap());
|
||||||
|
choice.add(button);
|
||||||
|
button.setText(option);
|
||||||
|
button.setColor(0xFFFFFF);
|
||||||
|
button.setWidthMode(SizeMode.RELATIVE);
|
||||||
|
button.setWidth(1f);
|
||||||
|
button.setFont(fonts.roboto_regular.$);
|
||||||
|
button.setFontSize(20f);
|
||||||
|
button.setAction(onChoose(index));
|
||||||
|
++index;
|
||||||
|
}
|
||||||
|
|
||||||
|
choice.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Runnable onChoose(int index) {
|
||||||
|
return () -> resolve(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DialogChoiceWindow(Context context, GUI gui, Map<String, Component> refs) {
|
||||||
|
super(context, gui, refs);
|
||||||
|
}
|
||||||
|
}
|
||||||
66
src/main/java/com/bartlomiejpluta/demo/gui/DialogWindow.java
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
package com.bartlomiejpluta.demo.gui;
|
||||||
|
|
||||||
|
import com.bartlomiejpluta.base.api.context.Context;
|
||||||
|
import com.bartlomiejpluta.base.api.gui.*;
|
||||||
|
import com.bartlomiejpluta.base.api.input.Key;
|
||||||
|
import com.bartlomiejpluta.base.api.input.KeyAction;
|
||||||
|
import com.bartlomiejpluta.base.api.input.KeyEvent;
|
||||||
|
import com.bartlomiejpluta.base.lib.gui.PrintedTextView;
|
||||||
|
import com.bartlomiejpluta.base.lib.gui.TextView;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class DialogWindow extends DecoratedWindow {
|
||||||
|
|
||||||
|
@Ref("speaker")
|
||||||
|
private TextView speaker;
|
||||||
|
|
||||||
|
@Ref("message")
|
||||||
|
private PrintedTextView text;
|
||||||
|
|
||||||
|
public DialogWindow(Context context, GUI gui, Map<String, Component> refs) {
|
||||||
|
super(context, gui, refs);
|
||||||
|
addEventListener(KeyEvent.TYPE, this::handleKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleKey(KeyEvent event) {
|
||||||
|
if (event.getKey() == Key.KEY_ESCAPE) {
|
||||||
|
event.consume();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.getKey() == Key.KEY_ENTER && event.getAction() == KeyAction.PRESS) {
|
||||||
|
if (text.isPrinting()) {
|
||||||
|
text.printAll();
|
||||||
|
event.consume();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
manager.close();
|
||||||
|
event.consume();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onOpen(WindowManager manager, Object[] args) {
|
||||||
|
super.onOpen(manager, args);
|
||||||
|
|
||||||
|
speaker.setText((String) args[0]);
|
||||||
|
speaker.setColor((int) args[1]);
|
||||||
|
|
||||||
|
text.setText((String) args[2]);
|
||||||
|
|
||||||
|
if (args.length > 3) {
|
||||||
|
setWindowPosition((WindowPosition) args[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
text.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClose(WindowManager manager) {
|
||||||
|
super.onClose(manager);
|
||||||
|
|
||||||
|
text.setText("");
|
||||||
|
}
|
||||||
|
}
|
||||||
202
src/main/java/com/bartlomiejpluta/demo/gui/EquipmentWindow.java
Normal file
@@ -0,0 +1,202 @@
|
|||||||
|
package com.bartlomiejpluta.demo.gui;
|
||||||
|
|
||||||
|
import com.bartlomiejpluta.base.api.context.Context;
|
||||||
|
import com.bartlomiejpluta.base.api.gui.*;
|
||||||
|
import com.bartlomiejpluta.base.api.input.Key;
|
||||||
|
import com.bartlomiejpluta.base.api.input.KeyAction;
|
||||||
|
import com.bartlomiejpluta.base.api.input.KeyEvent;
|
||||||
|
import com.bartlomiejpluta.base.lib.gui.HOptionChoice;
|
||||||
|
import com.bartlomiejpluta.base.lib.gui.Label;
|
||||||
|
import com.bartlomiejpluta.base.lib.gui.VGridOptionChoice;
|
||||||
|
import com.bartlomiejpluta.base.lib.gui.VOptionChoice;
|
||||||
|
import com.bartlomiejpluta.demo.entity.Player;
|
||||||
|
import com.bartlomiejpluta.demo.runner.DemoRunner;
|
||||||
|
import com.bartlomiejpluta.demo.world.item.Item;
|
||||||
|
import com.bartlomiejpluta.demo.world.item.Useable;
|
||||||
|
import com.bartlomiejpluta.demo.world.potion.Medicament;
|
||||||
|
import com.bartlomiejpluta.demo.world.weapon.MeleeWeapon;
|
||||||
|
import com.bartlomiejpluta.demo.world.weapon.RangedWeapon;
|
||||||
|
import com.bartlomiejpluta.demo.world.weapon.ThrowingWeapon;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
|
|
||||||
|
import static java.lang.String.format;
|
||||||
|
|
||||||
|
|
||||||
|
public class EquipmentWindow extends DecoratedWindow {
|
||||||
|
private final Player player;
|
||||||
|
|
||||||
|
private final Window popupMenuWindow;
|
||||||
|
private final Button useBtn;
|
||||||
|
private final Button dropBtn;
|
||||||
|
private final Button cancelBtn;
|
||||||
|
private final VOptionChoice popupMenu;
|
||||||
|
|
||||||
|
@Ref("layout")
|
||||||
|
private HOptionChoice layout;
|
||||||
|
|
||||||
|
@Ref("equipment")
|
||||||
|
private VGridOptionChoice equipment;
|
||||||
|
|
||||||
|
@Ref("inventory")
|
||||||
|
private VGridOptionChoice inventory;
|
||||||
|
|
||||||
|
@Ref("weapon")
|
||||||
|
private ItemIconView weaponSlot;
|
||||||
|
|
||||||
|
@Ref("ammo")
|
||||||
|
private ItemIconView ammoSlot;
|
||||||
|
|
||||||
|
@Ref("item-name")
|
||||||
|
private Label nameLbl;
|
||||||
|
|
||||||
|
@Ref("item-details")
|
||||||
|
private Label detailsLbl;
|
||||||
|
|
||||||
|
|
||||||
|
public EquipmentWindow(Context context, GUI gui, Map<String, Component> refs) {
|
||||||
|
super(context, gui, refs);
|
||||||
|
this.player = DemoRunner.instance().getPlayer();
|
||||||
|
this.popupMenuWindow = gui.inflateWindow(A.widgets.eq_item_menu.$);
|
||||||
|
this.popupMenu = popupMenuWindow.reference("menu", VOptionChoice.class);
|
||||||
|
this.useBtn = popupMenuWindow.reference("use", Button.class);
|
||||||
|
this.dropBtn = popupMenuWindow.reference("drop", Button.class);
|
||||||
|
this.cancelBtn = popupMenuWindow.reference("cancel", Button.class);
|
||||||
|
|
||||||
|
addEventListener(KeyEvent.TYPE, this::handleKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleKey(KeyEvent event) {
|
||||||
|
if (event.getKey() == Key.KEY_TAB && event.getAction() == KeyAction.PRESS) {
|
||||||
|
layout.selectNext();
|
||||||
|
layout.focus();
|
||||||
|
updateItemDetails(((VGridOptionChoice) layout.getSelectedComponent()).getSelectedComponent());
|
||||||
|
event.consume();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onOpen(WindowManager manager, Object... args) {
|
||||||
|
super.onOpen(manager, args);
|
||||||
|
|
||||||
|
cancelBtn.setAction(manager::close);
|
||||||
|
inventory.setOnSelect(this::updateItemDetails);
|
||||||
|
equipment.setOnSelect(this::updateItemDetails);
|
||||||
|
|
||||||
|
updateEquipment();
|
||||||
|
|
||||||
|
layout.select(1);
|
||||||
|
layout.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClose(WindowManager manager) {
|
||||||
|
super.onClose(manager);
|
||||||
|
layout.blur();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateEquipment() {
|
||||||
|
var i = 0;
|
||||||
|
for (var child : inventory.getChildren()) {
|
||||||
|
var slot = (ItemIconView) child;
|
||||||
|
slot.setItem(player.getEquipmentItem(i++));
|
||||||
|
slot.setAction(this::handleInventoryClick);
|
||||||
|
}
|
||||||
|
|
||||||
|
weaponSlot.setItem(player.getWeapon());
|
||||||
|
weaponSlot.setAction(handleEquipmentClick(() -> {
|
||||||
|
player.setWeapon(null);
|
||||||
|
updateEquipment();
|
||||||
|
manager.close();
|
||||||
|
}));
|
||||||
|
|
||||||
|
ammoSlot.setItem(player.getAmmunition());
|
||||||
|
ammoSlot.setAction(handleEquipmentClick(() -> {
|
||||||
|
player.setAmmunition(null);
|
||||||
|
updateEquipment();
|
||||||
|
manager.close();
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
private BiConsumer<ItemIconView, Item> handleEquipmentClick(Runnable deequip) {
|
||||||
|
return (slot, item) -> {
|
||||||
|
useBtn.setText("Disarm");
|
||||||
|
popupMenu.select(0);
|
||||||
|
popupMenu.focus();
|
||||||
|
|
||||||
|
manager.open(popupMenuWindow);
|
||||||
|
|
||||||
|
useBtn.setAction(deequip);
|
||||||
|
|
||||||
|
dropBtn.setAction(() -> {
|
||||||
|
player.dropItemFromEquipment(item);
|
||||||
|
slot.setItem(null);
|
||||||
|
updateItemDetails(slot);
|
||||||
|
manager.close();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleInventoryClick(ItemIconView slot, Item item) {
|
||||||
|
useBtn.setText(getButtonTitle(item));
|
||||||
|
popupMenu.select(0);
|
||||||
|
popupMenu.focus();
|
||||||
|
|
||||||
|
manager.open(popupMenuWindow);
|
||||||
|
|
||||||
|
if (item instanceof Useable useable) {
|
||||||
|
useBtn.setAction(() -> {
|
||||||
|
useable.use(player);
|
||||||
|
updateEquipment();
|
||||||
|
manager.close();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
dropBtn.setAction(() -> {
|
||||||
|
player.dropItemFromEquipment(item);
|
||||||
|
slot.setItem(null);
|
||||||
|
updateItemDetails(slot);
|
||||||
|
manager.close();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateItemDetails(Component slot) {
|
||||||
|
var item = ((ItemIconView) slot).getItem();
|
||||||
|
|
||||||
|
if (item == null) {
|
||||||
|
nameLbl.setText("");
|
||||||
|
detailsLbl.setText("");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nameLbl.setText(item.getName());
|
||||||
|
detailsLbl.setText("");
|
||||||
|
|
||||||
|
if (item instanceof MeleeWeapon weapon) {
|
||||||
|
detailsLbl.setText(format("Damage: %s\nCooldown: %s\n", weapon.getDmgRoller(), weapon.getCooldown()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item instanceof RangedWeapon weapon) {
|
||||||
|
detailsLbl.setText(format("Damage: %s\nRange: %s\nCooldown: %s\n", weapon.getDmgRoller(), weapon.getRangeRoller(), weapon.getCooldown()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item instanceof ThrowingWeapon weapon) {
|
||||||
|
detailsLbl.setText(format("Damage: %s\nRange: %s\nCooldown: %s\n", weapon.getDmgRoller(), weapon.getRangeRoller(), weapon.getCooldown()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item instanceof Medicament medicament) {
|
||||||
|
detailsLbl.setText(format("Restores: %s HP\n", medicament.getRoller()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getButtonTitle(Item item) {
|
||||||
|
if (item instanceof Useable useable) {
|
||||||
|
return useable.usageName();
|
||||||
|
}
|
||||||
|
|
||||||
|
return "Use";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,32 +1,28 @@
|
|||||||
package com.bartlomiejpluta.demo.gui;
|
package com.bartlomiejpluta.demo.gui;
|
||||||
|
|
||||||
import lombok.*;
|
|
||||||
import com.bartlomiejpluta.base.api.context.Context;
|
import com.bartlomiejpluta.base.api.context.Context;
|
||||||
import com.bartlomiejpluta.base.api.screen.Screen;
|
import com.bartlomiejpluta.base.api.gui.Component;
|
||||||
import com.bartlomiejpluta.base.api.gui.*;
|
import com.bartlomiejpluta.base.api.gui.GUI;
|
||||||
import com.bartlomiejpluta.base.lib.gui.*;
|
import com.bartlomiejpluta.base.api.gui.Ref;
|
||||||
|
import com.bartlomiejpluta.base.api.gui.WindowManager;
|
||||||
|
import com.bartlomiejpluta.base.lib.gui.VOptionChoice;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
|
||||||
public class GameMenuWindow extends DecoratedWindow implements Inflatable {
|
public class GameMenuWindow extends DecoratedWindow {
|
||||||
|
|
||||||
@Ref("resume_game")
|
@Ref("menu")
|
||||||
@Getter
|
private VOptionChoice menu;
|
||||||
private Button resumeGameBtn;
|
|
||||||
|
|
||||||
@Ref("start_menu")
|
public GameMenuWindow(Context context, GUI gui, Map<String, Component> refs) {
|
||||||
@Getter
|
super(context, gui, refs);
|
||||||
private Button startMenuBtn;
|
|
||||||
|
|
||||||
@Ref("exit")
|
|
||||||
@Getter
|
|
||||||
private Button exitBtn;
|
|
||||||
|
|
||||||
public GameMenuWindow(Context context, GUI gui) {
|
|
||||||
super(context, gui);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onInflate() {
|
public void onOpen(WindowManager manager, Object[] args) {
|
||||||
resumeGameBtn.focus();
|
super.onOpen(manager, args);
|
||||||
|
menu.select(0);
|
||||||
|
menu.focus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,20 +1,22 @@
|
|||||||
package com.bartlomiejpluta.demo.gui;
|
package com.bartlomiejpluta.demo.gui;
|
||||||
|
|
||||||
|
import com.bartlomiejpluta.base.api.context.Context;
|
||||||
|
import com.bartlomiejpluta.base.api.gui.Component;
|
||||||
|
import com.bartlomiejpluta.base.api.gui.GUI;
|
||||||
|
import com.bartlomiejpluta.base.api.gui.Ref;
|
||||||
|
import com.bartlomiejpluta.base.api.screen.Screen;
|
||||||
|
import com.bartlomiejpluta.base.lib.gui.BorderLayout;
|
||||||
|
import com.bartlomiejpluta.base.lib.gui.Label;
|
||||||
|
import com.bartlomiejpluta.base.lib.gui.TextView;
|
||||||
|
import com.bartlomiejpluta.demo.entity.Player;
|
||||||
|
import com.bartlomiejpluta.demo.event.EnemyDiedEvent;
|
||||||
|
import com.bartlomiejpluta.demo.event.HitEvent;
|
||||||
|
import com.bartlomiejpluta.demo.runner.DemoRunner;
|
||||||
|
import com.bartlomiejpluta.demo.util.LimitedQueue;
|
||||||
|
import com.bartlomiejpluta.demo.world.time.WorldTime;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import com.bartlomiejpluta.base.api.gui.*;
|
import java.util.Map;
|
||||||
import com.bartlomiejpluta.base.lib.gui.*;
|
|
||||||
|
|
||||||
import com.bartlomiejpluta.base.api.screen.*;
|
|
||||||
import com.bartlomiejpluta.base.api.context.Context;
|
|
||||||
import com.bartlomiejpluta.base.api.input.*;
|
|
||||||
|
|
||||||
import com.bartlomiejpluta.demo.runner.DemoRunner;
|
|
||||||
import com.bartlomiejpluta.demo.entity.*;
|
|
||||||
|
|
||||||
import com.bartlomiejpluta.demo.event.*;
|
|
||||||
import com.bartlomiejpluta.demo.util.LimitedQueue;
|
|
||||||
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@@ -22,10 +24,10 @@ public class HUD extends BorderLayout {
|
|||||||
private static final int MAX_LOG_SIZE = 10;
|
private static final int MAX_LOG_SIZE = 10;
|
||||||
private static final float LOG_VISIBILITY_DURATION = 8000f;
|
private static final float LOG_VISIBILITY_DURATION = 8000f;
|
||||||
private static final float LOG_VISIBILITY_FADING_OUT = 1000f;
|
private static final float LOG_VISIBILITY_FADING_OUT = 1000f;
|
||||||
private final DemoRunner runner;
|
|
||||||
private final Player player;
|
private final Player player;
|
||||||
|
private final WorldTime time;
|
||||||
private final Runtime runtime;
|
private final Runtime runtime;
|
||||||
private LimitedQueue<String> logger = new LimitedQueue<>(MAX_LOG_SIZE);
|
private final LimitedQueue<String> logger = new LimitedQueue<>(MAX_LOG_SIZE);
|
||||||
|
|
||||||
private float logVisibilityDuration = 0f;
|
private float logVisibilityDuration = 0f;
|
||||||
|
|
||||||
@@ -33,16 +35,16 @@ public class HUD extends BorderLayout {
|
|||||||
private Bar hp;
|
private Bar hp;
|
||||||
|
|
||||||
@Ref("debug")
|
@Ref("debug")
|
||||||
private Label debugLbl;
|
private TextView debugTxt;
|
||||||
|
|
||||||
@Ref("log")
|
@Ref("log")
|
||||||
private Label logLbl;
|
private Label logLbl;
|
||||||
|
|
||||||
public HUD(Context context, GUI gui) {
|
public HUD(Context context, GUI gui, Map<String, Component> refs) {
|
||||||
super(context, gui);
|
super(context, gui, refs);
|
||||||
this.runner = (DemoRunner) context.getGameRunner();
|
this.player = DemoRunner.instance().getPlayer();
|
||||||
this.player = runner.getPlayer();
|
|
||||||
this.runtime = Runtime.getRuntime();
|
this.runtime = Runtime.getRuntime();
|
||||||
|
this.time = DemoRunner.instance().getTime();
|
||||||
context.addEventListener(HitEvent.TYPE, this::logHitEvent);
|
context.addEventListener(HitEvent.TYPE, this::logHitEvent);
|
||||||
context.addEventListener(EnemyDiedEvent.TYPE, this::logEnemyDiedEvent);
|
context.addEventListener(EnemyDiedEvent.TYPE, this::logEnemyDiedEvent);
|
||||||
}
|
}
|
||||||
@@ -68,7 +70,7 @@ public class HUD extends BorderLayout {
|
|||||||
|
|
||||||
hp.setValue((float) player.getHp() / (float) player.getMaxHp());
|
hp.setValue((float) player.getHp() / (float) player.getMaxHp());
|
||||||
|
|
||||||
if(logVisibilityDuration > 0) {
|
if (logVisibilityDuration > 0) {
|
||||||
logVisibilityDuration -= dt * 1000;
|
logVisibilityDuration -= dt * 1000;
|
||||||
} else {
|
} else {
|
||||||
logVisibilityDuration = 0;
|
logVisibilityDuration = 0;
|
||||||
@@ -79,19 +81,7 @@ public class HUD extends BorderLayout {
|
|||||||
public void draw(Screen screen, GUI gui) {
|
public void draw(Screen screen, GUI gui) {
|
||||||
var coords = player.getCoordinates();
|
var coords = player.getCoordinates();
|
||||||
var pos = player.getPosition();
|
var pos = player.getPosition();
|
||||||
debugLbl.setText(String.format(
|
debugTxt.setText(String.format("Clock: %02d:%02d\nTime: %.2f\nMem: %.2f / %.2f [MB]\nCoords: %d : %d\nPos: %.2f : %.2f\nEntities: %d\n", time.getHour(), time.getMinute(), time.getProgress(), runtime.totalMemory() / 1024f / 1024f, runtime.maxMemory() / 1024f / 1024f, coords.x(), coords.y(), pos.x(), pos.y(), player.getLayer().getEntities().size()));
|
||||||
"FPS: %.2f\n" +
|
|
||||||
"Mem: %.2f / %.2f [MB]\n" +
|
|
||||||
"Coords: %d : %d\n" +
|
|
||||||
"Pos: %.2f : %.2f\n" +
|
|
||||||
"Entities: %d",
|
|
||||||
runner.instantFPS(),
|
|
||||||
runtime.totalMemory() / 1024f / 1024f,
|
|
||||||
runtime.maxMemory() / 1024f / 1024f,
|
|
||||||
coords.x(), coords.y(),
|
|
||||||
pos.x(), pos.y(),
|
|
||||||
player.getLayer().getEntities().size() - 1
|
|
||||||
));
|
|
||||||
|
|
||||||
logLbl.setAlpha(Math.min(1f, logVisibilityDuration / LOG_VISIBILITY_FADING_OUT));
|
logLbl.setAlpha(Math.min(1f, logVisibilityDuration / LOG_VISIBILITY_FADING_OUT));
|
||||||
|
|
||||||
|
|||||||
132
src/main/java/com/bartlomiejpluta/demo/gui/ItemIconView.java
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
package com.bartlomiejpluta.demo.gui;
|
||||||
|
|
||||||
|
import A.fonts;
|
||||||
|
import com.bartlomiejpluta.base.api.context.Context;
|
||||||
|
import com.bartlomiejpluta.base.api.gui.*;
|
||||||
|
import com.bartlomiejpluta.base.api.icon.Icon;
|
||||||
|
import com.bartlomiejpluta.base.api.input.Key;
|
||||||
|
import com.bartlomiejpluta.base.api.input.KeyAction;
|
||||||
|
import com.bartlomiejpluta.base.api.input.KeyEvent;
|
||||||
|
import com.bartlomiejpluta.base.api.screen.Screen;
|
||||||
|
import com.bartlomiejpluta.base.lib.gui.IconView;
|
||||||
|
import com.bartlomiejpluta.demo.util.IconUtil;
|
||||||
|
import com.bartlomiejpluta.demo.world.item.Item;
|
||||||
|
import com.bartlomiejpluta.demo.world.item.ItemStack;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
|
|
||||||
|
public class ItemIconView extends IconView {
|
||||||
|
private final GUI gui;
|
||||||
|
private final Color normal;
|
||||||
|
private final Color hover;
|
||||||
|
private final Color textColor;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private Item item;
|
||||||
|
|
||||||
|
private IconSet placeholderIconSet;
|
||||||
|
private Paint placeholderIconPaint;
|
||||||
|
|
||||||
|
private int placeholderIconSetRow;
|
||||||
|
private int placeholderIconSetColumn;
|
||||||
|
|
||||||
|
@Setter
|
||||||
|
private BiConsumer<ItemIconView, Item> action;
|
||||||
|
|
||||||
|
public ItemIconView(Context context, GUI gui, Map<String, Component> refs) {
|
||||||
|
super(context, gui, refs);
|
||||||
|
this.gui = gui;
|
||||||
|
this.normal = gui.createColor();
|
||||||
|
this.hover = gui.createColor();
|
||||||
|
this.textColor = gui.createColor();
|
||||||
|
|
||||||
|
normal.setRGBA(0x444444FF);
|
||||||
|
hover.setRGBA(0x888888FF);
|
||||||
|
textColor.setRGBA(0xFFFFFFFF);
|
||||||
|
|
||||||
|
super.setScale(2f);
|
||||||
|
|
||||||
|
addEventListener(KeyEvent.TYPE, this::handleKeyEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setItem(Item item) {
|
||||||
|
this.item = item;
|
||||||
|
super.setIcon(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setIcon(Icon icon) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setIconSet(String iconSetUid) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setIconSetRow(@NonNull Integer iconSetRow) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setIconSetColumn(@NonNull Integer iconSetColumn) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Attribute(value = "placeholder", separator = ",")
|
||||||
|
public void setPlaceholderIcon(String icon, int row, int column) {
|
||||||
|
this.placeholderIconPaint = gui.createPaint();
|
||||||
|
this.placeholderIconSet = gui.getIconSet(A.iconsets.byName(icon).$);
|
||||||
|
this.placeholderIconSetRow = row;
|
||||||
|
this.placeholderIconSetColumn = column;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleKeyEvent(KeyEvent event) {
|
||||||
|
if (event.getKey() == Key.KEY_ENTER && event.getAction() == KeyAction.PRESS && item != null && action != null) {
|
||||||
|
event.consume();
|
||||||
|
action.accept(this, item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected float getContentWidth() {
|
||||||
|
return 68f;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected float getContentHeight() {
|
||||||
|
return 68f;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void draw(Screen screen, GUI gui) {
|
||||||
|
gui.beginPath();
|
||||||
|
gui.drawRectangle(x, y, getWidth(), getHeight());
|
||||||
|
gui.setFillColor(focused ? hover : normal);
|
||||||
|
gui.fill();
|
||||||
|
gui.closePath();
|
||||||
|
|
||||||
|
if (item == null && placeholderIconSet != null) {
|
||||||
|
gui.icon(this.x, this.y, 2, 2, 0, 0.2f, placeholderIconSet, placeholderIconSetRow, placeholderIconSetColumn, placeholderIconPaint);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
super.draw(screen, gui);
|
||||||
|
|
||||||
|
if (item != null && item instanceof ItemStack stack) {
|
||||||
|
gui.beginPath();
|
||||||
|
gui.setFontFace(fonts.roboto_regular.$);
|
||||||
|
gui.setFontSize(17);
|
||||||
|
gui.putText(x + 15, y + 5, String.valueOf(stack.getCount()));
|
||||||
|
gui.setFillColor(textColor);
|
||||||
|
gui.fill();
|
||||||
|
gui.closePath();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
89
src/main/java/com/bartlomiejpluta/demo/gui/LootWindow.java
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
package com.bartlomiejpluta.demo.gui;
|
||||||
|
|
||||||
|
import com.bartlomiejpluta.base.api.context.Context;
|
||||||
|
import com.bartlomiejpluta.base.api.gui.*;
|
||||||
|
import com.bartlomiejpluta.base.lib.gui.Label;
|
||||||
|
import com.bartlomiejpluta.base.lib.gui.VGridOptionChoice;
|
||||||
|
import com.bartlomiejpluta.demo.entity.Enemy;
|
||||||
|
import com.bartlomiejpluta.demo.entity.Player;
|
||||||
|
import com.bartlomiejpluta.demo.runner.DemoRunner;
|
||||||
|
import com.bartlomiejpluta.demo.world.item.Item;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class LootWindow extends DecoratedWindow implements Inflatable {
|
||||||
|
private final Player player;
|
||||||
|
|
||||||
|
@Ref("title")
|
||||||
|
private Label titleLbl;
|
||||||
|
|
||||||
|
@Ref("loot")
|
||||||
|
private VGridOptionChoice lootMenu;
|
||||||
|
|
||||||
|
private Item[] loot;
|
||||||
|
|
||||||
|
private ItemIconView[] slots = new ItemIconView[Enemy.MAX_LOOT];
|
||||||
|
|
||||||
|
public LootWindow(Context context, GUI gui, Map<String, Component> refs) {
|
||||||
|
super(context, gui, refs);
|
||||||
|
this.player = DemoRunner.instance().getPlayer();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onInflate() {
|
||||||
|
for (int i = 0; i < Enemy.MAX_LOOT; ++i) {
|
||||||
|
var itemView = new ItemIconView(context, gui, Map.of());
|
||||||
|
itemView.setMargin(5f);
|
||||||
|
lootMenu.add(itemView);
|
||||||
|
slots[i] = itemView;
|
||||||
|
itemView.setAction(this::handleClick);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onOpen(WindowManager manager, Object[] args) {
|
||||||
|
super.onOpen(manager, args);
|
||||||
|
|
||||||
|
this.loot = (Item[]) args[0];
|
||||||
|
this.titleLbl.setText((String) args[1]);
|
||||||
|
this.lootMenu.select(0, 0);
|
||||||
|
this.lootMenu.focus();
|
||||||
|
updateSlots();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClose(WindowManager manager) {
|
||||||
|
super.onClose(manager);
|
||||||
|
|
||||||
|
clearSlots();
|
||||||
|
this.loot = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleClick(ItemIconView slot, Item item) {
|
||||||
|
if (item == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player.pushItemToEquipment(item)) {
|
||||||
|
for (int i = 0; i < Enemy.MAX_LOOT; i++) {
|
||||||
|
if (loot[i] == item) {
|
||||||
|
loot[i] = null;
|
||||||
|
slot.setItem(null);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateSlots() {
|
||||||
|
for (int i = 0; i < Enemy.MAX_LOOT; ++i) {
|
||||||
|
slots[i].setItem(loot[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clearSlots() {
|
||||||
|
for (var slot : slots) {
|
||||||
|
slot.setItem(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
package com.bartlomiejpluta.demo.gui;
|
||||||
|
|
||||||
|
import com.bartlomiejpluta.base.api.context.Context;
|
||||||
|
import com.bartlomiejpluta.base.api.gui.Component;
|
||||||
|
import com.bartlomiejpluta.base.api.gui.GUI;
|
||||||
|
import com.bartlomiejpluta.base.lib.gui.TextView;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class PrintTextView extends TextView {
|
||||||
|
|
||||||
|
@Setter
|
||||||
|
private Float duration;
|
||||||
|
|
||||||
|
private float acc;
|
||||||
|
|
||||||
|
private String originalText;
|
||||||
|
|
||||||
|
public void start() {
|
||||||
|
acc = 0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isPrinting() {
|
||||||
|
return originalText.length() != super.getText().length();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void printAll() {
|
||||||
|
acc = originalText.length() * duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setText(String text) {
|
||||||
|
super.setText("");
|
||||||
|
this.originalText = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(float dt) {
|
||||||
|
super.update(dt);
|
||||||
|
|
||||||
|
acc += dt;
|
||||||
|
super.setText(originalText.substring(0, Math.min(originalText.length(), (int) (acc / duration))));
|
||||||
|
}
|
||||||
|
|
||||||
|
public PrintTextView(Context context, GUI gui, Map<String, Component> refs) {
|
||||||
|
super(context, gui, refs);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,27 +1,27 @@
|
|||||||
package com.bartlomiejpluta.demo.gui;
|
package com.bartlomiejpluta.demo.gui;
|
||||||
|
|
||||||
import lombok.*;
|
|
||||||
import com.bartlomiejpluta.base.api.context.Context;
|
import com.bartlomiejpluta.base.api.context.Context;
|
||||||
import com.bartlomiejpluta.base.api.screen.Screen;
|
import com.bartlomiejpluta.base.api.gui.Component;
|
||||||
import com.bartlomiejpluta.base.api.gui.*;
|
import com.bartlomiejpluta.base.api.gui.GUI;
|
||||||
import com.bartlomiejpluta.base.lib.gui.*;
|
import com.bartlomiejpluta.base.api.gui.Ref;
|
||||||
|
import com.bartlomiejpluta.base.api.gui.WindowManager;
|
||||||
|
import com.bartlomiejpluta.base.lib.gui.VOptionChoice;
|
||||||
|
|
||||||
public class StartMenuWindow extends DecoratedWindow implements Inflatable {
|
import java.util.Map;
|
||||||
|
|
||||||
@Ref("new_game")
|
public class StartMenuWindow extends DecoratedWindow {
|
||||||
@Getter
|
|
||||||
private Button newGameBtn;
|
|
||||||
|
|
||||||
@Ref("exit")
|
@Ref("menu")
|
||||||
@Getter
|
private VOptionChoice menu;
|
||||||
private Button exitBtn;
|
|
||||||
|
|
||||||
public StartMenuWindow(Context context, GUI gui) {
|
public StartMenuWindow(Context context, GUI gui, Map<String, Component> refs) {
|
||||||
super(context, gui);
|
super(context, gui, refs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onInflate() {
|
public void onOpen(WindowManager manager, Object[] args) {
|
||||||
newGameBtn.focus();
|
super.onOpen(manager, args);
|
||||||
|
menu.select(0);
|
||||||
|
menu.focus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,45 +1,54 @@
|
|||||||
package com.bartlomiejpluta.demo.map;
|
package com.bartlomiejpluta.demo.map;
|
||||||
|
|
||||||
import lombok.*;
|
|
||||||
|
|
||||||
import com.bartlomiejpluta.base.api.map.handler.MapHandler;
|
|
||||||
import com.bartlomiejpluta.base.api.map.model.GameMap;
|
|
||||||
import com.bartlomiejpluta.base.api.map.layer.object.ObjectLayer;
|
|
||||||
import com.bartlomiejpluta.base.api.context.Context;
|
|
||||||
import com.bartlomiejpluta.base.api.move.Direction;
|
|
||||||
import com.bartlomiejpluta.base.api.screen.Screen;
|
|
||||||
import com.bartlomiejpluta.base.api.camera.Camera;
|
import com.bartlomiejpluta.base.api.camera.Camera;
|
||||||
import com.bartlomiejpluta.base.api.input.*;
|
import com.bartlomiejpluta.base.api.context.Context;
|
||||||
|
import com.bartlomiejpluta.base.api.entity.Entity;
|
||||||
import com.bartlomiejpluta.base.lib.camera.*;
|
import com.bartlomiejpluta.base.api.gui.WindowPosition;
|
||||||
|
import com.bartlomiejpluta.base.api.icon.Icon;
|
||||||
import com.bartlomiejpluta.base.util.world.EntitySpawner;
|
import com.bartlomiejpluta.base.api.input.Input;
|
||||||
|
import com.bartlomiejpluta.base.api.input.Key;
|
||||||
import com.bartlomiejpluta.demo.runner.DemoRunner;
|
import com.bartlomiejpluta.base.api.light.Light;
|
||||||
|
import com.bartlomiejpluta.base.api.map.handler.MapHandler;
|
||||||
|
import com.bartlomiejpluta.base.api.map.layer.object.MapPin;
|
||||||
|
import com.bartlomiejpluta.base.api.map.model.GameMap;
|
||||||
|
import com.bartlomiejpluta.base.api.screen.Screen;
|
||||||
|
import com.bartlomiejpluta.base.lib.camera.CameraController;
|
||||||
|
import com.bartlomiejpluta.base.lib.camera.FollowingCameraController;
|
||||||
|
import com.bartlomiejpluta.base.util.input.InputUtil;
|
||||||
|
import com.bartlomiejpluta.base.util.world.CharacterSpawner;
|
||||||
|
import com.bartlomiejpluta.base.util.world.Warp;
|
||||||
import com.bartlomiejpluta.demo.entity.*;
|
import com.bartlomiejpluta.demo.entity.*;
|
||||||
import com.bartlomiejpluta.demo.event.*;
|
import com.bartlomiejpluta.demo.event.EnemyDiedEvent;
|
||||||
|
import com.bartlomiejpluta.demo.menu.GuiManager;
|
||||||
|
import com.bartlomiejpluta.demo.runner.DemoRunner;
|
||||||
|
import com.bartlomiejpluta.demo.world.light.Torch;
|
||||||
|
import com.bartlomiejpluta.demo.world.potion.Medicament;
|
||||||
|
import lombok.NonNull;
|
||||||
|
|
||||||
import com.bartlomiejpluta.demo.util.*;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
import java.util.*;
|
import static java.lang.Math.*;
|
||||||
import java.util.function.*;
|
|
||||||
|
|
||||||
public abstract class BaseMapHandler implements MapHandler {
|
public abstract class BaseMapHandler implements MapHandler {
|
||||||
protected Screen screen;
|
protected Screen screen;
|
||||||
protected Context context;
|
protected Context context;
|
||||||
protected DemoRunner runner;
|
protected DemoRunner runner;
|
||||||
|
protected GuiManager guiManager;
|
||||||
protected Camera camera;
|
protected Camera camera;
|
||||||
protected GameMap map;
|
protected GameMap map;
|
||||||
protected Player player;
|
protected Player player;
|
||||||
protected ObjectLayer mainLayer;
|
|
||||||
protected CameraController cameraController;
|
protected CameraController cameraController;
|
||||||
protected final List<EntitySpawner> spawners = new LinkedList<>();
|
|
||||||
|
protected boolean dayNightCycle = false;
|
||||||
|
|
||||||
|
protected boolean controls = true;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Context context, GameMap map) {
|
public void onCreate(Context context, GameMap map) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.screen = context.getScreen();
|
this.screen = context.getScreen();
|
||||||
this.runner = (DemoRunner) context.getGameRunner();
|
this.runner = DemoRunner.instance();
|
||||||
|
this.guiManager = runner.getGuiManager();
|
||||||
this.camera = context.getCamera();
|
this.camera = context.getCamera();
|
||||||
this.map = map;
|
this.map = map;
|
||||||
this.player = runner.getPlayer();
|
this.player = runner.getPlayer();
|
||||||
@@ -50,70 +59,117 @@ public abstract class BaseMapHandler implements MapHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void input(Input input) {
|
public void input(Input input) {
|
||||||
if(context.isPaused()) {
|
if (context.isPaused()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(input.isKeyPressed(Key.KEY_SPACE)) {
|
if (guiManager.openedWindows() > 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (input.isKeyPressed(Key.KEY_SPACE)) {
|
||||||
player.attack();
|
player.attack();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(input.isKeyPressed(Key.KEY_ENTER)) {
|
if (input.isKeyPressed(Key.KEY_ENTER)) {
|
||||||
player.interact();
|
player.interact();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(input.isKeyPressed(Key.KEY_LEFT_CONTROL)) {
|
if (!controls) {
|
||||||
if(input.isKeyPressed(Key.KEY_DOWN)) {
|
return;
|
||||||
player.setFaceDirection(Direction.DOWN);
|
|
||||||
} else if(input.isKeyPressed(Key.KEY_UP)) {
|
|
||||||
player.setFaceDirection(Direction.UP);
|
|
||||||
} else if(input.isKeyPressed(Key.KEY_LEFT)) {
|
|
||||||
player.setFaceDirection(Direction.LEFT);
|
|
||||||
} else if(input.isKeyPressed(Key.KEY_RIGHT)) {
|
|
||||||
player.setFaceDirection(Direction.RIGHT);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if(input.isKeyPressed(Key.KEY_DOWN)) {
|
|
||||||
mainLayer.pushMovement(player.prepareMovement(Direction.DOWN));
|
|
||||||
} else if(input.isKeyPressed(Key.KEY_UP)) {
|
|
||||||
mainLayer.pushMovement(player.prepareMovement(Direction.UP));
|
|
||||||
} else if(input.isKeyPressed(Key.KEY_LEFT)) {
|
|
||||||
mainLayer.pushMovement(player.prepareMovement(Direction.LEFT));
|
|
||||||
} else if(input.isKeyPressed(Key.KEY_RIGHT)) {
|
|
||||||
mainLayer.pushMovement(player.prepareMovement(Direction.RIGHT));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InputUtil.handleBasicControl(player, input);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(Context context, GameMap map, float dt) {
|
public void update(Context context, GameMap map, float dt) {
|
||||||
cameraController.update();
|
cameraController.update();
|
||||||
for(var spawner : spawners) {
|
|
||||||
spawner.update(dt);
|
if(!dayNightCycle) {
|
||||||
}
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Enemy enemy(@NonNull String id) {
|
var x = runner.getTime().getProgress();
|
||||||
return new Enemy(context, runner.getEnemyDAO().find(id));
|
map.setAmbientColor(
|
||||||
|
ambientColor(1.2f, -0.3f, 0, x),
|
||||||
|
ambientColor(1.4f, -0.6f, 0.05f, x),
|
||||||
|
ambientColor(1.7f, -1.1f, 0.2f, x)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Enemy enemy(int x, int y, @NonNull String id) {
|
private float ambientColor(float a, float b, float offset, float x) {
|
||||||
var enemy = new Enemy(context, runner.getEnemyDAO().find(id));
|
return ((float) max(sin(x * PI * a + b), 0) + offset) / (1 + offset);
|
||||||
enemy.setCoordinates(x, y);
|
|
||||||
mainLayer.addEntity(enemy);
|
|
||||||
return enemy;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public MapObject object(int x, int y, @NonNull String id) {
|
public CompletableFuture<Object> dialog(NamedCharacter speaker, String message, WindowPosition position) {
|
||||||
var object = new MapObject(context, runner.getMapObjectDAO().find(id));
|
return guiManager.showDialog(speaker.getName(), speaker.getDialogNameColor(), message, position);
|
||||||
object.setCoordinates(x, y);
|
|
||||||
mainLayer.addEntity(object);
|
|
||||||
return object;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public EntitySpawner spawner(int x, int y, ObjectLayer layer) {
|
public CompletableFuture<Object> dialog(NamedCharacter speaker, String message) {
|
||||||
var spawner = new EntitySpawner(x, y, context, map, layer).trackEntities(EnemyDiedEvent.TYPE);
|
return guiManager.showDialog(speaker.getName(), speaker.getDialogNameColor(), message, WindowPosition.BOTTOM);
|
||||||
this.spawners.add(spawner);
|
}
|
||||||
return spawner;
|
|
||||||
|
public CompletableFuture<Integer> dialogChoice(NamedCharacter speaker, String... choices) {
|
||||||
|
return guiManager.showDialogChoice(speaker.getName(), speaker.getDialogNameColor(), choices);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected <T extends Entity> T addEntity(T entity, MapPin tile) {
|
||||||
|
entity.setCoordinates(tile.getX(), tile.getY());
|
||||||
|
map.getObjectLayer(tile.getLayer()).addEntity(entity);
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Enemy enemy(@NonNull MapPin tile, @NonNull String id) {
|
||||||
|
return addEntity(new Enemy(id), tile);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Friend friend(@NonNull MapPin tile, @NonNull String id) {
|
||||||
|
return addEntity(new Friend(id), tile);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Chest chest(@NonNull MapPin tile, @NonNull String id) {
|
||||||
|
return addEntity(new Chest(id), tile);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Door door(@NonNull MapPin tile, @NonNull MapPin target, @NonNull String id) {
|
||||||
|
return addEntity(new Door(target, id), tile);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CharacterSpawner spawner(@NonNull MapPin tile) {
|
||||||
|
return addEntity(new CharacterSpawner().trackEntities(EnemyDiedEvent.TYPE), tile);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Medicament medicament(@NonNull MapPin tile, @NonNull String id, int count) {
|
||||||
|
return addEntity(new Medicament(id, count), tile);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Icon icon(@NonNull MapPin tile, String iconSetUid, int row, int column) {
|
||||||
|
var icon = context.createIcon(iconSetUid, row, column);
|
||||||
|
icon.setScale(1f);
|
||||||
|
icon.setZIndex(-1);
|
||||||
|
return addEntity(icon, tile);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Torch torch(MapPin tile) {
|
||||||
|
var torch = new Torch();
|
||||||
|
map.getLayer(tile.getLayer()).addLight(torch);
|
||||||
|
torch.setCoordinates(tile.toCoordinates());
|
||||||
|
return torch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Light light(MapPin tile) {
|
||||||
|
var light = context.createLight();
|
||||||
|
map.getLayer(tile.getLayer()).addLight(light);
|
||||||
|
light.setCoordinates(tile.toCoordinates());
|
||||||
|
light.setIntensity(1f, 1f, 1f);
|
||||||
|
light.setAttenuation(0.1f, 0, 0.001f);
|
||||||
|
return light;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Warp warp(@NonNull MapPin tile, MapPin target) {
|
||||||
|
var warp = new Warp(target);
|
||||||
|
warp.setEntity(player);
|
||||||
|
return addEntity(warp, tile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package com.bartlomiejpluta.demo.map;
|
||||||
|
|
||||||
|
import com.bartlomiejpluta.base.api.context.Context;
|
||||||
|
import com.bartlomiejpluta.base.api.map.model.GameMap;
|
||||||
|
|
||||||
|
public class ForrestHandler extends BaseMapHandler {
|
||||||
|
@Override
|
||||||
|
public void onCreate(Context context, GameMap map) {
|
||||||
|
super.onCreate(context, map);
|
||||||
|
dayNightCycle = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
package com.bartlomiejpluta.demo.map;
|
|
||||||
|
|
||||||
import com.bartlomiejpluta.base.api.context.Context;
|
|
||||||
import com.bartlomiejpluta.base.api.input.Input;
|
|
||||||
import com.bartlomiejpluta.base.api.map.model.GameMap;
|
|
||||||
import com.bartlomiejpluta.base.api.screen.Screen;
|
|
||||||
|
|
||||||
public class ForrestTempleHandler extends BaseMapHandler {
|
|
||||||
public static final String UID = "f845355e-b9ad-4884-a217-dd3a4c18a3fa";
|
|
||||||
public static final int MAIN_LAYER = 4;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(Context context, GameMap map) {
|
|
||||||
super.onCreate(context, map);
|
|
||||||
this.mainLayer = map.getObjectLayer(MAIN_LAYER);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
package com.bartlomiejpluta.demo.map;
|
||||||
|
|
||||||
|
import A.animations;
|
||||||
|
import A.maps;
|
||||||
|
import com.bartlomiejpluta.base.api.context.Context;
|
||||||
|
import com.bartlomiejpluta.base.api.map.model.GameMap;
|
||||||
|
import com.bartlomiejpluta.base.util.path.CharacterPath;
|
||||||
|
import com.bartlomiejpluta.base.util.pathfinder.AstarPathFinder;
|
||||||
|
import com.bartlomiejpluta.base.util.pathfinder.PathFinder;
|
||||||
|
import com.bartlomiejpluta.demo.entity.Friend;
|
||||||
|
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
import static com.bartlomiejpluta.base.api.move.Direction.LEFT;
|
||||||
|
|
||||||
|
public class HeroHomeHandler extends BaseMapHandler {
|
||||||
|
private final PathFinder finder = new AstarPathFinder(100);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Context context, GameMap map) {
|
||||||
|
super.onCreate(context, map);
|
||||||
|
map.setAmbientColor(0.05f, 0.01f, 0.01f);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected CharacterPath<Friend> grandmaPath(Friend grandma) {
|
||||||
|
return new CharacterPath<Friend>()
|
||||||
|
.run(() -> controls = false)
|
||||||
|
.run(() -> player.runEmoji(A.animations.zzz.$, r -> r.repeat(5)))
|
||||||
|
.insertPath(finder.findPath(grandma.getLayer(), grandma, maps.hero_home.main.grandma_waking.toCoordinates()))
|
||||||
|
.wait(2f)
|
||||||
|
.turn(LEFT)
|
||||||
|
.wait(1f)
|
||||||
|
.suspend(() -> morningDialogWithGrandma(grandma))
|
||||||
|
.wait(1f)
|
||||||
|
.run(() -> controls = true)
|
||||||
|
.insertPath(finder.findPath(grandma.getLayer(), maps.hero_home.main.grandma_waking.toCoordinates(), maps.hero_home.main.grandma_origin.toCoordinates()))
|
||||||
|
.run(() -> grandma.randomMovementAI(4f, grandma.getCoordinates(), 4));
|
||||||
|
}
|
||||||
|
|
||||||
|
private CompletableFuture<Object> morningDialogWithGrandma(Friend grandma) {
|
||||||
|
return dialog(grandma, "Hello Honey, wake up, it's another beautiful day!")
|
||||||
|
.thenCompose(n -> dialog(player, "Ahhh, good morning Grandma!"))
|
||||||
|
.thenCompose(n -> dialog(grandma, "Have a wonderful day, Luna!"))
|
||||||
|
.thenCompose(n -> dialog(player, "Thank you Grandma, have a nice day too!"));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected CompletableFuture<Object> triggerGrandmaDialog(Friend grandma) {
|
||||||
|
return dialog(grandma, "What are you going to do today, Luna?")
|
||||||
|
.thenCompose(n -> dialogChoice(player,
|
||||||
|
"I'm going to fix your roof, Grandma",
|
||||||
|
"I'd like to look for some hidden treasure around your house",
|
||||||
|
"I'm going to kill the Dekus outside",
|
||||||
|
"Hmm... I don't know yet..."
|
||||||
|
)).thenCompose(o -> dialog(grandma, switch (o) {
|
||||||
|
case 0 -> "Ohh, Luna! It would be amazing, thank you!";
|
||||||
|
case 1 -> "It seems you are going to have a wonderful adventure. Good luck!";
|
||||||
|
case 2 -> "Be careful! Dekus are capable to attack from a distance!";
|
||||||
|
case 3 -> "Hmm... our roof requires urgent fix... also there are some dangerous Dekus around our house...";
|
||||||
|
default -> null;
|
||||||
|
}).thenApply(n -> o))
|
||||||
|
.thenCompose(o -> dialog(player, switch (o) {
|
||||||
|
case 0 -> "You're welcome Grandma!";
|
||||||
|
case 1 -> "Thank you Grandma! Hopefully will found something interesting...";
|
||||||
|
case 2 -> "Oh, thanks. I believe I also would need to have some ranged weapon...";
|
||||||
|
case 3 -> "Okay, there is lot of things to be done then.";
|
||||||
|
default -> null;
|
||||||
|
}))
|
||||||
|
.thenCompose(n -> dialog(player, "Okay, I need to go. Thank you Grandma!"))
|
||||||
|
.thenCompose(n -> dialog(grandma, "Thank you Luna! Be careful!"));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected CompletableFuture<Object> triggerNekoDialog(Friend neko) {
|
||||||
|
return dialog(player, "Ohhh, here you are Kitty...")
|
||||||
|
.thenCompose(n -> CompletableFuture.allOf(
|
||||||
|
player.runEmoji(animations.heart_emoji.$),
|
||||||
|
neko.runEmoji(animations.heart_emoji.$, r -> r.offset(0, -15).delay(100))
|
||||||
|
))
|
||||||
|
.thenCompose(n -> dialog(neko, "Meow, meow..."))
|
||||||
|
.thenCompose(n -> dialog(neko, "Purr, purr..."));
|
||||||
|
}
|
||||||
|
}
|
||||||
12
src/main/java/com/bartlomiejpluta/demo/map/HeroHouse.java
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
package com.bartlomiejpluta.demo.map;
|
||||||
|
|
||||||
|
import com.bartlomiejpluta.base.api.context.Context;
|
||||||
|
import com.bartlomiejpluta.base.api.map.model.GameMap;
|
||||||
|
|
||||||
|
public class HeroHouse extends BaseMapHandler {
|
||||||
|
@Override
|
||||||
|
public void onCreate(Context context, GameMap map) {
|
||||||
|
super.onCreate(context, map);
|
||||||
|
dayNightCycle = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
133
src/main/java/com/bartlomiejpluta/demo/menu/GuiManager.java
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
package com.bartlomiejpluta.demo.menu;
|
||||||
|
|
||||||
|
import A.widgets;
|
||||||
|
import com.bartlomiejpluta.base.api.context.Context;
|
||||||
|
import com.bartlomiejpluta.base.api.gui.*;
|
||||||
|
import com.bartlomiejpluta.base.api.input.Key;
|
||||||
|
import com.bartlomiejpluta.base.api.input.KeyAction;
|
||||||
|
import com.bartlomiejpluta.base.api.input.KeyEvent;
|
||||||
|
import com.bartlomiejpluta.demo.entity.Chest;
|
||||||
|
import com.bartlomiejpluta.demo.entity.Enemy;
|
||||||
|
import com.bartlomiejpluta.demo.gui.*;
|
||||||
|
import com.bartlomiejpluta.demo.runner.DemoRunner;
|
||||||
|
import lombok.NonNull;
|
||||||
|
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
public class GuiManager {
|
||||||
|
private final DemoRunner runner;
|
||||||
|
private final Context context;
|
||||||
|
private final GUI gui;
|
||||||
|
private final WindowManager manager;
|
||||||
|
|
||||||
|
private final StartMenuWindow startMenu;
|
||||||
|
private final GameMenuWindow gameMenu;
|
||||||
|
private final EquipmentWindow equipment;
|
||||||
|
private final LootWindow loot;
|
||||||
|
private final DialogWindow dialog;
|
||||||
|
private final DialogChoiceWindow dialogChoice;
|
||||||
|
private final Consumer<KeyEvent> gameMenuHandler = this::handleGameMenuKeyEvent;
|
||||||
|
|
||||||
|
public GuiManager(@NonNull DemoRunner runner, @NonNull Context context) {
|
||||||
|
this.runner = runner;
|
||||||
|
this.context = context;
|
||||||
|
this.gui = context.newGUI();
|
||||||
|
this.manager = new WindowManager(context, DisplayMode.DISPLAY_TOP, UpdateMode.UPDATE_TOP);
|
||||||
|
|
||||||
|
this.gui.setRoot(this.manager);
|
||||||
|
|
||||||
|
this.startMenu = gui.inflateWindow(A.widgets.start_menu.$, StartMenuWindow.class);
|
||||||
|
this.startMenu.reference("new_game", Button.class).setAction(runner::newGame);
|
||||||
|
this.startMenu.reference("exit", Button.class).setAction(runner::exit);
|
||||||
|
|
||||||
|
this.equipment = gui.inflateWindow(A.widgets.equipment.$, EquipmentWindow.class);
|
||||||
|
|
||||||
|
this.gameMenu = gui.inflateWindow(A.widgets.game_menu.$, GameMenuWindow.class);
|
||||||
|
this.gameMenu.reference("resume_game", Button.class).setAction(this::resumeGame);
|
||||||
|
this.gameMenu.reference("equipment", Button.class).setAction(() -> manager.open(equipment));
|
||||||
|
this.gameMenu.reference("start_menu", Button.class).setAction(runner::returnToStartMenu);
|
||||||
|
this.gameMenu.reference("exit", Button.class).setAction(runner::exit);
|
||||||
|
|
||||||
|
this.dialog = gui.inflateWindow(A.widgets.dialog.$, DialogWindow.class);
|
||||||
|
this.dialogChoice = gui.inflateWindow(A.widgets.dialog_choice.$, DialogChoiceWindow.class);
|
||||||
|
this.loot = gui.inflateWindow(widgets.loot_menu.$, LootWindow.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleGameMenuKeyEvent(KeyEvent event) {
|
||||||
|
if (event.getKey() == Key.KEY_E && event.getAction() == KeyAction.PRESS) {
|
||||||
|
if (manager.isEmpty()) {
|
||||||
|
manager.open(equipment);
|
||||||
|
} else if (manager.top() == equipment) {
|
||||||
|
manager.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
event.consume();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.getKey() == Key.KEY_ESCAPE && event.getAction() == KeyAction.PRESS) {
|
||||||
|
if (manager.size() > 0) {
|
||||||
|
manager.close();
|
||||||
|
} else {
|
||||||
|
manager.open(gameMenu);
|
||||||
|
context.pause();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (manager.isEmpty()) {
|
||||||
|
context.resume();
|
||||||
|
}
|
||||||
|
|
||||||
|
event.consume();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int openedWindows() {
|
||||||
|
return manager.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public CompletableFuture<Object> showStartMenu() {
|
||||||
|
manager.closeAll();
|
||||||
|
return manager.open(startMenu);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void enableGameMenu() {
|
||||||
|
manager.closeAll();
|
||||||
|
|
||||||
|
context.getInput().addKeyEventHandler(gameMenuHandler);
|
||||||
|
manager.setDisplayMode(DisplayMode.DISPLAY_STACK);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void disableGameMenu() {
|
||||||
|
context.getInput().removeKeyEventHandler(gameMenuHandler);
|
||||||
|
manager.setDisplayMode(DisplayMode.DISPLAY_TOP);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CompletableFuture<Object> showDialog(@NonNull String speaker, int color, @NonNull String message, @NonNull WindowPosition position) {
|
||||||
|
return manager.open(dialog, speaker, color, message, position);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CompletableFuture<Integer> showDialogChoice(@NonNull String speaker, int color, @NonNull String... choices) {
|
||||||
|
return manager.openForResult(Integer.class, dialogChoice, speaker, color, choices);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CompletableFuture<Object> openLootWindow(@NonNull Enemy enemy) {
|
||||||
|
return manager.open(loot, enemy.getLoot(), "Loot");
|
||||||
|
}
|
||||||
|
|
||||||
|
public CompletableFuture<Object> openChestWindow(@NonNull Chest chest) {
|
||||||
|
return manager.open(loot, chest.getContent(), chest.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
public CompletableFuture<Object> openGameMenu() {
|
||||||
|
return manager.open(gameMenu);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void closeAll() {
|
||||||
|
manager.closeAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void resumeGame() {
|
||||||
|
manager.closeAll();
|
||||||
|
context.resume();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,88 +0,0 @@
|
|||||||
package com.bartlomiejpluta.demo.menu;
|
|
||||||
|
|
||||||
import lombok.*;
|
|
||||||
|
|
||||||
import java.util.function.*;
|
|
||||||
|
|
||||||
import com.bartlomiejpluta.base.api.context.Context;
|
|
||||||
import com.bartlomiejpluta.base.api.screen.Screen;
|
|
||||||
import com.bartlomiejpluta.base.api.input.*;
|
|
||||||
import com.bartlomiejpluta.base.api.gui.*;
|
|
||||||
import com.bartlomiejpluta.base.lib.gui.*;
|
|
||||||
|
|
||||||
import com.bartlomiejpluta.demo.runner.DemoRunner;
|
|
||||||
import com.bartlomiejpluta.demo.gui.*;
|
|
||||||
|
|
||||||
public class MenuManager {
|
|
||||||
private final DemoRunner runner;
|
|
||||||
private final Context context;
|
|
||||||
private final GUI gui;
|
|
||||||
private final WindowManager manager;
|
|
||||||
|
|
||||||
private final StartMenuWindow startMenu;
|
|
||||||
private final GameMenuWindow gameMenu;
|
|
||||||
|
|
||||||
private final Consumer<KeyEvent> gameMenuHandler = this::handleGameMenuKeyEvent;
|
|
||||||
|
|
||||||
public MenuManager(@NonNull DemoRunner runner, @NonNull Context context) {
|
|
||||||
this.runner = runner;
|
|
||||||
this.context = context;
|
|
||||||
this.gui = context.newGUI();
|
|
||||||
this.manager = new WindowManager(context, DisplayMode.DISPLAY_TOP, UpdateMode.UPDATE_TOP);
|
|
||||||
|
|
||||||
this.gui.setRoot(this.manager);
|
|
||||||
|
|
||||||
this.startMenu = (StartMenuWindow) gui.inflateWindow("ab9d40b4-eb28-45d7-bff2-9432a05eb41a");
|
|
||||||
this.startMenu.getNewGameBtn().setAction(runner::newGame);
|
|
||||||
this.startMenu.getExitBtn().setAction(runner::exit);
|
|
||||||
|
|
||||||
this.gameMenu = (GameMenuWindow) gui.inflateWindow("56ca6b39-f949-4212-9c23-312db25887e0");
|
|
||||||
this.gameMenu.getResumeGameBtn().setAction(this::resumeGame);
|
|
||||||
this.gameMenu.getStartMenuBtn().setAction(runner::returnToStartMenu);
|
|
||||||
this.gameMenu.getExitBtn().setAction(runner::exit);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleGameMenuKeyEvent(KeyEvent event) {
|
|
||||||
if (event.getKey() == Key.KEY_ESCAPE && event.getAction() == KeyAction.PRESS) {
|
|
||||||
if(manager.size() > 0) {
|
|
||||||
manager.close();
|
|
||||||
} else {
|
|
||||||
manager.open(gameMenu);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(manager.size() > 0) {
|
|
||||||
context.pause();
|
|
||||||
} else {
|
|
||||||
context.resume();
|
|
||||||
}
|
|
||||||
|
|
||||||
event.consume();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void showStartMenu() {
|
|
||||||
manager.closeAll();
|
|
||||||
manager.open(startMenu);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void enableGameMenu() {
|
|
||||||
manager.closeAll();
|
|
||||||
|
|
||||||
context.getInput().addKeyEventHandler(gameMenuHandler);
|
|
||||||
manager.setDisplayMode(DisplayMode.DISPLAY_STACK);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void disableGameMenu() {
|
|
||||||
context.getInput().removeKeyEventHandler(gameMenuHandler);
|
|
||||||
manager.setDisplayMode(DisplayMode.DISPLAY_TOP);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void closeAll() {
|
|
||||||
manager.closeAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void resumeGame() {
|
|
||||||
manager.closeAll();
|
|
||||||
context.resume();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,143 +1,128 @@
|
|||||||
package com.bartlomiejpluta.demo.runner;
|
package com.bartlomiejpluta.demo.runner;
|
||||||
|
|
||||||
import lombok.*;
|
|
||||||
|
|
||||||
|
import DB.dao;
|
||||||
|
import com.bartlomiejpluta.base.api.context.Context;
|
||||||
|
import com.bartlomiejpluta.base.api.gui.GUI;
|
||||||
|
import com.bartlomiejpluta.base.api.runner.GameRunner;
|
||||||
|
import com.bartlomiejpluta.base.api.screen.Screen;
|
||||||
|
import com.bartlomiejpluta.demo.entity.Player;
|
||||||
|
import com.bartlomiejpluta.demo.menu.GuiManager;
|
||||||
|
import com.bartlomiejpluta.demo.world.time.WorldTime;
|
||||||
|
import lombok.Getter;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import com.bartlomiejpluta.base.api.context.Context;
|
|
||||||
import com.bartlomiejpluta.base.api.input.Input;
|
|
||||||
import com.bartlomiejpluta.base.api.screen.Screen;
|
|
||||||
import com.bartlomiejpluta.base.api.runner.GameRunner;
|
|
||||||
import com.bartlomiejpluta.base.api.gui.GUI;
|
|
||||||
|
|
||||||
import com.bartlomiejpluta.base.util.profiler.FPSProfiler;
|
|
||||||
|
|
||||||
import com.bartlomiejpluta.base.generated.db.dao.*;
|
|
||||||
|
|
||||||
import com.bartlomiejpluta.demo.map.ForrestTempleHandler;
|
|
||||||
import com.bartlomiejpluta.demo.entity.Player;
|
|
||||||
import com.bartlomiejpluta.demo.menu.MenuManager;
|
|
||||||
|
|
||||||
import com.bartlomiejpluta.demo.world.weapon.*;
|
|
||||||
|
|
||||||
public class DemoRunner implements GameRunner {
|
public class DemoRunner implements GameRunner {
|
||||||
private static final Logger log = LoggerFactory.getLogger(DemoRunner.class);
|
private static final Logger log = LoggerFactory.getLogger(DemoRunner.class);
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private WorldTime time;
|
||||||
|
private static DemoRunner INSTANCE;
|
||||||
|
|
||||||
private Screen screen;
|
private Screen screen;
|
||||||
private Context context;
|
private Context context;
|
||||||
private MenuManager menu;
|
|
||||||
private GUI hud;
|
private GUI hud;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private MeleeWeaponDAO meleeWeaponDAO;
|
private GuiManager guiManager;
|
||||||
|
|
||||||
@Getter
|
|
||||||
private RangedWeaponDAO rangedWeaponDAO;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
private EnemyDAO enemyDAO;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
private MapObjectDAO mapObjectDAO;
|
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private Player player;
|
private Player player;
|
||||||
|
|
||||||
private final FPSProfiler fpsProfiler = FPSProfiler.create(20);
|
public static DemoRunner instance() {
|
||||||
|
return INSTANCE;
|
||||||
@Override
|
|
||||||
public void init(Context context) {
|
|
||||||
this.context = context;
|
|
||||||
this.screen = context.getScreen();
|
|
||||||
|
|
||||||
configureScreen();
|
|
||||||
configureCamera();
|
|
||||||
initPlayer();
|
|
||||||
initDAOs();
|
|
||||||
initHUD();
|
|
||||||
initMenu();
|
|
||||||
|
|
||||||
menu.showStartMenu();
|
|
||||||
|
|
||||||
screen.show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void configureScreen() {
|
private void configureScreen() {
|
||||||
var resolution = screen.getCurrentResolution();
|
var resolution = screen.getCurrentResolution();
|
||||||
screen.setSize(800, 600);
|
var config = dao.config.find("screen").getValue().split("x");
|
||||||
screen.setPosition((resolution.x() - 800)/2, (resolution.y() - 600)/2);
|
var width = Integer.parseInt(config[0]);
|
||||||
|
var height = Integer.parseInt(config[1]);
|
||||||
|
screen.setSize(width, height);
|
||||||
|
screen.setPosition((resolution.x() - width) / 2, (resolution.y() - height) / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void configureCamera() {
|
private void configureCamera() {
|
||||||
context.getCamera().setScale(2f);
|
context.getCamera().setScale(Float.parseFloat(dao.config.find("camera_scale").getValue()));
|
||||||
}
|
|
||||||
|
|
||||||
private void initDAOs() {
|
|
||||||
meleeWeaponDAO = new MeleeWeaponDAO(context);
|
|
||||||
enemyDAO = new EnemyDAO(context);
|
|
||||||
rangedWeaponDAO = new RangedWeaponDAO(context);
|
|
||||||
mapObjectDAO = new MapObjectDAO(context);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initMenu() {
|
private void initMenu() {
|
||||||
this.menu = new MenuManager(this, context);
|
this.guiManager = new GuiManager(this, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initHUD() {
|
private void initHUD() {
|
||||||
hud = context.newGUI();
|
hud = context.newGUI();
|
||||||
hud.hide();
|
hud.hide();
|
||||||
var hudComponent = hud.inflateComponent("00bd0625-b3b8-4abf-97b7-91f42bce28ec");
|
var hudComponent = hud.inflateComponent(A.widgets.hud.$);
|
||||||
hud.setRoot(hudComponent);
|
hud.setRoot(hudComponent);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initPlayer() {
|
private void initPlayer() {
|
||||||
this.player = new Player(context, context.createEntity("815a5c5c-4979-42f5-a42a-ccbbff9a97e5"));
|
this.player = new Player(context.createCharacter(A.charsets.luna.$));
|
||||||
}
|
|
||||||
|
|
||||||
private void resetPlayer() {
|
|
||||||
this.player.changeEntitySet("815a5c5c-4979-42f5-a42a-ccbbff9a97e5");
|
|
||||||
this.player.setScale(1.0f);
|
|
||||||
this.player.setSpeed(0.07f);
|
|
||||||
this.player.setAnimationSpeed(0.005f);
|
|
||||||
this.player.setBlocking(true);
|
|
||||||
this.player.setCoordinates(0, 11);
|
|
||||||
this.player.setWeapon(new RangedWeapon(context, rangedWeaponDAO.find("wooden_bow")));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void newGame() {
|
public void newGame() {
|
||||||
menu.closeAll();
|
context.resetMaps();
|
||||||
menu.enableGameMenu();
|
guiManager.closeAll();
|
||||||
resetPlayer();
|
guiManager.enableGameMenu();
|
||||||
context.openMap(ForrestTempleHandler.UID);
|
player.reset();
|
||||||
context.getMap().getObjectLayer(ForrestTempleHandler.MAIN_LAYER).addEntity(this.player);
|
var start = dao.config.find("start_game").getValue().split(",");
|
||||||
|
|
||||||
|
var map = A.maps.byName(start[0]);
|
||||||
|
var layer = map.layer(start[1]);
|
||||||
|
var label = layer.label(start[2]);
|
||||||
|
|
||||||
|
time.setTime(dao.config.find("initial_time").getValue());
|
||||||
|
|
||||||
|
context.openMap(map.$);
|
||||||
|
context.getMap().getObjectLayer(layer.$).addEntity(this.player);
|
||||||
|
player.setCoordinates(label.getX(), label.getY());
|
||||||
context.resume();
|
context.resume();
|
||||||
hud.show();
|
hud.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void returnToStartMenu() {
|
public void returnToStartMenu() {
|
||||||
menu.closeAll();
|
guiManager.closeAll();
|
||||||
hud.hide();
|
hud.hide();
|
||||||
context.pause();
|
context.pause();
|
||||||
context.closeMap();
|
context.closeMap();
|
||||||
menu.disableGameMenu();
|
guiManager.disableGameMenu();
|
||||||
menu.showStartMenu();
|
guiManager.showStartMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void exit() {
|
public void exit() {
|
||||||
context.close();
|
context.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
public double instantFPS() {
|
|
||||||
return fpsProfiler.getInstantFPS();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void update(float dt) {
|
|
||||||
fpsProfiler.update(dt);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
// Do something after game loop is end
|
// Do something after game loop is end
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(Context context) {
|
||||||
|
DemoRunner.INSTANCE = this;
|
||||||
|
|
||||||
|
this.context = context;
|
||||||
|
this.screen = context.getScreen();
|
||||||
|
this.time = new WorldTime(context);
|
||||||
|
|
||||||
|
configureScreen();
|
||||||
|
configureCamera();
|
||||||
|
initPlayer();
|
||||||
|
initHUD();
|
||||||
|
initMenu();
|
||||||
|
|
||||||
|
guiManager.showStartMenu();
|
||||||
|
|
||||||
|
screen.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(float dt) {
|
||||||
|
time.update(dt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
11
src/main/java/com/bartlomiejpluta/demo/util/IconUtil.java
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package com.bartlomiejpluta.demo.util;
|
||||||
|
|
||||||
|
import com.bartlomiejpluta.base.api.context.ContextHolder;
|
||||||
|
import com.bartlomiejpluta.base.api.icon.Icon;
|
||||||
|
|
||||||
|
public class IconUtil {
|
||||||
|
public static Icon parseIcon(String iconDefinition) {
|
||||||
|
var parts = iconDefinition.split(",");
|
||||||
|
return ContextHolder.INSTANCE.getContext().createIcon(A.iconsets.byName(parts[0]).$, Integer.parseInt(parts[1]), Integer.parseInt(parts[2]));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.bartlomiejpluta.demo.util;
|
package com.bartlomiejpluta.demo.util;
|
||||||
|
|
||||||
import lombok.*;
|
import lombok.AllArgsConstructor;
|
||||||
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
|
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
|
|||||||
21
src/main/java/com/bartlomiejpluta/demo/util/ListUtil.java
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
package com.bartlomiejpluta.demo.util;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
|
public class ListUtil {
|
||||||
|
private static final Random random = new Random();
|
||||||
|
|
||||||
|
public static <T> T sample(List<T> list) {
|
||||||
|
return list.get(random.nextInt(list.size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<Integer> randomIntSequence(int startInclusive, int endExclusive) {
|
||||||
|
var ints = new ArrayList<>(IntStream.range(startInclusive, endExclusive).boxed().toList());
|
||||||
|
Collections.shuffle(ints);
|
||||||
|
return ints;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
package com.bartlomiejpluta.demo.util;
|
||||||
|
|
||||||
|
import DB.EnemyDropDAO;
|
||||||
|
import DB.dao;
|
||||||
|
import com.bartlomiejpluta.base.lib.db.Relop;
|
||||||
|
import com.bartlomiejpluta.demo.world.item.Item;
|
||||||
|
import com.bartlomiejpluta.demo.world.item.ItemStack;
|
||||||
|
import com.bartlomiejpluta.demo.world.junk.Junk;
|
||||||
|
import com.bartlomiejpluta.demo.world.potion.Medicament;
|
||||||
|
import com.bartlomiejpluta.demo.world.weapon.Ammunition;
|
||||||
|
import com.bartlomiejpluta.demo.world.weapon.MeleeWeapon;
|
||||||
|
import com.bartlomiejpluta.demo.world.weapon.RangedWeapon;
|
||||||
|
import com.bartlomiejpluta.demo.world.weapon.ThrowingWeapon;
|
||||||
|
import lombok.NonNull;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import static com.bartlomiejpluta.base.util.random.DiceRoller.roll;
|
||||||
|
import static com.bartlomiejpluta.demo.util.ListUtil.randomIntSequence;
|
||||||
|
|
||||||
|
public class LootGenerator {
|
||||||
|
private static final Random rand = new Random();
|
||||||
|
private static final Map<String, Function<String, Item>> itemGenerators = Map.of(
|
||||||
|
"melee", MeleeWeapon::new,
|
||||||
|
"ranged", RangedWeapon::new,
|
||||||
|
"junk", Junk::new
|
||||||
|
);
|
||||||
|
private static final Map<String, BiFunction<String, Integer, ItemStack>> stackableGenerator = Map.of(
|
||||||
|
"ammo", Ammunition::new,
|
||||||
|
"throwing", ThrowingWeapon::new,
|
||||||
|
"med", Medicament::new
|
||||||
|
);
|
||||||
|
|
||||||
|
public static void generate(@NonNull String enemy, @NonNull Item[] loot) {
|
||||||
|
var def = dao.enemy_drop.query()
|
||||||
|
.where(EnemyDropDAO.Column.ENEMY, Relop.EQ, enemy)
|
||||||
|
.orderBy("rand()")
|
||||||
|
.find();
|
||||||
|
|
||||||
|
var index = randomIntSequence(0, loot.length).iterator();
|
||||||
|
|
||||||
|
for (var template : def) {
|
||||||
|
var parts = template.getItem().split(":");
|
||||||
|
|
||||||
|
var item = itemGenerators.get(parts[0]);
|
||||||
|
if (item != null) {
|
||||||
|
for (int i = 0; i < roll(template.getAmount()) && index.hasNext(); ++i) {
|
||||||
|
if (rand.nextFloat() <= template.getChance()) {
|
||||||
|
loot[index.next()] = item.apply(parts[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var stack = stackableGenerator.get(parts[0]);
|
||||||
|
if (stack != null && index.hasNext()) {
|
||||||
|
if (rand.nextFloat() <= template.getChance()) {
|
||||||
|
loot[index.next()] = stack.apply(parts[1], roll(template.getAmount()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package com.bartlomiejpluta.demo.world.item;
|
||||||
|
|
||||||
|
import com.bartlomiejpluta.base.lib.icon.IconDelegate;
|
||||||
|
import com.bartlomiejpluta.demo.util.IconUtil;
|
||||||
|
import lombok.NonNull;
|
||||||
|
|
||||||
|
public abstract class BaseItem extends IconDelegate implements Item {
|
||||||
|
protected BaseItem(@NonNull String icon) {
|
||||||
|
super(IconUtil.parseIcon(icon));
|
||||||
|
setZIndex(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package com.bartlomiejpluta.demo.world.item;
|
||||||
|
|
||||||
|
import com.bartlomiejpluta.base.api.icon.Icon;
|
||||||
|
|
||||||
|
public interface Item extends Icon {
|
||||||
|
String getName();
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package com.bartlomiejpluta.demo.world.item;
|
||||||
|
|
||||||
|
public interface ItemStack extends Item {
|
||||||
|
String getId();
|
||||||
|
|
||||||
|
int getCount();
|
||||||
|
|
||||||
|
void setCount(int count);
|
||||||
|
|
||||||
|
void decrease();
|
||||||
|
|
||||||
|
void increase();
|
||||||
|
|
||||||
|
void increase(int count);
|
||||||
|
|
||||||
|
void decrease(int count);
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package com.bartlomiejpluta.demo.world.item;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
public abstract class StackableItem extends BaseItem implements ItemStack {
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
protected int count;
|
||||||
|
|
||||||
|
protected StackableItem(@NonNull String id, int count) {
|
||||||
|
super(id);
|
||||||
|
this.count = Math.max(0, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void decrease() {
|
||||||
|
if (count > 0) {
|
||||||
|
--count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void increase() {
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void increase(int count) {
|
||||||
|
this.count += count;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void decrease(int count) {
|
||||||
|
this.count = Math.max(0, count);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package com.bartlomiejpluta.demo.world.item;
|
||||||
|
|
||||||
|
import com.bartlomiejpluta.demo.entity.Creature;
|
||||||
|
|
||||||
|
public interface Useable {
|
||||||
|
void use(Creature creature);
|
||||||
|
|
||||||
|
default String usageName() {
|
||||||
|
return "Use";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package com.bartlomiejpluta.demo.world.item;
|
||||||
|
|
||||||
|
import com.bartlomiejpluta.demo.entity.Creature;
|
||||||
|
import lombok.NonNull;
|
||||||
|
|
||||||
|
public abstract class UseableStackableItem extends StackableItem implements Useable {
|
||||||
|
|
||||||
|
protected UseableStackableItem(@NonNull String id, int count) {
|
||||||
|
super(id, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void use(Creature creature) {
|
||||||
|
if (--count == 0) {
|
||||||
|
creature.removeItemFromEquipment(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
20
src/main/java/com/bartlomiejpluta/demo/world/junk/Junk.java
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
package com.bartlomiejpluta.demo.world.junk;
|
||||||
|
|
||||||
|
import com.bartlomiejpluta.demo.world.item.BaseItem;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NonNull;
|
||||||
|
|
||||||
|
public class Junk extends BaseItem {
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
public Junk(@NonNull String id) {
|
||||||
|
this(DB.dao.junk.find(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Junk(@NonNull DB.model.JunkModel template) {
|
||||||
|
super(template.getIcon());
|
||||||
|
this.name = template.getName();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package com.bartlomiejpluta.demo.world.light;
|
||||||
|
|
||||||
|
import com.bartlomiejpluta.base.api.context.ContextHolder;
|
||||||
|
import com.bartlomiejpluta.base.lib.light.LightDelegate;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
public class Torch extends LightDelegate {
|
||||||
|
private final Random random = new Random();
|
||||||
|
private float acc = 0;
|
||||||
|
|
||||||
|
public Torch() {
|
||||||
|
super(ContextHolder.INSTANCE.getContext().createLight());
|
||||||
|
setIntensity(100f, 50f, 0f);
|
||||||
|
setConstantAttenuation(1f);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(float dt) {
|
||||||
|
super.update(dt);
|
||||||
|
|
||||||
|
if (acc > 0.1f) {
|
||||||
|
setQuadraticAttenuation(0.1f * (1f + ((float) random.nextGaussian()) * 0.1f));
|
||||||
|
acc = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
acc += dt;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package com.bartlomiejpluta.demo.world.potion;
|
||||||
|
|
||||||
|
import DB.dao;
|
||||||
|
import com.bartlomiejpluta.base.util.random.DiceRoller;
|
||||||
|
import com.bartlomiejpluta.demo.entity.Creature;
|
||||||
|
import com.bartlomiejpluta.demo.world.item.Useable;
|
||||||
|
import com.bartlomiejpluta.demo.world.item.UseableStackableItem;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NonNull;
|
||||||
|
|
||||||
|
import static java.lang.String.format;
|
||||||
|
|
||||||
|
public class Medicament extends UseableStackableItem implements Useable {
|
||||||
|
@Getter
|
||||||
|
private final String id;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private final DiceRoller roller;
|
||||||
|
|
||||||
|
public Medicament(@NonNull String id, int count) {
|
||||||
|
this(dao.medicaments.find(id), count);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Medicament(@NonNull DB.model.MedicamentsModel template, int count) {
|
||||||
|
super(template.getIcon(), count);
|
||||||
|
this.name = template.getName();
|
||||||
|
this.roller = DiceRoller.of(template.getHp());
|
||||||
|
this.id = format("med:%s", template.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void use(Creature creature) {
|
||||||
|
super.use(creature);
|
||||||
|
creature.heal(roller.roll());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
package com.bartlomiejpluta.demo.world.time;
|
||||||
|
|
||||||
|
import DB.dao;
|
||||||
|
import com.bartlomiejpluta.base.api.context.Context;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
|
import static java.lang.Math.max;
|
||||||
|
import static java.lang.Math.min;
|
||||||
|
|
||||||
|
public class WorldTime {
|
||||||
|
private static final float MINUTES_PER_DAY = 1440f; // 60min * 24
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private float progress = 0;
|
||||||
|
private final float period; // seconds
|
||||||
|
private final Context context;
|
||||||
|
|
||||||
|
public WorldTime(@NonNull Context context) {
|
||||||
|
this.context = context;
|
||||||
|
this.period = Float.parseFloat(dao.config.find("full_day_duration").getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProgress(float progress) {
|
||||||
|
this.progress = max(0, min(1, progress));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTime(@NonNull String time) {
|
||||||
|
var splitted = time.split(":");
|
||||||
|
this.setTime(Integer.valueOf(splitted[0], 10), Integer.valueOf(splitted[1], 10));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTime(int h, int m) {
|
||||||
|
this.progress = (h * 60 + m) / MINUTES_PER_DAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getHour() {
|
||||||
|
return (int) (progress * 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMinute() {
|
||||||
|
return (int) (progress * 24 * 60) % 60;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update(float dt) {
|
||||||
|
if (context.isPaused()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
progress += dt / period;
|
||||||
|
if (progress > 1) {
|
||||||
|
progress = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
package com.bartlomiejpluta.demo.world.weapon;
|
||||||
|
|
||||||
|
import com.bartlomiejpluta.demo.entity.Creature;
|
||||||
|
import com.bartlomiejpluta.demo.world.item.StackableItem;
|
||||||
|
import com.bartlomiejpluta.demo.world.item.Useable;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import lombok.ToString;
|
||||||
|
|
||||||
|
import static java.lang.String.format;
|
||||||
|
|
||||||
|
@ToString
|
||||||
|
public class Ammunition extends StackableItem implements Useable {
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private final String id;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private final String appliesTo;
|
||||||
|
|
||||||
|
public Ammunition(@NonNull String id, int count) {
|
||||||
|
this(DB.dao.ammunition.find(id), count);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Ammunition(@NonNull DB.model.AmmunitionModel template, int count) {
|
||||||
|
super(template.getIcon(), count);
|
||||||
|
|
||||||
|
this.id = format("ammo:%s", template.getId());
|
||||||
|
this.name = template.getName();
|
||||||
|
this.appliesTo = template.getAppliesTo();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void use(Creature creature) {
|
||||||
|
creature.setAmmunition(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String usageName() {
|
||||||
|
return "Arm";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,53 +1,52 @@
|
|||||||
package com.bartlomiejpluta.demo.world.weapon;
|
package com.bartlomiejpluta.demo.world.weapon;
|
||||||
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
import lombok.*;
|
|
||||||
import org.joml.Vector2i;
|
|
||||||
import com.bartlomiejpluta.base.api.context.Context;
|
import com.bartlomiejpluta.base.api.context.Context;
|
||||||
import com.bartlomiejpluta.base.lib.animation.*;
|
import com.bartlomiejpluta.base.api.context.ContextHolder;
|
||||||
|
import com.bartlomiejpluta.base.lib.animation.AnimationRunner;
|
||||||
|
import com.bartlomiejpluta.base.lib.animation.RandomAnimationsRunner;
|
||||||
import com.bartlomiejpluta.base.util.random.DiceRoller;
|
import com.bartlomiejpluta.base.util.random.DiceRoller;
|
||||||
|
import com.bartlomiejpluta.demo.entity.Creature;
|
||||||
import com.bartlomiejpluta.base.generated.db.model.MeleeWeaponModel;
|
|
||||||
import com.bartlomiejpluta.demo.entity.Character;
|
|
||||||
|
|
||||||
import com.bartlomiejpluta.demo.event.HitEvent;
|
import com.bartlomiejpluta.demo.event.HitEvent;
|
||||||
|
import com.bartlomiejpluta.demo.world.item.BaseItem;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NonNull;
|
||||||
|
import org.joml.Vector2i;
|
||||||
|
|
||||||
public class MeleeWeapon implements Weapon {
|
public class MeleeWeapon extends BaseItem implements Weapon {
|
||||||
private final Random random = new Random();
|
|
||||||
private final Context context;
|
private final Context context;
|
||||||
private final DiceRoller roller;
|
|
||||||
private final AnimationRunner animation;
|
private final AnimationRunner animation;
|
||||||
private final String sound;
|
private final String sound;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private String name;
|
private final String name;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private int cooldown;
|
private final DiceRoller dmgRoller;
|
||||||
|
|
||||||
public MeleeWeapon(@NonNull Context context, @NonNull MeleeWeaponModel template) {
|
@Getter
|
||||||
this.context = context;
|
private final int cooldown;
|
||||||
|
|
||||||
|
public MeleeWeapon(@NonNull String id) {
|
||||||
|
this(DB.dao.melee_weapon.find(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
public MeleeWeapon(@NonNull DB.model.MeleeWeaponModel template) {
|
||||||
|
super(template.getIcon());
|
||||||
|
|
||||||
|
this.context = ContextHolder.INSTANCE.getContext();
|
||||||
this.name = template.getName();
|
this.name = template.getName();
|
||||||
this.roller = DiceRoller.of(template.getDamage());
|
this.dmgRoller = DiceRoller.of(template.getDamage());
|
||||||
this.cooldown = template.getCooldown();
|
this.cooldown = template.getCooldown();
|
||||||
this.animation = new RandomAnimationsRunner(5)
|
this.animation = new RandomAnimationsRunner(2).nRange(0, 2f).nScale(0.2f, 0.15f).uAnimationSpeed(0.5f, 1f).nRotation(0, 10).offset(0, -10).uDelay(250, 500).with(A.animations.byName(template.getAnimation()).$);
|
||||||
.nRange(0, 2f)
|
this.sound = A.sounds.byName(template.getSound()).$;
|
||||||
.nScale(0.2f, 0.15f)
|
|
||||||
.uAnimationSpeed(0.01f, 0.05f)
|
|
||||||
.offset(0, -10)
|
|
||||||
.uDelay(0, 500)
|
|
||||||
.with(template.getAnimation());
|
|
||||||
this.sound = template.getSound();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean attack(Character attacker) {
|
public boolean attack(Creature attacker) {
|
||||||
var facingNeighbour = attacker.getCoordinates().add(attacker.getFaceDirection().vector, new Vector2i());
|
var facingNeighbour = attacker.getCoordinates().add(attacker.getFaceDirection().vector, new Vector2i());
|
||||||
for(var entity : attacker.getLayer().getEntities()) {
|
for (var entity : attacker.getLayer().getEntities()) {
|
||||||
if(entity.getCoordinates().equals(facingNeighbour) && entity.isBlocking() && entity instanceof Character) {
|
if (entity.getCoordinates().equals(facingNeighbour) && entity.isBlocking() && entity instanceof Creature character) {
|
||||||
var character = (Character) entity;
|
var damage = dmgRoller.roll();
|
||||||
var damage = roller.roll();
|
|
||||||
character.hit(attacker, damage);
|
character.hit(attacker, damage);
|
||||||
animation.run(context, character.getLayer(), character);
|
animation.run(context, character.getLayer(), character);
|
||||||
context.playSound(sound);
|
context.playSound(sound);
|
||||||
@@ -58,4 +57,14 @@ public class MeleeWeapon implements Weapon {
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void use(Creature creature) {
|
||||||
|
creature.setWeapon(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String usageName() {
|
||||||
|
return "Arm";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,26 +1,22 @@
|
|||||||
package com.bartlomiejpluta.demo.world.weapon;
|
package com.bartlomiejpluta.demo.world.weapon;
|
||||||
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
import lombok.*;
|
|
||||||
import com.bartlomiejpluta.base.api.context.Context;
|
|
||||||
import com.bartlomiejpluta.base.api.entity.Entity;
|
|
||||||
import com.bartlomiejpluta.base.api.animation.Animation;
|
import com.bartlomiejpluta.base.api.animation.Animation;
|
||||||
import com.bartlomiejpluta.base.api.move.*;
|
import com.bartlomiejpluta.base.api.context.Context;
|
||||||
import com.bartlomiejpluta.base.lib.animation.*;
|
import com.bartlomiejpluta.base.api.context.ContextHolder;
|
||||||
|
import com.bartlomiejpluta.base.api.entity.Entity;
|
||||||
|
import com.bartlomiejpluta.base.api.move.Movable;
|
||||||
|
import com.bartlomiejpluta.base.lib.animation.AnimationRunner;
|
||||||
|
import com.bartlomiejpluta.base.lib.animation.BulletAnimationRunner;
|
||||||
|
import com.bartlomiejpluta.base.lib.animation.SimpleAnimationRunner;
|
||||||
import com.bartlomiejpluta.base.util.random.DiceRoller;
|
import com.bartlomiejpluta.base.util.random.DiceRoller;
|
||||||
|
import com.bartlomiejpluta.demo.entity.Creature;
|
||||||
import com.bartlomiejpluta.base.generated.db.model.RangedWeaponModel;
|
|
||||||
import com.bartlomiejpluta.demo.entity.Character;
|
|
||||||
import com.bartlomiejpluta.demo.entity.NamedEntity;
|
|
||||||
|
|
||||||
import com.bartlomiejpluta.demo.event.HitEvent;
|
import com.bartlomiejpluta.demo.event.HitEvent;
|
||||||
|
import com.bartlomiejpluta.demo.world.item.BaseItem;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NonNull;
|
||||||
|
|
||||||
public class RangedWeapon implements Weapon {
|
public class RangedWeapon extends BaseItem implements Weapon {
|
||||||
private final Random random = new Random();
|
|
||||||
private final Context context;
|
private final Context context;
|
||||||
private final DiceRoller dmgRoller;
|
|
||||||
private final DiceRoller rangeRoller;
|
|
||||||
private final BulletAnimationRunner animation;
|
private final BulletAnimationRunner animation;
|
||||||
private final String sound;
|
private final String sound;
|
||||||
private final AnimationRunner punchAnimation;
|
private final AnimationRunner punchAnimation;
|
||||||
@@ -29,37 +25,44 @@ public class RangedWeapon implements Weapon {
|
|||||||
private final String missSound;
|
private final String missSound;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private String name;
|
private final String name;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private int cooldown;
|
private final String type;
|
||||||
|
|
||||||
public RangedWeapon(@NonNull Context context, @NonNull RangedWeaponModel template) {
|
@Getter
|
||||||
this.context = context;
|
private final DiceRoller dmgRoller;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private final DiceRoller rangeRoller;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private final int cooldown;
|
||||||
|
|
||||||
|
public RangedWeapon(@NonNull String id) {
|
||||||
|
this(DB.dao.ranged_weapon.find(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
public RangedWeapon(@NonNull DB.model.RangedWeaponModel template) {
|
||||||
|
super(template.getIcon());
|
||||||
|
|
||||||
|
this.context = ContextHolder.INSTANCE.getContext();
|
||||||
this.name = template.getName();
|
this.name = template.getName();
|
||||||
|
this.type = template.getType();
|
||||||
this.dmgRoller = DiceRoller.of(template.getDamage());
|
this.dmgRoller = DiceRoller.of(template.getDamage());
|
||||||
this.rangeRoller = DiceRoller.of(template.getRange());
|
this.rangeRoller = DiceRoller.of(template.getRange());
|
||||||
this.cooldown = template.getCooldown();
|
this.cooldown = template.getCooldown();
|
||||||
this.animation = new BulletAnimationRunner(template.getAnimation())
|
this.animation = new BulletAnimationRunner(A.animations.byName(template.getAnimation()).$).infinite().offset(0, -15).onHit(this::onHit).onMiss(this::onMiss).speed(7f).animationSpeed(4f).scale(0.6f);
|
||||||
.infinite()
|
this.sound = A.sounds.byName(template.getSound()).$;
|
||||||
.offset(0, -15)
|
this.punchAnimation = new SimpleAnimationRunner(A.animations.byName(template.getPunchAnimation()).$);
|
||||||
.onHit(this::onHit)
|
this.punchSound = A.sounds.byName(template.getPunchSound()).$;
|
||||||
.onMiss(this::onMiss)
|
this.missAnimation = new SimpleAnimationRunner(A.animations.byName(template.getMissAnimation()).$).scale(0.4f);
|
||||||
.speed(0.25f)
|
this.missSound = A.sounds.byName(template.getMissSound()).$;
|
||||||
.animationSpeed(0.07f)
|
|
||||||
.scale(0.6f);
|
|
||||||
this.sound = template.getSound();
|
|
||||||
this.punchAnimation = new SimpleAnimationRunner(template.getPunchAnimation());
|
|
||||||
this.punchSound = template.getPunchSound();
|
|
||||||
this.missAnimation = new SimpleAnimationRunner(template.getMissAnimation())
|
|
||||||
.scale(0.4f);
|
|
||||||
this.missSound = template.getMissSound();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onHit(Movable attacker, Entity target) {
|
private void onHit(Movable attacker, Entity target) {
|
||||||
if(target.isBlocking() && target instanceof Character) {
|
if (target.isBlocking() && target instanceof Creature character) {
|
||||||
var namedAttacker = (Character) attacker;
|
var namedAttacker = (Creature) attacker;
|
||||||
var character = (Character) target;
|
|
||||||
var damage = dmgRoller.roll();
|
var damage = dmgRoller.roll();
|
||||||
character.hit(namedAttacker, damage);
|
character.hit(namedAttacker, damage);
|
||||||
punchAnimation.run(context, character.getLayer(), character);
|
punchAnimation.run(context, character.getLayer(), character);
|
||||||
@@ -69,19 +72,31 @@ public class RangedWeapon implements Weapon {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void onMiss(Movable attacker, Animation animation) {
|
private void onMiss(Movable attacker, Animation animation) {
|
||||||
missAnimation.run(context, ((Character) attacker).getLayer(), animation.getPosition());
|
missAnimation.run(context, ((Creature) attacker).getLayer(), animation.getPosition());
|
||||||
context.playSound(missSound);
|
context.playSound(missSound);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean attack(Character attacker) {
|
public boolean attack(Creature attacker) {
|
||||||
|
var ammunition = attacker.getAmmunition();
|
||||||
|
|
||||||
|
if (ammunition == null || !ammunition.getAppliesTo().equals(type)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
var direction = attacker.getFaceDirection();
|
var direction = attacker.getFaceDirection();
|
||||||
context.playSound(sound);
|
context.playSound(sound);
|
||||||
animation
|
animation.range(rangeRoller.roll()).direction(direction).rotation(direction.xAngle - 180).run(context, attacker.getLayer(), attacker);
|
||||||
.range(rangeRoller.roll())
|
|
||||||
.direction(direction)
|
|
||||||
.rotation(direction.xAngle - 180)
|
|
||||||
.run(context, attacker.getLayer(), attacker);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void use(Creature creature) {
|
||||||
|
creature.setWeapon(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String usageName() {
|
||||||
|
return "Arm";
|
||||||
|
}
|
||||||
}
|
}
|
||||||