def report(intel: Intel, target: NPC): player = Player.current() # check if player has the intel if not PlayerKnowledgeBook.get_or_none(player=player, intel=intel): Message.error("You don't have the intel '%s'" % intel) return False # check if player is in the target place_location if target.place != player.place: Message.debug("Player is not at the target (%s) location (%s)" % (target, target.place)) Message.error("You are not at the target's (%s) location" % target) return False # check if player know where the receiver is if not PlayerKnowledgeBook.get_or_none( player=player, intel=Intel.construct(npc_place=target)): Message.debug("Player does not know where the NPC (%s) is located" % target) Message.error("Player does not know where the NPC is located") return False # update Player's favours book if target hasn't have it already if not NPCKnowledgeBook.get_or_none(npc=target, intel=intel): FavoursBook.construct(target, intel.worth_()) # update target's intel list NPCKnowledgeBook.create(npc=target, intel=intel) Message.achievement("Intel '%s' reported to the NPC '%s'" % (intel.detail(), target)) return True
def spy(spy_on: NPC, intel_target: Intel): player = Player.current() # check if player is at target's location if player.place != spy_on.place: Message.debug("Player is not at the NPC (%s) location (%s) to spy" % (spy_on, spy_on.place)) Message.error("You are not at the NPC '%s's location to spy" % spy_on) return False # check if player know where the receiver is if not PlayerKnowledgeBook.get_or_none( player=player, intel=Intel.construct(npc_place=intel_target)): Message.debug("Player does not know where the NPC (%s) is located" % intel_target) Message.error("Player does not know where the NPC is located") return False # check if the target has the piece of intel if not NPCKnowledgeBook.get_or_none(npc=spy_on, intel=intel_target): Message.debug( "Target (%s) does not have the intel (%s) player wanted" % (spy_on, intel_target)) Message.error( "Target (%s) does not have the intel (%s) player wanted" % (spy_on, intel_target)) return False # update Player's intel NarrativeHelper.add_intel(intel_target) Message.achievement("Intel '%s' gathered by spying on '%s'" % (intel_target.detail(), spy_on)) return True
def listen(intel: Intel, informer: NPC): # check if informer has the intel if not NPCKnowledgeBook.get_or_none(intel=intel, npc=informer): Message.error("Informer doesn't have the intel (%s) player wants" % intel) return False player = Player.current() # check if player is in the informer place_location if informer.place != player.place: Message.error("You are not at the informer's (%s) location" % informer) return False # check if player know where the receiver is if not PlayerKnowledgeBook.get_or_none( player=player, intel=Intel.construct(npc_place=informer)): Message.debug("Player does not know where the NPC (%s) is located" % informer) Message.error("Player does not know where the NPC is located") return False # update Player's intel NarrativeHelper.add_intel(intel) FavoursBook.construct(informer, -intel.worth_(), player) Message.achievement("Intel '%s' acquired by listening to '%s'" % (intel.detail(), informer)) return True
def learn_1(required_intel: Intel): """ You already know it. :param required_intel: :return: """ player = Player.current() # update player intel PlayerKnowledgeBook.get_or_create(player=player, intel=required_intel) if (required_intel.npc_place or required_intel.item_place) and not required_intel.place_location: # if player knows an NPC's place but doesn't know the location of that place, add the location too if required_intel.npc_place: place = required_intel.npc_place.place else: place = required_intel.item_place.place if not place: Message.debug("Error! npc_place or item_place are empty") PlayerKnowledgeBook.get_or_create( player=player, intel=Intel.construct(place_location=place)) Message.event("Intel '%s' discovered" % required_intel.detail()) return [[]]
def knowledge_2(NPC_knowledge_motivated: NPC): player = Player.current() # find someone enemy to the given NPC who has a worthy intel that the given NPC doesn't have. # or player already know them already_known_intel_list = Intel.select(Intel.id)\ .join(NPCKnowledgeBook)\ .where(NPCKnowledgeBook.npc == NPC_knowledge_motivated) already_known_intel_list += Intel.select(Intel.id)\ .join(PlayerKnowledgeBook)\ .where(PlayerKnowledgeBook.player == player) results = NPC.select(NPC, Intel.id.alias('intel_id'))\ .join(NPCKnowledgeBook)\ .join(Intel)\ .where(NPC.clan != NPC_knowledge_motivated.clan, Intel.id.not_in(already_known_intel_list))\ .order_by(Intel.worth.desc()).group_by(NPC).objects() if results: locations_scores = [player.distance(res.place) for res in results] results = sort_by_list(results, locations_scores) spy_target = results[0] spy_intel = Intel.get_by_id(spy_target.intel_id) del spy_target.intel_id else: # enemies results = NPC.select().where(NPC.clan != NPC_knowledge_motivated.clan) if not results: # no enemy found, pick any NPC Message.debug("knowledge_2: no enemy found, pick any NPC") results = NPC.select() locations_scores = [player.distance(res.place) for res in results] results = sort_by_list(results, locations_scores) spy_target = results[0] new_intel_list = Intel.select().where( Intel.id.not_in(already_known_intel_list)).order_by( Intel.worth.desc()) if new_intel_list: # add the most valuable intel to the NPC knowledge book Message.debug( "knowledge_2: add the most valuable intel to the NPC knowledge book" ) spy_intel = new_intel_list[0] else: # no new intel found, create a new intel spy_intel = Intel.construct(spell=Spell.create( name=SpellName.fetch_new(), text='magical arbitrary spell')) NPCKnowledgeBook.create(npc=spy_target, intel=spy_intel) # steps: # spy: on target, to get intel, then report it to knowledge_motivated NPC steps = [[spy_target, spy_intel, NPC_knowledge_motivated]] Message.instruction("%s: Spy on '%s' to get the intel '%s' for me" % (NPC_knowledge_motivated, spy_target, spy_intel)) return steps
def finish_quest(self): print("Congratulations!! Quest completed!!!!") self.progress.current_node = self.progress.quest self.quest_in_progress = False self.quest_done = True Intel.delete_all_arbitrary() query = Item.delete().where(Item.name.contains('arbitrary')) query.execute() query = Place.delete().where(Place.name.contains('arbitrary')) query.execute() query = NPC.delete().where(NPC.name.contains('arbitrary')) query.execute()
def goto_1(destination: Place, npc: NPC = None, item: Item = None): """ You are already there. :return: """ player = Player.current() if npc or item: event_dest_str = str(npc if npc else item) + ' (' + str( destination) + ')' else: event_dest_str = str(destination) if npc: # move the npc npc.place = player.place npc.save() intel = Intel.construct(npc_place=npc) PlayerKnowledgeBook.get_or_create(player=player, intel=intel) Message.debug("NPC (%s) moved to the player location (%s)" % (npc, player.place)) Message.event("%s moved to your location" % npc) elif item: # move item or the holder if item.belongs_to: holder = item.belongs_to # type: NPC holder.place = player.place holder.save() intel = Intel.construct(npc_place=holder) PlayerKnowledgeBook.get_or_create(player=player, intel=intel) Message.debug( "Item (%s) holder (%s) moved to the player location (%s)" % (item, item.belongs_to, player.place)) Message.event("Item '%s's holder moved to your location" % item) elif item.belongs_to_player: Message.debug("Player already has the item %s" % item) Message.event("You already have the item '%s'" % item) else: item.place = player.place item.save() intel = Intel.construct(item_place=item) PlayerKnowledgeBook.get_or_create(player=player, intel=intel) Message.debug("Item (%s) moved to the player location (%s)" % (item, player.place)) Message.event("Item '%s' has been moved to your location" % item) else: # update player's location player.place = destination player.save() Message.debug("Player moved to %s location" % event_dest_str) Message.event("Player has been moved to %s location" % destination) return [[]]
def explore(area_location: Place, npc: NPC = None, item: Item = None): player = Player.current() if player.place != area_location: Message.error("You are not at the area '%s'" % area_location) return False if (npc and npc.place != area_location) or (item and item.place != area_location): Message.error("What you're looking for, is not here") return False # check if player knows the location results = PlayerKnowledgeBook.select().join(Intel)\ .where(PlayerKnowledgeBook.player == player, Intel.place_location == area_location).limit(1) if not results: Message.debug( "Location %s unknown (Intel not found in player's knowledge book)" % area_location) Message.error("Location %s is unknown" % area_location) return False # update Player's location player.place = area_location player.save() if npc: target = npc elif item: target = item else: target = '' Message.achievement("You have found '%s' by exploring '%s'" % (target, area_location)) if npc: # find npc for player (give npc place intel to player) intel = Intel.construct(npc_place=npc) elif item: intel = Intel.construct(item_place=item) else: intel = None if intel: PlayerKnowledgeBook.get_or_create(player=player, intel=intel) Message.achievement("Intel '%s' learned" % intel.detail()) return True
def add_item_place_intel(item: Item): player = Player.current() if item.place: PlayerKnowledgeBook.get_or_create(player=player, intel=Intel.construct(item_place=item)) PlayerKnowledgeBook.get_or_create(player=player, intel=Intel.construct(place_location=item.place)) elif item.belongs_to: PlayerKnowledgeBook.get_or_create(player=player, intel=Intel.construct(item_place=item)) PlayerKnowledgeBook.get_or_create(player=player, intel=Intel.construct(npc_place=item.belongs_to)) PlayerKnowledgeBook.get_or_create(player=player, intel=Intel.construct(place_location=item.belongs_to.place)) else: # player has the item pass return True
def explore(area_location: Place, npc: NPC, item: Item): player = Player.current() if npc: intel = Intel.construct(npc_place=npc) elif item: intel = Intel.construct(item_place=item) else: intel = None if intel and not PlayerKnowledgeBook.get_or_none(player=player, intel=intel): return False return player.place == area_location
def use(item_to_use: Item, target: NPC): player = Player.current() # check if player has the item if item_to_use.belongs_to_player != player: Message.error("You don't have the item (%s)" % item_to_use) return False # check if player at target's place_location if target.place != player.place: Message.debug("Player is not at the target '%s's location (%s)" % (target, target.place)) Message.error("You are not at the target '%s's location" % target) return False # check if player know where the receiver is if not PlayerKnowledgeBook.get_or_none( player=player, intel=Intel.construct(npc_place=target)): Message.debug("Player does not know where the NPC (%s) is located" % target) Message.error("Player does not know where the NPC is located") return False item_to_use.use(npc=target) # depending on positive or negative impact_factor of the item usage, target record in player's favour gets updated FavoursBook.construct(target, float(item_to_use.impact_factor or 0.0)) Message.achievement("Item '%s' used on the '%s'" % (item_to_use, target)) return True
def gather(item_to_gather: Item): player = Player.current() # check if player is at item location if item_to_gather.place != player.place: Message.debug( "Player is not at the item '%s's location (%s) to gather it" % (item_to_gather, item_to_gather.place)) Message.error("You are not at the item '%s's location to gather it" % item_to_gather) return False # check if player know where the item is if not PlayerKnowledgeBook.get_or_none( player=player, intel=Intel.construct(item_place=item_to_gather)): Message.debug("Player does not know where the item (%s) is located" % item_to_gather) Message.error("Player does not know where the item is located") return False # update Player's belongings item_to_gather.belongs_to_player = player item_to_gather.save() Message.achievement("Item '%s' gathered" % item_to_gather) return True
def damage(target: NPC): player = Player.current() # check if player is at target place_location if player.place != target.place: Message.error("You are not at the target '%s's location" % target) return False # check if player know where the receiver is if not PlayerKnowledgeBook.get_or_none( player=player, intel=Intel.construct(npc_place=target)): Message.debug("Player does not know where the NPC (%s) is located" % target) Message.error("Player does not know where the NPC is located") return False target.health_meter -= 0.3 if target.health_meter <= 0: return kill(target) else: Message.debug("NPC '%s' has been damaged, current health meter: %s" % (target, target.health_meter)) Message.achievement("NPC '%s' has been damaged" % target) target.save() return True
def reputation_2(motivated: NPC) -> list: """ Kill enemies of motivated :param motivated: given from higher level nodes :return: """ results = NPC.select().where(NPC.clan != motivated.clan).order_by( fn.Random()).limit(1) if results: enemy = results.get() else: # No NPC left in the world except the motivated enemies_clan = Clan.select().where(Clan.id != motivated.clan).order_by( fn.Random()).get() enemy = NPC.create(place=Place.select().order_by(fn.Random()).get(), clan=enemies_clan, name=NPCName.fetch_new()) player = Player.current() killing_report_intel = Intel.construct(other='arbitrary_killing_report_' + str(randint(100, 999))) PlayerKnowledgeBook.create(player=player, intel=killing_report_intel) # steps: # goto enemies place # kill enemies # goto motivated place # T.report intel(?) to motivated steps = [[enemy.place, enemy], [enemy], [motivated.place, motivated], [killing_report_intel, motivated]] Message.instruction("%s: Kill my enemy '%s', and report it" % (motivated, enemy)) return steps
def comfort_2(motivated: NPC) -> list: """ Kill pests :param motivated: :return: """ # find enemy of motivated, or create one results = NPC.select().where(NPC.clan != motivated.clan).order_by( fn.Random()).limit(1) if results: enemy = results.get() else: # No NPC left in the world except the motivated enemies_clan = Clan.select().where(Clan.id != motivated.clan).order_by( fn.Random()).get() enemy = NPC.create(place=Place.select().order_by(fn.Random()).get(), clan=enemies_clan, name=NPCName.fetch_new()) player = Player.current() damage_report_intel = Intel.construct( other='arbitrary_pest_damage_report_' + str(randint(100, 999))) PlayerKnowledgeBook.create(player=player, intel=damage_report_intel) # steps: # goto enemies place # kill enemies # goto motivated place # T.report intel(?) to motivated steps = [[enemy.place, enemy], [enemy], [motivated.place, motivated], [damage_report_intel, motivated]] Message.instruction("%s: Take care of that pest '%s' for me" % (motivated, enemy)) return steps
def reputation_3(motivated: NPC) -> list: """ Visit a dangerous place :param motivated: :return: """ # goto an enemies place enemies = NPC.select().where(NPC.clan != motivated.clan).order_by( fn.Random()).limit(1) if enemies: place = enemies[0].place else: place = Place.select().order_by(fn.Random()).limit(1) if place: place = place[0] else: Message.debug("No place found in the World!") place = helper.create_place() player = Player.current() danger_report_intel = Intel.construct(other='arbitrary_danger_report_' + str(randint(100, 999))) PlayerKnowledgeBook.create(player=player, intel=danger_report_intel) # steps # goto # goto # report steps = [[place], [motivated.place, motivated], [danger_report_intel, motivated]] Message.instruction( "%s: Goto the dangerous '%s' and report what you've seen there" % (motivated, place)) return steps
def steal_1(item_to_steal: Item, item_holder: NPC): """ Go someplace, sneak up on somebody, and take something. :return: """ # item[1] is to be stolen from NPC[1] who has it # place_location[1] is where NPC[1] lives item_holder_place = item_holder.place player = Player.current() player.next_location = item_holder_place player.save() intel = Intel.construct(item_place=item_to_steal) PlayerKnowledgeBook.get_or_create(player=player, intel=intel) Message.achievement("Intel '%s' learned" % intel.detail()) # steps: # goto: place_location[1] # T.stealth: stealth NPC[1] # T.take: take item[1] from NPC[1] steps = [[item_holder_place, item_holder], [item_holder], [item_to_steal, item_holder]] Message.instruction("Sneak up on '%s', and take '%s'" % (item_holder, item_to_steal)) return steps
def protection_1(motivated: NPC) -> list: """ Attack threatening entities :param motivated: :return: """ # find enemy of motivated, or create one results = NPC.select().where(NPC.clan != motivated.clan).order_by( fn.Random()).limit(1) if results: enemy = results.get() else: # No NPC left in the world except the motivated enemies_clan = Clan.select().where(Clan.id != motivated.clan).order_by( fn.Random()).get() enemy = NPC.create(place=Place.select().order_by(fn.Random()).get(), clan=enemies_clan, name=NPCName.fetch_new()) player = Player.current() threat_report_intel = Intel.construct( other='arbitrary_threat_damage_report_' + str(randint(100, 999))) PlayerKnowledgeBook.create(player=player, intel=threat_report_intel) # steps: # goto enemies place # kill enemies # goto motivated place # T.report intel(?) to motivated steps = [[enemy.place, enemy], [enemy], [motivated.place, motivated], [threat_report_intel, motivated]] Message.instruction("%s: Relieve me of '%s' threats, then report it" % (motivated, enemy)) return steps
def give(item: Item, receiver: NPC): # check if player has the item player = Player.current() if item.belongs_to_player != player: Message.error("You don't have the item (%s) to give" % item) return False # check if player is at receiver's location if player.place != receiver.place: Message.debug("Player is not at the receiver NPC (%s) location (%s)" % (receiver, receiver.place)) Message.error("You are not at the receiver's (%s) location" % receiver) return False # check if player know where the receiver is if not PlayerKnowledgeBook.get_or_none( player=player, intel=Intel.construct(npc_place=receiver)): Message.debug("Player does not know where the NPC (%s) is located" % receiver) Message.error("Player does not know where the NPC is located") return False item.belongs_to_player = None item.belongs_to = receiver item.save() # update favours book FavoursBook.construct(npc=receiver, owe_factor=item.worth_(), player=player) Message.achievement("Item '%s' has been given to the NPC '%s'" % (item, receiver)) return True
def goto_2(destination: Place, npc: NPC = None, item: Item = None): """ Explore destination to find npc or item :return: """ # place_location[1] is destination # area around location[1] is given to player to explore and find location[1] player = Player.current() # ensure player doesn't already know where the NPC or item is if npc: intel = Intel.construct(npc_place=npc) if PlayerKnowledgeBook.get_or_none(player=player, intel=intel): # player knows where the NPC is, move the NPC then npc.place = Place.select().where(Place.id != destination).order_by( fn.Random()).get() npc.save() destination = npc.place Message.event( "You just missed '%s' he has moved to somewhere else" % npc) elif item: intel = Intel.construct(item_place=item) if PlayerKnowledgeBook.get_or_none(player=player, intel=intel): # player knows where the Item is, move the item or item's holder if item.belongs_to: holder = item.belongs_to holder.place = Place.select().where( Place.id != destination).order_by(fn.Random()).get() holder.save() destination = holder.place Message.event( "Item '%s's holder just has been moved to somewhere else" % item) else: item.place = Place.select().where( Place.id != destination).order_by(fn.Random()).get() item.save() destination = item.place Message.event( "Item '%s' just has been moved to somewhere else" % item) # steps: # T.explore steps = [[destination, npc, item]] Message.instruction("Explore around '%s'" % destination) return steps
def add_intel(intel: Intel): player = Player.current() PlayerKnowledgeBook.get_or_create(player=player, intel=intel) # add additional intel if needed if intel.npc_place: place = intel.npc_place.place PlayerKnowledgeBook.get_or_create(player=player, intel=Intel.construct(place_location=place)) elif intel.item_place: add_item_place_intel(intel.item_place)
def create_place(): player = Player.current() player_place = player.place # type: Place new_x = abs(player_place.x + randint(WorldParams.minimum_distance, WorldParams.reachable_distance) * (1 if random() < 0.5 else -1)) new_y = abs(player_place.y + randint(WorldParams.minimum_distance, WorldParams.reachable_distance) * (1 if random() < 0.5 else -1)) place_to_go = Place.create(name=PlaceName.fetch_new(), x=new_x, y=new_y) PlayerKnowledgeBook.create(player=player, intel=Intel.construct(place_location=place_to_go)) return place_to_go
def print_player_intel(player: Player = None, print_locations: bool = False): if not player: player = Player.current() results = Intel.select().join(PlayerKnowledgeBook).where( PlayerKnowledgeBook.player == player) if not print_locations: results = results.where(Intel.type != IntelTypes.location) detailed = [] for intel in results: detailed.append(intel.detail()) print("intel:") print_indented(detailed)
def talk(npc: NPC): player = Player.current() if player.place != npc.place: Message.error("You are not at the NPC '%s's place, can't talk to him" % npc) return False if not PlayerKnowledgeBook.get_or_none( player=player, intel=Intel.construct(npc_place=npc)): Message.error("NPC '%s's current location is unknown" % npc) return False Message.achievement("Talking to '%s'" % npc) return True
def exchange(item_holder: NPC, item_to_give: Item, item_to_take: Item): player = Player.current() # check if player has the item_to_give and holder has the item_to_take if item_to_give.belongs_to_player != player: Message.debug("item_to_give: '%s', belongs_to_player: '%s'" % (item_to_give, item_to_give.belongs_to_player)) return False if item_to_take.belongs_to != item_holder: Message.debug( "item_to_take: '%s', belongs_to: '%s', item_holder: '%s'" % (item_to_take, item_to_give.belongs_to, item_holder)) return False # check if player is at item_holder's place_location if item_holder.place != player.place: Message.debug( "Player is not at the item_holder (%s) place_location (%s)" % (item_holder, item_holder.place)) Message.error("You are not at the item holder (%s) location" % item_holder) return False # check if player know where the receiver is if not PlayerKnowledgeBook.get_or_none( player=player, intel=Intel.construct(npc_place=item_holder)): Message.debug("Player does not know where the NPC (%s) is located" % item_holder) Message.error("Player does not know where the NPC is located") return False # update Player's belongings item_to_take.belongs_to = None item_to_take.belongs_to_player = player item_to_take.save() item_to_give.belongs_to_player = None item_to_give.belongs_to = item_holder item_to_give.save() npc_owing = item_to_give.worth_() - item_to_take.worth_() FavoursBook.construct(item_holder, npc_owing, player) Message.achievement("Item '%s' exchanged for '%s', with NPC '%s'" % (item_to_give, item_to_take, item_holder)) return True
def do_listen(self, args): """Listen a piece of intel from an NPC (intel: type intel_value). LISTEN spell needs_path Goblin""" args = parse(args) if not self.check_length(args, 3): return intel = Intel.find_by_name(args[0], [args[1]]) npc = NPC.get_or_none(NPC.name == args[2]) if not self.set_inputs(action=T.listen, args=[intel, npc]): return found = terminals.listen(intel=intel, informer=npc) if not found: print("failed!") return print("Player intel updated.") print_player_intel() self.last_action_doable = True
def do_read(self, args): """Read a piece of intel from a book (intel: type intel_value). READ location goblin_place address_book""" args = parse(args) if not self.check_length(args, 3): return intel = Intel.find_by_name(args[0], [args[1]]) readable = Item.get_or_none(Item.name == args[2]) if not self.set_inputs(action=T.read, args=[intel, readable]): return found = terminals.read(intel=intel, readable=readable) if not found: print("failed!") return print("Player intel updated.") print_player_intel() self.last_action_doable = True
def do_spy(self, args): """Spy on an NPC to gather some information (intel: type intel_value). SPY Goblin place_location tomas_place""" args = parse(args) if not self.check_length(args, 3): return target = NPC.get_or_none(NPC.name == args[0]) intel = Intel.find_by_name(args[1], [args[2]]) if not self.set_inputs(action=T.spy, args=[target, intel]): return found = terminals.spy(spy_on=target, intel_target=intel) if not found: print("failed!") return print("Player intel updated.") print_player_intel() self.last_action_doable = True
def do_report(self, args): """Report a piece of intel to an NPC (intel: type intel_value). REPORT spell needs_path Steve""" args = parse(args) if not self.check_length(args, 3): return intel = Intel.find_by_name(args[0], [args[1]]) npc = NPC.get_or_none(NPC.name == args[2]) if not self.set_inputs(action=T.report, args=[intel, npc]): return found = terminals.report(intel=intel, target=npc) if not found: print("failed!") return print("NPC intel updated.") print_npc_intel(npc) self.last_action_doable = True
def take(item_to_take: Item, item_holder: NPC = None): if item_holder is None: return take_loot(item_to_take) player = Player.current() # check if NPC has the item if item_to_take.belongs_to != item_holder: Message.debug( "NPC '%s' doesn't have the item '%s' to give. It belongs to '%s'" % (item_holder, item_to_take, item_to_take.belongs_to)) Message.error("NPC '%s' doesn't have the item '%s' to give" % (item_holder, item_to_take)) return False # check if player is at item_holder's place_location if item_holder.place != player.place: Message.debug( "Player is not at the item_holder (%s) place_location (%s)" % (item_holder, item_holder.place)) Message.error("You are not at the NPC '%s's location" % item_holder) return False # check if player know where the receiver is if not PlayerKnowledgeBook.get_or_none( player=player, intel=Intel.construct(npc_place=item_holder)): Message.debug("Player does not know where the NPC (%s) is located" % item_holder) Message.error("Player does not know where the NPC is located") return False # remove item from holder's belongings and add to player's item_to_take.belongs_to = None item_to_take.belongs_to_player = player item_to_take.save() FavoursBook.construct(item_holder, -item_to_take.worth_(), player) Message.achievement("Item '%s' taken" % item_to_take) return True