This repository has been archived on 2024-07-18. You can view files and clone it, but cannot push or open issues or pull requests.
lwb6/legacyworlds-server/legacyworlds-server-data/db-structure/parts/updates/020-empire-research.sql

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;