Compare commits
77 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
|
|||
|
ccd3e44130
|
|||
|
9124f5c58a
|
|||
|
7b778845ba
|
|||
|
f98806f2f9
|
|||
|
0f365410b0
|
|||
|
1e3e2e6abb
|
|||
|
1e4a9a02c9
|
|||
|
0bfe53cd8e
|
|||
|
bf04597af6
|
|||
|
ffdc9e930a
|
|||
|
b4f385db5c
|
|||
|
dd7a4bf304
|
|||
|
e28667c14e
|
|||
|
2bd9d077cc
|
|||
|
a2d95855c5
|
|||
|
ad30a8dcf5
|
|||
|
1eda877a09
|
|||
|
8dcbf5a972
|
|||
|
f28f647368
|
|||
|
da77d25f6d
|
3
.gitignore
vendored
@@ -1,2 +1,5 @@
|
||||
.direnv
|
||||
build/
|
||||
data.trace.db
|
||||
*.jar
|
||||
result
|
||||
BIN
animations/0ddac391-4086-4e9c-8310-59db649419ff.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
animations/312cc4e6-8c44-43e7-828a-e7e2a77836f3.png
Normal file
|
After Width: | Height: | Size: 951 B |
BIN
animations/54f657bd-8108-464c-9bbe-63944fc14f6b.png
Normal file
|
After Width: | Height: | Size: 276 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
animations/e6f067f1-eba0-4e62-99c3-2fd867e6f142.png
Normal file
|
After Width: | Height: | Size: 324 KiB |
BIN
audio/1311327d-4b74-4252-94da-23ee4129e357.ogg
Normal file
BIN
audio/7c33cfee-e6a8-42b8-8b1d-c801b242dcf0.ogg
Normal file
BIN
audio/cd8a40f2-1e2e-4e1d-a13f-b4fe210a04df.ogg
Normal file
BIN
audio/e452e215-f581-40fe-a5cf-f555d3db83b8.ogg
Normal file
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 |
BIN
charsets/0dcbaf26-d634-4ca8-9691-7a8ff966f702.png
Normal file
|
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 |
BIN
charsets/7a723b64-e54a-4fff-852d-108349133111.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
charsets/92ac46ff-8cf2-4748-907f-873030c8e378.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
charsets/a6863639-d563-4d88-af8e-c6d087ee2ffb.png
Normal file
|
After Width: | Height: | Size: 42 KiB |
BIN
charsets/c7ec2341-e5fc-4285-9ecb-a2dfc8a0ed67.png
Normal file
|
After Width: | Height: | Size: 7.7 KiB |
BIN
charsets/e605b2b1-3cab-499f-882d-160ab65b49d8.png
Normal file
|
After Width: | Height: | Size: 7.8 KiB |
BIN
charsets/f1113db3-4a6c-4a07-9b64-32ba8e653e4f.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
charsets/f529cbfc-c29d-470b-8804-e50d6a1efc98.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
charsets/fbea4628-e1d3-4acc-800a-ed54c1bb51b6.png
Normal file
|
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.*;"
|
||||
}
|
||||
11
project.bep
@@ -1,11 +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 (:`
|
||||
$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 Menu
|
||||
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";
|
||||
}
|
||||
40
src/main/java/com/bartlomiejpluta/demo/ai/AnimalAI.java
Normal file
@@ -0,0 +1,40 @@
|
||||
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.lib.ai.RandomMovementAI;
|
||||
import com.bartlomiejpluta.base.lib.ai.RunawayAI;
|
||||
import com.bartlomiejpluta.demo.entity.Creature;
|
||||
import com.bartlomiejpluta.demo.entity.Enemy;
|
||||
|
||||
public class AnimalAI implements AI {
|
||||
private final Enemy animal;
|
||||
private final Creature creature;
|
||||
private final int range;
|
||||
private final AI idleAI;
|
||||
private final AI runawayAI;
|
||||
|
||||
public AnimalAI(Enemy animal, Creature creature, int range) {
|
||||
this.animal = animal;
|
||||
this.creature = creature;
|
||||
this.range = range;
|
||||
this.idleAI = new RandomMovementAI<>(animal, 4);
|
||||
this.runawayAI = new RunawayAI<>(animal, creature);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nextActivity(ObjectLayer layer, float dt) {
|
||||
if (animal.isMoving()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var distance = animal.manhattanDistance(creature);
|
||||
|
||||
if (animal.getHp() < animal.getMaxHp() && distance < range) {
|
||||
runawayAI.nextActivity(layer, dt);
|
||||
return;
|
||||
}
|
||||
|
||||
idleAI.nextActivity(layer, dt);
|
||||
}
|
||||
}
|
||||
42
src/main/java/com/bartlomiejpluta/demo/ai/ArcherAI.java
Normal file
@@ -0,0 +1,42 @@
|
||||
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.lib.ai.KeepStraightDistanceAI;
|
||||
import com.bartlomiejpluta.base.lib.ai.RandomMovementAI;
|
||||
import com.bartlomiejpluta.base.util.pathfinder.AstarPathFinder;
|
||||
import com.bartlomiejpluta.demo.entity.Creature;
|
||||
import com.bartlomiejpluta.demo.entity.Enemy;
|
||||
|
||||
public class ArcherAI extends KeepStraightDistanceAI<Enemy, Creature> {
|
||||
private static final int ASTAR_MAX_NODES = 100;
|
||||
private static final int IDLE_MOVEMENT_INTERVAL = 4;
|
||||
private final int range;
|
||||
private final AI idle;
|
||||
|
||||
public ArcherAI(Enemy enemy, Creature target, int minRange, int maxRange, int range) {
|
||||
super(new AstarPathFinder(ASTAR_MAX_NODES), enemy, target, minRange, maxRange);
|
||||
this.range = range;
|
||||
this.idle = new RandomMovementAI<>(enemy, IDLE_MOVEMENT_INTERVAL);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean sees(Enemy enemy, Creature target, ObjectLayer layer) {
|
||||
return enemy.manhattanDistance(target) < range;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void interact(Enemy enemy, Creature target, ObjectLayer layer, float dt) {
|
||||
enemy.attack();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void follow(Enemy enemy, Creature target, ObjectLayer layer, float dt) {
|
||||
// noop
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void idle(Enemy enemy, Creature target, ObjectLayer layer, float dt) {
|
||||
idle.nextActivity(layer, dt);
|
||||
}
|
||||
}
|
||||
@@ -1,43 +1,42 @@
|
||||
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.util.pathfinder.*;
|
||||
import com.bartlomiejpluta.base.api.ai.*;
|
||||
import com.bartlomiejpluta.base.lib.ai.*;
|
||||
|
||||
import com.bartlomiejpluta.base.lib.ai.FollowObjectAI;
|
||||
import com.bartlomiejpluta.base.lib.ai.RandomMovementAI;
|
||||
import com.bartlomiejpluta.base.util.pathfinder.AstarPathFinder;
|
||||
import com.bartlomiejpluta.demo.entity.Creature;
|
||||
import com.bartlomiejpluta.demo.entity.Enemy;
|
||||
import com.bartlomiejpluta.demo.entity.Character;
|
||||
|
||||
public class SimpleEnemyAI extends FollowEntityAI<Enemy, Character> {
|
||||
private static final int ASTAR_MAX_NODES = 100;
|
||||
private static final int IDLE_MOVEMENT_INTERVAL = 4;
|
||||
private final AI idle;
|
||||
private final int range;
|
||||
public class SimpleEnemyAI extends FollowObjectAI<Enemy, Creature> {
|
||||
private static final int ASTAR_MAX_NODES = 100;
|
||||
private static final int IDLE_MOVEMENT_INTERVAL = 4;
|
||||
private final AI idle;
|
||||
private final int range;
|
||||
|
||||
public SimpleEnemyAI(Enemy enemy, Character target, int range) {
|
||||
super(new AstarPathFinder(ASTAR_MAX_NODES), enemy, target);
|
||||
this.range = range;
|
||||
this.idle = new RandomMovementAI(enemy, IDLE_MOVEMENT_INTERVAL);
|
||||
}
|
||||
public SimpleEnemyAI(Enemy enemy, Creature target, int range) {
|
||||
super(new AstarPathFinder(ASTAR_MAX_NODES), enemy, target);
|
||||
this.range = range;
|
||||
this.idle = new RandomMovementAI<>(enemy, IDLE_MOVEMENT_INTERVAL);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean sees(Enemy enemy, Character target, ObjectLayer layer, int distance) {
|
||||
return distance < range;
|
||||
}
|
||||
@Override
|
||||
protected boolean sees(Enemy enemy, Creature target, ObjectLayer layer, int distance) {
|
||||
return distance < range;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void interact(Enemy enemy, Character target, ObjectLayer layer, float dt) {
|
||||
enemy.attack();
|
||||
}
|
||||
@Override
|
||||
protected void interact(Enemy enemy, Creature target, ObjectLayer layer, float dt) {
|
||||
enemy.attack();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void follow(Enemy enemy, Character target, ObjectLayer layer, float dt) {
|
||||
// noop
|
||||
}
|
||||
@Override
|
||||
protected void follow(Enemy enemy, Creature target, ObjectLayer layer, float dt) {
|
||||
// noop
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void idle(Enemy enemy, Character target, ObjectLayer layer, float dt) {
|
||||
idle.nextActivity(layer, dt);
|
||||
}
|
||||
@Override
|
||||
protected void idle(Enemy enemy, Creature target, ObjectLayer layer, float dt) {
|
||||
idle.nextActivity(layer, dt);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.bartlomiejpluta.demo.ai;
|
||||
|
||||
import com.bartlomiejpluta.base.api.ai.AI;
|
||||
import com.bartlomiejpluta.base.api.map.layer.object.ObjectLayer;
|
||||
import com.bartlomiejpluta.demo.entity.Creature;
|
||||
import com.bartlomiejpluta.demo.entity.Enemy;
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class SimpleSniperAI implements AI {
|
||||
private final Enemy enemy;
|
||||
private Creature target;
|
||||
private int range;
|
||||
|
||||
@Override
|
||||
public void nextActivity(ObjectLayer layer, float dt) {
|
||||
var enemyCoords = enemy.getCoordinates();
|
||||
var targetCoords = target.getCoordinates();
|
||||
if (enemy.manhattanDistance(target) <= range && (enemyCoords.x() == targetCoords.x() || enemyCoords.y() == targetCoords.y())) {
|
||||
var direction = enemy.getDirectionTowards(target);
|
||||
enemy.setFaceDirection(direction);
|
||||
enemy.attack();
|
||||
}
|
||||
}
|
||||
}
|
||||
84
src/main/java/com/bartlomiejpluta/demo/ai/WeaponBasedAI.java
Normal file
@@ -0,0 +1,84 @@
|
||||
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.move.MoveEvent;
|
||||
import com.bartlomiejpluta.base.lib.ai.RunawayAI;
|
||||
import com.bartlomiejpluta.demo.entity.Creature;
|
||||
import com.bartlomiejpluta.demo.entity.Enemy;
|
||||
import lombok.NonNull;
|
||||
|
||||
public class WeaponBasedAI implements AI {
|
||||
private static final int RANGE = 20;
|
||||
private static final int MIN_RANGE = 3;
|
||||
private static final int MAX_RANGE = 12;
|
||||
private final Enemy enemy;
|
||||
private final Creature target;
|
||||
private final RunawayAI<Enemy, Creature> runawayAI;
|
||||
private final SimpleEnemyAI meleeAI;
|
||||
private final ArcherAI archerAI;
|
||||
|
||||
public WeaponBasedAI(@NonNull Enemy enemy, @NonNull Creature target) {
|
||||
this.enemy = enemy;
|
||||
this.target = target;
|
||||
this.runawayAI = new RunawayAI<>(enemy, target);
|
||||
this.meleeAI = new SimpleEnemyAI(enemy, target, RANGE);
|
||||
this.archerAI = new ArcherAI(enemy, target, MIN_RANGE, MAX_RANGE, RANGE);
|
||||
}
|
||||
|
||||
public void recomputePath() {
|
||||
meleeAI.recomputePath();
|
||||
archerAI.recomputePath();
|
||||
}
|
||||
|
||||
public void recomputePath(@NonNull MoveEvent event) {
|
||||
meleeAI.recomputePath(event);
|
||||
archerAI.recomputePath(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void nextActivity(ObjectLayer layer, float dt) {
|
||||
var lastAttacker = enemy.getLastAttacker();
|
||||
if (lastAttacker instanceof Creature attacker) {
|
||||
if (attacker.isAlive()) {
|
||||
runawayAI.setDanger(attacker);
|
||||
meleeAI.setTarget(attacker);
|
||||
archerAI.setTarget(attacker);
|
||||
} else {
|
||||
runawayAI.setDanger(target);
|
||||
meleeAI.setTarget(target);
|
||||
archerAI.setTarget(target);
|
||||
}
|
||||
}
|
||||
|
||||
var meleeWeapon = enemy.getMeleeWeapon();
|
||||
var rangedWeapon = enemy.getRangedWeapon();
|
||||
var throwingWeapon = enemy.getThrowingWeapon();
|
||||
|
||||
if (meleeWeapon == null && rangedWeapon == null && throwingWeapon == null) {
|
||||
runawayAI.nextActivity(layer, dt);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((rangedWeapon == null && throwingWeapon == null) || (rangedWeapon != null && enemy.getAmmunition() == null && throwingWeapon == null) || enemy.manhattanDistance(target) == 1) {
|
||||
enemy.setWeapon(meleeWeapon);
|
||||
meleeAI.nextActivity(layer, dt);
|
||||
return;
|
||||
}
|
||||
|
||||
if (throwingWeapon != null) {
|
||||
enemy.setWeapon(throwingWeapon);
|
||||
archerAI.nextActivity(layer, dt);
|
||||
return;
|
||||
}
|
||||
|
||||
enemy.setWeapon(rangedWeapon);
|
||||
archerAI.nextActivity(layer, dt);
|
||||
|
||||
// if (enemy.getWeapon() instanceof MeleeWeapon) {
|
||||
// meleeAI.nextActivity(layer, dt);
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
package com.bartlomiejpluta.demo.database.dao;
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.*;
|
||||
|
||||
import com.bartlomiejpluta.base.api.context.Context;
|
||||
|
||||
import com.bartlomiejpluta.demo.database.model.EnemyModel;
|
||||
|
||||
public class EnemyDAO {
|
||||
private final Map<String, EnemyModel> enemies = new HashMap<>();
|
||||
|
||||
public void init(Context context) {
|
||||
context.withDatabase(db -> {
|
||||
var result = db.prepareStatement("SELECT * FROM `enemy`").executeQuery();
|
||||
|
||||
while(result.next()) {
|
||||
var enemy = EnemyModel.builder()
|
||||
.id(result.getString("id"))
|
||||
.name(result.getString("name"))
|
||||
.entitySet(result.getString("entset"))
|
||||
.deadEntitySet(result.getString("dead_entset"))
|
||||
.hp(result.getInt("hp"))
|
||||
.speed(result.getFloat("speed"))
|
||||
.animationSpeed(result.getFloat("animation_speed"))
|
||||
.blocking(result.getBoolean("blocking"))
|
||||
.meleeWeapon(result.getString("melee_weapon"))
|
||||
.build();
|
||||
enemies.put(result.getString("id"), enemy);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public EnemyModel get(String id) {
|
||||
return enemies.get(id);
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
package com.bartlomiejpluta.demo.database.dao;
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.*;
|
||||
|
||||
import com.bartlomiejpluta.base.api.context.Context;
|
||||
|
||||
import com.bartlomiejpluta.demo.database.model.MeleeWeaponModel;
|
||||
|
||||
public class MeleeWeaponDAO {
|
||||
private final Map<String, MeleeWeaponModel> items = new HashMap<>();
|
||||
|
||||
public void init(Context context) {
|
||||
context.withDatabase(db -> {
|
||||
var result = db.prepareStatement("SELECT * FROM `melee_weapon`").executeQuery();
|
||||
|
||||
while(result.next()) {
|
||||
var weapon = MeleeWeaponModel.builder()
|
||||
.id(result.getString("id"))
|
||||
.name(result.getString("name"))
|
||||
.damage(result.getString("damage"))
|
||||
.cooldown(result.getInt("cooldown"))
|
||||
.build();
|
||||
items.put(result.getString("id"), weapon);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public MeleeWeaponModel get(String id) {
|
||||
return items.get(id);
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package com.bartlomiejpluta.demo.database.model;
|
||||
|
||||
import lombok.*;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
public class EnemyModel {
|
||||
private final String id;
|
||||
private final String name;
|
||||
private final String entitySet;
|
||||
private final String deadEntitySet;
|
||||
private final int hp;
|
||||
private final float speed;
|
||||
private final float animationSpeed;
|
||||
private final boolean blocking;
|
||||
private final String meleeWeapon;
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
package com.bartlomiejpluta.demo.database.model;
|
||||
|
||||
import lombok.*;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
public class MeleeWeaponModel {
|
||||
private final String id;
|
||||
private final String name;
|
||||
private final String damage;
|
||||
private final int cooldown;
|
||||
}
|
||||
@@ -1,80 +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.entity.EntityDelegate;
|
||||
|
||||
import com.bartlomiejpluta.demo.runner.DemoRunner;
|
||||
import com.bartlomiejpluta.demo.world.weapon.MeleeWeapon;
|
||||
|
||||
public class Character extends EntityDelegate {
|
||||
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 hp;
|
||||
|
||||
@Setter
|
||||
private MeleeWeapon weapon;
|
||||
|
||||
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()) {
|
||||
var facingNeighbour = getCoordinates().add(getFaceDirection().vector, new Vector2i());
|
||||
for(var entity : getLayer().getEntities()) {
|
||||
if(entity.getCoordinates().equals(facingNeighbour) && entity.isBlocking() && entity instanceof Character) {
|
||||
weapon.attack((Character) entity);
|
||||
attackCooldown = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void hit(int dmg) {
|
||||
if(immortal) {
|
||||
return;
|
||||
}
|
||||
|
||||
log.info(toString() + " received " + dmg + " damage");
|
||||
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() {
|
||||
log.info(toString() + " died with HP = " + hp);
|
||||
}
|
||||
}
|
||||
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,67 +1,155 @@
|
||||
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.NPC;
|
||||
import com.bartlomiejpluta.base.api.context.ContextHolder;
|
||||
import com.bartlomiejpluta.base.api.move.MoveEvent;
|
||||
|
||||
import com.bartlomiejpluta.base.lib.ai.NoopAI;
|
||||
|
||||
import com.bartlomiejpluta.demo.runner.DemoRunner;
|
||||
import com.bartlomiejpluta.demo.database.model.EnemyModel;
|
||||
import com.bartlomiejpluta.demo.world.weapon.MeleeWeapon;
|
||||
import com.bartlomiejpluta.demo.event.EnemyDiedEvent;
|
||||
import com.bartlomiejpluta.base.lib.animation.AnimationRunner;
|
||||
import com.bartlomiejpluta.base.lib.animation.SimpleAnimationRunner;
|
||||
import com.bartlomiejpluta.base.util.random.DiceRoller;
|
||||
import com.bartlomiejpluta.demo.ai.*;
|
||||
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 {
|
||||
private final EnemyModel template;
|
||||
private AI ai = NoopAI.INSTANCE;
|
||||
public class Enemy extends Creature implements NPC {
|
||||
public static final int MAX_LOOT = 4 * 4;
|
||||
|
||||
public Enemy(@NonNull Context context, @NonNull EnemyModel template) {
|
||||
super(context, context.createEntity(template.getEntitySet()));
|
||||
this.template = template;
|
||||
hp = template.getHp();
|
||||
setSpeed(template.getSpeed());
|
||||
setAnimationSpeed(template.getAnimationSpeed());
|
||||
setBlocking(template.isBlocking());
|
||||
setWeapon(new MeleeWeapon(((DemoRunner) context.getGameRunner()).getMeleeWeaponDAO().get(template.getMeleeWeapon())));
|
||||
}
|
||||
private final Random random = new Random();
|
||||
private final DB.model.EnemyModel template;
|
||||
private final AnimationRunner dieAnimation;
|
||||
|
||||
@Override
|
||||
public AI getStrategy() {
|
||||
return ai;
|
||||
}
|
||||
@Getter
|
||||
private final Item[] loot = new Item[MAX_LOOT];
|
||||
@Getter
|
||||
private final String name;
|
||||
private AI ai = NoopAI.INSTANCE;
|
||||
@Getter
|
||||
private MeleeWeapon meleeWeapon;
|
||||
@Getter
|
||||
private RangedWeapon rangedWeapon;
|
||||
@Getter
|
||||
@Setter
|
||||
private ThrowingWeapon throwingWeapon;
|
||||
|
||||
@Override
|
||||
public void die() {
|
||||
super.die();
|
||||
changeEntitySet(template.getDeadEntitySet());
|
||||
setScale(0.5f);
|
||||
setBlocking(false);
|
||||
setZIndex(-1);
|
||||
public Enemy(@NonNull String id) {
|
||||
this(DB.dao.enemy.find(id));
|
||||
}
|
||||
|
||||
ai = NoopAI.INSTANCE;
|
||||
public Enemy(@NonNull DB.model.EnemyModel template) {
|
||||
super(ContextHolder.INSTANCE.getContext().createCharacter(A.charsets.byName(template.getCharset()).$));
|
||||
this.template = template;
|
||||
name = template.getName();
|
||||
maxHp = DiceRoller.roll(template.getHp());
|
||||
hp = maxHp;
|
||||
var speed = DiceRoller.roll(template.getSpeed()) / 10f;
|
||||
setSpeed(speed);
|
||||
setAnimationSpeed(speed / 2.0f);
|
||||
setBlocking(template.isBlocking());
|
||||
var meleeWeaponTemplate = template.getMeleeWeapon();
|
||||
var rangedWeaponTemplate = template.getRangedWeapon();
|
||||
var throwingWeaponTemplate = template.getThrowingWeapon();
|
||||
|
||||
getLayer().handleEvent(new EnemyDiedEvent(this));
|
||||
}
|
||||
if (meleeWeaponTemplate != null) {
|
||||
this.meleeWeapon = new MeleeWeapon(meleeWeaponTemplate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return template.getName() + "@" + hashCode();
|
||||
}
|
||||
if (rangedWeaponTemplate != null) {
|
||||
var split = rangedWeaponTemplate.split(",");
|
||||
|
||||
public Enemy followAndAttack(Character target, int range) {
|
||||
var ai = new SimpleEnemyAI(this, target, range);
|
||||
this.rangedWeapon = new RangedWeapon(split[0]);
|
||||
setAmmunition(new Ammunition(split[1], DiceRoller.roll(split[2])));
|
||||
}
|
||||
|
||||
addEventListener(MoveEvent.TYPE, e -> ai.recomputePath());
|
||||
addEventListener(EnemyDiedEvent.TYPE, e -> ai.recomputePath());
|
||||
if (throwingWeaponTemplate != null) {
|
||||
var split = throwingWeaponTemplate.split(",");
|
||||
this.throwingWeapon = new ThrowingWeapon(split[0], DiceRoller.roll(split[1]));
|
||||
}
|
||||
|
||||
this.ai = ai;
|
||||
this.dieAnimation = new SimpleAnimationRunner(A.animations.byName(template.getDieAnimation()).$);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
@Override
|
||||
public AI getStrategy() {
|
||||
return ai;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeItemFromEquipment(Item item) {
|
||||
// noop
|
||||
}
|
||||
|
||||
@Override
|
||||
public void die() {
|
||||
super.die();
|
||||
changeCharacterSet(A.charsets.byName(template.getDeadCharset()).$);
|
||||
setScale(0.5f);
|
||||
setBlocking(false);
|
||||
setZIndex(-1);
|
||||
|
||||
ai = NoopAI.INSTANCE;
|
||||
|
||||
dieAnimation.run(context, getLayer(), this);
|
||||
context.playSound(A.sounds.byName(template.getDieSound()).$);
|
||||
context.fireEvent(new EnemyDiedEvent(this));
|
||||
|
||||
LootGenerator.generate(template.getId(), loot);
|
||||
}
|
||||
|
||||
public Enemy followAndAttack(Creature target, int range) {
|
||||
var ai = new SimpleEnemyAI(this, target, range);
|
||||
|
||||
addEventListener(MoveEvent.TYPE, ai::recomputePath);
|
||||
addEventListener(EnemyDiedEvent.TYPE, e -> ai.recomputePath());
|
||||
|
||||
this.ai = ai;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Enemy campAndHunt(Creature target, int range) {
|
||||
this.ai = new SimpleSniperAI(this, target, range);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Enemy asAnimal(Creature source, int range) {
|
||||
this.ai = new AnimalAI(this, source, range);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Enemy archer(Creature target, int minRange, int maxRange, int range) {
|
||||
var ai = new ArcherAI(this, target, minRange, maxRange, range);
|
||||
|
||||
addEventListener(MoveEvent.TYPE, ai::recomputePath);
|
||||
addEventListener(EnemyDiedEvent.TYPE, e -> ai.recomputePath());
|
||||
|
||||
this.ai = ai;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public Enemy defaultAI() {
|
||||
var ai = new WeaponBasedAI(this, DemoRunner.instance().getPlayer());
|
||||
|
||||
addEventListener(MoveEvent.TYPE, ai::recomputePath);
|
||||
addEventListener(EnemyDiedEvent.TYPE, e -> ai.recomputePath());
|
||||
|
||||
this.ai = ai;
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
40
src/main/java/com/bartlomiejpluta/demo/entity/MapObject.java
Normal file
@@ -0,0 +1,40 @@
|
||||
package com.bartlomiejpluta.demo.entity;
|
||||
|
||||
import com.bartlomiejpluta.base.api.context.Context;
|
||||
import com.bartlomiejpluta.base.api.context.ContextHolder;
|
||||
import com.bartlomiejpluta.demo.runner.DemoRunner;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static java.util.concurrent.CompletableFuture.completedFuture;
|
||||
|
||||
public abstract class MapObject extends com.bartlomiejpluta.base.util.world.MapObject {
|
||||
protected final Context context;
|
||||
protected final DemoRunner runner;
|
||||
@Getter
|
||||
private final String name;
|
||||
private final String interactSound;
|
||||
|
||||
public MapObject(@NonNull String id) {
|
||||
this(DB.dao.object.find(id));
|
||||
}
|
||||
|
||||
public MapObject(@NonNull DB.model.ObjectModel template) {
|
||||
super(ContextHolder.INSTANCE.getContext().createCharacter(A.charsets.byName(template.getCharset()).$), template.getFrame());
|
||||
this.context = ContextHolder.INSTANCE.getContext();
|
||||
this.runner = DemoRunner.instance();
|
||||
this.name = template.getName();
|
||||
this.interactSound = A.sounds.byName(template.getInteractSound()).$;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NonNull CompletableFuture<?> onInteractionBegin() {
|
||||
if (interactSound != null) {
|
||||
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,20 +1,259 @@
|
||||
package com.bartlomiejpluta.demo.entity;
|
||||
|
||||
import lombok.*;
|
||||
import org.slf4j.*;
|
||||
import com.bartlomiejpluta.base.api.context.Context;
|
||||
import com.bartlomiejpluta.base.api.entity.Entity;
|
||||
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;
|
||||
|
||||
public class Player extends Character {
|
||||
private static final Logger log = LoggerFactory.getLogger(Player.class);
|
||||
import java.util.Arrays;
|
||||
|
||||
public Player(@NonNull Context context, @NonNull Entity entity) {
|
||||
super(context, entity);
|
||||
}
|
||||
public class Player extends Creature {
|
||||
public static final int EQUIPMENT_SIZE = 6 * 6;
|
||||
private final Item[] equipment = new Item[EQUIPMENT_SIZE];
|
||||
private int interactionCooldown = 0;
|
||||
|
||||
@Override
|
||||
public void die() {
|
||||
super.die();
|
||||
runner.returnToStartMenu();
|
||||
}
|
||||
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() {
|
||||
if (interactionCooldown > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
var coords = getCoordinates().add(getFaceDirection().vector, new Vector2i());
|
||||
var entities = getLayer().getEntities();
|
||||
for (var i = 0; i < entities.size(); ++i) {
|
||||
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
|
||||
public void die() {
|
||||
super.die();
|
||||
runner.returnToStartMenu();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
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,20 +1,20 @@
|
||||
package com.bartlomiejpluta.demo.event;
|
||||
|
||||
import lombok.*;
|
||||
|
||||
import com.bartlomiejpluta.base.api.event.*;
|
||||
import com.bartlomiejpluta.base.lib.event.*;
|
||||
import com.bartlomiejpluta.base.api.event.EventType;
|
||||
import com.bartlomiejpluta.base.lib.event.BaseEvent;
|
||||
import com.bartlomiejpluta.demo.entity.Enemy;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
public class EnemyDiedEvent extends BaseEvent {
|
||||
public static final EventType<EnemyDiedEvent> TYPE = new EventType<>("ENEMY_DIED_EVENT");
|
||||
public static final EventType<EnemyDiedEvent> TYPE = new EventType<>("ENEMY_DIED_EVENT");
|
||||
|
||||
private final Enemy enemy;
|
||||
private final Enemy enemy;
|
||||
|
||||
@Override
|
||||
public EventType<EnemyDiedEvent> getType() {
|
||||
return TYPE;
|
||||
}
|
||||
@Override
|
||||
public EventType<EnemyDiedEvent> getType() {
|
||||
return TYPE;
|
||||
}
|
||||
}
|
||||
22
src/main/java/com/bartlomiejpluta/demo/event/HitEvent.java
Normal file
@@ -0,0 +1,22 @@
|
||||
package com.bartlomiejpluta.demo.event;
|
||||
|
||||
import com.bartlomiejpluta.base.api.event.EventType;
|
||||
import com.bartlomiejpluta.base.lib.event.BaseEvent;
|
||||
import com.bartlomiejpluta.demo.entity.Creature;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
public class HitEvent extends BaseEvent {
|
||||
public static final EventType<HitEvent> TYPE = new EventType<>("HIT_EVENT");
|
||||
|
||||
private final Creature attacker;
|
||||
private final Creature target;
|
||||
private final int damage;
|
||||
|
||||
@Override
|
||||
public EventType<HitEvent> getType() {
|
||||
return TYPE;
|
||||
}
|
||||
}
|
||||
69
src/main/java/com/bartlomiejpluta/demo/gui/Bar.java
Normal file
@@ -0,0 +1,69 @@
|
||||
package com.bartlomiejpluta.demo.gui;
|
||||
|
||||
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.screen.Screen;
|
||||
import com.bartlomiejpluta.base.lib.gui.BaseComponent;
|
||||
import lombok.NonNull;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class Bar extends BaseComponent {
|
||||
|
||||
private final Color stroke;
|
||||
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, Map<String, Component> refs) {
|
||||
super(context, gui, refs);
|
||||
|
||||
this.stroke = gui.createColor();
|
||||
this.fill = gui.createColor();
|
||||
|
||||
stroke.setAlpha(1f);
|
||||
fill.setAlpha(1f);
|
||||
}
|
||||
|
||||
public void setValue(@NonNull Float value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public void setStrokeColor(Integer hex) {
|
||||
stroke.setRGB(hex);
|
||||
}
|
||||
|
||||
public void setFillColor(Integer hex) {
|
||||
fill.setRGB(hex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getContentWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getContentHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Screen screen, GUI gui) {
|
||||
var remainingDistance = value - actualValue;
|
||||
actualValue += remainingDistance * speed;
|
||||
|
||||
gui.beginPath();
|
||||
gui.drawRectangle(x + paddingLeft, y + paddingTop, Math.max(width * actualValue, 0), height);
|
||||
gui.setFillColor(fill);
|
||||
gui.fill();
|
||||
gui.closePath();
|
||||
gui.beginPath();
|
||||
gui.drawRectangle(x + paddingLeft, y + paddingTop, width, height);
|
||||
gui.setStrokeColor(stroke);
|
||||
gui.stroke();
|
||||
gui.closePath();
|
||||
}
|
||||
}
|
||||
@@ -1,47 +1,54 @@
|
||||
package com.bartlomiejpluta.demo.gui;
|
||||
|
||||
import lombok.*;
|
||||
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.input.*;
|
||||
import com.bartlomiejpluta.base.api.gui.*;
|
||||
import com.bartlomiejpluta.base.lib.gui.*;
|
||||
import com.bartlomiejpluta.base.lib.gui.Label;
|
||||
import com.bartlomiejpluta.base.lib.gui.TextAlignment;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class Button extends Label {
|
||||
private Color color;
|
||||
private final Color color;
|
||||
|
||||
@Setter
|
||||
private Runnable action;
|
||||
@Setter
|
||||
private Runnable action;
|
||||
|
||||
public Button(Context context, GUI gui) {
|
||||
super(context, gui);
|
||||
this.color = gui.createColor();
|
||||
this.color.setRGBA(1, 1, 1, 0);
|
||||
public Button(Context context, GUI gui, Map<String, Component> refs) {
|
||||
super(context, gui, refs);
|
||||
this.color = gui.createColor();
|
||||
this.color.setRGBA(1, 1, 1, 0);
|
||||
|
||||
setText("");
|
||||
setFontSize(17f);
|
||||
setAlignment(GUI.ALIGN_TOP | GUI.ALIGN_CENTER);
|
||||
setColor(0.4f, 0.7f, 0.0f, 1f);
|
||||
setPadding(10f);
|
||||
addEventListener(KeyEvent.TYPE, this::handleKeyEvent);
|
||||
}
|
||||
setText("");
|
||||
setFontSize(17f);
|
||||
setAlignment(TextAlignment.TOP, TextAlignment.CENTER);
|
||||
setColor(0.4f, 0.7f, 0.0f, 1f);
|
||||
setPadding(10f);
|
||||
addEventListener(KeyEvent.TYPE, this::handleKeyEvent);
|
||||
}
|
||||
|
||||
private void handleKeyEvent(KeyEvent event) {
|
||||
if(event.getKey() == Key.KEY_ENTER && event.getAction() == KeyAction.PRESS && action != null) {
|
||||
event.consume();
|
||||
action.run();
|
||||
}
|
||||
}
|
||||
private void handleKeyEvent(KeyEvent event) {
|
||||
if (event.getKey() == Key.KEY_ENTER && event.getAction() == KeyAction.PRESS && action != null) {
|
||||
event.consume();
|
||||
action.run();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Screen screen, GUI gui) {
|
||||
color.setAlpha(focused ? 0.7f : 0f);
|
||||
@Override
|
||||
public void draw(Screen screen, GUI gui) {
|
||||
color.setAlpha(focused ? 0.7f : 0f);
|
||||
|
||||
gui.beginPath();
|
||||
gui.drawRectangle(x, y, getWidth(), getHeight());
|
||||
gui.setFillColor(color);
|
||||
gui.fill();
|
||||
gui.beginPath();
|
||||
gui.drawRectangle(x, y, getWidth(), getHeight());
|
||||
gui.setFillColor(color);
|
||||
gui.fill();
|
||||
|
||||
super.draw(screen, gui);
|
||||
}
|
||||
super.draw(screen, gui);
|
||||
}
|
||||
}
|
||||
@@ -1,35 +1,40 @@
|
||||
package com.bartlomiejpluta.demo.gui;
|
||||
|
||||
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.gui.*;
|
||||
import com.bartlomiejpluta.base.lib.gui.*;
|
||||
import com.bartlomiejpluta.base.lib.gui.BaseWindow;
|
||||
|
||||
public abstract class DecoratedWindow extends BaseWindow {
|
||||
private Paint paint;
|
||||
private Color inner;
|
||||
private Color outer;
|
||||
import java.util.Map;
|
||||
|
||||
public DecoratedWindow(Context context, GUI gui) {
|
||||
super(context, gui);
|
||||
public class DecoratedWindow extends BaseWindow {
|
||||
private final Paint paint;
|
||||
private final Color inner;
|
||||
private final Color outer;
|
||||
|
||||
this.inner = gui.createColor();
|
||||
this.outer = gui.createColor();
|
||||
this.paint = gui.createPaint();
|
||||
public DecoratedWindow(Context context, GUI gui, Map<String, Component> refs) {
|
||||
super(context, gui, refs);
|
||||
|
||||
inner.setRGBA(0.1f, 0.1f, 0.1f, 1f);
|
||||
outer.setRGBA(0.2f, 0.2f, 0.2f, 1f);
|
||||
}
|
||||
this.inner = gui.createColor();
|
||||
this.outer = gui.createColor();
|
||||
this.paint = gui.createPaint();
|
||||
|
||||
@Override
|
||||
public void draw(Screen screen, GUI gui) {
|
||||
gui.beginPath();
|
||||
gui.drawRectangle(x, y, getWidth(), getHeight());
|
||||
gui.setFillPaint(paint);
|
||||
gui.boxGradient(x, y, getWidth(), getHeight(), 10f, 100f, inner, outer, paint);
|
||||
gui.fill();
|
||||
gui.stroke();
|
||||
inner.setRGBA(0.1f, 0.1f, 0.1f, 1f);
|
||||
outer.setRGBA(0.2f, 0.2f, 0.2f, 1f);
|
||||
}
|
||||
|
||||
super.draw(screen, gui);
|
||||
}
|
||||
@Override
|
||||
public void draw(Screen screen, GUI gui) {
|
||||
gui.beginPath();
|
||||
gui.drawRectangle(x, y, getWidth(), getHeight());
|
||||
gui.setFillPaint(paint);
|
||||
gui.boxGradient(x, y, getWidth(), getHeight(), 10f, 100f, inner, outer, paint);
|
||||
gui.fill();
|
||||
gui.stroke();
|
||||
|
||||
super.draw(screen, gui);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
import lombok.*;
|
||||
import com.bartlomiejpluta.base.api.context.Context;
|
||||
import com.bartlomiejpluta.base.api.screen.Screen;
|
||||
import com.bartlomiejpluta.base.api.gui.*;
|
||||
import com.bartlomiejpluta.base.lib.gui.*;
|
||||
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.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")
|
||||
@Getter
|
||||
private Button resumeGameBtn;
|
||||
@Ref("menu")
|
||||
private VOptionChoice menu;
|
||||
|
||||
@Ref("start_menu")
|
||||
@Getter
|
||||
private Button startMenuBtn;
|
||||
public GameMenuWindow(Context context, GUI gui, Map<String, Component> refs) {
|
||||
super(context, gui, refs);
|
||||
}
|
||||
|
||||
@Ref("exit")
|
||||
@Getter
|
||||
private Button exitBtn;
|
||||
|
||||
public GameMenuWindow(Context context, GUI gui) {
|
||||
super(context, gui);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInflate() {
|
||||
resumeGameBtn.focus();
|
||||
}
|
||||
@Override
|
||||
public void onOpen(WindowManager manager, Object[] args) {
|
||||
super.onOpen(manager, args);
|
||||
menu.select(0);
|
||||
menu.focus();
|
||||
}
|
||||
}
|
||||
90
src/main/java/com/bartlomiejpluta/demo/gui/HUD.java
Normal file
@@ -0,0 +1,90 @@
|
||||
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 java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
public class HUD extends BorderLayout {
|
||||
private static final int MAX_LOG_SIZE = 10;
|
||||
private static final float LOG_VISIBILITY_DURATION = 8000f;
|
||||
private static final float LOG_VISIBILITY_FADING_OUT = 1000f;
|
||||
private final Player player;
|
||||
private final WorldTime time;
|
||||
private final Runtime runtime;
|
||||
private final LimitedQueue<String> logger = new LimitedQueue<>(MAX_LOG_SIZE);
|
||||
|
||||
private float logVisibilityDuration = 0f;
|
||||
|
||||
@Ref("hp")
|
||||
private Bar hp;
|
||||
|
||||
@Ref("debug")
|
||||
private TextView debugTxt;
|
||||
|
||||
@Ref("log")
|
||||
private Label logLbl;
|
||||
|
||||
public HUD(Context context, GUI gui, Map<String, Component> refs) {
|
||||
super(context, gui, refs);
|
||||
this.player = DemoRunner.instance().getPlayer();
|
||||
this.runtime = Runtime.getRuntime();
|
||||
this.time = DemoRunner.instance().getTime();
|
||||
context.addEventListener(HitEvent.TYPE, this::logHitEvent);
|
||||
context.addEventListener(EnemyDiedEvent.TYPE, this::logEnemyDiedEvent);
|
||||
}
|
||||
|
||||
private void logHitEvent(HitEvent event) {
|
||||
log(String.format("%s hits %s with damage = %d", event.getAttacker().getName(), event.getTarget().getName(), event.getDamage()));
|
||||
}
|
||||
|
||||
private void log(String message) {
|
||||
logger.add(message);
|
||||
log.info(message);
|
||||
logLbl.setText(logger.stream().collect(Collectors.joining("\n")));
|
||||
logVisibilityDuration = LOG_VISIBILITY_DURATION;
|
||||
}
|
||||
|
||||
private void logEnemyDiedEvent(EnemyDiedEvent event) {
|
||||
log(String.format("%s has died with HP = %d", event.getEnemy().getName(), event.getEnemy().getHp()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(float dt) {
|
||||
super.update(dt);
|
||||
|
||||
hp.setValue((float) player.getHp() / (float) player.getMaxHp());
|
||||
|
||||
if (logVisibilityDuration > 0) {
|
||||
logVisibilityDuration -= dt * 1000;
|
||||
} else {
|
||||
logVisibilityDuration = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Screen screen, GUI gui) {
|
||||
var coords = player.getCoordinates();
|
||||
var pos = player.getPosition();
|
||||
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()));
|
||||
|
||||
logLbl.setAlpha(Math.min(1f, logVisibilityDuration / LOG_VISIBILITY_FADING_OUT));
|
||||
|
||||
super.draw(screen, gui);
|
||||
}
|
||||
}
|
||||
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;
|
||||
|
||||
import lombok.*;
|
||||
import com.bartlomiejpluta.base.api.context.Context;
|
||||
import com.bartlomiejpluta.base.api.screen.Screen;
|
||||
import com.bartlomiejpluta.base.api.gui.*;
|
||||
import com.bartlomiejpluta.base.lib.gui.*;
|
||||
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.gui.WindowManager;
|
||||
import com.bartlomiejpluta.base.lib.gui.VOptionChoice;
|
||||
|
||||
public class StartMenuWindow extends DecoratedWindow implements Inflatable {
|
||||
import java.util.Map;
|
||||
|
||||
@Ref("new_game")
|
||||
@Getter
|
||||
private Button newGameBtn;
|
||||
public class StartMenuWindow extends DecoratedWindow {
|
||||
|
||||
@Ref("exit")
|
||||
@Getter
|
||||
private Button exitBtn;
|
||||
@Ref("menu")
|
||||
private VOptionChoice menu;
|
||||
|
||||
public StartMenuWindow(Context context, GUI gui) {
|
||||
super(context, gui);
|
||||
}
|
||||
public StartMenuWindow(Context context, GUI gui, Map<String, Component> refs) {
|
||||
super(context, gui, refs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInflate() {
|
||||
newGameBtn.focus();
|
||||
}
|
||||
@Override
|
||||
public void onOpen(WindowManager manager, Object[] args) {
|
||||
super.onOpen(manager, args);
|
||||
menu.select(0);
|
||||
menu.focus();
|
||||
}
|
||||
}
|
||||
@@ -1,84 +1,175 @@
|
||||
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.input.*;
|
||||
|
||||
import com.bartlomiejpluta.base.lib.camera.*;
|
||||
|
||||
import com.bartlomiejpluta.demo.runner.DemoRunner;
|
||||
import com.bartlomiejpluta.base.api.context.Context;
|
||||
import com.bartlomiejpluta.base.api.entity.Entity;
|
||||
import com.bartlomiejpluta.base.api.gui.WindowPosition;
|
||||
import com.bartlomiejpluta.base.api.icon.Icon;
|
||||
import com.bartlomiejpluta.base.api.input.Input;
|
||||
import com.bartlomiejpluta.base.api.input.Key;
|
||||
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.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 java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static java.lang.Math.*;
|
||||
|
||||
public abstract class BaseMapHandler implements MapHandler {
|
||||
protected Screen screen;
|
||||
protected Context context;
|
||||
protected DemoRunner runner;
|
||||
protected Camera camera;
|
||||
protected Player player;
|
||||
protected ObjectLayer mainLayer;
|
||||
protected CameraController cameraController;
|
||||
protected Screen screen;
|
||||
protected Context context;
|
||||
protected DemoRunner runner;
|
||||
protected GuiManager guiManager;
|
||||
protected Camera camera;
|
||||
protected GameMap map;
|
||||
protected Player player;
|
||||
protected CameraController cameraController;
|
||||
|
||||
@Override
|
||||
public void onCreate(Context context, GameMap map) {
|
||||
this.context = context;
|
||||
this.screen = context.getScreen();
|
||||
this.runner = (DemoRunner) context.getGameRunner();
|
||||
this.camera = context.getCamera();
|
||||
this.player = runner.getPlayer();
|
||||
this.cameraController = FollowingCameraController
|
||||
.on(screen, camera, map)
|
||||
.follow(player.getPosition());
|
||||
}
|
||||
protected boolean dayNightCycle = false;
|
||||
|
||||
@Override
|
||||
public void input(Input input) {
|
||||
if(context.isPaused()) {
|
||||
return;
|
||||
}
|
||||
protected boolean controls = true;
|
||||
|
||||
if(input.isKeyPressed(Key.KEY_SPACE)) {
|
||||
player.attack();
|
||||
}
|
||||
@Override
|
||||
public void onCreate(Context context, GameMap map) {
|
||||
this.context = context;
|
||||
this.screen = context.getScreen();
|
||||
this.runner = DemoRunner.instance();
|
||||
this.guiManager = runner.getGuiManager();
|
||||
this.camera = context.getCamera();
|
||||
this.map = map;
|
||||
this.player = runner.getPlayer();
|
||||
this.cameraController = FollowingCameraController
|
||||
.on(screen, camera, map)
|
||||
.follow(player.getPosition());
|
||||
}
|
||||
|
||||
if(input.isKeyPressed(Key.KEY_LEFT_CONTROL)) {
|
||||
if(input.isKeyPressed(Key.KEY_DOWN)) {
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void input(Input input) {
|
||||
if (context.isPaused()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(Context context, GameMap map, float dt) {
|
||||
cameraController.update();
|
||||
}
|
||||
if (guiManager.openedWindows() > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
public Enemy enemy(int x, int y, @NonNull String id) {
|
||||
var enemy = new Enemy(context, runner.getEnemyDAO().get(id));
|
||||
enemy.setCoordinates(x, y);
|
||||
mainLayer.addEntity(enemy);
|
||||
return enemy;
|
||||
}
|
||||
if (input.isKeyPressed(Key.KEY_SPACE)) {
|
||||
player.attack();
|
||||
}
|
||||
|
||||
if (input.isKeyPressed(Key.KEY_ENTER)) {
|
||||
player.interact();
|
||||
}
|
||||
|
||||
if (!controls) {
|
||||
return;
|
||||
}
|
||||
|
||||
InputUtil.handleBasicControl(player, input);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(Context context, GameMap map, float dt) {
|
||||
cameraController.update();
|
||||
|
||||
if(!dayNightCycle) {
|
||||
return;
|
||||
}
|
||||
|
||||
var x = runner.getTime().getProgress();
|
||||
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)
|
||||
);
|
||||
}
|
||||
|
||||
private float ambientColor(float a, float b, float offset, float x) {
|
||||
return ((float) max(sin(x * PI * a + b), 0) + offset) / (1 + offset);
|
||||
}
|
||||
|
||||
public CompletableFuture<Object> dialog(NamedCharacter speaker, String message, WindowPosition position) {
|
||||
return guiManager.showDialog(speaker.getName(), speaker.getDialogNameColor(), message, position);
|
||||
}
|
||||
|
||||
public CompletableFuture<Object> dialog(NamedCharacter speaker, String message) {
|
||||
return guiManager.showDialog(speaker.getName(), speaker.getDialogNameColor(), message, WindowPosition.BOTTOM);
|
||||
}
|
||||
|
||||
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,114 +1,128 @@
|
||||
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.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.demo.map.ForrestTempleHandler;
|
||||
import com.bartlomiejpluta.demo.entity.Player;
|
||||
import com.bartlomiejpluta.demo.menu.MenuManager;
|
||||
import com.bartlomiejpluta.demo.database.dao.*;
|
||||
|
||||
import com.bartlomiejpluta.demo.world.weapon.MeleeWeapon;
|
||||
|
||||
public class DemoRunner implements GameRunner {
|
||||
private static final Logger log = LoggerFactory.getLogger(DemoRunner.class);
|
||||
|
||||
@Getter
|
||||
private WorldTime time;
|
||||
private static DemoRunner INSTANCE;
|
||||
|
||||
private Screen screen;
|
||||
private Context context;
|
||||
private MenuManager menu;
|
||||
private GUI hud;
|
||||
|
||||
@Getter
|
||||
private MeleeWeaponDAO meleeWeaponDAO = new MeleeWeaponDAO();
|
||||
|
||||
@Getter
|
||||
private EnemyDAO enemyDAO = new EnemyDAO();
|
||||
private GuiManager guiManager;
|
||||
|
||||
@Getter
|
||||
private Player player;
|
||||
|
||||
@Override
|
||||
public void init(Context context) {
|
||||
this.context = context;
|
||||
this.screen = context.getScreen();
|
||||
|
||||
configureScreen();
|
||||
configureCamera();
|
||||
initDAOs();
|
||||
initMenu();
|
||||
initPlayer();
|
||||
|
||||
menu.showStartMenu();
|
||||
|
||||
screen.show();
|
||||
public static DemoRunner instance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
private void configureScreen() {
|
||||
var resolution = screen.getCurrentResolution();
|
||||
screen.setSize(800, 600);
|
||||
screen.setPosition((resolution.x() - 800)/2, (resolution.y() - 600)/2);
|
||||
var resolution = screen.getCurrentResolution();
|
||||
var config = dao.config.find("screen").getValue().split("x");
|
||||
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() {
|
||||
context.getCamera().setScale(2f);
|
||||
}
|
||||
|
||||
private void initDAOs() {
|
||||
meleeWeaponDAO.init(context);
|
||||
enemyDAO.init(context);
|
||||
context.getCamera().setScale(Float.parseFloat(dao.config.find("camera_scale").getValue()));
|
||||
}
|
||||
|
||||
private void initMenu() {
|
||||
this.menu = new MenuManager(this, context);
|
||||
this.guiManager = new GuiManager(this, context);
|
||||
}
|
||||
|
||||
private void initHUD() {
|
||||
hud = context.newGUI();
|
||||
hud.hide();
|
||||
var hudComponent = hud.inflateComponent(A.widgets.hud.$);
|
||||
hud.setRoot(hudComponent);
|
||||
}
|
||||
|
||||
private void initPlayer() {
|
||||
this.player = new Player(context, context.createEntity("815a5c5c-4979-42f5-a42a-ccbbff9a97e5"));
|
||||
}
|
||||
|
||||
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 MeleeWeapon(meleeWeaponDAO.get("wooden_sword")));
|
||||
this.player = new Player(context.createCharacter(A.charsets.luna.$));
|
||||
}
|
||||
|
||||
public void newGame() {
|
||||
menu.closeAll();
|
||||
menu.enableGameMenu();
|
||||
resetPlayer();
|
||||
context.openMap(ForrestTempleHandler.UID);
|
||||
context.getMap().getObjectLayer(ForrestTempleHandler.MAIN_LAYER).addEntity(this.player);
|
||||
context.resume();
|
||||
context.resetMaps();
|
||||
guiManager.closeAll();
|
||||
guiManager.enableGameMenu();
|
||||
player.reset();
|
||||
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();
|
||||
hud.show();
|
||||
}
|
||||
|
||||
public void returnToStartMenu() {
|
||||
menu.closeAll();
|
||||
context.pause();
|
||||
context.closeMap();
|
||||
menu.disableGameMenu();
|
||||
menu.showStartMenu();
|
||||
guiManager.closeAll();
|
||||
hud.hide();
|
||||
context.pause();
|
||||
context.closeMap();
|
||||
guiManager.disableGameMenu();
|
||||
guiManager.showStartMenu();
|
||||
}
|
||||
|
||||
public void exit() {
|
||||
context.close();
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(float dt) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
package com.bartlomiejpluta.demo.util;
|
||||
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import java.util.regex.*;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class DiceRoller {
|
||||
private static final Pattern CODE_PATTERN = Pattern.compile("(\\d+)d(\\d+)([+-]\\d+)?");
|
||||
private final Random random = new Random();
|
||||
private int rolls;
|
||||
private int dice;
|
||||
private int modifier;
|
||||
|
||||
public int roll() {
|
||||
var sum = modifier;
|
||||
|
||||
for(int i=0; i<rolls; ++i) {
|
||||
sum += random.nextInt(dice) + 1;
|
||||
}
|
||||
|
||||
return Math.max(0, sum);
|
||||
}
|
||||
|
||||
public static DiceRoller of(String code) {
|
||||
var matcher = CODE_PATTERN.matcher(code);
|
||||
matcher.matches();
|
||||
return new DiceRoller(Integer.valueOf(matcher.group(1)), Integer.valueOf(matcher.group(2)), Integer.valueOf(matcher.group(3)));
|
||||
}
|
||||
}
|
||||
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]));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.bartlomiejpluta.demo.util;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
import java.util.LinkedList;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class LimitedQueue<E> extends LinkedList<E> {
|
||||
private int limit;
|
||||
|
||||
@Override
|
||||
public boolean add(E o) {
|
||||
super.add(o);
|
||||
|
||||
while (size() > limit) {
|
||||
super.remove();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||