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 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 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 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 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 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 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 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 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 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 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 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 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
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 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 read(intel: Intel, readable: Item): # check if the readable has the intel if not ReadableKnowledgeBook.get_or_none( ReadableKnowledgeBook.intel == intel, ReadableKnowledgeBook.readable == readable): Message.debug( "Readable '%s' does not contain the intel '%s', ReadableKnowledgeBook not found" % (readable, intel)) Message.error( "Readable '%s' does not contain the intel player looking for" % readable) return False player = Player.current() # check if player owns the readable if readable.belongs_to_player != player: Message.debug("Player doesn't have the readable '%s'" % readable) if readable.place_() == player.place: readable.belongs_to = None readable.belongs_to_player = player readable.save() Message.debug( "Player didn't own the readable (%s) but at its place so he take it" % readable) else: Message.debug( "Player neither own the readable (%s), nor at the item's place_location (%s)" % (readable, readable.place_())) Message.error( "You neither own the readable (%s), nor are at the item's location" % readable) return False # update Player's intel NarrativeHelper.add_intel(intel) Message.achievement("By reading '%s', intel '%s' has been learned" % (readable, intel.detail())) return True
def kill(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 NPCDead.create(name=target.name, place=target.place, clan=target.clan) Message.achievement("NPC '%s' has been killed" % target) target.delete_instance(recursive=True) return True
def steal_2(item_to_steal: Item, item_holder: NPC): """ Go someplace, kill somebody and take something :param item_to_steal: :param item_holder: :return: """ 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 holder # kill holder # T.take item from holder steps = [[item_holder.place, item_holder], [item_holder], [item_to_steal]] Message.instruction("Kill '%s' and take '%s'" % (item_holder, item_to_steal)) return steps
def get_4(item_to_fetch: Item): """ an NPC have the item, but you need to give the NPC something in an exchange :param item_to_fetch: :return: """ player = Player.current() # find an NPC who has the needed item, and has it in exchange list exchanges = Exchange.select().join(Item) if item_to_fetch.is_singleton(): exchanges = exchanges.where(Exchange.item == item_to_fetch) else: exchanges = exchanges.where( Exchange.item.generic == item_to_fetch.generic) if exchanges: locations_scores = [ player.distance(exc.need.npc.place) for exc in exchanges ] exchanges = sort_by_list(exchanges, locations_scores) exchange = exchanges[0] item_to_give = exchange.need.item item_holder = exchange.need.npc else: # no one wants to offer the "item_to_fetch" in exchange for something else # you can even trade with your enemies so alliance doesn't really matters here # first try find someone who needs this item Message.debug( "No one wants to offer the '%s' in exchange for something else" % item_to_fetch) needs = Need.select().where(Need.item == item_to_fetch).group_by( Need.npc) if needs.count(): need = needs.order_by(fn.Random()).get() item_holder = need.npc Message.debug( "NPC '%s' needs something, ideal to create an exchange motive with the item '%s' for him" % (item_holder, item_to_fetch)) else: # no one need anything create a need for coin for an NPC results = NPC.select() locations_scores = [player.distance(npc.place) for npc in results] results = sort_by_list(results, locations_scores) item_holder = results[0] Message.debug( "No one need anything create a need for 'coin' for a close-by NPC '%s'" % item_holder) need = Need.create( npc=item_holder, item=Item.get(generic=GenericItem.get(name='coin'))) Exchange.create(need=need, item=item_to_fetch) if item_to_fetch.belongs_to != item_holder: # ensure NPC has the item item_to_fetch.belongs_to = item_holder item_to_fetch.save() item_to_give = need.item player.next_location = item_holder.place 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()) # check for player belonging for the exchange item if item_to_give.is_singleton(): player_owns = (item_to_give.belongs_to_player == player) else: player_owns = Item.select().where(Item.generic == item_to_give.generic, Item.belongs_to_player == player) is True if player_owns: # player has the item # goto # exchange steps = [[], [], [], [item_holder.place, item_holder], [item_holder, item_to_give, item_to_fetch]] Message.instruction( "Do a sub-quest, meet '%s' and exchange '%s' with '%s'" % (item_holder, item_to_give, item_to_fetch)) return steps # steps: # goto # get # sub-quest # goto # exchange steps = [[item_to_give.place_(), None, item_to_give], [item_to_give], [], [item_holder.place, item_holder], [item_holder, item_to_give, item_to_fetch]] Message.instruction( "Get '%s', do a sub-quest, meet '%s' and exchange '%s' with '%s'" % (item_to_give, item_holder, item_to_give, item_to_fetch)) 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
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