Technology implementation

* A stored procedure which implements technologies has been added. It
will mark a pending technology as implemented and remove the
corresponding quantity of money from the empire, then add any newly
available research items to the empire's research.
This commit is contained in:
Emmanuel BENOîT 2012-02-28 16:15:02 +01:00
parent 8c0b4abd1e
commit f4e38e4943
3 changed files with 210 additions and 1 deletions
legacyworlds-server-data/db-structure/parts/040-functions

View file

@ -68,6 +68,92 @@ REVOKE EXECUTE
FROM PUBLIC;
/*
* Implements a technology
* ------------------------
*
* This stored procedure is called when an empire attempts to implement a
* technology. It will check the empire's resources and the technology itself,
* then mark it as implemented if necessary. It will also add new research
* entries if necessary.
*
* Parameters:
* _empire The empire's identifier
* _technology The string identifier for the technology to implement
*/
DROP FUNCTION emp.technology_implement( INT , TEXT );
CREATE FUNCTION emp.technology_implement( _empire INT , _technology TEXT )
RETURNS BOOLEAN
LANGUAGE PLPGSQL
STRICT VOLATILE
SECURITY DEFINER
AS $technology_implement$
DECLARE
_impl_data RECORD;
BEGIN
-- Access and lock the records
SELECT INTO _impl_data
technology_name_id , technology_price
FROM emp.empires _emp
INNER JOIN emp.technologies_v2 _tech
ON _tech.empire_id = _emp.name_id
INNER JOIN defs.technologies _def
USING ( technology_name_id )
INNER JOIN defs.strings _name
ON _def.technology_name_id = _name.id
WHERE _emp.name_id = _empire
AND _name.name = _technology
AND _tech.emptech_state = 'PENDING'
AND _emp.cash >= _def.technology_price
FOR UPDATE OF _emp , _tech
FOR SHARE OF _def;
IF NOT FOUND THEN
RETURN FALSE;
END IF;
-- Implement the technology
UPDATE emp.empires
SET cash = cash - _impl_data.technology_price
WHERE name_id = _empire;
UPDATE emp.technologies_v2
SET emptech_state = 'KNOWN'
WHERE empire_id = _empire
AND technology_name_id = _impl_data.technology_name_id;
-- Insert new research
INSERT INTO emp.technologies_v2 ( empire_id , technology_name_id )
SELECT _empire , _valid.technology_name_id
FROM ( SELECT _tech.technology_name_id ,
( COUNT(*) = COUNT(_emptech.emptech_state) ) AS emptech_has_dependencies
FROM defs.technologies _tech
INNER JOIN defs.technology_dependencies _deps
USING ( technology_name_id )
LEFT OUTER JOIN emp.technologies_v2 _emptech
ON _emptech.technology_name_id = _deps.technology_name_id_depends
AND _emptech.emptech_state = 'KNOWN'
AND _emptech.empire_id = _empire
GROUP BY _tech.technology_name_id ) _valid
LEFT OUTER JOIN emp.technologies_v2 _emptech
ON _emptech.empire_id = _empire
AND _emptech.technology_name_id = _valid.technology_name_id
WHERE _emptech.empire_id IS NULL AND _valid.emptech_has_dependencies;
RETURN TRUE;
END;
$technology_implement$;
REVOKE EXECUTE
ON FUNCTION emp.technology_implement( INT , TEXT )
FROM PUBLIC;
GRANT EXECUTE
ON FUNCTION emp.technology_implement( INT , TEXT )
TO :dbuser;
--
-- Returns a planet owner's empire size
@ -107,7 +193,7 @@ GRANT EXECUTE ON FUNCTION emp.get_current( INT ) TO :dbuser;
--
-- Implements a technology
-- Implements a technology (OLD VERSION)
--
CREATE OR REPLACE FUNCTION emp.implement_tech( e_id INT , l_id INT )