| 1 |  |  | # | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2 |  |  | #  Copyright 2001 - 2016 Ludek Smid [http://www.ospace.net/] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3 |  |  | # | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4 |  |  | #  This file is part of Outer Space. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 5 |  |  | # | 
            
                                                                                                            
                            
            
                                    
            
            
                | 6 |  |  | #  Outer Space is free software; you can redistribute it and/or modify | 
            
                                                                                                            
                            
            
                                    
            
            
                | 7 |  |  | #  it under the terms of the GNU General Public License as published by | 
            
                                                                                                            
                            
            
                                    
            
            
                | 8 |  |  | #  the Free Software Foundation; either version 2 of the License, or | 
            
                                                                                                            
                            
            
                                    
            
            
                | 9 |  |  | #  (at your option) any later version. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 10 |  |  | # | 
            
                                                                                                            
                            
            
                                    
            
            
                | 11 |  |  | #  Outer Space is distributed in the hope that it will be useful, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 12 |  |  | #  but WITHOUT ANY WARRANTY; without even the implied warranty of | 
            
                                                                                                            
                            
            
                                    
            
            
                | 13 |  |  | #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
            
                                                                                                            
                            
            
                                    
            
            
                | 14 |  |  | #  GNU General Public License for more details. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 15 |  |  | # | 
            
                                                                                                            
                            
            
                                    
            
            
                | 16 |  |  | #  You should have received a copy of the GNU General Public License | 
            
                                                                                                            
                            
            
                                    
            
            
                | 17 |  |  | #  along with Outer Space; if not, write to the Free Software | 
            
                                                                                                            
                            
            
                                    
            
            
                | 18 |  |  | #  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA | 
            
                                                                                                            
                            
            
                                    
            
            
                | 19 |  |  | # | 
            
                                                                                                            
                            
            
                                    
            
            
                | 20 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 21 |  |  | import time, math | 
            
                                                                                                            
                            
            
                                    
            
            
                | 22 |  |  | from ige.ospace import Rules | 
            
                                                                                                            
                            
            
                                    
            
            
                | 23 |  |  | import ige | 
            
                                                                                                            
                            
            
                                    
            
            
                | 24 |  |  | from ige import log | 
            
                                                                                                            
                            
            
                                    
            
            
                | 25 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 26 |  |  | def recordScanLevel(distance, tObj, tSigMod, scannerPwr, owner, playerMaps): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 27 |  |  |     level = min((tObj.signature + tSigMod) * scannerPwr / max(0.0001, distance), Rules.maxScanPwr) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 28 |  |  |     if level >= Rules.level1InfoScanPwr and owner > 0: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 29 |  |  |         if owner not in playerMaps: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 30 |  |  |             playerMaps[owner] = {} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 31 |  |  |         playerMaps[owner][tObj] = max(level, playerMaps[owner].get(tObj, 0)) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 32 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 33 |  |  | def computeScanner(obj1, obj2, playerMaps, signatures): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 34 |  |  |     d = math.hypot(obj1.x - obj2.x, obj1.y - obj2.y) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 35 |  |  |     sigMod = signatures.get(obj2.oid, 0) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 36 |  |  |     if hasattr(obj1, "scannerPwr"): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 37 |  |  |         recordScanLevel(d, obj2, sigMod, obj1.scannerPwr, obj1.owner, playerMaps) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 38 |  |  |     elif hasattr(obj1, "scannerPwrs"): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 39 |  |  |         for owner, scannerPwr in obj1.scannerPwrs.iteritems(): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 40 |  |  |             recordScanLevel(d, obj2, sigMod, scannerPwr, owner, playerMaps) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 41 |  |  |     else: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 42 |  |  |         raise ige.ServerException("Unsupported object") | 
            
                                                                                                            
                            
            
                                    
            
            
                | 43 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 44 |  |  | def detectClose(obj1, obj2, signatures): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 45 |  |  |     # ignore itself | 
            
                                                                                                            
                            
            
                                    
            
            
                | 46 |  |  |     if obj1.oid >= obj2.oid: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 47 |  |  |         return | 
            
                                                                                                            
                            
            
                                    
            
            
                | 48 |  |  |     d = math.hypot(obj1.x - obj2.x, obj1.y - obj2.y) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 49 |  |  |     if d < 1.0: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 50 |  |  |         log.debug("CLOSE FLEET detected", obj1.oid, obj2.oid, obj1.signature, obj2.signature) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 51 |  |  |         signatures[obj1.oid] = signatures.get(obj1.oid, 0) + obj2.signature | 
            
                                                                                                            
                            
            
                                    
            
            
                | 52 |  |  |         signatures[obj2.oid] = signatures.get(obj2.oid, 0) + obj1.signature | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 53 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 54 |  |  | def computeMap(galaxyCmdObj, tran, galaxy): | 
            
                                                                        
                            
            
                                    
            
            
                | 55 |  |  |     log.debug("SCAN2 Phase - starting") | 
            
                                                                        
                            
            
                                    
            
            
                | 56 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 57 |  |  |     start = time.time() | 
            
                                                                        
                            
            
                                    
            
            
                | 58 |  |  |     _map, fleets, alwaysVisible = generateMap(galaxyCmdObj, tran, galaxy) | 
            
                                                                        
                            
            
                                    
            
            
                | 59 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 60 |  |  |     # compute close fleets | 
            
                                                                        
                            
            
                                    
            
            
                | 61 |  |  |     sectors, surroundingSectors = generateSectors(fleets, sectorSize = 1, size = 1) | 
            
                                                                        
                            
            
                                    
            
            
                | 62 |  |  |     signatures = {} | 
            
                                                                        
                            
            
                                    
            
            
                | 63 |  |  |     processSectors(fleets, sectors, surroundingSectors, detectClose, (signatures,)) | 
            
                                                                        
                            
            
                                    
            
            
                | 64 |  |  |     log.debug("CLOSE FLEETS - result", signatures) | 
            
                                                                        
                            
            
                                    
            
            
                | 65 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 66 |  |  |     # compute map | 
            
                                                                        
                            
            
                                    
            
            
                | 67 |  |  |     start0 = time.time() | 
            
                                                                        
                            
            
                                    
            
            
                | 68 |  |  |     sectors, surroundingSectors = generateSectors(_map, sectorSize = 5, size     = 10) | 
            
                                                                        
                            
            
                                    
            
            
                | 69 |  |  |     playerMaps = {} | 
            
                                                                        
                            
            
                                    
            
            
                | 70 |  |  |     processSectors(_map, sectors, surroundingSectors, computeScanner, (playerMaps, signatures)) | 
            
                                                                        
                            
            
                                    
            
            
                | 71 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 72 |  |  |     # add always visible items | 
            
                                                                        
                            
            
                                    
            
            
                | 73 |  |  |     for owner in playerMaps: | 
            
                                                                        
                            
            
                                    
            
            
                | 74 |  |  |         for visibleObject in alwaysVisible.values(): | 
            
                                                                        
                            
            
                                    
            
            
                | 75 |  |  |             playerMaps[owner][visibleObject] = max(Rules.level1InfoScanPwr, playerMaps[owner].get(visibleObject, 0)) | 
            
                                                                        
                            
            
                                    
            
            
                | 76 |  |  |     stop = time.time() | 
            
                                                                        
                            
            
                                    
            
            
                | 77 |  |  |     log.debug("Time    : %0.3f s" % (stop - start)) | 
            
                                                                        
                            
            
                                    
            
            
                | 78 |  |  |     log.debug("Time    : %0.3f s (including sector generation)" % (stop - start0)) | 
            
                                                                        
                            
            
                                    
            
            
                | 79 |  |  |     return playerMaps | 
            
                                                                                                            
                            
            
                                    
            
            
                | 80 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 81 |  |  | def processSectors(_map, sectors, surroundingSectors, callable, args): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 82 |  |  |     while sectors: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 83 |  |  |         # get (and remove) random sector | 
            
                                                                                                            
                            
            
                                    
            
            
                | 84 |  |  |         (sX, sY), sObjs = sectors.popitem() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 85 |  |  |         # build list of objects in surrounding sectors | 
            
                                                                                                            
                            
            
                                    
            
            
                | 86 |  |  |         objs = [] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 87 |  |  |         for dx in surroundingSectors: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 88 |  |  |             for dy in surroundingSectors: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 89 |  |  |                 sIdx = (sX + dx, sY + dy) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 90 |  |  |                 if sIdx not in sectors: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 91 |  |  |                     continue | 
            
                                                                                                            
                            
            
                                    
            
            
                | 92 |  |  |                 objs.extend(sectors[sIdx]) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 93 |  |  |         # check objects in current sector | 
            
                                                                                                            
                            
            
                                    
            
            
                | 94 |  |  |         for obj1Idx in sObjs: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 95 |  |  |             obj1 = _map[obj1Idx] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 96 |  |  |             # with objects in surrounding sectors | 
            
                                                                                                            
                            
            
                                    
            
            
                | 97 |  |  |             for obj2Idx in objs: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 98 |  |  |                 obj2 = _map[obj2Idx] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 99 |  |  |                 callable(obj1, obj2, *args) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 100 |  |  |                 callable(obj2, obj1, *args) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 101 |  |  |             # with objects in current sector | 
            
                                                                                                            
                            
            
                                    
            
            
                | 102 |  |  |             for obj2Idx in sObjs: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 103 |  |  |                 # allow object scan on itself | 
            
                                                                                                            
                            
            
                                    
            
            
                | 104 |  |  |                 if obj1Idx > obj2Idx: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 105 |  |  |                     continue | 
            
                                                                                                            
                            
            
                                    
            
            
                | 106 |  |  |                 obj2 = _map[obj2Idx] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 107 |  |  |                 callable(obj1, obj2, *args) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 108 |  |  |                 callable(obj2, obj1, *args) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 109 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 110 |  |  | def generateSectors(_map, sectorSize = 5, size = 10): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 111 |  |  |     # generate sector map | 
            
                                                                                                            
                            
            
                                    
            
            
                | 112 |  |  |     sectors = {} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 113 |  |  |     # can be optimized to not include corner sectors | 
            
                                                                                                            
                            
            
                                    
            
            
                | 114 |  |  |     surroundingSectors = range(-size / sectorSize, size / sectorSize + 1) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 115 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 116 |  |  |     for i in _map: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 117 |  |  |         obj = _map[i] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 118 |  |  |         sIdx = (int(obj.x / sectorSize), int(obj.y / sectorSize)) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 119 |  |  |         if sIdx in sectors: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 120 |  |  |             sectors[sIdx].append(obj.oid) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 121 |  |  |         else: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 122 |  |  |             sectors[sIdx] = [obj.oid] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 123 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 124 |  |  |     return sectors, surroundingSectors | 
            
                                                                                                            
                            
            
                                    
            
            
                | 125 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 126 |  |  | def generateMap(cmdObj, tran, galaxy): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 127 |  |  |     _map = {} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 128 |  |  |     fleets = {} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 129 |  |  |     alwaysVisible = {} | 
            
                                                                                                            
                            
            
                                    
            
            
                | 130 |  |  |     # all systems are part of the map | 
            
                                                                                                            
                            
            
                                    
            
            
                | 131 |  |  |     for systemID in galaxy.systems: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 132 |  |  |         system = tran.db[systemID] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 133 |  |  |         # black holes are always visible, for easier orientation on the galaxy map | 
            
                                                                                                            
                            
            
                                    
            
            
                | 134 |  |  |         if system.starClass[0] == 'b': | 
            
                                                                                                            
                            
            
                                    
            
            
                | 135 |  |  |             alwaysVisible[systemID] = system | 
            
                                                                                                            
                            
            
                                    
            
            
                | 136 |  |  |         _map[systemID] = system | 
            
                                                                                                            
                            
            
                                    
            
            
                | 137 |  |  |         # get mobile objects (fleet, ...) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 138 |  |  |         for objID in cmdObj.cmd(system).getObjectsInSpace(tran, system): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 139 |  |  |             obj = tran.db[objID] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 140 |  |  |             _map[objID] = obj | 
            
                                                                                                            
                            
            
                                    
            
            
                | 141 |  |  |             fleets[objID] = obj | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 142 |  |  |     return _map, fleets, alwaysVisible | 
            
                                                        
            
                                    
            
            
                | 143 |  |  |  |