Importing SVN archives - Trunk
This commit is contained in:
parent
fc4c6bd340
commit
ff53af6668
507 changed files with 8866 additions and 2450 deletions
legacyworlds-server/legacyworlds-server-data
db-structure/parts
020-functions.sql
pom.xmldata
070-constants-data.sql080-techs-data.sql090-buildables-data.sql100-universe-data.sql110-empires-data.sql120-construction-data.sql130-fleets-data.sql170-events-data.sql
functions
010-constants-functions.sql030-tech-functions.sql040-empire-functions.sql045-research-functions.sql050-computation-functions.sql060-universe-functions.sql140-planets-functions.sql150-battle-functions.sql160-battle-views.sql165-fleets-functions.sql167-planet-list.sql170-event-functions.sql200-bugs-functions.sql
updates
src/main/java/com/deepclone/lw/sqld
|
@ -14,6 +14,7 @@
|
|||
\i parts/functions/030-tech-functions.sql
|
||||
\i parts/functions/035-users-view.sql
|
||||
\i parts/functions/040-empire-functions.sql
|
||||
\i parts/functions/045-research-functions.sql
|
||||
\i parts/functions/050-computation-functions.sql
|
||||
\i parts/functions/060-universe-functions.sql
|
||||
\i parts/functions/070-users-functions.sql
|
||||
|
|
|
@ -25,9 +25,9 @@ CREATE TABLE sys.constant_definitions(
|
|||
name VARCHAR(64) NOT NULL PRIMARY KEY,
|
||||
category_id INT NOT NULL ,
|
||||
description TEXT NOT NULL ,
|
||||
min_value REAL ,
|
||||
max_value REAL ,
|
||||
c_value REAL NOT NULL ,
|
||||
min_value DOUBLE PRECISION ,
|
||||
max_value DOUBLE PRECISION ,
|
||||
c_value DOUBLE PRECISION NOT NULL ,
|
||||
CHECK(
|
||||
( min_value IS NULL OR (
|
||||
min_value IS NOT NULL AND c_value >= min_value ) )
|
||||
|
|
|
@ -8,49 +8,65 @@
|
|||
|
||||
|
||||
--
|
||||
-- Technology lines
|
||||
-- Categories
|
||||
--
|
||||
|
||||
CREATE TABLE tech.lines(
|
||||
CREATE TABLE tech.categories(
|
||||
name_id INT NOT NULL PRIMARY KEY ,
|
||||
description_id INT NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX idx_lines_description
|
||||
ON tech.lines (description_id);
|
||||
CREATE INDEX idx_categories_description
|
||||
ON tech.categories (description_id);
|
||||
|
||||
ALTER TABLE tech.lines
|
||||
ADD CONSTRAINT fk_lines_name
|
||||
ALTER TABLE tech.categories
|
||||
ADD CONSTRAINT fk_categories_name
|
||||
FOREIGN KEY (name_id) REFERENCES defs.strings ,
|
||||
ADD CONSTRAINT fk_lines_description
|
||||
ADD CONSTRAINT fk_categories_description
|
||||
FOREIGN KEY (description_id) REFERENCES defs.strings;
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Technology levels
|
||||
-- Technologies
|
||||
--
|
||||
|
||||
CREATE TABLE tech.levels(
|
||||
id SERIAL NOT NULL PRIMARY KEY ,
|
||||
line_id INT NOT NULL ,
|
||||
level INT NOT NULL CHECK( level > 0 ) ,
|
||||
name_id INT NOT NULL ,
|
||||
CREATE TABLE tech.technologies(
|
||||
name_id INT NOT NULL PRIMARY KEY ,
|
||||
description_id INT NOT NULL ,
|
||||
category_id INT NOT NULL ,
|
||||
points INT NOT NULL CHECK( points > 0 ) ,
|
||||
cost INT NOT NULL CHECK( cost > 0 )
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX idx_levels_linelevel
|
||||
ON tech.levels (line_id, level);
|
||||
CREATE INDEX idx_levels_name
|
||||
ON tech.levels (name_id);
|
||||
CREATE INDEX idx_levels_description
|
||||
ON tech.levels (description_id);
|
||||
CREATE INDEX idx_technologies_description
|
||||
ON tech.technologies (description_id);
|
||||
CREATE INDEX idx_technologies_category
|
||||
ON tech.technologies (category_id);
|
||||
|
||||
ALTER TABLE tech.levels
|
||||
ADD CONSTRAINT fk_levels_line
|
||||
FOREIGN KEY (line_id) REFERENCES tech.lines ,
|
||||
ADD CONSTRAINT fk_levels_name
|
||||
ALTER TABLE tech.technologies
|
||||
ADD CONSTRAINT fk_technologies_category
|
||||
FOREIGN KEY (category_id) REFERENCES tech.categories ,
|
||||
ADD CONSTRAINT fk_technologies_name
|
||||
FOREIGN KEY (name_id) REFERENCES defs.strings ,
|
||||
ADD CONSTRAINT fk_levels_description
|
||||
ADD CONSTRAINT fk_technologies_description
|
||||
FOREIGN KEY (description_id) REFERENCES defs.strings;
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Dependencies
|
||||
--
|
||||
|
||||
CREATE TABLE tech.dependencies(
|
||||
technology_id INT NOT NULL ,
|
||||
depends_on INT NOT NULL ,
|
||||
PRIMARY KEY( technology_id , depends_on )
|
||||
);
|
||||
|
||||
CREATE INDEX idx_dependencies_dependson
|
||||
ON tech.dependencies (depends_on);
|
||||
|
||||
ALTER TABLE tech.dependencies
|
||||
ADD CONSTRAINT fk_dependencies_technology
|
||||
FOREIGN KEY (technology_id) REFERENCES tech.technologies ,
|
||||
ADD CONSTRAINT fk_dependencies_dependson
|
||||
FOREIGN KEY (depends_on) REFERENCES tech.technologies;
|
||||
|
|
|
@ -32,18 +32,18 @@ ALTER TABLE tech.buildables
|
|||
--
|
||||
CREATE TABLE tech.buildable_requirements(
|
||||
buildable_id INT NOT NULL ,
|
||||
level_id INT NOT NULL ,
|
||||
PRIMARY KEY( buildable_id , level_id )
|
||||
technology_id INT NOT NULL ,
|
||||
PRIMARY KEY( buildable_id , technology_id )
|
||||
);
|
||||
|
||||
CREATE INDEX idx_buildablereqs_level
|
||||
ON tech.buildable_requirements( level_id );
|
||||
CREATE INDEX idx_buildablereqs_technology
|
||||
ON tech.buildable_requirements( technology_id );
|
||||
|
||||
ALTER TABLE tech.buildable_requirements
|
||||
ADD CONSTRAINT fk_buildablereqs_buildable
|
||||
FOREIGN KEY (buildable_id) REFERENCES tech.buildables ,
|
||||
ADD CONSTRAINT fk_buildablereqs_level
|
||||
FOREIGN KEY (level_id) REFERENCES tech.levels;
|
||||
ADD CONSTRAINT fk_buildablereqs_technology
|
||||
FOREIGN KEY (technology_id) REFERENCES tech.technologies;
|
||||
|
||||
|
||||
--
|
||||
|
|
|
@ -28,7 +28,7 @@ CREATE TABLE verse.planets(
|
|||
orbit INT NOT NULL
|
||||
CHECK( orbit BETWEEN 1 AND 5 ) ,
|
||||
picture INT NOT NULL ,
|
||||
population REAL NOT NULL
|
||||
population DOUBLE PRECISION NOT NULL
|
||||
CHECK( population >= 0 )
|
||||
);
|
||||
|
||||
|
@ -47,9 +47,9 @@ ALTER TABLE verse.planets
|
|||
--
|
||||
CREATE TABLE verse.planet_happiness(
|
||||
planet_id INT NOT NULL PRIMARY KEY ,
|
||||
target REAL NOT NULL
|
||||
target DOUBLE PRECISION NOT NULL
|
||||
CHECK( target BETWEEN 0.0 AND 1.0 ) ,
|
||||
current REAL NOT NULL
|
||||
current DOUBLE PRECISION NOT NULL
|
||||
CHECK( current > 0 )
|
||||
);
|
||||
|
||||
|
@ -63,9 +63,9 @@ ALTER TABLE verse.planet_happiness
|
|||
--
|
||||
CREATE TABLE verse.planet_money(
|
||||
planet_id INT NOT NULL PRIMARY KEY ,
|
||||
income REAL NOT NULL
|
||||
income DOUBLE PRECISION NOT NULL
|
||||
CHECK( income >= 0 ) ,
|
||||
upkeep REAL NOT NULL
|
||||
upkeep DOUBLE PRECISION NOT NULL
|
||||
CHECK( upkeep >= 0 )
|
||||
);
|
||||
|
||||
|
@ -81,7 +81,7 @@ CREATE TABLE verse.planet_buildings(
|
|||
planet_id INT NOT NULL ,
|
||||
building_id INT NOT NULL ,
|
||||
amount INT NOT NULL CHECK( amount >= 0 ) ,
|
||||
damage REAL NOT NULL CHECK( damage >= 0 ) ,
|
||||
damage DOUBLE PRECISION NOT NULL CHECK( damage >= 0 ) ,
|
||||
PRIMARY KEY( planet_id , building_id )
|
||||
);
|
||||
|
||||
|
|
|
@ -13,9 +13,9 @@
|
|||
|
||||
CREATE TABLE emp.empires(
|
||||
name_id INT NOT NULL PRIMARY KEY ,
|
||||
cash REAL NOT NULL
|
||||
cash DOUBLE PRECISION NOT NULL
|
||||
CHECK( cash >= 0 ),
|
||||
debt REAL NOT NULL DEFAULT 0
|
||||
debt DOUBLE PRECISION NOT NULL DEFAULT 0
|
||||
CHECK( debt >= 0)
|
||||
);
|
||||
|
||||
|
@ -25,28 +25,55 @@ ALTER TABLE emp.empires
|
|||
|
||||
|
||||
--
|
||||
-- Empire technologies
|
||||
-- Research in progress
|
||||
--
|
||||
|
||||
CREATE TABLE emp.technologies(
|
||||
CREATE TABLE emp.research(
|
||||
empire_id INT NOT NULL ,
|
||||
line_id INT NOT NULL ,
|
||||
level INT NOT NULL DEFAULT 1
|
||||
CHECK( level > 0 ) ,
|
||||
accumulated REAL NOT NULL DEFAULT 0
|
||||
CHECK( accumulated >= 0 ),
|
||||
PRIMARY KEY( empire_id , line_id )
|
||||
technology_id INT NOT NULL ,
|
||||
accumulated DOUBLE PRECISION NOT NULL DEFAULT 0
|
||||
CHECK( accumulated >= 0 ) ,
|
||||
priority INT NOT NULL
|
||||
CHECK( priority BETWEEN 0 AND 100 ) ,
|
||||
PRIMARY KEY( empire_id , technology_id )
|
||||
);
|
||||
|
||||
CREATE INDEX idx_technologies_line
|
||||
ON emp.technologies (line_id);
|
||||
CREATE INDEX idx_research_technology
|
||||
ON emp.research (technology_id);
|
||||
|
||||
ALTER TABLE emp.technologies
|
||||
ADD CONSTRAINT fk_technologies_empire
|
||||
ALTER TABLE emp.research
|
||||
ADD CONSTRAINT fk_research_empire
|
||||
FOREIGN KEY (empire_id) REFERENCES emp.empires
|
||||
ON DELETE CASCADE ,
|
||||
ADD CONSTRAINT fk_technologies_line
|
||||
FOREIGN KEY (line_id) REFERENCES tech.lines;
|
||||
ADD CONSTRAINT fk_research_technology
|
||||
FOREIGN KEY (technology_id) REFERENCES tech.technologies
|
||||
ON DELETE CASCADE;
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Researched technologies (both implemented and pending implementation)
|
||||
--
|
||||
|
||||
CREATE TABLE emp.researched_technologies(
|
||||
empire_id INT NOT NULL ,
|
||||
technology_id INT NOT NULL ,
|
||||
implemented BOOLEAN NOT NULL ,
|
||||
PRIMARY KEY ( empire_id , technology_id )
|
||||
);
|
||||
|
||||
CREATE INDEX idx_researched_technology
|
||||
ON emp.researched_technologies ( technology_id );
|
||||
CREATE INDEX idx_researched_implemented
|
||||
ON emp.researched_technologies ( empire_id , implemented );
|
||||
|
||||
ALTER TABLE emp.researched_technologies
|
||||
ADD CONSTRAINT fk_researched_empire
|
||||
FOREIGN KEY ( empire_id ) REFERENCES emp.empires
|
||||
ON DELETE CASCADE ,
|
||||
ADD CONSTRAINT fk_researched_technology
|
||||
FOREIGN KEY ( technology_id ) REFERENCES tech.technologies
|
||||
ON DELETE CASCADE;
|
||||
|
||||
|
||||
--
|
||||
|
|
|
@ -13,8 +13,8 @@
|
|||
|
||||
CREATE TABLE verse.bld_queues(
|
||||
planet_id INT NOT NULL PRIMARY KEY ,
|
||||
money REAL NOT NULL CHECK( money >= 0 ),
|
||||
work REAL NOT NULL CHECK( work >= 0 )
|
||||
money DOUBLE PRECISION NOT NULL CHECK( money >= 0 ),
|
||||
work DOUBLE PRECISION NOT NULL CHECK( work >= 0 )
|
||||
);
|
||||
|
||||
ALTER TABLE verse.bld_queues
|
||||
|
@ -51,8 +51,8 @@ ALTER TABLE verse.bld_items
|
|||
|
||||
CREATE TABLE verse.mil_queues(
|
||||
planet_id INT NOT NULL PRIMARY KEY ,
|
||||
money REAL NOT NULL CHECK( money >= 0 ),
|
||||
work REAL NOT NULL CHECK( work >= 0 )
|
||||
money DOUBLE PRECISION NOT NULL CHECK( money >= 0 ),
|
||||
work DOUBLE PRECISION NOT NULL CHECK( work >= 0 )
|
||||
);
|
||||
|
||||
ALTER TABLE verse.mil_queues
|
||||
|
|
|
@ -46,7 +46,7 @@ CREATE TABLE fleets.ships(
|
|||
fleet_id BIGINT NOT NULL ,
|
||||
ship_id INT NOT NULL ,
|
||||
amount INT NOT NULL CHECK( amount >= 0 ) ,
|
||||
damage REAL NOT NULL ,
|
||||
damage DOUBLE PRECISION NOT NULL ,
|
||||
PRIMARY KEY( fleet_id , ship_id )
|
||||
);
|
||||
|
||||
|
@ -89,8 +89,8 @@ ALTER TABLE fleets.movements
|
|||
|
||||
CREATE TABLE fleets.ms_space(
|
||||
movement_id BIGINT NOT NULL PRIMARY KEY ,
|
||||
start_x REAL NOT NULL ,
|
||||
start_y REAL NOT NULL
|
||||
start_x DOUBLE PRECISION NOT NULL ,
|
||||
start_y DOUBLE PRECISION NOT NULL
|
||||
);
|
||||
|
||||
ALTER TABLE fleets.ms_space
|
||||
|
|
|
@ -3,10 +3,163 @@
|
|||
--
|
||||
-- Storage of events (internal messages)
|
||||
--
|
||||
-- Copyright(C) 2004-2010, DeepClone Development
|
||||
-- Copyright(C) 2004-2011, DeepClone Development
|
||||
-- --------------------------------------------------------
|
||||
|
||||
|
||||
--
|
||||
-- Event type definitionss
|
||||
--
|
||||
|
||||
CREATE TABLE events.event_type_definitions(
|
||||
etd_type VARCHAR( 48 ) NOT NULL
|
||||
PRIMARY KEY ,
|
||||
etd_priority INT NOT NULL
|
||||
CHECK( etd_priority BETWEEN 1 AND 5 ) ,
|
||||
etd_user_priority BOOLEAN NOT NULL
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Types of field contents
|
||||
--
|
||||
-- INMB integer
|
||||
-- RNMB real number
|
||||
-- TEXT text
|
||||
-- BOOL boolean
|
||||
-- I18N internationalised string
|
||||
-- EREF game entity reference
|
||||
--
|
||||
|
||||
CREATE TYPE events.field_content_type
|
||||
AS ENUM ( 'INMB' , 'RNMB' , 'TEXT' , 'BOOL' , 'I18N' , 'EREF' );
|
||||
|
||||
|
||||
--
|
||||
-- Subtypes of reference field contents
|
||||
--
|
||||
-- EMP empire
|
||||
-- MAP map object
|
||||
-- FLT fleet
|
||||
-- BAT battle
|
||||
-- ADM administrator
|
||||
-- MSG message
|
||||
-- BUG bug report
|
||||
--
|
||||
|
||||
CREATE TYPE events.field_reference_type
|
||||
AS ENUM ( 'EMP' , 'MAP' , 'FLT' , 'BAT' , 'ADM' , 'MSG' , 'BUG' );
|
||||
|
||||
|
||||
--
|
||||
-- Event field definitions
|
||||
--
|
||||
|
||||
CREATE TABLE events.event_field_definitions(
|
||||
etd_type VARCHAR( 48 ) NOT NULL ,
|
||||
efd_field VARCHAR( 48 ) NOT NULL ,
|
||||
efd_required BOOLEAN NOT NULL ,
|
||||
efd_type events.field_content_type NOT NULL ,
|
||||
efd_reference_type events.field_reference_type ,
|
||||
efd_low_boundary DOUBLE PRECISION ,
|
||||
efd_high_boundary DOUBLE PRECISION ,
|
||||
|
||||
PRIMARY KEY ( etd_type , efd_field ) ,
|
||||
|
||||
CHECK( efd_type = 'EREF' AND efd_reference_type IS NOT NULL
|
||||
OR efd_type <> 'EREF' AND efd_reference_type IS NULL ) ,
|
||||
|
||||
CHECK ( efd_type IN ( 'INMB' , 'RNMB' , 'TEXT' )
|
||||
OR efd_type NOT IN ( 'INMB' , 'RNMB' , 'TEXT' )
|
||||
AND efd_low_boundary IS NULL
|
||||
AND efd_high_boundary IS NULL ) ,
|
||||
|
||||
CHECK ( efd_low_boundary IS NULL OR efd_high_boundary IS NULL
|
||||
OR efd_low_boundary < efd_high_boundary )
|
||||
);
|
||||
|
||||
ALTER TABLE events.event_field_definitions
|
||||
ADD CONSTRAINT fk_efd_type
|
||||
FOREIGN KEY ( etd_type ) REFERENCES events.event_type_definitions;
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Event format definitions
|
||||
--
|
||||
|
||||
CREATE TABLE events.event_format_definitions(
|
||||
etd_type VARCHAR( 48 ) NOT NULL ,
|
||||
efmd_order INT NOT NULL ,
|
||||
efmd_template INT NOT NULL ,
|
||||
|
||||
PRIMARY KEY ( etd_type , efmd_order )
|
||||
);
|
||||
|
||||
CREATE INDEX idx_efmd_template
|
||||
ON events.event_format_definitions ( efmd_template );
|
||||
|
||||
ALTER TABLE events.event_format_definitions
|
||||
ADD CONSTRAINT fk_efmd_type
|
||||
FOREIGN KEY ( etd_type ) REFERENCES events.event_type_definitions ,
|
||||
ADD CONSTRAINT fk_efmd_template
|
||||
FOREIGN KEY ( efmd_template ) REFERENCES defs.strings;
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Types of format conditions
|
||||
--
|
||||
-- EX has value all
|
||||
-- EQ is equal to ... all except EREF
|
||||
-- NE is not equal to ... all except EREF
|
||||
-- GT > ... INMB , RNMB
|
||||
-- length > ... TEXT
|
||||
-- LT < ... INMB , RNMB
|
||||
-- shorter than ... TEXT
|
||||
-- GE >= ... INMB , RNMB
|
||||
-- length >= ... TEXT
|
||||
-- LE <= ... INMB , RNMB
|
||||
-- length <= ... TEXT
|
||||
-- AV available EREF
|
||||
--
|
||||
|
||||
CREATE TYPE events.format_condition_type
|
||||
AS ENUM ( 'EX' , 'EQ' , 'NE' , 'GT' , 'LT' , 'GE' , 'LE' , 'AV' );
|
||||
|
||||
|
||||
--
|
||||
-- Conditions on format definitions
|
||||
--
|
||||
|
||||
CREATE TABLE events.efmt_conditions(
|
||||
etd_type VARCHAR( 48 ) NOT NULL ,
|
||||
efmd_order INT NOT NULL ,
|
||||
efd_field VARCHAR( 48 ) NOT NULL ,
|
||||
efc_type events.format_condition_type NOT NULL ,
|
||||
efc_boolean BOOLEAN ,
|
||||
efc_numeric DOUBLE PRECISION ,
|
||||
efc_string TEXT ,
|
||||
|
||||
PRIMARY KEY( etd_type , efmd_order , efd_field , efc_type )
|
||||
);
|
||||
|
||||
CREATE INDEX idx_efmtc_field
|
||||
ON events.efmt_conditions ( etd_type , efd_field );
|
||||
|
||||
ALTER TABLE events.efmt_conditions
|
||||
ADD CONSTRAINT fk_efmtc_format
|
||||
FOREIGN KEY ( etd_type , efmd_order ) REFERENCES events.event_format_definitions ,
|
||||
ADD CONSTRAINT fk_efmtc_field
|
||||
FOREIGN KEY ( etd_type , efd_field ) REFERENCES events.event_field_definitions;
|
||||
|
||||
|
||||
|
||||
|
||||
-- --------------------------------------------------------
|
||||
-- OLD CODE BELOW
|
||||
--
|
||||
|
||||
CREATE TYPE event_type
|
||||
AS ENUM ( 'QUEUE' , 'EMPIRE' , 'FLEETS' , 'PLANET', 'ALLIANCE', 'ADMIN' , 'BUGS' );
|
||||
|
||||
|
@ -101,7 +254,7 @@ ALTER TABLE events.empire_events
|
|||
FOREIGN KEY (event_id) REFERENCES events.events
|
||||
ON DELETE CASCADE,
|
||||
ADD CONSTRAINT fk_empevents_tech
|
||||
FOREIGN KEY (technology_id) REFERENCES tech.levels;
|
||||
FOREIGN KEY (technology_id) REFERENCES tech.technologies;
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -57,8 +57,8 @@ $$ LANGUAGE plpgsql;
|
|||
-- the constant's actual value
|
||||
--
|
||||
|
||||
CREATE OR REPLACE FUNCTION sys.uoc_constant( cnm TEXT , cdesc TEXT , ccnm TEXT , dval REAL )
|
||||
RETURNS REAL
|
||||
CREATE OR REPLACE FUNCTION sys.uoc_constant( cnm TEXT , cdesc TEXT , ccnm TEXT , dval DOUBLE PRECISION )
|
||||
RETURNS DOUBLE PRECISION
|
||||
STRICT
|
||||
VOLATILE
|
||||
SECURITY DEFINER
|
||||
|
@ -66,7 +66,7 @@ CREATE OR REPLACE FUNCTION sys.uoc_constant( cnm TEXT , cdesc TEXT , ccnm TEXT ,
|
|||
DECLARE
|
||||
ccid INT;
|
||||
occid INT;
|
||||
cval REAL;
|
||||
cval DOUBLE PRECISION;
|
||||
BEGIN
|
||||
ccid := sys.cog_constant_category( ccnm );
|
||||
|
||||
|
@ -97,7 +97,7 @@ BEGIN
|
|||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
GRANT EXECUTE ON FUNCTION sys.uoc_constant( TEXT , TEXT , TEXT , REAL ) TO :dbuser;
|
||||
GRANT EXECUTE ON FUNCTION sys.uoc_constant( TEXT , TEXT , TEXT , DOUBLE PRECISION ) TO :dbuser;
|
||||
|
||||
|
||||
|
||||
|
@ -116,8 +116,8 @@ GRANT EXECUTE ON FUNCTION sys.uoc_constant( TEXT , TEXT , TEXT , REAL ) TO :dbus
|
|||
-- the constant's actual value
|
||||
--
|
||||
|
||||
CREATE OR REPLACE FUNCTION sys.uoc_constant( cnm TEXT , cdesc TEXT , ccnm TEXT , dval REAL , bval REAL , ismin BOOLEAN )
|
||||
RETURNS REAL
|
||||
CREATE OR REPLACE FUNCTION sys.uoc_constant( cnm TEXT , cdesc TEXT , ccnm TEXT , dval DOUBLE PRECISION , bval DOUBLE PRECISION , ismin BOOLEAN )
|
||||
RETURNS DOUBLE PRECISION
|
||||
STRICT
|
||||
VOLATILE
|
||||
SECURITY DEFINER
|
||||
|
@ -125,9 +125,9 @@ CREATE OR REPLACE FUNCTION sys.uoc_constant( cnm TEXT , cdesc TEXT , ccnm TEXT ,
|
|||
DECLARE
|
||||
ccid INT;
|
||||
occid INT;
|
||||
cval REAL;
|
||||
mival REAL;
|
||||
maval REAL;
|
||||
cval DOUBLE PRECISION;
|
||||
mival DOUBLE PRECISION;
|
||||
maval DOUBLE PRECISION;
|
||||
BEGIN
|
||||
IF ismin THEN
|
||||
mival := bval;
|
||||
|
@ -175,7 +175,7 @@ BEGIN
|
|||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
GRANT EXECUTE ON FUNCTION sys.uoc_constant( TEXT , TEXT , TEXT , REAL , REAL , BOOLEAN ) TO :dbuser;
|
||||
GRANT EXECUTE ON FUNCTION sys.uoc_constant( TEXT , TEXT , TEXT , DOUBLE PRECISION , DOUBLE PRECISION , BOOLEAN ) TO :dbuser;
|
||||
|
||||
|
||||
|
||||
|
@ -194,8 +194,8 @@ GRANT EXECUTE ON FUNCTION sys.uoc_constant( TEXT , TEXT , TEXT , REAL , REAL , B
|
|||
-- the constant's actual value
|
||||
--
|
||||
|
||||
CREATE OR REPLACE FUNCTION sys.uoc_constant( cnm TEXT , cdesc TEXT , ccnm TEXT , dval REAL , mival REAL , maval REAL )
|
||||
RETURNS REAL
|
||||
CREATE OR REPLACE FUNCTION sys.uoc_constant( cnm TEXT , cdesc TEXT , ccnm TEXT , dval DOUBLE PRECISION , mival DOUBLE PRECISION , maval DOUBLE PRECISION )
|
||||
RETURNS DOUBLE PRECISION
|
||||
STRICT
|
||||
VOLATILE
|
||||
SECURITY DEFINER
|
||||
|
@ -203,7 +203,7 @@ CREATE OR REPLACE FUNCTION sys.uoc_constant( cnm TEXT , cdesc TEXT , ccnm TEXT ,
|
|||
DECLARE
|
||||
ccid INT;
|
||||
occid INT;
|
||||
cval REAL;
|
||||
cval DOUBLE PRECISION;
|
||||
BEGIN
|
||||
ccid := sys.cog_constant_category( ccnm );
|
||||
|
||||
|
@ -243,7 +243,7 @@ BEGIN
|
|||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
GRANT EXECUTE ON FUNCTION sys.uoc_constant( TEXT , TEXT , TEXT , REAL , REAL , REAL ) TO :dbuser;
|
||||
GRANT EXECUTE ON FUNCTION sys.uoc_constant( TEXT , TEXT , TEXT , DOUBLE PRECISION , DOUBLE PRECISION , DOUBLE PRECISION ) TO :dbuser;
|
||||
|
||||
|
||||
|
||||
|
@ -259,7 +259,7 @@ GRANT EXECUTE ON FUNCTION sys.uoc_constant( TEXT , TEXT , TEXT , REAL , REAL , R
|
|||
-- TRUE on success, FALSE on failure
|
||||
--
|
||||
|
||||
CREATE OR REPLACE FUNCTION sys.set_constant( cnm TEXT , nval REAL , aid INT )
|
||||
CREATE OR REPLACE FUNCTION sys.set_constant( cnm TEXT , nval DOUBLE PRECISION , aid INT )
|
||||
RETURNS BOOLEAN
|
||||
STRICT
|
||||
VOLATILE
|
||||
|
@ -282,7 +282,7 @@ BEGIN
|
|||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
GRANT EXECUTE ON FUNCTION sys.set_constant( TEXT , REAL , INT ) TO :dbuser;
|
||||
GRANT EXECUTE ON FUNCTION sys.set_constant( TEXT , DOUBLE PRECISION , INT ) TO :dbuser;
|
||||
|
||||
|
||||
|
||||
|
@ -294,7 +294,7 @@ GRANT EXECUTE ON FUNCTION sys.set_constant( TEXT , REAL , INT ) TO :dbuser;
|
|||
--
|
||||
|
||||
CREATE OR REPLACE FUNCTION sys.get_constant( cnm TEXT )
|
||||
RETURNS REAL
|
||||
RETURNS DOUBLE PRECISION
|
||||
STRICT STABLE
|
||||
SECURITY DEFINER
|
||||
AS $$
|
||||
|
|
|
@ -40,94 +40,226 @@ CREATE VIEW tech.ships_view
|
|||
FROM tech.buildables b
|
||||
INNER JOIN tech.ships s
|
||||
ON b.name_id = s.buildable_id;
|
||||
|
||||
|
||||
--
|
||||
-- Categories view
|
||||
--
|
||||
|
||||
CREATE VIEW tech.categories_view
|
||||
AS SELECT ns.name AS name , ds.name AS description
|
||||
FROM tech.categories c
|
||||
INNER JOIN defs.strings ns
|
||||
ON ns.id = c.name_id
|
||||
INNER JOIN defs.strings ds
|
||||
ON ds.id = c.description_id;
|
||||
|
||||
GRANT SELECT ON tech.categories_view TO :dbuser;
|
||||
|
||||
|
||||
--
|
||||
-- Technologies view
|
||||
--
|
||||
|
||||
CREATE VIEW tech.technologies_view
|
||||
AS SELECT cs.name AS category , ns.name AS name ,
|
||||
ds.name AS description , t.points , t.cost
|
||||
FROM tech.technologies t
|
||||
INNER JOIN defs.strings cs
|
||||
ON cs.id = t.category_id
|
||||
INNER JOIN defs.strings ns
|
||||
ON ns.id = t.name_id
|
||||
INNER JOIN defs.strings ds
|
||||
ON ds.id = t.description_id;
|
||||
|
||||
GRANT SELECT ON tech.technologies_view TO :dbuser;
|
||||
|
||||
|
||||
--
|
||||
-- Dependencies view
|
||||
--
|
||||
|
||||
CREATE VIEW tech.dependencies_view
|
||||
AS SELECT ts.name AS technology , ds.name AS dependency
|
||||
FROM tech.dependencies d
|
||||
INNER JOIN defs.strings ts
|
||||
ON ts.id = d.technology_id
|
||||
INNER JOIN defs.strings ds
|
||||
ON ds.id = d.depends_on;
|
||||
|
||||
GRANT SELECT ON tech.dependencies_view TO :dbuser;
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Creates or updates a technology line
|
||||
-- Creates or updates a technology category
|
||||
--
|
||||
-- Parameters:
|
||||
-- tln Tech line name
|
||||
-- tld Tech line description
|
||||
-- cat_name String identifier of the category's name
|
||||
-- cat_desc String identifier of the category's description
|
||||
--
|
||||
-- Returns:
|
||||
-- 0 No error
|
||||
-- 1 Name string not found
|
||||
-- 2 Description string not found
|
||||
--
|
||||
|
||||
CREATE OR REPLACE FUNCTION tech.uoc_line( tln TEXT , tld TEXT )
|
||||
RETURNS VOID
|
||||
STRICT
|
||||
VOLATILE
|
||||
CREATE OR REPLACE FUNCTION tech.uoc_category( cat_name TEXT , cat_desc TEXT )
|
||||
RETURNS INT
|
||||
STRICT VOLATILE
|
||||
SECURITY DEFINER
|
||||
AS $$
|
||||
DECLARE
|
||||
nid INT;
|
||||
did INT;
|
||||
cn_id INT;
|
||||
cd_id INT;
|
||||
BEGIN
|
||||
-- Get string identifiers
|
||||
SELECT INTO nid id FROM defs.strings WHERE name = tln;
|
||||
SELECT INTO did id FROM defs.strings WHERE name = tld;
|
||||
|
||||
-- Try creating / updating
|
||||
-- Get name / description identifiers
|
||||
SELECT INTO cn_id id FROM defs.strings WHERE name = cat_name;
|
||||
IF NOT FOUND THEN
|
||||
RETURN 1;
|
||||
END IF;
|
||||
SELECT INTO cd_id id FROM defs.strings WHERE name = cat_desc;
|
||||
IF NOT FOUND THEN
|
||||
RETURN 2;
|
||||
END IF;
|
||||
|
||||
-- Create or update the category
|
||||
BEGIN
|
||||
INSERT INTO tech.lines ( name_id , description_id )
|
||||
VALUES ( nid , did );
|
||||
INSERT INTO tech.categories ( name_id , description_id )
|
||||
VALUES ( cn_id , cd_id );
|
||||
EXCEPTION
|
||||
WHEN unique_violation THEN
|
||||
UPDATE tech.lines SET description_id = did
|
||||
WHERE name_id = nid;
|
||||
UPDATE tech.categories SET description_id = cd_id
|
||||
WHERE name_id = cn_id;
|
||||
END;
|
||||
RETURN 0;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
GRANT EXECUTE ON FUNCTION tech.uoc_line( TEXT , TEXT ) TO :dbuser;
|
||||
|
||||
GRANT EXECUTE ON FUNCTION tech.uoc_category( TEXT , TEXT ) to :dbuser;
|
||||
|
||||
|
||||
--
|
||||
-- Creates or updates a technology level
|
||||
-- Creates or updates a technology. If there are dependencies, clear them.
|
||||
--
|
||||
-- Parameters:
|
||||
-- tln Tech line name
|
||||
-- lv Level
|
||||
-- lvn Level name
|
||||
-- lvd Level description
|
||||
-- lvp Points
|
||||
-- lvc Cost
|
||||
-- nt_name Name string identifier
|
||||
-- nt_category Category string identifier
|
||||
-- nt_desc Description string identifier
|
||||
-- nt_points Research points for the technology
|
||||
-- nt_cost Cost of the technology
|
||||
--
|
||||
-- Returns:
|
||||
-- 0 No error
|
||||
-- 1 Name string not found
|
||||
-- 2 Category not found
|
||||
-- 3 Description string not found
|
||||
-- 4 Invalid parameters (points or cost)
|
||||
--
|
||||
|
||||
CREATE OR REPLACE FUNCTION tech.uoc_level( tln TEXT , lv INT , lvn TEXT , lvd TEXT , lvp INT , lvc INT )
|
||||
RETURNS VOID
|
||||
STRICT
|
||||
VOLATILE
|
||||
CREATE OR REPLACE FUNCTION tech.uoc_technology( nt_name TEXT , nt_category TEXT , nt_desc TEXT ,
|
||||
nt_points INT , nt_cost INT )
|
||||
RETURNS INT
|
||||
STRICT VOLATILE
|
||||
SECURITY DEFINER
|
||||
AS $$
|
||||
DECLARE
|
||||
lid INT;
|
||||
nid INT;
|
||||
did INT;
|
||||
n_id INT;
|
||||
c_id INT;
|
||||
d_id INT;
|
||||
BEGIN
|
||||
-- Get tech line
|
||||
SELECT INTO lid t.name_id
|
||||
FROM tech.lines t
|
||||
INNER JOIN defs.strings s
|
||||
ON s.id = t.name_id
|
||||
WHERE s.name = tln;
|
||||
-- Get name, category and description identifiers
|
||||
SELECT INTO n_id id FROM defs.strings WHERE name = nt_name;
|
||||
IF NOT FOUND THEN
|
||||
RETURN 1;
|
||||
END IF;
|
||||
SELECT INTO c_id c.name_id FROM tech.categories c
|
||||
INNER JOIN defs.strings s
|
||||
ON s.id = c.name_id AND s.name = nt_category;
|
||||
IF NOT FOUND THEN
|
||||
RETURN 2;
|
||||
END IF;
|
||||
SELECT INTO d_id id FROM defs.strings WHERE name = nt_desc;
|
||||
IF NOT FOUND THEN
|
||||
RETURN 3;
|
||||
END IF;
|
||||
|
||||
-- Get name / description IDs
|
||||
SELECT INTO nid id FROM defs.strings WHERE name = lvn;
|
||||
SELECT INTO did id FROM defs.strings WHERE name = lvd;
|
||||
|
||||
-- Create or update the level
|
||||
-- Create or update the technology
|
||||
BEGIN
|
||||
INSERT INTO tech.levels ( line_id , level , name_id , description_id , points , cost )
|
||||
VALUES ( lid , lv , nid , did , lvp , lvc );
|
||||
BEGIN
|
||||
INSERT INTO tech.technologies ( name_id , category_id , description_id , points , cost )
|
||||
VALUES ( n_id , c_id , d_id , nt_points , nt_cost );
|
||||
EXCEPTION
|
||||
WHEN unique_violation THEN
|
||||
UPDATE tech.technologies
|
||||
SET category_id = c_id , description_id = cd_id ,
|
||||
points = nt_points , cost = nt_cost
|
||||
WHERE name_id = n_id;
|
||||
DELETE FROM tech.dependencies
|
||||
WHERE technology_id = n_id;
|
||||
END;
|
||||
EXCEPTION
|
||||
WHEN check_violation THEN
|
||||
RETURN 4;
|
||||
END;
|
||||
RETURN 0;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
GRANT EXECUTE ON FUNCTION tech.uoc_technology( TEXT , TEXT , TEXT , INT , INT ) to :dbuser;
|
||||
|
||||
|
||||
--
|
||||
-- Adds a technology dependency
|
||||
--
|
||||
-- Parameters:
|
||||
-- nd_name Name of the dependent technology
|
||||
-- nd_dep Name of the dependency
|
||||
--
|
||||
-- Returns:
|
||||
-- 0 No error
|
||||
-- 1 Technology not found
|
||||
-- 2 Dependency not found
|
||||
-- 3 Duplicate dependency
|
||||
--
|
||||
CREATE OR REPLACE FUNCTION tech.add_dependency( nd_name TEXT , nd_dep TEXT )
|
||||
RETURNS INT
|
||||
STRICT VOLATILE
|
||||
SECURITY DEFINER
|
||||
AS $$
|
||||
DECLARE
|
||||
t_id INT;
|
||||
d_id INT;
|
||||
BEGIN
|
||||
-- Get technology
|
||||
SELECT INTO t_id t.name_id FROM tech.technologies t
|
||||
INNER JOIN defs.strings s
|
||||
ON s.id = t.name_id AND s.name = nd_name;
|
||||
IF NOT FOUND THEN
|
||||
RETURN 1;
|
||||
END IF;
|
||||
|
||||
-- Get dependency
|
||||
SELECT INTO d_id t.name_id FROM tech.technologies t
|
||||
INNER JOIN defs.strings s
|
||||
ON s.id = t.name_id AND s.name = nd_dep;
|
||||
IF NOT FOUND THEN
|
||||
RETURN 2;
|
||||
END IF;
|
||||
|
||||
-- Add dependency
|
||||
BEGIN
|
||||
INSERT INTO tech.dependencies ( technology_id , depends_on )
|
||||
VALUES ( t_id , d_id );
|
||||
EXCEPTION
|
||||
WHEN unique_violation THEN
|
||||
UPDATE tech.levels SET name_id = nid , description_id = did , points = lvp , cost = lvc
|
||||
WHERE line_id = lid AND level = lv;
|
||||
RETURN 3;
|
||||
END;
|
||||
RETURN 0;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
GRANT EXECUTE ON FUNCTION tech.uoc_level( TEXT , INT , TEXT , TEXT , INT , INT ) to :dbuser;
|
||||
GRANT EXECUTE ON FUNCTION tech.add_dependency( TEXT, TEXT ) TO :dbuser;
|
||||
|
||||
|
||||
|
||||
|
@ -140,14 +272,13 @@ GRANT EXECUTE ON FUNCTION tech.uoc_level( TEXT , INT , TEXT , TEXT , INT , INT )
|
|||
-- bdc Cost
|
||||
-- bdw Work
|
||||
-- bdu Upkeep
|
||||
-- bdtn Dependency (name)
|
||||
-- bdtl Dependency (level)
|
||||
-- bdtn Dependency
|
||||
--
|
||||
-- Returns:
|
||||
-- the buildable's identifier
|
||||
--
|
||||
|
||||
CREATE OR REPLACE FUNCTION tech.uoc_buildable( bdn TEXT , bdd TEXT , bdc INT , bdw INT , bdu INT , bdtn TEXT , bdtl INT )
|
||||
CREATE OR REPLACE FUNCTION tech.uoc_buildable( bdn TEXT , bdd TEXT , bdc INT , bdw INT , bdu INT , bdtn TEXT )
|
||||
RETURNS INT
|
||||
STRICT
|
||||
VOLATILE
|
||||
|
@ -162,10 +293,10 @@ BEGIN
|
|||
SELECT INTO nid id FROM defs.strings WHERE name = bdn;
|
||||
SELECT INTO did id FROM defs.strings WHERE name = bdd;
|
||||
IF bdtn <> '' THEN
|
||||
SELECT INTO tdid tl.id FROM tech.levels tl
|
||||
SELECT INTO tdid tl.name_id FROM tech.technologies tl
|
||||
INNER JOIN defs.strings s
|
||||
ON s.id = tl.line_id
|
||||
WHERE s.name = bdtn AND tl.level = bdtl;
|
||||
ON s.id = tl.name_id
|
||||
WHERE s.name = bdtn;
|
||||
END IF;
|
||||
|
||||
-- Create or update the definition
|
||||
|
@ -181,7 +312,7 @@ BEGIN
|
|||
-- Set dependencies
|
||||
DELETE FROM tech.buildable_requirements WHERE buildable_id = nid;
|
||||
IF bdtn <> '' THEN
|
||||
INSERT INTO tech.buildable_requirements ( buildable_id , level_id )
|
||||
INSERT INTO tech.buildable_requirements ( buildable_id , technology_id )
|
||||
VALUES ( nid , tdid );
|
||||
END IF;
|
||||
|
||||
|
@ -215,7 +346,7 @@ CREATE OR REPLACE FUNCTION tech.uoc_building( bdn TEXT , bdd TEXT , bdc INT , bd
|
|||
DECLARE
|
||||
bdid INT;
|
||||
BEGIN
|
||||
bdid := tech.uoc_buildable( bdn , bdd , bdc , bdw , bdu , '' , 0 );
|
||||
bdid := tech.uoc_buildable( bdn , bdd , bdc , bdw , bdu , '' );
|
||||
|
||||
PERFORM buildable_id FROM tech.ships WHERE buildable_id = bdid;
|
||||
IF FOUND THEN
|
||||
|
@ -249,22 +380,20 @@ GRANT EXECUTE ON FUNCTION tech.uoc_building( TEXT , TEXT , INT , INT , INT , INT
|
|||
-- bdwk Workers
|
||||
-- bdot Output type
|
||||
-- bdo Output
|
||||
-- bdtn Dependency (name)
|
||||
-- bdtl Dependency (level)
|
||||
-- bdtn Dependency
|
||||
--
|
||||
|
||||
CREATE OR REPLACE FUNCTION tech.uoc_building( bdn TEXT , bdd TEXT , bdc INT , bdw INT ,
|
||||
bdu INT , bdwk INT , bdot building_output_type , bdo INT ,
|
||||
bdtn TEXT , bdtl INT )
|
||||
bdtn TEXT )
|
||||
RETURNS VOID
|
||||
STRICT
|
||||
VOLATILE
|
||||
STRICT VOLATILE
|
||||
SECURITY DEFINER
|
||||
AS $$
|
||||
DECLARE
|
||||
bdid INT;
|
||||
BEGIN
|
||||
bdid := tech.uoc_buildable( bdn , bdd , bdc , bdw , bdu , bdtn , bdtl );
|
||||
bdid := tech.uoc_buildable( bdn , bdd , bdc , bdw , bdu , bdtn );
|
||||
|
||||
PERFORM buildable_id FROM tech.ships WHERE buildable_id = bdid;
|
||||
IF FOUND THEN
|
||||
|
@ -282,7 +411,7 @@ BEGIN
|
|||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
GRANT EXECUTE ON FUNCTION tech.uoc_building( TEXT , TEXT , INT , INT , INT , INT , building_output_type , INT , TEXT , INT ) TO :dbuser;
|
||||
GRANT EXECUTE ON FUNCTION tech.uoc_building( TEXT , TEXT , INT , INT , INT , INT , building_output_type , INT , TEXT ) TO :dbuser;
|
||||
|
||||
|
||||
|
||||
|
@ -309,7 +438,7 @@ CREATE OR REPLACE FUNCTION tech.uoc_ship( sn TEXT , sd TEXT , sc INT , sw INT ,
|
|||
DECLARE
|
||||
bdid INT;
|
||||
BEGIN
|
||||
bdid := tech.uoc_buildable( sn , sd , sc , sw , su , '' , 0 );
|
||||
bdid := tech.uoc_buildable( sn , sd , sc , sw , su , '' );
|
||||
|
||||
PERFORM buildable_id FROM tech.buildings WHERE buildable_id = bdid;
|
||||
IF FOUND THEN
|
||||
|
@ -342,12 +471,11 @@ GRANT EXECUTE ON FUNCTION tech.uoc_ship( TEXT , TEXT , INT , INT , INT , INT , I
|
|||
-- su Upkeep
|
||||
-- sp Power
|
||||
-- sft Orbital flight time
|
||||
-- stdn Tech line name
|
||||
-- stdl Tech level
|
||||
-- stdn Tech name
|
||||
--
|
||||
|
||||
CREATE OR REPLACE FUNCTION tech.uoc_ship( sn TEXT , sd TEXT , sc INT , sw INT ,
|
||||
su INT , sp INT , sft INT , stdn TEXT , stdl INT )
|
||||
su INT , sp INT , sft INT , stdn TEXT )
|
||||
RETURNS VOID
|
||||
STRICT
|
||||
VOLATILE
|
||||
|
@ -356,7 +484,7 @@ CREATE OR REPLACE FUNCTION tech.uoc_ship( sn TEXT , sd TEXT , sc INT , sw INT ,
|
|||
DECLARE
|
||||
bdid INT;
|
||||
BEGIN
|
||||
bdid := tech.uoc_buildable( sn , sd , sc , sw , su , stdn , stdl );
|
||||
bdid := tech.uoc_buildable( sn , sd , sc , sw , su , stdn );
|
||||
|
||||
PERFORM buildable_id FROM tech.buildings WHERE buildable_id = bdid;
|
||||
IF FOUND THEN
|
||||
|
@ -374,6 +502,6 @@ BEGIN
|
|||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
GRANT EXECUTE ON FUNCTION tech.uoc_ship( TEXT , TEXT , INT , INT , INT , INT , INT , TEXT , INT ) TO :dbuser;
|
||||
GRANT EXECUTE ON FUNCTION tech.uoc_ship( TEXT , TEXT , INT , INT , INT , INT , INT , TEXT ) TO :dbuser;
|
||||
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
--
|
||||
-- Empire management functions and views
|
||||
--
|
||||
-- Copyright(C) 2004-2010, DeepClone Development
|
||||
-- Copyright(C) 2004-2011, DeepClone Development
|
||||
-- --------------------------------------------------------
|
||||
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
|||
-- pid Planet identifier
|
||||
-- icash Initial cash
|
||||
--
|
||||
CREATE OR REPLACE FUNCTION emp.create_empire( nid INT , pid INT , icash REAL )
|
||||
CREATE OR REPLACE FUNCTION emp.create_empire( nid INT , pid INT , icash DOUBLE PRECISION )
|
||||
RETURNS VOID
|
||||
STRICT
|
||||
VOLATILE
|
||||
|
@ -81,49 +81,6 @@ $$ LANGUAGE SQL;
|
|||
GRANT EXECUTE ON FUNCTION emp.get_current( INT ) TO :dbuser;
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Implements a technology
|
||||
--
|
||||
|
||||
CREATE OR REPLACE FUNCTION emp.implement_tech( e_id INT , l_id INT )
|
||||
RETURNS VOID
|
||||
STRICT VOLATILE
|
||||
SECURITY DEFINER
|
||||
AS $$
|
||||
DECLARE
|
||||
e_cash REAL;
|
||||
lev INT;
|
||||
cost REAL;
|
||||
BEGIN
|
||||
SELECT INTO e_cash , lev , cost e.cash , et.level , tl.cost
|
||||
FROM emp.empires e
|
||||
INNER JOIN emp.technologies et
|
||||
ON et.line_id = l_id AND et.empire_id = e.name_id
|
||||
INNER JOIN tech.levels tl
|
||||
ON tl.line_id = l_id AND tl.level = et.level
|
||||
AND tl.points = floor( et.accumulated )
|
||||
AND tl.cost <= e.cash
|
||||
WHERE e.name_id = e_id
|
||||
FOR UPDATE OF e , et;
|
||||
|
||||
IF NOT FOUND THEN
|
||||
RETURN;
|
||||
END IF;
|
||||
|
||||
UPDATE emp.empires
|
||||
SET cash = e_cash - cost
|
||||
WHERE name_id = e_id;
|
||||
UPDATE emp.technologies
|
||||
SET level = lev + 1 , accumulated = 0
|
||||
WHERE empire_id = e_id AND line_id = l_id;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
GRANT EXECUTE ON FUNCTION emp.implement_tech( INT , INT ) TO :dbuser;
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Add an enemy empire
|
||||
--
|
||||
|
@ -413,7 +370,7 @@ CREATE OR REPLACE FUNCTION emp.get_new_planet( e_id INT , p_name TEXT , OUT err_
|
|||
DECLARE
|
||||
plid INT;
|
||||
accid INT;
|
||||
ccash REAL;
|
||||
ccash DOUBLE PRECISION;
|
||||
f_id BIGINT;
|
||||
fleets BIGINT[];
|
||||
BEGIN
|
||||
|
@ -484,7 +441,7 @@ CREATE VIEW emp.enemies
|
|||
--
|
||||
|
||||
CREATE VIEW emp.general_information
|
||||
AS SELECT e.name_id AS id , en.name AS name ,
|
||||
AS SELECT e.name_id AS id , en.name AS name , av.language ,
|
||||
( CASE
|
||||
WHEN av.status = 'QUITTING' THEN 'q'
|
||||
WHEN av.status = 'VACATION' THEN 'v'
|
||||
|
@ -600,50 +557,6 @@ CREATE VIEW emp.overview
|
|||
GRANT SELECT ON emp.overview TO :dbuser;
|
||||
|
||||
|
||||
--
|
||||
-- Empire tech lines
|
||||
--
|
||||
|
||||
CREATE VIEW emp.tech_lines_view
|
||||
AS SELECT e.name_id AS empire , tl.name_id AS tech_line ,
|
||||
t1.translated_string AS name ,
|
||||
t2.translated_string AS description
|
||||
FROM emp.empires e
|
||||
INNER JOIN emp.technologies et ON et.empire_id = e.name_id
|
||||
INNER JOIN tech.lines tl ON tl.name_id = et.line_id
|
||||
INNER JOIN naming.empire_names en ON en.id = e.name_id
|
||||
INNER JOIN users.credentials c ON c.address_id = en.owner_id
|
||||
INNER JOIN defs.translations t1 ON t1.string_id = tl.name_id AND t1.lang_id = c.language_id
|
||||
INNER JOIN defs.translations t2 ON t2.string_id = tl.description_id AND t2.lang_id = c.language_id
|
||||
ORDER BY t1.translated_string;
|
||||
|
||||
GRANT SELECT ON emp.tech_lines_view TO :dbuser;
|
||||
|
||||
|
||||
--
|
||||
-- Empire technologies
|
||||
--
|
||||
|
||||
CREATE VIEW emp.technologies_view
|
||||
AS SELECT e.name_id AS empire , tl.name_id AS tech_line ,
|
||||
t1.translated_string AS name ,
|
||||
t2.translated_string AS description ,
|
||||
( et.level > tlv.level ) AS implemented ,
|
||||
floor( 100 * et.accumulated / tlv.points ) AS progress ,
|
||||
tlv.cost AS cost
|
||||
FROM emp.empires e
|
||||
INNER JOIN emp.technologies et ON et.empire_id = e.name_id
|
||||
INNER JOIN tech.lines tl ON tl.name_id = et.line_id
|
||||
INNER JOIN tech.levels tlv ON tlv.line_id = tl.name_id AND tlv.level <= et.level
|
||||
INNER JOIN naming.empire_names en ON en.id = e.name_id
|
||||
INNER JOIN users.credentials c ON c.address_id = en.owner_id
|
||||
INNER JOIN defs.translations t1 ON t1.string_id = tlv.name_id AND t1.lang_id = c.language_id
|
||||
INNER JOIN defs.translations t2 ON t2.string_id = tlv.description_id AND t2.lang_id = c.language_id
|
||||
ORDER BY tl.name_id , tlv.level;
|
||||
|
||||
GRANT SELECT ON emp.technologies_view TO :dbuser;
|
||||
|
||||
|
||||
--
|
||||
-- Enemy lists
|
||||
--
|
||||
|
|
|
@ -0,0 +1,227 @@
|
|||
-- LegacyWorlds Beta 6
|
||||
-- PostgreSQL database scripts
|
||||
--
|
||||
-- Research mananagement functions and views
|
||||
--
|
||||
-- Copyright(C) 2004-2011, DeepClone Development
|
||||
-- --------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Implement a technology
|
||||
--
|
||||
-- Parameters:
|
||||
-- e_id Empire identifier
|
||||
-- t_name Technology name
|
||||
--
|
||||
-- Returns:
|
||||
-- 0 on success
|
||||
-- 1 if the empire does not posses the necessary resources
|
||||
-- 2 if the technology or empire were not found
|
||||
--
|
||||
|
||||
CREATE OR REPLACE FUNCTION emp.implement_tech( e_id INT , t_name TEXT )
|
||||
RETURNS INT
|
||||
STRICT VOLATILE
|
||||
SECURITY DEFINER
|
||||
AS $$
|
||||
DECLARE
|
||||
e_cash DOUBLE PRECISION;
|
||||
t_id INT;
|
||||
t_cost DOUBLE PRECISION;
|
||||
BEGIN
|
||||
SELECT INTO e_cash , t_id , t_cost e.cash , ns.id , td.cost
|
||||
FROM defs.strings ns
|
||||
INNER JOIN tech.technologies td
|
||||
ON td.name_id = ns.id
|
||||
INNER JOIN emp.researched_technologies rt
|
||||
ON rt.technology_id = td.name_id
|
||||
INNER JOIN emp.empires e
|
||||
ON rt.empire_id = e.name_id
|
||||
WHERE e.name_id = e_id AND ns.name = t_name
|
||||
FOR UPDATE OF e , rt;
|
||||
IF NOT FOUND THEN
|
||||
RETURN 2;
|
||||
END IF;
|
||||
|
||||
IF e_cash < t_cost THEN
|
||||
RETURN 1;
|
||||
END IF;
|
||||
|
||||
UPDATE emp.empires
|
||||
SET cash = e_cash - t_cost
|
||||
WHERE name_id = e_id;
|
||||
UPDATE emp.researched_technologies
|
||||
SET implemented = TRUE
|
||||
WHERE empire_id = e_id AND technology_id = t_id;
|
||||
|
||||
RETURN 0;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
GRANT EXECUTE ON FUNCTION emp.implement_tech( INT , TEXT ) TO :dbuser;
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Prepare for research priorities updates
|
||||
--
|
||||
|
||||
CREATE OR REPLACE FUNCTION emp.prepare_research_priorities_update( )
|
||||
RETURNS VOID
|
||||
STRICT VOLATILE
|
||||
SECURITY DEFINER
|
||||
AS $$
|
||||
BEGIN
|
||||
CREATE TEMPORARY TABLE research_priorities_updates(
|
||||
technology TEXT ,
|
||||
priority INT
|
||||
);
|
||||
CREATE INDEX rpu_technology ON research_priorities_updates ( technology );
|
||||
IF session_user <> current_user THEN
|
||||
EXECUTE 'GRANT INSERT ON research_priorities_updates TO ' || session_user;
|
||||
END IF;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
GRANT EXECUTE ON FUNCTION emp.prepare_research_priorities_update( ) TO :dbuser;
|
||||
|
||||
|
||||
--
|
||||
-- Applies research priorities updates
|
||||
--
|
||||
-- Parameters:
|
||||
-- e_id identifier of the empire the updates should be applied to
|
||||
--
|
||||
-- Returns:
|
||||
-- an error code:
|
||||
-- 0 success
|
||||
-- 1 list of updates does not match current research topics
|
||||
-- 2 invalid priorities
|
||||
--
|
||||
|
||||
CREATE OR REPLACE FUNCTION emp.apply_research_priorities( IN e_id INT )
|
||||
RETURNS INT
|
||||
STRICT VOLATILE
|
||||
SECURITY DEFINER
|
||||
AS $$
|
||||
DECLARE
|
||||
rec RECORD;
|
||||
t INT;
|
||||
rval INT;
|
||||
BEGIN
|
||||
-- Lock empire and research info
|
||||
PERFORM er.technology_id
|
||||
FROM emp.empires e
|
||||
INNER JOIN emp.research er ON er.empire_id = e.name_id
|
||||
WHERE e.name_id = e_id
|
||||
FOR UPDATE OF e , er;
|
||||
|
||||
-- Check values
|
||||
t := 0;
|
||||
rval := 0;
|
||||
FOR rec IN SELECT rpu.priority , r.technology_id FROM research_priorities_updates rpu
|
||||
LEFT OUTER JOIN emp.research_view r
|
||||
ON ( r.detailed AND r.technology = rpu.technology )
|
||||
OR ( NOT r.detailed AND ( 'unknown-' || ( r.technology_id * e_id )::TEXT ) = rpu.technology )
|
||||
WHERE r.empire = e_id OR r.empire IS NULL
|
||||
UNION SELECT rpu.priority , r.technology_id FROM research_priorities_updates rpu
|
||||
RIGHT OUTER JOIN emp.research_view r
|
||||
ON ( r.detailed AND r.technology = rpu.technology )
|
||||
OR ( NOT r.detailed AND ( 'unknown-' || ( r.technology_id * e_id )::TEXT ) = rpu.technology )
|
||||
WHERE r.empire = e_id
|
||||
LOOP
|
||||
IF rec.priority IS NULL OR rec.technology_id IS NULL THEN
|
||||
rval := 1;
|
||||
EXIT;
|
||||
ELSIF rec.priority NOT BETWEEN 0 AND 100 THEN
|
||||
rval := 2;
|
||||
EXIT;
|
||||
END IF;
|
||||
t := t + rec.priority;
|
||||
END LOOP;
|
||||
IF rval = 0 AND t <> 100 THEN
|
||||
rval := 2;
|
||||
END IF;
|
||||
|
||||
-- Update research info
|
||||
IF rval = 0 THEN
|
||||
UPDATE emp.research er SET priority = rpu.priority
|
||||
FROM research_priorities_updates rpu , emp.research_view rv
|
||||
WHERE ( rpu.technology = CASE
|
||||
WHEN rv.detailed THEN
|
||||
rv.technology
|
||||
ELSE
|
||||
( 'unknown-' || ( rv.technology_id * e_id )::TEXT )
|
||||
END )
|
||||
AND rv.empire = e_id
|
||||
AND er.empire_id = e_id
|
||||
AND er.technology_id = rv.technology_id;
|
||||
END IF;
|
||||
DROP TABLE research_priorities_updates;
|
||||
RETURN rval;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
GRANT EXECUTE ON FUNCTION emp.apply_research_priorities( INT ) TO :dbuser;
|
||||
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Base research view
|
||||
--
|
||||
|
||||
CREATE VIEW emp.base_research_view
|
||||
AS SELECT er.empire_id AS empire , er.technology_id , ns.name AS technology ,
|
||||
td.points AS required , ( CASE
|
||||
WHEN er.accumulated > td.points THEN
|
||||
td.points - 1
|
||||
ELSE
|
||||
er.accumulated
|
||||
END ) AS accumulated , er.priority
|
||||
FROM emp.research er
|
||||
INNER JOIN tech.technologies td ON td.name_id = er.technology_id
|
||||
INNER JOIN defs.strings ns ON ns.id = er.technology_id;
|
||||
|
||||
|
||||
--
|
||||
-- Research view
|
||||
--
|
||||
|
||||
CREATE VIEW emp.research_view
|
||||
AS SELECT empire , technology , technology_id ,
|
||||
FLOOR( 100 * accumulated / required )::INT AS completion ,
|
||||
( accumulated >= sys.get_constant( 'game.research.minPoints' )
|
||||
OR accumulated / required >= sys.get_constant( 'game.research.minRatio' ) ) AS detailed ,
|
||||
priority
|
||||
FROM emp.base_research_view;
|
||||
|
||||
|
||||
--
|
||||
-- Researched and implemented technologies view
|
||||
|
||||
CREATE VIEW emp.known_techs_view
|
||||
AS SELECT et.empire_id AS empire , et.technology_id , ns.name AS technology ,
|
||||
( CASE WHEN et.implemented THEN NULL::INT ELSE td.cost END ) AS cost
|
||||
FROM emp.researched_technologies et
|
||||
INNER JOIN tech.technologies td ON td.name_id = et.technology_id
|
||||
INNER JOIN defs.strings ns ON ns.id = et.technology_id;
|
||||
|
||||
|
||||
--
|
||||
-- Combined research and technologies view
|
||||
--
|
||||
|
||||
CREATE VIEW emp.technologies_view
|
||||
AS SELECT empire , technology_id , technology ,
|
||||
detailed , completion , priority , NULL::INT AS cost
|
||||
FROM emp.research_view
|
||||
UNION ALL SELECT empire , technology_id , technology ,
|
||||
TRUE AS detailed , NULL::INT AS completion , NULL::INT AS priority , cost
|
||||
FROM emp.known_techs_view;
|
||||
|
||||
GRANT SELECT ON emp.technologies_view TO :dbuser;
|
||||
|
|
@ -11,14 +11,14 @@
|
|||
-- sigma( x ) = exp( x ) / ( 1 + exp( x ) )
|
||||
--
|
||||
|
||||
CREATE OR REPLACE FUNCTION verse.sigma( x REAL )
|
||||
RETURNS REAL
|
||||
CREATE OR REPLACE FUNCTION verse.sigma( x DOUBLE PRECISION )
|
||||
RETURNS DOUBLE PRECISION
|
||||
STRICT IMMUTABLE SECURITY INVOKER
|
||||
AS $$
|
||||
SELECT ( CASE
|
||||
WHEN $1 < -100 THEN 0
|
||||
WHEN $1 > 100 THEN 1
|
||||
ELSE ( exp( $1 ) / ( 1 + exp( $1 ) ) )::REAL
|
||||
ELSE ( exp( $1 ) / ( 1 + exp( $1 ) ) )
|
||||
END );
|
||||
$$ LANGUAGE SQL;
|
||||
|
||||
|
@ -28,8 +28,8 @@ $$ LANGUAGE SQL;
|
|||
-- poly( x , a , b , c ) = ( a * x + b ) * x + c
|
||||
--
|
||||
|
||||
CREATE OR REPLACE FUNCTION verse.poly( x REAL , a REAL , b REAL , c REAL )
|
||||
RETURNS REAL
|
||||
CREATE OR REPLACE FUNCTION verse.poly( x DOUBLE PRECISION , a DOUBLE PRECISION , b DOUBLE PRECISION , c DOUBLE PRECISION )
|
||||
RETURNS DOUBLE PRECISION
|
||||
STRICT IMMUTABLE SECURITY INVOKER
|
||||
AS $$
|
||||
SELECT ( $2 * $1 + $3 ) * $1 + $4;
|
||||
|
@ -41,11 +41,11 @@ $$ LANGUAGE SQL;
|
|||
-- Happiness curve, K1 constant
|
||||
--
|
||||
|
||||
CREATE OR REPLACE FUNCTION verse.hcc_const_k1( xmax REAL , ymax REAL , xlimit REAL , ylimit REAL )
|
||||
RETURNS REAL
|
||||
CREATE OR REPLACE FUNCTION verse.hcc_const_k1( xmax DOUBLE PRECISION , ymax DOUBLE PRECISION , xlimit DOUBLE PRECISION , ylimit DOUBLE PRECISION )
|
||||
RETURNS DOUBLE PRECISION
|
||||
STRICT IMMUTABLE SECURITY INVOKER
|
||||
AS $$
|
||||
SELECT ( ( $4 - $2 ) / ( ( $3 - $1 ) ^ 2 ) )::REAL;
|
||||
SELECT ( ( $4 - $2 ) / ( ( $3 - $1 ) ^ 2 ) );
|
||||
$$ LANGUAGE SQL;
|
||||
|
||||
|
||||
|
@ -54,11 +54,11 @@ $$ LANGUAGE SQL;
|
|||
-- Happiness curve, K2 constant
|
||||
--
|
||||
|
||||
CREATE OR REPLACE FUNCTION verse.hcc_const_k2( ylimit REAL , yasymptote REAL )
|
||||
RETURNS REAL
|
||||
CREATE OR REPLACE FUNCTION verse.hcc_const_k2( ylimit DOUBLE PRECISION , yasymptote DOUBLE PRECISION )
|
||||
RETURNS DOUBLE PRECISION
|
||||
STRICT IMMUTABLE SECURITY INVOKER
|
||||
AS $$
|
||||
SELECT ( 2 * ( $1 - $2 ) )::REAL;
|
||||
SELECT ( 2 * ( $1 - $2 ) );
|
||||
$$ LANGUAGE SQL;
|
||||
|
||||
|
||||
|
@ -67,11 +67,11 @@ $$ LANGUAGE SQL;
|
|||
-- Happiness curve, K3 constant
|
||||
--
|
||||
|
||||
CREATE OR REPLACE FUNCTION verse.hcc_const_k3( xmax REAL , ymax REAL , xlimit REAL , ylimit REAL , yasymptote REAL )
|
||||
RETURNS REAL
|
||||
CREATE OR REPLACE FUNCTION verse.hcc_const_k3( xmax DOUBLE PRECISION , ymax DOUBLE PRECISION , xlimit DOUBLE PRECISION , ylimit DOUBLE PRECISION , yasymptote DOUBLE PRECISION )
|
||||
RETURNS DOUBLE PRECISION
|
||||
STRICT IMMUTABLE SECURITY INVOKER
|
||||
AS $$
|
||||
SELECT ( verse.hcc_const_k1( $1 , $2 , $3 , $4 ) * 4 * ( $3 - $1 ) / ( $5 - $4 ) ) ::REAL;
|
||||
SELECT ( verse.hcc_const_k1( $1 , $2 , $3 , $4 ) * 4 * ( $3 - $1 ) / ( $5 - $4 ) );
|
||||
$$ LANGUAGE SQL;
|
||||
|
||||
|
||||
|
@ -80,15 +80,15 @@ $$ LANGUAGE SQL;
|
|||
-- Happiness curve, first part
|
||||
--
|
||||
|
||||
CREATE OR REPLACE FUNCTION verse.hcc_part_1( x REAL , ymin REAL , ymax REAL , xmax REAL )
|
||||
RETURNS REAL
|
||||
CREATE OR REPLACE FUNCTION verse.hcc_part_1( x DOUBLE PRECISION , ymin DOUBLE PRECISION , ymax DOUBLE PRECISION , xmax DOUBLE PRECISION )
|
||||
RETURNS DOUBLE PRECISION
|
||||
STRICT IMMUTABLE SECURITY INVOKER
|
||||
AS $$
|
||||
DECLARE
|
||||
v REAL;
|
||||
v DOUBLE PRECISION;
|
||||
BEGIN
|
||||
v := ( ymin - ymax ) / xmax;
|
||||
RETURN verse.poly( x , ( v / xmax )::REAL , ( -2 * v )::REAL , ymin );
|
||||
RETURN verse.poly( x , v / xmax , -2 * v , ymin );
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
|
@ -98,15 +98,15 @@ $$ LANGUAGE plpgsql;
|
|||
-- Happiness curve, second part
|
||||
--
|
||||
|
||||
CREATE OR REPLACE FUNCTION verse.hcc_part_2( x REAL , xmax REAL , ymax REAL , xlimit REAL , ylimit REAL )
|
||||
RETURNS REAL
|
||||
CREATE OR REPLACE FUNCTION verse.hcc_part_2( x DOUBLE PRECISION , xmax DOUBLE PRECISION , ymax DOUBLE PRECISION , xlimit DOUBLE PRECISION , ylimit DOUBLE PRECISION )
|
||||
RETURNS DOUBLE PRECISION
|
||||
STRICT IMMUTABLE SECURITY INVOKER
|
||||
AS $$
|
||||
DECLARE
|
||||
k1 REAL;
|
||||
k1 DOUBLE PRECISION;
|
||||
BEGIN
|
||||
k1 := verse.hcc_const_k1( xmax , ymax , xlimit , ylimit );
|
||||
RETURN verse.poly( x , k1 , ( -2 * xmax * k1 )::REAL , ( ymax + k1 * xmax * xmax )::REAL );
|
||||
RETURN verse.poly( x , k1 , -2 * xmax * k1 , ymax + k1 * xmax * xmax );
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
|
@ -116,17 +116,17 @@ $$ LANGUAGE plpgsql;
|
|||
-- Happiness curve, third part
|
||||
--
|
||||
|
||||
CREATE OR REPLACE FUNCTION verse.hcc_part_3( x REAL , xmax REAL , ymax REAL , xlimit REAL , ylimit REAL , yasymptote REAL )
|
||||
RETURNS REAL
|
||||
CREATE OR REPLACE FUNCTION verse.hcc_part_3( x DOUBLE PRECISION , xmax DOUBLE PRECISION , ymax DOUBLE PRECISION , xlimit DOUBLE PRECISION , ylimit DOUBLE PRECISION , yasymptote DOUBLE PRECISION )
|
||||
RETURNS DOUBLE PRECISION
|
||||
STRICT IMMUTABLE SECURITY INVOKER
|
||||
AS $$
|
||||
DECLARE
|
||||
k2 REAL;
|
||||
k3 REAL;
|
||||
k2 DOUBLE PRECISION;
|
||||
k3 DOUBLE PRECISION;
|
||||
BEGIN
|
||||
k2 := verse.hcc_const_k2( ylimit , yasymptote );
|
||||
k3 := verse.hcc_const_k3( xmax , ymax , xlimit , ylimit , yasymptote );
|
||||
RETURN yasymptote + k2 * ( 1 - verse.sigma( ( k3 * ( x - xlimit ) ) )::REAL );
|
||||
RETURN yasymptote + k2 * ( 1 - verse.sigma( ( k3 * ( x - xlimit ) ) ) );
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
|
@ -136,8 +136,8 @@ $$ LANGUAGE plpgsql;
|
|||
-- Happiness curve
|
||||
--
|
||||
|
||||
CREATE OR REPLACE FUNCTION verse.happiness_curve( x REAL , ymin REAL , xmax REAL , ymax REAL , xlimit REAL , ylimit REAL , yasymptote REAL )
|
||||
RETURNS REAL
|
||||
CREATE OR REPLACE FUNCTION verse.happiness_curve( x DOUBLE PRECISION , ymin DOUBLE PRECISION , xmax DOUBLE PRECISION , ymax DOUBLE PRECISION , xlimit DOUBLE PRECISION , ylimit DOUBLE PRECISION , yasymptote DOUBLE PRECISION )
|
||||
RETURNS DOUBLE PRECISION
|
||||
STRICT IMMUTABLE SECURITY INVOKER
|
||||
AS $$
|
||||
SELECT (CASE
|
||||
|
@ -156,37 +156,37 @@ $$ LANGUAGE SQL;
|
|||
-- Happiness computation
|
||||
--
|
||||
|
||||
CREATE OR REPLACE FUNCTION verse.compute_happiness( population REAL , workers REAL , defence REAL , empsize INT )
|
||||
RETURNS REAL
|
||||
CREATE OR REPLACE FUNCTION verse.compute_happiness( population DOUBLE PRECISION , workers DOUBLE PRECISION , defence DOUBLE PRECISION , empsize INT )
|
||||
RETURNS DOUBLE PRECISION
|
||||
STRICT STABLE SECURITY INVOKER
|
||||
AS $$
|
||||
DECLARE
|
||||
whappiness REAL;
|
||||
dhappiness REAL;
|
||||
shappiness REAL;
|
||||
whappiness DOUBLE PRECISION;
|
||||
dhappiness DOUBLE PRECISION;
|
||||
shappiness DOUBLE PRECISION;
|
||||
BEGIN
|
||||
-- Work-related happiness
|
||||
whappiness := verse.happiness_curve(
|
||||
( workers / population )::REAL ,
|
||||
workers / population ,
|
||||
sys.get_constant( 'game.happiness.noEmployment' ) , 1.0 , 1.0 ,
|
||||
sys.get_constant( 'game.happiness.employmentLimit' ) , 0.5 , 0
|
||||
);
|
||||
|
||||
-- Defence-related happiness
|
||||
dhappiness := verse.happiness_curve(
|
||||
( sys.get_constant( 'game.happiness.popPerDefencePoint' ) * defence / population )::REAL ,
|
||||
sys.get_constant( 'game.happiness.popPerDefencePoint' ) * defence / population ,
|
||||
sys.get_constant( 'game.happiness.noDefence' ) , 1.0 , 1.0 ,
|
||||
sys.get_constant( 'game.happiness.defenceLimit' ) , 0.5 , 0
|
||||
);
|
||||
|
||||
-- Influence of empire size
|
||||
shappiness := verse.happiness_curve(
|
||||
( empsize::REAL / sys.get_constant( 'game.happiness.idealEmpireSize' ) )::REAL ,
|
||||
empsize / sys.get_constant( 'game.happiness.idealEmpireSize' ) ,
|
||||
sys.get_constant( 'game.happiness.smallEmpire' ) , 1.0 , 1.0 ,
|
||||
sys.get_constant( 'game.happiness.eSizeLimit' ) , 0.5 , 0
|
||||
);
|
||||
|
||||
RETURN ( shappiness * ( whappiness + dhappiness ) / 2.0 )::REAL;
|
||||
RETURN shappiness * ( whappiness + dhappiness ) / 2.0;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
|
@ -195,14 +195,14 @@ $$ LANGUAGE plpgsql;
|
|||
--
|
||||
-- Production adjustment
|
||||
--
|
||||
CREATE OR REPLACE FUNCTION verse.adjust_production( prod REAL , happiness REAL )
|
||||
RETURNS REAL
|
||||
CREATE OR REPLACE FUNCTION verse.adjust_production( prod DOUBLE PRECISION , happiness DOUBLE PRECISION )
|
||||
RETURNS DOUBLE PRECISION
|
||||
STRICT IMMUTABLE
|
||||
SECURITY INVOKER
|
||||
AS $$
|
||||
SELECT ( CASE
|
||||
WHEN $2 < sys.get_constant( 'game.happiness.strike' ) THEN
|
||||
( $1 * ( 1 - ( $2 / sys.get_constant( 'game.happiness.strike' ) ) ) )::REAL
|
||||
$1 * ( 1 - ( $2 / sys.get_constant( 'game.happiness.strike' ) ) )
|
||||
ELSE
|
||||
$1
|
||||
END );
|
||||
|
@ -213,15 +213,15 @@ $$ LANGUAGE SQL;
|
|||
-- Income computation
|
||||
--
|
||||
|
||||
CREATE OR REPLACE FUNCTION verse.compute_income( population REAL , happiness REAL , cashprod REAL )
|
||||
RETURNS REAL
|
||||
CREATE OR REPLACE FUNCTION verse.compute_income( population DOUBLE PRECISION , happiness DOUBLE PRECISION , cashprod DOUBLE PRECISION )
|
||||
RETURNS DOUBLE PRECISION
|
||||
STRICT STABLE
|
||||
SECURITY INVOKER
|
||||
AS $$
|
||||
DECLARE
|
||||
base REAL;
|
||||
badj REAL;
|
||||
cprod REAL;
|
||||
base DOUBLE PRECISION;
|
||||
badj DOUBLE PRECISION;
|
||||
cprod DOUBLE PRECISION;
|
||||
BEGIN
|
||||
badj := ( 1 - verse.adjust_production( 1.0 , happiness ) ) * sys.get_constant( 'game.work.strikeEffect' );
|
||||
base := floor( population ) * sys.get_constant( 'game.work.population' ) * ( 1 - badj );
|
||||
|
|
|
@ -19,14 +19,14 @@
|
|||
--
|
||||
|
||||
CREATE OR REPLACE FUNCTION verse.get_raw_production( pid INT , pt building_output_type )
|
||||
RETURNS REAL
|
||||
RETURNS DOUBLE PRECISION
|
||||
STRICT STABLE
|
||||
SECURITY DEFINER
|
||||
AS $$
|
||||
DECLARE
|
||||
rv REAL;
|
||||
rv DOUBLE PRECISION;
|
||||
BEGIN
|
||||
SELECT INTO rv SUM( b.amount * d.output )::REAL
|
||||
SELECT INTO rv SUM( b.amount * d.output )
|
||||
FROM verse.planet_buildings b
|
||||
INNER JOIN tech.buildings d
|
||||
ON d.buildable_id = b.building_id AND d.output_type = pt
|
||||
|
@ -114,14 +114,14 @@ $$ LANGUAGE SQL;
|
|||
--
|
||||
|
||||
CREATE OR REPLACE FUNCTION verse.get_planet_upkeep( pid INT )
|
||||
RETURNS REAL
|
||||
RETURNS DOUBLE PRECISION
|
||||
STRICT STABLE
|
||||
SECURITY INVOKER
|
||||
AS $$
|
||||
DECLARE
|
||||
rv REAL;
|
||||
rv DOUBLE PRECISION;
|
||||
BEGIN
|
||||
SELECT INTO rv SUM( b.amount * d.upkeep )::REAL
|
||||
SELECT INTO rv SUM( b.amount * d.upkeep )
|
||||
FROM verse.planet_buildings b
|
||||
INNER JOIN tech.buildables d
|
||||
ON d.name_id = b.building_id
|
||||
|
@ -145,7 +145,7 @@ $$ LANGUAGE plpgsql;
|
|||
-- npics Amount of planet pictures
|
||||
--
|
||||
|
||||
CREATE OR REPLACE FUNCTION verse.create_planet( sid INT , o INT , ipop REAL , npics INT )
|
||||
CREATE OR REPLACE FUNCTION verse.create_planet( sid INT , o INT , ipop DOUBLE PRECISION , npics INT )
|
||||
RETURNS VOID
|
||||
STRICT VOLATILE
|
||||
SECURITY INVOKER
|
||||
|
@ -156,7 +156,7 @@ DECLARE
|
|||
bpp INT;
|
||||
uid BIGINT;
|
||||
utp update_type;
|
||||
happiness REAL;
|
||||
happiness DOUBLE PRECISION;
|
||||
BEGIN
|
||||
-- Planet name and planet
|
||||
pnid := naming.create_map_name( 'P' );
|
||||
|
@ -217,7 +217,7 @@ $$ LANGUAGE plpgsql;
|
|||
-- npics Amount of planet pictures
|
||||
--
|
||||
|
||||
CREATE OR REPLACE FUNCTION verse.create_system( sx INT , sy INT , ipop REAL , npics INT )
|
||||
CREATE OR REPLACE FUNCTION verse.create_system( sx INT , sy INT , ipop DOUBLE PRECISION , npics INT )
|
||||
RETURNS VOID
|
||||
STRICT VOLATILE
|
||||
SECURITY INVOKER
|
||||
|
@ -249,7 +249,7 @@ $$ LANGUAGE plpgsql;
|
|||
-- ipop Initial population
|
||||
--
|
||||
|
||||
CREATE OR REPLACE FUNCTION verse.create_systems( x0 INT , y0 INT , x1 INT , y1 INT , ipop REAL )
|
||||
CREATE OR REPLACE FUNCTION verse.create_systems( x0 INT , y0 INT , x1 INT , y1 INT , ipop DOUBLE PRECISION )
|
||||
RETURNS VOID
|
||||
STRICT VOLATILE
|
||||
SECURITY INVOKER
|
||||
|
@ -283,7 +283,7 @@ CREATE OR REPLACE FUNCTION verse.generate_initial_universe( )
|
|||
AS $$
|
||||
DECLARE
|
||||
sz INT;
|
||||
pop REAL;
|
||||
pop DOUBLE PRECISION;
|
||||
npics INT;
|
||||
BEGIN
|
||||
sz := floor( sys.get_constant( 'game.universe.initialSize' ) );
|
||||
|
@ -316,7 +316,7 @@ DECLARE
|
|||
y0 INT;
|
||||
x1 INT;
|
||||
y1 INT;
|
||||
pop REAL;
|
||||
pop DOUBLE PRECISION;
|
||||
BEGIN
|
||||
-- Get current bounds
|
||||
SELECT INTO min_x , max_x , min_y , max_y
|
||||
|
@ -368,7 +368,7 @@ CREATE OR REPLACE FUNCTION verse.generate( )
|
|||
AS $$
|
||||
DECLARE
|
||||
p_count INT;
|
||||
f_ratio REAL;
|
||||
f_ratio DOUBLE PRECISION;
|
||||
BEGIN
|
||||
-- Get total planet count
|
||||
SELECT INTO p_count 5 * count(*)
|
||||
|
@ -381,7 +381,7 @@ BEGIN
|
|||
END IF;
|
||||
|
||||
-- Get available planets ratio
|
||||
SELECT INTO f_ratio count(*)::REAL / p_count::REAL
|
||||
SELECT INTO f_ratio count(*)::DOUBLE PRECISION / p_count::DOUBLE PRECISION
|
||||
FROM verse.available_planets;
|
||||
|
||||
-- Expand universe if required
|
||||
|
|
|
@ -175,17 +175,17 @@ CREATE OR REPLACE FUNCTION verse.get_orbital_view( e_id INT , p_id INT )
|
|||
AS $$
|
||||
DECLARE
|
||||
rv planet_orbital_data;
|
||||
happ REAL;
|
||||
happ DOUBLE PRECISION;
|
||||
e_att BOOLEAN;
|
||||
rec RECORD;
|
||||
BEGIN
|
||||
-- Get the planet's population and defence
|
||||
SELECT INTO rv.population , happ
|
||||
floor( p.population )::BIGINT , ( ph.current / p.population )::REAL
|
||||
floor( p.population )::BIGINT , ( ph.current / p.population )::DOUBLE PRECISION
|
||||
FROM verse.planets p
|
||||
INNER JOIN verse.planet_happiness ph ON ph.planet_id = p.name_id
|
||||
WHERE p.name_id = p_id;
|
||||
rv.defence := round( verse.adjust_production( verse.get_raw_production( p_id , 'DEF' ) , happ ) );
|
||||
rv.defence := verse.adjust_production( verse.get_raw_production( p_id , 'DEF' ) , happ );
|
||||
|
||||
-- Get the empire's fleet mode
|
||||
SELECT INTO e_att f.attacking
|
||||
|
@ -332,8 +332,7 @@ AS $$
|
|||
( bd.workers * b.amount )::INT AS jobs ,
|
||||
( bd.upkeep * b.amount )::BIGINT AS upkeep ,
|
||||
bd.output_type AS p_type ,
|
||||
floor( verse.adjust_production( ( bd.output * b.amount )::REAL ,
|
||||
( ph.current / p.population )::REAL )
|
||||
floor( verse.adjust_production( bd.output * b.amount , ph.current / p.population )
|
||||
)::BIGINT AS p_value
|
||||
FROM verse.planet_buildings b
|
||||
INNER JOIN verse.planets p ON p.name_id = b.planet_id
|
||||
|
@ -373,9 +372,9 @@ AS $$
|
|||
ELSE floor( qi.amount * bd.cost - ( CASE WHEN qi.queue_order = 0 THEN q.money ELSE 0 END ) )
|
||||
END )::BIGINT AS investment ,
|
||||
( CASE
|
||||
WHEN ceil( verse.adjust_production( ( p.population * sys.get_constant( 'game.work.wuPerPopUnit' ) )::REAL , ( ph.current / p.population )::REAL ) ) = 0 THEN NULL
|
||||
WHEN ceil( verse.adjust_production( p.population * sys.get_constant( 'game.work.wuPerPopUnit' ) , ph.current / p.population ) ) = 0 THEN NULL
|
||||
ELSE ceil( ( qi.amount * bd.work * ( CASE WHEN qi.destroy THEN sys.get_constant( 'game.work.destructionWork' ) ELSE 1 END ) - ( CASE WHEN qi.queue_order = 0 THEN q.work ELSE 0 END ) )
|
||||
/ verse.adjust_production( ( p.population * sys.get_constant( 'game.work.wuPerPopUnit' ) )::REAL , ( ph.current / p.population )::REAL ) )
|
||||
/ verse.adjust_production( p.population * sys.get_constant( 'game.work.wuPerPopUnit' ) , ph.current / p.population ) )
|
||||
END )::BIGINT AS time_left
|
||||
FROM verse.planets p
|
||||
INNER JOIN verse.planet_happiness ph ON ph.planet_id = p.name_id
|
||||
|
@ -414,9 +413,9 @@ AS $$
|
|||
qi.amount AS amount , FALSE AS destroy ,
|
||||
floor( qi.amount * bd.cost - ( CASE WHEN qi.queue_order = 0 THEN q.money ELSE 0 END ) )::BIGINT AS investment ,
|
||||
( CASE
|
||||
WHEN ceil( verse.adjust_production( verse.get_raw_production( $1 , 'WORK' ) , ( ph.current / p.population )::REAL ) ) = 0 THEN NULL
|
||||
WHEN ceil( verse.adjust_production( verse.get_raw_production( $1 , 'WORK' ) , ph.current / p.population ) ) = 0 THEN NULL
|
||||
ELSE ceil( ( qi.amount * bd.work - ( CASE WHEN qi.queue_order = 0 THEN q.work ELSE 0 END ) )
|
||||
/ verse.adjust_production( verse.get_raw_production( $1 , 'WORK' ) , ( ph.current / p.population )::REAL ) )
|
||||
/ verse.adjust_production( verse.get_raw_production( $1 , 'WORK' ) , ph.current / p.population ) )
|
||||
END )::BIGINT AS time_left
|
||||
FROM verse.planets p
|
||||
INNER JOIN verse.planet_happiness ph ON ph.planet_id = p.name_id
|
||||
|
@ -465,12 +464,12 @@ AS $$
|
|||
UNION SELECT bv.*
|
||||
FROM tech.buildings_view bv
|
||||
INNER JOIN tech.buildable_requirements r ON r.buildable_id = bv.name_id
|
||||
INNER JOIN tech.levels l ON l.id = r.level_id
|
||||
INNER JOIN tech.technologies l ON l.name_id = r.technology_id
|
||||
INNER JOIN emp.planets ep ON ep.planet_id = $1
|
||||
INNER JOIN emp.technologies t
|
||||
ON t.empire_id = ep.empire_id AND t.line_id = l.line_id AND t.level > l.level
|
||||
INNER JOIN emp.researched_technologies t
|
||||
ON t.empire_id = ep.empire_id AND t.technology_id = l.name_id
|
||||
) AS bv , (
|
||||
SELECT verse.adjust_production( ( p.population * sys.get_constant( 'game.work.wuPerPopUnit' ) )::REAL , ( ph.current / p.population )::REAL ) AS p_work ,
|
||||
SELECT verse.adjust_production( p.population * sys.get_constant( 'game.work.wuPerPopUnit' ) , ph.current / p.population ) AS p_work ,
|
||||
c.language_id AS language
|
||||
FROM verse.planets p
|
||||
INNER JOIN verse.planet_happiness ph ON ph.planet_id = p.name_id
|
||||
|
@ -517,12 +516,12 @@ AS $$
|
|||
UNION SELECT bv.*
|
||||
FROM tech.ships_view bv
|
||||
INNER JOIN tech.buildable_requirements r ON r.buildable_id = bv.name_id
|
||||
INNER JOIN tech.levels l ON l.id = r.level_id
|
||||
INNER JOIN tech.technologies l ON l.name_id = r.technology_id
|
||||
INNER JOIN emp.planets ep ON ep.planet_id = $1
|
||||
INNER JOIN emp.technologies t
|
||||
ON t.empire_id = ep.empire_id AND t.line_id = l.line_id AND t.level > l.level
|
||||
INNER JOIN emp.researched_technologies t
|
||||
ON t.empire_id = ep.empire_id AND t.technology_id = l.name_id
|
||||
) AS bv , (
|
||||
SELECT verse.adjust_production( verse.get_raw_production( $1 , 'WORK' ) , ( ph.current / p.population )::REAL ) AS p_work ,
|
||||
SELECT verse.adjust_production( verse.get_raw_production( $1 , 'WORK' ) , ph.current / p.population ) AS p_work ,
|
||||
c.language_id AS language
|
||||
FROM verse.planets p
|
||||
INNER JOIN verse.planet_happiness ph ON ph.planet_id = p.name_id
|
||||
|
@ -594,7 +593,7 @@ CREATE OR REPLACE FUNCTION verse.flush_build_queue( p_id INT )
|
|||
AS $$
|
||||
DECLARE
|
||||
e_id INT;
|
||||
q_cash REAL;
|
||||
q_cash DOUBLE PRECISION;
|
||||
BEGIN
|
||||
SELECT INTO e_id , q_cash e.name_id , q.money
|
||||
FROM verse.planets p
|
||||
|
@ -633,7 +632,7 @@ CREATE OR REPLACE FUNCTION verse.flush_military_queue( p_id INT )
|
|||
AS $$
|
||||
DECLARE
|
||||
e_id INT;
|
||||
q_cash REAL;
|
||||
q_cash DOUBLE PRECISION;
|
||||
BEGIN
|
||||
SELECT INTO e_id , q_cash e.name_id , q.money
|
||||
FROM verse.planets p
|
||||
|
@ -699,10 +698,10 @@ BEGIN
|
|||
FROM tech.ships s
|
||||
LEFT OUTER JOIN tech.buildable_requirements r
|
||||
ON r.buildable_id = s.buildable_id
|
||||
LEFT OUTER JOIN tech.levels l
|
||||
ON l.id = r.level_id
|
||||
LEFT OUTER JOIN emp.technologies t
|
||||
ON t.empire_id = e_id AND t.line_id = l.line_id AND t.level > l.level
|
||||
LEFT OUTER JOIN tech.technologies l
|
||||
ON l.name_id = r.technology_id
|
||||
LEFT OUTER JOIN emp.researched_technologies t
|
||||
ON t.empire_id = e_id AND t.technology_id = l.name_id
|
||||
WHERE s.buildable_id = s_id;
|
||||
IF NOT FOUND OR ( has_level IS NULL AND dep_level IS NOT NULL ) THEN
|
||||
RETURN;
|
||||
|
@ -765,10 +764,10 @@ BEGIN
|
|||
FROM tech.buildings b
|
||||
LEFT OUTER JOIN tech.buildable_requirements r
|
||||
ON r.buildable_id = b.buildable_id
|
||||
LEFT OUTER JOIN tech.levels l
|
||||
ON l.id = r.level_id
|
||||
LEFT OUTER JOIN emp.technologies t
|
||||
ON t.empire_id = e_id AND t.line_id = l.line_id AND t.level > l.level
|
||||
LEFT OUTER JOIN tech.technologies l
|
||||
ON l.name_id = r.technology_id
|
||||
LEFT OUTER JOIN emp.researched_technologies t
|
||||
ON t.empire_id = e_id AND t.technology_id = l.name_id
|
||||
WHERE b.buildable_id = b_id;
|
||||
IF NOT FOUND OR ( has_level IS NULL AND dep_level IS NOT NULL ) THEN
|
||||
RETURN;
|
||||
|
@ -979,7 +978,7 @@ $$ LANGUAGE plpgsql;
|
|||
-- tick Current tick
|
||||
--
|
||||
|
||||
CREATE OR REPLACE FUNCTION verse.inflict_battle_damage( p_id INT , t_power BIGINT , dmg REAL , b_id BIGINT , tick BIGINT )
|
||||
CREATE OR REPLACE FUNCTION verse.inflict_battle_damage( p_id INT , t_power BIGINT , dmg DOUBLE PRECISION , b_id BIGINT , tick BIGINT )
|
||||
RETURNS VOID
|
||||
STRICT VOLATILE
|
||||
SECURITY INVOKER
|
||||
|
@ -987,7 +986,7 @@ CREATE OR REPLACE FUNCTION verse.inflict_battle_damage( p_id INT , t_power BIGIN
|
|||
DECLARE
|
||||
rec RECORD;
|
||||
bp_id BIGINT;
|
||||
st_dmg REAL;
|
||||
st_dmg DOUBLE PRECISION;
|
||||
n_dest INT;
|
||||
BEGIN
|
||||
PERFORM sys.write_log( 'BattleUpdate' , 'TRACE'::log_level , 'Inflicting ' || dmg
|
||||
|
@ -1038,18 +1037,18 @@ $$ LANGUAGE plpgsql;
|
|||
-- d_ratio Debt damage ratio
|
||||
--
|
||||
|
||||
CREATE OR REPLACE FUNCTION verse.handle_debt( e_id INT , t_upkeep REAL , debt REAL , d_ratio REAL )
|
||||
CREATE OR REPLACE FUNCTION verse.handle_debt( e_id INT , t_upkeep DOUBLE PRECISION , debt DOUBLE PRECISION , d_ratio DOUBLE PRECISION )
|
||||
RETURNS VOID
|
||||
STRICT VOLATILE
|
||||
SECURITY INVOKER
|
||||
AS $$
|
||||
DECLARE
|
||||
tick BIGINT;
|
||||
tot_damage REAL;
|
||||
tot_damage DOUBLE PRECISION;
|
||||
p_rec RECORD;
|
||||
b_rec RECORD;
|
||||
bp_id BIGINT;
|
||||
b_damage REAL;
|
||||
b_damage DOUBLE PRECISION;
|
||||
n_destroy INT;
|
||||
BEGIN
|
||||
tick := sys.get_tick( ) - 1;
|
||||
|
@ -1066,7 +1065,7 @@ BEGIN
|
|||
bp_id := NULL;
|
||||
|
||||
FOR b_rec IN SELECT b.building_id AS building , b.amount AS amount ,
|
||||
( b.amount * bb.upkeep )::REAL AS upkeep ,
|
||||
b.amount * bb.upkeep AS upkeep ,
|
||||
b.damage AS damage , ( bd.output_type = 'DEF' ) AS is_def
|
||||
FROM verse.planet_buildings b
|
||||
INNER JOIN tech.buildables bb ON bb.name_id = b.building_id
|
||||
|
@ -1099,4 +1098,4 @@ BEGIN
|
|||
END LOOP;
|
||||
END LOOP;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
$$ LANGUAGE plpgsql;
|
|
@ -626,7 +626,7 @@ $$ LANGUAGE plpgsql;
|
|||
-- tick Current tick identifier
|
||||
--
|
||||
|
||||
CREATE OR REPLACE FUNCTION battles.inflict_damage( b_id BIGINT , dmg REAL , att BOOLEAN , tick BIGINT )
|
||||
CREATE OR REPLACE FUNCTION battles.inflict_damage( b_id BIGINT , dmg DOUBLE PRECISION , att BOOLEAN , tick BIGINT )
|
||||
RETURNS VOID
|
||||
STRICT VOLATILE
|
||||
SECURITY INVOKER
|
||||
|
@ -654,9 +654,9 @@ BEGIN
|
|||
st_power := battles.get_defence_power( b_id , tick );
|
||||
tot_power := tot_power + st_power;
|
||||
PERFORM sys.write_log( 'BattleUpdate' , 'TRACE'::log_level , 'About to inflict planet damage; total power: ' || tot_power
|
||||
|| '; planet power: ' || st_power || '; computed damage: ' || ( dmg * st_power / tot_power )::REAL );
|
||||
|| '; planet power: ' || st_power || '; computed damage: ' || ( dmg * st_power / tot_power ) );
|
||||
IF st_power <> 0 THEN
|
||||
PERFORM verse.inflict_battle_damage( planet , st_power , ( dmg * st_power / tot_power )::REAL , b_id , tick );
|
||||
PERFORM verse.inflict_battle_damage( planet , st_power , dmg * st_power / tot_power , b_id , tick );
|
||||
END IF;
|
||||
END IF;
|
||||
|
||||
|
@ -668,7 +668,7 @@ BEGIN
|
|||
LEFT OUTER JOIN fleets.movements m ON m.fleet_id = f.id
|
||||
WHERE b.id = b_id AND m.fleet_id IS NULL AND f.attacking = att
|
||||
LOOP
|
||||
PERFORM fleets.inflict_battle_damage( rec.id , ( dmg * rec.power / tot_power )::REAL , b_id , tick );
|
||||
PERFORM fleets.inflict_battle_damage( rec.id , dmg * rec.power / tot_power , b_id , tick );
|
||||
END LOOP;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
|
|
@ -256,8 +256,8 @@ CREATE VIEW battles.buildings_history
|
|||
WHEN rbp.raw_power = 0 THEN
|
||||
rbh.raw_power
|
||||
ELSE
|
||||
rbh.raw_power::REAL * rbp.actual_power::REAL / rbp.raw_power::REAL
|
||||
END )::REAL AS power
|
||||
rbh.raw_power * rbp.actual_power / rbp.raw_power
|
||||
END ) AS power
|
||||
FROM battles.empire_list_view elv
|
||||
INNER JOIN battles.raw_buildings_history rbh USING (battle)
|
||||
INNER JOIN battles.raw_buildings_power rbp USING (battle,tick)
|
||||
|
|
|
@ -55,7 +55,7 @@ $$ LANGUAGE plpgsql;
|
|||
-- the in-system movement's duration
|
||||
--
|
||||
|
||||
CREATE OR REPLACE FUNCTION fleets.compute_insystem_duration( f_time INT , s_orbit REAL , d_orbit REAL )
|
||||
CREATE OR REPLACE FUNCTION fleets.compute_insystem_duration( f_time INT , s_orbit DOUBLE PRECISION , d_orbit DOUBLE PRECISION )
|
||||
RETURNS INT
|
||||
STRICT IMMUTABLE
|
||||
SECURITY INVOKER
|
||||
|
@ -84,7 +84,7 @@ $$ LANGUAGE plpgsql;
|
|||
-- the outer space movement's duration
|
||||
--
|
||||
|
||||
CREATE OR REPLACE FUNCTION fleets.compute_outerspace_duration( f_time INT , s_x REAL , s_y REAL , d_x REAL , d_y REAL )
|
||||
CREATE OR REPLACE FUNCTION fleets.compute_outerspace_duration( f_time INT , s_x DOUBLE PRECISION , s_y DOUBLE PRECISION , d_x DOUBLE PRECISION , d_y DOUBLE PRECISION )
|
||||
RETURNS INT
|
||||
STRICT IMMUTABLE
|
||||
SECURITY INVOKER
|
||||
|
@ -115,16 +115,16 @@ $$ LANGUAGE plpgsql;
|
|||
|
||||
CREATE OR REPLACE FUNCTION fleets.compute_current_orbit(
|
||||
f_time INT , rp_orbit INT , outwards BOOLEAN , past_rp BOOLEAN , ft_left INT )
|
||||
RETURNS REAL
|
||||
RETURNS DOUBLE PRECISION
|
||||
STRICT IMMUTABLE
|
||||
SECURITY INVOKER
|
||||
AS $$
|
||||
DECLARE
|
||||
dist REAL;
|
||||
dir REAL;
|
||||
rloc REAL;
|
||||
dist DOUBLE PRECISION;
|
||||
dir DOUBLE PRECISION;
|
||||
rloc DOUBLE PRECISION;
|
||||
BEGIN
|
||||
dist := 1.0 - ft_left::REAL / f_time::REAL;
|
||||
dist := 1.0 - ft_left::DOUBLE PRECISION / f_time::DOUBLE PRECISION;
|
||||
dir := ( CASE WHEN outwards THEN 0.5 ELSE -0.5 END );
|
||||
IF past_rp THEN
|
||||
rloc := rp_orbit;
|
||||
|
@ -157,13 +157,14 @@ $$ LANGUAGE plpgsql;
|
|||
--
|
||||
|
||||
CREATE OR REPLACE FUNCTION fleets.compute_current_location(
|
||||
f_time INT , s_x REAL , s_y REAL , d_x REAL , d_y REAL , r_time INT ,
|
||||
OUT c_x REAL , OUT c_y REAL )
|
||||
f_time INT , s_x DOUBLE PRECISION , s_y DOUBLE PRECISION ,
|
||||
d_x DOUBLE PRECISION , d_y DOUBLE PRECISION , r_time INT ,
|
||||
OUT c_x DOUBLE PRECISION , OUT c_y DOUBLE PRECISION )
|
||||
STRICT IMMUTABLE
|
||||
SECURITY INVOKER
|
||||
AS $$
|
||||
DECLARE
|
||||
tot_time REAL;
|
||||
tot_time DOUBLE PRECISION;
|
||||
BEGIN
|
||||
tot_time := fleets.compute_outerspace_duration( f_time , s_x , s_y , d_x , d_y );
|
||||
c_x := s_x + ( d_x - s_x ) * ( 1 - r_time / tot_time );
|
||||
|
@ -251,7 +252,7 @@ $$ LANGUAGE plpgsql;
|
|||
--
|
||||
|
||||
CREATE OR REPLACE FUNCTION fleets.compute_insystem_redirect(
|
||||
f_time INT , s_sys INT , s_orbit REAL , d_id INT ,
|
||||
f_time INT , s_sys INT , s_orbit DOUBLE PRECISION , d_id INT ,
|
||||
OUT duration INT , OUT direction BOOLEAN , OUT s_duration INT ,
|
||||
OUT ref_point INT , OUT past_rp BOOLEAN )
|
||||
STRICT IMMUTABLE
|
||||
|
@ -260,7 +261,7 @@ CREATE OR REPLACE FUNCTION fleets.compute_insystem_redirect(
|
|||
DECLARE
|
||||
s_rec RECORD;
|
||||
d_rec RECORD;
|
||||
torb REAL;
|
||||
torb DOUBLE PRECISION;
|
||||
rporb INT;
|
||||
BEGIN
|
||||
-- Get destination planet coordinates, orbit and system ID
|
||||
|
@ -294,9 +295,9 @@ BEGIN
|
|||
ELSE
|
||||
torb := floor( torb );
|
||||
END IF;
|
||||
s_duration := fleets.compute_insystem_duration( f_time , s_orbit , ( torb / 2 )::REAL );
|
||||
s_duration := fleets.compute_insystem_duration( f_time , s_orbit , torb / 2 );
|
||||
rporb := round( s_orbit );
|
||||
past_rp := ( CASE WHEN direction THEN ( rporb::REAL <= s_orbit ) ELSE ( rporb::REAL >= s_orbit ) END );
|
||||
past_rp := ( CASE WHEN direction THEN ( rporb <= s_orbit ) ELSE ( rporb >= s_orbit ) END );
|
||||
END IF;
|
||||
SELECT INTO ref_point name_id FROM verse.planets p
|
||||
WHERE p.system_id = s_sys AND orbit = rporb;
|
||||
|
@ -322,7 +323,7 @@ $$ LANGUAGE plpgsql;
|
|||
--
|
||||
|
||||
CREATE OR REPLACE FUNCTION fleets.compute_outerspace_redirect(
|
||||
f_time INT , s_x REAL , s_y REAL , d_id INT ,
|
||||
f_time INT , s_x DOUBLE PRECISION , s_y DOUBLE PRECISION , d_id INT ,
|
||||
OUT duration INT , OUT s_duration INT )
|
||||
STRICT IMMUTABLE
|
||||
SECURITY INVOKER
|
||||
|
@ -365,8 +366,8 @@ DECLARE
|
|||
dir BOOLEAN;
|
||||
rpid INT;
|
||||
prp BOOLEAN;
|
||||
cx REAL;
|
||||
cy REAL;
|
||||
cx DOUBLE PRECISION;
|
||||
cy DOUBLE PRECISION;
|
||||
BEGIN
|
||||
-- Lock fleets and planets
|
||||
PERFORM * FROM fleets.fleets f
|
||||
|
@ -676,10 +677,10 @@ DECLARE
|
|||
old_ft INT;
|
||||
new_ft INT;
|
||||
sp_ft INT;
|
||||
x REAL;
|
||||
y REAL;
|
||||
cx REAL;
|
||||
cy REAL;
|
||||
x DOUBLE PRECISION;
|
||||
y DOUBLE PRECISION;
|
||||
cx DOUBLE PRECISION;
|
||||
cy DOUBLE PRECISION;
|
||||
sid INT;
|
||||
BEGIN
|
||||
SELECT INTO main * FROM fleet_split_main;
|
||||
|
@ -705,7 +706,7 @@ BEGIN
|
|||
IF new_ft <> old_ft THEN
|
||||
IF ism_rec IS NULL THEN
|
||||
-- Outer space movement
|
||||
SELECT INTO x , y s.x::REAL , s.y::REAL
|
||||
SELECT INTO x , y s.x , s.y
|
||||
FROM verse.planets p
|
||||
INNER JOIN verse.systems s ON s.id = p.system_id
|
||||
WHERE p.name_id = main.location;
|
||||
|
@ -754,7 +755,7 @@ BEGIN
|
|||
IF sp_ft <> old_ft THEN
|
||||
IF ism_rec IS NULL THEN
|
||||
-- Outer space movement
|
||||
SELECT INTO x , y s.x::REAL , s.y::REAL
|
||||
SELECT INTO x , y s.x , s.y
|
||||
FROM verse.planets p
|
||||
INNER JOIN verse.systems s ON s.id = p.system_id
|
||||
WHERE p.name_id = main.location;
|
||||
|
@ -983,7 +984,7 @@ GRANT EXECUTE ON FUNCTION fleets.disband( INT , BIGINT[] ) TO :dbuser;
|
|||
-- tick Current tick
|
||||
--
|
||||
|
||||
CREATE OR REPLACE FUNCTION fleets.inflict_battle_damage( f_id BIGINT , dmg REAL , b_id BIGINT , tick BIGINT )
|
||||
CREATE OR REPLACE FUNCTION fleets.inflict_battle_damage( f_id BIGINT , dmg DOUBLE PRECISION , b_id BIGINT , tick BIGINT )
|
||||
RETURNS VOID
|
||||
STRICT VOLATILE
|
||||
SECURITY INVOKER
|
||||
|
@ -995,7 +996,7 @@ DECLARE
|
|||
bp_id BIGINT;
|
||||
bf_id BIGINT;
|
||||
rec RECORD;
|
||||
st_dmg REAL;
|
||||
st_dmg DOUBLE PRECISION;
|
||||
n_dest INT;
|
||||
found INT;
|
||||
deleted INT;
|
||||
|
@ -1066,19 +1067,19 @@ $$ LANGUAGE plpgsql;
|
|||
-- d_ratio Debt damage ratio
|
||||
--
|
||||
|
||||
CREATE OR REPLACE FUNCTION fleets.handle_debt( e_id INT , t_upkeep REAL , debt REAL , d_ratio REAL )
|
||||
CREATE OR REPLACE FUNCTION fleets.handle_debt( e_id INT , t_upkeep DOUBLE PRECISION , debt DOUBLE PRECISION , d_ratio DOUBLE PRECISION )
|
||||
RETURNS VOID
|
||||
STRICT VOLATILE
|
||||
SECURITY INVOKER
|
||||
AS $$
|
||||
DECLARE
|
||||
tot_damage REAL;
|
||||
tot_damage DOUBLE PRECISION;
|
||||
f_rec RECORD;
|
||||
s_rec RECORD;
|
||||
n_found INT;
|
||||
n_killed INT;
|
||||
s_killed INT;
|
||||
s_damage REAL;
|
||||
s_damage DOUBLE PRECISION;
|
||||
n_ships INT;
|
||||
tick BIGINT;
|
||||
bp_id BIGINT;
|
||||
|
@ -1086,10 +1087,10 @@ DECLARE
|
|||
mv_rec fleets.movements%ROWTYPE;
|
||||
ism_rec fleets.ms_system%ROWTYPE;
|
||||
osm_rec fleets.ms_space%ROWTYPE;
|
||||
x REAL;
|
||||
y REAL;
|
||||
cx REAL;
|
||||
cy REAL;
|
||||
x DOUBLE PRECISION;
|
||||
y DOUBLE PRECISION;
|
||||
cx DOUBLE PRECISION;
|
||||
cy DOUBLE PRECISION;
|
||||
sid INT;
|
||||
BEGIN
|
||||
tick := sys.get_tick( ) - 1;
|
||||
|
@ -1120,7 +1121,7 @@ BEGIN
|
|||
n_killed := 0;
|
||||
s_killed := 0;
|
||||
FOR s_rec IN SELECT s.ship_id AS ship , s.amount AS amount , s.damage AS damage ,
|
||||
( d.upkeep * s.amount )::REAL AS upkeep
|
||||
d.upkeep * s.amount AS upkeep
|
||||
FROM fleets.ships s
|
||||
INNER JOIN tech.buildables d ON d.name_id = s.ship_id
|
||||
WHERE s.fleet_id = f_rec.fleet
|
||||
|
@ -1174,7 +1175,7 @@ BEGIN
|
|||
|
||||
IF ism_rec IS NULL THEN
|
||||
-- Outer space movement
|
||||
SELECT INTO x , y s.x::REAL , s.y::REAL
|
||||
SELECT INTO x , y s.x , s.y
|
||||
FROM verse.planets p
|
||||
INNER JOIN verse.systems s ON s.id = p.system_id
|
||||
WHERE p.name_id = f_rec.location;
|
||||
|
@ -1386,7 +1387,7 @@ GRANT SELECT ON fleets.static_fleets TO :dbuser;
|
|||
CREATE VIEW fleets.outer_space_fleets
|
||||
AS SELECT s.movement_id AS id , m.state_time_left AS time_left ,
|
||||
s.start_x AS x0 , s.start_y AS y0 ,
|
||||
ts.x::REAL AS x1 , ts.y::REAL AS y1
|
||||
ts.x::DOUBLE PRECISION AS x1 , ts.y::DOUBLE PRECISION AS y1
|
||||
FROM fleets.ms_space s
|
||||
INNER JOIN fleets.movements m ON m.fleet_id = s.movement_id
|
||||
INNER JOIN fleets.fleets f ON m.fleet_id = f.id
|
||||
|
@ -1422,14 +1423,14 @@ CREATE VIEW fleets.moving_fleets
|
|||
f.location_id AS to_id , dn.name AS to_name ,
|
||||
( CASE
|
||||
WHEN osf.id IS NULL THEN isf.x
|
||||
ELSE ( osf.x1 - osf.time_left::REAL * ( osf.x1 - osf.x0 )
|
||||
ELSE ( osf.x1 - osf.time_left * ( osf.x1 - osf.x0 )
|
||||
/ fleets.compute_outerspace_duration( fs.flight_time , osf.x0 , osf.y0 , osf.x1 , osf.y1 ) )
|
||||
END )::REAL AS cx ,
|
||||
END )::DOUBLE PRECISION AS cx ,
|
||||
( CASE
|
||||
WHEN osf.id IS NULL THEN isf.y
|
||||
ELSE ( osf.y1 - osf.time_left::REAL * ( osf.y1 - osf.y0 )
|
||||
ELSE ( osf.y1 - osf.time_left * ( osf.y1 - osf.y0 )
|
||||
/ fleets.compute_outerspace_duration( fs.flight_time , osf.x0 , osf.y0 , osf.x1 , osf.y1 ) )
|
||||
END )::REAL AS cy ,
|
||||
END )::DOUBLE PRECISION AS cy ,
|
||||
( CASE
|
||||
WHEN osf.id IS NULL THEN isf.planet
|
||||
ELSE NULL
|
||||
|
@ -1487,7 +1488,7 @@ GRANT SELECT ON fleets.ships_view TO :dbuser;
|
|||
CREATE VIEW fleets.short_static_fleets
|
||||
AS SELECT sf.empire , sf.location AS location_id ,
|
||||
fl.name AS location_name ,
|
||||
fl.x::REAL AS x , fl.y::REAL AS y ,
|
||||
fl.x::DOUBLE PRECISION AS x , fl.y::DOUBLE PRECISION AS y ,
|
||||
sf.id , sf.name , sf.status , sf.penalty ,
|
||||
fl.attacking , sf.power , sf.flight_time
|
||||
FROM fleets.static_fleets sf
|
||||
|
|
|
@ -15,7 +15,7 @@ CREATE VIEW emp.planets_list_basic
|
|||
AS SELECT e.name_id AS empire ,
|
||||
p.name_id AS id , n.name ,
|
||||
s.x , s.y , p.orbit ,
|
||||
p.population , ph.current / p.population::REAL AS happiness ,
|
||||
p.population , ph.current / p.population AS happiness ,
|
||||
floor( pm.income )::BIGINT AS income ,
|
||||
floor( pm.upkeep )::BIGINT AS upkeep
|
||||
FROM emp.empires e
|
||||
|
|
|
@ -860,7 +860,7 @@ CREATE VIEW events.empire_events_view
|
|||
AS SELECT e.event_id AS id , e.evt_type , e.evt_subtype , e.tick , e.real_time , s.name AS technology
|
||||
FROM events.events e
|
||||
LEFT OUTER JOIN events.empire_events ed USING (event_id)
|
||||
LEFT OUTER JOIN tech.levels tl ON tl.id = ed.technology_id
|
||||
LEFT OUTER JOIN tech.technologies tl ON tl.name_id = ed.technology_id
|
||||
LEFT OUTER JOIN defs.strings s ON s.id = tl.name_id
|
||||
WHERE e.evt_type = 'EMPIRE';
|
||||
|
||||
|
|
|
@ -1196,18 +1196,24 @@ GRANT SELECT ON bugs.dump_main_view TO :dbuser;
|
|||
|
||||
|
||||
CREATE VIEW bugs.dump_research_view
|
||||
AS SELECT et.empire_id , et.line_id AS line_id , et.level AS level ,
|
||||
tst.name AS name , et.accumulated AS accumulated
|
||||
FROM emp.technologies et
|
||||
LEFT OUTER JOIN tech.levels tlv ON tlv.line_id = et.line_id AND tlv.level = et.level
|
||||
LEFT OUTER JOIN defs.strings tst ON tst.id = tlv.name_id;
|
||||
AS SELECT r.empire_id , ns.name , r.accumulated , r.priority
|
||||
FROM emp.research r
|
||||
INNER JOIN defs.strings ns ON ns.id = r.technology_id;
|
||||
|
||||
GRANT SELECT ON bugs.dump_research_view TO :dbuser;
|
||||
|
||||
|
||||
CREATE VIEW bugs.dump_technologies_view
|
||||
AS SELECT et.empire_id , ns.name , et.implemented
|
||||
FROM emp.researched_technologies et
|
||||
INNER JOIN defs.strings ns ON ns.id = et.technology_id;
|
||||
|
||||
GRANT SELECT ON bugs.dump_technologies_view TO :dbuser;
|
||||
|
||||
|
||||
CREATE VIEW bugs.dump_planets_view
|
||||
AS SELECT ep.empire_id , ep.planet_id , p.population ,
|
||||
( ph.current / p.population )::REAL AS current_happiness , ph.target AS target_happiness ,
|
||||
ph.current / p.population AS current_happiness , ph.target AS target_happiness ,
|
||||
cq.money AS civ_money , cq.work AS civ_work ,
|
||||
mq.money AS mil_money , mq.work AS mil_work
|
||||
FROM emp.planets ep
|
||||
|
|
|
@ -52,7 +52,7 @@ GRANT EXECUTE ON FUNCTION sys.start_tick( ) TO :dbuser;
|
|||
CREATE OR REPLACE FUNCTION sys.end_tick( IN tick_id BIGINT )
|
||||
RETURNS VOID
|
||||
STRICT VOLATILE
|
||||
SECURITY INVOKER
|
||||
SECURITY DEFINER
|
||||
AS $$
|
||||
BEGIN
|
||||
UPDATE events.events SET status = 'READY'
|
||||
|
@ -62,6 +62,8 @@ BEGIN
|
|||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
GRANT EXECUTE ON FUNCTION sys.end_tick( BIGINT ) TO :dbuser;
|
||||
|
||||
|
||||
|
||||
--
|
||||
|
@ -103,70 +105,78 @@ GRANT EXECUTE ON FUNCTION sys.check_stuck_tick( ) TO :dbuser;
|
|||
|
||||
|
||||
--
|
||||
-- Process game updates
|
||||
-- Prepare game updates
|
||||
--
|
||||
-- Parameters:
|
||||
-- c_tick Current tick
|
||||
-- u_id Current update identifier
|
||||
-- u_type Type of game updates to prepare
|
||||
--
|
||||
-- Returns:
|
||||
-- TRUE if the function must be called again, FALSE otherwise
|
||||
-- has_more TRUE if there are more updates, FALSE otherwise
|
||||
--
|
||||
|
||||
CREATE OR REPLACE FUNCTION sys.process_updates( IN c_tick BIGINT , OUT has_more BOOLEAN )
|
||||
CREATE OR REPLACE FUNCTION sys.prepare_updates( IN u_id BIGINT , IN u_type update_type , OUT has_more BOOLEAN )
|
||||
STRICT VOLATILE
|
||||
SECURITY DEFINER
|
||||
AS $$
|
||||
DECLARE
|
||||
b_size INT;
|
||||
p_utype update_type;
|
||||
utype update_type;
|
||||
uid BIGINT;
|
||||
BEGIN
|
||||
b_size := sys.get_constant( 'game.batchSize' );
|
||||
p_utype := NULL;
|
||||
UPDATE sys.updates SET status = 'PROCESSING'
|
||||
WHERE id IN (
|
||||
SELECT id FROM sys.updates
|
||||
WHERE gu_type = u_type
|
||||
AND last_tick = u_id
|
||||
AND status = 'FUTURE'
|
||||
ORDER BY id
|
||||
LIMIT sys.get_constant( 'game.batchSize' )::BIGINT
|
||||
);
|
||||
|
||||
-- Mark at most b_size entries as being updated
|
||||
FOR uid , utype IN SELECT id , gu_type FROM sys.updates
|
||||
WHERE last_tick = c_tick AND status = 'FUTURE'
|
||||
ORDER BY gu_type LIMIT b_size
|
||||
LOOP
|
||||
IF p_utype IS NULL THEN
|
||||
p_utype := utype;
|
||||
END IF;
|
||||
EXIT WHEN utype <> p_utype;
|
||||
UPDATE sys.updates SET status = 'PROCESSING' WHERE id = uid;
|
||||
END LOOP;
|
||||
|
||||
has_more := p_utype IS NOT NULL;
|
||||
IF has_more THEN
|
||||
-- Execute actual updates
|
||||
EXECUTE 'SELECT sys.process_' || lower( p_utype::TEXT ) || '_updates( $1 )'
|
||||
USING c_tick;
|
||||
UPDATE sys.updates SET status = 'PROCESSED'
|
||||
WHERE status = 'PROCESSING' AND last_tick = c_tick;
|
||||
ELSE
|
||||
-- If nothing was found, we're done
|
||||
PERFORM sys.end_tick( c_tick );
|
||||
END IF;
|
||||
has_more := FOUND;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
GRANT EXECUTE ON FUNCTION sys.process_updates( BIGINT ) TO :dbuser;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
GRANT EXECUTE ON FUNCTION sys.prepare_updates( BIGINT , update_type ) TO :dbuser;
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Execute procedural game updates
|
||||
--
|
||||
-- Parameters:
|
||||
-- c_tick Current tick identifier
|
||||
-- u_type Type of updates to execute
|
||||
--
|
||||
|
||||
CREATE OR REPLACE FUNCTION sys.exec_update_proc( IN c_tick BIGINT , IN u_type update_type )
|
||||
RETURNS VOID
|
||||
STRICT VOLATILE
|
||||
SECURITY DEFINER
|
||||
AS $$
|
||||
BEGIN
|
||||
EXECUTE 'SELECT sys.process_' || lower( u_type::TEXT ) || '_updates( $1 )'
|
||||
USING c_tick;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
GRANT EXECUTE ON FUNCTION sys.exec_update_proc( BIGINT , update_type ) TO :dbuser;
|
||||
|
||||
|
||||
--
|
||||
-- Mark updates as processed
|
||||
--
|
||||
-- Parameters:
|
||||
-- c_tick Current tick identifier
|
||||
-- u_type Type of updates to execute
|
||||
--
|
||||
|
||||
CREATE OR REPLACE FUNCTION sys.updates_processed( IN c_tick BIGINT , IN u_type update_type )
|
||||
RETURNS VOID
|
||||
STRICT VOLATILE
|
||||
SECURITY DEFINER
|
||||
AS $$
|
||||
UPDATE sys.updates SET status = 'PROCESSED'
|
||||
WHERE status = 'PROCESSING'
|
||||
AND last_tick = $1
|
||||
AND gu_type = $2
|
||||
$$ LANGUAGE SQL;
|
||||
|
||||
GRANT EXECUTE ON FUNCTION sys.updates_processed( BIGINT , update_type ) TO :dbuser;
|
||||
|
|
|
@ -14,8 +14,8 @@ CREATE OR REPLACE FUNCTION sys.process_empire_money_updates( c_tick BIGINT )
|
|||
AS $$
|
||||
DECLARE
|
||||
rec RECORD;
|
||||
c_cash REAL;
|
||||
c_debt REAL;
|
||||
c_cash DOUBLE PRECISION;
|
||||
c_debt DOUBLE PRECISION;
|
||||
BEGIN
|
||||
-- Lock empires for update
|
||||
PERFORM e.name_id FROM sys.updates su
|
||||
|
|
|
@ -7,15 +7,22 @@
|
|||
-- --------------------------------------------------------
|
||||
|
||||
|
||||
CREATE OR REPLACE FUNCTION sys.process_empire_research_updates( c_tick BIGINT )
|
||||
|
||||
--
|
||||
-- Prepare the research update
|
||||
--
|
||||
-- Parameters:
|
||||
-- update_id The current update's identifier
|
||||
--
|
||||
-- Returns:
|
||||
-- a set of tech._research_update_input records
|
||||
--
|
||||
|
||||
CREATE OR REPLACE FUNCTION emp.prepare_research_update( update_id BIGINT )
|
||||
RETURNS VOID
|
||||
STRICT VOLATILE
|
||||
SECURITY INVOKER
|
||||
SECURITY DEFINER
|
||||
AS $$
|
||||
DECLARE
|
||||
rec RECORD;
|
||||
r_points REAL;
|
||||
tu_rec RECORD;
|
||||
BEGIN
|
||||
-- Lock empires for update and planets for share
|
||||
PERFORM e.name_id FROM sys.updates su
|
||||
|
@ -23,64 +30,137 @@ BEGIN
|
|||
INNER JOIN emp.empires e ON eu.empire_id = e.name_id
|
||||
INNER JOIN emp.planets ep ON ep.empire_id = e.name_id
|
||||
INNER JOIN verse.planets p ON p.name_id = ep.planet_id
|
||||
WHERE su.last_tick = c_tick AND su.status = 'PROCESSING'
|
||||
WHERE su.last_tick = update_id AND su.status = 'PROCESSING'
|
||||
AND su.gu_type = 'EMPIRE_RESEARCH'
|
||||
FOR UPDATE OF e
|
||||
FOR SHARE OF ep , p;
|
||||
|
||||
-- Process empires
|
||||
FOR rec IN SELECT e.name_id AS id , ( v.status = 'PROCESSED' ) AS on_vacation ,
|
||||
sum( p.population ) AS population
|
||||
FROM sys.updates su
|
||||
INNER JOIN emp.updates eu ON eu.update_id = su.id
|
||||
INNER JOIN emp.empires e ON eu.empire_id = e.name_id
|
||||
INNER JOIN emp.planets ep ON ep.empire_id = e.name_id
|
||||
INNER JOIN verse.planets p ON p.name_id = ep.planet_id
|
||||
INNER JOIN naming.empire_names en ON en.id = e.name_id
|
||||
LEFT OUTER JOIN users.vacations v ON v.account_id = en.owner_id
|
||||
WHERE su.last_tick = c_tick AND su.status = 'PROCESSING'
|
||||
AND su.gu_type = 'EMPIRE_RESEARCH'
|
||||
GROUP BY e.name_id , v.status
|
||||
LOOP
|
||||
-- Insert any missing tech line
|
||||
INSERT INTO emp.technologies ( empire_id , line_id )
|
||||
SELECT rec.id , l.name_id
|
||||
FROM tech.lines l
|
||||
LEFT OUTER JOIN emp.technologies t
|
||||
ON t.line_id = l.name_id AND t.empire_id = rec.id
|
||||
WHERE t.empire_id IS NULL;
|
||||
|
||||
-- Compute research output
|
||||
r_points := rec.population * sys.get_constant( 'game.work.rpPerPopUnit' ) / 1440.0;
|
||||
IF rec.on_vacation
|
||||
THEN
|
||||
r_points := r_points / sys.get_constant( 'vacation.researchDivider' );
|
||||
END IF;
|
||||
|
||||
-- Update technologies where:
|
||||
-- 1) the level actually exists and
|
||||
-- 2) accumulated points haven't reach the level's
|
||||
FOR tu_rec IN SELECT t.line_id AS line_id , t.accumulated AS accumulated ,
|
||||
l.points AS points , ( l.points - t.accumulated ) AS diff ,
|
||||
l.id AS level_id
|
||||
FROM emp.technologies t
|
||||
INNER JOIN tech.levels l ON l.line_id = t.line_id
|
||||
AND l.level = t.level AND t.accumulated < l.points
|
||||
WHERE t.empire_id = rec.id
|
||||
FOR UPDATE OF t
|
||||
LOOP
|
||||
UPDATE emp.technologies t SET accumulated = ( CASE
|
||||
WHEN tu_rec.diff <= r_points THEN tu_rec.points
|
||||
ELSE tu_rec.accumulated + r_points
|
||||
END )
|
||||
WHERE t.line_id = tu_rec.line_id AND t.empire_id = rec.id;
|
||||
|
||||
-- Send message
|
||||
IF tu_rec.diff <= r_points
|
||||
THEN
|
||||
PERFORM events.tech_ready_event( rec.id , tu_rec.level_id );
|
||||
END IF;
|
||||
END LOOP;
|
||||
END LOOP;
|
||||
-- Create temporary table for update output and grant INSERT privilege
|
||||
-- to session user.
|
||||
CREATE TEMPORARY TABLE research_update_output(
|
||||
empire_id INT ,
|
||||
technology TEXT ,
|
||||
creation BOOLEAN ,
|
||||
points DOUBLE PRECISION ,
|
||||
priority INT
|
||||
);
|
||||
IF session_user <> current_user THEN
|
||||
EXECUTE 'GRANT INSERT ON research_update_output TO ' || session_user;
|
||||
END IF;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
GRANT EXECUTE ON FUNCTION emp.prepare_research_update( update_id BIGINT ) TO :dbuser;
|
||||
|
||||
|
||||
--
|
||||
-- Research update input views
|
||||
--
|
||||
|
||||
CREATE VIEW emp.rui_inprogress_view
|
||||
AS SELECT su.last_tick AS update_id , er.empire_id , ns.name AS technology ,
|
||||
er.accumulated AS points , er.priority AS priority
|
||||
FROM sys.updates su
|
||||
INNER JOIN emp.updates eu ON eu.update_id = su.id
|
||||
INNER JOIN emp.research er ON er.empire_id = eu.empire_id
|
||||
INNER JOIN defs.strings ns ON ns.id = er.technology_id
|
||||
WHERE su.status = 'PROCESSING'
|
||||
AND su.gu_type = 'EMPIRE_RESEARCH';
|
||||
|
||||
|
||||
CREATE VIEW emp.rui_researched_view
|
||||
AS SELECT su.last_tick AS update_id , er.empire_id , ns.name AS technology ,
|
||||
er.implemented AS implemented
|
||||
FROM sys.updates su
|
||||
INNER JOIN emp.updates eu ON eu.update_id = su.id
|
||||
INNER JOIN emp.researched_technologies er
|
||||
ON er.empire_id = eu.empire_id
|
||||
INNER JOIN defs.strings ns ON ns.id = er.technology_id
|
||||
WHERE su.status = 'PROCESSING'
|
||||
AND su.gu_type = 'EMPIRE_RESEARCH';
|
||||
|
||||
CREATE VIEW emp.research_update_input_view
|
||||
AS SELECT update_id , empire_id , technology ,
|
||||
NULL::BOOLEAN AS implemented , points , priority
|
||||
FROM emp.rui_inprogress_view
|
||||
UNION ALL SELECT update_id , empire_id , technology ,
|
||||
implemented , NULL::DOUBLE PRECISION AS points ,
|
||||
NULL::INT AS priority
|
||||
FROM emp.rui_researched_view;
|
||||
|
||||
GRANT SELECT ON emp.research_update_input_view TO :dbuser;
|
||||
|
||||
|
||||
--
|
||||
-- Research points production view
|
||||
--
|
||||
|
||||
CREATE VIEW emp.research_points_production
|
||||
AS SELECT su.last_tick AS update_id , e.name_id AS empire_id ,
|
||||
( sum( p.population ) * sys.get_constant( 'game.research.perPopUnit' )
|
||||
/ ( sys.get_constant( 'game.updatesPerDay' ) * ( CASE
|
||||
WHEN v.status = 'PROCESSED' THEN
|
||||
sys.get_constant( 'game.research.perPopUnit' )
|
||||
ELSE
|
||||
1.0
|
||||
END ) ) ) AS points
|
||||
FROM sys.updates su
|
||||
INNER JOIN emp.updates eu ON eu.update_id = su.id
|
||||
INNER JOIN emp.empires e ON eu.empire_id = e.name_id
|
||||
INNER JOIN emp.planets ep ON ep.empire_id = e.name_id
|
||||
INNER JOIN verse.planets p ON p.name_id = ep.planet_id
|
||||
INNER JOIN naming.empire_names en ON en.id = e.name_id
|
||||
LEFT OUTER JOIN users.vacations v ON v.account_id = en.owner_id
|
||||
WHERE su.status = 'PROCESSING' AND su.gu_type = 'EMPIRE_RESEARCH'
|
||||
GROUP BY su.last_tick , e.name_id , v.status;
|
||||
|
||||
GRANT SELECT ON emp.research_points_production TO :dbuser;
|
||||
|
||||
|
||||
|
||||
--
|
||||
-- Submit the contents of the research update table
|
||||
--
|
||||
|
||||
CREATE OR REPLACE FUNCTION emp.submit_research_update( )
|
||||
RETURNS VOID
|
||||
STRICT VOLATILE
|
||||
SECURITY DEFINER
|
||||
AS $$
|
||||
BEGIN
|
||||
-- Delete finished research topics
|
||||
DELETE FROM emp.research er
|
||||
USING research_update_output ruo , defs.strings ns
|
||||
WHERE er.empire_id = ruo.empire_id
|
||||
AND er.technology_id = ns.id AND ns.name = ruo.technology
|
||||
AND ruo.points IS NULL;
|
||||
|
||||
-- Insert researched technologies
|
||||
INSERT INTO emp.researched_technologies ( empire_id , technology_id , implemented )
|
||||
SELECT ruo.empire_id , ns.id , FALSE
|
||||
FROM research_update_output ruo
|
||||
INNER JOIN defs.strings ns ON ns.name = ruo.technology
|
||||
WHERE ruo.points IS NULL;
|
||||
|
||||
-- Insert new research topics
|
||||
INSERT INTO emp.research ( empire_id , technology_id , accumulated , priority )
|
||||
SELECT ruo.empire_id , ns.id , ruo.points , ruo.priority
|
||||
FROM research_update_output ruo
|
||||
INNER JOIN defs.strings ns ON ns.name = ruo.technology
|
||||
WHERE ruo.points IS NOT NULL AND ruo.creation;
|
||||
|
||||
-- Update existing research topics
|
||||
UPDATE emp.research er
|
||||
SET accumulated = ruo.points , priority = ruo.priority
|
||||
FROM research_update_output ruo , defs.strings ns
|
||||
WHERE ruo.points IS NOT NULL AND NOT ruo.creation
|
||||
AND ns.name = ruo.technology
|
||||
AND er.technology_id = ns.id
|
||||
AND er.empire_id = ruo.empire_id;
|
||||
|
||||
-- Drop temporary table
|
||||
DROP TABLE research_update_output;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
GRANT EXECUTE ON FUNCTION emp.submit_research_update( ) TO :dbuser;
|
||||
|
|
|
@ -15,11 +15,11 @@ CREATE OR REPLACE FUNCTION sys.process_empire_debt_updates( c_tick BIGINT )
|
|||
SECURITY INVOKER
|
||||
AS $$
|
||||
DECLARE
|
||||
fleet_dr REAL;
|
||||
bld_dr REAL;
|
||||
fleet_dr DOUBLE PRECISION;
|
||||
bld_dr DOUBLE PRECISION;
|
||||
empire INT;
|
||||
debt REAL;
|
||||
upkeep REAL;
|
||||
debt DOUBLE PRECISION;
|
||||
upkeep DOUBLE PRECISION;
|
||||
BEGIN
|
||||
fleet_dr := sys.get_constant( 'game.debt.fleet');
|
||||
bld_dr := sys.get_constant( 'game.debt.buildings');
|
||||
|
|
|
@ -42,17 +42,17 @@ CREATE OR REPLACE FUNCTION sys.process_planet_battle_main_updates( c_tick BIGINT
|
|||
AS $$
|
||||
DECLARE
|
||||
ttfi INT;
|
||||
initi REAL;
|
||||
dbonus REAL;
|
||||
dmg REAL;
|
||||
rdmg REAL;
|
||||
initi DOUBLE PRECISION;
|
||||
dbonus DOUBLE PRECISION;
|
||||
dmg DOUBLE PRECISION;
|
||||
rdmg DOUBLE PRECISION;
|
||||
rec RECORD;
|
||||
a_power BIGINT;
|
||||
d_power BIGINT;
|
||||
p_power BIGINT;
|
||||
bmod REAL;
|
||||
a_dmg REAL;
|
||||
d_dmg REAL;
|
||||
bmod DOUBLE PRECISION;
|
||||
a_dmg DOUBLE PRECISION;
|
||||
d_dmg DOUBLE PRECISION;
|
||||
BEGIN
|
||||
ttfi := floor( sys.get_constant( 'game.battle.timeToFullIntensity' ) )::INT;
|
||||
initi := sys.get_constant( 'game.battle.initialIntensity' );
|
||||
|
@ -61,7 +61,7 @@ BEGIN
|
|||
rdmg := sys.get_constant( 'game.battle.randomDamage' );
|
||||
|
||||
FOR rec IN SELECT b.id AS battle , b.first_tick AS first_tick ,
|
||||
b.location_id AS location , ( ph.current / p.population )::REAL AS happiness
|
||||
b.location_id AS location , ph.current / p.population AS happiness
|
||||
FROM sys.updates su
|
||||
INNER JOIN verse.updates vu ON vu.update_id = su.id
|
||||
INNER JOIN verse.planets p ON vu.planet_id = p.name_id
|
||||
|
|
|
@ -14,20 +14,20 @@ CREATE OR REPLACE FUNCTION sys.process_planet_construction_updates( c_tick BIGIN
|
|||
AS $$
|
||||
DECLARE
|
||||
rec RECORD;
|
||||
wu_per_pop REAL;
|
||||
dest_work REAL;
|
||||
dest_rec REAL;
|
||||
wu_per_pop DOUBLE PRECISION;
|
||||
dest_work DOUBLE PRECISION;
|
||||
dest_rec DOUBLE PRECISION;
|
||||
cur_empire INT;
|
||||
cur_cash REAL;
|
||||
cur_cash DOUBLE PRECISION;
|
||||
cur_planet INT;
|
||||
p_finished BOOLEAN;
|
||||
cur_wus REAL;
|
||||
cur_acc_c REAL;
|
||||
cur_wus DOUBLE PRECISION;
|
||||
cur_acc_c DOUBLE PRECISION;
|
||||
n_found INT;
|
||||
n_removed INT;
|
||||
i_work REAL;
|
||||
i_cost REAL;
|
||||
can_do REAL;
|
||||
i_work DOUBLE PRECISION;
|
||||
i_cost DOUBLE PRECISION;
|
||||
can_do DOUBLE PRECISION;
|
||||
must_do INT;
|
||||
BEGIN
|
||||
-- Get constants
|
||||
|
@ -39,7 +39,7 @@ BEGIN
|
|||
cur_empire := NULL;
|
||||
cur_planet := NULL;
|
||||
FOR rec IN SELECT p.name_id AS id , p.population AS pop ,
|
||||
( ph.current / p.population )::REAL AS happiness ,
|
||||
ph.current / p.population AS happiness ,
|
||||
e.name_id AS owner , e.cash AS cash ,
|
||||
q.money AS acc_cash , q.work AS acc_work ,
|
||||
qi.queue_order AS qorder , qi.amount AS amount ,
|
||||
|
@ -100,10 +100,7 @@ BEGIN
|
|||
IF cur_planet IS NULL THEN
|
||||
cur_planet := rec.id;
|
||||
cur_cash := cur_cash + rec.acc_cash;
|
||||
cur_wus := rec.acc_work + verse.adjust_production(
|
||||
( rec.pop * wu_per_pop )::REAL ,
|
||||
rec.happiness
|
||||
);
|
||||
cur_wus := rec.acc_work + verse.adjust_production( rec.pop * wu_per_pop , rec.happiness );
|
||||
n_found := 1;
|
||||
n_removed := 0;
|
||||
cur_acc_c := 0;
|
||||
|
|
|
@ -15,14 +15,14 @@ CREATE OR REPLACE FUNCTION sys.process_planet_military_updates( c_tick BIGINT )
|
|||
DECLARE
|
||||
rec RECORD;
|
||||
cur_empire INT;
|
||||
cur_cash REAL;
|
||||
cur_cash DOUBLE PRECISION;
|
||||
cur_planet INT;
|
||||
p_finished BOOLEAN;
|
||||
cur_wus REAL;
|
||||
cur_acc_c REAL;
|
||||
cur_wus DOUBLE PRECISION;
|
||||
cur_acc_c DOUBLE PRECISION;
|
||||
n_found INT;
|
||||
n_removed INT;
|
||||
can_do REAL;
|
||||
can_do DOUBLE PRECISION;
|
||||
must_do INT;
|
||||
fl_id BIGINT;
|
||||
BEGIN
|
||||
|
@ -38,7 +38,7 @@ BEGIN
|
|||
cur_empire := NULL;
|
||||
cur_planet := NULL;
|
||||
FOR rec IN SELECT p.name_id AS id ,
|
||||
( ph.current / p.population )::REAL AS happiness ,
|
||||
ph.current / p.population AS happiness ,
|
||||
e.name_id AS owner , e.cash AS cash ,
|
||||
q.money AS acc_cash , q.work AS acc_work ,
|
||||
qi.queue_order AS qorder , qi.amount AS amount ,
|
||||
|
|
|
@ -14,16 +14,16 @@ CREATE OR REPLACE FUNCTION sys.process_planet_population_updates( c_tick BIGINT
|
|||
AS $$
|
||||
DECLARE
|
||||
rec RECORD;
|
||||
rel_ch REAL;
|
||||
abs_ch REAL;
|
||||
g_fact REAL;
|
||||
gf_inc REAL;
|
||||
n_happ REAL;
|
||||
t_happ REAL;
|
||||
temp REAL;
|
||||
growth REAL;
|
||||
workers REAL;
|
||||
str_thr REAL;
|
||||
rel_ch DOUBLE PRECISION;
|
||||
abs_ch DOUBLE PRECISION;
|
||||
g_fact DOUBLE PRECISION;
|
||||
gf_inc DOUBLE PRECISION;
|
||||
n_happ DOUBLE PRECISION;
|
||||
t_happ DOUBLE PRECISION;
|
||||
temp DOUBLE PRECISION;
|
||||
growth DOUBLE PRECISION;
|
||||
workers DOUBLE PRECISION;
|
||||
str_thr DOUBLE PRECISION;
|
||||
BEGIN
|
||||
-- Get constants
|
||||
rel_ch := sys.get_constant( 'game.happiness.relativeChange' );
|
||||
|
@ -35,7 +35,7 @@ BEGIN
|
|||
-- Process planets
|
||||
FOR rec IN SELECT p.name_id AS id , p.population AS pop ,
|
||||
ph.target AS target , ph.current AS happy_pop ,
|
||||
( ph.current / p.population )::REAL AS current
|
||||
ph.current / p.population AS current
|
||||
FROM sys.updates su
|
||||
INNER JOIN verse.updates vu ON vu.update_id = su.id
|
||||
INNER JOIN verse.planets p ON vu.planet_id = p.name_id
|
||||
|
|
|
@ -14,10 +14,10 @@ CREATE OR REPLACE FUNCTION sys.process_planet_money_updates( c_tick BIGINT )
|
|||
AS $$
|
||||
DECLARE
|
||||
rec RECORD;
|
||||
incme REAL;
|
||||
incme DOUBLE PRECISION;
|
||||
BEGIN
|
||||
FOR rec IN SELECT p.name_id AS id , p.population AS pop ,
|
||||
( ph.current / p.population )::REAL AS happiness ,
|
||||
ph.current / p.population AS happiness ,
|
||||
( ea.planet_id IS NULL ) AS produces_income
|
||||
FROM sys.updates su
|
||||
INNER JOIN verse.updates vu ON vu.update_id = su.id
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
<parent>
|
||||
<artifactId>legacyworlds-server</artifactId>
|
||||
<groupId>com.deepclone.lw</groupId>
|
||||
<version>5.99.1</version>
|
||||
<version>5.99.2</version>
|
||||
</parent>
|
||||
|
||||
<groupId>com.deepclone.lw</groupId>
|
||||
<artifactId>legacyworlds-server-data</artifactId>
|
||||
<name>Legacy Worlds server data</name>
|
||||
<version>5.99.1</version>
|
||||
<version>5.99.2</version>
|
||||
<description>This package contains all data access classes for the Legacy Worlds server.</description>
|
||||
|
||||
<dependencies>
|
||||
|
|
|
@ -1,66 +0,0 @@
|
|||
package com.deepclone.lw.sqld.game;
|
||||
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
|
||||
public class EmpireTechLine
|
||||
{
|
||||
private int id;
|
||||
|
||||
private String name;
|
||||
|
||||
private String description;
|
||||
|
||||
private List< EmpireTechnology > technologies = new LinkedList< EmpireTechnology >( );
|
||||
|
||||
|
||||
public int getId( )
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
public void setId( int id )
|
||||
{
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
|
||||
public String getName( )
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
public void setName( String name )
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
|
||||
public String getDescription( )
|
||||
{
|
||||
return description;
|
||||
}
|
||||
|
||||
|
||||
public void setDescription( String description )
|
||||
{
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
|
||||
public List< EmpireTechnology > getTechnologies( )
|
||||
{
|
||||
return technologies;
|
||||
}
|
||||
|
||||
|
||||
public void addTechnology( EmpireTechnology eTech )
|
||||
{
|
||||
this.technologies.add( eTech );
|
||||
}
|
||||
}
|
|
@ -1,90 +0,0 @@
|
|||
package com.deepclone.lw.sqld.game;
|
||||
|
||||
|
||||
public class EmpireTechnology
|
||||
{
|
||||
private int line;
|
||||
|
||||
private String name;
|
||||
|
||||
private String description;
|
||||
|
||||
private boolean implemented;
|
||||
|
||||
private int progress;
|
||||
|
||||
private int cost;
|
||||
|
||||
|
||||
public int getLine( )
|
||||
{
|
||||
return line;
|
||||
}
|
||||
|
||||
|
||||
public void setLine( int line )
|
||||
{
|
||||
this.line = line;
|
||||
}
|
||||
|
||||
|
||||
public String getName( )
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
public void setName( String name )
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
|
||||
public String getDescription( )
|
||||
{
|
||||
return description;
|
||||
}
|
||||
|
||||
|
||||
public void setDescription( String description )
|
||||
{
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
|
||||
public boolean isImplemented( )
|
||||
{
|
||||
return implemented;
|
||||
}
|
||||
|
||||
|
||||
public void setImplemented( boolean implemented )
|
||||
{
|
||||
this.implemented = implemented;
|
||||
}
|
||||
|
||||
|
||||
public int getProgress( )
|
||||
{
|
||||
return progress;
|
||||
}
|
||||
|
||||
|
||||
public void setProgress( int progress )
|
||||
{
|
||||
this.progress = progress;
|
||||
}
|
||||
|
||||
|
||||
public int getCost( )
|
||||
{
|
||||
return cost;
|
||||
}
|
||||
|
||||
|
||||
public void setCost( int cost )
|
||||
{
|
||||
this.cost = cost;
|
||||
}
|
||||
|
||||
}
|
|
@ -4,24 +4,28 @@ package com.deepclone.lw.sqld.game;
|
|||
public class GeneralInformation
|
||||
{
|
||||
|
||||
private Character status;
|
||||
private final Character status;
|
||||
|
||||
private String name;
|
||||
private final String name;
|
||||
|
||||
private String tag;
|
||||
private final String tag;
|
||||
|
||||
private long cash;
|
||||
private final String language;
|
||||
|
||||
private long nextTick;
|
||||
private final long cash;
|
||||
|
||||
private int accountId;
|
||||
private final long nextTick;
|
||||
|
||||
private final int accountId;
|
||||
|
||||
|
||||
public GeneralInformation( Character status , String name , String tag , long cash , long nextTick , int accountId )
|
||||
public GeneralInformation( Character status , String name , String tag , String language , long cash ,
|
||||
long nextTick , int accountId )
|
||||
{
|
||||
this.status = status;
|
||||
this.name = name;
|
||||
this.tag = tag;
|
||||
this.language = language;
|
||||
this.cash = cash;
|
||||
this.nextTick = nextTick;
|
||||
this.accountId = accountId;
|
||||
|
@ -46,6 +50,12 @@ public class GeneralInformation
|
|||
}
|
||||
|
||||
|
||||
public String getLanguage( )
|
||||
{
|
||||
return language;
|
||||
}
|
||||
|
||||
|
||||
public long getCash( )
|
||||
{
|
||||
return cash;
|
||||
|
|
|
@ -0,0 +1,169 @@
|
|||
package com.deepclone.lw.sqld.game.techs;
|
||||
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A technology category for the technology graph.
|
||||
*
|
||||
* @author tseeker
|
||||
*/
|
||||
public class Category
|
||||
{
|
||||
|
||||
/** The string identifier of the category's name */
|
||||
private final String name;
|
||||
|
||||
/** The string identifier of the category's description */
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* Map of the technologies belonging to the category, with their name string identifier as the
|
||||
* index.
|
||||
*/
|
||||
private Map< String , Technology > technologies;
|
||||
|
||||
|
||||
/**
|
||||
* Initialise a category's representation.
|
||||
*
|
||||
* @param name
|
||||
* string identifier of the category's name
|
||||
* @param description
|
||||
* string identifier of the category's description
|
||||
*/
|
||||
Category( String name , String description )
|
||||
{
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.technologies = new HashMap< String , Technology >( );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copy a category.
|
||||
*
|
||||
* @param cat
|
||||
* the category being copied.
|
||||
*/
|
||||
Category( Category cat )
|
||||
{
|
||||
this.name = cat.name;
|
||||
this.description = cat.description;
|
||||
this.technologies = new HashMap< String , Technology >( );
|
||||
for ( Technology tech : cat.technologies.values( ) ) {
|
||||
this.technologies.put( tech.getName( ) , new Technology( tech ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** @return the string identifier of the category's name */
|
||||
public String getName( )
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
/** @return the string identifier of the category's description */
|
||||
public String getDescription( )
|
||||
{
|
||||
return description;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update the category's description.
|
||||
*
|
||||
* @param description
|
||||
* the string identifier of the category's description
|
||||
*/
|
||||
void setDescription( String description )
|
||||
{
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* List technologies in the category.
|
||||
*
|
||||
* @return an alphabetically ordered list of technology names
|
||||
*/
|
||||
public List< String > getTechnologies( )
|
||||
{
|
||||
List< String > names = new LinkedList< String >( this.technologies.keySet( ) );
|
||||
Collections.sort( names );
|
||||
return names;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Find technology objects stored in the category.
|
||||
*
|
||||
* @return the list of technology objects.
|
||||
*/
|
||||
Collection< Technology > getTechnologyObjects( )
|
||||
{
|
||||
return this.technologies.values( );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a new technology to the category's record.
|
||||
*
|
||||
* @param name
|
||||
* string identifier of the technology's name
|
||||
* @param description
|
||||
* string identifier of the technology's description
|
||||
* @param points
|
||||
* research points required to implement the technology
|
||||
* @param cost
|
||||
* cost of implementing the technology
|
||||
* @return the newly created {@link Technology} instance
|
||||
*/
|
||||
Technology addTechnology( String name , String description , int points , int cost )
|
||||
{
|
||||
Technology tech = new Technology( this , name , description , points , cost );
|
||||
this.technologies.put( name , tech );
|
||||
return tech;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Move a technology from another category into the current category.
|
||||
*
|
||||
* @param tech
|
||||
* the technology to move
|
||||
*/
|
||||
void addExistingTechnology( Technology tech )
|
||||
{
|
||||
Category previous = tech.getCategory( );
|
||||
if ( previous.name.equals( this.name ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
previous.technologies.remove( tech.getName( ) );
|
||||
this.technologies.put( tech.getName( ) , tech );
|
||||
tech.setCategory( this );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove a technology from the category. This method is meant to be called from
|
||||
* {@link Technology#delete()}.
|
||||
*
|
||||
* @param technology
|
||||
* the technology to remove.
|
||||
*/
|
||||
void removeTechnology( Technology technology )
|
||||
{
|
||||
this.technologies.remove( technology );
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,175 @@
|
|||
package com.deepclone.lw.sqld.game.techs;
|
||||
|
||||
|
||||
/**
|
||||
* Empire technology and research record.
|
||||
*
|
||||
* @author tseeker
|
||||
*/
|
||||
public class EmpireTechnology
|
||||
{
|
||||
|
||||
/** Numeric identifier used for unknown technologies */
|
||||
private final Integer numericId;
|
||||
|
||||
/** Technology string name */
|
||||
private final String identifier;
|
||||
|
||||
/** Status of the technology */
|
||||
private final ResearchStatus status;
|
||||
|
||||
/** Whether additional details should be provided */
|
||||
private final boolean detailed;
|
||||
|
||||
/** Research completion percentage */
|
||||
private final Integer percentage;
|
||||
|
||||
/** Research priority */
|
||||
private final Integer priority;
|
||||
|
||||
/** Implementation cost */
|
||||
private final Integer cost;
|
||||
|
||||
|
||||
/**
|
||||
* Initialise the record for an implemented technology.
|
||||
*
|
||||
* @param identifier
|
||||
* string identifier of the technology's name.
|
||||
*/
|
||||
public EmpireTechnology( String identifier )
|
||||
{
|
||||
this.numericId = null;
|
||||
this.identifier = identifier;
|
||||
this.status = ResearchStatus.IMPLEMENTED;
|
||||
this.detailed = true;
|
||||
this.percentage = null;
|
||||
this.priority = null;
|
||||
this.cost = null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialise the record for an unidentified technology being researched.
|
||||
*
|
||||
* @param numericId
|
||||
* numeric identifier of the technology
|
||||
* @param identifier
|
||||
* string identifier of the technology's name
|
||||
* @param percentage
|
||||
* research completion percentage
|
||||
* @param priority
|
||||
* research priority
|
||||
*/
|
||||
public EmpireTechnology( int numericId , String identifier , int percentage , int priority )
|
||||
{
|
||||
this.numericId = numericId;
|
||||
this.identifier = identifier;
|
||||
this.status = ResearchStatus.IN_PROGRESS;
|
||||
this.detailed = false;
|
||||
this.percentage = percentage;
|
||||
this.priority = priority;
|
||||
this.cost = null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialise the record for an identified technology being researched.
|
||||
*
|
||||
* @param identifier
|
||||
* string identifier of the technology's name
|
||||
* @param percentage
|
||||
* research completion percentage
|
||||
* @param priority
|
||||
* research priority
|
||||
*/
|
||||
public EmpireTechnology( String identifier , int percentage , int priority )
|
||||
{
|
||||
this.numericId = null;
|
||||
this.identifier = identifier;
|
||||
this.status = ResearchStatus.IN_PROGRESS;
|
||||
this.detailed = true;
|
||||
this.percentage = percentage;
|
||||
this.priority = priority;
|
||||
this.cost = null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialise the record for a researched technology.
|
||||
*
|
||||
* @param identifier
|
||||
* string identifier of the technology's name
|
||||
* @param cost
|
||||
* implementation cost
|
||||
*/
|
||||
public EmpireTechnology( String identifier , int cost )
|
||||
{
|
||||
this.numericId = null;
|
||||
this.identifier = identifier;
|
||||
this.status = ResearchStatus.RESEARCHED;
|
||||
this.detailed = true;
|
||||
this.percentage = null;
|
||||
this.priority = null;
|
||||
this.cost = cost;
|
||||
}
|
||||
|
||||
|
||||
/** @return the numeric identifier used for unknown technologies */
|
||||
public Integer getNumericId( )
|
||||
{
|
||||
return this.numericId;
|
||||
}
|
||||
|
||||
|
||||
/** @return the string identifier of the technology's name */
|
||||
public String getIdentifier( )
|
||||
{
|
||||
return this.identifier;
|
||||
}
|
||||
|
||||
|
||||
/** @return the technology's research status */
|
||||
public ResearchStatus getStatus( )
|
||||
{
|
||||
return this.status;
|
||||
}
|
||||
|
||||
|
||||
/** @return whether details are to be displayed */
|
||||
public boolean isDetailed( )
|
||||
{
|
||||
return this.detailed;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the technology's research completion percentage or <code>null</code> if the
|
||||
* technology is not under research.
|
||||
*/
|
||||
public Integer getPercentage( )
|
||||
{
|
||||
return this.percentage;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the technology's research priority or <code>null</code> if the technology is not under
|
||||
* research
|
||||
*/
|
||||
public Integer getPriority( )
|
||||
{
|
||||
return priority;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the technology's implementation cost, or <code>null</code> if the technology is
|
||||
* either implemented or being researched.
|
||||
*/
|
||||
public Integer getCost( )
|
||||
{
|
||||
return this.cost;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package com.deepclone.lw.sqld.game.techs;
|
||||
|
||||
|
||||
/**
|
||||
* Research status for empire technologies.
|
||||
*
|
||||
* @author tseeker
|
||||
*/
|
||||
public enum ResearchStatus {
|
||||
|
||||
/** Research in progress */
|
||||
IN_PROGRESS ,
|
||||
|
||||
/** Technology researched but unimplemented */
|
||||
RESEARCHED ,
|
||||
|
||||
/** Technology researched and implemented */
|
||||
IMPLEMENTED
|
||||
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
package com.deepclone.lw.sqld.game.techs;
|
||||
|
||||
|
||||
/**
|
||||
* Record used as the input of the research update handler.
|
||||
*
|
||||
* @author tseeker
|
||||
*/
|
||||
public class ResearchUpdateInput
|
||||
{
|
||||
|
||||
private final int empireId;
|
||||
private final String technology;
|
||||
private final ResearchStatus status;
|
||||
private final Double points;
|
||||
private final Integer priority;
|
||||
|
||||
|
||||
/**
|
||||
* Initialise the record for a researched technology
|
||||
*
|
||||
* @param empireId
|
||||
* empire identifier
|
||||
* @param technology
|
||||
* technology name
|
||||
* @param implemented
|
||||
* whether the technology has been implemented or not
|
||||
*/
|
||||
public ResearchUpdateInput( int empireId , String technology , boolean implemented )
|
||||
{
|
||||
this.empireId = empireId;
|
||||
this.technology = technology;
|
||||
this.status = implemented ? ResearchStatus.IMPLEMENTED : ResearchStatus.RESEARCHED;
|
||||
this.points = null;
|
||||
this.priority = null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialise the record for an ongoing research process.
|
||||
*
|
||||
* @param empireId
|
||||
* empire identifier
|
||||
* @param technology
|
||||
* technology name
|
||||
* @param points
|
||||
* accumulated research points
|
||||
* @param priority
|
||||
* current priority
|
||||
*/
|
||||
public ResearchUpdateInput( int empireId , String technology , double points , int priority )
|
||||
{
|
||||
this.empireId = empireId;
|
||||
this.technology = technology;
|
||||
this.status = ResearchStatus.IN_PROGRESS;
|
||||
this.points = points;
|
||||
this.priority = priority;
|
||||
}
|
||||
|
||||
|
||||
public int getEmpireId( )
|
||||
{
|
||||
return this.empireId;
|
||||
}
|
||||
|
||||
|
||||
public String getTechnology( )
|
||||
{
|
||||
return this.technology;
|
||||
}
|
||||
|
||||
|
||||
public ResearchStatus getStatus( )
|
||||
{
|
||||
return this.status;
|
||||
}
|
||||
|
||||
|
||||
public Double getPoints( )
|
||||
{
|
||||
return this.points;
|
||||
}
|
||||
|
||||
|
||||
public Integer getPriority( )
|
||||
{
|
||||
return this.priority;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
package com.deepclone.lw.sqld.game.techs;
|
||||
|
||||
|
||||
/**
|
||||
* Record that describes the output of the research update.
|
||||
*
|
||||
* @author tseeker
|
||||
*/
|
||||
public class ResearchUpdateOutput
|
||||
{
|
||||
|
||||
private final int empireId;
|
||||
private final String technology;
|
||||
private final Boolean creation;
|
||||
private Double points;
|
||||
private Integer priority;
|
||||
|
||||
|
||||
/**
|
||||
* Create a research update output record which indicates that a technology has been fully
|
||||
* researched.
|
||||
*
|
||||
* @param empireId
|
||||
* the empire's identifier
|
||||
* @param technology
|
||||
* the name of the technology
|
||||
*/
|
||||
public ResearchUpdateOutput( int empireId , String technology )
|
||||
{
|
||||
this.empireId = empireId;
|
||||
this.technology = technology;
|
||||
this.creation = null;
|
||||
this.points = null;
|
||||
this.priority = null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a research update output record which indicates that a research progress row should be
|
||||
* either created or updated.
|
||||
*
|
||||
* @param empireId
|
||||
* the empire's identifier
|
||||
* @param technology
|
||||
* the name of the technology
|
||||
* @param creation
|
||||
* whether the research process for this technology is a new one
|
||||
* @param points
|
||||
* amount of research points accumulated in the record
|
||||
* @param priority
|
||||
* priority of the research process
|
||||
*/
|
||||
public ResearchUpdateOutput( int empireId , String technology , boolean creation , double points , int priority )
|
||||
{
|
||||
this.empireId = empireId;
|
||||
this.technology = technology;
|
||||
this.creation = creation;
|
||||
this.points = points;
|
||||
this.priority = priority;
|
||||
}
|
||||
|
||||
|
||||
/** @return the empire's identifier */
|
||||
public int getEmpireId( )
|
||||
{
|
||||
return empireId;
|
||||
}
|
||||
|
||||
|
||||
/** @return the name of the technology */
|
||||
public String getTechnology( )
|
||||
{
|
||||
return technology;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return whether the research process for this technology is a new one, or <code>null</code>
|
||||
* if the record is about a fully researched technology
|
||||
*/
|
||||
public Boolean getCreation( )
|
||||
{
|
||||
return creation;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the amount of accumulated research points for the research process or
|
||||
* <code>null</code> if the record is about a fully researched technology
|
||||
*/
|
||||
public Double getPoints( )
|
||||
{
|
||||
return points;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update the accumulated research points
|
||||
*
|
||||
* @param points
|
||||
* the amount of points to add
|
||||
*/
|
||||
public void addPoints( Double points )
|
||||
{
|
||||
this.points = this.points + points;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the research topic's priority or <code>null</code> if the record is about a fully
|
||||
* researched technology
|
||||
*/
|
||||
public Integer getPriority( )
|
||||
{
|
||||
return priority;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the priority of the research
|
||||
*
|
||||
* @param priority
|
||||
* the new priority
|
||||
*/
|
||||
public void setPriority( int priority )
|
||||
{
|
||||
if ( this.priority == null ) {
|
||||
throw new IllegalArgumentException( "trying to set priority on known technology " + this.technology
|
||||
+ " for empire #" + this.empireId );
|
||||
}
|
||||
this.priority = priority;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,366 @@
|
|||
package com.deepclone.lw.sqld.game.techs;
|
||||
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.deepclone.lw.sqld.game.techs.TechGraphException.Code;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Representation of the whole technology graph.
|
||||
*/
|
||||
public class TechGraph
|
||||
{
|
||||
|
||||
/** List of all technologies */
|
||||
private List< Technology > technologies;
|
||||
|
||||
/** Technologies indexed by name */
|
||||
private Map< String , Technology > techsByName;
|
||||
|
||||
/** Technology categories indexed by name */
|
||||
private Map< String , Category > categoriesByName;
|
||||
|
||||
|
||||
/** Initialise an empty tech graph */
|
||||
public TechGraph( )
|
||||
{
|
||||
this.technologies = new LinkedList< Technology >( );
|
||||
this.techsByName = new HashMap< String , Technology >( );
|
||||
this.categoriesByName = new HashMap< String , Category >( );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a copy of an existing tech graph
|
||||
*
|
||||
* @param graph
|
||||
* the original tech graph
|
||||
*/
|
||||
public TechGraph( TechGraph graph )
|
||||
{
|
||||
this.technologies = new LinkedList< Technology >( );
|
||||
this.techsByName = new HashMap< String , Technology >( );
|
||||
this.categoriesByName = new HashMap< String , Category >( );
|
||||
|
||||
// Copy category and technology fields
|
||||
for ( Category cat : graph.categoriesByName.values( ) ) {
|
||||
Category copyCat = new Category( cat );
|
||||
this.categoriesByName.put( cat.getName( ) , copyCat );
|
||||
|
||||
for ( Technology tech : copyCat.getTechnologyObjects( ) ) {
|
||||
this.technologies.add( tech );
|
||||
this.techsByName.put( tech.getName( ) , tech );
|
||||
}
|
||||
}
|
||||
|
||||
// Copy dependencies
|
||||
for ( Technology tech : this.technologies ) {
|
||||
for ( String depName : graph.techsByName.get( tech.getName( ) ).getDependencies( ) ) {
|
||||
tech.addDependency( this.techsByName.get( depName ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Register a new technology category.
|
||||
*
|
||||
* @param name
|
||||
* the name of the new category
|
||||
* @param description
|
||||
* the description of the new category
|
||||
*
|
||||
* @throws TechGraphException
|
||||
* with {@link TechGraphException.Code#DUPLICATE_CATEGORY} if the category already
|
||||
* exists.
|
||||
*/
|
||||
public void addCategory( String name , String description )
|
||||
throws TechGraphException
|
||||
{
|
||||
if ( this.categoriesByName.containsKey( name ) ) {
|
||||
throw new TechGraphException( Code.DUPLICATE_CATEGORY );
|
||||
}
|
||||
this.categoriesByName.put( name , new Category( name , description ) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* List all categories in alphabetic order
|
||||
*
|
||||
* @return the list of category names
|
||||
*/
|
||||
public List< String > getCategories( )
|
||||
{
|
||||
List< String > result = new LinkedList< String >( this.categoriesByName.keySet( ) );
|
||||
Collections.sort( result );
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Access a registered category.
|
||||
*
|
||||
* @param name
|
||||
* the name of the category
|
||||
*
|
||||
* @return the category's record
|
||||
*
|
||||
* @throws TechGraphException
|
||||
* with {@link TechGraphException.Code#MISSING_CATEGORY} if the category does not
|
||||
* exist.
|
||||
*/
|
||||
public Category getCategory( String name )
|
||||
throws TechGraphException
|
||||
{
|
||||
Category cat = this.categoriesByName.get( name );
|
||||
if ( cat == null ) {
|
||||
throw new TechGraphException( Code.MISSING_CATEGORY , name );
|
||||
}
|
||||
return cat;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set a category's description.
|
||||
*
|
||||
* @param name
|
||||
* the name of the category
|
||||
*
|
||||
* @param description
|
||||
* the string identifier of the new description
|
||||
*
|
||||
* @throws TechGraphException
|
||||
* with {@link TechGraphException.Code#MISSING_CATEGORY} if the category does not
|
||||
* exist.
|
||||
*/
|
||||
public void updateCategory( String name , String description )
|
||||
throws TechGraphException
|
||||
{
|
||||
this.getCategory( name ).setDescription( description );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Delete a category from the graph's information.
|
||||
*
|
||||
* @param name
|
||||
* the name of the category
|
||||
*
|
||||
* @throws TechGraphException
|
||||
* with {@link TechGraphException.Code#MISSING_CATEGORY} if the category does not
|
||||
* exist, or with {@link TechGraphException.Code#DEPENDENCY_ERROR} if the category
|
||||
* contains technologies.
|
||||
*/
|
||||
public void deleteCategory( String name )
|
||||
throws TechGraphException
|
||||
{
|
||||
Category cat = this.getCategory( name );
|
||||
if ( !cat.getTechnologies( ).isEmpty( ) ) {
|
||||
throw new TechGraphException( Code.DEPENDENCY_ERROR );
|
||||
}
|
||||
this.categoriesByName.remove( name );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Register a technology into the graph.
|
||||
*
|
||||
* @param category
|
||||
* the name of the category the new technology will be added to
|
||||
* @param name
|
||||
* the string identifier of name of the new technology
|
||||
* @param description
|
||||
* the string identifier of description of the new technology
|
||||
* @param points
|
||||
* the amount of research points required to research the technology
|
||||
* @param cost
|
||||
* the monetary cost of implementing the technology
|
||||
*
|
||||
* @throws TechGraphException
|
||||
* with {@link TechGraphException.Code#MISSING_CATEGORY} if the category does not
|
||||
* exist, or with {@link TechGraphException.Code#DUPLICATE_TECHNOLOGY} if the
|
||||
* technology already exists.
|
||||
*/
|
||||
public void addTechnology( String category , String name , String description , int points , int cost )
|
||||
throws TechGraphException
|
||||
{
|
||||
if ( this.techsByName.containsKey( name ) ) {
|
||||
throw new TechGraphException( Code.DUPLICATE_TECHNOLOGY , name );
|
||||
}
|
||||
|
||||
Technology tech = this.getCategory( category ).addTechnology( name , description , points , cost );
|
||||
this.technologies.add( tech );
|
||||
this.techsByName.put( name , tech );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Access a technology's record.
|
||||
*
|
||||
* @param technology
|
||||
* the name of the technology
|
||||
*
|
||||
* @return the {@link Technology} instance describing the technology
|
||||
*
|
||||
* @throws TechGraphException
|
||||
* with {@link TechGraphException.Code#MISSING_TECHNOLOGY} if the technology does
|
||||
* not exist
|
||||
*/
|
||||
public Technology getTechnology( String technology )
|
||||
throws TechGraphException
|
||||
{
|
||||
Technology tech = this.techsByName.get( technology );
|
||||
if ( tech == null ) {
|
||||
throw new TechGraphException( Code.MISSING_TECHNOLOGY , technology );
|
||||
}
|
||||
return tech;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update a technology's record.
|
||||
*
|
||||
* @param technology
|
||||
* the technology's name
|
||||
* @param description
|
||||
* the string identifier of the new description, or <code>null</code> if the
|
||||
* description must be kept.
|
||||
* @param points
|
||||
* the new amount of research points for the technology, or <code>null</code> if the
|
||||
* research points are not to be modified.
|
||||
* @param cost
|
||||
* the new implementation cost of the technology, or <code>null</code> if the cost
|
||||
* does not change.
|
||||
*
|
||||
* @throws TechGraphException
|
||||
* with {@link TechGraphException.Code#MISSING_TECHNOLOGY} if the technology does
|
||||
* not exist
|
||||
*/
|
||||
public void updateTechnology( String technology , String description , Integer points , Integer cost )
|
||||
throws TechGraphException
|
||||
{
|
||||
Technology tech = this.getTechnology( technology );
|
||||
if ( description != null ) {
|
||||
tech.setDescription( description );
|
||||
}
|
||||
if ( points != null ) {
|
||||
tech.setPoints( points );
|
||||
}
|
||||
if ( cost != null ) {
|
||||
tech.setCost( cost );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Modify the category of a technology.
|
||||
*
|
||||
* @param technology
|
||||
* the name of the technology
|
||||
* @param category
|
||||
* the name of the category the technology should be moved into
|
||||
* @throws TechGraphException
|
||||
* with {@link TechGraphException.Code#MISSING_TECHNOLOGY} if the technology does
|
||||
* not exist or with {@link TechGraphException.Code#MISSING_CATEGORY} if the
|
||||
* category does not exist
|
||||
*/
|
||||
public void setCategory( String technology , String category )
|
||||
throws TechGraphException
|
||||
{
|
||||
this.getCategory( category ).addExistingTechnology( this.getTechnology( technology ) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a dependency to a technology.
|
||||
*
|
||||
* @param technology
|
||||
* the name of the technology to add a dependency to
|
||||
* @param dependsOn
|
||||
* the name of the new dependency
|
||||
*
|
||||
* @throws TechGraphException
|
||||
* with {@link TechGraphException.Code#MISSING_TECHNOLOGY} if the dependent
|
||||
* technology does not exist, with
|
||||
* {@link TechGraphException.Code#MISSING_DEPENDENCY} if the dependency does not
|
||||
* exist, with {@link TechGraphException.Code#RECURSIVE_DEPENDENCY} if adding the
|
||||
* dependency would cause a recursion in the graph, or with
|
||||
* {@link TechGraphException.Code#DUPLICATE_DEPENDENCY} if the technology already
|
||||
* depends on the specified technology (either directly or indirectly)
|
||||
*/
|
||||
public void addDependency( String technology , String dependsOn )
|
||||
throws TechGraphException
|
||||
{
|
||||
Technology tech = this.getTechnology( technology );
|
||||
Technology dep;
|
||||
try {
|
||||
dep = this.getTechnology( dependsOn );
|
||||
} catch ( TechGraphException e ) {
|
||||
throw new TechGraphException( Code.MISSING_DEPENDENCY );
|
||||
}
|
||||
|
||||
if ( technology.equals( dependsOn ) || dep.hasDependency( technology ) ) {
|
||||
throw new TechGraphException( Code.RECURSIVE_DEPENDENCY );
|
||||
}
|
||||
if ( tech.hasDependency( dependsOn ) ) {
|
||||
throw new TechGraphException( Code.DUPLICATE_DEPENDENCY );
|
||||
}
|
||||
|
||||
tech.addDependency( dep );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove a dependency from a technology's definition.
|
||||
*
|
||||
* @param technology
|
||||
* the name of the dependent technology
|
||||
* @param dependency
|
||||
* the name of the dependency to remove
|
||||
* @throws TechGraphException
|
||||
* with {@link TechGraphException.Code#MISSING_TECHNOLOGY} if the dependent
|
||||
* technology does not exist or with
|
||||
* {@link TechGraphException.Code#MISSING_DEPENDENCY} if the technology does not
|
||||
* have the specified dependency.
|
||||
*/
|
||||
public void removeDependency( String technology , String dependency )
|
||||
throws TechGraphException
|
||||
{
|
||||
Technology tech = this.getTechnology( technology );
|
||||
if ( !tech.hasDirectDependency( dependency ) ) {
|
||||
throw new TechGraphException( Code.MISSING_DEPENDENCY );
|
||||
}
|
||||
tech.removeDependency( dependency );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Delete a technology's definition.
|
||||
*
|
||||
* @param technology
|
||||
* the name of the technology to delete.
|
||||
* @throws TechGraphException
|
||||
* with {@link TechGraphException.Code#MISSING_TECHNOLOGY} if the technology does
|
||||
* not exist or with {@link TechGraphException.Code#DEPENDENCY_ERROR} if other
|
||||
* technologies depend on the technology to delete.
|
||||
*/
|
||||
public void deleteTechnology( String technology )
|
||||
throws TechGraphException
|
||||
{
|
||||
Technology tech = this.getTechnology( technology );
|
||||
if ( tech.hasReverseDependencies( ) ) {
|
||||
throw new TechGraphException( Code.DEPENDENCY_ERROR );
|
||||
}
|
||||
|
||||
tech.delete( );
|
||||
this.techsByName.remove( technology );
|
||||
this.technologies.remove( tech );
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
package com.deepclone.lw.sqld.game.techs;
|
||||
|
||||
|
||||
/**
|
||||
* Exceptions thrown by the {@link TechGraph} class when operations on the graph would result in an
|
||||
* incorrect graph.
|
||||
*
|
||||
* @author tseeker
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings( "serial" )
|
||||
public class TechGraphException
|
||||
extends Exception
|
||||
{
|
||||
|
||||
/** Error codes associated with tech graph exceptions */
|
||||
public static enum Code {
|
||||
/** Trying to add a duplicate category */
|
||||
DUPLICATE_CATEGORY ,
|
||||
|
||||
/** Trying to access a category that does not exist */
|
||||
MISSING_CATEGORY ,
|
||||
|
||||
/** Trying to delete a category or technology on which other technologies depend */
|
||||
DEPENDENCY_ERROR ,
|
||||
|
||||
/** Trying to add a duplicate technology */
|
||||
DUPLICATE_TECHNOLOGY ,
|
||||
|
||||
/** Trying to access a technology that does not exist */
|
||||
MISSING_TECHNOLOGY ,
|
||||
|
||||
/** Trying to access a dependency that does not exist */
|
||||
MISSING_DEPENDENCY ,
|
||||
|
||||
/** Trying to add a recursive dependency */
|
||||
RECURSIVE_DEPENDENCY ,
|
||||
|
||||
/**
|
||||
* Trying to add a dependency that is already present (whether directly or through other
|
||||
* dependencies)
|
||||
*/
|
||||
DUPLICATE_DEPENDENCY ,
|
||||
}
|
||||
|
||||
/** Error code for the exception */
|
||||
private final Code code;
|
||||
|
||||
|
||||
public TechGraphException( Code code )
|
||||
{
|
||||
super( code.toString( ) );
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
|
||||
public TechGraphException( Code code , String identifier )
|
||||
{
|
||||
super( code.toString( ) + " : " + identifier );
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
|
||||
public Code getCode( )
|
||||
{
|
||||
return code;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,285 @@
|
|||
package com.deepclone.lw.sqld.game.techs;
|
||||
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Representation of a technology from the technology graph.
|
||||
*
|
||||
* @author tseeker
|
||||
*/
|
||||
public class Technology
|
||||
{
|
||||
|
||||
/** The string identifier of the technology's name */
|
||||
private final String name;
|
||||
|
||||
/** The category the technology belongs to */
|
||||
private Category category;
|
||||
|
||||
/** The string identifier of the technology's description */
|
||||
private String description;
|
||||
|
||||
/** The amount of research points required before the technology can be implemented */
|
||||
private double points;
|
||||
|
||||
/** The cost of implementing the technology */
|
||||
private double cost;
|
||||
|
||||
/** Map of technologies the current technology depends on */
|
||||
private final Map< String , Technology > dependencies;
|
||||
|
||||
/** Map of technologies that depend on the current technology */
|
||||
private final Map< String , Technology > dependencyOf;
|
||||
|
||||
/** Names of all technologies the current technology depends on, whether directly or indirectly. */
|
||||
private Set< String > fullDependencies;
|
||||
|
||||
|
||||
/**
|
||||
* Initialise the technology's record. This method is meant to be called from
|
||||
* {@link Category#addTechnology(String, String, int, int)}.
|
||||
*
|
||||
* @param category
|
||||
* the category the technology belongs to
|
||||
* @param name
|
||||
* string identifier of the technology's name
|
||||
* @param description
|
||||
* string identifier of the technology's description
|
||||
* @param points
|
||||
* amount of research points required before the technology can be implemented
|
||||
* @param cost
|
||||
* cost of implementing the technology
|
||||
*/
|
||||
Technology( Category category , String name , String description , double points , double cost )
|
||||
{
|
||||
this.category = category;
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.points = points;
|
||||
this.cost = cost;
|
||||
this.dependencies = new HashMap< String , Technology >( );
|
||||
this.dependencyOf = new HashMap< String , Technology >( );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a partial copy of an existing technology. Dependencies will not be copied as they need
|
||||
* to be resolved after a full graph copy has been performed.
|
||||
*
|
||||
* @param tech
|
||||
* the technology to copy
|
||||
*/
|
||||
Technology( Technology tech )
|
||||
{
|
||||
this.category = tech.category;
|
||||
this.name = tech.name;
|
||||
this.description = tech.description;
|
||||
this.points = tech.points;
|
||||
this.cost = tech.cost;
|
||||
this.dependencies = new HashMap< String , Technology >( );
|
||||
this.dependencyOf = new HashMap< String , Technology >( );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if the technology depends on another, whether directly or indirectly.
|
||||
*
|
||||
* @param technology
|
||||
* the name of the dependency to look for
|
||||
* @return <code>true</code> if the current technology depends on the specified technology,
|
||||
* <code>false</code> otherwise
|
||||
*/
|
||||
public boolean hasDependency( String technology )
|
||||
{
|
||||
if ( this.fullDependencies == null ) {
|
||||
this.buildDependencies( );
|
||||
}
|
||||
return this.fullDependencies.contains( technology );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Build the contents of the {@link #fullDependencies} property based on the list of direct
|
||||
* dependencies.
|
||||
*/
|
||||
private void buildDependencies( )
|
||||
{
|
||||
Set< String > deps = new HashSet< String >( );
|
||||
for ( Technology dep : this.dependencies.values( ) ) {
|
||||
deps.add( dep.name );
|
||||
if ( dep.fullDependencies == null ) {
|
||||
dep.buildDependencies( );
|
||||
}
|
||||
deps.addAll( dep.fullDependencies );
|
||||
}
|
||||
this.fullDependencies = deps;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if the current technology has another technology in its list of direct dependencies.
|
||||
*
|
||||
* @param dependency
|
||||
* the dependency to look for
|
||||
* @return <code>true</code> if the current technology depends on the specified technology
|
||||
* directly, <code>false</code> otherwise.
|
||||
*/
|
||||
public boolean hasDirectDependency( String dependency )
|
||||
{
|
||||
return this.dependencies.containsKey( dependency );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if there are technologies which depend on the current technology.
|
||||
*
|
||||
* @return <code>true</code> if at least one technology depends on the current technology,
|
||||
* <code>false</code> otherwise.
|
||||
*/
|
||||
public boolean hasReverseDependencies( )
|
||||
{
|
||||
return !this.dependencyOf.isEmpty( );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a new dependency to the current technology.
|
||||
*
|
||||
* @param dep
|
||||
* the dependency to add
|
||||
*/
|
||||
void addDependency( Technology dep )
|
||||
{
|
||||
this.dependencies.put( dep.name , dep );
|
||||
dep.dependencyOf.put( this.name , this );
|
||||
this.fullDependencies = null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove an existing dependency from the current technology.
|
||||
*
|
||||
* @param dependency
|
||||
* the name of the dependency to remove
|
||||
*/
|
||||
void removeDependency( String dependency )
|
||||
{
|
||||
Technology dep = this.dependencies.get( dependency );
|
||||
dep.dependencyOf.remove( this.name );
|
||||
this.dependencies.remove( dependency );
|
||||
this.fullDependencies = null;
|
||||
}
|
||||
|
||||
|
||||
/** @return the list of technology names the current technology directly depends on */
|
||||
public List< String > getDependencies( )
|
||||
{
|
||||
return new LinkedList< String >( this.dependencies.keySet( ) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Delete the current technology, removing it from the reverse dependency lists of its
|
||||
* dependencies and from its category.
|
||||
*/
|
||||
void delete( )
|
||||
{
|
||||
List< String > deps = new LinkedList< String >( this.dependencies.keySet( ) );
|
||||
for ( String dep : deps ) {
|
||||
this.removeDependency( dep );
|
||||
}
|
||||
this.category.removeTechnology( this );
|
||||
}
|
||||
|
||||
|
||||
/** @return the string identifier of the technology's name */
|
||||
public String getName( )
|
||||
{
|
||||
return this.name;
|
||||
}
|
||||
|
||||
|
||||
/** @return the category the technology belongs to. */
|
||||
public Category getCategory( )
|
||||
{
|
||||
return category;
|
||||
}
|
||||
|
||||
|
||||
/** @return the string identifier of the technology's description */
|
||||
public String getDescription( )
|
||||
{
|
||||
return description;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update the technology's category
|
||||
*
|
||||
* @param category
|
||||
* the new category
|
||||
*/
|
||||
void setCategory( Category category )
|
||||
{
|
||||
this.category = category;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update the string identifier of the technology's description
|
||||
*
|
||||
* @param description
|
||||
* the new description string ID
|
||||
*/
|
||||
void setDescription( String description )
|
||||
{
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
|
||||
/** @return the amount of research points required to implement the technology */
|
||||
public double getPoints( )
|
||||
{
|
||||
return points;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update the amount of research points required to implement the technology.
|
||||
*
|
||||
* @param points
|
||||
* the new amount of points
|
||||
*/
|
||||
void setPoints( int points )
|
||||
{
|
||||
this.points = points;
|
||||
}
|
||||
|
||||
|
||||
/** @return the implementation cost */
|
||||
public double getCost( )
|
||||
{
|
||||
return cost;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update the implementation cost.
|
||||
*
|
||||
* @param cost
|
||||
* the new implementation cost.
|
||||
*/
|
||||
void setCost( int cost )
|
||||
{
|
||||
this.cost = cost;
|
||||
}
|
||||
|
||||
}
|
|
@ -71,13 +71,6 @@ public class Constant
|
|||
}
|
||||
|
||||
|
||||
public void setMinValue( Float minValue )
|
||||
{
|
||||
|
||||
this.minValue = ( minValue == null ? null : minValue.doubleValue( ) );
|
||||
}
|
||||
|
||||
|
||||
public Double getMaxValue( )
|
||||
{
|
||||
return maxValue;
|
||||
|
@ -90,13 +83,6 @@ public class Constant
|
|||
}
|
||||
|
||||
|
||||
public void setMaxValue( Float maxValue )
|
||||
{
|
||||
|
||||
this.maxValue = ( maxValue == null ? null : maxValue.doubleValue( ) );
|
||||
}
|
||||
|
||||
|
||||
public double getValue( )
|
||||
{
|
||||
return value;
|
||||
|
|
Reference in a new issue