class LaserTurret(Turret): img=Img.imgx("War/LaserBase") ds=1 turret=Img.lotsrots(Img.imgx("War/LaserTurret"),ds) fx=FX.Laser def explode(self,area,pos,tier): if tier>=2: super().explode(area,pos,tier)
def get_item_image(name): try: return iimgs[name] except KeyError: try: nimg = Img.imgx("Resources/" + name) except error: nimg = Img.imgx("Placeables/" + name) iimgs[name] = nimg return nimg
class Turret(Machine): img=Img.imgx("War/GunBase") ds=1 turret=Img.lotsrots(Img.imgx("War/GunTurret"),ds) angle=0 rspeed=0.04 sleep=60 hardness = 300 targetable = True hp=1 fx=FX.Gunfire damage=0.01 rng=4 def render(self, layer, surf, tpos, area,scale=3): super().render(layer,surf,tpos,area,scale) if layer==self.renderlayer: surf.blit(self.turret[int(math.degrees(self.angle%math.tau)//self.ds)][scale],(tpos[0],tpos[1]-4)) def shoot(self,area,target): target.on_shoot(area, target.coords.pos, self.damage) return True def update(self, pos, area, events): ls=[] if self.hp<=1: self.hp+=0.001 if self.sleep: self.sleep-=1 for t in area.targets: length=pos.len_to(t.coords.pos) if t.team is not None and t.team!=self.p.team: if length<=self.rng: apos=t.coords.pos+t.moveoff/64 tar_ang=pos.angle_to(apos)%math.tau d=ang_d(self.angle,tar_ang) if abs(d)<=self.rspeed: self.angle=tar_ang if self.shoot(area,t): area["FX"].add(self.fx(pos*64+Vector.VectorX(32+32*math.cos(self.angle),24-32*math.sin(self.angle)),t.coords.pos*64+t.moveoff,self.angle,pos.len_to(apos)*64-32)) elif d<0: self.angle+=self.rspeed else: self.angle-=self.rspeed self.angle%=math.tau break else: ls.append(length) else: self.sleep=60 if not ls else min(ls)*5 def on_shoot(self,area,pos,power): self.hp-=power if self.hp<=0: self.explode(area,pos,2) @property def team(self): return self.p.team
class Pickaxe(Item): img=Img.imgx("Tools/Pickaxe") last_used=0 MAX_CONTINUOUS=200 last_mined=None stack_size = 1 singular = True continuous = True def use(self,area,tpos,tr,p): for l in reversed(area.layers): o=l[tpos] if o and o.hardness: if o is self.last_mined and pygame.time.get_ticks()-self.last_used<self.MAX_CONTINUOUS: self.prog+=1 if self.prog==o.hardness: item=o.mined() o.on_mine(area,tpos) if item is None or p.inv.add(item,1): bsnd.play() elif area.clear("Items",tpos): area.spawn_item(item,tpos) bsnd.play() else: o.on_mine(area, tpos,True) error.play() self.prog=0 self.prog_max=0 self.last_mined=None else: self.prog=0 self.prog_max=o.hardness self.last_mined=o break self.last_used=pygame.time.get_ticks()
class Bridger(Item): img=Img.imgx("Tools/BridgeBuilder") def use(self,area,tpos,tr,p): t=area.get("Tiles",tpos) if t and not t.support: area.set_tile("Bridge",tpos) return True
class ElectroSlot(Element): colour = (255, 216, 0) nullcolour = (100, 100, 100) electro = Img.imgx("Electro") last_power = 0 last_need = 0 def __init__(self, mach): self.mach = mach def render(self, screen, y, size, rcpos=None): screen.blit(self.electro[3], (0, y)) if rcpos is not None: screen.blit(sel[3], (0, y)) draw.rect(screen, self.nullcolour, Rect(64, y + 16, (size.x * 64 - 64), 32)) area = self.mach.coords.area if not area.infinite and area.ebuffer: draw.rect( screen, self.colour, Rect(64, y + 16, (size.x * 64 - 64) * area.ebuffer / area.emax, 32)) def get_power(self, needed): self.last_need = needed self.last_power = self.mach.coords.area.get_power(needed) return self.last_power
class Explosion(Object): layers = ["Objects"] img=Img.imgx("War/Exp") t=20 def update(self, pos, area, events): self.t-=1 if self.t==0: area.dobj(self,pos)
class ChainSaw(Item): img=Img.imgx("Tools/ChainSaw") stack_size = 1 name="Chainsaw" def use(self,area,tpos,tr,p): tree=area.get("Objects",tpos) if tree and tree.name=="Tree" and p.inv.add(tree.mined()): area.dobj(tree,tpos)
class Storage(FixedMachine): imgs=[Img.imgx("Transport/Storage")] def __init__(self,c,p): super().__init__(c,p) self.inv=MultiSlot([Slot() for _ in range(7)]) self.gui=MUI.MUI("Storage",[MUI.Inventory(self.inv)]) def input(self,d,i): return self.inv.add(i)
class ChaosChest(FixedMachine): imgs=[Img.imgx("Transport/ChaosChest")] def __init__(self,c,p): super().__init__(c,p) self.inv=MUI.ChaosInventory(self.p.team) self.gui=MUI.MUI("Chaos Chest",[self.inv]) def input(self,d,i): return chaos_slots[self.p.team].add(i,1) def re_own(self,p): self.p=p self.inv.team=p.team
class Mine(Owned): layers = ["Conv"] img=Img.imgx("War/Mine") def update(self, pos, area, events): o=area.get("Objects",pos) if o and not o.mprog: self.explode(area,pos,1) def explode(self,area,pos,tier): area.dobj(self, pos) area.create_exp(pos, 1, "Square") return False def is_visible(self,p): return p.team==self.p.team
class ChaosCrystal(Object): layers = ["Conv","Items","Objects"] renderlayer = "Objects" cimg=resources["ChaosCrystal"].img shadow=Img.imgx("Shadow") tick=0 def interact(self,player,ppos,pos,area): if player.inv.add(resources["ChaosCrystal"]): area.dobj(self,pos) def update(self, pos, area, events): self.tick+=0.1 self.tick%=math.tau def render(self, layer, surf, tpos, area,scale=3): if layer==self.renderlayer: surf.blit(self.shadow[scale],tpos) surf.blit(self.cimg[scale],[tpos[0],tpos[1]-8+(scale+1)*math.sin(self.tick)])
class SpawnBox(Box): img = Img.imgx("Buildings/SpawnBox") def __init__(self, c, t): super().__init__(c) self.team = t def in_warp(self, d): return False def mined(self): from Lib import GUI raise GUI.GameEnd(not self.team) def explode(self, area, pos, tier): pass @property def hardness(self): return 600
class GunTurret2(GunTurret): rspeed = 0.12 fire_rate = 4 turret = Img.lotsrots(Img.imgx("War/GunTurret2"), 1) rng = 8
class Lab(Element): progress = 0 pcol = (200, 200, 255) backcol = (0, 0, 0) overlay = Img.imgx("SCIENCE") done = Img.sndget("research") def __init__(self, energy, power, team): self.inputs = Items.MultiSlot([ Items.FilterSlot(Items.resources["SP%s" % n]) for n in range(1, 7) ]) self.energy = energy self.power = power / 60 self.team = team def inside(self, rpos, w): return rpos.x < len(self.inputs.slots) and not rpos.y def get_h(self, w): return 2 def render(self, screen, y, size, rcpos=None): for n, s in enumerate(self.inputs.slots): s.render(screen, (n * 64, y), 3) if rcpos is not None and n == rcpos.x: screen.blit(sel[3], (n * 64, y)) if Research.current_research[self.team]: Img.draw_with_num(screen, Research.current_research[self.team].img, Research.rprogs[self.team], ((n + 1) * 64, y), 4) draw.rect(screen, self.backcol, Rect(0, y + 64, len(self.inputs.slots) * 64, 32)) if self.progress: draw.rect( screen, self.pcol, Rect(0, y + 64, len(self.inputs.slots) * 64 * self.progress / self.energy, 32)) screen.blit(self.overlay[3], (0, y + 64)) def on_a(self, rpos, w, p): self.inputs.slots[rpos.x].transfer(p.inv) def on_drop(self, rpos, w, slot): slot.transfer(self.inputs.slots[rpos.x]) def machine_update(self, ui, machine): cr = Research.current_research[self.team] if cr: if self.progress: if self.progress == self.energy: Research.rprogs[self.team] += 1 if Research.rprogs[self.team] == cr.n: Research.on_complete(self.team) self.done.play() self.progress = 0 else: self.progress += ui.get_power( min(self.power, self.energy - self.progress)) else: if all(self.inputs.slots[n - 1] for n in cr.packs): gp = ui.get_power(self.power) if gp: for n in cr.packs: self.inputs.slots[n - 1].remove(1) self.progress += gp break
class Crossover(FixedMachine): imgs=[Img.imgx("Transport/Crossover")] exoff = Vector.VectorX(0,-4) def input(self,d,i): return self.add_output(i,override_d=d)
class StdBox(Box): img = Img.imgx("Buildings/StdBox")
class Arrow(Overlay): imgs = Img.imgrot(Img.imgx("Overlays/Arrow"))
class Wrench(Item): img=Img.imgx("Tools/Wrench") def use(self,area,tpos,tr,p): o=area.get("Objects",tpos) if o: o.wrench(p,p.coords.pos,tpos,area)
from Objects import Base from random import randint from math import log from Lib import Img from Engine import Items from Game import Registry infsparks = Img.imgx("Ores/InfiniteSparkles") def ore_strip(fil): imgs = Img.imgstriprot(fil) inf = imgs[-1][0].copy() inf.blit(infsparks, (0, 0)) imgs.append(Img.imgrot(inf)) return imgs class Ore(Base.Object): layers = ["Ore"] imgs = [] updates = False hardness = 120 def __init__(self, coords, q, aq): super().__init__(coords) self.inf = q == "INF" self.q = q if self.inf else q + 1 self.r = randint(0, 3) self.i = len(self.imgs) - 1 if self.inf else max( 0, min(int(log(aq, 7) - 1), len(self.imgs) - 2))
from Lib import Vector, Img from Game import Registry, Research from Engine import Items from collections import Counter from pygame import draw, Rect tfont = Img.fload("cool", 64) sel = Img.imgx("GUISelect") arrow = Img.imgx("Arrow") error = Img.sndget("error") class MUI(object): bcol = (210, ) * 3 size = Vector.zero def __init__(self, title, elements): self.re_init(title, elements) self.cdict = {} def re_init(self, title, elements): self.title = title self.es = elements def on_enter(self, j, sz): self.size = sz self.cdict[j] = Vector.zero def render(self, screen, srcj): screen.fill(self.bcol) Img.bcentrex(tfont, self.title, screen, 48) y = 0