Adding waiting between location moves.

This commit is contained in:
Sergiotarxz 2023-06-23 01:39:47 +02:00
parent de2cfae5a7
commit 305c5316b3
19 changed files with 4103 additions and 114 deletions

View File

@ -0,0 +1,312 @@
--
-- Created by SQL::Translator::Producer::PostgreSQL
-- Created on Thu Jun 22 23:52:23 2023
--
;
--
-- Table: equipment
--
CREATE TABLE "equipment" (
"uuid" uuid NOT NULL,
PRIMARY KEY ("uuid")
);
;
--
-- Table: inventories
--
CREATE TABLE "inventories" (
"uuid" uuid NOT NULL,
PRIMARY KEY ("uuid")
);
;
--
-- Table: players
--
CREATE TABLE "players" (
"uuid" uuid NOT NULL,
"username" text NOT NULL,
"encrypted_password" text NOT NULL,
"email" text NOT NULL,
"verified" boolean NOT NULL,
"verification_token" text,
"register_date" timestamp DEFAULT NOW() NOT NULL,
"last_activity" timestamp DEFAULT NOW() NOT NULL,
PRIMARY KEY ("uuid"),
CONSTRAINT "unique_constraint_email" UNIQUE ("email"),
CONSTRAINT "unique_constraint_username" UNIQUE ("username")
);
;
--
-- Table: skill_like_lists
--
CREATE TABLE "skill_like_lists" (
"uuid" uuid DEFAULT uuid_generate_v4() NOT NULL,
PRIMARY KEY ("uuid")
);
;
--
-- Table: stats
--
CREATE TABLE "stats" (
"uuid" uuid NOT NULL,
"health" integer NOT NULL,
"mana" integer NOT NULL,
"strength" integer NOT NULL,
"resistance" integer NOT NULL,
"magic" integer NOT NULL,
"speed" integer NOT NULL,
"intelligence" integer NOT NULL,
PRIMARY KEY ("uuid")
);
;
--
-- Table: equipment_items
--
CREATE TABLE "equipment_items" (
"kind" text NOT NULL,
"equipment" uuid NOT NULL,
"identifier" text NOT NULL,
"quantity" integer NOT NULL,
PRIMARY KEY ("kind", "equipment")
);
CREATE INDEX "equipment_items_idx_equipment" on "equipment_items" ("equipment");
;
--
-- Table: inventory_items
--
CREATE TABLE "inventory_items" (
"uuid" uuid DEFAULT uuid_generate_v4() NOT NULL,
"inventory" uuid NOT NULL,
"identifier" text NOT NULL,
"quantity" integer NOT NULL,
PRIMARY KEY ("uuid"),
CONSTRAINT "inventory_items_unique_item" UNIQUE ("inventory", "identifier")
);
CREATE INDEX "inventory_items_idx_inventory" on "inventory_items" ("inventory");
;
--
-- Table: skill_like_items
--
CREATE TABLE "skill_like_items" (
"identifier" text NOT NULL,
"owner_list" uuid NOT NULL,
"level" integer DEFAULT 1 NOT NULL,
PRIMARY KEY ("identifier", "owner_list")
);
CREATE INDEX "skill_like_items_idx_owner_list" on "skill_like_items" ("owner_list");
;
--
-- Table: teams
--
CREATE TABLE "teams" (
"uuid" uuid NOT NULL,
"is_exploring" boolean DEFAULT false NOT NULL,
"leader" uuid,
"name" text NOT NULL,
"planet" text NOT NULL,
"super_area" text NOT NULL,
"area" text NOT NULL,
"location" text NOT NULL,
PRIMARY KEY ("uuid"),
CONSTRAINT "u_name" UNIQUE ("name")
);
CREATE INDEX "teams_idx_leader" on "teams" ("leader");
;
--
-- Table: player_pjs
--
CREATE TABLE "player_pjs" (
"uuid" uuid DEFAULT uuid_generate_v4() NOT NULL,
"owner" uuid NOT NULL,
"full_name" text NOT NULL,
"short_name" text NOT NULL,
"nick" text NOT NULL,
"race" text NOT NULL,
"team" uuid NOT NULL,
"creation_date" timestamp DEFAULT NOW() NOT NULL,
"last_activity" timestamp DEFAULT NOW() NOT NULL,
"experience" integer DEFAULT 1 NOT NULL,
"equipment" uuid NOT NULL,
"born_stats" uuid NOT NULL,
"training_stats" uuid NOT NULL,
"skills" uuid NOT NULL,
"spells" uuid NOT NULL,
"inventory" uuid NOT NULL,
"health" integer NOT NULL,
"mana" integer NOT NULL,
PRIMARY KEY ("uuid")
);
CREATE INDEX "player_pjs_idx_born_stats" on "player_pjs" ("born_stats");
CREATE INDEX "player_pjs_idx_equipment" on "player_pjs" ("equipment");
CREATE INDEX "player_pjs_idx_inventory" on "player_pjs" ("inventory");
CREATE INDEX "player_pjs_idx_owner" on "player_pjs" ("owner");
CREATE INDEX "player_pjs_idx_skills" on "player_pjs" ("skills");
CREATE INDEX "player_pjs_idx_spells" on "player_pjs" ("spells");
CREATE INDEX "player_pjs_idx_team" on "player_pjs" ("team");
CREATE INDEX "player_pjs_idx_training_stats" on "player_pjs" ("training_stats");
;
--
-- Table: player_companion_npcs
--
CREATE TABLE "player_companion_npcs" (
"uuid" uuid DEFAULT uuid_generate_v4() NOT NULL,
"owner" uuid NOT NULL,
"identifier" text NOT NULL,
"nick" text,
"race" text NOT NULL,
"level" integer DEFAULT 1 NOT NULL,
"exp" integer DEFAULT 1 NOT NULL,
"equipment" uuid NOT NULL,
"stats" uuid NOT NULL,
"skills" uuid NOT NULL,
"spells" uuid NOT NULL,
"inventory" uuid NOT NULL,
PRIMARY KEY ("uuid")
);
CREATE INDEX "player_companion_npcs_idx_equipment" on "player_companion_npcs" ("equipment");
CREATE INDEX "player_companion_npcs_idx_inventory" on "player_companion_npcs" ("inventory");
CREATE INDEX "player_companion_npcs_idx_owner" on "player_companion_npcs" ("owner");
CREATE INDEX "player_companion_npcs_idx_skills" on "player_companion_npcs" ("skills");
CREATE INDEX "player_companion_npcs_idx_spells" on "player_companion_npcs" ("spells");
CREATE INDEX "player_companion_npcs_idx_stats" on "player_companion_npcs" ("stats");
;
--
-- Table: player_pjs_flags
--
CREATE TABLE "player_pjs_flags" (
"name" text NOT NULL,
"owner" uuid NOT NULL,
PRIMARY KEY ("name", "owner")
);
CREATE INDEX "player_pjs_flags_idx_owner" on "player_pjs_flags" ("owner");
CREATE INDEX "index_flag" on "player_pjs_flags" ("owner", "name");
;
--
-- Table: player_pjs_known_places
--
CREATE TABLE "player_pjs_known_places" (
"owner" uuid NOT NULL,
"planet" text NOT NULL,
"super_area" text NOT NULL,
"area" text NOT NULL,
"location" text NOT NULL,
PRIMARY KEY ("owner", "planet", "super_area", "area", "location")
);
CREATE INDEX "player_pjs_known_places_idx_owner" on "player_pjs_known_places" ("owner");
;
--
-- Table: player_pjs_log
--
CREATE TABLE "player_pjs_log" (
"uuid" uuid NOT NULL,
"content" jsonb NOT NULL,
"owner" uuid NOT NULL,
"date" timestamp DEFAULT NOW() NOT NULL,
PRIMARY KEY ("uuid")
);
CREATE INDEX "player_pjs_log_idx_owner" on "player_pjs_log" ("owner");
CREATE INDEX "index_log" on "player_pjs_log" ("owner", "date");
;
--
-- Foreign Key Definitions
--
;
ALTER TABLE "equipment_items" ADD CONSTRAINT "equipment_items_fk_equipment" FOREIGN KEY ("equipment")
REFERENCES "equipment" ("uuid") ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE;
;
ALTER TABLE "inventory_items" ADD CONSTRAINT "inventory_items_fk_inventory" FOREIGN KEY ("inventory")
REFERENCES "inventories" ("uuid") ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE;
;
ALTER TABLE "skill_like_items" ADD CONSTRAINT "skill_like_items_fk_owner_list" FOREIGN KEY ("owner_list")
REFERENCES "skill_like_lists" ("uuid") ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE;
;
ALTER TABLE "teams" ADD CONSTRAINT "teams_fk_leader" FOREIGN KEY ("leader")
REFERENCES "player_pjs" ("uuid") DEFERRABLE;
;
ALTER TABLE "player_pjs" ADD CONSTRAINT "player_pjs_fk_born_stats" FOREIGN KEY ("born_stats")
REFERENCES "stats" ("uuid") DEFERRABLE;
;
ALTER TABLE "player_pjs" ADD CONSTRAINT "player_pjs_fk_equipment" FOREIGN KEY ("equipment")
REFERENCES "equipment" ("uuid") DEFERRABLE;
;
ALTER TABLE "player_pjs" ADD CONSTRAINT "player_pjs_fk_inventory" FOREIGN KEY ("inventory")
REFERENCES "inventories" ("uuid") DEFERRABLE;
;
ALTER TABLE "player_pjs" ADD CONSTRAINT "player_pjs_fk_owner" FOREIGN KEY ("owner")
REFERENCES "players" ("uuid") ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE;
;
ALTER TABLE "player_pjs" ADD CONSTRAINT "player_pjs_fk_skills" FOREIGN KEY ("skills")
REFERENCES "skill_like_lists" ("uuid") DEFERRABLE;
;
ALTER TABLE "player_pjs" ADD CONSTRAINT "player_pjs_fk_spells" FOREIGN KEY ("spells")
REFERENCES "skill_like_lists" ("uuid") DEFERRABLE;
;
ALTER TABLE "player_pjs" ADD CONSTRAINT "player_pjs_fk_team" FOREIGN KEY ("team")
REFERENCES "teams" ("uuid") ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE;
;
ALTER TABLE "player_pjs" ADD CONSTRAINT "player_pjs_fk_training_stats" FOREIGN KEY ("training_stats")
REFERENCES "stats" ("uuid") DEFERRABLE;
;
ALTER TABLE "player_companion_npcs" ADD CONSTRAINT "player_companion_npcs_fk_equipment" FOREIGN KEY ("equipment")
REFERENCES "equipment" ("uuid") DEFERRABLE;
;
ALTER TABLE "player_companion_npcs" ADD CONSTRAINT "player_companion_npcs_fk_inventory" FOREIGN KEY ("inventory")
REFERENCES "inventories" ("uuid") DEFERRABLE;
;
ALTER TABLE "player_companion_npcs" ADD CONSTRAINT "player_companion_npcs_fk_owner" FOREIGN KEY ("owner")
REFERENCES "player_pjs" ("uuid") ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE;
;
ALTER TABLE "player_companion_npcs" ADD CONSTRAINT "player_companion_npcs_fk_skills" FOREIGN KEY ("skills")
REFERENCES "skill_like_lists" ("uuid") DEFERRABLE;
;
ALTER TABLE "player_companion_npcs" ADD CONSTRAINT "player_companion_npcs_fk_spells" FOREIGN KEY ("spells")
REFERENCES "skill_like_lists" ("uuid") DEFERRABLE;
;
ALTER TABLE "player_companion_npcs" ADD CONSTRAINT "player_companion_npcs_fk_stats" FOREIGN KEY ("stats")
REFERENCES "stats" ("uuid") DEFERRABLE;
;
ALTER TABLE "player_pjs_flags" ADD CONSTRAINT "player_pjs_flags_fk_owner" FOREIGN KEY ("owner")
REFERENCES "player_pjs" ("uuid") ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE;
;
ALTER TABLE "player_pjs_known_places" ADD CONSTRAINT "player_pjs_known_places_fk_owner" FOREIGN KEY ("owner")
REFERENCES "player_pjs" ("uuid") ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE;
;
ALTER TABLE "player_pjs_log" ADD CONSTRAINT "player_pjs_log_fk_owner" FOREIGN KEY ("owner")
REFERENCES "player_pjs" ("uuid") ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE;
;

View File

@ -0,0 +1,315 @@
--
-- Created by SQL::Translator::Producer::PostgreSQL
-- Created on Thu Jun 22 23:54:09 2023
--
;
--
-- Table: equipment
--
CREATE TABLE "equipment" (
"uuid" uuid NOT NULL,
PRIMARY KEY ("uuid")
);
;
--
-- Table: inventories
--
CREATE TABLE "inventories" (
"uuid" uuid NOT NULL,
PRIMARY KEY ("uuid")
);
;
--
-- Table: players
--
CREATE TABLE "players" (
"uuid" uuid NOT NULL,
"username" text NOT NULL,
"encrypted_password" text NOT NULL,
"email" text NOT NULL,
"verified" boolean NOT NULL,
"verification_token" text,
"register_date" timestamp DEFAULT NOW() NOT NULL,
"last_activity" timestamp DEFAULT NOW() NOT NULL,
PRIMARY KEY ("uuid"),
CONSTRAINT "unique_constraint_email" UNIQUE ("email"),
CONSTRAINT "unique_constraint_username" UNIQUE ("username")
);
;
--
-- Table: skill_like_lists
--
CREATE TABLE "skill_like_lists" (
"uuid" uuid DEFAULT uuid_generate_v4() NOT NULL,
PRIMARY KEY ("uuid")
);
;
--
-- Table: stats
--
CREATE TABLE "stats" (
"uuid" uuid NOT NULL,
"health" integer NOT NULL,
"mana" integer NOT NULL,
"strength" integer NOT NULL,
"resistance" integer NOT NULL,
"magic" integer NOT NULL,
"speed" integer NOT NULL,
"intelligence" integer NOT NULL,
PRIMARY KEY ("uuid")
);
;
--
-- Table: equipment_items
--
CREATE TABLE "equipment_items" (
"kind" text NOT NULL,
"equipment" uuid NOT NULL,
"identifier" text NOT NULL,
"quantity" integer NOT NULL,
PRIMARY KEY ("kind", "equipment")
);
CREATE INDEX "equipment_items_idx_equipment" on "equipment_items" ("equipment");
;
--
-- Table: inventory_items
--
CREATE TABLE "inventory_items" (
"uuid" uuid DEFAULT uuid_generate_v4() NOT NULL,
"inventory" uuid NOT NULL,
"identifier" text NOT NULL,
"quantity" integer NOT NULL,
PRIMARY KEY ("uuid"),
CONSTRAINT "inventory_items_unique_item" UNIQUE ("inventory", "identifier")
);
CREATE INDEX "inventory_items_idx_inventory" on "inventory_items" ("inventory");
;
--
-- Table: skill_like_items
--
CREATE TABLE "skill_like_items" (
"identifier" text NOT NULL,
"owner_list" uuid NOT NULL,
"level" integer DEFAULT 1 NOT NULL,
PRIMARY KEY ("identifier", "owner_list")
);
CREATE INDEX "skill_like_items_idx_owner_list" on "skill_like_items" ("owner_list");
;
--
-- Table: teams
--
CREATE TABLE "teams" (
"uuid" uuid NOT NULL,
"is_exploring" boolean DEFAULT false NOT NULL,
"action_frame" integer DEFAULT 0 NOT NULL,
"is_moving" boolean DEFAULT false NOT NULL,
"moving_to" jsonb DEFAULT 'null' NOT NULL,
"leader" uuid,
"name" text NOT NULL,
"planet" text NOT NULL,
"super_area" text NOT NULL,
"area" text NOT NULL,
"location" text NOT NULL,
PRIMARY KEY ("uuid"),
CONSTRAINT "u_name" UNIQUE ("name")
);
CREATE INDEX "teams_idx_leader" on "teams" ("leader");
;
--
-- Table: player_pjs
--
CREATE TABLE "player_pjs" (
"uuid" uuid DEFAULT uuid_generate_v4() NOT NULL,
"owner" uuid NOT NULL,
"full_name" text NOT NULL,
"short_name" text NOT NULL,
"nick" text NOT NULL,
"race" text NOT NULL,
"team" uuid NOT NULL,
"creation_date" timestamp DEFAULT NOW() NOT NULL,
"last_activity" timestamp DEFAULT NOW() NOT NULL,
"experience" integer DEFAULT 1 NOT NULL,
"equipment" uuid NOT NULL,
"born_stats" uuid NOT NULL,
"training_stats" uuid NOT NULL,
"skills" uuid NOT NULL,
"spells" uuid NOT NULL,
"inventory" uuid NOT NULL,
"health" integer NOT NULL,
"mana" integer NOT NULL,
PRIMARY KEY ("uuid")
);
CREATE INDEX "player_pjs_idx_born_stats" on "player_pjs" ("born_stats");
CREATE INDEX "player_pjs_idx_equipment" on "player_pjs" ("equipment");
CREATE INDEX "player_pjs_idx_inventory" on "player_pjs" ("inventory");
CREATE INDEX "player_pjs_idx_owner" on "player_pjs" ("owner");
CREATE INDEX "player_pjs_idx_skills" on "player_pjs" ("skills");
CREATE INDEX "player_pjs_idx_spells" on "player_pjs" ("spells");
CREATE INDEX "player_pjs_idx_team" on "player_pjs" ("team");
CREATE INDEX "player_pjs_idx_training_stats" on "player_pjs" ("training_stats");
;
--
-- Table: player_companion_npcs
--
CREATE TABLE "player_companion_npcs" (
"uuid" uuid DEFAULT uuid_generate_v4() NOT NULL,
"owner" uuid NOT NULL,
"identifier" text NOT NULL,
"nick" text,
"race" text NOT NULL,
"level" integer DEFAULT 1 NOT NULL,
"exp" integer DEFAULT 1 NOT NULL,
"equipment" uuid NOT NULL,
"stats" uuid NOT NULL,
"skills" uuid NOT NULL,
"spells" uuid NOT NULL,
"inventory" uuid NOT NULL,
PRIMARY KEY ("uuid")
);
CREATE INDEX "player_companion_npcs_idx_equipment" on "player_companion_npcs" ("equipment");
CREATE INDEX "player_companion_npcs_idx_inventory" on "player_companion_npcs" ("inventory");
CREATE INDEX "player_companion_npcs_idx_owner" on "player_companion_npcs" ("owner");
CREATE INDEX "player_companion_npcs_idx_skills" on "player_companion_npcs" ("skills");
CREATE INDEX "player_companion_npcs_idx_spells" on "player_companion_npcs" ("spells");
CREATE INDEX "player_companion_npcs_idx_stats" on "player_companion_npcs" ("stats");
;
--
-- Table: player_pjs_flags
--
CREATE TABLE "player_pjs_flags" (
"name" text NOT NULL,
"owner" uuid NOT NULL,
PRIMARY KEY ("name", "owner")
);
CREATE INDEX "player_pjs_flags_idx_owner" on "player_pjs_flags" ("owner");
CREATE INDEX "index_flag" on "player_pjs_flags" ("owner", "name");
;
--
-- Table: player_pjs_known_places
--
CREATE TABLE "player_pjs_known_places" (
"owner" uuid NOT NULL,
"planet" text NOT NULL,
"super_area" text NOT NULL,
"area" text NOT NULL,
"location" text NOT NULL,
PRIMARY KEY ("owner", "planet", "super_area", "area", "location")
);
CREATE INDEX "player_pjs_known_places_idx_owner" on "player_pjs_known_places" ("owner");
;
--
-- Table: player_pjs_log
--
CREATE TABLE "player_pjs_log" (
"uuid" uuid NOT NULL,
"content" jsonb NOT NULL,
"owner" uuid NOT NULL,
"date" timestamp DEFAULT NOW() NOT NULL,
PRIMARY KEY ("uuid")
);
CREATE INDEX "player_pjs_log_idx_owner" on "player_pjs_log" ("owner");
CREATE INDEX "index_log" on "player_pjs_log" ("owner", "date");
;
--
-- Foreign Key Definitions
--
;
ALTER TABLE "equipment_items" ADD CONSTRAINT "equipment_items_fk_equipment" FOREIGN KEY ("equipment")
REFERENCES "equipment" ("uuid") ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE;
;
ALTER TABLE "inventory_items" ADD CONSTRAINT "inventory_items_fk_inventory" FOREIGN KEY ("inventory")
REFERENCES "inventories" ("uuid") ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE;
;
ALTER TABLE "skill_like_items" ADD CONSTRAINT "skill_like_items_fk_owner_list" FOREIGN KEY ("owner_list")
REFERENCES "skill_like_lists" ("uuid") ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE;
;
ALTER TABLE "teams" ADD CONSTRAINT "teams_fk_leader" FOREIGN KEY ("leader")
REFERENCES "player_pjs" ("uuid") DEFERRABLE;
;
ALTER TABLE "player_pjs" ADD CONSTRAINT "player_pjs_fk_born_stats" FOREIGN KEY ("born_stats")
REFERENCES "stats" ("uuid") DEFERRABLE;
;
ALTER TABLE "player_pjs" ADD CONSTRAINT "player_pjs_fk_equipment" FOREIGN KEY ("equipment")
REFERENCES "equipment" ("uuid") DEFERRABLE;
;
ALTER TABLE "player_pjs" ADD CONSTRAINT "player_pjs_fk_inventory" FOREIGN KEY ("inventory")
REFERENCES "inventories" ("uuid") DEFERRABLE;
;
ALTER TABLE "player_pjs" ADD CONSTRAINT "player_pjs_fk_owner" FOREIGN KEY ("owner")
REFERENCES "players" ("uuid") ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE;
;
ALTER TABLE "player_pjs" ADD CONSTRAINT "player_pjs_fk_skills" FOREIGN KEY ("skills")
REFERENCES "skill_like_lists" ("uuid") DEFERRABLE;
;
ALTER TABLE "player_pjs" ADD CONSTRAINT "player_pjs_fk_spells" FOREIGN KEY ("spells")
REFERENCES "skill_like_lists" ("uuid") DEFERRABLE;
;
ALTER TABLE "player_pjs" ADD CONSTRAINT "player_pjs_fk_team" FOREIGN KEY ("team")
REFERENCES "teams" ("uuid") ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE;
;
ALTER TABLE "player_pjs" ADD CONSTRAINT "player_pjs_fk_training_stats" FOREIGN KEY ("training_stats")
REFERENCES "stats" ("uuid") DEFERRABLE;
;
ALTER TABLE "player_companion_npcs" ADD CONSTRAINT "player_companion_npcs_fk_equipment" FOREIGN KEY ("equipment")
REFERENCES "equipment" ("uuid") DEFERRABLE;
;
ALTER TABLE "player_companion_npcs" ADD CONSTRAINT "player_companion_npcs_fk_inventory" FOREIGN KEY ("inventory")
REFERENCES "inventories" ("uuid") DEFERRABLE;
;
ALTER TABLE "player_companion_npcs" ADD CONSTRAINT "player_companion_npcs_fk_owner" FOREIGN KEY ("owner")
REFERENCES "player_pjs" ("uuid") ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE;
;
ALTER TABLE "player_companion_npcs" ADD CONSTRAINT "player_companion_npcs_fk_skills" FOREIGN KEY ("skills")
REFERENCES "skill_like_lists" ("uuid") DEFERRABLE;
;
ALTER TABLE "player_companion_npcs" ADD CONSTRAINT "player_companion_npcs_fk_spells" FOREIGN KEY ("spells")
REFERENCES "skill_like_lists" ("uuid") DEFERRABLE;
;
ALTER TABLE "player_companion_npcs" ADD CONSTRAINT "player_companion_npcs_fk_stats" FOREIGN KEY ("stats")
REFERENCES "stats" ("uuid") DEFERRABLE;
;
ALTER TABLE "player_pjs_flags" ADD CONSTRAINT "player_pjs_flags_fk_owner" FOREIGN KEY ("owner")
REFERENCES "player_pjs" ("uuid") ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE;
;
ALTER TABLE "player_pjs_known_places" ADD CONSTRAINT "player_pjs_known_places_fk_owner" FOREIGN KEY ("owner")
REFERENCES "player_pjs" ("uuid") ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE;
;
ALTER TABLE "player_pjs_log" ADD CONSTRAINT "player_pjs_log_fk_owner" FOREIGN KEY ("owner")
REFERENCES "player_pjs" ("uuid") ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE;
;

View File

@ -0,0 +1,12 @@
-- Convert schema '/home/sergio/LasTres/script/../dbicdh/_source/deploy/7/001-auto.yml' to '/home/sergio/LasTres/script/../dbicdh/_source/deploy/8/001-auto.yml':;
;
BEGIN;
;
ALTER TABLE teams DROP COLUMN explore_frame;
;
COMMIT;

View File

@ -0,0 +1,18 @@
-- Convert schema '/home/sergio/LasTres/script/../dbicdh/_source/deploy/8/001-auto.yml' to '/home/sergio/LasTres/script/../dbicdh/_source/deploy/9/001-auto.yml':;
;
BEGIN;
;
ALTER TABLE teams ADD COLUMN action_frame integer DEFAULT 0 NOT NULL;
;
ALTER TABLE teams ADD COLUMN is_moving boolean DEFAULT false NOT NULL;
;
ALTER TABLE teams ADD COLUMN moving_to jsonb DEFAULT 'null' NOT NULL;
;
COMMIT;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -41,6 +41,7 @@ export default function Game (props: GameProps): JSX.Element {
const [logLines, setLogLines] = React.useState<LogLine[] | null>(null) const [logLines, setLogLines] = React.useState<LogLine[] | null>(null)
const [error, setError] = React.useState<string | null>(null) const [error, setError] = React.useState<string | null>(null)
const [scrollLog, setScrollLog] = React.useState<number | null>(null) const [scrollLog, setScrollLog] = React.useState<number | null>(null)
const [movingTo, setMovingTo] = React.useState<Location | null>(null)
const logPresentationRef = React.useRef<HTMLDivElement>(null) const logPresentationRef = React.useRef<HTMLDivElement>(null)
window.setTimeout(() => { window.setTimeout(() => {
setWebsocket((websocket): WebSocket | null => { setWebsocket((websocket): WebSocket | null => {
@ -65,7 +66,7 @@ export default function Game (props: GameProps): JSX.Element {
const inputPackets = new InputPackets(setTeamPJs, const inputPackets = new InputPackets(setTeamPJs,
setCurrentLocation, setConnectedLocations, setCurrentLocation, setConnectedLocations,
logLines, setLogLines, setError, setScrollLog, logLines, setLogLines, setError, setScrollLog,
logPresentationRef) logPresentationRef, setMovingTo)
webSocket.onmessage = (event) => { webSocket.onmessage = (event) => {
const packet = JSON.parse(event.data) const packet = JSON.parse(event.data)
inputPackets.handle(packet) inputPackets.handle(packet)
@ -74,6 +75,7 @@ export default function Game (props: GameProps): JSX.Element {
console.log(event) console.log(event)
} }
webSocket.onclose = (event) => { webSocket.onclose = (event) => {
console.log('Websocket closed')
setWebsocket(null) setWebsocket(null)
} }
return webSocket return webSocket
@ -88,7 +90,8 @@ export default function Game (props: GameProps): JSX.Element {
connectedLocations={connectedLocations} connectedLocations={connectedLocations}
logLines={logLines} logLines={logLines}
websocket={websocket} websocket={websocket}
logPresentationRef={logPresentationRef}/> logPresentationRef={logPresentationRef}
movingTo={movingTo}/>
<BottomPanel/> <BottomPanel/>
</> </>
) )

View File

@ -15,6 +15,7 @@ interface UpperPanelProps {
logLines: LogLine[] | null logLines: LogLine[] | null
websocket: WebSocket | null websocket: WebSocket | null
logPresentationRef: React.RefObject<HTMLDivElement> logPresentationRef: React.RefObject<HTMLDivElement>
movingTo: Location | null
} }
export default function UpperPanel (props: UpperPanelProps): JSX.Element { export default function UpperPanel (props: UpperPanelProps): JSX.Element {
@ -39,6 +40,46 @@ export default function UpperPanel (props: UpperPanelProps): JSX.Element {
} }
} }
function availableLocationsToMove (): JSX.Element {
if (connectedLocations === null || connectedLocations.length === 0) {
return (
<>
</>
)
}
return (
<>
<p>Puedes ir a:</p>
<ul>
{
connectedLocations.map((item, i) => {
return <li key={i}>
<a href="#" onClick={() => {
onClickLocation(item)
}}>{item.area.name}/{item.location.name}</a>
</li>
})
}
</ul>
</>
)
}
function showLocationMenuHeaderText (): JSX.Element {
if (currentLocation === null) {
return <></>
}
if (props.movingTo === null) {
return <p>Estás en <span style={{ color: 'red' }}>{currentLocation.area.name}</span>
/
<span style={{ color: 'green' }}>{currentLocation.location.name}</span>.
</p>
}
return <p>Estás yendo a <span style={{ color: 'red' }}>{props.movingTo.area.name}</span>
/
<span style={{ color: 'green' }}>{props.movingTo.location.name}</span>.
</p>
}
return ( return (
<Presentation> <Presentation>
<PresentationItem> <PresentationItem>
@ -52,19 +93,12 @@ export default function UpperPanel (props: UpperPanelProps): JSX.Element {
<LogPanel logLines={logLines}/> <LogPanel logLines={logLines}/>
</PresentationItem> </PresentationItem>
<PresentationItem> <PresentationItem>
<p>Estás en {currentLocation.area.name}/{currentLocation.location.name}.</p> {
<p>Puedes ir a:</p> showLocationMenuHeaderText()
<ul> }
{ {
connectedLocations.map((item, i) => { availableLocationsToMove()
return <li key={i}> }
<a href="#" onClick={() => {
onClickLocation(item)
}}>{item.area.name}/{item.location.name}</a>
</li>
})
}
</ul>
</PresentationItem> </PresentationItem>
</Presentation> </Presentation>
) )

View File

@ -15,6 +15,7 @@ type SetError = (set: string | null) => void
type SetScrollLogCallback = (set: number | null) => number | null type SetScrollLogCallback = (set: number | null) => number | null
type SetScrollLog = (set: number | null | SetScrollLogCallback) => void type SetScrollLog = (set: number | null | SetScrollLogCallback) => void
type LogPresentationRef = React.RefObject<HTMLDivElement> type LogPresentationRef = React.RefObject<HTMLDivElement>
type SetMovingTo = (set: Location | null) => void
interface Packet { interface Packet {
command: string command: string
@ -22,7 +23,6 @@ interface Packet {
} }
type LogHash = Record<string, LogLine> type LogHash = Record<string, LogLine>
export default class InputPackets { export default class InputPackets {
setTeamPJs: SetTeamPJs setTeamPJs: SetTeamPJs
setCurrentLocation: SetCurrentLocation setCurrentLocation: SetCurrentLocation
@ -34,6 +34,7 @@ export default class InputPackets {
setError: SetError setError: SetError
setScrollLog: SetScrollLog setScrollLog: SetScrollLog
logPresentationRef: LogPresentationRef logPresentationRef: LogPresentationRef
setMovingTo: SetMovingTo
constructor (setTeamPJs: SetTeamPJs, constructor (setTeamPJs: SetTeamPJs,
setCurrentLocation: SetCurrentLocation, setCurrentLocation: SetCurrentLocation,
setConnectedLocations: SetConnectedLocations, setConnectedLocations: SetConnectedLocations,
@ -41,7 +42,8 @@ export default class InputPackets {
setLogLines: SetLogLines, setLogLines: SetLogLines,
setError: SetError, setError: SetError,
setScrollLog: SetScrollLog, setScrollLog: SetScrollLog,
logPresentationRef: LogPresentationRef) { logPresentationRef: LogPresentationRef,
setMovingTo: SetMovingTo) {
this.setTeamPJs = setTeamPJs this.setTeamPJs = setTeamPJs
this.setCurrentLocation = setCurrentLocation this.setCurrentLocation = setCurrentLocation
this.setConnectedLocations = setConnectedLocations this.setConnectedLocations = setConnectedLocations
@ -50,6 +52,7 @@ export default class InputPackets {
this.setError = setError this.setError = setError
this.setScrollLog = setScrollLog this.setScrollLog = setScrollLog
this.logPresentationRef = logPresentationRef this.logPresentationRef = logPresentationRef
this.setMovingTo = setMovingTo
} }
handle (packet: Packet): void { handle (packet: Packet): void {
@ -104,11 +107,19 @@ export default class InputPackets {
if (data.team_pjs !== undefined) { if (data.team_pjs !== undefined) {
this.setTeamPJs(data.team_pjs) this.setTeamPJs(data.team_pjs)
} }
if (data.location_data?.connected_places !== undefined) { if (data.location_data !== undefined) {
this.setConnectedLocations(data.location_data.connected_places) console.log(data.location_data)
} if (data.location_data.connected_places !== undefined) {
if (data.location_data?.current !== undefined) { this.setConnectedLocations(data.location_data.connected_places)
this.setCurrentLocation(data.location_data.current) }
if (data.location_data.current !== undefined) {
this.setCurrentLocation(data.location_data.current)
}
if (data.location_data.moving_to !== undefined) {
this.setMovingTo(data.location_data.moving_to)
} else {
this.setMovingTo(null)
}
} }
if (data.set_log !== undefined) { if (data.set_log !== undefined) {
saveScroll() saveScroll()

View File

@ -2,9 +2,16 @@ export interface NameIdentifierHash {
name: string name: string
identifier: string identifier: string
} }
export interface Area {
name: string
identifier: string
can_explore: boolean
}
export interface Location { export interface Location {
location: NameIdentifierHash location: NameIdentifierHash
area: NameIdentifierHash area: Area
super_area: NameIdentifierHash super_area: NameIdentifierHash
planet: NameIdentifierHash planet: NameIdentifierHash
} }

View File

@ -52,7 +52,14 @@ sub handle ( $self, $ws, $session, $data ) {
my $connected_places = $self->_get_connected_places($pj); my $connected_places = $self->_get_connected_places($pj);
$pj->append_log_line( $pj->append_log_line(
[ { text => 'Nueva conexion a este pj.', color => 'red', background => 'black' }, ] ); [
{
text => 'Nueva conexion a este pj.',
color => 'red',
background => 'black'
},
]
);
if ( !$pj->get_flag( LasTres::Flags::INTRO_MESSAGE_SENT_FLAG() ) ) { if ( !$pj->get_flag( LasTres::Flags::INTRO_MESSAGE_SENT_FLAG() ) ) {
$pj->set_flag(LasTres::Flags::INTRO_MESSAGE_SENT_FLAG); $pj->set_flag(LasTres::Flags::INTRO_MESSAGE_SENT_FLAG);
@ -64,18 +71,14 @@ sub handle ( $self, $ws, $session, $data ) {
] ]
); );
$pj->location->show_intro($pj); $pj->location->show_intro($pj);
$pj->set_known_location($pj->location); $pj->set_known_location( $pj->location );
} }
my $info_packet_to_send = my $info_packet_to_send =
LasTres::Controller::Websocket::OutputPacket::Info->new( LasTres::Controller::Websocket::OutputPacket::Info->new(
set_log => [ $pj->last_50_log ], set_log => [ $pj->last_50_log ],
team_pjs => $team_pjs, team_pjs => $team_pjs,
location_data => { clear => $JSON::true,
current => $location->hash,
connected_places => $connected_places,
},
clear => $JSON::true,
); );
$info_packet_to_send->send($ws); $info_packet_to_send->send($ws);
my $redis = LasTres::Redis->new; my $redis = LasTres::Redis->new;
@ -87,12 +90,14 @@ sub handle ( $self, $ws, $session, $data ) {
} }
); );
$session->{redis} = $redis; $session->{redis} = $redis;
$redis->publish( $redis->pj_subscription($pj),
to_json( { command => 'update-location' } ) );
} }
sub _on_redis_event ( $self, $ws, $session, $message, $topic, $topics ) { sub _on_redis_event ( $self, $ws, $session, $message, $topic, $topics ) {
my $data = from_json($message); my $data = from_json($message);
$session->{pj} = $session->{pj}->get_from_storage; $session->{pj} = $session->{pj}->get_from_storage;
my $pj = $session->{pj}; my $pj = $session->{pj};
if ( $data->{command} eq 'append-log' ) { if ( $data->{command} eq 'append-log' ) {
my $info_packet_to_send = my $info_packet_to_send =
LasTres::Controller::Websocket::OutputPacket::Info->new( LasTres::Controller::Websocket::OutputPacket::Info->new(
@ -101,13 +106,18 @@ sub _on_redis_event ( $self, $ws, $session, $message, $topic, $topics ) {
return; return;
} }
if ( $data->{command} eq 'update-location' ) { if ( $data->{command} eq 'update-location' ) {
my $team = $pj->team; my $team = $pj->team;
my $location = $team->location; my $location = $team->location;
my $connected_places = $self->_get_connected_places($pj); my $connected_places = $self->_get_connected_places($pj);
my $info_packet_to_send = my $info_packet_to_send =
LasTres::Controller::Websocket::OutputPacket::Info->new( LasTres::Controller::Websocket::OutputPacket::Info->new(
location_data => { location_data => {
current => $location->hash, current => $location->hash,
(
( $team->is_moving )
? ( moving_to => LasTres::Location::get(@{from_json( $team->moving_to )})->hash )
: ()
),
connected_places => $connected_places, connected_places => $connected_places,
}, },
); );

View File

@ -64,17 +64,6 @@ sub handle ( $self, $ws, $session, $data ) {
return $ws->send( to_json( { error => 'You cannot travel there.' } ) ); return $ws->send( to_json( { error => 'You cannot travel there.' } ) );
} }
$wanted_location->place_team($team); $wanted_location->move($team);
my $connected_places = $location->get_available_locations_to_move_to($pj);
@$connected_places = map { $_->hash } @$connected_places;
my $info_packet_to_send =
LasTres::Controller::Websocket::OutputPacket::Info->new(
location_data => {
current => $team->location->hash,
connected_places => $connected_places,
},
);
$info_packet_to_send->send($ws);
} }
1; 1;

View File

@ -8,6 +8,7 @@ use warnings;
use feature 'signatures'; use feature 'signatures';
use Moo; use Moo;
use JSON qw/to_json from_json/;
has _app => ( has _app => (
is => 'lazy' is => 'lazy'
@ -47,26 +48,56 @@ $SIG{TERM} = \&_exit_the_program;
sub loop($self) { sub loop($self) {
my $child_pid = fork; my $child_pid = fork;
if ($child_pid) { if (!$child_pid) {
$self->_real_loop; $self->_real_loop;
} }
} }
sub _work_frame($self) { sub _work_frame($self) {
$self->_increment_frame_for_movers();
}
sub _increment_frame_for_movers($self) {
my $schema = $self->_schema; my $schema = $self->_schema;
my $result_set_teams = $schema->resultset('Team');
my @teams = $result_set_teams->search({-bool => 'is_moving'});
for my $team (@teams) {
$self->_increment_frame_for_mover($team);
}
}
sub _increment_frame_for_mover($self, $team) {
$team = $team->get_from_storage;
my $frame = $team->action_frame;
$team->action_frame(++$frame);
$team->update;
my $location = $team->location;
my $target_location = LasTres::Location::get(from_json($team->moving_to)->@*);
if ($frame >= $location->parent->frames_to_move) {
$team->action_frame(0);
$team->is_moving(0);
$team->moving_to('null');
$team->update;
$target_location->place_team($team);
}
} }
sub _real_loop($self) { sub _real_loop($self) {
my $redis = $self->_redis; eval {
while (1) { my $redis = $self->_redis;
if (!defined $redis->db->get($redis->executing_frame_key)) { while (1) {
$redis->db->setex($redis->executing_frame_key, 10, 1); if (!defined $redis->db->get($redis->executing_frame_key)) {
$self->_work_frame; $redis->db->setex($redis->executing_frame_key, 10, 1);
} $self->_work_frame;
my $ttl = $redis->db->ttl($redis->executing_frame_key); }
if ($ttl > 0) { my $ttl = $redis->db->ttl($redis->executing_frame_key);
sleep $ttl; if ($ttl > 0) {
sleep $ttl;
}
} }
};
if ($@) {
warn $@;
} }
} }
1; 1;

View File

@ -10,55 +10,57 @@ use feature 'signatures';
use LasTres::Planets; use LasTres::Planets;
use Moo::Role; use Moo::Role;
use JSON qw/to_json/; use JSON qw/to_json from_json/;
use utf8;
requires qw/identifier name description parent actions npcs/; requires qw/identifier name description parent actions npcs/;
my $planets = LasTres::Planets->new; my $planets = LasTres::Planets->new;
## OVERRIDE ## OVERRIDE
sub can_visit($self, $pj) { sub can_visit ( $self, $pj ) {
return 1; return 1;
} }
## OVERRIDE ## OVERRIDE
sub can_discover($self, $pj) { sub can_discover ( $self, $pj ) {
return 1; return 1;
} }
## OVERRIDE ## OVERRIDE
sub chance_discover($self, $pj) { sub chance_discover ( $self, $pj ) {
return 50; return 50;
} }
## OVERRIDE ## OVERRIDE
sub allow_forced_discovery($self, $pj) { sub allow_forced_discovery ( $self, $pj ) {
return 1; return 1;
} }
## OVERRIDE ## OVERRIDE
sub order($self) { sub order ($self) {
return 1000; return 1000;
} }
## OVERRIDE (Always use $self->SUPER::on_team_arrival.) ## OVERRIDE (Always use $self->SUPER::on_team_arrival.)
sub on_team_arrival($self, $team) { sub on_team_arrival ( $self, $team ) {
$team = $team->get_from_storage; $team = $team->get_from_storage;
for my $pj ($team->members) { for my $pj ( $team->members ) {
$self->on_pj_arrival($pj); $self->on_pj_arrival($pj);
} }
} }
## OVERRIDE (Always use $self->SUPER::on_pj_arrival.) ## OVERRIDE (Always use $self->SUPER::on_pj_arrival.)
sub on_pj_arrival($self, $pj) { sub on_pj_arrival ( $self, $pj ) {
require LasTres::Redis; require LasTres::Redis;
$pj = $pj->get_from_storage; $pj = $pj->get_from_storage;
my $redis = LasTres::Redis->new; my $redis = LasTres::Redis->new;
if (!$pj->knows_location($self)) { if ( !$pj->knows_location($self) ) {
$pj->set_known_location($self); $pj->set_known_location($self);
} }
$self->show_intro($pj); $self->show_intro($pj);
$redis->publish( $redis->pj_subscription($pj), to_json({ command => 'update-location' })); $redis->publish( $redis->pj_subscription($pj),
to_json( { command => 'update-location' } ) );
} }
sub show_intro ( $self, $pj ) { sub show_intro ( $self, $pj ) {
@ -73,7 +75,53 @@ sub show_intro ( $self, $pj ) {
$pj->append_log_line( [ { text => $pj->location->description }, ] ); $pj->append_log_line( [ { text => $pj->location->description }, ] );
} }
sub place_team($self, $team) { sub move ( $self, $team ) {
$team = $team->get_from_storage;
my $current_location = $team->location;
my $json_array_until_area_current_location =
to_json( [ $current_location->to_array->@[ 0 .. 2 ] ] );
my $json_array_until_area_destination =
to_json( [ $self->to_array->@[ 0 .. 2 ] ] );
if ( $json_array_until_area_current_location ne
$json_array_until_area_destination
|| $self->parent->frames_to_move <= 0 )
{
$self->place_team($team);
return;
}
my $schema;
$team->is_moving(1);
$team->moving_to( $self->to_json_array );
$team->update;
$self->on_team_moving($team);
}
## OVERRIDE (Always use $self->SUPER::on_team_moving.)
sub on_team_moving ( $self, $team ) {
$team = $team->get_from_storage;
for my $pj ( $team->members ) {
$self->on_pj_moving($pj);
}
}
sub on_pj_moving ( $self, $pj ) {
require LasTres::Redis;
my $redis = LasTres::Redis->new;
$pj = $pj->get_from_storage;
$pj->append_log_line(
[
{ text => 'Tu equipo se está moviendo a ' },
{ color => 'red', text => $self->parent->name },
{ text => '/' },
{ color => 'green', text => $self->name },
]
);
$redis->publish( $redis->pj_subscription($pj),
to_json( { command => 'update-location' } ) );
}
sub place_team ( $self, $team ) {
$team = $team->get_from_storage;
$team->location($self); $team->location($self);
$team->update; $team->update;
$self->on_team_arrival($team); $self->on_team_arrival($team);
@ -88,7 +136,7 @@ sub to_array ($self) {
} }
sub to_json_array ($self) { sub to_json_array ($self) {
return to_json($self->to_array); return to_json( $self->to_array );
} }
sub is_connected_by_move ( $self, $otherLocation, $pj = undef ) { sub is_connected_by_move ( $self, $otherLocation, $pj = undef ) {
@ -105,26 +153,40 @@ sub is_connected_by_move ( $self, $otherLocation, $pj = undef ) {
} }
sub get_available_locations_to_move_to ( $self, $pj = undef ) { sub get_available_locations_to_move_to ( $self, $pj = undef ) {
if ( defined $pj ) {
$pj = $pj->get_from_storage;
}
my $location = $self; my $location = $self;
my $connected_places = []; my $connected_places = [];
if ( $location->can('connected_places') ) { if ( !$self->pj_is_moving($pj) && $location->can('connected_places') ) {
@$connected_places = ( @{ $self->connected_places } ); @$connected_places = ( @{ $self->connected_places } );
} }
@$connected_places = (
@$connected_places, @{ $self->_get_neighbour_locations_accesible($pj) }
);
@$connected_places = @$connected_places =
( @$connected_places, @{$self->_get_neighbour_locations_accesible($pj)} ); grep { $_->to_json_array ne $location->to_json_array }
@$connected_places = grep { $_->to_json_array; $_->to_json_array ne to_json(from_json($pj->team->moving_to)) }
grep { $_->identifier ne $location->identifier } @$connected_places; @$connected_places;
if (defined $pj) { if ( defined $pj ) {
@$connected_places = grep { $_->can_visit($pj) } @$connected_places; @$connected_places = grep { $_->can_visit($pj) } @$connected_places;
} }
return $connected_places; return $connected_places;
} }
sub _get_neighbour_locations_accesible($self, $pj) { sub pj_is_moving ( $self, $pj = undef ) {
if ( defined $pj ) {
$pj = $pj->get_from_storage;
}
return defined $pj && $pj->team->is_moving;
}
sub _get_neighbour_locations_accesible ( $self, $pj ) {
my $places = []; my $places = [];
@$places = @{ $self->parent->children }; @$places = @{ $self->parent->children };
if (!$self->parent->get_auto_discover && defined $pj) { if ( !$self->parent->get_auto_discover && defined $pj ) {
@$places = grep { $pj->knows_location($_) } @$places;
@$places = grep { $pj->knows_location($_) } @$places; @$places = grep { $pj->knows_location($_) } @$places;
} }
return $places; return $places;
@ -180,8 +242,9 @@ sub hash ($self) {
identifier => $super_area->identifier, identifier => $super_area->identifier,
}, },
area => { area => {
name => $area->name, name => $area->name,
identifier => $area->identifier, identifier => $area->identifier,
can_explore => ( $area->can_explore ? $JSON::true : $JSON::false ),
}, },
location => { location => {
name => $location->name, name => $location->name,

View File

@ -16,34 +16,25 @@ use Module::Pluggable search_path => ['LasTres::Planet::Bahdder::BosqueDelHeroe:
use Moo; use Moo;
use LasTres::Planet::Bahdder::BosqueDelHeroe; use LasTres::Planet::Bahdder::BosqueDelHeroe;
has locations => (
is => 'ro',
builder => \&_build_locations,
lazy => 1,
);
has identifier => (
is => 'ro',
builder => \&_build_identifier,
);
has name => (
is => 'ro',
builder => \&_build_name,
);
has parent => (
is => 'ro',
builder => \&_build_parent,
);
with 'LasTres::Area'; with 'LasTres::Area';
sub _build_identifier { sub can_explore {
return 0;
}
sub get_auto_discover($self) {
return 1;
}
sub frames_to_move {
return 1;
}
sub identifier {
return 'tribu_de_la_lima'; return 'tribu_de_la_lima';
} }
sub _build_locations { sub locations {
my $self = shift; my $self = shift;
my $hash = {}; my $hash = {};
my @locations = $self->plugins(); my @locations = $self->plugins();
@ -53,11 +44,11 @@ sub _build_locations {
return $hash; return $hash;
} }
sub _build_name { sub name {
return 'Tribu de la Lima'; return 'Tribu de la Lima';
} }
sub _build_parent { sub parent {
return LasTres::Planet::Bahdder::BosqueDelHeroe->instance; return LasTres::Planet::Bahdder::BosqueDelHeroe->instance;
} }

View File

@ -0,0 +1,54 @@
package LasTres::Planet::Bahdder::BosqueDelHeroe::TribuDeLaLima::ArbolCentral;
use v5.36.0;
use strict;
use warnings;
use feature 'signatures';
use utf8;
use Moo;
use LasTres::Planet::Bahdder::BosqueDelHeroe::TribuDeLaLima;
with 'LasTres::Location';
sub identifier {
return 'arbol_central';
}
sub name {
return 'Árbol central';
}
sub description {
return 'Desde este árbol se puede contemplar toda la Tribu de la Lima, sus casitas de paja y los cultivos de lima.';
}
sub parent {
return LasTres::Planet::Bahdder::BosqueDelHeroe::TribuDeLaLima->instance;
}
sub actions {
return [];
}
sub npcs {
return [];
}
sub connected_places {
return [];
}
my $singleton;
sub instance {
my $class = shift;
if (!defined $singleton) {
$singleton = $class->new(@_);
}
return $singleton;
}
1;

View File

@ -5,7 +5,7 @@ use v5.36.0;
use strict; use strict;
use warnings; use warnings;
our $VERSION = 7; our $VERSION = 9;
use feature 'signatures'; use feature 'signatures';

View File

@ -21,11 +21,21 @@ __PACKAGE__->add_columns(
is_nullable => 0, is_nullable => 0,
default_value => \'false', default_value => \'false',
}, },
explore_frame => { action_frame => {
data_type => 'integer', data_type => 'integer',
is_nullable => 0, is_nullable => 0,
default_value => \'0', default_value => \'0',
}, },
is_moving => {
data_type => 'boolean',
is_nullable => 0,
default_value => \'false',
},
moving_to => {
data_type => 'jsonb',
is_nullable => 0,
default_value => \'\'null\'',
},
leader => { leader => {
data_type => 'uuid', data_type => 'uuid',
is_nullable => 1, is_nullable => 1,

File diff suppressed because one or more lines are too long