Vega strike Python Modules doc  0.5.1
Documentation of the " Modules " folder of Vega strike
 All Data Structures Namespaces Files Functions Variables
fg_util.py
Go to the documentation of this file.
1 #WARNING THIS FILE HAS A MIRROR FILE IN C++ FOR SIMILAR ACCESS...
2 #SO THAT C++ CAN LEARN ABOUT THE DYNAMIC UNIVERSE SHIPS
3 #
4 import Director
5 import VS
6 import vsrandom
7 import Vector
8 import faction_ships
9 from universe import AllSystems
10 
11 import ShowProgress
12 import debug
13 
14 ccp=VS.getCurrentPlayer()
15 _tweaktuple = ('Squadron','Prime','Arc','Alpha','Aleph','Beta','Quadratis','Zeta','X','Plus','Blade','Delta','Dash','Xprime','Gamma','Hydris','Dual','Tri','Quad','Penta','Hex','Octo','Deca','Octate')
16 
17 #Aera Plants
18 #Rlaan Rocks
19 #Hum0n Cities
20 #Uln adVerbs
21 #klkk Adjectives
23  if syst in faction_ships.max_flightgroups:
24  return faction_ships.max_flightgroups[syst]
25  else:
26  return 3
27 
29  if syst in faction_ships.min_flightgroups:
30  return faction_ships.min_flightgroups[syst]
31  else:
32  return 1
33 
35  return 10
36 
38  return 0
39 
40 def MakeFactionKey (faction):
41  return 'FF:'+str(VS.GetFactionIndex(faction))
42 
43 def MakeFGKey (fgname,faction):
44  return 'FG:'+str(fgname)+'|'+str(VS.GetFactionIndex(faction))
45 
46 def MakeStarSystemFGKey (starsystem):
47  return 'SS:'+str(starsystem)
48 
49 def MakeStarSystemFactionFGKey(starsystem,faction):
50  skey = MakeStarSystemFGKey (starsystem)
51  index = VS.GetFactionIndex (faction)
52  key = "%s[%d]" % (skey,index)
53  return key
54 
56  return 3
57 
59  return 3
60 
61 def AllFactions ():
62  facs =[]
63  for i in xrange (VS.GetNumFactions()):
64  facs.append(VS.GetFactionName(i))
65  return facs
66 
67 basenamelist={}
68 flightgroupnamelist={}
69 genericalphabet=['Alpha','Beta','Gamma','Delta','Epsilon','Zeta','Phi','Omega']
70 
71 def ReadBaseNameList(faction):
72  bnl=[]
73  debug.debug('reading base names %s', faction)
74  filename = 'universe/fgnames/'+faction+'.txt'
75  try:
76  f = open (filename,'r')
77  bnl = f.readlines()
78  f.close()
79  except:
80  try:
81  f = open ('../'+filename,'r')
82  bnl = f.readlines()
83  f.close()
84  except:
85  try:
86  f = open ('../universe/names.txt','r')
87  bnl = f.readlines()
88  f.close()
89  except:
90  try:
91  f = open ('universe/names.txt','r')
92  bnl = f.readlines()
93  f.close()
94  except:
95  global genericalphabet
96  bnl=genericalphabet
97  for i in xrange(len(bnl)):
98  bnl[i]=bnl[i].rstrip()#.decode('utf8','ignore')
99  import vsrandom
100  vsrandom.shuffle(bnl)
101  return bnl
102 
103 def GetRandomFGNames (numflightgroups, faction):
104  global flightgroupnamelist
105  if (not (faction in flightgroupnamelist)):
106  flightgroupnamelist[faction]=ReadBaseNameList(faction)
107  if numflightgroups < 0:
108  numflightgroups = len(flightgroupnamelist[faction])
109  additional=[]
110  if (numflightgroups>len(flightgroupnamelist[faction])):
111  for i in xrange (numflightgroups-len(flightgroupnamelist)):
112  additional.append(str(i))
113  if (len(additional)+len(flightgroupnamelist[faction])==0):
114  flightgroupnamelist[faction]=ReadBaseNameList(faction)
115  return additional+flightgroupnamelist[faction]
116 basecounter=0
117 
118 def GetRandomBaseName (n,faction):
119  global basecounter
120  retval=[]
121  global basenamelist
122  try:
123  import seedrandom
124  if (not (faction in basenamelist)):
125  basenamelist[faction]=ReadBaseNameList(faction+'_base')
126  retval = basenamelist[faction][basecounter:basecounter+n]
127  while len(retval)<n:
128  basecounter=n-len(retval)
129  retval = retval + basenamelist[faction][:basecounter]
130  basecounter = basecounter % len(basenamelist[faction])
131  except:
132  debug.error('uhoh base lsit wrong')
133  retval=[]
134  for i in xrange (n):
135  retval+=[str(n)]
136  n+=1
137  return retval
138 
139 origfgoffset=0
140 
141 def TweakFGNames (origfgnames):
142  global origfgoffset
143  tweaker=str(origfgoffset)
144  if (origfgoffset<len(_tweaktuple)):
145  tweaker = _tweaktuple[origfgoffset]
146  rez=[]
147  for i in origfgnames:
148  rez.append (i+'_'+tweaker)
149  return rez
150 
152  return len(_tweaktuple)
153 
154 def WriteStringList(cp,key,tup):
155  siz = Director.getSaveStringLength (cp,key)
156  s_size=siz;
157  lentup= len(tup)
158  if (lentup<siz):
159  siz=lentup
160  for i in xrange(siz):
161  Director.putSaveString(cp,key,i,tup[i])
162  for i in xrange (s_size,lentup):
163  Director.pushSaveString(cp,key,tup[i])
164  while s_size > lentup:
165  Director.eraseSaveString(cp,key,s_size-1)
166  s_size -= 1
167 
168 def ReadStringList (cp,key):
169  siz = Director.getSaveStringLength (cp,key)
170  tup =[]
171  for i in xrange (siz):
172  tup.append(Director.getSaveString(cp,key,i))
173  return tup
174 
175 def AllFlightgroups (faction):
176  key = MakeFactionKey (faction)
177  return ReadStringList(ccp,key)
178 
179 def NumAllFlightgroups (faction):
180  key = MakeFactionKey(faction)
181  return Director.getSaveStringLength(ccp,key)
182 
183 def RandomFlightgroup (faction):
184  key = MakeFactionKey(faction)
185  i = Director.getSaveStringLength(ccp,MakeFactionKey(faction))
186  if (i==0):
187  return ''
188  import vsrandom
189  return Director.getSaveString(ccp,key,vsrandom.randrange(0,i))
190 
191 def ListToPipe (tup):
192  fina=''
193  if (len(tup)):
194  fina=tup[0]
195  for i in xrange (1,len(tup)):
196  fina+='|'+tup[i]
197  return fina
198 
199 def _MakeFGString (starsystem,typenumlist):
200  totalships = 0
201  ret = []
202  damage=0
203  strlist=[]
204  for tt in typenumlist:
205  totalships+=int(tt[1])
206  strlist+=[str(tt[0]),str(tt[1]),str(tt[1])]
207  return [str(totalships),str(starsystem),str(damage)]+strlist
208 
209 def _AddShipsToKnownFG(key,tnlist):
210  leg = Director.getSaveStringLength (ccp,key)
211 
212  numtotships = int(Director.getSaveString(ccp,key,0))
213  fgentry = {}
214  for i in xrange(ShipListOffset(),leg,PerShipDataSize()):
215  fgentry[Director.getSaveString(ccp,key,i)] = \
216  ( int(Director.getSaveString(ccp,key,i+1)) , \
217  int(Director.getSaveString(ccp,key,i+2)) , \
218  int(i), \
219  0 )
220 
221  for tn in tnlist:
222  numtotships += int(tn[1])
223  if tn[0] in fgentry:
224  fgentry[tn[0]] = ( \
225  fgentry[tn[0]][0]+int(tn[1]), \
226  fgentry[tn[0]][1]+int(tn[1]), \
227  fgentry[tn[0]][2], \
228  1 )
229  else:
230  baseidx=\
231  Director.pushSaveString(ccp,key,str(tn[0]))
232  Director.pushSaveString(ccp,key,str(tn[1]))
233  Director.pushSaveString(ccp,key,str(tn[1]))
234  fgentry[tn[0]] = (int(tn[1]),int(tn[1]),int(baseidx),0)
235 
236  Director.putSaveString(ccp,key,0,str(numtotships))
237  for fg in fgentry:
238  #only if dirty
239  if fgentry[fg][3]:
240  Director.putSaveString(ccp,key,fgentry[fg][2]+1,str(fgentry[fg][0]))
241  Director.putSaveString(ccp,key,fgentry[fg][2]+2,str(fgentry[fg][1]))
242 
243 def _AddFGToSystem (fgname,faction,starsystem):
244  key = MakeStarSystemFactionFGKey(starsystem,faction)
245  Director.pushSaveString(ccp,key,fgname)
246 
247 def _RemoveFGFromSystem (fgname,faction,starsystem):
248  key = MakeStarSystemFactionFGKey(starsystem,faction)
249  leg = Director.getSaveStringLength(ccp,key)
250  for index in xrange(leg):
251  if Director.getSaveString(ccp,key,index) == fgname:
252  Director.eraseSaveString(ccp,key,index)
253  break
254 
255 def _RemoveAllFGFromSystem (faction,starsystem):
256  key = MakeStarSystemFactionFGKey(starsystem,faction)
257  WriteStringList(ccp,key,[])
258 
259 def _AddFGToFactionList(fgname,faction):
260  key = MakeFactionKey(faction)
261  Director.pushSaveString (ccp,key,fgname)
262 
263 def _RemoveFGFromFactionList (fgname,faction):
264  key = MakeFactionKey(faction)
265  leg=Director.getSaveStringLength(ccp,key)
266  for index in xrange(leg):
267  if Director.getSaveString(ccp,key,index) == fgname:
268  Director.eraseSaveString(ccp,key,index)
269  return 1
270 
271 def _RemoveAllFGFromFactionList(faction):
272  key = MakeFactionKey(faction)
273  WriteStringList(ccp,key,[])
274 
275 def CheckFG (fgname,faction):
276  key = MakeFGKey (fgname,faction)
277  leg = Director.getSaveStringLength (ccp,key)
278  totalships=0
279  try:
280  # Check ship counts
281  for i in xrange (ShipListOffset()+1,leg,PerShipDataSize()):
282  shipshere=Director.getSaveString(ccp,key,i)
283  totalships+=int(shipshere)
284  temp=Director.getSaveString(ccp,key,i+1)
285  if (temp!=shipshere):
286  debug.debug('correcting flightgroup %r to have right landed ships', fgname)
287  Director.putSaveString(ccp,key,i+1,shipshere)#set num actives to zero
288  #DEBUG ONLY if (totalships!=int(Director.getSaveString(ccp,key,0))):
289  # debug.debug('mismatch on flightgroup '+fgname+' faction '+faction)
290  # return 0
291  except:
292  debug.debug('nonint reading on flightgroup %r faction %r', fgname, faction)
293  return 0
294  return 1
295 
296 def PurgeZeroShips (faction):
297  return #perf problem...but we need it for persistent bases...so now it's in C++, not python---means this whole file is duplicated
298  key=MakeFactionKey(faction)
299  len=Director.getSaveStringLength (ccp,key)
300  i=0
301  debug.debug("purging 0 ships start")
302  while i<len:
303  curfg=Director.getSaveString(ccp,key,i)
304  CheckFG (curfg,faction)
305  #numships=NumShipsInFG(curfg,faction)
306  #commented to allow 0 ship flightgroups for future reinforcement
307  #if (numships==0):
308  # DeleteFG(curfg,faction)
309  # i-=1
310  # len-=1
311  i+=1
312  debug.debug("purging 0 ships end")
313 
314 def NumShipsInFG (fgname,faction):
315  key = MakeFGKey (fgname,faction)
316  len = Director.getSaveStringLength (ccp,key)
317  if (len==0):
318  return 0
319  else:
320  try:
321  return int(Director.getSaveString(ccp,key,0))
322  except:
323  debug.debug("fatal: flightgroup without size")
324  return 0
325 
326 def GetDamageInFGPool (fgname,faction):
327  key = MakeFGKey (fgname,faction)
328  len = Director.getSaveStringLength (ccp,key)
329  if (len<3):
330  return 0
331  else:
332  try:
333  return int(Director.getSaveString(ccp,key,2))
334  except:
335  debug.debug("nonfatal: flightgroup without size")
336  return 0
337 
338 def SetDamageInFGPool (fgname,faction,num):
339  key = MakeFGKey (fgname,faction)
340  len = Director.getSaveStringLength (ccp,key)
341  if (len>2):
342  Director.putSaveString(ccp,key,2,str(num))
343 
344 def DeleteFG(fgname,faction,deferaux=0):
345  key = MakeFGKey (fgname,faction)
346  leg = Director.getSaveStringLength (ccp,key)
347  if (leg>=ShipListOffset()):
348  starsystem=Director.getSaveString(ccp,key,1)
349  if not deferaux:
350  _RemoveFGFromSystem(fgname,faction,starsystem)
351  _RemoveFGFromFactionList(fgname,faction)
352  WriteStringList (ccp,key,[])
353 
354 def AllFG(faction):
355  return ReadStringList (ccp,MakeFactionKey (faction))
356 
358  sysSpan = {}
359  rv = []
360  for fgname in AllFG(faction):
361  sysSpan[FGSystem(fgname,faction)] = 1
362  for starsystem in sysSpan:
363  rv.append(starsystem)
364  return rv
365 
366 def DeleteAllFG (faction):
367  # Watch the ordering of operations! (won't work in most other permutations)
368  debug.debug("DeleteAllFG from %s", faction)
369  sysspan = SystemsWithFactionFGs(faction)
370  for fgname in AllFG(faction):
371  DeleteFG(fgname,faction,1)
372  for starsystem in sysspan:
373  _RemoveAllFGFromSystem(faction,starsystem)
374  _RemoveAllFGFromFactionList(faction)
375 
377  for faction in AllFactions():
378  DeleteAllFG(faction)
379 
381  key = MakeStarSystemFGKey(sys)
382  factionfglists = ReadStringList(ccp,key)
383  for i in xrange(len(factionfglists)):
384  faction = VS.GetFactionName(i)
385  fglist = factionfglists[i].split('|')
386  for fg in fglist:
387  DeleteFG(fg,faction)
388 
389 
391  # Legacy cleanup
392  allsys = AllSystems()
393  numsys = len(allsys)
394  count = 0
395  oldpct = 0
396  for sys in allsys:
397  count += 1
398  pct = count*100/len(allsys)
399  if pct != oldpct:
400  ShowProgress.setProgressBar("loading",pct/100.)
401  ShowProgress.setProgressMessage("loading","Resetting old universe (%d%%)" % (pct))
402  oldpct = pct
403  DeleteLegacyFGs(sys)
404 
406  for starsystem in AllSystems():
407  key = MakeStarSystemFGKey(starsystem)
408  if Director.getSaveStringLength(ccp,key)>0:
409  return 1
410  return 0
411 
412 def FGSystem (fgname,faction):
413  key = MakeFGKey(fgname,faction)
414  len = Director.getSaveStringLength(ccp,key)
415  if (len>1):
416  return Director.getSaveString(ccp,key,1)
417  else:
418  debug.debug('%r for %r already died, in no system', fgname, faction)
419  return 'nil'
420 def TransferFG (fgname,faction,tosys):
421  key = MakeFGKey(fgname,faction)
422  len = Director.getSaveStringLength(ccp,key)
423  if (len>1):
424  starsystem=Director.getSaveString(ccp,key,1)
425  _RemoveFGFromSystem(fgname,faction,starsystem)
426  _AddFGToSystem(fgname,faction,tosys)
427  Director.putSaveString(ccp,key,1,tosys)
428 
429 def AddShipsToFG (fgname,faction,typenumbertuple,starsystem):
430  key = MakeFGKey(fgname,faction)
431  len = Director.getSaveStringLength (ccp,key)
432  if (len<ShipListOffset()):
433  debug.debug('adding new fg %r of %s to %s', fgname, typenumbertuple, starsystem)
434  WriteStringList(ccp,key,_MakeFGString( starsystem,typenumbertuple) )
435  _AddFGToSystem (fgname,faction,starsystem)
436  _AddFGToFactionList (fgname,faction)
437  debug.info('adding new fg %r of %s to %s', fgname, typenumbertuple, starsystem)
438  else:
439  debug.info('adding old fg %r of %s to %s', fgname, typenumbertuple, FGSystem(fgname,faction))
440  _AddShipsToKnownFG(key,typenumbertuple)
441 
442 def RemoveShipFromFG (fgname,faction,type,numkill=1,landed=0):
443  key = MakeFGKey (fgname,faction)
444  leg = Director.getSaveStringLength (ccp,key)
445  debug.debug("Scanning %d units...", leg)
446  for i in xrange (ShipListOffset()+1,leg,PerShipDataSize()):
447  if (Director.getSaveString(ccp,key,i-1)==str(type)):
448  debug.debug("Removing unit %s", type)
449  numships=0
450  numlandedships=0
451  try:
452  numships = int (Director.getSaveString (ccp,key,i))
453  numlandedships=int (Director.getSaveString (ccp,key,i+1))
454  except:
455  debug.error("unable to get savestring %s from FG %s %s %s", i, fgname, faction, type)
456  if (numships>numkill):
457  numships-=numkill
458  if (numships<numlandedships):
459  if (landed==0):
460  debug.debug('trying to remove launched ship %s but all are landed', type)
461  landed=1
462  return 0#failur
463  Director.putSaveString (ccp,key,i,str(numships))
464  if (landed and numlandedships>0):
465  Director.putSaveString(ccp,key,i+1,str(numlandedships-numkill))
466  else:
467  numkill=numships
468  numships=0
469  for j in xrange (i-1,i+PerShipDataSize()-1):
470  Director.eraseSaveString(ccp,key,i-1)
471  if (numships>=0):
472  try:
473  totalnumships = int(Director.getSaveString(ccp,key,0))
474  totalnumships -=numkill
475  if (totalnumships>=0):
476  Director.putSaveString(ccp,key,0,str(totalnumships))
477  if(totalnumships==0):
478  debug.debug("Removing %s FG %r", faction, fgname)
479  DeleteFG(fgname,faction)
480  else:
481  debug.error('error...removing too many ships')
482  except:
483  debug.error('error, flight record %r corrupt', fgname)
484  return numkill
485  debug.debug('cannot find ship to delete in %s fg %r', faction, fgname)
486  return 0
487 
488 def BaseFGInSystemName (system):
489  return 'Base_'+system
490 
491 def AllFGsInSystem(faction,system):
492  key = MakeStarSystemFactionFGKey(system,faction)
493  return ReadStringList(ccp,key)
494 
495 def FGsInSystem(faction,system):
496  ret = AllFGsInSystem(faction,system)
497  basefg = BaseFGInSystemName(system)
498  if (basefg in ret):
499  del ret[ret.index(basefg)]
500  return ret
501 
502 def BaseFGInSystem(faction,system):
503  ret = AllFGsInSystem(faction,system)
504  basefg = BaseFGInSystemName(system)
505  if (basefg in ret):
506  return 1
507  return 0
508 
509 def BaseFG(faction,system):
510  if (BaseFGInSystem(faction,system)):
511  return LandedShipsInFG (BaseFGInSystemName(system),faction)
512  return []
513 
514 def NumFactionFGsInSystem(faction,system):
515  key = MakeStarSystemFactionFGKey(system,faction)
516  return Director.getSaveStringLength(ccp,key)
517 
518 def CountFactionShipsInSystem(faction,system):
519  count=0
520  st=''
521  for fgs in FGsInSystem (faction,system):
522  st+=fgs+' '
523  ships=ReadStringList (ccp,MakeFGKey (fgs,faction))
524  for num in xrange(ShipListOffset()+2,len(ships),PerShipDataSize()):
525  try:
526  count+= int(ships[num])
527  except:
528  debug.error('number ships '+ships[num] + ' not read')
529  debug.debug('OFFICIALCOUNT %s is %s', st, count)
530  return count
531 
532 def _prob_round(curnum):
533  import vsrandom
534  ret = int(curnum)
535  diff = curnum-int(curnum)
536  if (diff>0):
537  if (vsrandom.uniform (0,1)<diff):
538  ret+=1
539  else:
540  if (vsrandom.uniform (0,1)<-diff):
541  ret-=1
542  return ret
543 
544 def LandedShipsInFG(fgname,faction):
545  return ShipsInFG(fgname,faction,2)
546 def ShipsInFG(fgname,faction,offset=1):
547  ships = ReadStringList (ccp,MakeFGKey(fgname,faction))
548  rez=[]
549  for num in xrange (ShipListOffset(),len(ships),PerShipDataSize()):
550  rez.append((ships[num],int(ships[num+offset])))
551  return rez
552 def CapshipInFG(fg,fac):
553  key = MakeFGKey(fg,fac)
554  for num in xrange(ShipListOffset(),Director.getSaveStringLength(ccp,key),PerShipDataSize()):
555  import faction_ships
556  shipinquestion=Director.getSaveString(ccp,key,num)
557  if (faction_ships.isCapital(shipinquestion)):
558  return shipinquestion
559  return None
560 
561 def RandomShipIn (fg,fac):
562  key = MakeFGKey(fg,fac)
563  len = Director.getSaveStringLength(ccp,key)-ShipListOffset()
564  len = int(len/PerShipDataSize())
565  if (len>0):
566  return Director.getSaveString(ccp,key,ShipListOffset()+PerShipDataSize()*vsrandom.randrange(0,len))
567  return ''
568 
569 def minIndex (vals,indices):
570  mini = None
571  minv = None
572  for i in indices:
573  if (mini == None) or (minv > vals[i]):
574  mini = i
575  minv = vals[i]
576  return mini or 0
577 
578 def launchBaseOrbit(type,faction,loc,orbitradius,orbitspeed,unit):
579  #orbitradius*=2
580  import Vector
581  import dynamic_universe
582  R = Vector.Vector(vsrandom.uniform(1.25*orbitradius,orbitradius),
583  vsrandom.uniform(1.25*orbitradius,orbitradius),
584  vsrandom.uniform(1.25*orbitradius,orbitradius))
585  RMag = Vector.Mag(R)
586  T = Vector.Vector(vsrandom.uniform(.5*orbitradius,orbitradius),
587  vsrandom.uniform(.75*orbitradius,.85*orbitradius),
588  vsrandom.uniform(.5*orbitradius,orbitradius))
589  S = Vector.Cross (T,R)
590 
591  S = Vector.Scale(S,
592  vsrandom.uniform (1.5*orbitradius,orbitradius)
593  /Vector.Mag(S))
594  SMag = Vector.Mag(S)
595  bas=VS.launch("Base",type,faction,"unit","default",1,1,Vector.Add(loc,R),'')
596  nam=GetRandomBaseName (1,faction);
597  R = Vector.Scale (R,(RMag+2.0*bas.rSize())/RMag)
598  S = Vector.Scale (S,(SMag+2.0*bas.rSize())/SMag)
599  bas.orbit (unit,orbitspeed,R,S,(0.0,0.0,0.0))
600  #bas.SetPosition(Vector.Add(loc,R))
601  dynamic_universe.TrackLaunchedShip (BaseFGInSystemName(VS.getSystemFile()),
602  faction,
603  type,
604  bas)
605 
606 def launchSingleBase (type,faction,sig):
607  radpct = VS.getPlanetRadiusPercent()
608  sigrsize=sig.rSize()
609  radpct = sigrsize*(1+radpct)
610  if radpct<200000000.+sigrsize:
611  radpct=200000000.+sigrsize
612  speed = vsrandom.uniform (0,50)
613  debug.debug('Lauching %s base %s by sig %s (%s)', faction, type, sig.getName(), sig.getFullname())
614  launchBaseOrbit (type,faction,sig.Position(),radpct,speed,sig)
615 
616 def launchBaseStuck (type,faction):
617  un=VS.getPlayer()
618  maxspeed=100.1
619  if (un):
620  maxspeed=un.maxAfterburnerSpeed()+30.1
621  un.setNull();
622  launchBaseOrbit (type,faction,un.Position(),maxspeed*180,0,un)
623 
624 def launchBase (type,num,faction,system,sig_units,numfighters):
625  import seedrandom
626  debug.debug('launching base %s', type)
628  'faction',
629  'system'])))
630  if (len(sig_units)):
631  for i in xrange (num):
632  one=seedrandom.rand()
633  two=seedrandom.rand()
634  three=seedrandom.rand()
635  indices = [one%len(sig_units),
636  two%len(sig_units),
637  three%len(sig_units)];
638  which = minIndex(numfighters,indices)
639  if (sig_units[which].isJumppoint()):
640  numfighters[which]+=20
641  else:
642  numfighters[which]+=1
643  launchSingleBase (type,faction,sig_units[which])
644  else:
645  for i in xrange(num):
646  launchBaseStuck(type,faction)
647 
648 def zeros (le):
649  return [0 for i in xrange(le)]
650 
651 def launchBases(sys):
652  import universe
653  print 'Launching bases for '+sys
654  fac = VS.GetGalaxyFaction(sys)
655  fgs = BaseFG (fac,sys)
656  sig_units = universe.significantUnits()
657  shipcount=zeros(len(sig_units))
658  for fg in fgs:
659  launchBase(fg[0],fg[1],fac,sys,sig_units,shipcount)
660 
662  leng=2
663  while leng>1 or leng<.00001:
664  X = vsrandom.uniform(-1,1);
665  Y = vsrandom.uniform(-1,1);
666  Z = vsrandom.uniform(-1,1);
667  leng=X*X+Y*Y+Z*Z
668  import VS
669  leng=VS.sqrt(leng)
670  return (X/leng,Y/leng,Z/leng)
671 
672 def incr_by_abs(num,val):
673  debug.debug("A: %s or %s", num+val, num-val)
674  if (num>0):
675  return num+val
676  return num-val
677 
679  rvset = {}
680  iter = VS.getUnitList()
681  while iter.notDone():
682  un = iter.next()
683  rvset[un.getFlightgroupName()] = 1
684  return rvset
685 
688  rv = []
689  for fg in rvset:
690  rv.append(fg)
691  return rv
692 
693 def filterLaunchedFGs(fglist):
695  rv = []
696  for fg in fglist:
697  if not fg in launched:
698  rv.append(fg)
699  return rv
700 
701 def launchUnits(sys):
702  debug.info("Launching units for %s", sys)
703 
704  import faction_ships
705  import launch_recycle
706  import universe
707  sig_units=universe.significantUnits()
708  ownerfac= VS.GetGalaxyFaction(sys)
709  jumpcount=0
710  planetcount=0
711 # asteroidcount=0
712  basecount=0
713  farlen=0
714  for sig in sig_units:
715  if sig.isJumppoint():
716  jumpcount+=1
717  elif sig.isPlanet():
718  planetcount+=1
719 # elif sig.isAsteroid():
720 # asteroidcount+=1
721  else:
722  basecount+=1
723  tmplen=Vector.Mag(sig.Position())
724  if tmplen>farlen:
725  farlen=tmplen
726 
727  for factionnum in xrange(0,faction_ships.getMaxFactions()-1):
728  faction=faction_ships.intToFaction(factionnum)
729  fglist=filterLaunchedFGs(FGsInSystem(faction,sys))
730  isHostile=VS.GetRelation(ownerfac,faction)<0
731  isForeign=faction.find(ownerfac)==-1
732 
733  if isForeign:
734  if basecount+jumpcount:
735  frac=len(fglist)/float(basecount+jumpcount)
736  else:
737  frac=0.0
738  else:
739  if basecount+planetcount+jumpcount:
740  frac=len(fglist)/float(planetcount+basecount+jumpcount)
741  else:
742  frac=0.0
743  if isHostile:
744  for flightgroup in fglist:
745  X=incr_by_abs(vsrandom.uniform(-1.0,1.0),1)*farlen
746  Y=incr_by_abs(vsrandom.uniform(-1.0,1.0),1)*farlen
747  Z=incr_by_abs(vsrandom.uniform(-1.0,1.0),1)*farlen
748  XYZ = (X,Y,Z)
749  typenumbers=ShipsInFG(flightgroup,faction)
750  debug.debug("Really Far Apart around %s and 10000",XYZ)
751  debug.debug(" launching %s for %s at %s", typenumbers, faction, XYZ)
752  launch_recycle.launch_types_around(flightgroup,faction,typenumbers,'default',1,XYZ,0,'','',1,10000)
753  else:
754  for flightgroup in fglist:
755  #jp = sig.isJumppoint()
756  #if sig.isPlanet() or not isForeign:
757  sig = sig_units[vsrandom.randrange(0,len(sig_units))]
758  typenumbers=ShipsInFG(flightgroup,faction)
759  debug.debug(" launching %s for %s", typenumbers, faction)
760 
761  launch_recycle.launch_types_around(flightgroup,faction,typenumbers,'default',sig.rSize()*vsrandom.randrange(10,100),sig,0,'','',1,10000)
762 
763 
764 
766  import vsrandom
767  diff=VS.GetDifficulty()
768  if (diff>.9):
769  return vsrandom.randrange(1,5)
770  if (diff>.5):
771  return vsrandom.randrange(1,4)
772  if (diff>.2):
773  return vsrandom.randrange(1,3)
774  if (vsrandom.randrange(0,4)==0):
775  return 2
776  return 1
777 
778 def GetShipsInFG(fgname,faction):
779  ships = ReadStringList (ccp,MakeFGKey(fgname,faction))
780  if (len(ships)<=ShipListOffset()):
781  return []
782  try:
783  count=int(ships[0])
784  except:
785  debug.error('bad flightgroup record %s', ships)
786  launchnum = DefaultNumShips()
787  if (launchnum>count):
788  launchnum=count
789 
790  nent = (len(ships) - ShipListOffset()) / PerShipDataSize()
791  retn = [0] * nent
792  for i in xrange(_prob_round(launchnum*(0.7+vsrandom.random()+0.3))):
793  which = vsrandom.randrange(count)
794  for j in xrange(nent):
795  pos = j*PerShipDataSize()+ShipListOffset()
796  which -= int(ships[pos+2])
797  if which <= 0:
798  retn[j] += 1
799  break
800  ret = []
801  for i in xrange(nent):
802  if retn[i]:
803  pos = i*PerShipDataSize()+ShipListOffset()
804  ret.append((ships[pos],retn[i]))
805  return ret
806 
807 def LaunchLandShip(fgname,faction,typ,numlaunched=1):
808  key = MakeFGKey (fgname,faction)
809  ships=ReadStringList (ccp,key)
810  debug.debug('LaunchLandShip: fg:%s fac:%s typ:%s, num:%s', fgname, faction, typ, numlaunched)
811  for num in xrange (ShipListOffset(),len(ships),PerShipDataSize()):
812  if (typ == ships[num]):
813  try:
814  ntobegin=int(ships[num+1])
815  nactive=int(ships[num+2])
816 
817  debug.debug("attempting launch for ship %s, begin %s, act %s)",
818  typ, ntobegin, nactive)
819 
820  nactive-=numlaunched
821  # Happens regularly -Patrick
822  # In the first system, nactive seems to always be 0 for all ships.
823  # In other systems, this isn't always true.
824  # This doesn't really seem to matter, though.
825  # Klauss: turned debug.error into debug.debug if it happens so often
826  # to clean up non-debug logs
827  if (nactive<0):
828  nactive=0
829  debug.debug('error more ships launched than in FG %s', fgname)
830  if (nactive>ntobegin):
831  nactive=ntobegin
832  debug.debug('error ships %s landed that never launched', typ)
833  Director.putSaveString(ccp,key,num+2,str(nactive))
834  except:
835  debug.error('error in FG data (str->int)')
836 
837 def LaunchShip (fgname,faction,typ,num=1):
838  LaunchLandShip (fgname,faction,typ,num)
839 
840 def LandShip (fgname,faction,typ,num=1):
841  LaunchLandShip(fgname,faction,typ,-num)
842 
843 def AllShips (faction,offset=1):
844  ret=[]
845  for i in AllFlightgroups (faction):
846  ret+=ShipsInFG (i,faction,offset)
847  return ret
848 
849 def CheckAllShips(faction):
850  for i in AllFlightgroups(faction):
851  sys = FGSystem(i,faction)
852  fgsin=AllFGsInSystem(faction,sys)
853  if (not i in fgsin):
854  debug.error('error '+str(fgsin) + i+' not in system '+ sys)
855 
856 def SortedAllShips (faction,offset=1):
857  ret={}
858  for i in AllFlightgroups (faction):
859  for j in ShipsInFG(i,faction,offset):
860  if j[0] in ret:
861  ret[j[0]]+=j[1]
862  else:
863  ret[j[0]]=j[1]
864  return ret
865 
866 def getFgLeaderType(fgname,faction):
867 # print "wah " +str(ShipsInFG(fgname,faction))
868  l = ShipsInFG(fgname,faction)
869  if (len(l)):
870  if (len(l[0])):
871  return l[0][0];
872  import faction_ships
873  return faction_ships.getRandomFighter(faction)