def capture_1(target: NPC): """ Get something, go someplace and use it to capture somebody :param target: :return: """ item_to_fetch = Item.get_or_none(type=ItemTypes.tool.name, usage=T.capture.value) if not item_to_fetch: # No item usable for capture, left in the world item_to_fetch = Item.create( name='arbitrary_capture_tool_' + str(randint(100, 999)), type=ItemTypes.tool.name, usage=T.capture.value, generic=GenericItem.get_or_create( name=ItemTypes.singleton.name)[0], place=Place.select().order_by(fn.Random()).get(), impact_factor=1.0, worth=0.75) Message.debug( "No item usable for 'capture' left in the world, create a new one '%s'" % item_to_fetch) # steps: # get # goto # T.capture steps = [[item_to_fetch], [target.place, target], [target]] Message.instruction("Get '%s', then goto '%s' and capture '%s'" % (item_to_fetch, target, target)) return steps
def null(*args): """ Nothing to do :return: """ Message.debug("null terminal called") return True
def quest_neutral(motivation: NT) -> List[List[BaseElement]]: # select an ally NPC with a certain motivation results = Motivation.select()\ .where(Motivation.action == motivation.value, Motivation.motive > 0.5)\ .order_by(Motivation.motive.desc()).limit(1) if results: motivated = results.get().npc else: # No motivated NPC found, create one place = Place.select().order_by(fn.Random()).get() clan = Clan.select().order_by(fn.Random()).get() motivated = NPC.create(place=place, clan=clan, name=NPCName.fetch_new()) Motivation.create(npc=motivated, action=motivation.value, motive=0.65) # steps: # give useful info to this NPC steps = [[motivated]] Message.instruction("NPC '%s' has '%s' motivation" % (motivated.name, motivation.name)) return steps
def __str__(self) -> str: if not self.type: return str(self.type) if self.type == str(IntelTypes.spell.name): return str(self.spell) + " spell" elif self.type == str(IntelTypes.location.name): return str(self.place_location) + " location" elif self.type == str(IntelTypes.npc_place.name) or self.type == str( IntelTypes.item_place.name): if self.npc_place: if PlayParams.debug_mode: return "%s's place (%s)" % (self.npc_place, self.npc_place.place) else: return "%s's place" % self.npc_place elif self.item_place: if PlayParams.debug_mode: return "%s's place (%s)" % (self.item_place, self.item_place.place) else: return "%s's place" % self.item_place else: Message.debug( "Error! neither item_place nor npc_place but type: %s. Intel id:%i" % (self.type, self.id)) return "unknown" else: # self.type == str(IntelTypes.other.name) return str(self.other)
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 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 serenity_1(motivated: NPC): """ Revenge, Justice :param motivated: :return: """ enemies = NPC.select().where(NPC.clan != motivated.clan).order_by( fn.Random()).limit(1) if enemies: target = enemies[0] 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() enemy_clan = Clan.select().where(Clan.id != motivated.clan).order_by( fn.Random()).limit(1).get() target = NPC.create(clan=enemy_clan, name=NPCName.fetch_new(), place=place) # steps # goto # damage steps = [[target.place, target], [target]] Message.instruction("%s: Get my revenge from '%s'" % (motivated, target)) 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 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 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_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 take_loot(item_to_take: Item, loot_npc: NPCDead = None): player = Player.current() # check if the item belongs to dead if not loot_npc: # NPC confirmed dead already, object among dead is given try: holder = item_to_take.belongs_to except: # holder not found = dead Message.debug("Item '%s' holder is dead") holder = None if holder: # holder is alive return take(item_to_take, item_holder=holder) # 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' has taken by looting" % item_to_take) return True
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 detail(self) -> str: if not self.type: return str(self.type) if self.type == str(IntelTypes.spell.name): return "spell %s: %s" % (self.spell, self.spell.text) elif self.type == str(IntelTypes.location.name): return "location %s is at: %s,%s" % (self.place_location, self.place_location.x, self.place_location.y) elif self.type == str(IntelTypes.npc_place.name) or self.type == str( IntelTypes.item_place.name): if self.npc_place: return "NPC %s located at %s" % (self.npc_place, self.npc_place.place) elif self.item_place: if self.item_place.place: return "Item %s located at %s" % (self.item_place, self.item_place.place) elif self.item_place.belongs_to.place: return "Item %s belongs to %s" % ( self.item_place, self.item_place.belongs_to) else: Message.debug( "Error! item_place intel doesn't have place nor belongs_to" ) return "unknown" else: Message.debug( "Error! neither item_place nor npc_place but type: %s. Intel id:%i" % (self.type, self.id)) return "unknown" else: # self.type == str(IntelTypes.other.name) return str(self.other)
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 sub_quest_2(suggested_destination: Place = None) -> list: player = Player.current() if suggested_destination: return_point = suggested_destination else: return_point = player.place results = Place.select()\ .join(Intel)\ .join(PlayerKnowledgeBook, JOIN.LEFT_OUTER)\ .group_by(Intel).having(fn.COUNT(PlayerKnowledgeBook.id) == 0) locations_scores = [player.distance(place) for place in results] results = sort_by_list(results, locations_scores) if results: place_to_go = results[0] else: # not enough places to go, then create a new place unknown to player place_to_go = narrative_helper.create_place() player.next_location = place_to_go player.save() # steps: # goto # Quest # goto steps = [[place_to_go], [], [return_point]] Message.instruction("Goto '%s' do another Quest, then go to '%s'" % (place_to_go, return_point)) return steps
def conquest_1(motivated: NPC) -> list: """ Attack enemy :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()) # steps: # goto enemies place # damage enemies steps = [[enemy.place, enemy], [enemy]] Message.instruction("%s: Damage my enemy '%s' for me" % (motivated, enemy)) return steps
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 sub_quest_1(suggested_destination: Place = None): # just go somewhere - pick a place_location unknown to player to go to # the reason for unknown place_location is, if "learn" comes up in next level, we'll be lucky, # if it doesn't, intel can be added to Players knowledge right away. player = Player.current() if suggested_destination: place_to_go = suggested_destination else: results = Place.select()\ .join(Intel)\ .join(PlayerKnowledgeBook, JOIN.LEFT_OUTER)\ .group_by(Intel).having(fn.COUNT(PlayerKnowledgeBook.id) == 0) locations_scores = [player.distance(place) for place in results] results = sort_by_list(results, locations_scores) if results: place_to_go = results[0] else: # not enough places to go, then create a new place unknown to player place_to_go = narrative_helper.create_place() player.next_location = place_to_go player.save() # steps: # goto steps = [[place_to_go]] Message.instruction("Goto '%s'" % place_to_go) return steps
def get_1(item_to_fetch: Item): # if not, add it to player's belongings item_to_fetch.belongs_to_player = Player.current() item_to_fetch.save() Message.event("Item '%s' acquired" % item_to_fetch) return []
def get_2(item_to_fetch: Item): """ Steal it from somebody. :return: """ if not item_to_fetch.belongs_to: holder = NPC.select().get() item_to_fetch.belongs_to = holder item_to_fetch.save() # steps: # steal: steal item[1] from NPC[1] steps = [[item_to_fetch, item_to_fetch.belongs_to]] Message.instruction("Steal '%s' from '%s'" % (item_to_fetch, item_to_fetch.belongs_to)) return steps
def start_quest(self, quest): print("Starting a quest from:", quest.action) self.quest_in_progress = True self.quest_done = False self.last_action = T.null self.last_args = [] self.last_action_doable = False quest.set_indices() self.progress = Progress(quest=quest) self.progress.check_action_proceed(self.last_action, self.last_args) self.progress.print_progress() Message.print_queue(debug_mode=Playground.debug_mode) export_semantics_plot( quest, semantics_indices=self.progress.semantics_indices, current_level_index=self.progress.current_node.index)
def kill_1(target: NPC): """ Go someplace and kill somebody. :param target: :return: """ player = Player.current() player.next_location = target.place player.save() # steps: # goto target # kill target steps = [[target.place, target], [target]] Message.instruction("Kill '%s'" % target) return steps
def goto(destination: Place): player = Player.current() # check if player knows the location results = PlayerKnowledgeBook.select().join(Intel)\ .where(PlayerKnowledgeBook.player == player, Intel.place_location == destination).limit(1) if not results: Message.error("Location '%s' is unknown" % destination) return False # update Player's location player.place = destination player.save() Message.achievement("Player went to '%s'" % destination) return True
def conquest_2(motivated: NPC) -> list: """ Steal stuff :param motivated: :return: """ # find something an enemy to motivated has item = None enemy_ids = NPC.select(NPC.id).where(NPC.clan != motivated.clan) if enemy_ids: items = Item.select().where(Item.belongs_to.in_(enemy_ids)).order_by( fn.Random()).limit(1) if items: item = items[0] if not item: 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() enemy_clan = Clan.select().where(Clan.id != motivated.clan).order_by( fn.Random()).limit(1).get() target = NPC.create(clan=enemy_clan, name=NPCName.fetch_new(), place=place) item = Item.create(type=ItemTypes.singleton.name, generic=GenericItem.get_or_create( name=ItemTypes.singleton.name)[0], name='arbitrary_item_' + str(randint(100, 999)), belongs_to=target) # steps # goto # steal # goto # give steps = [[item.place_(), None, item], [item, item.belongs_to], [motivated.place, motivated], [item, motivated]] Message.instruction("%s: Steal item '%s' from '%s' for me" % (motivated, item, item.belongs_to)) return steps
def serenity_5(motivated: NPC) -> list: """ Check on NPC(2) :param motivated: :return: """ # find ally NPC to motivated get an item from he/she allies = NPC.select().where(NPC.clan == motivated.clan, NPC.id != motivated).order_by( fn.Random()).limit(1) if allies: target = allies[0] 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() target = NPC.create(clan=motivated.clan, name=NPCName.fetch_new(), place=place) belongings = Item.select().where(Item.belongs_to == target.id).order_by( fn.Random()).limit(1) if belongings: item = belongings[0] else: item = Item.create(type=ItemTypes.singleton.name, generic=GenericItem.get_or_create( name=ItemTypes.singleton.name)[0], name='arbitrary_item_' + str(randint(100, 999)), belongs_to=target) # steps # goto # take # goto # give steps = [[target.place, target], [item, target], [motivated.place, motivated], [item, motivated]] Message.instruction("%s: Get item '%s' from my friend, '%s' for me" % (motivated, item, target)) return steps
def knowledge_1(NPC_target: NPC): """ Deliver item for study :param NPC_target: :return: """ player = Player.current() results = Item.select().where(Item.belongs_to != NPC_target, Item.belongs_to_player != player) if results: locations_scores = [player.distance(res.place_()) for res in results] results = sort_by_list(results, locations_scores) item = results[0] else: results = NPC.select().where(NPC.id != NPC_target) if results: locations_scores = [player.distance(res.place) for res in results] results = sort_by_list(results, locations_scores) new_item_holder = results[0] else: # No NPC left in the world except the target new_item_holder = NPC.create( place=Place.select().order_by(fn.Random()).get(), clan=Clan.select().order_by(fn.Random()).get(), name=NPCName.fetch_new()) item = Item.create(type=ItemTypes.unknown.name, generic=GenericItem.get_or_create( name=ItemTypes.singleton.name)[0], name='arbitrary_item_unknown_' + str(randint(100, 999)), place=None, belongs_to=new_item_holder) # steps: # get item # goto target place # give item to target steps = [[item], [NPC_target.place, NPC_target], [item, NPC_target]] Message.instruction("%s: Get item '%s' for me, I want to study it" % (NPC_target, item)) return steps
def stealth(target: NPC): player = Player.current() # check if player at target's place_location if player.place != target.place: Message.debug("Player is not at the target (%s) place_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 Message.achievement("Successfully snuck on '%s'" % target) return True
def print_progress(self, full: bool = False): Message.debug("level: %i, current-node: %s" % (self.current_node.index, self.current_node.action)) if full: Message.debug("semantics: %s" % self.semantics_indices) else: Message.debug("semantics: %s" % self.get_current_semantics())
def spy_1(spy_on: NPC, intel_needed: Intel, receiver: NPC): """ Go someplace, spy on somebody, return and report :param spy_on: :param intel_needed: :param receiver: :return: """ player = Player.current() player.next_location = spy_on.place player.save() # steps: # goto spy_on place_location # spy on 'spy_on' get the intel_needed # goto receiver place_location # report intel_needed to receiver steps = [[spy_on.place, spy_on], [spy_on, intel_needed], [receiver.place, receiver], [intel_needed, receiver]] Message.instruction( "Spy on '%s' to get intel '%s', goto '%s', report the intel to '%s'" % (spy_on, intel_needed, receiver, receiver)) return steps