+ # get and interact with objects and characters if present in a particular row/col
+ def level_interact (self, level, row, col):
+ objs = []
+ # get list of objects at current location
+ for obj in level.objects:
+ if obj.row == row and obj.col == col:
+ objs.append (obj)
+
+ notblock = self.interact_objects (level, objs)
+
+ # get npc at current location
+ current_npc = None
+ for npc in level.npcs:
+ if npc.row == row and npc.col == col:
+ current_npc = npc
+ break
+
+ # npcs always block the tile. So return false if there is an NPC
+ # at the location
+ if current_npc is not None:
+ self.interact_npc (current_npc)
+ return False
+
+ return notblock
+
+ # interaction with npcs
+ def interact_npc (self, npc):
+ # interact with NPC and get the response ID
+ # if the NPC is Bulisa
+
+ # if the NPC is dead cannot talk with the NPC
+ if npc.is_dead is True:
+ self.status_message = "%s is dead! RIP..." % npc.charname
+ return
+
+ if isinstance (npc, npcs.Bulisa):
+ # interact
+ self.interact_npc_bulisa (npc)
+
+ # interact with NPC Bulisa
+ def interact_npc_bulisa (self, npc):
+ # set initial response ID to none
+ resp_id = None
+ # not yet started mission drawing water from well and not refused it
+ if (gamestate.mission_bulisa_water_from_well is False
+ and gamestate.mission_bulisa_water_from_well_refused is False):
+ # set the current dialogue
+ npc.currentdialog = 0
+ # get the response ID
+ resp_id = utility.dialogue_play (self.screen, self.img_dialogue, npc, self.butaba.portrait, 0, 90)
+ if (gamestate.mission_bulisa_water_from_well_refused is True and
+ gamestate.mission_bulisa_water_from_well is False):
+ # set the current dialog
+ npc.currentdialog = 2
+ resp_id = utility.dialogue_play (self.screen, self.img_dialogue, npc, self.butaba.portrait, 0, 90)
+ # mission accepted but not completed - check if completed and set value
+ # accordingly
+ elif (gamestate.mission_bulisa_water_from_well is True
+ and gamestate.mission_bulisa_water_from_well_complete is False):
+ for invobj in self.butaba.objects:
+ if isinstance (invobj, gameobjects.Bucket) is True:
+ if invobj.liquid == "water":
+ gamestate.mission_bulisa_water_from_well_complete = True
+ self.butaba.objects.remove (invobj)
+ key1 = gameobjects.Key (5, 3, "a chest key", self.img_key2, constants.KEY_CHEST1)
+ self.butaba.objects.append (key1)
+
+ break
+ # water mission is not completed yet
+ if gamestate.mission_bulisa_water_from_well_complete is False:
+ npc.currentdialog = 1
+ else:
+ npc.currentdialog = 3
+
+ # get the response ID
+ resp_id = utility.dialogue_play (self.screen, self.img_dialogue, npc, self.butaba.portrait, 0, 90)
+
+ # if response ID is 12, then drawing water from well mission is refused
+ if resp_id == "12" or resp_id == "18":
+ gamestate.mission_bulisa_water_from_well_refused = True
+ # if response ID is 13: that is accepted the drawing water from well mission begins
+ if resp_id == "13" or resp_id == "17":
+ gamestate.mission_bulisa_water_from_well = True
+ # if response ID is none
+ elif resp_id is None:
+ self.status_message = "You cannot initiate a conversation with %s" % npc.charname
+
+ # interaction with objects
+ def interact_objects (self, container, objs):
+ # overall flag for blocking/non-blocking objects
+ notblock = True
+
+ # now perform interaction
+ for obj in objs:
+ # run the object interact function
+ if obj.interact () is False:
+ notblock = False
+ # if object can be picked up ask
+ if obj.can_pickup is True:
+ ans = utility.ask_question (self.screen, "Found %s." % obj.text, ["Pick up", obj.use_str, "Ignore"], self.img_menu)
+ # if the answer is "pick up"
+ if ans == 1:
+ self.pickup_object (container, obj)
+ elif ans == 2:
+ # use the object according to its type
+ self.use_object (container, obj)
+ # if it cannot be picked up, try to use it anyway
+ else:
+ ans = utility.ask_question (self.screen, "Found %s." % obj.text, [obj.use_str, "Ignore"], self.img_menu)
+ if ans == 1:
+ self.use_object (container, obj)
+
+ return notblock
+
+ # transfer an object from one container to another
+ # container must have an objects list
+ def transfer_object (self, source, obj, dest):
+ # remove object from source
+ source.objects.remove (obj)
+ # add object to destination
+ dest.objects.append (obj)
+
+ # picking up an object
+ def pickup_object (self, container, obj):
+ # only if object can be picked up, pick it up or use it
+ if obj.can_pickup is True:
+ # check if the inventory is full
+ if len (self.butaba.objects) >= constants.MAXITEMS:
+ self.status_message = "Cannot pick up item. Inventory full"
+ else:
+ # add item to inventory
+ self.transfer_object (container, obj, self.butaba)
+
+ self.status_message = "You picked up %s" % obj.text
+
+ # this method uses the object first by calling the object use () method
+ # and then performing specific actions as necessary
+ def use_object (self, container, obj):
+ # if the object is a health potion
+ if isinstance (obj, gameobjects.HealthPotion) is True:
+ if self.butaba.health < constants.MAXHEALTH:
+ obj.use (self.butaba)
+ container.objects.remove (obj)
+ self.status_message = "You gained health"
+ else:
+ self.status_message = "You already have maximum health!"
+ # if the object is a chest
+ elif isinstance (obj, gameobjects.Chest) is True:
+ # if chest is locked, try to open it
+ if obj.locked is True:
+ # try opening the chest with every item 9the use () function
+ # of the chest determines if item is a key anyway
+ fittedkey = None
+ for invobj in self.butaba.objects:
+ fittedkey = obj.use (invobj)
+ # if a key fits
+ if fittedkey is not None:
+ break
+ # if no key found
+ if fittedkey is None:
+ self.status_message = "No key found to open %s" % obj.text
+ # chest successfully unlocked
+ else:
+ self.status_message = "You unlocked the %s" % obj.text
+ # remove the key from Butaba
+ self.butaba.objects.remove (fittedkey)
+ # add an experience point for unlocking chest subject
+ # to a limit of KNOWLEDGEMAX_CHEST_UNLOCK
+ if self.butaba.experience < constants.KNOWLEDGEMAX_CHEST_UNLOCK:
+ self.butaba.experience += 1
+ self.status_message += " and gained experience!"
+ # display the contents of the chest
+ else:
+ item = utility.get_container_object (self.screen, obj, self.img_chestbg, 30)
+ if item is not None:
+ self.interact_objects (obj, [ item, ])
+
+ # if the object is gold coins
+ elif isinstance (obj, gameobjects.GoldCoins) is True:
+ obj.use (self.butaba)
+ self.status_message = "You picked up %d gold." % obj.value
+ # remove the gold coins after adding it to Butaba's gold
+ container.objects.remove (obj)
+ # using a bucket means emptying it
+ elif isinstance (obj, gameobjects.Bucket) is True:
+ if obj.liquid is not None:
+ self.status_message = "You emptied the bucket of %s" % obj.liquid
+ obj.use (self.butaba)
+ else:
+ self.status_message = "Bucket is already empty."
+ # using a well
+ elif isinstance (obj, gameobjects.Well) is True:
+ # if the well is not dry, i.e. it has some liquid
+ if obj.liquid is not None:
+ # search butaba inventory for an empty bucket
+ for invobj in self.butaba.objects:
+ # bucket found, now check if it is empty
+ if isinstance (invobj, gameobjects.Bucket) is True:
+ # if empty fill it
+ if invobj.liquid is None:
+ obj.use (invobj)
+ self.status_message = "You successfully filled the %s with %s" % (invobj.text, obj.liquid)
+ if self.butaba.strength < constants.STRENGTHMAX_DRAW_WELL_WATER:
+ self.butaba.strength += 2
+ self.status_message += " and gained strength!"
+ return
+ self.status_message = "You have no empty bucket to draw %s with!" % obj.liquid
+ else:
+ self.status_message = "%s appears to be dry!" % obj.text
+