Advertisement
Guest User

Untitled

a guest
Jul 28th, 2017
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. CREATE OR REPLACE FUNCTION "move"(moving_ship_id integer, new_speed integer, new_direction integer, new_destination_x integer, new_destination_y
  2. integer)
  3.   RETURNS boolean AS
  4. $BODY$
  5. DECLARE
  6.         max_speed integer;
  7.         current_speed integer;
  8.         current_fuel integer;
  9.         current_direction integer;
  10.         fuel_cost integer;
  11.         direction_fuel_cost integer := 0;
  12.         final_speed integer;
  13.         final_direction  integer;
  14.         final_fuel integer;
  15.         distance  bigint;
  16.         distance_x bigint;
  17.         distance_y bigint;
  18.         range integer;
  19.         location_x  integer;
  20.         location_y  integer;
  21.         ship_player_id integer;
  22. BEGIN
  23.         -- Grab current stats of ship
  24.         SELECT INTO max_speed, current_fuel, location_x, location_y, ship_player_id  ship.max_speed, ship.current_fuel, ship.location_x, ship.location_y, player_id from ship WHERE id=moving_ship_id;
  25.         SELECT INTO current_speed, current_direction speed, direction FROM ship_control WHERE ship_id = moving_ship_id;
  26.                
  27.         IF MOVE_PERMISSION_CHECK(moving_ship_id) THEN
  28.                 -- If they don't know what direction they're going, calculate it for them
  29.                 IF (final_direction IS NULL) THEN
  30.                     final_direction := getangle(location_x, location_y, new_destination_x, new_destination_y);
  31.                 ELSE
  32.                     final_direction := MOD(new_direction, 360);
  33.                 END IF;
  34.                
  35.                 -- Make sure they don't travel faster than max_speed!
  36.                 SELECT INTO final_speed CASE WHEN new_speed < max_speed THEN new_speed ELSE max_speed END;
  37.                
  38.                 -- Calculate the distance to target (if it exists)
  39.                 IF (new_destination_x IS NOT NULL AND new_destination_y IS NOT NULL) THEN
  40.                     distance_x := new_destination_x - location_x;
  41.                     distance_y := new_destination_y - location_y;
  42.                     distance := CAST(SQRT((distance_x * distance_x) + (distance_y * distance_y)) AS bigint);
  43.                    
  44.                     -- If their distance is less than their speed, override it
  45.                     IF (distance < final_speed) THEN
  46.                         IF (distance < 2147483647) THEN
  47.                             final_speed = CAST(distance AS integer);
  48.                         ELSE
  49.                             final_speed := 2147483647;
  50.                         END IF;
  51.                     END IF;
  52.                 END IF;
  53.                
  54.                 -- If they're not currently travelling at this speed/direction...
  55.                 IF (current_speed <> final_speed OR current_direction <> final_direction) THEN
  56.                     fuel_cost := ABS(final_speed - current_speed); -- Calculate the fuel cost to change speed
  57.                    
  58.                     -- if they're already moving and aren't trying to stop...
  59.                     IF (current_speed <> 0 AND final_speed <> 0) THEN -- add 1 fuel cost per degree changed
  60.                         direction_fuel_cost := ABS(final_direction - current_direction);
  61.                        
  62.                         -- Pythagorus is inexact with integer-only datatypes, so sometimes we're off by 1 degree when calculating the direction.
  63.                         -- Don't let this eat up our fuel!
  64.                         IF (direction_fuel_cost = 1) THEN direction_fuel_cost := 0; END IF;
  65.                         fuel_cost := fuel_cost + direction_fuel_cost;
  66.                     END IF;
  67.                 ELSE
  68.                     fuel_cost := 0;
  69.                 END IF;
  70.  
  71.                 -- Abort moving if they specified a destination and don't have enough fuel to get/stop there
  72.                 IF ((new_destination_x IS NOT NULL AND new_destination_y IS NOT NULL) AND (current_fuel < fuel_cost + direction_fuel_cost + final_speed)) THEN
  73.                     EXECUTE 'NOTIFY ' || get_player_error_channel(GET_PLAYER_USERNAME(ship_player_id)) || ', ''' || GET_SHIP_NAME(moving_ship_id) || ' does not have enough fuel to fly heading ' || final_direction || ', accelerate to ' || final_speed ||' and then stop! To override, specify a NULL destination x and y.'';';
  74.                     RETURN 'f';
  75.                 END IF;
  76.                
  77.                 final_fuel := current_fuel - fuel_cost;
  78.                 --EXECUTE 'NOTIFY ' || get_player_error_channel(GET_PLAYER_USERNAME(ship_player_id)) || ', ''Ship:' || moving_ship_id || '. Fuel:' || current_fuel || '. Cost:' || fuel_cost || '. DirCost:' || direction_fuel_cost || '. finalspeed: ' || final_speed || ''';';
  79.                
  80.                 -- Move the ship!
  81.                 UPDATE
  82.                         ship
  83.                 SET
  84.                         current_fuel = final_fuel,
  85.                         location_x = ship.location_x + CAST(COS(RADIANS(final_direction)) * final_speed AS integer),
  86.                         location_y = ship.location_y + CAST(SIN(RADIANS(final_direction)) * final_speed AS integer),
  87.                         last_move_tic = (SELECT last_value FROM tic_seq)
  88.                 WHERE
  89.                         id = moving_ship_id;
  90.                
  91.                 -- Update ship_control so future ticks know how to move this ship
  92.                 UPDATE
  93.                         ship_control
  94.                 SET
  95.                         destination_x=new_destination_x,
  96.                         destination_y=new_destination_y,
  97.                         speed=new_speed,
  98.                         direction=final_direction
  99.                 WHERE
  100.                         ship_id = moving_ship_id;
  101.                
  102.  
  103.                 -- Re-retrieve the current ship stats
  104.                 SELECT INTO max_speed, current_fuel, location_x, location_y, range, ship_player_id  ship.max_speed, ship.current_fuel, ship.location_x, ship.location_y, ship.range, player_id FROM ship WHERE id=moving_ship_id;
  105.                 SELECT INTO current_speed, current_direction speed, direction FROM ship_control WHERE ship_id = moving_ship_id;
  106.  
  107.                 -- If the ship is in range of its target..
  108.                 IF (new_destination_x BETWEEN (location_x - range) AND (location_x + range) AND new_destination_y BETWEEN (location_y - range) AND (location_y + range)) THEN
  109.                     -- calculate how much fuel it would require to stop (or slow down as much as possible)
  110.                     IF (current_fuel >= current_speed) THEN
  111.                         final_fuel := current_fuel - current_speed;
  112.                         final_speed := 0;
  113.                         final_direction := 0;
  114.                     ELSE
  115.                         final_fuel := 0;
  116.                         final_speed := current_speed - current_fuel;
  117.                         final_direction := current_direction;
  118.                     END IF;
  119.                    
  120.                     -- Update the control and ship tables with the stopping results
  121.                     UPDATE ship_control
  122.                     SET speed = final_speed,
  123.                     direction = final_direction
  124.                     WHERE ship_id = moving_ship_id;
  125.  
  126.                     UPDATE ship
  127.                     SET current_fuel = final_fuel
  128.                     WHERE id = moving_ship_id;
  129.                 END IF;
  130.  
  131.                 RETURN 't';
  132.         ELSE
  133.                 EXECUTE 'NOTIFY ' || get_player_error_channel(GET_PLAYER_USERNAME(ship_player_id)) ||', ''Ship '|| moving_ship_id || ' did not budge!'';';
  134.                 RETURN 'f';
  135.         END IF;
  136. END
  137. $BODY$
  138.   LANGUAGE plpgsql VOLATILE SECURITY DEFINER;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement