from mesa import Agent, Model import random def dice(number): return random.randint(1,number) class Wall(Agent): def __init__(self, unique_id, model): super().__init__(unique_id, model) class Chest(Agent): def __init__(self, unique_id, model, loot): super().__init__(unique_id, model) self.gold = 3*dice(6) self.loot = loot class Weapon(): def __init__(self,name,typ,damage): self.name = name self.typ = typ self.damage = damage class Armor(): def __init__(self,name,defence,mp): self.name = name self.defence = defence self.mag_protection = mp class Creature(Agent): def __init__(self, unique_id, model, n, s, a, w, maxhp, hp, weap, arm, g): super().__init__(unique_id, model) self.name = n self.strength = s self.agility = a self.wisdom = w self.maxHealth = maxhp self.health = hp self.gold = g self.weapon1 = weap self.armor = arm def meleeAttack(self,opponent): attackValue = self.strength + dice(6) defenseValue = opponent.strength + opponent.armor.defence damage = attackValue - defenseValue if damage > 0: opponent.health = opponent.health - (damage + self.weapon1.damage) def rangeAttack(self,opponent): attackValue = self.agility + dice(6) defenseValue = opponent.agility damage = attackValue - defenseValue if (damage > 0) and (damage + self.weapon1.damage - opponent.armor.defence > 0): opponent.health = opponent.health - (damage + self.weapon1.damage - opponent.armor.defence) def magicAttack(self,opponent): attackValue = self.wisdom + dice(6) defenseValue = opponent.wisdom damage = attackValue - defenseValue if (damage > 0) and (damage + self.weapon1.damage - opponent.armor.mag_protection > 0): opponent.health = opponent.health - (damage + self.weapon1.damage - opponent.armor.mag_protection) def defaultAttack(self,opponent): if self.weapon1.typ == "Meele": self.meleeAttack(opponent) elif self.weapon1.typ == "Range": self.rangeAttack(opponent) else: self.magicAttack(opponent) class Player(Creature): def __init__(self, unique_id, model, n, s, a, w, maxhp, hp, weap, arm, g, w2, w3): super().__init__(self, unique_id, model, n, s, a, w, maxhp, hp, weap, arm, g) self.name = n self.strength = s self.agility = a self.wisdom = w self.maxHealth = maxhp self.health = hp self.gold = g self.weapon1 = weap self.weapon2 = w2 self.weapon3 = w3 self.armor = arm def move(self): possible_steps = self.model.grid.get_neighborhood( self.pos, moore=True, include_center=False) new_position = self.random.choice(possible_steps) self.model.grid.move_agent(self, new_position) def meleeAttack(self,opponent): attackValue = self.strength + dice(6) defenseValue = opponent.strength + opponent.armor.defence damage = attackValue - defenseValue if damage > 0: opponent.health = opponent.health - (damage + self.weapon1.damage) def rangeAttack(self,opponent): attackValue = self.agility + dice(6) defenseValue = opponent.agility damage = attackValue - defenseValue if (damage > 0) and (damage + self.weapon2.damage - opponent.armor.defence > 0): opponent.health = opponent.health - (damage + self.weapon2.damage - opponent.armor.defence) def magicAttack(self,opponent): attackValue = self.wisdom + dice(6) defenseValue = opponent.wisdom damage = attackValue - defenseValue if (damage > 0) and (damage + self.weapon3.damage - opponent.armor.mag_protection > 0): opponent.health = opponent.health - (damage + self.weapon3.damage - opponent.armor.mag_protection) def fightOrFlight(self, opponent): combat = True while combat: choice = dice(4) if choice == 1: running_speed = self.agility + dice(6) opponent_speed = opponent.agility + dice(6) if running_speed > opponent_speed: combat = False self.step() else: opponent.defaultAttack(self) if self.health <= 0: combat = False elif choice == 2: self.meleeAttack(opponent) if opponent.health > 0: opponent.defaultAttack(self) if self.health <= 0: combat = False else: combat = False self.gold = self.gold + opponent.gold opponent.gold = 0 opponent.model.grid.remove_agent(opponent) elif choice == 3: self.rangeAttack(opponent) if opponent.health > 0: opponent.defaultAttack(self) if self.health <= 0: combat = False else: combat = False self.gold = self.gold + opponent.gold opponent.gold = 0 opponent.model.grid.remove_agent(opponent) else: self.magicAttackAttack(opponent) if opponent.health > 0: opponent.defaultAttack(self) if self.health <= 0: combat = False else: combat = False self.gold = self.gold + opponent.gold opponent.gold = 0 opponent.model.grid.remove_agent(opponent) def openChest(self,chest): self.gold = self.gold + chest.gold chest.gold = 0 if isinstance(chest.loot,Armor): buffer = self.armor self.armor = chest.loot chest.loot = buffer if isinstance(chest.loot,Weapon): if chest.loot.typ == "Melee": buffer = self.weapon1 self.weapon1 = chest.loot chest.loot = buffer elif chest.loot.typ == "Range": buffer = self.weapon2 self.weapon2 = chest.loot chest.loot = buffer elif chest.loot.typ == "Magic": buffer = self.weapon3 self.weapon3 = chest.loot chest.loot = buffer def step(self): if self.health > 0: self.move() cellmates = self.model.grid.get_cell_list_contents([self.pos]) if len(cellmates) > 1: if isinstance(cellmates[1],Chest): openChest(cellmates[1]) else: opponent = cellmates[1] fightOrFlight(opponent) print("HP: "+self.health+" / "+self.maxHealth) print("Gold: "+self.gold) else: print("HP: 0 / "+self.maxHealth)