def distance(self, candid_dest: Place) -> float: current = Place.get_by_id(self.place.id) if self.next_location is None: return two_point_distance(current, dest=candid_dest) # three point distance later = Place.get_by_id(self.next_location.id) return triangle_distance(current, dest=candid_dest, later=later)
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 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 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 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 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 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 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 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 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 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 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 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 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 do_goto(self, args): """Move player to a named position. GOTO Rivervale""" args = parse(args) if not self.check_length(args, 1): return dest = Place.get_or_none(Place.name == args[0]) if not self.set_inputs(action=T.goto, args=[dest]): return found = terminals.goto(destination=dest) if not found: print("failed!") return self.last_action_doable = True
def comfort_1(motivated: NPC) -> list: """ Obtain luxuries for the motivated NPC :param motivated: :return: """ # get item useful for motivated needed_item = Item.select().join(Need).where(Need.npc == motivated, Item.belongs_to_player.is_null())\ .order_by(fn.Random()).limit(1) if needed_item: # motivated NPC need some items item = needed_item[0] else: # motivated NPC doesn't have any needs items_in_world = Item.select().where( Item.belongs_to_player.is_null()).order_by( Item.worth.desc()).limit(1) if items_in_world: item = items_in_world[0] else: # item not found in the world 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() item = Item.create(type=ItemTypes.unknown.name, generic=GenericItem.get_or_create( name=ItemTypes.singleton.name)[0], name='arbitrary_item_' + str(randint(100, 999)), place=place, worth=1) Message.debug("No Item found in the world, item created: %s" % item) # steps: # get # goto # give steps = [[item], [motivated.place, motivated], [item, motivated]] Message.instruction("%s: Get luxury item '%s' for me" % (motivated, item)) 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 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 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 get_3(item_to_fetch: Item): """ Go someplace and pick something up that’s lying around there :param item_to_fetch: :return: """ if item_to_fetch.place: dest = item_to_fetch.place elif item_to_fetch.belongs_to: # someone took it and put it in a specific place, put it where the NPC is Message.event( "Someone has stolen the item '%s' and put it somewhere else" % item_to_fetch) dest = item_to_fetch.belongs_to.place item_to_fetch.belongs_to = None item_to_fetch.place = dest item_to_fetch.save() else: # player already has the item or no one has it, put it in a random place Message.event( "Someone has stolen the item '%s' and has put it in a random place" % item_to_fetch) dest = Place.select().order_by(fn.Random()).get() item_to_fetch.place = dest item_to_fetch.save() player = Player.current() player.next_location = dest player.save() intel = Intel.construct(item_place=item_to_fetch) PlayerKnowledgeBook.get_or_create(player=player, intel=intel) Message.achievement("Intel '%s' learned" % intel.detail()) # steps: # goto # gather steps = [[dest, None, item_to_fetch], [item_to_fetch]] Message.instruction("Gather '%s' from '%s'" % (item_to_fetch, dest)) return steps
def reputation_1(motivated: NPC) -> list: """ Obtain rare items :param motivated: :return: """ # find high worth item worthy_item = Item.select().where( Item.belongs_to_player.is_null()).order_by(Item.worth.desc()).limit(1) if worthy_item: # item found for NPC item = worthy_item[0] else: # item not found in the world 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() item = Item.create(type=ItemTypes.unknown.name, generic=GenericItem.get_or_create( name=ItemTypes.singleton.name)[0], name='arbitrary_item_' + str(randint(100, 999)), place=place, worth=1) Message.debug("No Item found in the world, item created: %s" % item) # steps: # get # goto # give steps = [[item], [motivated.place, motivated], [item, motivated]] Message.instruction("%s: Get the rare item '%s' for me" % (motivated, item)) return steps
def serenity_4(motivated: NPC) -> list: """ Check on NPC(1) :param motivated: :return: """ # find ally NPC to motivated get generated intel about health and well being 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) well_being_intel = Intel.construct(other='arbitrary_well_being_report_' + str(randint(100, 999))) NPCKnowledgeBook.create(npc=target, intel=well_being_intel) # steps # goto # listen # goto # report steps = [[target.place, target], [well_being_intel, target], [motivated.place, motivated], [well_being_intel, motivated]] Message.instruction( "%s: Check on my friend, '%s' ask how he's doing for me" % (motivated, target)) return steps
def create(): alliance = Clan.create(name='alliance') horde = Clan.create(name='horde') beach = Place.create(name='beach', x=10, y=80) azshara = Place.create(name='azshara', x=50, y=50) cataclysm = Place.create(name='cataclysm', x=70, y=90) crystalsong = Place.create(name='crystalsong', x=10, y=60) forest = Place.create(name='forest', x=60, y=20) dalaran = Place.create(name='dalaran', x=80, y=85) feralas = Place.create(name='feralas', x=10, y=10) harbor = Place.create(name='harbor', x=80, y=10) shrine = Place.create(name='shrine', x=30, y=80) nagrand = Place.create(name='nagrand', x=70, y=40) acherus = Place.create(name='acherus', x=10, y=40) alcaz = Place.create(name='alcaz', x=90, y=60) PlaceName.create(name='hamilton') PlaceName.create(name='denver') PlaceName.create(name='munich') PlaceName.create(name='quebec') player = Player.create(name='player_1', place=beach, clan=alliance) qeynos = NPC.create(name='qeynos', place=azshara, clan=alliance) npc_2 = NPC.create(name='npc2', place=beach, clan=alliance) # = adon steve = NPC.create(name='steve', place=forest, clan=alliance) tomas = NPC.create(name='tomas', place=feralas, clan=alliance) lempeck = NPC.create(name='lempeck', place=harbor, clan=alliance, health_meter=0.7) # = Denros bixies = NPC.create(name='bixies', place=cataclysm, clan=horde) goblin = NPC.create(name='goblin', place=dalaran, clan=horde) NPCName.create(name='gabriel') NPCName.create(name='mariah') NPCName.create(name='sia') NPCName.create(name='silva') NPCName.create(name='berg') NPCName.create(name='jessie') NPCName.create(name='lizzy') NPCName.create(name='amanda') NPCName.create(name='bernard') NPCName.create(name='monica') NPCName.create(name='catrina') NPCName.create(name='leo') NPCName.create(name='richard') NPCName.create(name='naomi') NPCName.create(name='aaron') Motivation.create(npc=steve, action=NT.knowledge.value, motive=0.6) Motivation.create(npc=lempeck, action=NT.comfort.value, motive=0.9) Motivation.create(npc=npc_2, action=NT.reputation.value, motive=0.7) Motivation.create(npc=goblin, action=NT.serenity.value, motive=0.7) Motivation.create(npc=tomas, action=NT.protection.value, motive=0.7) Motivation.create(npc=qeynos, action=NT.conquest.value, motive=0.7) potion = Item.create( type=ItemTypes.tool.name, generic=GenericItem.get_or_create(name=ItemTypes.singleton.name)[0], name='potion', place=None, belongs_to=qeynos, usage=T.treat.value, impact_factor=0.5) jum = Item.create(type=ItemTypes.unknown.name, generic=GenericItem.get_or_create(name='jum')[0], name='jum', place=None, belongs_to=npc_2) comb = Item.create(type=ItemTypes.unknown.name, generic=GenericItem.get_or_create(name='comb')[0], name='comb', place=None, belongs_to=bixies) bandage = Item.create(type=ItemTypes.tool.name, generic=GenericItem.get_or_create(name='bandage')[0], name='bandage', place=crystalsong, belongs_to=None, usage=T.treat.value) address_book = Item.create( type=ItemTypes.readable.name, generic=GenericItem.get_or_create(name=ItemTypes.singleton.name)[0], name='address_book', belongs_to=tomas) # address-book (goblin loc) coin = Item.create(type=ItemTypes.unknown.name, generic=GenericItem.get_or_create(name='coin')[0], name='coin', belongs_to_player=player) Need.create(npc=lempeck, item=potion) spell = Intel.construct(spell=Spell.create( name="needs_path", text="'Earth, grass, trees and seeds reveal the path to suit my needs'" )) spell_2 = Intel.construct( spell=Spell.create(name="flat_earth", text="Earth is flat! LoL")) spell_3 = Intel.construct( spell=Spell.create(name="gravity", text="Gravity is a myth")) # SpellName.create() NPCKnowledgeBook.create(npc=goblin, intel=spell) NPCKnowledgeBook.create(npc=bixies, intel=spell_2) NPCKnowledgeBook.create(npc=steve, intel=spell_2) intel_bandage_loc = Intel.construct(item_place=bandage) intel_npc2_loc = Intel.construct(npc_place=npc_2, worth=0.6) intel_goblin_loc = Intel.construct(npc_place=goblin, worth=0.8) ReadableKnowledgeBook.create(readable=address_book, intel=intel_goblin_loc) intel_tomas_loc = Intel.construct(npc_place=tomas) NPCKnowledgeBook.create(npc=bixies, intel=intel_tomas_loc) NPCKnowledgeBook.create(npc=lempeck, intel=intel_tomas_loc) intel_lempeck_loc = Intel.construct(npc_place=lempeck) NPCKnowledgeBook.create(npc=qeynos, intel=intel_lempeck_loc) intel_qeynos_loc = Intel.construct(npc_place=qeynos) NPCKnowledgeBook.create(npc=npc_2, intel=intel_qeynos_loc) intel_comb_place = Intel.construct(item_place=comb) NPCKnowledgeBook.create(npc=npc_2, intel=intel_comb_place) intel_cataclysm = Intel.construct(npc_place=bixies) NPCKnowledgeBook.create(npc=npc_2, intel=intel_cataclysm) Exchange.create(npc=qeynos, item=potion, need=Need.get_or_create(npc=qeynos, item=jum)[0]) Exchange.create(npc=npc_2, intel=intel_comb_place, need=Need.get_or_create(npc=npc_2, item=bandage)[0]) Exchange.create(npc=npc_2, intel=intel_cataclysm, need=Need.get_or_create(npc=npc_2, item=bandage)[0]) Exchange.create(npc=npc_2, item=jum, need=Need.get_or_create(npc=npc_2, item=comb)[0]) Exchange.create(npc=tomas, item=address_book, need=Need.get_or_create(npc=tomas, item=coin)[0]) for place in Place.select(): intel = Intel.construct(place_location=place) PlayerKnowledgeBook.create(player=player, intel=intel)
def goto_3(destination: Place, npc: NPC = None, item: Item = None): """ Find out where to go and go there. :return: """ # place_location[1] is destination # location[1] is place_location[1] exact location player = Player.current() # find correct type of Intel from npc_place, item_place and place_location if npc: intel = Intel.get_or_none(type=IntelTypes.npc_place.name, npc_place=npc) if PlayerKnowledgeBook.get_or_none(player=player, intel=intel): # player already knows, move the npc destination = Place.select().where(Place.id != npc.place).order_by( fn.Random()) if destination: destination = destination.get() else: destination = narrative_helper.create_place() npc.place = destination npc.save() # by moving NPC place, npc_place intel removes from player knowledge book automatically Message.event("NPC %s has moved to somewhere else" % npc) elif item: if item.belongs_to: intel = Intel.get_or_none(type=IntelTypes.npc_place.name, npc_place=item.belongs_to) if PlayerKnowledgeBook.get_or_none(player=player, intel=intel): # player already knows where the item holder is, move the npc holder = item.belongs_to destination = Place.select().where( Place.id != holder.place).order_by(fn.Random()) if destination: destination = destination.get() else: destination = narrative_helper.create_place() holder.place = destination holder.save() Message.debug( "Item holder (%s) is moved somewhere else (item: %s)" % (item.belongs_to, item)) Message.event( "Item '%s's holder has been just moved to somewhere else" % item) else: intel = Intel.get_or_none(type=IntelTypes.item_place.name, item_place=item) if PlayerKnowledgeBook.get_or_none(player=player, intel=intel): # player already knows where the item is located at, move the item destination = Place.select().where( Place.id != item.place).order_by(fn.Random()) if destination: destination = destination.get() else: destination = narrative_helper.create_place() item.place = destination item.save() Message.event("Item '%s' has been misplaced" % item) else: intel = Intel.get_or_none(type=IntelTypes.location.name, place_location=destination) if PlayerKnowledgeBook.get_or_none(player=player, intel=intel): # player already knows where the place is exactly, # so create a new place at the same location with a different name, now player doesn't know! destination = Place.create(name=PlaceName.fetch_new(), x=destination.x, y=destination.y) intel = Intel.construct(place_location=destination) Message.event("Change of plans, destination is now '%s'" % destination) if not intel: # create the correct type of intel based on what is being asked if npc: intel = Intel.construct(npc_place=npc) elif item and item.belongs_to: intel = Intel.construct(npc_place=item.belongs_to) elif item: intel = Intel.construct(item_place=item) else: intel = Intel.construct(place_location=destination) # update player's next location player.next_location = destination player.save() # steps: # learn: location[1] # T.goto: location[1] steps = [[intel], [destination]] if PlayParams.debug_mode and (npc or item): destination_str = str(npc if npc else item) + ' (' + str( destination) + ')' else: if npc: destination_str = npc elif item: destination_str = item else: destination_str = destination Message.instruction("Find out how to get to '%s' location, then go to it" % destination_str) return steps
def learn_2(required_intel: Intel): """ Go someplace, perform subquest, get info from NPC. :param required_intel: :return: """ player = Player.current() # find NPC who has the intel, goto the NPC and listen to get the intel results = NPC.select()\ .join(NPCKnowledgeBook)\ .where(NPCKnowledgeBook.intel == required_intel, NPC.clan == player.clan) # sort by triangle distance locations_scores = [player.distance(row.place) for row in results] results = sort_by_list(results, locations_scores) if results: knowledgeable_npc = results[0] else: # NPC pool to add required intel to one of them results = NPC.select().where(NPC.clan == player.clan) if not results: # No NPC in clan found search among all NPCs Message.debug("No NPC in clan %s found, search among all NPCs" % NPC.clan) results = NPC.select().order_by(fn.Random()).get() if required_intel.npc_place: # exclude the same NPC looking for results = results.where(NPC.id != required_intel.npc_place) elif required_intel.item_place and required_intel.item_place.belongs_to: # exclude the owner of the item to ask where is the item! results = results.where( NPC.id != required_intel.item_place.belongs_to) if not results: # No NPC left in the world knowledgeable_npc = NPC.create( place=Place.select().order_by(fn.Random()).get(), clan=Clan.select().order_by(fn.Random()).get(), name=NPCName.fetch_new()) Message.debug( "No NPC left in the world, new one %s created for learn_2" % knowledgeable_npc) else: locations_scores = [player.distance(row.place) for row in results] results = sort_by_list(results, locations_scores) knowledgeable_npc = results[0] NPCKnowledgeBook.create(npc=knowledgeable_npc, intel=required_intel) player.next_location = knowledgeable_npc.place player.save() # steps: # do sub-quest # goto knowledgeable_npc place_location # listen knowledgeable_npc to get required_intel steps = [[], [knowledgeable_npc.place, knowledgeable_npc], [required_intel, knowledgeable_npc]] Message.instruction( "Do a sub-quest, goto '%s', listen intel '%s' from '%s'" % (knowledgeable_npc, required_intel, knowledgeable_npc)) return steps
def learn_3(required_intel: Intel): """ Go someplace, get something, and read what is written on it. :param required_intel: :return: """ player = Player.current() # intel[1] is to be learned # find a book[1] (readable, it could be a sign) that has intel[1] on it results = ReadableKnowledgeBook.select()\ .join(Item, on=(ReadableKnowledgeBook.readable == Item.id))\ .where(ReadableKnowledgeBook.intel == required_intel, Item.belongs_to_player != player) # sort by readable place_ triangle locations_scores = [ player.distance(knowledge_book.readable.place_()) for knowledge_book in results ] results = sort_by_list(results, locations_scores) if results: book_containing_intel = results[0].readable # type: Item else: # create an address book containing the intel player is looking for known_places = Place.select()\ .join(Intel, on=(Intel.place_location == Place.id))\ .join(PlayerKnowledgeBook, on=(PlayerKnowledgeBook.intel == Intel.id))\ .where(PlayerKnowledgeBook.player == player) if known_places: known_place = known_places.order_by(fn.Random()).get() else: known_place = narrative_helper.create_place() book_containing_intel = Item.create( type=ItemTypes.readable.name, generic=GenericItem.get_or_create( name=ItemTypes.singleton.name)[0], name=ItemName.fetch_new(), place=known_place) ReadableKnowledgeBook.create(readable=book_containing_intel, intel=required_intel) PlayerKnowledgeBook.create( player=player, intel=Intel.construct(item_place=book_containing_intel)) player.next_location = book_containing_intel.place_() player.save() intel = Intel.construct(item_place=book_containing_intel) PlayerKnowledgeBook.get_or_create(player=player, intel=intel) Message.achievement("Intel '%s' learned" % intel.detail()) # steps: # goto: place_location[1] # get: book[1] # T.read: intel[1] from book[1] steps = [[book_containing_intel.place_(), None, book_containing_intel], [book_containing_intel], [required_intel, book_containing_intel]] Message.instruction("Get '%s', and read the intel '%s' from it" % (book_containing_intel, required_intel)) return steps
def learn_4(required_intel: Intel): # find an NPC who has the required intel in exchange, get the NPC's needed item to give if required_intel.npc_place: bad_needs = Need.select(Need.id).join(Item).where( (Need.npc == required_intel.npc_place) | (Item.belongs_to == required_intel.npc_place)) elif required_intel.item_place: bad_needs = Need.select( Need.id).where(Need.item == required_intel.item_place) else: bad_needs = [] # NPC who has the intel knowledgeable = NPC.select(NPC.id).join(NPCKnowledgeBook).where( NPC.id != required_intel.npc_place, NPCKnowledgeBook.intel == required_intel.id) exchange = None if knowledgeable.count(): needs = Need.select()\ .join(NPC)\ .where(NPC.id.in_(knowledgeable), Need.id.not_in(bad_needs), Need.item_id.is_null(False)) if needs: exchanges = Exchange.select().where( Exchange.need.in_(needs), Exchange.intel == required_intel.id).limit(1) if exchanges: exchange = exchanges[0] else: exchange = Exchange.create(need=needs[0], intel=required_intel) if not exchange: # no NPC has the intel or no need found accessible_items = Item.select().where( (Item.id != required_intel.item_place) & (Item.belongs_to_player.is_null()) & ((Item.belongs_to.is_null()) | Item.belongs_to != required_intel.npc_place)).order_by( fn.Random()).limit(1) if accessible_items: item = accessible_items[0] else: holder = NPC.select().where( NPC.id != required_intel.npc_place).order_by( fn.Random()).limit(1) if holder: holder = holder[0] else: holder = NPC.create( name=NPCName.fetch_new(), clan=Clan.select().order_by(fn.Random()).get(), place=Place.select().order_by(fn.Random()).get()) item = Item.create(name='arbitrary_item_' + str(randint(100, 999)), generic=GenericItem.get_or_create( name=ItemTypes.singleton.name)[0], belongs_to=holder, type=ItemTypes.unknown.name) if knowledgeable: informer = knowledgeable.order_by(fn.Random()).get() else: npc = NPC.select().where( NPC.id != required_intel.npc_place).order_by( fn.Random()).limit(1) if npc: informer = npc[0] else: informer = NPC.create( name=NPCName.fetch_new(), clan=Clan.select().order_by(fn.Random()).get(), place=Place.select().order_by(fn.Random()).get()) NPCKnowledgeBook.create(npc=informer, intel=required_intel) need = Need.create(npc=informer, item=item) exchange = Exchange.create(need=need, intel=required_intel) informer = exchange.need.npc item_to_get_for_exchange = exchange.need.item player = Player.current() player.next_location = informer.place player.save() intel = Intel.construct(item_place=item_to_get_for_exchange) PlayerKnowledgeBook.get_or_create(player=player, intel=intel) Message.achievement("Intel '%s' learned" % intel.detail()) # steps: # get # sub-quest # give # listen steps = [[item_to_get_for_exchange], [informer.place], [item_to_get_for_exchange, informer], [required_intel, informer]] Message.instruction( "Get '%s', perform a sub-quest, give the acquired item to '%s' in return get an intel on '%s'" % (item_to_get_for_exchange, informer, required_intel)) return steps