Beispiel #1
0
 def transact(self, me):
     employer = me.get_knowledge('employer', me)
     if employer:
         print('Already employed by ' + employer)
         return Operation(
             "talk",
             Entity(say="Sorry, I am currently working for someone else."))
     who = me.map.get(self.who)
     if not who:
         print("Who am I talking to")
         return
     if self.payed < self.cost:
         return Operation(
             "talk",
             Entity(say=who.name + " you owe me " +
                    str(self.cost - self.payed) + " coins."))
     res = Oplist()
     me.add_knowledge('employer', me.entity.id, who.id)
     # FIXME add the new goal
     goal = Accompany(who.id)
     me.goals.insert(0, goal)
     res.append(
         Operation("talk",
                   Entity(say="I will help you out until sundown today.")))
     self.irrelevant = 1
     return res
Beispiel #2
0
    def completed(self):
        res = Oplist()
        # Find one charcoal and one ore amongst the children and delete them, and create one iron ingot.
        charcoals = self.usage.tool.find_in_contains(charcoal_filter)
        if len(charcoals):
            # We have charcoal, lets see if we also have something to smelt. We'll go through the map of ores to find a match.
            for key, value in ores.items():
                inputs = self.usage.tool.find_in_contains(value)
                if len(inputs) > 0:
                    res.append(
                        Operation("delete", Entity(inputs[0].id),
                                  to=inputs[0]))
                    res.append(
                        Operation("delete",
                                  Entity(charcoals[0].id),
                                  to=charcoals[0]))

                    new_entity = Entity(parent=key, loc=self.usage.tool.id)
                    res.append(
                        Operation("create", new_entity, to=self.usage.tool.id))
                    res.append(
                        Operation(
                            "imaginary",
                            Entity(
                                description="You successfully refine the ore."
                            ),
                            to=self.usage.actor.id,
                            from_=self.usage.actor.id))

        return res
Beispiel #3
0
def consume(instance):
    """ When drinking the potion the __effects should be applied to the drinker, and the potion destroyed.
     In addition, if a script handler is registered in the __handler property it will be called as well.
     """

    op_list = Oplist()
    op_list += Operation("delete", Entity(instance.tool.id), to=instance.tool)

    handler_props = instance.tool.props["__handler"]
    if handler_props is not None:
        mod_name, func_name = handler_props["name"].rsplit('.', 1)
        mod = importlib.import_module(mod_name)
        func = getattr(mod, func_name)
        result = func(instance)
        if result:
            op_list.append(result)

    effects_prop = instance.tool.props["__effects"]
    if effects_prop is not None:
        # Copy over all props in "__effects" to a "set" op.
        for prop_name, effect in effects_prop.items():
            ent = Entity(instance.actor.id)
            ent[str(prop_name)] = effect
            op_list += Operation("set", ent, to=instance.actor.id)

    msg_prop = instance.tool.props["__message"]
    if msg_prop is not None:
        op_list += Operation("imaginary",
                             Entity(description=str(msg_prop)),
                             to=instance.actor.id,
                             from_=instance.actor.id)
    op_list.append(instance.actor.start_action("drinking", 1))

    return server.OPERATION_BLOCKED, op_list
Beispiel #4
0
    def do(self, me):
        if (self.tool in me.things) == 0:
            # print "No tool"
            return
        tool = me.find_thing(self.tool)[0]
        if not hasattr(me,
                       'right_hand_wield') or me.right_hand_wield != tool.id:
            # FIXME We need to sort out how to tell seed one is wielding
            return Operation("wield", Entity(tool.id))
        id = me.get_knowledge('focus', self.seed)
        if id is None:
            return
        seed = me.map.get(id)
        if seed is None:
            me.remove_knowledge('focus', self.seed)
            return
        if not seed.visible:
            me.remove_knowledge('focus', self.seed)
            return

        # Check that the seed isn't too close to other sources (to prevent us from planting too closely)
        sources_all = me.map.find_by_filter(self.source_filter)
        for thing in sources_all:
            #TODO: add "distance_between"; this won't work
            dist = me.steering.distance_to(thing, ai.EDGE, ai.EDGE)
            if dist is not None and dist < self.spacing:
                # We've found a source which is too close to the seed, so we'll not plant this one
                me.remove_knowledge('focus', self.seed)
                return

        return Operation("use", Entity(seed.id, objtype="obj"))
Beispiel #5
0
    def tick(self):

        (valid, err) = self.usage.is_valid()
        if not valid:
            return self.irrelevant(err)

        self.usage.actor.send_world(Operation("sight", self.usage.op))

        target = self.usage.get_arg("targets", 0)
        instance = self.usage

        # Ignore pos
        if target:
            if instance.actor.can_reach(target):
                damage = 0
                damage_attr = getattr(instance.actor.props,
                                      "damage_" + instance.op.parent)
                if damage_attr:
                    damage = damage_attr
                hit_op = Operation('hit',
                                   Entity(damage=damage,
                                          hit_type=instance.op.parent,
                                          id=instance.actor.id),
                                   to=target.entity)
                return server.OPERATION_BLOCKED, hit_op, Operation(
                    'sight', hit_op)
            else:
                return server.OPERATION_BLOCKED, instance.actor.client_error(
                    instance.op, "Too far away")
        else:
            return server.OPERATION_BLOCKED
Beispiel #6
0
 def do_peck(self, me):
     if not self.last_time or time.time() - self.last_time > self.interval:
         self.last_time = time.time()
         # stop moving
         me.steering.set_destination()
         return Operation("use", Operation("consume",
                                           Entity(me.entity.id, targets=[Entity(me.entity.parent.id, pos=me.entity.location.pos)])))
Beispiel #7
0
def strike(instance):
    """Strike another entity with your fists."""

    # If there's a cooldown we need to mark the actor
    cooldown = getattr(instance.tool.props, "cooldown_" + instance.op.parent)
    if cooldown and cooldown > 0.0:
        instance.tool.send_world(Operation('set', Entity(instance.tool.id, ready_at=server.world.get_time() + cooldown), to=instance.tool.id))

    # Send sight even if we miss
    instance.actor.send_world(Operation("sight", instance.op))

    # Unarmed strike only handles one target
    target = instance.get_arg("targets", 0)
    # Ignore pos
    if target:
        if instance.actor.can_reach(target):
            damage = 0
            damage_attr = getattr(instance.actor.props, "damage_" + instance.op.parent)
            if damage_attr:
                damage = damage_attr
            hit_op = Operation('hit', Entity(damage=damage, hit_type=instance.op.parent), to=target.entity, id=instance.actor.id)
            return server.OPERATION_BLOCKED, hit_op, Operation('sight', hit_op)
        else:
            return server.OPERATION_BLOCKED, instance.actor.client_error(instance.op, "Too far away")
    else:
        return server.OPERATION_BLOCKED
    def do(self, me):
        if (self.tool in me.things) == 0:
            # print "No tool"
            return
        tool = me.find_thing(self.tool)[0]
        if not hasattr(me, 'right_hand_wield') or me.right_hand_wield != tool.id:
            # FIXME We need to sort out how to tell seed one is wielding
            return Operation("wield", Entity(tool.id))
        id = me.get_knowledge('focus', self.seed)
        if id is None:
            return
        seed = me.map.get(id)
        if seed is None:
            me.remove_knowledge('focus', self.seed)
            return
        if not seed.visible:
            me.remove_knowledge('focus', self.seed)
            return

        # Check that the seed isn't too close to other sources (to prevent us from planting too closely)
        sources_all = me.map.find_by_filter(self.source_filter)
        spacing_sqr = self.spacing * self.spacing
        for thing in sources_all:
            sqr_dist = square_distance(seed.location, thing.location)
            if sqr_dist and sqr_dist < spacing_sqr:
                # We've found a source which is too close to the seed, so we'll not plant this one
                me.remove_knowledge('focus', self.seed)
                return

        return Operation("use", Entity(seed.id, objtype="obj"))
Beispiel #9
0
def strike(instance):
    # Check that we can reach the target with our weapon
    extra_reach = 0.0
    if instance.tool.props.reach:
        extra_reach = instance.tool.props.reach

    # If there's a cooldown we need to mark the actor
    Usage.set_cooldown_on_attached(instance.tool, instance.actor)

    # Send sight even if we miss
    instance.actor.send_world(Operation("sight", instance.op))

    # Melee weapons only handles one target
    target = instance.get_arg("targets", 0)
    if target:
        # Ignore pos
        if instance.actor.can_reach(target, extra_reach):
            damage = 0
            if instance.tool.props.damage:
                damage = instance.tool.props.damage
            hit_op = Operation('hit',
                               Entity(damage=damage, hit_type=instance.op.id),
                               to=target.entity)
            return server.OPERATION_BLOCKED, hit_op, Operation('sight', hit_op)
        else:
            return server.OPERATION_BLOCKED, instance.actor.client_error(
                instance.op, "Too far away")
    else:
        return server.OPERATION_BLOCKED
Beispiel #10
0
    def hit_operation(self, op):
        res = Oplist()
        arg = op[0]
        if arg:
            # Place the explosion at the point of collision.
            new_location = rules.Location(self.location.parent, arg.pos)

            entity = Entity(parent="explosion",
                            location=new_location,
                            mode="fixed")
            mode_data = self.props.mode_data
            actor_id = self.id
            # Check if there's an entity ref contained in the mode_data prop,
            # and if so attach that to the "entity_ref" prop of the explosion.
            # This way the explosion can properly attribute any Hit op it sends to the actor which fired the item.
            if mode_data:
                entity_ref = mode_data['$eid']
                if entity_ref is not None:
                    actor_id = entity_ref
            entity["entity_ref"] = {"$eid": actor_id}
            damage_explosion = self.props.damage_explosion
            if damage_explosion is not None:
                entity["damage"] = damage_explosion

            res.append(Operation("create", entity, to=self.id))
            res.append(Operation("delete", Entity(self.id), to=self.id))
        return server.OPERATION_HANDLED, res
Beispiel #11
0
 def sift_operation(self, op):
     newloc = self.location.copy()
     newloc.velocity = Vector3D()
     item = Gravestone.items[randint(0, 5)]
     newloc.pos = newloc.pos + Vector3D(uniform(-1, 1), uniform(-1, 1), uniform(-1, 1))
     return Operation("create", Entity(name=item, parent=item, location=newloc.copy()), to=self) + \
            Operation("imaginary", Entity(description="You dig up a bone from the grave."), to=op.id, from_=op.id)
Beispiel #12
0
    def consume_operation(self, op):
        if len(op) > 0:
            arg = op[0]
            if arg.consume_type == "fire":
                # Determine the burn speed, i.e. how much to remove of the status for each burn
                burn_speed = 0.1
                burn_speed_prop = self.props._burn_speed
                if burn_speed_prop:
                    burn_speed = burn_speed_prop

                nourish_ent = Entity()

                nourish_ent.consume_type = arg.consume_type
                nourish_op = Operation("nourish", nourish_ent, to=op.from_)

                status_prop = self.props.status

                if status_prop:
                    return server.OPERATION_BLOCKED, nourish_op, Operation(
                        "set",
                        Entity(self.id, status=status_prop - burn_speed),
                        to=self)
                else:
                    return server.OPERATION_BLOCKED, nourish_op

        return server.OPERATION_IGNORED
Beispiel #13
0
    def tick(self):

        (valid, err) = self.usage.is_valid()
        if not valid:
            return self.irrelevant(err)

        self.usage.actor.send_world(Operation("sight", self.usage.op))

        target = self.usage.get_arg("targets", 0)
        if target:
            # Take a swing
            extra_reach = 0.0
            if self.usage.tool.props.reach:
                extra_reach = self.usage.tool.props.reach

            if self.usage.actor.can_reach(target, extra_reach):
                damage = 0
                if self.usage.tool.props.damage:
                    damage = self.usage.tool.props.damage
                hit_op = Operation('hit',
                                   Entity(damage=damage,
                                          hit_type=self.usage.op.parent,
                                          id=self.usage.actor.id),
                                   to=target.entity)
                return server.OPERATION_BLOCKED, hit_op
            else:
                return server.OPERATION_BLOCKED, self.usage.actor.client_error(
                    self.usage.op, "Too far away")
        return server.OPERATION_BLOCKED
Beispiel #14
0
    def hit_operation(self, op):
        arg = op[0]
        if arg:
            hit_op = op.copy()
            res = Oplist()
            if hasattr(arg, 'damage'):
                # Apply any armor modifiers
                armor = self.get_prop_float("armor", 0)
                status_decrease = (arg.damage - armor) / 100.0
                # Check if there's a modifier for the specific type of hit.
                if hasattr(arg,
                           'hit_type') and self.props["__modifier_hit_type_" +
                                                      arg.hit_type]:
                    status_decrease = status_decrease * self.props[
                        "__modifier_hit_type_" + arg.hit_type]
                print("Hit for {} damage".format(status_decrease))
                status_decrease = max(
                    0.0, status_decrease)  # Make sure it's not negative
                hit_op[0].damage = status_decrease
                if status_decrease > 0:
                    res.append(
                        Operation("set",
                                  Entity(self.id,
                                         {"status!subtract": status_decrease}),
                                  to=self.id))
            return server.OPERATION_BLOCKED, res, Operation('sight', hit_op)

        return server.OPERATION_IGNORED
Beispiel #15
0
    def delete_operation(self, op):
        res = Oplist()

        # Restore status if it's zero.
        if self.has_prop_float("status"):
            res += Operation("set", Entity(self.id, status=1.0), to=self.id)

        # Respawn in a spawn area
        respawn_alias = self.get_prop_string("_respawning")
        if respawn_alias:
            respawn_entity = server.get_alias_entity(respawn_alias)
            if respawn_entity:
                pos = Spawner.get_spawn_pos(respawn_entity)
                if pos:
                    location = Location()
                    location.pos = pos
                    # Randomize orientation
                    rotation = random.random() * math.pi * 2
                    location.orientation = physics.Quaternion(physics.Vector3D(0, 1, 0), rotation)
                    location.parent = respawn_entity.location.parent
                    # Emit a sight of this entity being defeated
                    res += Operation("sight", Operation("defeated", Entity(self.id)))
                    res += Operation("move", Entity(self.id, location=location), to=self.id)
                    res += Operation("imaginary", Entity(description="You were killed and will be respawned."), to=self.id, from_=self.id)
                    return server.OPERATION_BLOCKED, res
Beispiel #16
0
    def completed(self):
        res = Oplist()
        if self.is_valid():
            for input_def in self.temporaries["inputs"]:
                input_entities = self.usage.actor.find_in_contains(
                    input_def["criteria"])
                needed_amount = input_def["amount"]
                for entity in input_entities:
                    entity_amount = entity.get_prop_int("amount", 1)
                    amount_to_delete = min(needed_amount, entity_amount)
                    res.append(
                        Operation("delete",
                                  Entity(entity.id, amount=amount_to_delete),
                                  to=entity))
                    needed_amount = needed_amount - amount_to_delete
                    if needed_amount <= 0:
                        break
            for output_def in self.temporaries["outputs"]:
                res.append(
                    Operation("create", output_def, to=self.usage.tool.id))

            craft_name = self.usage.tool.get_prop_string("craft_name", "tool")
            res.append(
                Operation(
                    "imaginary",
                    Entity(description="You successfully create '{}'.".format(
                        craft_name)),
                    to=self.usage.actor.id,
                    from_=self.usage.actor.id))
            return res
Beispiel #17
0
    def tick_operation(self, op):
        if len(op) > 0:
            arg = op[0]

            if arg.name == self.__class__.__name__:
                res = Oplist()
                # Handle the world being recreated by checking for 0
                if op.refno == self.tick_refno or self.tick_refno == 0:
                    minds_prop = self.get_prop_list("_minds")
                    if hasattr(arg, "type") and arg.type == "remove":
                        # Check that the entity hasn't gotten a new mind in the meantime
                        if minds_prop is None or len(minds_prop) == 0:
                            # Move entity to limbo
                            limbo_entity = server.get_alias_entity("limbo")
                            if limbo_entity and self.location.parent != limbo_entity:
                                # Store the current position in "__respawn" so we can spawn back there.
                                res += Operation(
                                    "set",
                                    Entity(self.id,
                                           __respawn={
                                               "loc": self.location.parent.id,
                                               "pos": self.location.pos
                                           }),
                                    to=self.id)
                                res += Operation("move",
                                                 Entity(self.id,
                                                        loc=limbo_entity.id),
                                                 to=self.id)
                    else:
                        # Only respawn if there's a mind
                        if minds_prop is not None and len(minds_prop) > 0:
                            res += self.respawn()

                return server.OPERATION_BLOCKED, res
Beispiel #18
0
 def respawn(self):
     limbo_entity = server.get_alias_entity("limbo")
     # If we're in limbo we should respawn
     if limbo_entity and self.location.parent == limbo_entity:
         respawn_prop = self.props["__respawn"]
         if respawn_prop:
             set_op = Operation("set",
                                Entity(self.id, __respawn=None),
                                to=self.id)
             if hasattr(respawn_prop, "pos") and hasattr(
                     respawn_prop, "loc"):
                 return Operation("move",
                                  Entity(self.id,
                                         pos=respawn_prop.pos,
                                         loc=respawn_prop.loc),
                                  to=self.id), set_op
             elif hasattr(respawn_prop, "spawn") and respawn_prop.spawn:
                 # Respawn in a spawn area
                 respawn_entity = server.get_alias_entity(
                     respawn_prop.spawn)
                 if respawn_entity:
                     location = respawn_entity.location
                     return Operation("move",
                                      Entity(self.id, location=location),
                                      to=self.id), set_op
                 else:
                     print(
                         "Could not get any entity with alias '{}'.".format(
                             respawn_prop.spawn))
Beispiel #19
0
    def tick_operation(self, op):
        res = Oplist()
        if Ticks.verify_tick(self, op, res, self.tick_interval):
            # Make ourselves go away after ten ticks by decreasing our status.
            res.append(
                Operation("set",
                          Entity(self.id, {"status!subtract": 0.1}),
                          to=self.id))

            damage_prop = self.props.damage
            if self.parent and damage_prop is not None:
                # If there's an "entity_ref" prop it's the reference to the actor which caused the poisoning.
                actor_id = self.id
                entity_ref_prop = self.props.entity_ref
                if entity_ref_prop is not None:
                    actor_id = entity_ref_prop["$eid"]

                res.append(
                    Operation('hit',
                              Entity(hit_type="poison",
                                     id=actor_id,
                                     damage=damage_prop),
                              to=self.parent.id))

            return server.OPERATION_HANDLED, res
        return server.OPERATION_IGNORED
Beispiel #20
0
    def equip_melee_weapon(self, me):
        # First check if we're holding a weapon
        attached_current = me.get_attached_entity("hand_primary")
        has_attached = False
        if attached_current:
            has_attached = True
            # Check that the attached entity can be used to strike
            usages = attached_current.get_prop_map("usages")
            if usages:
                for usage, _ in usages.items():
                    if usage in weapon_usages:
                        self.weapon_usage = usage
                        return None
        # Current tool isn't a weapon, or we have nothing attached, try to find one,
        # and if not unequip so we can fight with our fists
        for child in me.entity.contains:
            usages = child.get_prop_map("usages")
            if usages:
                for usage, _ in usages.items():
                    if usage in weapon_usages:
                        self.weapon_usage = usage
                        return Operation("wield", Entity(child.id, attachment="hand_primary"))

        # Couldn't find any weapon to wield, check if we should unwield the current tool so we can fight with our fists
        if has_attached:
            return Operation("wield", Entity(attachment="hand_primary"))

        return None
Beispiel #21
0
    def attack_ranged(self, me):
        enemy = self.get_enemy(me)
        # check that we can reach the target, and if so attack it
        distance = me.steering.distance_to(enemy, ai.EDGE, ai.EDGE)
        if distance is None:
            print("Could not calculate distance.")
            return
        attached_current = me.get_attached_entity("hand_primary")
        tasks_prop = me.entity.get_prop_map('tasks')

        if distance < 50:
            move_to_face = me.face(enemy)

            if attached_current:
                # Check if we're already drawing
                if tasks_prop and "draw" in tasks_prop:
                    # Check if we can release
                    draw_task = tasks_prop["draw"]
                    # print("draw task {}".format(str(draw_task)))
                    usages = draw_task["usages"]
                    for usage in usages:
                        if usage.name == "release":
                            direction = (enemy.location.pos + enemy.location.bbox.center) - (me.entity.location.pos + me.entity.location.bbox.center)
                            direction.normalize()
                            return move_to_face + Operation("use",
                                                            Root(args=[Entity("release", direction=[direction])],
                                                                 id="draw",
                                                                 objtype="task"))

                    return True
                direction = enemy.location.pos - me.entity.location.pos
                direction.normalize()
                return move_to_face + Operation("use", Operation("draw", Entity(attached_current.id, direction=[direction])))
Beispiel #22
0
    def do_strike(self):
        self.usage.actor.send_world(Operation("sight", self.usage.op))

        # If there's a cooldown we need to mark the actor
        Usage.set_cooldown_on_attached(self.usage.tool, self.usage.actor)

        target = self.usage.get_arg("targets", 0)
        if target:
            # Take a swing
            # Check that we can reach the target with our weapon
            extra_reach = 0.0
            if self.usage.tool.props.reach:
                extra_reach = self.usage.tool.props.reach

            if self.usage.actor.can_reach(target, extra_reach):
                damage = 0
                if self.usage.tool.props.damage:
                    damage = self.usage.tool.props.damage
                hit_op = Operation('hit', Entity(damage=damage, hit_type=self.usage.op.parent, id=self.usage.actor.id),
                                   to=target.entity)
                return server.OPERATION_BLOCKED, hit_op
            else:
                return server.OPERATION_BLOCKED, self.usage.actor.client_error(self.usage.op, "Too far away")
        else:
            print("No target")
        return server.OPERATION_BLOCKED
Beispiel #23
0
 def harvest_operation(self, op):
     res = Oplist()
     if self.props.fruits and self.props.fruits > 0 and self.props.fruit_name:
         res.append(
             Operation("create",
                       Entity(parent=self.props.fruit_name, loc=op.id),
                       to=self))
         res.append(
             Operation("set",
                       Entity(self.id, {"fruits!subtract": 1}),
                       to=self))
         res.append(
             Operation(
                 "imaginary",
                 Entity(description="You harvest an {} from the {}.".format(
                     self.props.fruit_name, self.type)),
                 to=op.id,
                 from_=op.id))
     else:
         res.append(
             Operation(
                 "imaginary",
                 Entity(
                     description="There aren't any {}s in this {}.".format(
                         self.props.fruit_name, self.type)),
                 to=op.id,
                 from_=op.id))
     return server.OPERATION_BLOCKED, res
Beispiel #24
0
 def stop_usage(self, args):
     # Check that the usage still is valid
     (valid, _) = self.usage.is_valid()
     self.irrelevant()
     res = Oplist()
     if valid and self.fish_on_hook:
         worms = self.usage.actor.find_in_contains(
             entity_filter.Filter("entity instance_of types.annelid"))
         if len(worms):
             fish_type = self.fishes[randint(0, len(self.fishes) - 1)]
             res.append(
                 Operation("create",
                           Entity(parent=fish_type,
                                  loc=self.usage.actor.id,
                                  mind=None),
                           to=self.usage.tool))
             # Delete the worm
             res.append(
                 Operation("delete", Entity(id=worms[0].id),
                           to=worms[0].id))
             res.append(
                 Operation(
                     "imaginary",
                     Entity(
                         description="You caught a {}.".format(fish_type)),
                     to=self.usage.actor.id,
                     from_=self.usage.actor.id))
     return server.OPERATION_HANDLED, res
Beispiel #25
0
 def event(self, me, op, say):
     object = say[1].word
     thing = me.map.get(object)
     who = me.map.get(op.to)
     if thing is None:
         if object != self.what:
             return Operation("talk",
                              Entity(say=who.name + ", I am not interested in buying your " + str(object) + "."))
         me.goals.insert(0, BuyFrom(self.what, self.cost, op.to))
         return Operation("talk", Entity(say=who.name + " which " + object + " would you like to sell?"))
     if self.what not in thing.type:
         return
     if thing in me.find_thing(self.what):
         return
     # price=me.get_knowledge("price", thing.type[0])
     price = self.cost * int(thing.mass)
     res = Oplist()
     coins = me.find_thing("coin")
     if len(coins) < int(price):
         print("Coins: " + str(len(coins)) + " Cost: " + str(self.cost))
         return Operation("talk", Entity(say="I can't afford any " + self.what + "s at the moment."))
     for i in range(0, int(price)):
         coin = coins[0]
         me.remove_thing(coin)
         res.append(Operation("move", Entity(coin.id, location=Location(who, Point3D(0, 0, 0)))))
     res.append(Operation("talk", Entity(say="Thankyou " + who.name + ", come again.")))
     me.add_thing(thing)
     return res
Beispiel #26
0
    def think_look_operation(self, op):
        """Sends back information about goals. This is mainly to be used for debugging minds.
        If no arguments are specified all goals will be reported, else a match will be done
        using 'index'.
        The information will be sent back as a Think operation wrapping an Info operation.
        
        This method is automatically invoked by the C++ BaseMind code, due to its *_*_operation name.
        """
        think_op = Operation("think")
        goal_info_op = Operation("info")
        goal_infos = []

        if not op.get_args():
            # get all goals
            for (index, goal) in enumerate(self.goals):
                goal_infos.append(Entity(index=index, report=goal.report()))
        else:
            for arg in op.get_args():
                goal = self.goals[arg.index]
                if goal and goal is not None:
                    goal_infos.append(
                        Entity(index=arg.index, report=goal.report()))

        goal_info_op.set_args(goal_infos)
        think_op.set_refno(op.get_serialno())
        think_op.set_args([goal_info_op])
        res = Oplist()
        res = res + think_op
        return res
Beispiel #27
0
def consume(instance):
    """ When drinking the potion the __effects should be applied to the drinker, and the potion destroyed """

    op_list = Oplist()
    op_list += Operation("delete", Entity(instance.tool.id), to=instance.tool)

    effects_prop = instance.tool.props["__effects"]
    if effects_prop is not None:
        for prop_name, effect in effects_prop.items():
            actual_value = effect
            effect_prop = instance.actor.props[prop_name]
            if effect_prop is not None:
                actual_value = effect_prop + effect
            ent = Entity(instance.actor.id)
            ent[str(prop_name)] = actual_value
            op_list += Operation("set", ent, to=instance.actor.id)

    msg_prop = instance.tool.props["__message"]
    if msg_prop is not None:
        op_list += Operation("imaginary",
                             Entity(description=str(msg_prop)),
                             to=instance.actor.id,
                             from_=instance.actor.id)

    return server.OPERATION_BLOCKED, op_list
Beispiel #28
0
 def xp_property_update(self):
     xp = self.get_prop_float("xp")
     if xp is not None:
         level_from_xp = int(math.floor(xp / 100))
         level = self.get_prop_int("level")
         if level is None or level != level_from_xp:
             return Operation("set", Entity(self.id, level=level_from_xp), to=self.id), \
                    Operation("imaginary", Entity(description="You are now at level {}!".format(level_from_xp)), to=self.id, from_=self.id)
Beispiel #29
0
 def burn_operation(self, op):
     ret = Oplist()
     for fuel in self.contains:
         if hasattr(fuel, "burn_speed"):
             ret.append(Operation("burn", op[0], to=fuel))
     if op[0].props.status > 1.0:
         to_ = op[0].id
         ret.append(Operation("extinguish", op[0], to=to_))
     return ret
Beispiel #30
0
 def process(self, me):
     if (self.wbuy in me.things) == 0: return
     if (self.tool in me.things) == 0: return
     tool = me.find_thing(self.tool)[0]
     if not self.wield:
         self.wield = True
         return Operation("wield", Entity(tool.id))
     thing = me.find_thing(self.wbuy)[0]
     return Operation("use", Entity(thing.id, objtype="obj"))
Beispiel #31
0
    def commune_path(self, op):
        """Sends back information about the path."""
        think_op = Operation("think")
        path = []
        my_path = self.path
        # print("path size: " + str(len(my_path)))
        for point in my_path:
            path.append([point.x, point.y, point.z])

        think_op.set_args([Entity(path=path, current_path_index=self.current_path_index)])

        res = Oplist()
        res = res + think_op
        return res
Beispiel #32
0
    def think_look_operation(self, op):
        """Sends back information about goals. This is mainly to be used for debugging minds.
        If no arguments are specified all goals will be reported, else a match will be done
        using 'index'.
        The information will be sent back as a Think operation wrapping an Info operation.
        
        This method is automatically invoked by the C++ BaseMind code, due to its *_*_operation name.
        """
        think_op = Operation("think")
        goal_info_op = Operation("info")
        goal_infos = []

        if not op.get_args():
            # get all goals
            for (index, goal) in enumerate(self.goals):
                goal_infos.append(Entity(index=index, report=goal.report()))
        else:
            for arg in op.get_args():
                goal = self.goals[arg.index]
                if goal and goal is not None:
                    goal_infos.append(Entity(index=arg.index, report=goal.report()))

        goal_info_op.set_args(goal_infos)
        think_op.set_refno(op.get_serialno())
        think_op.set_args([goal_info_op])
        res = Oplist()
        res = res + think_op
        return res
Beispiel #33
0
    def commune_all_thoughts(self, op, name):
        """Sends back information on all thoughts. This includes knowledge and goals, 
        as well as known things.
        The thoughts will be sent back as a "think" operation, wrapping a Set operation, in a manner such that if the
        same think operation is sent back to the mind all thoughts will be restored. In
        this way the mind can support server side persistence of its thoughts.
        A name can optionally be supplied, which will be set on the Set operation.
        """
        think_op = Operation("think")
        set_op = Operation("set")
        thoughts = []

        for what in sorted(self.knowledge.knowings.keys()):
            d = self.knowledge.knowings[what]
            for key in sorted(d):
                if what != "goal":
                    object_val = d[key]
                    if type(object_val) is Location:
                        # Serialize Location as tuple, with parent if available
                        if object_val.parent is None:
                            location = object_val.position
                        else:
                            location = ("$eid:" + object_val.parent.id, object_val.pos)
                        goal_object = str(location)
                    else:
                        goal_object = str(d[key])

                    thoughts.append(Entity(predicate=what, subject=str(key), object=goal_object))

        if len(self.things) > 0:
            things = {}
            for (id, thinglist) in sorted(self.things.items()):
                idlist = []
                for thing in thinglist:
                    idlist.append(thing.id)
                things[id] = idlist
            thoughts.append(Entity(things=things))

        if len(self.pending_things) > 0:
            thoughts.append(Entity(pending_things=self.pending_things))

        set_op.set_args(thoughts)
        think_op.set_args([set_op])
        if not op.is_default_serialno():
            think_op.set_refno(op.get_serialno())
        if name:
            set_op.set_name(name)
        res = Oplist()
        res = res + think_op
        return res
Beispiel #34
0
 def tick_operation(self, op):
     """periodically reassess situation
     
     This method is automatically invoked by the C++ BaseMind code, due to its *_operation name.
     """
     args = op.get_args()
     if len(args) != 0:
         if args[0].name == "think":
             # It's a "thinking" op, which is the base of the AI behaviour.
             # At regular intervals the AI needs to assess its goals; this is done through "thinking" ops.
             op_tick = Operation("tick")
             # just copy the args from the previous tick
             op_tick.set_args(args)
             op_tick.set_future_seconds(const.basic_tick + self.jitter)
             op_tick.set_to(self.id)
             for t in self.pending_things:
                 thing = self.map.get(t)
                 if thing and thing.type[0]:
                     self.add_thing(thing)
             self.pending_things = []
             result = self.think()
             if self.message_queue:
                 result = self.message_queue + result
                 self.message_queue = None
             return op_tick + result
Beispiel #35
0
    def commune_goals(self, op, goal_entity):
        """Sends back information about goals only."""
        think_op = Operation("think")
        set_op = Operation("set")
        thoughts = []

        # It's important that the order of the goals is retained
        for goal in self.goals:
            if hasattr(goal, "str"):
                goal_string = goal.str
            else:
                goal_string = goal.__class__.__name__

            thoughts.append(Entity(goal=goal_string, id=goal_string))

        set_op.set_args(thoughts)
        think_op.set_args([set_op])
        think_op.set_refno(op.get_serialno())
        res = Oplist()
        res = res + think_op
        return res
Beispiel #36
0
    def setup_operation(self, op):
        """called once by world after object has been made
           send first tick operation to object
           
        This method is automatically invoked by the C++ BaseMind code, due to its *_operation name."""
        # CHEAT!: add memory, etc... initialization (or some of it to __init__)

        # Setup a tick operation for thinking
        think_tick_op = Operation("tick")
        think_tick_op.set_to(self.id)
        think_tick_op.set_args([Entity(name="think")])

        # Setup a tick operation for moving
        move_tick_op = Operation("tick")
        think_tick_op.set_to(self.id)
        move_tick_op.set_args([Entity(name="move")])
        move_tick_op.set_future_seconds(0.2)

        return Operation("look") + think_tick_op + move_tick_op