Mining settings

* Changed the way mining settings work: use a priority value (between 0
and 4) as the weight. Leaving them as they were before would have caused
numerous problems (and a lot of unnecessary code to work around them)

* Empire mining settings will be created along with the empire's own
record. By default all natural resources will have weight = 2.

* Added a set of four stored procedures which can be used to update an
empire's mining settings, including planet-specific settings. The
emp.mset_update_start() function can be used to start an update (on an
empire's settings if there is only one parameter, or on a planet's
settings if there are two parameters); the emp.mset_update_set() and
emp.mset_update_apply() functions are then used to modify the settings
and apply the changes, respectively.
This commit is contained in:
Emmanuel BENOîT 2012-01-10 10:17:47 +01:00
parent 3e109b13bc
commit afc66166e0
15 changed files with 745 additions and 55 deletions
legacyworlds-server-data/db-structure/parts/040-functions

View file

@ -7,43 +7,60 @@
-- --------------------------------------------------------
--
-- Empire creation
--
-- Parameters:
-- nid Empire name identifier
-- pid Planet identifier
-- icash Initial cash
--
CREATE OR REPLACE FUNCTION emp.create_empire( nid INT , pid INT , icash REAL )
/*
* Empire creation
*
* This function inserts the rows that represent an empire and its settings.
* It also initialises the empire's updates.
*
* Parameters:
* _name_id Empire name identifier
* _planet_id Planet identifier
* _initial_cash Initial cash
*/
DROP FUNCTION IF EXISTS emp.create_empire( INT , INT , REAL );
CREATE FUNCTION emp.create_empire(
_name_id INT ,
_planet_id INT ,
_initial_cash REAL )
RETURNS VOID
STRICT
VOLATILE
STRICT VOLATILE
SECURITY INVOKER
AS $$
DECLARE
uid BIGINT;
utp update_type;
_update BIGINT;
_update_type update_type;
BEGIN
-- Add empire and give initial planet
INSERT INTO emp.empires ( name_id , cash )
VALUES ( nid , icash );
VALUES ( _name_id , _initial_cash );
INSERT INTO emp.planets ( planet_id , empire_id )
VALUES ( pid , nid );
VALUES ( _planet_id , _name_id );
-- Add mining settings
INSERT INTO emp.mining_settings ( empire_id , resource_name_id )
SELECT _name_id , _resource.resource_name_id
FROM defs.natural_resources _resource;
-- Add empire update records
FOR utp IN SELECT x FROM unnest( enum_range( NULL::update_type ) ) AS x
WHERE x::text LIKE 'EMPIRE_%'
FOR _update_type IN SELECT _type
FROM unnest( enum_range( NULL::update_type ) ) AS _type
WHERE _type::text LIKE 'EMPIRE_%'
LOOP
INSERT INTO sys.updates( gu_type )
VALUES ( utp )
RETURNING id INTO uid;
VALUES ( _update_type )
RETURNING id INTO _update;
INSERT INTO emp.updates ( update_id , empire_id )
VALUES ( uid , nid );
VALUES ( _update , _name_id );
END LOOP;
END;
$$ LANGUAGE plpgsql;
REVOKE EXECUTE
ON FUNCTION emp.create_empire( INT , INT , REAL )
FROM PUBLIC;
--
-- Returns a planet owner's empire size

View file

@ -0,0 +1,234 @@
-- LegacyWorlds Beta 6
-- PostgreSQL database scripts
--
-- Functions that control and compute empire mining
--
-- Copyright(C) 2004-2010, DeepClone Development
-- --------------------------------------------------------
/*
* Prepare for an update on empire mining settings
*
* This function creates a temporary table mimicking the structure of
* emp.mining_settings, and stores default settings into it.
*
* Parameters:
* _empire_id The empire's identifier
*
* Returns:
* ? True if the empire exists, false otherwise
*/
DROP FUNCTION IF EXISTS emp.mset_update_start( INT );
CREATE FUNCTION emp.mset_update_start( _empire_id INT )
RETURNS BOOLEAN
STRICT VOLATILE
SECURITY DEFINER
AS $mset_update_start$
BEGIN
CREATE TEMPORARY TABLE mset_update(
empire_id INT ,
resource_name_id INT ,
empmset_weight INT
) ON COMMIT DROP;
INSERT INTO mset_update
SELECT _mset.empire_id , _mset.resource_name_id , 2
FROM emp.empires _empire
INNER JOIN emp.mining_settings _mset
ON _empire.name_id = _mset.empire_id
WHERE _empire.name_id = _empire_id
FOR SHARE OF _empire
FOR UPDATE OF _mset;
RETURN FOUND;
END;
$mset_update_start$ LANGUAGE PLPGSQL;
REVOKE EXECUTE
ON FUNCTION emp.mset_update_start( INT )
FROM PUBLIC;
GRANT EXECUTE
ON FUNCTION emp.mset_update_start( INT )
TO :dbuser;
/*
* Prepare for an update on planet-specific mining settings
*
* This function creates a temporary table mimicking the structure of
* emp.planet_mining_settings, and stores default settings into it, using the
* planet's list of resource provider as the source.
*
* Parameters:
* _empire_id The empire's identifier
* _planet_id The planet's identifier
*
* Returns:
* ? True if the empire exists and owns the planet, false
* otherwise
*/
DROP FUNCTION IF EXISTS emp.mset_update_start( INT , INT );
CREATE FUNCTION emp.mset_update_start( _empire_id INT , _planet_id INT )
RETURNS BOOLEAN
STRICT VOLATILE
SECURITY DEFINER
AS $mset_update_start$
BEGIN
CREATE TEMPORARY TABLE mset_update(
empire_id INT ,
planet_id INT ,
resource_name_id INT ,
empmset_weight INT
) ON COMMIT DROP;
PERFORM 1
FROM emp.empires _empire
INNER JOIN emp.planets _emp_planet
ON _empire.name_id = _emp_planet.empire_id
INNER JOIN verse.planets _planet
ON _planet.name_id = _emp_planet.planet_id
INNER JOIN verse.resource_providers _resprov
ON _resprov.planet_id = _planet.name_id
WHERE _empire.name_id = _empire_id
AND _planet.name_id = _planet_id
FOR SHARE OF _empire, _emp_planet , _planet , _resprov;
IF NOT FOUND THEN
RETURN FALSE;
END IF;
PERFORM 1
FROM emp.planet_mining_settings
WHERE empire_id = _empire_id AND planet_id = _planet_id
FOR UPDATE;
INSERT INTO mset_update
SELECT _empire_id , _planet_id , resource_name_id , 2
FROM verse.resource_providers
WHERE planet_id = _planet_id;
RETURN TRUE;
END;
$mset_update_start$ LANGUAGE PLPGSQL;
REVOKE EXECUTE
ON FUNCTION emp.mset_update_start( INT , INT )
FROM PUBLIC;
GRANT EXECUTE
ON FUNCTION emp.mset_update_start( INT , INT )
TO :dbuser;
/*
* Update the weight of some resource
*
* This function updates the weight of a resource in the temporary table. It
* must be called after emp.mset_update_start() has initialised the table.
*
* Parameters:
* _resource_id The resource's identifier
* _weight The setting's new value
*
* Returns:
* ? True if the resource exists, false otherwise.
*/
DROP FUNCTION IF EXISTS emp.mset_update_set( INT , INT );
CREATE FUNCTION emp.mset_update_set( _resource_id INT , _weight INT )
RETURNS BOOLEAN
STRICT VOLATILE
SECURITY DEFINER
AS $mset_update_set$
BEGIN
UPDATE mset_update
SET empmset_weight = _weight
WHERE resource_name_id = _resource_id;
RETURN FOUND;
END;
$mset_update_set$ LANGUAGE PLPGSQL;
REVOKE EXECUTE
ON FUNCTION emp.mset_update_set( INT , INT )
FROM PUBLIC;
GRANT EXECUTE
ON FUNCTION emp.mset_update_set( INT , INT )
TO :dbuser;
/*
* Apply a pending update to empire or planet mining settings
*
* This function is called once mining settings (whether empire-wise or
* planet-specific) have been uploaded. It will apply all changes to the
* actual mining settings table.
*
* Returns:
* ? True if the update was applied, false if one of the
* weights was invalid.
*/
DROP FUNCTION IF EXISTS emp.mset_update_apply( );
CREATE FUNCTION emp.mset_update_apply( )
RETURNS BOOLEAN
STRICT VOLATILE
SECURITY DEFINER
AS $mset_update_apply$
DECLARE
_empire INT;
_planet INT;
BEGIN
BEGIN
-- Get empire and planet identifier (will cause exception if this is
-- not a planet settings update).
SELECT INTO _empire , _planet
empire_id , planet_id
FROM mset_update
LIMIT 1;
DELETE FROM emp.planet_mining_settings
WHERE empire_id = _empire AND planet_id = _planet;
INSERT INTO emp.planet_mining_settings (
empire_id , planet_id , resource_name_id ,
emppmset_weight
) SELECT empire_id , planet_id ,
resource_name_id , empmset_weight
FROM mset_update;
EXCEPTION
-- These are empire-wide settings
WHEN undefined_column THEN
UPDATE emp.mining_settings _settings
SET empmset_weight = _update.empmset_weight
FROM mset_update _update
WHERE _update.empire_id = _settings.empire_id
AND _update.resource_name_id = _settings.resource_name_id;
END;
RETURN TRUE;
EXCEPTION
-- One of the weights was invalid
WHEN check_violation THEN
RETURN FALSE;
END;
$mset_update_apply$ LANGUAGE PLPGSQL;
REVOKE EXECUTE
ON FUNCTION emp.mset_update_apply( )
FROM PUBLIC;
GRANT EXECUTE
ON FUNCTION emp.mset_update_apply( )
TO :dbuser;