git.fiddlerwoaroof.com
libs/combat.py
3d5a515d
 from . import dice
cf0eb698
 
 from .combat_parts import races
 from .combat_parts import equipment
 from .combat_parts import skills
 from .combat_parts import constants as const
3d5a515d
 
b8f124a1
 from src import events
 eh = events.EventHandler()
 
3d5a515d
 import collections
dff12016
 import random
 
 def get_stats(sum_):
 	stats = [sum_/4]*4
 	if sum(stats) != sum_:
 		stats[0] += sum_ - sum(stats)
 
 	mod = +1
 	for x in range(100):
 		idx = random.choice([x for x in range(len(stats)) if stats[x] > 3])
 		stats[idx] += mod
 		mod *= -1
 	return stats
3d5a515d
 
 class Attributes(object):
dff12016
 	@classmethod
 	def randomize(cls, sum_):
 		chosen_stats = get_stats(sum_)
 		return cls(*chosen_stats)
 
3d5a515d
 	def __init__(self, strength, intellect, dexterity, spirit):
 		self.str = strength
 		self.int = intellect
 		self.dex = dexterity
 		self.spt = spirit
cf0eb698
 		self.state = const.HEALTHY
dff12016
 	def __str__(self):
 		return '%s %s %s %s %s' % (self.str, self.int, self.dex, self.spt, self.state)
3d5a515d
 
 
cf0eb698
 @equipment.Slot.add_slot('weapon', equipment.Weapon)
 @equipment.Slot.add_slot('armor', equipment.Armor)
3d5a515d
 class Adventurer(object):
 	@property
 	def state(self):
 		return self.attributes.state
 	@state.setter
 	def state(self, val):
ac4ad8e3
 		if val < 0: val == 0
 		if val > const.KNOCKOUT: val = const.KNOCKOUT
3d5a515d
 		self.attributes.state = val
 
b8f124a1
 	@property
 	def readable_state(self):
 		return ['healthy', 'wounded', 'knocked out'][self.state if self.state < 3 else 2]
 
dff12016
 	@classmethod
 	def randomize(cls, stat_sum=28):
 		name = '%s %s%s' % (
 			random.choice(['Bill', 'Bob', 'Jerry']),
 			random.choice(['Longnose', 'Short-Tail', 'Squint']),
 			random.choice(['', ' the Great', ' The Cross-eyed', ' The Magnificent'])
 		)
 		race = races.Race.random_race()
 		attr = Attributes.randomize(stat_sum)
 		print attr
 		return cls(name, race, attr)
 
 	@classmethod
 	def with_stats(cls, name, race, str, int, dex, spt):
 		attr = Attributes(str, int, dex, spt)
 		return cls(name, race, attr)
 
 	def __init__(self, name, race, attr):
3d5a515d
 		self.name = name
dff12016
 		self.attributes = attr
cf0eb698
 		self.skills = skills.Skills(self.attributes)
 		self.race = races.Race.registry[race](self.attributes)
3d5a515d
 
 	def wield(self, slot, equipment):
 		turns = 1
 		if self.equipment_slots[slot].filled(self):
 			turns += 1
 		self.equipment_slots[slot].setitem(self, equipment)
 		return turns
 
 	def attack(self, opponent, type='fighting', num_allies=0):
 		dieroll = dice.DieRoll()
 
 		ally_bonus = -1 if num_allies > 0 else 0
 		# TODO: implement professions, figure out how to mod ally_bonus for thieves cleanly
 		dieroll.add_adjustment(add=ally_bonus)
 
 		pass_, damage = self.skills.check(type, dieroll)
 		if pass_:
 			if self.weapon is not None:
 				damage += self.weapon.damage_mod
b8f124a1
 			eh.trigger_event('msg',
 				'%s inflicts %d damage upon %s' % (self.name, damage, opponent.name)
 			)
3d5a515d
 			opponent.take_damage(damage)
 
 	def take_damage(self, damage):
 		if self.armor is not None:
 			damage += self.armor.damage_mod
 
 		dieroll = dice.DieRoll()
 		dieroll.add_adjustment(-damage)
 
86f3fea2
 		result, __ = self.skills.check('toughness', dieroll)
3d5a515d
 
 		if not result:
 			if damage > 0:
 				self.state += 1
b8f124a1
 				eh.trigger_event('msg',
 					'%s takes %d damage and is now %s' % (self.name, damage, self.readable_state)
 				)
cf0eb698
 				if self.state >= const.KNOCKOUT:
3d5a515d
 					self.die()
 
 	def die(self): pass
 
cf0eb698
 if __name__ == '__main__':
dff12016
 	a = Adventurer.randomize(28)
 	b = Adventurer.randomize(28)
3d5a515d
 
cf0eb698
 	while const.KNOCKOUT not in {a.state, b.state}:
 		a.attack(b)
 		b.attack(a)
3d5a515d
 
cf0eb698
 	print a.name, 'is', ['healthy', 'wounded', 'ko'][a.state if a.state < 3 else 2]
 	print b.name, 'is', ['healthy', 'wounded', 'ko'][b.state if b.state < 3 else 2]