Example #1
0
	def __init__(self, world):
		self.image = None
		self.gore = None
		self.position = Vector2(0,0)
		self.world = world
		self.group = None
		self.ai = AIController()
		self.abilities = [Ability(self, Ability.lookup["Attack"])]
		self.singular = 'unknown'
		self.sight = 5
		self.health = self.maxHealth = 30
		self.inventory = Inventory(self, world.items)
		self.deathTimer = 50
		self.lastDamage = 0
		self.hostile = False
		self.lastAttacker = None
		self.name = None
		self.action = None
		self.lastTarget = None
		self.observers = []
		self.quickcast = None
Example #2
0
class Entity:

	living = "player"
	dead = "body"
	damage = "damage"
	step = "step.wav"
	ouch = "ouch.wav"
	
	def __init__(self, world):
		self.image = None
		self.gore = None
		self.position = Vector2(0,0)
		self.world = world
		self.group = None
		self.ai = AIController()
		self.abilities = [Ability(self, Ability.lookup["Attack"])]
		self.singular = 'unknown'
		self.sight = 5
		self.health = self.maxHealth = 30
		self.inventory = Inventory(self, world.items)
		self.deathTimer = 50
		self.lastDamage = 0
		self.hostile = False
		self.lastAttacker = None
		self.name = None
		self.action = None
		self.lastTarget = None
		self.observers = []
		self.quickcast = None

	def move(self, direction):

		x, y = direction
		oldx, oldy = self.position

		newx = floor(oldx + x)
		newy = floor(oldy + y)

		if not self.world.isLocationPassable(Vector2(newx, newy)):
			return False

		self.position = Vector2(newx, newy)
		
		return True

	def update(self):
		
		done = True
		
		if self.action is not None:
			done = self.action.update()
			if done:
				self.action = None
				
		return done
			

			
	def draw(self, screen, camPos, images, visible):

		tileSize = 32
		relx = self.position[0] - camPos[0]  
		rely = self.position[1] - camPos[1] 
		position = (((relx + 8)*tileSize), ((rely + 8) * tileSize))

		if visible(self.position):
			screen.blit(self.getImage(images), position)
	
		if self.action is not None:
			self.action.draw(screen, camPos, visible)
	
	def getImage(self, images):
			if self.health == 0:
				return images.get(self.__class__.dead, self.position)
			elif time() - self.lastDamage < 0.2:
				return images.get(self.__class__.damage, self.position)
			else:
				return images.get(self.__class__.living, self.position)

	def save(self):
		data = {}
		data['type'] = self.__class__.__name__
		data['position'] = Vector2.save(self.position)
		data['health'] = self.health
		data['deathTimer'] = self.deathTimer
		data['hostile'] = self.hostile
		data['name'] = self.name
		data['inventory'] = self.inventory.save()
		abi = []
		for ability in self.abilities:
			abi.append(ability.save())
		data['abilities'] = abi
		data['ai'] = self.ai.save()
			
		return data

	def load(self, data):
		if 'position' in data.keys():
			self.position = Vector2.load(data['position'])
		if 'health' in data.keys():
			self.health = data['health']
		if 'deathTimer' in data.keys():
			self.deathTimer = data['deathTimer']
		if 'hostile' in data.keys():
			self.hostile = data['hostile']
		if 'name' in data.keys():
			self.name = data['name']
		if 'inventory' in data.keys():
			self.inventory.load(data['inventory'])
		if 'abilities' in data.keys():
			self.abilities = []
			for ability in data['abilities']:
				toAdd = Ability(self)
				toAdd.load(ability)
				self.abilities.append(toAdd)
		if 'ai' in data.keys():
			self.ai.load(data['ai'])
			
	def turn(self):

		for ability in self.abilities:
			ability.update()
	
		if self.health > 0:
			if self.group is not None:
				if self.distance(self.getLeader().position) > 20:
					self.teleportToLeader()
			self.regen()
			self.ai.act()
		else:			
			self.deathTimer -= 1
		
	def inChunk(self, position):
		
		
		posX = position[0] << 4
		posY = position[1] << 4
		
		mobX = self.position[0]
		mobY = self.position[1]
		
		if mobX < posX:
			return False
		
		if mobX > posX + 16:
			return False
		
		if mobY < posY:
			return False
		
		if mobY > posY + 16:
			return False
		
		return True
		
		
	def canSpawn(self, position):
		
		tile = self.world.getTile(position)
		ground = tile.getGround()
		if not ground.passable:
			return False
		
		if not ground.spawnable:
			return False
		
		return True
	
	def partyCanSee(self, position):
		if self.group is None:
			return self.canSee(position)
			
		return self.group.canSee(position)
	
	def canSee(self, target):
		
		relx = abs(self.position[0] - target[0])
		rely = abs(self.position[1] - target[1])

		if relx > self.sight or rely > self.sight:
			return False
		
		if(relx * relx + rely * rely > self.sight * self.sight):
			return False

		if self.world.obscured(self.position, target):
			return False
		
		return True
		
	def inflict(self, attacker, damage):
		
		startHealth = self.health
		
		self.hostile = True
		self.lastAttacker = attacker
		self.health -= damage
		
		if self.health <= 0:
			self.kill()
			
		endHealth = self.health
		
		damageDealt = startHealth - endHealth
		self.world.log.append(attacker.getName() + " hit " + self.getName() + " for " + str(damage) + " damage!")
		
		self.lastDamage = time()
		self.__class__.onDamage(self.world.sounds)
		return damageDealt
	
	def heal(self, healer, amount):
		if not self.isAlive():
			return 0
		
		startHealth = self.health
		self.health += amount
		
		if self.health > self.maxHealth:
			self.health = self.maxHealth
		
		healingDone = self.health - startHealth
		self.world.log.append(healer.getName() + " healed " + self.getName() + " for " + str(healingDone) + "!")
		return healingDone
		
	def kill(self):
		self.world.log.append(self.getName() + ' Died!')
		self.health = 0
		
	def revive(self, reviver):
		
		if self.health != 0:
			return
		
		self.health = 1
		self.world.log.append(self.getName() + ' resurrected by ' + reviver.getName())
		
		
	def distance(self, location):
		relx = abs(self.position[0] - location[0])
		rely = abs(self.position[1] - location[1])
		
		return int(sqrt(relx**2 + rely**2))
	
	def acquireTarget(self):
		
		for e in self.getEnemies():
			if self.canSee(e.position):
				return e
			
	def getAttackable(self):
		
		for e in self.getEnemies():
			if e.isAlive() and self.canSee(e.position) and self.canHit(e.position) :
				return e
			
	def getEnemies(self):
		if self in self.world.friendly:
			return self.world.mobManager.mobs
		else:
			return self.world.friendly
	
	def getFriends(self):
		if self in self.world.friendly:
			return self.world.friendly
		else:
			return self.world.mobManager.mobs
		
	def canHit(self, location, attackRange):
		pos = Vector2(self.position[0], self.position[1])
		pos.center()
		target = Vector2(location)
		target.center()
		pos -= target
		return pos.inRange(attackRange)
			
	def isAlive(self):
		return self.health > 0
	
	def regen(self):
		if self.health >= self.maxHealth:
			return
		
		if randint(0,5) is not 0:
			return
		
		self.health += 1
		
	def setGroup(self, group):
		self.group = group
		
		
	def getLeader(self):
		return self.group.getLeader() if self.group is not None else None
		
	def teleportToLeader(self):
		
		leader = self.getLeader()
		x, y = leader.position
		r = 1
		while(not self.world.isLocationPassable((x, y))):
			x = randint(-r,r) + leader.position[0]
			y = randint(-r,r) + leader.position[1]
			if r is 10:
				print "Failed to find a place to teleport to"
				return
			r += 1
			
		self.position = Vector2(x, y)


	def getName(self):
		if self.name is None:
			return self.__class__.__name__
		else:
			return self.name

	
	def getAction(self):

		if len(self.abilities) == 0:
			return None
		
		for ability in self.abilities:
			
			for e in self.world.getAllEntities():
				
				if not ability.ready():
					continue
				
				if not ability.valid(e):
					continue
				
				return ability.cast(e.position) #ability instance
	
	
	def pocket(self, item):
		self.inventory.pocket(item)
	
	def equip(self):
		pass
		
	def notify(self, event):
		for obs in self.observers:
			obs.notify(self, event)
		
	def __str__(self):
		return self.__class__.__name__ + 'Pos: ' + str(self.position) + ' ' + 'HP: ' + str(self.health)

	@classmethod
	def onDamage(cls, sounds):
		sounds.get("damage.wav").play()