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
Пример #2
0
def null(*args):
    """
    Nothing to do
    :return:
    """
    Message.debug("null terminal called")
    return True
Пример #3
0
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
Пример #4
0
    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)
Пример #5
0
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
Пример #7
0
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
Пример #8
0
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
Пример #9
0
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
Пример #10
0
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
Пример #11
0
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
Пример #12
0
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
Пример #13
0
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
Пример #14
0
    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)
Пример #15
0
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
Пример #16
0
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
Пример #17
0
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
Пример #18
0
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 [[]]
Пример #19
0
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
Пример #20
0
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 []
Пример #21
0
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
Пример #22
0
 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)
Пример #23
0
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
Пример #24
0
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
Пример #25
0
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
Пример #26
0
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
Пример #27
0
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
Пример #28
0
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
Пример #29
0
 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())
Пример #30
0
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