148 lines
No EOL
5.7 KiB
PL/PgSQL
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; |