-- LegacyWorlds Beta 6 -- PostgreSQL database scripts -- -- Game updates - fleet movements -- -- Copyright(C) 2004-2010, DeepClone Development -- -------------------------------------------------------- CREATE OR REPLACE FUNCTION sys.process_planet_fleet_movements_updates( c_tick BIGINT ) RETURNS VOID STRICT VOLATILE SECURITY INVOKER AS $$ DECLARE rec RECORD; rpid INT; 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_MOVEMENTS' AND f.status = 'AVAILABLE' FOR UPDATE; -- Handle state transitions FOR rec IN SELECT f.id AS id , max( fsd.flight_time ) AS flight_time , s.x AS x , s.y AS y , s.id AS sys_id , isms.ref_point_id AS is_ref_point , isms.outwards AS is_outwards , isms.past_ref_point AS is_past_ref_point , rp.system_id AS is_ref_point_system , rp.orbit AS is_ref_point_orbit , rps.x AS is_ref_point_x , rps.y AS is_ref_point_y 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 verse.systems s ON s.id = p.system_id INNER JOIN fleets.fleets f ON f.location_id = p.name_id INNER JOIN fleets.ships fs ON fs.fleet_id = f.id INNER JOIN tech.ships fsd ON fsd.buildable_id = fs.ship_id INNER JOIN fleets.movements m ON m.fleet_id = f.id LEFT OUTER JOIN fleets.ms_system isms ON isms.movement_id = f.id LEFT OUTER JOIN verse.planets rp ON isms.ref_point_id = rp.name_id LEFT OUTER JOIN verse.systems rps ON rps.id = rp.system_id WHERE su.last_tick = c_tick AND su.status = 'PROCESSING' AND su.gu_type = 'PLANET_FLEET_MOVEMENTS' AND f.status = 'AVAILABLE' AND m.state_time_left = 1 GROUP BY f.id , s.x , s.y , s.id , isms.ref_point_id , isms.outwards , isms.past_ref_point , rp.system_id , rp.orbit , rps.x , rps.y LOOP IF rec.is_ref_point_orbit IS NOT NULL THEN IF rec.is_ref_point_orbit = 5 AND rec.is_outwards AND rec.is_past_ref_point THEN -- Fleet exiting system INSERT INTO fleets.ms_space ( movement_id , start_x , start_y ) VALUES ( rec.id , rec.is_ref_point_x , rec.is_ref_point_y ); DELETE FROM fleets.ms_system WHERE movement_id = rec.id; UPDATE fleets.movements SET state_time_left = 1 + fleets.compute_outerspace_duration( rec.flight_time , rec.is_ref_point_x , rec.is_ref_point_y , rec.x , rec.y ) WHERE fleet_id = rec.id; ELSE -- In-system state change IF rec.is_past_ref_point THEN SELECT INTO rpid p.name_id FROM verse.planets p WHERE p.system_id = rec.is_ref_point_system AND p.orbit = rec.is_ref_point_orbit + ( CASE WHEN rec.is_outwards THEN 1 ELSE -1 END ); UPDATE fleets.ms_system SET past_ref_point = FALSE , ref_point_id = rpid WHERE movement_id = rec.id; ELSE UPDATE fleets.ms_system SET past_ref_point = TRUE WHERE movement_id = rec.id; END IF; UPDATE fleets.movements SET state_time_left = rec.flight_time + 1 WHERE fleet_id = rec.id; END IF; ELSE -- Fleet entering system SELECT INTO rpid p.name_id FROM verse.planets p WHERE p.system_id = rec.sys_id AND p.orbit = 5; INSERT INTO fleets.ms_system ( movement_id , ref_point_id , outwards , past_ref_point ) VALUES ( rec.id , rpid , FALSE , FALSE ); DELETE FROM fleets.ms_space WHERE movement_id = rec.id; UPDATE fleets.movements SET state_time_left = rec.flight_time + 1 WHERE fleet_id = rec.id; END IF; END LOOP; -- Decrease movement and state time UPDATE fleets.movements SET state_time_left = state_time_left - 1 , time_left = time_left - 1 WHERE fleet_id IN ( SELECT 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_MOVEMENTS' AND f.status = 'AVAILABLE' ); END; $$ LANGUAGE plpgsql;