-- 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;