86 lines
No EOL
2.9 KiB
PL/PgSQL
86 lines
No EOL
2.9 KiB
PL/PgSQL
-- LegacyWorlds Beta 6
|
|
-- PostgreSQL database scripts
|
|
--
|
|
-- Game updates - empire research
|
|
--
|
|
-- Copyright(C) 2004-2010, DeepClone Development
|
|
-- --------------------------------------------------------
|
|
|
|
|
|
CREATE OR REPLACE FUNCTION sys.process_empire_research_updates( c_tick BIGINT )
|
|
RETURNS VOID
|
|
STRICT VOLATILE
|
|
SECURITY INVOKER
|
|
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
|
|
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
|
|
WHERE su.last_tick = c_tick 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;
|
|
END;
|
|
$$ LANGUAGE plpgsql; |