def render(self, surf, pos, scale): draw.rect(surf, self.backcol, Rect(pos, (scale * 16 + 16, ) * 2)) draw.rect(surf, Colour.darker(self.backcol, 0.9), Rect(pos, (scale * 16 + 15, ) * 2), 2) if self.item: surf.blit(self.item.img[scale], pos) Img.draw_num(surf, self.q, pos, scale + 1)
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)
class Boat(Vehicle): base = Img.imgstripx("Vehicles/Boat") occupied = Img.ColourImageManager(Img.hflip(base[1])) unocc = Img.hflip(base[0]) inverse_support = True @property def imgs(self): return self.occupied[self.player.col] if self.player else self.unocc
def render(self, screen, y, size, rcpos=None): for n, s in enumerate(self.sels): Img.bcentrex( tfont, s, screen, n * 64 + y - 16, col=(0, 0, 0) if rcpos is None or rcpos.y != n else self.selcol)
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
def render(self, screen, srcj): screen.fill(self.bcol) Img.bcentrex(tfont, self.title, screen, 48) y = 0 cc = self.cdict[srcj] for e in self.es: h = e.get_h(self.size.x) e.render(screen, y * 64 + 128, self.size, cc - Vector.VectorX(0, y) if y <= cc.y < y + h else None) y += h
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 FireFlower(Item): img=Img.imgstripx("Plants/FireFlower")[-1] def use(self,area,tpos,tr,p): if area.clear("Objects",tpos): area.spawn_new(War.Fireball,tpos,p.d) return True return False
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 Conveyor(Rotatable): override_name="Conveyor1" override_ss = 100 cspeed=2 imgs=Img.conv_imgs("Transport/Conveyor1") ani=0 layers = ["Conv"] hardness = 10 slayer = "Tiles" cm=None def __init__(self,c,r): super().__init__(c,r) self.tpos=c.pos+Vector.vdirs[self.r] self.d=Vector.vdirs[self.r] def update(self, pos, area, events): if self.cm: self.cm.conv_update(pos,area,self) self.ani=area.anitick item=area.get("Items",pos) if item and not item.mprog: area.move(item,pos,self.d,override_speed=self.cspeed,tpos_cache=self.tpos) def mined(self): return Placeable(self.__class__) @property def img(self): return self.imgs[(self.ani*self.cspeed%64)//4][self.r]
class Miner(Machine): imgs = Img.imgstripxf("Machines/Miner", 16) mine_prog = 0 mine_speed = 0.25 a = 0 mrects = [ Rect(4, 36, 56, 40), Rect(4, 4, 44, 72), Rect(4, 4, 56, 44), Rect(16, 4, 44, 72) ] def update(self, pos, area, events): super().update(pos, area, events) if "Ore" in area.ldict: ore = area.get("Ore", pos) if ore: self.a += 0.1 self.a %= math.tau self.mine_prog += self.mine_speed if self.mine_prog >= ore.hardness and self.add_output( Items.resources[ore.name]): if not ore.inf: ore.q -= 1 if ore.q == 0: area.dobj(ore, pos) self.mine_prog = 0 def render(self, layer, surf, tpos, area, scale=3): if layer == self.renderlayer: Img.draw_rotor(surf, V(*tpos) + V(32, 48), 24, 3, self.a, (80, 80, 80)) super().render(layer, surf, tpos, area, scale)
class BigStack(Object): #BIG SHAQ #In awe at the size of this lad. ABSOLUTE UNIT layers = ["Conv", "Items"] renderlayer = "Items" pickup = Img.sndget("pickup") def __init__(self, coords, item, q): super().__init__(coords) self.item = item self.q = q def interact(self, player, ppos, pos, area): self.q -= player.inv.add(self.item, self.q) if self.q == 0: area.dobj(self, pos) self.pickup.play() def render(self, layer, surf, tpos, area, scale=3): super().render(layer, surf, tpos, area, scale) if layer == self.renderlayer: Img.draw_num(surf, self.q, tpos, scale + 1, True) @property def img(self): return self.item.img
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 Splitter(Machine): imgs=Img.imgstripxf("Transport/Splitter",16) phase=-1 def input(self,d,i): for r in (self.phase,-self.phase): if self.add_output(i,r): self.phase=-r return True
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 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 OutputMachine(Machine): arrows = Img.imgrot("Machines/OutputOnly") def render(self, layer, surf, tpos, area, scale=3): super().render(layer, surf, tpos, area, scale) if layer == self.renderlayer: surf.blit(self.arrows[self.r][scale], tpos) @property def img(self): return self.imgs[self.r==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))
class Tree(Object): hardness = 60 img = Img.imgstripxf("World/Tree")[-1] layers = ["Conv", "Items", "Objects"] renderlayer = "Objects" exoff = Vector.VectorX(0, -16) updates = False def mined(self): return Items.resources["Log"]
def render(self, screen, y, size, rcpos=None): if Research.current[self.team]: for x, r in enumerate(Research.current[self.team]): if r is Research.current_research[self.team]: draw.rect( screen, (100, 100, 100), Rect(x % size.x * 64, y + x // size.x * 64, 64, 64)) screen.blit(r.img[3], (x % size.x * 64, y + x // size.x * 64)) if rcpos is not None: screen.blit(sel[3], rcpos * 64 + Vector.VectorX(0, y)) selr = Research.current[self.team][rcpos.x + rcpos.y * size.x] l = len(selr.packs) offset = (size.x - l) * 32 for x, p in enumerate(selr.packs): Img.draw_with_num(screen, Items.get_item_image("SP%s" % p), selr.n, (offset + x * 64, (size.y - 1) * 64), 4) else: Img.bcentrex(tfont, "NO RESEARCH AVAILABLE", screen, y - 16)
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 Farmer(OutputMachine): imgs = Img.imgstripxf("Machines/Farmer") crops = None crop = None def __init__(self, c, r, p): self.gui = MUI.MUI( "Select Crop", [MUI.SelList([c.get_name() for c in Agriculture.crops])]) super().__init__(c, r, p) def init_crops(self, area, pos): self.crops = {} for tpos in V(5, 5).iter_space_2d(pos - V(2, 2)): pcrop = True for l in self.crop.layers: if not area.clear(l, tpos): pcrop = False tcrop = area.get(l, tpos) if isinstance(tcrop, self.crop) and not tcrop.bound: tcrop.bound = self area.ups.remove((tpos, tcrop)) self.crops[tpos] = tcrop break if area.get("Tiles", tpos).name != self.crop.tile: pcrop = False if tpos not in self.crops: self.crops[tpos] = area.spawn_new(self.crop, tpos, self) if pcrop else None def gui_trigger(self, *args): self.crop = Agriculture.crops[args[0]] def update(self, pos, area, events): if self.crops: if not randint(0, self.crop.gspeed // 25): tpos, ch = choice(list(self.crops.items())) if ch: if not ch.exists: self.crops[tpos] = None elif ch.growth < ch.max_g: ch.growth += 1 elif self.add_output(ch.mined()): ch.growth = ch.harvest_state elif self.crop: self.init_crops(area, pos) super().update(pos, area, events) def on_dest(self, area, pos): if self.crops: for tpos, crop in self.crops.items(): if crop: crop.bound = None area.ups.add((tpos, crop))
class SlotMachine(OutputMachine): outputslot=None output_enabled=False arrows=Img.imgrot("Machines/StandardIO") def update(self, pos, area, events): if self.output_enabled: if self.outputslot and self.outputslot.q: if self.add_output(self.outputslot.item): self.outputslot.remove(1) elif area.get("Conv",pos+Vector.vdirs[self.r]): self.output_enabled=True super().update(pos,area,events)
class EntangledBox1(Box): img = Img.imgstripxf("Buildings/EntangledBox")[0] gen = Generators.EntangledBuilding() def __init__(self, c): Object.__init__(self, c) self.dummy = EntangledDummy(self) self.area = Area(self.internalsize, self.gen, self.dummy) def in_warp(self, d): hb = self.area.bounds // 2 return Coordinate(self.area, hb - d * hb - V(bool(d.y), bool(d.x)))
class Electrolyser(Furnace): imgs = Img.imgstripxf("Machines/Electrolyser") def __init__(self, c, r, p): SlotMachine.__init__(self, c, r, p) self.processor = MUI.Processor("Electrolyser", 20) self.fuel = MUI.ElectroSlot(self) self.gui = MUI.MUI("Electrolyser", [self.processor, self.fuel]) self.outputslot = self.processor.output def input(self, d, i): return self.processor.input.add(i)
class Monolith(Owned): imgs=Img.imgstripxf("Buildings/Monolith",16) t=0 layers = ["Conv","Items","Objects"] renderlayer = "Objects" def update(self, pos, area, events): self.t+=1 if self.t==240: from Lib import GUI raise GUI.GameEnd(self.p.team) @property def img(self): return self.imgs[self.t%20==19]
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 Fireball(Rotatable): layers = ["Objects"] imgs=Img.imgrot("War/Fireball") rng=4 mspeed = 8 def update(self, pos, area, events): if self.mprog: return if self.rng and area.move(self,pos,Vector.vdirs[self.r]): self.rng-=1 else: area.dobj(self,pos) area.create_exp(pos,1,"Cross",0)