def create_table_if_not_exists(cls, connection): """timestamp can be null, if stream goes offline for example""" Trait.create_table_if_not_exists(connection) Special.create_table_if_not_exists(connection) connection.execute( """create table if not exists characters (character_id integer PRIMARY KEY NOT NULL, name text UNIQUE NOT NULL, user_id text UNIQUE NOT NULL, experience integer NOT NULL, lvl integer NOT NULL, weapon_id integer, armor_id integer, trait_id text NOT NULL, exp_gain_time timestamp, x integer NOT NULL, y integer NOT NULL, trait_bonus real, alive boolean NOT NULL DEFAULT 1, FOREIGN KEY (weapon_id) REFERENCES weapons(weapon_id), FOREIGN KEY (armor_id) REFERENCES armors(armor_id), FOREIGN KEY (trait_id) REFERENCES traits(orig_name) );""" ) if "alive" not in [i[1] for i in connection.execute("""PRAGMA table_info(characters)""")]: connection.execute("""ALTER TABLE characters ADD COLUMN alive boolean NOT NULL DEFAULT 1;""") SpecialCooldown.create_table_if_not_exists(connection) ActiveEffect.create_table_if_not_exists(connection)
def armor_bonus(self): armor_bonus = self.trait.defense_bonus if self.armor is not None: armor_bonus += self.armor.min_lvl if ActiveEffect.find_by_target_and_special(self, Item.Items.POTION_OF_DEFENSE, self.connection): armor_bonus += 4 if ActiveEffect.find_by_target_and_special(self, Item.Items.STONE_ELIXIR, self.connection): armor_bonus += 2 return armor_bonus
def attack_bonus(self): attack_bonus = self.trait.attack_bonus if self.weapon is not None: attack_bonus += self.weapon.min_lvl if ActiveEffect.find_by_target_and_special(self, Special.Specials.EMPOWER, self.connection): attack_bonus += 4 if ActiveEffect.find_by_target_and_special(self, Item.Items.POTION_OF_STRENGTH, self.connection): attack_bonus += 4 if ActiveEffect.find_by_target_and_special(self, Item.Items.BULL_ELIXIR, self.connection): attack_bonus += 2 return attack_bonus
def check_survival(self): rand = random.random() * 100 terrain_factor = 1.5 if self.position.location.difficulty * 2 < self.lvl: terrain_factor = 0.5 death_chance = 100 * (max(2.5 + terrain_factor * (self.position.location.difficulty * 2 - self.lvl), 1)) / ( 100 + self.armor_bonus * 20) if ActiveEffect.find_by_target_and_special(self, Special.Specials.CURSE, self.connection): death_chance += 5 if ActiveEffect.find_by_target_and_special(self, Special.Specials.GUARDIAN, self.connection): death_chance -= 10 if self.lvl <= 4: death_chance -= 5 - self.lvl return rand > (self.trait.death_chance_factor * death_chance)
def delete(self): attack = Attack.find_by_attacker_or_target(self, self.connection) if attack is not None and attack.boss_id is None: # TODO: fix problem is person is attacked during boss battle and dies by boss. self.Parent.Log( "rpgGame", "something is wrong in the code, char got deleted while still in a fight." ) elif attack is not None: attack.delete() for bounty in Bounty.find_all_by_character(self, self.connection): bounty.delete() SpecialCooldown.delete_all_from_character(self, self.connection) ActiveEffect.delete_all_by_target(self, self.connection) self.connection.execute( """DELETE FROM characters WHERE character_id = ?""", (self.char_id, ))
def attack_bonus(self): attack_bonus = self.trait.attack_bonus if self.weapon is not None: attack_bonus += self.weapon.min_lvl if ActiveEffect.find_by_target_and_special(self, Special.Specials.EMPOWER, self.connection): attack_bonus += 4 return attack_bonus
def attack(self, defender, sneak, defense_bonus=False, attack_bonus=False): roll = random.randint(1, 40) weapon_bonus = self.attack_bonus + sneak * 2 * defender.trait.sneak_penalty_factor armor_bonus = defender.armor_bonus if ActiveEffect.find_by_target_and_special(self, Special.Specials.BLIND, self.connection) is not None: if random.random > 0.6: return False return roll + self.lvl * 2 + weapon_bonus + (attack_bonus * 2) > \ defender.lvl * 2 + armor_bonus + 18 + (defense_bonus * 2)
def check_survival(self): rand = random.random() * 100 armor_bonus = 0 if self.armor is not None: armor_bonus = self.armor.min_lvl * 20 terrain_factor = 1.5 if self.position.location.difficulty * 2 < self.lvl: terrain_factor = 0.5 death_chance = 100 * self.trait.death_chance_factor * ( 3 + terrain_factor * (self.position.location.difficulty * 2 - self.lvl)) / (100 + armor_bonus) if ActiveEffect.find_by_target_and_special(self, Special.Specials.CURSE, self.connection): death_chance += 5 if ActiveEffect.find_by_target_and_special(self, Special.Specials.GUARDIAN, self.connection): death_chance -= 10 return rand > death_chance
def create_table_if_not_exists(cls, connection): """timestamp can be null, if stream goes offline for example""" Trait.create_table_if_not_exists(connection) Special.create_table_if_not_exists(connection) connection.execute("""create table if not exists characters (character_id integer PRIMARY KEY NOT NULL, name text UNIQUE NOT NULL, user_id text UNIQUE NOT NULL, experience integer NOT NULL, lvl integer NOT NULL, weapon_id integer, armor_id integer, trait_id text NOT NULL, exp_gain_time timestamp, x integer NOT NULL, y integer NOT NULL, trait_bonus integer, FOREIGN KEY (weapon_id) REFERENCES weapons(weapon_id), FOREIGN KEY (armor_id) REFERENCES armors(armor_id), FOREIGN KEY (trait_id) REFERENCES traits(orig_name) );""") SpecialCooldown.create_table_if_not_exists(connection) ActiveEffect.create_table_if_not_exists(connection)
def attack_boss(self, boss): roll = random.randint(1, 40) weapon_bonus = self.attack_bonus if ActiveEffect.find_by_target_and_special( self, Special.Specials.BLIND, self.connection) is not None: if random.random > 0.6: return False if roll + self.lvl * 2 + weapon_bonus > \ boss.lvl * 2 + boss.defense_bonus + 20: success = boss.damage(1) boss.save() self.Parent.SendStreamMessage( self.format_message( "{0} managed to hit the {1}, {2}/{3} HP remaining", self.name, boss.name, boss.hp, boss.max_hp)) return success self.Parent.SendStreamMessage( self.format_message("{0} failed to hit boss {1}.", self.name, boss.name)) return False
def is_stunned(self): return ActiveEffect.find_by_target_and_special( self, Special.Specials.STUN, self.connection) is not None
def remove_invisibility(self): invisibility = ActiveEffect.find_by_target_and_special(self, Special.Specials.INVIS, self.connection) if invisibility is not None: invisibility.delete()
def is_invisible(self): return ActiveEffect.find_by_target_and_special(self, Special.Specials.INVIS, self.connection) is not None