1 import os
2 import re
3 import time
4 import thread
5 import random
6 from threading import Timer
7
8 from cocos import euclid
9 from cocos.actions import MoveTo, Delay
10 from cocos.actions.instant_actions import CallFunc, Hide, Show
11 from cocos.sprite import *
12 from pyglet.resource import media
13 from cocos.actions import FadeOut
14
15 import utils
16 import objects
17 from constants import *
18 from utils import aabb_to_aa_rect
19
21 speed = 1
22
24 parity = random.choice(["0","1"])
25 super(Packet, self).__init__(os.path.join("images", "packet" + parity + ".png"))
26 self.position = position
27 self.onMap = False
28
29
31
32 - def __init__(self, image, curVertex, health=0, pid=0, buildTime=1):
33 super(Unit, self).__init__(image)
34 self.imageName = image
35 self.imageName = image.split("/")[2]
36 self.imageOutline = "images/outlines/" + self.imageName.split(".")[0] + "_outline.png"
37
38 self.initialHealth = health
39
40 self.pid = pid
41
42 tid = -1
43
44 self.maxHealth = health
45
46 self.buildTime = buildTime/TEST_SPEEDUP
47
48 self.playerIndicator = None
49
50 self.curVertex = curVertex
51
52 self.health = 1
53
54 self.uid = -1
55
56 self.slotIndex = -1
57
58 self.isSelected = False
59
60 self.menu = None
61
62 self.isDestroyed = False
63
64 self.isSelectable = True
65
66 self.color = (255,255,255)
67
68 self.selectedColor = (200,200,200)
69
70 self.unselectedColor = self.color
71
72 self.selectedSprite = None
73
74 self.isRemoved = False
75
76
79
81 pass
82
84
85
86 if selectedVal == True:
87 self.curVertex.highlight_adjacents(True)
88 else:
89 self.curVertex.highlight_adjacents(False)
90
91 if selectedVal == self.isSelected:
92 return
93
94 if selectedVal:
95 self.scale = UNIT_SCALE_SELECTED
96 self.unselectedColor = self.color
97 if self.playerIndicator:
98 self.playerIndicator.visible = False
99 self.color = self.selectedColor
100 if self.selectedSprite:
101 self.add(self.selectedSprite)
102 if not type(self) == CPU:
103 self.display_action_menu(gameMap, cm, player)
104 else:
105 self.scale = UNIT_SCALE_NORMAL
106 self.color = self.unselectedColor
107 if self.playerIndicator:
108 self.playerIndicator.visible = True
109 if self.selectedSprite:
110 self.remove(self.selectedSprite)
111 if not type(self) == CPU:
112 self.clear_action_menu(gameMap, cm, player)
113 self.isSelected = selectedVal
114
130
139
141
142 self.actionList = player.unitActionLists[self.__class__.__name__]
143 return self.actionList
144
146
147
148
149 c = objects.Objects.get_controller()
150 c.client_attack(self.pid,self.uid,power)
151 self.health -= power
152 self.color = (self.unselectedColor[0] * float(self.health) / self.maxHealth, self.unselectedColor[1] *
153 float(self.health) / self.maxHealth, self.unselectedColor[2] * float(self.health) / self.maxHealth)
154
155 if self.health <= 0:
156
157 if self in attacker.shouldAttack:
158 attacker.shouldAttack.remove(self)
159 self.shouldAttack = set()
160 if not self.isDestroyed:
161 self.isDestroyed = True
162 self.isSelectable = False
163 self.do(CallFunc(self.destroy_action))
164
166 self.health -= power
167 self.color = (self.unselectedColor[0] * float(self.health) / self.maxHealth, self.unselectedColor[1] *
168 float(self.health) / self.maxHealth, self.unselectedColor[2] * float(self.health) / self.maxHealth)
169
174
175 Unit.register_event_type("on_destruction")
176
177
179
180 - def __init__(self, image, curVertex, health=0, pid=0, speed=0, power=0, attackRange=0, buildTime=1):
181
182 fullImagePath = os.path.join("images", "troops", image)
183
184 super(Troop, self).__init__(fullImagePath, curVertex, health, pid=pid, buildTime=buildTime)
185
186
187 self.initialHealth = health
188
189 self.playerIndicator = Sprite(os.path.join("images","troops", "player.png"))
190 self.playerIndicator.color = PLAYER_COLORS[self.pid]
191 self.playerIndicator.opacity = 0
192 self.add(self.playerIndicator,z=-1)
193
194
195 if not curVertex.add_troop(self):
196 self.slotIndex = -1
197 return
198
199 self.position = curVertex.troopSlots[self.slotIndex].position
200 self.cshape = aabb_to_aa_rect(self.get_AABB())
201 self.cshape.center = self.position
202
203 self.power = power
204
205
206 self.destVertex = None
207
208 self.speed = float(speed) * TEST_SPEEDUP
209
210 self.attackRange = attackRange
211
212 self.scale = UNIT_SCALE_NORMAL
213
214
215 self.shouldAttack = set()
216
217 self.is_attacking = False
218
219 self.attackingPath = []
220
221 self.packets = []
222
223 self.targetVid = -1
224
225 self.sourceVid = -1
226
227 for i in range(4):
228 self.packets.append(Packet(self.position))
229
230
232 self.opacity = o
233 self.playerIndicator.opacity = o
234
236
237 if self.is_attacking and type(self) != BufferOverflow:
238
239
240
241 return
242 self.shouldAttack.add(target)
243 if self.can_attack(target):
244 path = m.get_path(self.curVertex, target.curVertex, self.pid, self, "attack")
245
246 if path and len(path) <= self.attackRange + 1:
247 self.attackingPath = path
248 self.is_attacking = True
249 c = objects.Objects.get_controller()
250 c.client_attack_animation(self.pid,self.uid,target.pid,target.uid,self.attackingPath)
251 self.targetVid = target.curVertex.vid
252 self.sourceVid = self.curVertex.vid
253 self.schedule_interval(self.attack_action, 1, target, m)
254 else:
255
256 utils.play_sound("error.wav")
257 return
258
259
261 self.is_attacking = True
262 self.schedule_interval(self.animate_packets,1,target,m)
263
265
266 if (issubclass(type(target),Unit) and type(self) != DNSPoison and type(self) != SQLInjection) or (type(self) == DNSPoison and issubclass(type(target),Unit)):
267
268
269 return True
270 elif type(self) == SQLInjection and issubclass(type(target),Unit) and target.curVertex.building != None and (type(target.curVertex.building) == Server or type(target.curVertex.building) == Database):
271
272 return True
273 else:
274 return False
275
277 targetVid = target.curVertex.vid
278 sourceVid = self.curVertex.vid
279 c = objects.Objects.get_controller()
280 if len(self.shouldAttack) > 0:
281 if target in self.shouldAttack:
282 if sourceVid != self.sourceVid:
283 self.end_attack()
284 return
285 if self.targetVid != targetVid:
286 self.attackingPath = gameMap.get_path(self.curVertex, target.curVertex, self.pid, self, action="Attack")
287
288 if self.attackingPath == None or len(self.attackingPath) > self.attackRange:
289 self.end_attack()
290 return
291 c.client_attack_animation(self.pid,self.uid,target.pid,target.uid,self.attackingPath)
292 self.targetVid = targetVid
293 target.on_attack(self.power, self)
294 self.animate_packets(dt,target,gameMap)
295 else:
296 self.end_attack()
297
298
300
301 if self.is_attacking:
302 if self.packets:
303 p = self.packets.pop()
304 p.position = self.position
305 if not p.onMap:
306 p.onMap = True
307 gameMap.add(p, z=PACKET_Z)
308 action = Show()
309 action += MoveTo(gameMap.vertices[self.attackingPath[0]].position, 0.2)
310 for v in self.attackingPath[1:]:
311 vertex = gameMap.vertices[v]
312 action += MoveTo(vertex.position, float(1 / p.speed))
313 action += MoveTo(target.position, 0.2)
314 action += Hide()
315 p.do(action)
316 self.packets.insert(0, p)
317
318
319
332
335
336 Troop.register_event_type("troop_attack")
337
338
340
341 - def __init__(self, image, curVertex, health=0, pid=0, buildTime=1):
342 fullImagePath = os.path.join("images", "buildings", image)
343 super(Building, self).__init__(fullImagePath, curVertex, health, pid, buildTime=buildTime)
344
345
346 self.isBusy = False
347 self.initialHealth = health
348
349
350 if not curVertex.add_building(self):
351 self.slotIndex = -1
352 return
353
354 if type(self) == CPU:
355 self.position = curVertex.position
356 else:
357 self.position = euclid.Vector2(curVertex.buildingSlot.position[0], curVertex.buildingSlot.position[1] + 10)
358 self.cshape = aabb_to_aa_rect(self.get_AABB())
359 self.cshape.center = self.position
360
363
366
368 - def __init__(self, curVertex=None, position=None, health=24, pid=0, buildTime=0, speed=2):
372
374
375 - def __init__(self, curVertex, health=24, pid=0, speed=1.0):
376 super(Ping, self).__init__('ping_gray.png', curVertex, health, pid, speed,buildTime=10)
377 self.selectedSprite = Sprite("images/troops/ping.png")
378 self.tid = "Ping"
379
380 - def ping(self, delete_method):
381 c = objects.Objects.get_controller()
382 if self.curVertex.borderVertices:
383 curVertex = self.curVertex
384 for asID in self.curVertex.borderVertices.keys():
385 destVertexList = self.curVertex.borderVertices[asID]
386 for destVertex in destVertexList:
387 if destVertex.asID not in c.visibleASes:
388 self.isSelectable = False
389 self.isDestroyed = True
390 pingAction = MoveTo(self.curVertex.position, 0.6)
391 pingAction += MoveTo(destVertex.position, 2)
392 pingAction += MoveTo(self.curVertex.position, 2)
393 pingAction += CallFunc(c._show_as, asID)
394
395 pingAction += CallFunc(delete_method, self)
396 pingAction += CallFunc(curVertex._update_visibility)
397
398 self.do(pingAction)
399 self.dispatch_event("Ping")
400
401 utils.play_sound("ping.wav")
402
403 return True
404
405 return False
406
407
408 Ping.register_event_type("Ping")
409
410
412
413 - def __init__(self, curVertex, health=32, pid=0, speed=0.5, power=2, attackRange=2):
414 super(DOS, self).__init__("dos_gray.png", curVertex, health, pid, speed, power, attackRange=attackRange,buildTime=11)
415 self.selectedSprite = Sprite("images/troops/dos.png")
416 self.tid = "DOS"
417
418
420
421 - def __init__(self, curVertex, health=48, pid=0, speed=0.25, power=2, attackRange=2):
422 super(BufferOverflow, self).__init__("buffer_overflow_gray.png", curVertex, health, pid, speed,power, attackRange=attackRange,buildTime=25)
423 self.selectedSprite = Sprite("images/troops/buffer_overflow.png")
424 self.tid = "BufferOverflow"
425
426
428
429 - def __init__(self, curVertex, health=60, pid=0, speed=0.4, power=10, attackRange=2):
430 super(SQLInjection, self).__init__("sql_injection_gray.png", curVertex, health, pid, speed,power, attackRange=attackRange,buildTime=18)
431 self.selectedSprite = Sprite("images/troops/sql_injection.png")
432 self.tid = "SQLInjection"
433
434
436
437 - def __init__(self, curVertex, health=96, pid=0, speed=0.3, power=2, attackRange=2):
438 super(PingOfDeath, self).__init__("ping_of_death_gray.png", curVertex, health, pid, speed,power, attackRange=attackRange,buildTime=20)
439 self.selectedSprite = Sprite("images/troops/ping_of_death.png")
440 self.tid = "PingOfDeath"
441
442 - def attack(self, target, gameMap):
443 from maps import Vertex
444 if type(target) == Vertex or ((issubclass(type(target), Troop) or type(target) == Firewall) and target.pid != self.pid):
445
446 if type(target) != Vertex:
447 target = target.curVertex
448 path = gameMap.get_path(self.curVertex, target, self.pid, self, "attack")
449 if path and len(path) <= self.attackRange + 1:
450 self.attackingPath = path
451 self.is_attacking = True
452
453
454 pingOfDeathAction = Delay(0)
455
456 for vertexID in path:
457 vertex = gameMap.vertices[vertexID]
458 pingOfDeathAction += MoveTo(vertex.position, self.speed)
459
460
461 pingOfDeathAction += CallFunc(self.POD, target)
462
463 controller = objects.Objects.get_controller()
464 pingOfDeathAction += CallFunc(controller.remove_unit, self)
465 self.do(pingOfDeathAction)
466 return True
467 return False
468
469
470 - def POD(self, target):
471 hitEnemyTroop = False
472
473 if target.building != None and type(target.building) == Firewall and target.building.pid != self.pid:
474
475 target.building.destroy_action()
476 hitEnemyTroop = True
477 self.isDestroyed = True
478
479 s = objects.Objects.get_controller()
480 for slot in target.troopSlots.values():
481 troop = slot.troop
482 if troop.pid != self.pid:
483
484 troop.on_attack((troop.health + 1) / 2,self)
485 self.isDestroyed = True
486 hitEnemyTroop = True
487 if self.pid == s.pid:
488 if hitEnemyTroop:
489 utils.play_sound("ping_of_death.wav")
490 else:
491 utils.play_sound("ping_of_death_fail.wav")
492
494
495 - def __init__(self, curVertex, health=42, pid=0, speed=0.1, power=7, attackRange=2):
496 super(DNSPoison, self).__init__("dns_poison_gray.png", curVertex, health, pid, speed,power, attackRange=attackRange,buildTime=28)
497 self.selectedSprite = Sprite("images/troops/dns_poison.png")
498 self.tid = "DNSPoison"
499
500
501
503
504 - def __init__(self, curVertex, health=32, pid=0, speed=0.5):
507
508
510
511 - def __init__(self, curVertex, health=48, pid=0, speed=0.5):
514
515
517
518 - def __init__(self, curVertex, health=100, pid=0, speed=0.15):
521
523
524 - def __init__(self, curVertex, health=20, pid=0, speed=0.15):
525 super(Handshake, self).__init__("handshake_gray.png", curVertex, health, pid, speed,buildTime=8)
526 self.selectedSprite = Sprite("images/troops/handshake.png")
527 self.tid = "Handshake"
528
530
531
532 c = objects.Objects.get_controller()
533 source = c.map.vertices[str(self.curVertex.vid)]
534 dest = c.map.vertices[str(other.curVertex.vid)]
535 source_position = c.map.vertexPositions[source.vid]
536 dest_position = c.map.vertexPositions[dest.vid]
537
538
539 if dest == source:
540 print "Can't make an edge to the same vertex"
541
542 else:
543
544 from maps import Edge, ASEdge
545 if source.asID != dest.asID:
546 source.borderVertices[dest.asID].append(dest)
547 dest.borderVertices[source.asID].append(source)
548 new_edge = ASEdge(source_position, dest_position, source, dest, AS_EDGE_COLOR, visible=True)
549 else:
550
551
552 new_edge = Edge(source_position, dest_position, source, dest, EDGE_COLOR, visible=True)
553
554
555 source.adjacentVertices.append(dest)
556 dest.adjacentVertices.append(source)
557
558 source.edges.append(new_edge)
559 dest.edges.append(new_edge)
560
561 new_edge.visible = True
562
563 c.map.edges.append(new_edge)
564 c.map.add(new_edge, z=EDGE_Z)
565
566 c.remove_unit(other)
567 c.remove_unit(self)
568
569
571
572 - def __init__(self, curVertex, health=50, pid=0, speed=0.5):
573 super(Spoof, self).__init__("spoof_gray.png", curVertex, health, pid, speed,buildTime=5)
574 self.selectedSprite = Sprite("images/troops/spoof.png")
575 self.tid = "Spoof"
576
578
579 - def __init__(self, curVertex, health=50, pid=0):
580
581 image = random.choice(["firewall.png", "research_factory.png", "algorithm_factory.png", "sinkhole.png", "server.png", "rsa.png",
582 "database.png"])
583
584 self.buildingType = {
585 "firewall.png":Firewall,
586 "research_factory.png":SoftwareUpdater,
587 "algorithm_factory.png":AlgorithmFactory,
588 "sinkhole.png":Sinkhole,
589 "server.png":Server,
590 "rsa.png":RSA,
591 "database.png":Database
592 }[image]
593 super(SpoofedBuilding, self).__init__(image, curVertex, health, pid, buildTime=7)
594 self.tid = "SpoofedBuilding"
595
597
598 - def __init__(self, curVertex, health=190, pid=0):
601
603 - def __init__(self, curVertex, health=130, pid=0):
606
608 - def __init__(self, curVertex, health=130, pid=0):
611
613 - def __init__(self, curVertex, health=150, pid=0):
614 super(Sinkhole, self).__init__("sinkhole.png", curVertex, health, pid,buildTime=13)
615 self.tid = "Sinkhole"
616 self.shouldAttack = set()
617
618 -class CPU(Building):
619 - def __init__(self, initCore, health=90, pid=0):
620 super(CPU, self).__init__("cpu.png", initCore, health, pid,buildTime=40)
621 self.action = None
622 self.transTimer = None
623 self.tid = "CPU"
624
626 - def __init__(self, curVertex, health=220, pid=0):
629
630
631 -class RSA(Building):
632 - def __init__(self, curVertex, player=None, health=100, pid=0,buildTime=9):
637
643
649
650
652 - def __init__(self, curVertex, health=150, pid=0,buildTime=30):
653 super(Database, self).__init__("database.png", curVertex, health, pid)
654 self.tid = "Database"
655
660
665
666
667
668 ALL_UNITS = {
669 "Ping": Ping,
670 "PingOfDeath": PingOfDeath,
671 "Installer": Installer,
672 "APTGet": APTGet,
673 "SQL": SQLInjection,
674 "DOS": DOS,
675 "DNSPoison": DNSPoison,
676 "Firewall": Firewall,
677 "Server": Server,
678 "AlgorithmFactory": AlgorithmFactory,
679 "SoftwareUpdater": SoftwareUpdater,
680 "RSA": RSA,
681 "Database": Database
682 }
683