private function separationMatrix()
 {
     $acumPlus = array();
     $acumMinus = array();
     for ($i = 0; $i < $this->N; $i++) {
         $acumPlus[$i] = $acumMinus[$i] = 0;
         for ($j = 0; $j < $this->M; $j++) {
             $this->Dplus[$i][$j] = distanceBetween($this->envelopes[$i][$j], $this->pis[$j]);
             $acumPlus[$i] += $this->Dplus[$i][$j];
             $this->Dminus[$i][$j] = distanceBetween($this->envelopes[$i][$j], $this->nis[$j]);
             $acumMinus[$i] += $this->Dminus[$i][$j];
         }
     }
     if ($this->debug) {
         echo '<br>D+<pre>';
         print_r($this->Dplus);
         echo '</pre>';
         echo '<br>acum of D+<pre>';
         print_r($acumPlus);
         echo '</pre>';
         echo '<br>D-<pre>';
         print_r($this->Dminus);
         echo '</pre>';
         echo '<br>acum of D-<pre>';
         print_r($acumMinus);
         echo '</pre>';
     }
     //compute the closeness coefficient RC(A_i)
     for ($i = 0; $i < $this->N; $i++) {
         $this->RC[$i] = $acumMinus[$i] / ($acumPlus[$i] + $acumMinus[$i]);
         //echo $this->RC[$i] . "<br>";
     }
 }
Exemple #2
0
/**
 * 计算两个坐标之间的距离(米)
 * @param float $fP1Lat 起点(纬度)
 * @param float $fP1Lon 起点(经度)
 * @param float $fP2Lat 终点(纬度)
 * @param float $fP2Lon 终点(经度)
 * @return int
 */
function echoDistance($fP1Lat, $fP1Lon, $fP2Lat, $fP2Lon)
{
    if ($fP1Lat === '' || $fP1Lon === '' || $fP2Lat === '' || $fP2Lon === '') {
        return '';
    }
    $distance = distanceBetween($fP1Lat, $fP1Lon, $fP2Lat, $fP2Lon);
    if ($distance > 1000) {
        $distance = round($distance / 1000) . 'km';
    } else {
        $distance .= 'M';
    }
    return $distance;
}
function rigorMortis()
{
    global $sVars, $rmd, $rmtick, $rmLastPush, $rmCount, $rmSCount, $rmSendCount, $rmBuffer, $rmStartTick, $rmLastID;
    global $rm, $rmMap;
    global $rmeHistory;
    global $send, $sendTo;
    $rmd = $rmtick;
    $rmtick = floor(microtime(true) * 1000) - $rmStartTick;
    $rmd = $rmtick - $rmd;
    $rmLastPush += $rmd;
    $rmSCount += $rmd;
    $rmCount++;
    //echo "RMD|$rmd|LAST|$rmLastPush\n";
    //echo "\033[s\033[0F\033[1;37;41m"; // Save cursor position, start color change
    //echo "Tick: " . $rmtick . " / Last: ".$rmLastPush; // Output server time
    //echo "\033[m\033[u"; // End color change, restore cursor position
    if ($rmLastPush >= 1000 / $rm['netFrequency']) {
        if (isset($sVars['observing'])) {
            /* Server Logic, Send & Receive Prefixes ################################################### SERVER LOGIC, SEND & RECEIVE PREFIXES #########################################################################
            			   
                        ----------======== SERVER LOGIC RULES =========-------------
                        All values ROUNDed to the thousandth. 3-point precision. (3.142)
                        
                        +-------------------------     SEND PREFIXES     ------------------------+
                        |                      THESE ARE  ALL PREFIXED WITH ~                    |
                        
                        vL[variable]T[value] - Set player variable [VARNAMELENGTH / NAME / VALUETYPECHAR / VALUE
                                                e.g. v5speed2300 <-- [300 being UI16]
                        ValueTypeChars. 1-4: BigEndian Integer, a-z: String of length [letter] (j=10)           //// Not yet implemented
                        
                        i## - Unsigned16 - Iterations since last push
                        xTICK - Unsigned32 - Ticks since server start [Caps out at about 39 months]
                        T"""""""" - String8 - HH:MM:SS Server Time
                        p## - Unsigned16 - Time since last net push
                        P# - Unsigned8 - Current packet being sent through this (in 1 second time frame)
                        
                        D## - Unsigned16 - CLIENT DISCONNECT [CLIENTID UI16]
            			
            			                    ALL DELTA UI16s ARE CURRENTLY TIME UI32s. RECEIVED VALUES ARE MULTIPLES OF 7BIT, SENT ARE OF 8BIT
            			
                        ========== Initiate...
                        Id##TTTT - Send player their client ID & servers current tick [UI16 / UI32 SERVER TIME-TICK]
                        IpXXXXYYYY - Initiate player [XPOS*10000 UI32 / YPOS*10000 UI 32]
                        IeXXYYWWHH - Initiate emitter [XPOS UI16 / YPOS UI 16 / WIDTH UI 16 / HEIGHT UI 16] // Not yet implemented
                        Iz##TIMEXXYYTHP - Initiate zombie [ZOMBIEID UI16 / TIME UI32 / XPOS UI16 / YPOS UI16 / TYPE UI8 / HP UI16]
            			Io##TIMEXXYYTT - Initiate object [OBJECTID UI16 / TIME UI32 / XPOS UI16 / YPOS UI16 / TYPE UI16 ]
                        
                        ========== Object...
                        Od##TIME - Object destroy [OBJECTID UI16 / TIME UI32]
                        Ou## - Object update variable [OBJECTID UI16 / TIME UI32 / VARIABLE UI8 / VALUE UI32]
                        
                        ========== World updates
                        Wp##XXXXYYYYDD - Push any players ID,X,Y to another player [ID / X / Y / REPLAYDELAY-aka-LERP UI 16]
                        Wl##DD - Push players lerp/ReplayDelay to another player [CLIENTID UI16 / REPLAYDELAY UI16]
            	    
            			W=##DD - Push players syncDelay to another player [TIME UI32 / SYNCDELAY UI32] // REMOVED
            	    
                        ========== Buffer updates
                        Bp##DDXXXXYYYYDDDDSS - PUSH: Player movement buffer addition - [CLIENTID UI16 / TIME UI32 / XPOS*1000 UI32 / YPOS*1000 UI16 / (DIR+PI)*1000 UI16 / SPEED UI16]
                        Bf##DD - PUSH: Player has fired [CLIENTID UI16 / TIME UI32]
                        BF##DDd - PUSH: Player changed facing direction to d [CLIENTID UI16 / TIME UI32 / DIRECTION UI8]
                        B=##DD - PUSH: Player is keeping alive  [CLIENTID UI16 / TIME UI32] ****POTENTIAL BANDWIDTH REDUCTION. NEVER/RARELY SEND THIS, BUT, INCREASE SIZE OF SENT DELTA****
                        
                        BZp##TIMEXXXXYYYYDDDDSS - PUSH: Zombie movement buffer add - [ZOMBIEID UI16 / TIME UI32 / XPOS*1000 UI32 / YPOS*1000 UI16 / (DIR+PI)*1000 UI16 / SPEED UI16]
                        BZc##TIMEID - PUSH: Zombie start chasing player ID at TIME [PID UI16 / TIME UI32 / ZOMBIEID16]
                        BZh##TIMEHP - PUSH: Zombie health [ZID UI16 / TIME UI32 / HP UI16]
                        
            			= - Ping player, wait for response to determine players latency.
            	    
                        +---------------------     RECEIVE PREFIXES     -------------------------+
                        |                   THESE ARE ALSO ALL PREFIXED WITH ~                   |
                        (Do not accept authoritative data. Inputs only). Add to buffer
                        
                        0x00DD - Stop all movement (for when user is holding a key, then changes focus) - Time UI28
                        -DD - Ping - Time UI28 // Client requests to keep connection open
            			= - Pong
                        kDD# - Keydown UI7 - Time UI28  ***ALL DELTA UI14'S ARE CURRENTLY UI28's***
                        KDD# - Keyup UI7 - Time UI28
                        fDD - Fire - Time UI28
                        FDD# - Facing direction - [TIME UI28 / DIRECTION UI7] // Not yet implemented
            			
                        R#GAMEDD - Request entry to GAME# UI7 / GAMESTART UI28 / REPLAYDELAY UI14
                        
                        +------------------------     OBJECT IDs      ----------------------------+
            			|                                                                         |
            			| 14bit: 0-16383, 16bit: 0-65535                                          |
            			|                                                                         |
            			| 1001 - Money :: [0] - Amount UI21 (0-2,097,152)
            			
            			*/
            $rmSendCount++;
            for ($i = 0; $i < count($sVars['observing']); $i++) {
                send("~i" . pack("n", $rmCount) . "p" . pack("n", $rmLastPush) . "x" . pack("N", $rmtick) . "P" . pack("C", $rmSendCount), $sVars['observing'][$i], true);
            }
            if (!$rmSendCount) {
                echo "\n";
            }
            //echo "OBS[$rmSendCount]";
        }
        //############################### ALL INITIATE ACTIONS NEED TO BE DONE BEFORE BUFFERS. IF NOT, BUFFER WILL HAVE NOTHING TO MODIFY
        //############################### INITIATE ACTIONS TIME SHOULD NOT BE REQUIRED BECAUSE BUFFER SHOULD COME ASAP AFTER
        // However, initiate actions should really only be sent on game request. Client should handle buffer-only updates after that
        if ($rm['gameRunning'][0]) {
            // Actions based on player buffers, players
            foreach ($rm['p'] as $j => &$k) {
                if (isset($k['game']) && isset($rmBuffer[$j])) {
                    /*if (count($rmBuffer[$j]) == 1) {
                    			$tmp = round(atan2($k['keyv'][1],$k['keyv'][0]),3);
                    			$calcArray = array($k[0],$k[1],$tmp,$k[3]); // Send oldx, oldy, oldDIR, oldSpeed
                    			$calcArray['size'] = $k['size']; // Must transmit size of this unit to run collision checks properly
                    			$tpos = calculateNewPosition($rmtick-$rmBuffer[$j][count($rmBuffer[$j])-1][1], $calcArray); // Send new delta along with unit values
                    			
                    			$k[0] = $tpos[0]; $k[1] = $tpos[1]; $k[2] = $tpos[2]; $k[3] = $tpos[3];
                    			
                    			$rmBuffer[$j][count($rmBuffer[$j])-1][1] = $rmtick;
                    		}*/
                    if (count($rmBuffer[$j]) == 1) {
                        // Pre-position collision checking
                        $tmp = round(atan2($k['keyv'][1], $k['keyv'][0]), 3);
                        //addlog("\033[1;37;44mPre-Colliz Chk: (".$k[0].",".$k[1].") From X: ".round(cos($tmp) * $k[3] * ($rmtick-$rmBuffer[$j][count($rmBuffer[$j])-1][1]-$k['lerp'])*0.001,3)." -or- ".$rmtick." - ".$rmBuffer[$j][count($rmBuffer[$j])-1][1]." - L".$k['lerp']);
                        $calcArray = array($k[0] + round(cos($tmp) * $k[3] * ($rmtick - $rmBuffer[$j][count($rmBuffer[$j]) - 1][1] - $k['lerp']) * 0.001, 3), $k[1] + round(sin($tmp) * $k[3] * ($rmtick - $rmBuffer[$j][count($rmBuffer[$j]) - 1][1] - $k['lerp']) * 0.001, 3), 'size' => $k['size']);
                        //addlog("Collision checking (".$calcArray[0].",".$calcArray[1].")");
                        $col = collisionCheck($calcArray);
                        // Check current position of this player and reposition them if necessary
                        if (isset($col['collision'])) {
                            if (count($rmBuffer[$j]) == 1) {
                                $k[0] = $col[0];
                                $k[1] = $col[1];
                                $send .= 'Bp' . pack('n', $j) . pack('N', $rmtick - $k['lerp']) . pack('N', round($k[0] * 1000)) . pack('N', round($k[1] * 1000)) . pack('N', round(($tmp + M_PI) * 1000)) . pack('n', $k[3]);
                                $rmBuffer[$j][count($rmBuffer[$j]) - 1][1] = $rmtick - $k['lerp'];
                                //addlog("LAST RMBUFFER CHANGED TO ".$rmtick-$k['lerp']);
                            } else {
                                // This triggers when releasing a key while pressed against a wall
                                //addlog("MORE THAN 1 BUFFER, WAS CHANGED TO ".$rmtick-$k['lerp']);
                                $k[0] = $col[0];
                                $k[1] = $col[1];
                                $send .= 'Bp' . pack('n', $j) . pack('N', $rmtick - $k['lerp']) . pack('N', round($k[0] * 1000)) . pack('N', round($k[1] * 1000)) . pack('N', round(($tmp + M_PI) * 1000)) . pack('n', $k[3]);
                                $rmBuffer[$j][count($rmBuffer[$j]) - 1][1] = $rmtick - $k['lerp'];
                            }
                        } else {
                            //$k[0] = $col[0]; $k[1] = $col[1];
                            //$rmBuffer[$j][count($rmBuffer[$j])-1][1] = $rmtick-$k['lerp'];
                        }
                        //addlog("\033[m");
                        // addlog("\033[1;33;40m".print_r($rmBuffer[$j],true)."\033[m");
                    }
                    //addlog("####XPOS:".$k[0].",YPOS:".$k[1]);
                    for ($i = 1; $i < count($rmBuffer[$j]); $i++) {
                        $tbuff = array();
                        $tmp = round(atan2($k['keyv'][1], $k['keyv'][0]), 3);
                        /*$calcArray = array($k[0],$k[1],$tmp,$k[3]); // Send oldx, oldy, oldDIR, oldSpeed
                        		$calcArray['size'] = $k['size']; // Must transmit size of this unit to run collision checks properly
                        		$tpos = calculateNewPosition($rmBuffer[$j][$i][1]-$rmBuffer[$j][$i-1][1], $calcArray); // Send new delta along with unit values
                        		
                        		$k[0] = $tpos[0]; $k[1] = $tpos[1]; $k[2] = $tpos[2]; $k[3] = $tpos[3];*/
                        // Standard position processing
                        // If old delta is newer than the current. Something was injected in the future incorrectly. Throwout next position update by merging deltas.
                        // This can stall for time but eventually will cause a problem. Too low latency, things walk through walls.
                        //if ($rmBuffer[$j][$i-1][1]>$rmBuffer[$j][$i][1]) { $rmBuffer[$j][$i-1][1] = $rmBuffer[$j][$i][1]; }
                        // Instead of the above; don't change the time of this buffer, just ignore it. Or it will cause issues with next iteration collision checks
                        //if ($rmBuffer[$j][$i-1][1]>$rmBuffer[$j][$i][1]) { $tmpd = 0; }
                        //else { $tmpd = $rmBuffer[$j][$i][1]-$rmBuffer[$j][$i-1][1]; }
                        $tmpd = $rmBuffer[$j][$i][1] - $rmBuffer[$j][$i - 1][1];
                        // Allow delta setting regardless
                        // Update 8/22/2013: All goes well until the buffer is larger than 1 and there is a collision. The next time the buffer is 1 again
                        // the delta gets so high it causes the unit to jump through the wall.
                        // Update: Seems this is partially caused by a drastically changing lerp while in-game.
                        // Update: Caused by clients latency changing, causing their time sync to be off of the servers. Even if lerp remains unchanged, a large change in latency will ruin collision checking.
                        //addlog("\033[1;37;41mPre-B2+Col Chk: (".$k[0].",".$k[1].") From X: ".round(cos($tmp) * $k[3] * ($tmpd)*0.001,3));
                        $k[0] += round(cos($tmp) * $k[3] * $tmpd * 0.001, 3);
                        // Set xpos from oldx + oldDIR * oldSP * newdelta
                        $k[1] += round(sin($tmp) * $k[3] * $tmpd * 0.001, 3);
                        // Set ypos from ypos + (oldDIR * oldSP * (newdelta))
                        $calcArray = array($k[0], $k[1], 'size' => $k['size']);
                        //addlog("B2+ Collision checking (".$calcArray[0].",".$calcArray[1].")");
                        //addlog("Buffer deltas ".$rmBuffer[$j][$i][1]." - ".$rmBuffer[$j][$i-1][1]."\033[m");
                        $col = collisionCheck($calcArray);
                        if (isset($col['collision'])) {
                            $k[0] = $col[0];
                            $k[1] = $col[1];
                            $send .= 'Bp' . pack('n', $j) . pack('N', $rmtick - $k['lerp']) . pack('N', round($k[0] * 1000)) . pack('N', round($k[1] * 1000)) . pack('N', round(($tmp + M_PI) * 1000)) . pack('n', $k[3]);
                            //$rmBuffer[$j][$i][1] = $rmtick-$k['lerp'];
                            //$rmBuffer[$j][$i][1] = $rmtick;
                        } else {
                            // Fires when pressing a key while already pressed against a wall, or just regular buffer additions.
                            if ($i == count($rmBuffer[$j]) - 1) {
                                //$rmBuffer[$j][$i][1] = $rmtick-$k['lerp'];
                            }
                        }
                        //addlog(print_r($k,true));
                        if ($rmBuffer[$j][$i][0] == chr(0)) {
                            // Movement ALL-STOP
                            $k[3] = 0;
                            $k['keyv'] = array(0, 0);
                            $k['keyb'] = array();
                            //addlog('Movement all-stop (Client lost focus)');
                            $send .= 'Bp' . pack('n', $j) . pack('N', $rmBuffer[$j][$i][1]) . pack('N', round($k[0] * 1000)) . pack('N', round($k[1] * 1000)) . pack('N', round(($k[2] + M_PI) * 1000)) . pack('n', $k[3]);
                        } elseif ($rmBuffer[$j][$i][0] == '=') {
                            // Ping, to stay synced with server
                            //$send .= 'B='.pack('n',$j).pack('n',$rmBuffer[$j][$i][1]); // Forward this ping so other players deltas are correct
                            //addlog('Forwarded keep-alive ping');
                        } elseif ($rmBuffer[$j][$i][0] == 'k') {
                            // Keydown
                            //$k[0] += round($k['keyv'][0] * $k[3] * $rmBuffer[$j][$i][2]*0.001,3); // Set xpos from oldx + oldDIR * oldSP * newdelta
                            //$k[1] += round($k['keyv'][1] * $k[3] * $rmBuffer[$j][$i][2]*0.001,3);
                            //addlog('DO new calc: '.$k['keyv'][0].'*'.$k[3].'*'.($rmBuffer[$j][$i][1]-$rmBuffer[$j][$i-1][1])*0.001);
                            if (!in_array($rmBuffer[$j][$i][2], $k['keyb'])) {
                                // Only continue if keys aren't already down
                                $tbuff[3] = $k['speed'];
                                if ($rmBuffer[$j][$i][2] == 68) {
                                    // Right
                                    $k['keyb'][] = 68;
                                    $k['keyv'][0] += 1;
                                } elseif ($rmBuffer[$j][$i][2] == 87) {
                                    // Up
                                    $k['keyb'][] = 87;
                                    $k['keyv'][1] -= 1;
                                } elseif ($rmBuffer[$j][$i][2] == 65) {
                                    // Left
                                    $k['keyb'][] = 65;
                                    $k['keyv'][0] -= 1;
                                } elseif ($rmBuffer[$j][$i][2] == 83) {
                                    // Down
                                    $k['keyb'][] = 83;
                                    $k['keyv'][1] += 1;
                                }
                                $tbuff[2] = round(atan2($k['keyv'][1], $k['keyv'][0]), 3);
                                // Standard movement without collisions check
                                $send .= 'Bp' . pack('n', $j) . pack('N', $rmBuffer[$j][$i][1]) . pack('N', round($k[0] * 1000)) . pack('N', round($k[1] * 1000)) . pack('N', round(($tbuff[2] + M_PI) * 1000)) . pack('n', $tbuff[3]);
                                //addlog("#CLIENT".$j."MOVE@".$rmBuffer[$j][$i][1]."|X:".$k[0].",Y:".$k[1].",D:".$tbuff[2].",S:".$tbuff[3]);
                                // For now, when a key is pressed down, we will also broadcast this clients lerp
                                //$send .= 'Wl'.pack('n',$j).pack('n',$rm['p'][$j]['lerp']);
                                //addlog("Transmitted a lerp of: ".$rm['p'][$j]['lerp']);
                                // #REVISE: For now, we will ping the client to judge their lerp. Later this should be done periodically
                                //if (!isset($rm['p'][$j]['ping'])) { // Only prepare if not already waiting to receive pong
                                //	$send .= '=';
                                //	$rm['p'][$j]['ping'] = $rmtick; // Prepare to receive pong
                                //}
                                //$send .= 'Wl'.pack('n',$j).pack('n',$rm['p'][$j]['lerp']);
                                $k[2] = $tbuff[2];
                                // Update direction
                                $k[3] = $tbuff[3];
                                // Update new speed
                            }
                        } elseif ($rmBuffer[$j][$i][0] == 'K') {
                            // Keyup
                            //$k[0] += round($k['keyv'][0] * $k[3] * $rmBuffer[$j][$i][2]*0.001,3); // Set xpos from oldx + oldvectorx * oldSP * newdelta
                            //$k[1] += round($k['keyv'][1] * $k[3] * $rmBuffer[$j][$i][2]*0.001,3); // Set ypos from oldy + oldvectory * oldSP * newdelta
                            //addlog('UP new calc: '.$k['keyv'][0].'*'.$k[3].'*'.($rmBuffer[$j][$i][1]-$rmBuffer[$j][$i-1][1])*0.001);
                            //addlog('KeyBefore: '.var_dump($k['keyb']));
                            if ($rmBuffer[$j][$i][2] == 68) {
                                // Right
                                if (array_search(68, $k['keyb']) !== false) {
                                    $k['keyv'][0] -= 1;
                                    array_splice($k['keyb'], array_search(68, $k['keyb']), 1);
                                }
                            } elseif ($rmBuffer[$j][$i][2] == 87) {
                                // Up
                                if (array_search(87, $k['keyb']) !== false) {
                                    $k['keyv'][1] += 1;
                                    array_splice($k['keyb'], array_search(87, $k['keyb']), 1);
                                }
                            } elseif ($rmBuffer[$j][$i][2] == 65) {
                                // Left
                                if (array_search(65, $k['keyb']) !== false) {
                                    $k['keyv'][0] += 1;
                                    array_splice($k['keyb'], array_search(65, $k['keyb']), 1);
                                }
                            } elseif ($rmBuffer[$j][$i][2] == 83) {
                                // Down
                                if (array_search(83, $k['keyb']) !== false) {
                                    $k['keyv'][1] -= 1;
                                    array_splice($k['keyb'], array_search(83, $k['keyb']), 1);
                                }
                            }
                            //addlog('KeyAfter: '.var_dump($k['keyb']));
                            if (empty($k['keyb']) || !$k['keyv'][0] && !$k['keyv'][1]) {
                                //addlog('Player STOP empty?'.empty($k['keyvb']).'---or?'.(!$k['keyv'][0] && !$k['keyv'][1]));
                                $tbuff[3] = 0;
                                // Player speed has stopped
                                $tbuff[2] = $k[2];
                                // Direction can stay the same
                            } else {
                                $tbuff[2] = round(atan2($k['keyv'][1], $k['keyv'][0]), 3);
                                // Direction has simply changed
                                $tbuff[3] = $k[3];
                                // Speed remains the same
                            }
                            $send .= 'Bp' . pack('n', $j) . pack('N', $rmBuffer[$j][$i][1]) . pack('N', round($k[0] * 1000)) . pack('N', round($k[1] * 1000)) . pack('N', round(($tbuff[2] + M_PI) * 1000)) . pack('n', $tbuff[3]);
                            //addlog("#CLIENT".$j."MOVE@".$rmBuffer[$j][$i][1]."|X:".$k[0].",Y:".$k[1].",D:".$tbuff[2].",S:".$tbuff[3]);
                            $k[2] = $tbuff[2];
                            // Update direction
                            $k[3] = $tbuff[3];
                            // Update new speed
                        } elseif ($rmBuffer[$j][$i][0] == 'f') {
                            // We need to calculate this actual k0,k1 position at this time
                            // We can't just use [] because it ends up ruining the structure of the array. Deletes weapons
                            for ($int = 0; $int < count($rm['bullets']); $int++) {
                                if (!isset($rm['bullets'][$int])) {
                                    break;
                                }
                            }
                            $rm['bullets'][$int] = array($k[0], $k[1], $k['aim'] / (128 / (M_PI * 2)) - M_PI, $rm['bullets']['pistol']['speed'], $j);
                            $send .= 'Bf' . pack("n", $j) . pack("N", $rmBuffer[$j][$i][1]);
                            // Send clientID, delta
                            //addlog("##ADDED## Fire from client ".$j." @ ".$rmBuffer[$j][$i][1]);
                        } elseif ($rmBuffer[$j][$i][0] == 'F') {
                            $k['aim'] = $rmBuffer[$j][$i][2];
                            // To get dir from this:: players[i]['aim']/(128/(Math.PI*2))-Math.PI = Direction
                            $send .= 'BF' . pack("n", $j) . pack("N", $rmBuffer[$j][$i][1]) . pack("C", $rmBuffer[$j][$i][2]);
                            //addlog("#CLIENT".$j." FACES ".$rmBuffer[$j][$i][2]." @ ".$rmBuffer[$j][$i][1]);
                        }
                        if (isset($col['collision'])) {
                            // Position overwrite and movement reset due to previous collision
                            $send .= 'Bp' . pack('n', $j) . pack('N', $rmtick - $k['lerp']) . pack('N', round($k[0] * 1000)) . pack('N', round($k[1] * 1000)) . pack('N', round(($tmp + M_PI) * 1000)) . pack('n', $k[3]);
                        }
                        //$send .= 'Bp'.pack("n",$j).$rmBuffer[$j][0];
                    }
                    //addlog("@@@@XPOS:".$k[0].",YPOS:".$k[1]);
                    //////////// Post position collision checking
                    /*$tmp = round(atan2($k['keyv'][1],$k['keyv'][0]),3);
                    		$calcArray = array(
                    						   $k[0] + round(cos($tmp) * $k[3] * ($rmtick-$rmBuffer[$j][count($rmBuffer[$j])-1][1]-$k['lerp'])*0.001,3),
                    						   $k[1] + round(sin($tmp) * $k[3] * ($rmtick-$rmBuffer[$j][count($rmBuffer[$j])-1][1]-$k['lerp'])*0.001,3),
                    						   
                    						   //$k[0] + round(cos($tmp) * $k[3] * ($rmLastPush)*0.001,3),
                    						   //$k[1] + round(sin($tmp) * $k[3] * ($rmLastPush)*0.001,3),
                    						   
                    						   
                    						   'size' => $k['size']
                    						   );
                    		//addlog("Using ".$rmLastPush." not ".($rmtick-$rmBuffer[$j][count($rmBuffer[$j])-1][1]));
                    		addlog("Collision checking (".$calcArray[0].",".$calcArray[1].")");
                    		$col = collisionCheck($calcArray); // Check current position of this player and reposition them if necessary
                    		
                    		if (isset($col['collision'])) {
                    			$k[0] = $col[0]; $k[1] = $col[1];
                    			
                    			//$send = ''; // Cancel out any previous pending movement sends
                    			$send .= 'Bp'.pack('n',$j).pack('N',$rmtick-$k['lerp']).pack('N',round($k[0]*1000)).pack('N',round($k[1]*1000)).pack('N',round(($tmp+M_PI)*1000)).pack('n',$k[3]);
                    			$rmBuffer[$j][count($rmBuffer[$j])-1][1] = $rmtick-$k['lerp'];
                    		} else {
                    			//$k[0] = $col[0]; $k[1] = $col[1];
                    		}*/
                    // Calc new position
                    // Will periodically check for collisions and move players even if buffer has not changed
                    /*$tmp = round(atan2($k['keyv'][1],$k['keyv'][0]),3);
                    		$calcArray = array($k[0],$k[1],$tmp,$k[3]);
                    		$calcArray['size'] = $k['size'];
                    		
                    		$tpos = calculateNewPosition($rmtick-$rmBuffer[$j][count($rmBuffer[$j])-1][1], $calcArray);
                    		addlog("Calculated New Pos: (".$tpos[0].",".$tpos[1].")");
                    		$rmBuffer[$j][count($rmBuffer[$j])-1][1] = $rmtick; // Set the last time this buffer was accessed to current time. Makes ready for when a change to buffer comes, or next collision check.
                    		
                    		$k[0] = $tpos[0]; $k[1] = $tpos[1]; $k[2] = $tpos[2]; $k[3] = $tpos[3];*/
                    //$send .= 'Bp'.pack('n',$j).pack('N',$rmBuffer[$j][$i][1]).pack('N',round($k[0]*1000)).pack('N',round($k[1]*1000)).pack('N',round(($k[2]+M_PI)*1000)).pack('n',$k[3]);
                    $rmBuffer[$j] = array_slice($rmBuffer[$j], count($rmBuffer[$j]) - 1);
                    // Save the last sent packet to use for the next buffer push
                    //$rmBuffer[$j][0][1] = $rmtick; // Set the time last accessed of this buffer to current time
                } else {
                    //addlog("Client $j is not a player.");
                }
            }
            // Actions based on time
            for ($i = 0; $i < count($rm['emitters']); $i++) {
                if ($rmtick > $rm['emitters'][$i]['next']) {
                    $tmp = array(randomInt($rm['emitters'][$i][0], $rm['emitters'][$i][2]), randomInt($rm['emitters'][$i][1], $rm['emitters'][$i][3]), randomInt($rm['enemies'][$rm['emitters'][$i]['type']]['hp']));
                    $rm['emitters'][$i]['next'] = $rmtick + randomInt($rm['emitters'][$i]['frequency']);
                    $num = count($rm['enemies']) - (count($rm['enemies']['types']) + 1);
                    // Don't take into account string indices on enemies when counting
                    for ($j = 0; $j <= $num; $j++) {
                        if (!isset($rm['enemies'][$j])) {
                            $k = $j;
                            break;
                            // Find the earliest zombie ID slot we can use
                        }
                    }
                    //$j = count($rm['enemies'])-(count($rm['enemies']['types'])+1);
                    $rm['enemies'][$k] = array(0 => $tmp[0], 1 => $tmp[1], 2 => 0, 3 => 0, 'type' => $rm['emitters'][$i]['type'], 'hp' => $tmp[2], 'maxhp' => $tmp[2], 'attack' => array(0, 0));
                    $rmeHistory[$k] = array(array($rmtick, $tmp[0], $tmp[1], 0, 0));
                    addlog('Sent zombie [' . $k . ']:');
                    $tmpType = max(array_search($rm['emitters'][$i]['type'], $rm['enemies']['types']), 0);
                    // Try to find this emitter type to spawn or default to 0
                    $send .= 'Iz' . pack('n', $k) . pack('N', $rmtick) . pack('n', $tmp[0]) . pack('n', $tmp[1]) . pack('C', $tmpType) . pack('n', $tmp[2]);
                    // Initiate zombie
                }
            }
            // Enemy tick
            foreach ($rm['enemies'] as $j => &$k) {
                if (is_numeric($j)) {
                    if (isset($k['chasing'])) {
                        // #REVISE: $rmeHistory must be constantly optimized to reduce memory usage
                        $k[2] = round(atan2($rm['p'][$k['chasing']][1] - $k[1], $rm['p'][$k['chasing']][0] - $k[0]), 3);
                        // Set direction
                        if (distanceBetween($k[0], $k[1], $rm['p'][$k['chasing']][0], $rm['p'][$k['chasing']][1]) > $rm['enemies'][$k['type']]['stopDistance']) {
                            $k[3] = $rm['enemies'][$k['type']]['speed'];
                            $k[0] += round(cos($k[2]) * $k[3] * $rmLastPush * 0.001, 3);
                            $k[1] += round(sin($k[2]) * $k[3] * $rmLastPush * 0.001, 3);
                            //$update = true;
                            $rmeHistory[$j][] = array($rmtick, $k[0], $k[1], $k[2], $k[3]);
                        } else {
                            //if ($k[3] != 0) $update = true;
                            if ($k[3] != 0) {
                                addlog("FoolZombie {$j} stopped moving at " . $k[0] . "," . $k[1] . ".");
                                $k[3] = 0;
                                $rmeHistory[$j][] = array($rmtick, $k[0], $k[1], $k[2], $k[3]);
                            }
                            // Else, it's already 0, and stopped
                            // Stop moving if we are closer than the stopDistance
                        }
                    } else {
                        foreach ($rm['p'] as $l => &$m) {
                            // #REVISE: We should only check players that are physically nearby to enemy
                            if (isset($m['game'])) {
                                // Only set to chase if logged in to a game
                                if (distanceBetween($k[0], $k[1], $m[0], $m[1]) < $rm['enemies'][$k['type']]['chaseRange']) {
                                    // Initiate chase
                                    //addlog("Well $j is now chasing $l");
                                    $k['chasing'] = $l;
                                    //Let client know this enemy is chasing them
                                    $send .= 'BZc' . pack('n', $l) . pack('N', $rmtick) . pack('n', $j);
                                    //addlog('Send:::'.$send);
                                    //break; // This break is really fucking things up. Game will lose complete sync. Later found in another foreach iteration, it might be a problem with using $l and $m as variables, as they are used again later for network send
                                    //addlog('Distance:'.distanceBetween($k[0],$k[1],$m[0],$m[1]).' <? '.$rm['enemies'][$k['type']]['chaseRange']);
                                } else {
                                    //addlog('No Distance:'.round(distanceBetween($k[0],$k[1],$m[0],$m[1]),3).' <? '.$rm['enemies'][$k['type']]['chaseRange']);
                                }
                            }
                        }
                    }
                }
            }
            //Bullet operations
            foreach ($rm['bullets'] as $j => &$k) {
                if (is_numeric($j)) {
                    // Only iterate over actual bullets
                    //echo var_dump($k);
                    //echo "Iterate".$j;
                    $k['last'] = array($k[0], $k[1]);
                    $k[0] = round($k[0] + cos($k[2]) * $k[3] * $rmLastPush * 0.001, 3);
                    $k[1] = round($k[1] + sin($k[2]) * $k[3] * $rmLastPush * 0.001, 3);
                    if ($k[0] < 0 || $k[1] < 0 || $k[0] > $rm['clientWidth'] || $k[1] > $rm['clientHeight']) {
                        // Client bounds only for now
                        //echo 'Removed bullet'.$j.'/::'.var_dump($rm['bullets'][$j]);
                        unset($rm['bullets'][$j]);
                    } else {
                        // If the bullet is still around, lets check all collisions
                        //echo ">BULLET:X:".$k[0].":Y:".$k[1]."<";
                        $collisions = array();
                        foreach ($rm['enemies'] as $n => &$o) {
                            if (is_numeric($n)) {
                                $rewind = array();
                                // This will be an array of the enemy where it was $usersDelay msecs ago
                                //$usersDelay = 0; // We'll need to know the users delay from user[bulletOwner][delay]
                                $usersDelay = $rm['p'][$k[4]]['lerp'];
                                for ($i = count($rmeHistory[$n]) - 1; $i >= 0; $i--) {
                                    // Start from the latest and movie back
                                    if ($rmeHistory[$n][$i][0] <= $rmtick - $usersDelay) {
                                        // Continue back through the array until we are at time of this user, and the currently iterated enemy
                                        $rewind = array(0, 0, $rmeHistory[$n][$i][3], $rmeHistory[$n][$i][4]);
                                        // Same direction and speed
                                        $tmpdel = $rmtick - $usersDelay - $rmeHistory[$n][$i][0];
                                        // Delta since this history point in time
                                        $rewind[0] = $rmeHistory[$n][$i][1] + cos($rmeHistory[$n][$i][3]) * $rmeHistory[$n][$i][4] * $tmpdel * 0.001;
                                        $rewind[1] = $rmeHistory[$n][$i][2] + sin($rmeHistory[$n][$i][3]) * $rmeHistory[$n][$i][4] * $tmpdel * 0.001;
                                        //////////echo '  |TICK'.$i.':'.$rmeHistory[$i][0].','.$rmeHistory[$i][1].','.$rmeHistory[$i][2].'|  ';
                                        //echo "\n\nPOSITION FOR $n AT TIME ".$rmtick."::".var_dump($rmeHistory[$n][$i])."\n\n";
                                        break;
                                    }
                                }
                                //These will throw undefined index errors if user makes an action at a time less than 0. (e.g. his delay is 3000 and $rmtick is only at 1000)
                                $collide = false;
                                @($rewind[0] -= $rm['enemies'][$o['type']][0] / 2);
                                // This will now contain the position of the enemy at currentTime MINUS
                                @($rewind[1] -= $rm['enemies'][$o['type']][1] / 2);
                                // userDelay. Allowing for proper bullet hit detection
                                @($rewind[2] = $rm['enemies'][$o['type']][0]);
                                @($rewind[3] = $rm['enemies'][$o['type']][1]);
                                //if (isset($rewind[0])) echo "\nBOUNDS($n)::".$rewind[0].",".$rewind[1].",".$rewind[2].",".$rewind[3];
                                if (isset($k['last'])) {
                                    $collide = colLineRect(array($k[0], $k[1], $k['last'][0], $k['last'][1]), $rewind);
                                } else {
                                    $collide = posInBounds(array($k[0], $k[1]), $rewind);
                                }
                                /* if (isset($k['last'])) {
                                				$collide = colLineRect(array($k[0],$k[1],$k['last'][0],$k['last'][1]),array($o[0]-$rm['enemies'][$o['type']][0]/2,$o[1]-$rm['enemies'][$o['type']][1]/2,$rm['enemies'][$o['type']][0],$rm['enemies'][$o['type']][1]));
                                			} else {
                                				$collide = posInBounds(array($k[0],$k[1]),array($o[0]-$rm['enemies'][$o['type']][0]/2,$o[1]-$rm['enemies'][$o['type']][1]/2,$rm['enemies'][$o['type']][0],$rm['enemies'][$o['type']][1]));
                                			} */
                                if ($collide) {
                                    //$collisions[] = $n;
                                    $collisions[] = array($n, distanceBetween($rm['p'][$k[4]][0], $rm['p'][$k[4]][1], $k[0], $k[1]));
                                    //break;
                                }
                            }
                        }
                        // Collision processing
                        $penetrating = false;
                        // Penetration will trigger damage on the same enemies more than once
                        if (!!count($collisions)) {
                            // If 1 or more collisions
                            if ($penetrating) {
                                for ($i = 0; $i < count($collisions); $i++) {
                                    $rm['enemies'][$collisions[$i][0]]['hp'] -= randomInt($rm['bullets']['pistol']['damage']);
                                    $rm['enemies'][$collisions[$i][0]]['hp'] = max(0, $rm['enemies'][$collisions[$i][0]]['hp']);
                                    // Don't allow lower than 0
                                    //$send .= 'BZh'.pack('n',$collisions[$i][0]).pack('N',$rmtick-$usersDelay).pack('n',$rm['enemies'][$collisions[$i][0]]['hp']); // Send zombie health update [ID / TIME / HP]
                                    foreach ($rm['p'] as $p => &$q) {
                                        if (isset($q['game'])) {
                                            if (!isset($sendTo[$p])) {
                                                $sendTo[$p] = '';
                                            }
                                            $sendTo[$p] .= 'BZh' . pack('n', $collisions[$i][0]) . pack('N', $rmtick - $usersDelay - $q['lerp']) . pack('n', $rm['enemies'][$collisions[$i][0]]['hp']);
                                            // Send zombie health update [ID / TIME / HP]
                                        }
                                    }
                                    addlog("Bullet {$j} Collided with ID:" . $collisions[$i][0] . " (" . $i . "," . count($collisions) . ") making new hp " . $rm['enemies'][$collisions[$i][0]]['hp']);
                                    if ($rm['enemies'][$collisions[$i][0]]['hp'] <= 0) {
                                        $send .= createObject($rm['enemies'][$collisions[$i][0]][0], $rm['enemies'][$collisions[$i][0]][1], 1001, $rmtick - $usersDelay);
                                        $val = randomInt(1, 20);
                                        $rm['objects'][$rmLastID]['value'] = $val;
                                        //$send .= 'Io'.pack('n',$k).pack('N',$rmtick-$usersDelay).pack('n',$rm['enemies'][$collisions[$i][0]][0]).pack('n',$rm['enemies'][$collisions[$i][0]][1]).pack('n',1001));
                                        addlog("New money: " . print_r($rm['objects'][$rmLastID], true));
                                        unset($rm['enemies'][$collisions[$i][0]]);
                                        // Destroy zombie
                                        addlog("Zombie " . $collisions[$i][0] . " destroyed");
                                    }
                                }
                            } else {
                                $closest = array(0, $collisions[0][1]);
                                for ($i = 1; $i < count($collisions); $i++) {
                                    if ($collisions[$i][1] < $closest) {
                                        $closest = array($i, $collisions[$i][1]);
                                    }
                                }
                                $closest = $collisions[$closest[0]][0];
                                $rm['enemies'][$closest]['hp'] -= randomInt($rm['bullets']['pistol']['damage']);
                                $rm['enemies'][$closest]['hp'] = max(0, $rm['enemies'][$closest]['hp']);
                                // Don't allow lower than 0
                                //$send .= 'BZh'.pack('n',$collisions[$i]).pack('N',$rmtick-$usersDelay).pack('n',$rm['enemies'][$collisions[$i]]['hp']); // Send zombie health update [ID / TIME / HP]
                                foreach ($rm['p'] as $p => &$q) {
                                    if (isset($q['game'])) {
                                        if (!isset($sendTo[$p])) {
                                            $sendTo[$p] = '';
                                        }
                                        $sendTo[$p] .= 'BZh' . pack('n', $closest) . pack('N', $rmtick - $usersDelay - $q['lerp']) . pack('n', $rm['enemies'][$closest]['hp']);
                                        // Send zombie health update [ID / TIME / HP]
                                    }
                                }
                                addlog("Bullet {$j} Collided with single target (" . $closest . ") making new hp " . $rm['enemies'][$closest]['hp']);
                                if ($rm['enemies'][$closest]['hp'] <= 0) {
                                    $send .= createObject($rm['enemies'][$closest][0], $rm['enemies'][$closest][1], 1001, $rmtick - $usersDelay);
                                    $val = randomInt(1, 20);
                                    $rm['objects'][$rmLastID]['value'] = $val;
                                    //$send .= 'Io'.pack('n',$k).pack('N',$rmtick-$usersDelay).pack('n',$rm['enemies'][$collisions[$i][0]][0]).pack('n',$rm['enemies'][$collisions[$i][0]][1]).pack('n',1001));
                                    addlog("New money: " . print_r($rm['objects'][$rmLastID], true));
                                    unset($rm['enemies'][$closest]);
                                    addlog("Zombie " . $closest . " destroyed");
                                }
                                unset($rm['bullets'][$j]);
                                // Remove bullet, unless this is a penetrating round
                            }
                        }
                    }
                }
            }
            /*_*/
            /*
            foreach ($rm['enemies'] as $j => &$k) {
            	if (is_numeric($j)) { // Only operate on 'ACTUAL' enemies
            		if (isset($k['chasing'])) {
            			$update = false;
            			$k[2] = round(atan2($rm['p'][$k['chasing']][1]-$k[1],$rm['p'][$k['chasing']][0]-$k[0]),3); // Set direction
            			if (distanceBetween($k[0],$k[1],$rm['p'][$k['chasing']][0],$rm['p'][$k['chasing']][1]) > $rm['enemies'][$k['type']]['stopDistance']) {
            				$k[3] = $rm['enemies'][$k['type']]['speed'];
            				$k[0] += cos($k[2]) * $k[3] * $rmLastPush*0.001;
            				$k[1] += sin($k[2]) * $k[3] * $rmLastPush*0.001;
            				//$update = true;
            			} else {
            				//if ($k[3] != 0) $update = true;
            				$k[3] = 0; // Stop moving if we are closer than the stopDistance
            			}
            			// ID, time, x, y, dir, speed
            			echo '>'.$j.'Chasing ';
            			if ($update) {
            				//addlog('Send: '.$k[0].','.$k[1].','.$k[2].','.$k[3]);
            				$send .= 'BZp' . pack('n',$j) . pack('N',$rmtick) . pack('N',round($k[0]*1000)) . pack('N',round($k[1]*1000)) . pack('N',round(($k[2]+M_PI)*1000)) . pack('n',$k[3]);
            			}
            		} else {
            			//addlog('K chasing not set');
            			foreach ($rm['p'] as $l => &$m) {
            				if (isset($m['game'])) { // Only set to chase if logged in
            					if (distanceBetween($k[0],$k[1],$m[0],$m[1]) < $rm['enemies'][$k['type']]['chaseRange']) { // Initiate chase
            						$k['chasing'] = $l; break;
            						addlog('Distance:'.distanceBetween($k[0],$k[1],$m[0],$m[1]).' <? '.$rm['enemies'][$k['type']]['chaseRange']);
            					} else {
            						addlog('No Distance:'.round(distanceBetween($k[0],$k[1],$m[0],$m[1]),3).' <? '.$rm['enemies'][$k['type']]['chaseRange']);
            					}
            				}
            			}
            		}
            	}
            }
            */
            if (!empty($send) || count($sendTo) > 0) {
                // Send everything processed
                foreach ($rm['p'] as $l => $m) {
                    if (isset($m['game'])) {
                        //addlog('SEND  TO ('.$l.') >~'.$send);
                        $tmpsend = '~' . $send;
                        if (isset($sendTo[$l])) {
                            $tmpsend .= $sendTo[$l];
                        }
                        send($tmpsend, $l, true);
                    }
                }
                $sendTo = array();
                // Buffer to store everything we're going to send to each player individually
                $send = '';
                // String to store things we'll send to everyone
            }
        }
        // End conditional check for- game is running
        //addlog('FULLTEMP:'.$tmp);
        //send("s$rmSendCount", $sVars['observing']);
        //send("sSend count: $rmSendCount");
        //send("~P".pack("C",$rmSendCount), $sVars['observing'], true);
        $rmLastPush = 0;
        // Reset time since push
        $rmCount = 0;
        // Reset iterations per push
    }
    // End check for is this time to push
    if ($rmSCount >= 1000) {
        foreach ($rm['p'] as $l => &$m) {
            if (isset($m['game'])) {
                if (!isset($m['ping'])) {
                    // Check and update latency
                    $send .= '=';
                    $m['ping'] = $rmtick;
                    // Prepare to receive pong
                }
                $send .= 'Wl' . pack('n', $l) . pack('n', $m['lerp']);
                // Send clients lerp out based on latency on next net push
                // Reset client variables that cause issues for server collision checking
                if ($GLOBALS['cVars'][$l]['name'] == 'reset') {
                    $rmBuffer[$l] = array();
                    $rmBuffer[$l][0] = array('=', 0);
                    //if (!isset($sendTo[$l])) $sendTo[$l] = '';
                    //$sendTo[$l] .= 'Id'.pack('n',$l).pack('N',$rmtick); // Re-initialize the current game time on the net for this client
                    addlog("HARD RESET PLAYER BUFFER");
                }
            }
        }
        $rmSendCount = 0;
        // Reset sends per second
        $rmSCount = 0;
        // Second timer
    }
}
            $newitems = $items;
            $newPermutations = $permutations;
            list($nextItem) = array_splice($newitems, $i, 1);
            array_unshift($newPermutations, $nextItem);
            permutate($newitems, $newPermutations);
        }
    }
    return $allPermutations;
}
$distances = file(__DIR__ . '/input', FILE_IGNORE_NEW_LINES);
$cityList = [];
$adjencyList = [];
foreach ($distances as $distance) {
    if (preg_match("/(\\S+) to (\\S+) = (\\d+)/", $distance, $matches)) {
        list(, $from, $to, $distance) = $matches;
        $adjencyList[$from][$to] = (int) $distance;
        $cityList[] = $from;
        $cityList[] = $to;
    }
}
unset($distances);
$permutations = permutate(array_unique($cityList));
$distances = [];
foreach ($permutations as $permutation) {
    $distance = 0;
    for ($i = 0; $i < count($permutation); $i++) {
        $distance += distanceBetween($permutation[$i], $permutation[$i + 1], $adjencyList);
    }
    $distances[] = $distance;
}
unset($permutations);
Exemple #5
0
function locationSearch($location)
{
    $_POST['title'] = "Stations Near {$location}";
    $data_arr = geocode($location);
    // geocode the address given
    // Query SQL database for locations within given range
    // One degree of latitude approx. equal to 69 miles
    // eqn: deg = (enteredMiles/69)
    // get the connection
    $latitude = $data_arr[0];
    // calc upper and lower bounds of latitude search
    $diffLat = 100 / 69;
    $upperLat = $latitude + $diffLat;
    $lowerLat = $latitude - $diffLat;
    $longitude = $data_arr[1];
    $divisor = 37;
    $diffLong = 100 / $divisor;
    $upperLong = $longitude + $diffLong;
    $lowerLong = $longitude - $diffLong;
    $conn = new mysqli("localhost", DB_USERNAME, DB_PASSWORD, "radiodb");
    if ($conn->connect_error) {
        $_POST['results'] = "Connection error";
    }
    $sql = "SELECT *\n    FROM fmstations WHERE\n    (latitude BETWEEN {$lowerLat} AND {$upperLat}) AND\n    (longitude BETWEEN {$lowerLong} AND {$upperLong})";
    $result = $conn->query($sql);
    //SELECT * FROM fmstations WHERE (latitude BETWEEN 43 AND 44) AND (longitude BETWEEN -90 AND -89) UNION SELECT * FROM amstations WHERE (latitude BETWEEN 43 AND 44) AND (longitude BETWEEN -90 AND -89)
    //TODO above is for getting AM AND FM stations.
    //TODO above query moves the genre of the AM stations over into another column to match column space.
    // AM Stations start their freq at 500 hz, check if is am based off of that.
    // Store all possible station class ranges
    $class_A = 17.6;
    $class_C3 = 24.3;
    $class_B1 = 27.8;
    $class_C2 = 32.4;
    $class_B = 40.5;
    $class_C1 = 44.9;
    $class_C0 = 51.8;
    $class_C = 57.0;
    // array to store the results after range check
    $rangedResults[] = array();
    while ($row = $result->fetch_assoc()) {
        $class = $row['antClass'];
        $row['enteredLat'] = $latitude;
        $row['enteredLng'] = $longitude;
        $row['enteredLoc'] = $location;
        /**
         * Switch statement on radio station class to determine if entered location is in range of
         * radio station's predicted broadcasting range.
         */
        switch ($class) {
            case 'A':
                if (distanceBetween($latitude, $longitude, $row['latitude'], $row['longitude'], "M") < $class_A) {
                    $rangedResults[] = $row;
                }
                break;
            case 'C3':
                if (distanceBetween($latitude, $longitude, $row['latitude'], $row['longitude'], "M") < $class_C3) {
                    $rangedResults[] = $row;
                }
                break;
            case 'B1':
                if (distanceBetween($latitude, $longitude, $row['latitude'], $row['longitude'], "M") < $class_B1) {
                    $rangedResults[] = $row;
                }
                break;
            case 'C2':
                if (distanceBetween($latitude, $longitude, $row['latitude'], $row['longitude'], "M") < $class_C2) {
                    $rangedResults[] = $row;
                }
                break;
            case 'B':
                if (distanceBetween($latitude, $longitude, $row['latitude'], $row['longitude'], "M") < $class_B) {
                    $rangedResults[] = $row;
                }
                break;
            case 'C1':
                if (distanceBetween($latitude, $longitude, $row['latitude'], $row['longitude'], "M") < $class_C1) {
                    $rangedResults[] = $row;
                }
                break;
            case 'C0':
                if (distanceBetween($latitude, $longitude, $row['latitude'], $row['longitude'], "M") < $class_C0) {
                    $rangedResults[] = $row;
                }
                break;
            case 'C':
                if (distanceBetween($latitude, $longitude, $row['latitude'], $row['longitude'], "M") < $class_C) {
                    $rangedResults[] = $row;
                }
                break;
            default:
                break;
        }
    }
    $_POST['results'] = $rangedResults;
    // Require the php page to display the results
    require "locationSearch.php";
}
function colLineCircle($line, $circle, $slide)
{
    // [x1,y1,x2,y2] , [x, y, r]
    if (!isset($slide)) {
        $slide = false;
    }
    $ret = false;
    //Find slope of original $line
    $mm = array($line[3] - $line[1], $line[2] - $line[0]);
    if ($mm[0] == 0) {
        $calcline = array($circle[0], 0, $circle[0], 1024);
        // Output will be a vertical $line
    } else {
        if ($mm[1] == 0) {
            $calcline = array(0, $circle[1], 1024, $circle[1]);
            // Output will be a horizontal $line
        } else {
            //Find negative reciprocal of slope of $line (perpendicular $line)
            $mm = 0 - $mm[1] / $mm[0];
            //Plug into y = mx + b to find y-intercept | $circle[1] = mm * $circle[0] + b
            $b = $circle[1] - $mm * $circle[0];
            //Create $line
            $calcline = array(0, $mm * 0 + $b, 1024, $mm * 1024 + $b);
        }
    }
    $is = colLineLine($line, $calcline, true);
    // Will return [xint, yint, bezier A($line2), bezier B($line1)] // Intersect
    if ($is[2] < 0 || $is[2] > 1 || $is[3] < 0 || $is[3] > 1) {
        // No collision
        if ($is[2] < 0) {
            // Collision with endpoint A
            if (distanceBetween($line[0], $line[1], $circle[0], $circle[1]) < $circle[2]) {
                $ret = array($line[0], $line[1]);
            }
        } else {
            if ($is[2] > 1) {
                // Collision with endpoint B
                if (distanceBetween($line[2], $line[3], $circle[0], $circle[1]) < $circle[2]) {
                    $ret = array($line[2], $line[3]);
                }
            }
        }
        //cg.strokeStyle = '#666'; cg.beginPath(); cg.moveTo($calcline[0],$calcline[1]); cg.$lineTo($calcline[2],$calcline[3]); cg.stroke();
    } else {
        // Collision with the $line
        //cg.strokeStyle = '#F00'; cg.beginPath(); cg.moveTo($calcline[0],$calcline[1]); cg.$lineTo($calcline[2],$calcline[3]); cg.stroke();
        if (distanceBetween($circle[0], $circle[1], $is[0], $is[1]) < $circle[2]) {
            $ret = array($is[0], $is[1]);
        }
        //alert(is[2]+','+is[3]);
    }
    if (!!$ret) {
        if ($slide) {
            // Calculate the proposed position to remain entering collision zone if $slide is opted
            // This $slides using a push-away from the point
            $slid = atan2($circle[1] - $ret[1], $circle[0] - $ret[0]);
            addlog("Size(" . $circle[2] . ") Recommending from " . $ret[0] . "," . $ret[1] . ": Dir: " . $slid);
            $slid = array($ret[0] + cos($slid) * $circle[2], $ret[1] + sin($slid) * $circle[2]);
            return $slid;
        } else {
            // Simply return that we've collided
            return !!$ret;
        }
    }
    return $ret;
    // Return. In the case of no collision
}