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/030-fleet-arrivals.sql

148 lines
No EOL
5.7 KiB
PL/PgSQL

-- LegacyWorlds Beta 6
-- PostgreSQL database scripts
--
-- Game updates - fleet arrivals
--
-- Copyright(C) 2004-2010, DeepClone Development
-- --------------------------------------------------------
CREATE OR REPLACE FUNCTION sys.process_planet_fleet_arrivals_updates( c_tick BIGINT )
RETURNS VOID
STRICT VOLATILE
SECURITY INVOKER
AS $$
DECLARE
rec RECORD;
lstat BOOLEAN;
f_ids BIGINT[];
BEGIN
-- Lock all records
PERFORM f.id FROM sys.updates su
INNER JOIN verse.updates vu ON vu.update_id = su.id
INNER JOIN verse.planets p ON p.name_id = vu.planet_id
INNER JOIN fleets.fleets f ON f.location_id = p.name_id
INNER JOIN fleets.movements fm ON fm.fleet_id = f.id
INNER JOIN emp.empires e ON e.name_id = f.owner_id
WHERE su.last_tick = c_tick AND su.status = 'PROCESSING'
AND su.gu_type = 'PLANET_FLEET_ARRIVALS'
AND f.status = 'AVAILABLE' AND fm.time_left = 1
FOR UPDATE;
-- Update attack status according to planet owners and enemy lists
FOR rec IN SELECT ep.empire_id AS planet_owner , p.name_id AS planet ,
f.owner_id AS fleet_owner , ( v.status = 'PROCESSED' AND b.id IS NULL ) AS on_vacation ,
bool_or( f.attacking ) AS attacking
FROM sys.updates su
INNER JOIN verse.updates vu ON vu.update_id = su.id
INNER JOIN verse.planets p ON p.name_id = vu.planet_id
INNER JOIN fleets.fleets f ON f.location_id = p.name_id
INNER JOIN fleets.movements fm ON fm.fleet_id = f.id
LEFT OUTER JOIN emp.planets ep ON ep.planet_id = p.name_id
LEFT OUTER JOIN naming.empire_names en ON en.id = ep.empire_id
LEFT OUTER JOIN users.vacations v ON v.account_id = en.owner_id
LEFT OUTER JOIN battles.battles b
ON b.location_id = p.name_id AND b.last_tick IS NULL
WHERE su.last_tick = c_tick AND su.status = 'PROCESSING'
AND su.gu_type = 'PLANET_FLEET_ARRIVALS'
AND f.status = 'AVAILABLE' AND fm.time_left = 1
GROUP BY p.name_id , ep.empire_id , f.owner_id , v.status , b.id
LOOP
-- Fleets owned by the planet's owner are never attacking, same for fleets arriving on
-- planets that are on vacation
IF rec.fleet_owner = rec.planet_owner OR rec.on_vacation THEN
UPDATE fleets.fleets f SET attacking = FALSE
FROM fleets.movements m
WHERE f.status = 'AVAILABLE' AND f.owner_id = rec.fleet_owner
AND f.location_id = rec.planet AND m.fleet_id = f.id AND m.time_left = 1;
CONTINUE;
END IF;
-- Check enemy lists
PERFORM * FROM emp.enemies
WHERE empire = rec.planet_owner AND enemy = rec.fleet_owner;
IF FOUND
THEN
-- Fleet owner in the planet owner's EL
UPDATE fleets.fleets f SET attacking = TRUE
FROM fleets.movements m
WHERE f.status = 'AVAILABLE' AND f.owner_id = rec.fleet_owner
AND f.location_id = rec.planet AND m.fleet_id = f.id AND m.time_left = 1;
CONTINUE;
END IF;
-- If one of the arriving fleets is attacking, or if the local fleets are already attacking,
-- then switch all local or arriving fleets to attack
SELECT INTO lstat f.attacking
FROM fleets.fleets f
LEFT OUTER JOIN fleets.movements fm ON fm.fleet_id = f.id
WHERE f.owner_id = rec.fleet_owner AND f.location_id = rec.planet AND fm IS NULL
GROUP BY f.attacking;
IF ( FOUND AND lstat ) OR rec.attacking
THEN
SELECT INTO f_ids array_agg( f.id ) FROM fleets.fleets f
WHERE f.owner_id = rec.fleet_owner AND f.location_id = rec.planet;
PERFORM fleets.set_mode( rec.fleet_owner , f_ids , TRUE );
CONTINUE;
END IF;
END LOOP;
-- Prepare fleet arrival events
CREATE TEMPORARY TABLE fleet_arrivals(
loc_id INT ,
loc_name VARCHAR(20) ,
own_id INT ,
own_name VARCHAR(20) ,
name VARCHAR(64) ,
power BIGINT ,
mode BOOLEAN ,
src_id INT ,
src_name VARCHAR(20)
);
INSERT INTO fleet_arrivals
SELECT f.location_id , ln.name , f.owner_id , fon.name ,
f.name , fs.power , f.attacking , fm.source_id , sn.name
FROM sys.updates su
INNER JOIN verse.updates vu ON vu.update_id = su.id
INNER JOIN verse.planets p ON p.name_id = vu.planet_id
INNER JOIN fleets.fleets f ON f.location_id = p.name_id
INNER JOIN fleets.movements fm ON fm.fleet_id = f.id
INNER JOIN fleets.stats_view fs ON fs.id = f.id
INNER JOIN naming.empire_names fon ON fon.id = f.owner_id
INNER JOIN naming.map_names ln ON ln.id = f.location_id
INNER JOIN naming.map_names sn ON sn.id = fm.source_id
WHERE su.last_tick = c_tick AND su.status = 'PROCESSING'
AND su.gu_type = 'PLANET_FLEET_ARRIVALS'
AND f.status = 'AVAILABLE' AND fm.time_left = 1;
-- Delete movement records, set redeployment penalties, update battles
FOR rec IN SELECT f.id AS fleet , fs.flight_time AS flight_time ,
f.attacking AS attacking , b.id AS battle ,
f.location_id AS location
FROM sys.updates su
INNER JOIN verse.updates vu ON vu.update_id = su.id
INNER JOIN verse.planets p ON p.name_id = vu.planet_id
INNER JOIN fleets.fleets f ON f.location_id = p.name_id
INNER JOIN fleets.movements fm ON fm.fleet_id = f.id
INNER JOIN fleets.stats_view fs ON fs.id = f.id
LEFT OUTER JOIN battles.battles b
ON b.location_id = p.name_id AND b.last_tick IS NULL
WHERE su.last_tick = c_tick AND su.status = 'PROCESSING'
AND su.gu_type = 'PLANET_FLEET_ARRIVALS'
AND f.status = 'AVAILABLE' AND fm.time_left = 1
LOOP
DELETE FROM fleets.movements
WHERE fleet_id = rec.fleet;
UPDATE fleets.fleets
SET status = 'REDEPLOYING' ,
penalty = 1 + rec.flight_time * ( CASE WHEN rec.attacking THEN 40 ELSE 10 END )
WHERE id = rec.fleet;
-- Add fleets to battle (will not be executed if battle is NULL)
PERFORM battles.add_fleet( rec.battle , rec.fleet , FALSE , c_tick );
END LOOP;
-- Send fleet arrival events
PERFORM events.commit_fleet_arrivals( c_tick );
END;
$$ LANGUAGE plpgsql;