FIFE forums

Please login or register.

Login with username, password and session length
Advanced search  

News:

FIFE 0.4.0 has been released on 15th of January, 2017!

Pages: 1 [2] 3

Author Topic: Jim's problems  (Read 7568 times)

Jim

  • Newbie
  • Posts: 24
    • View Profile
Re: Jim's problems
« Reply #15 on: July 08, 2013, 08:15:52 am »

Well, I've made my first version of the amazing fiferpg demo, "the enhanced edition". You can now pick up gold, open your inventory and see the gold in it, click on it to remove it from your inventory and open the chest and compare inventories with it in a friendly fashion. You can also have a short dialogue with David, though that's still a bit... odd. There's even a console where the descriptions of the "inspect" action neatly appear. Which brings me to the three things I've really not managed to figure out how to accomplish:

1: I found out how to make a list of labeled inventory items in pychan where if you click on a specific label, it removes it. But as far as I can tell, you can only do this using the generic widget like in the dynamic widgets demo. Because if you don't, then it's impossible to have it tell which label you've clicked (just that you've clicked some label). Now, the problem with this is that I've noticed that you can't carry over variables with this generic widget, i.e. you can do:

item.capture(self.drop) [with "item" being the label, and "drop" being the item removing function]

but you can't do:

item.capture(self.drop(entity)) or item.capture(lambda: self.drop(entity))

and still use the generic widget. While this isn't a problem with, say, dropping an item, it seems to make taking an item from one container to another impossible. Is there maybe another way to tell exactly which label is being "captured"?

2: A more fiferpg specific question: after removing the gold from the inventory I want it to appear on the ground; I'm sure I can create an instance of gold easily, but what I should actually be doing is create a gold entity instead, right? But how would I do that? I know there's a get_or_create_entity function, but that doesn't seem to do anything even when I do something like update_entities after that.

3: Another fiferpg specific question: I have no clue how to make it so that the possible responses of the dialogue appear as the responses themselves, rather than the keys of the dictionary, so in the dialogue I have now, the responses appear as "no_introduce" etc. I probably just don't understand dictionaries well enough, because I assumed the keys would "point" to the text itself, but instead they point to a certain address in the code, which I have no idea how to use.

Again, sorry if one/some/all of these questions is/are really stupid.
« Last Edit: July 08, 2013, 08:20:12 am by Jim »
Logged

Beliar

  • Newbie
  • Posts: 25
    • View Profile
Re: Jim's problems
« Reply #16 on: July 08, 2013, 04:18:53 pm »

Hi Jim,

for the second question, it should be enough to set the Map and Position fields of the Agent component of the gold entity.

for the third, you should read the Dialogue tutorial

For the first you will have to wait for someone who knows more about the widgets than i do.
Logged

Jim

  • Newbie
  • Posts: 24
    • View Profile
Re: Jim's problems
« Reply #17 on: July 09, 2013, 10:40:52 am »

Thanks again! I've already gone over all your tutorials (they're very nice by the way, would be cool if fife had the same type of introductory tutorials), but I'll go over the dialogue one again when I get back from holidays. Like I said, it's probably that I just don't know yet how to handle dictionaries properly; I'll probably just have to go over some general Python tutorials again too.
Logged

Beliar

  • Newbie
  • Posts: 25
    • View Profile
Re: Jim's problems
« Reply #18 on: July 10, 2013, 10:42:57 am »

Hi Jim,

seems like I wrote to fast, the tutorial actually would not help with your problem. The way you iterate over the dictionary will only return the keys of it, not the items, which are dialogue sections. So, yeah, you probably should look at a Tutorial about python dictionaries.

[Edit]
Also:

For your second question, I pushed a commit that fixes a bug where that would have been impossible.
You will have to set the "new_map", "new_position", and "new_layer" fields of the Agent component.
You could just use the "map", "position", and "layer" fields of the Player Agent component for these.
« Last Edit: July 10, 2013, 01:56:44 pm by Beliar »
Logged

Jim

  • Newbie
  • Posts: 24
    • View Profile
Re: Jim's problems
« Reply #19 on: August 14, 2013, 04:44:52 pm »

I'm back and ready to be annoying again!

So, two of the three problems I've had still completely elude me. Good news is I finally figured out how to do the fiferpg dialogue thing properly, though I'm admittedly not entirely sure whether it's an unnecessary workaround or not, because I'm still basically just using the keys in the dictionary and not the values. Works fine though, so I'm happy.

The pychan problem is still utterly baffling to me, no matter how many different approaches I try. Maybe I'll just ask it on irc at some point in case nobody responds (unless they're all purposely ignoring me of course). To rephrase the problem a bit: when you populate lists of dialogue options or inventory items or whatever, then you usually need to know which one the player clicked on. For some reason I can't figure out, this is seemingly only possible without carrying over any additional arguments. I.e., to use the way I did the dialogue thing as an example:

        for possible_response in dlg.possible_responses:
            response = pychan.widgets.Label(max_size=(200,1000),wrap_text=True)
            response.text = dlg.dialogue.sections["%s" % possible_response].text
            self.responsesbox.addChild( response )
            response.capture(self.respond)

This works fine, as long as you use a "generic widget" in the called function. But the moment you don't use this generic widget, and try to carry over any information (e.g. use "response.capture(lambda: self.respond(response))" then suddenly the event mapping goes all wrong and pychan can't tell anymore which label in the list you've clicked on (I think it automatically assumes it's the last one). Again, does anyone happen to know how to avoid this?

Quote
For your second question, I pushed a commit that fixes a bug where that would have been impossible.
You will have to set the "new_map", "new_position", and "new_layer" fields of the Agent component.
You could just use the "map", "position", and "layer" fields of the Player Agent component for these.

I still can't get it to work I'm afraid. When I do this (with your commit downloaded of course):

        thing.Agent.new_map = player.Agent.map
        thing.Agent.new_layer = player.Agent.layer
        thing.Agent.new_position = player.Agent.position

Then I get this error:

  Traceback (most recent call last):
  File "C:\Program Files (x86)\FIFE\demos\fiferpg demo\run.py", line 266, in <module> main()
  File "C:\Program Files (x86)\FIFE\demos\fiferpg demo\run.py", line 251, in main app.run()
  File "C:\Python27\lib\site-packages\fife\extensions\basicapplication.py", line 197, in run retval = self.mainLoop()
  File "C:\Python27\lib\site-packages\fife\extensions\basicapplication.py", line 222, in mainLoop  self._pump()
  File "C:\Python27\lib\site-packages\bGrease\grease_fife\mode.py", line 54, in _pump  self.pump(delta_time)
  File "C:\Python27\lib\site-packages\fife_rpg\rpg_application.py", line 833, in pump self.current_map.update_entitities_agent()
  File "C:\Python27\lib\site-packages\fife_rpg\map.py", line 209, in update_entitities_agent location = fifeagent.behaviour.location
  AttributeError: 'NoneType' object has no attribute 'location'

I tried some (probably stupid) workarounds of forcibly giving the Gold agent a behavior (with the idea of that giving him the error-inducing behavior.location as well), but that just resulted in nothing happening. No clue what's going wrong.


 
Logged

Beliar

  • Newbie
  • Posts: 25
    • View Profile
Re: Jim's problems
« Reply #20 on: August 15, 2013, 02:54:40 am »

Hmm, could you give me the complete code from run.py and demo_game_scene.py?

And to what commit did you update? You need to have at least this one: https://github.com/fife-rpg/fife-rpg/commit/d4d15bf9e107a07b04f42aaf2b77f223a9e8ea39

Although even without that I would not get the error you get, so i'd be best to have the code to check if you try to do things differently than me.
Logged

Jim

  • Newbie
  • Posts: 24
    • View Profile
Re: Jim's problems
« Reply #21 on: August 15, 2013, 05:41:30 am »

Of course! Here it is. These are all the files I've changed/added (plus run.py and actions.py which I didn't change at all). Worked exactly like my own when I overwrote the original fiferpg demo with these files.

And yeah, I just updated that commit (I haven't updated any of the other ones since then).
Logged

Beliar

  • Newbie
  • Posts: 25
    • View Profile
Re: Jim's problems
« Reply #22 on: August 15, 2013, 06:23:34 am »

Hmm, this is really strange. With that code you sent it works without problems here.

I have uploaded a complete working version here: https://dl.dropboxusercontent.com/u/29933429/programming/fiferpg%20demo.7z (May take a few minutes before its available)
Logged

Jim

  • Newbie
  • Posts: 24
    • View Profile
Re: Jim's problems
« Reply #23 on: August 15, 2013, 08:12:41 am »

Hmmm... I must be doing something seriously wrong. I downloaded your version of the demo, which still had the same problem, so I thought I'd better just update to the latest version (downloading the batch, run setup.py). Then I got this error right off the bat:

Traceback (most recent call last):
  File "C:\Program Files (x86)\FIFE\demos\fiferpg demo\run.py", line 100, in <module>
    main()
  File "C:\Program Files (x86)\FIFE\demos\fiferpg demo\run.py", line 70, in main
    app.switch_map("Level1")
  File "C:\Python27\lib\site-packages\fife_rpg\rpg_application.py", line 450, in switch_map
    callback(old_map, name)
TypeError: on_map_switched() takes exactly 1 argument (3 given)

Then reinstalled, feeling I'd done the exact same thing, and now the error has changed (slightly) to:

Traceback (most recent call last):
  File "C:\Program Files (x86)\FIFE\demos\fiferpg demo1\run.py", line 266, in <module>
    main()
  File "C:\Program Files (x86)\FIFE\demos\fiferpg demo1\run.py", line 70, in main
    app.switch_map("Level1")
  File "C:\Python27\lib\site-packages\fife_rpg\rpg_application.py", line 446, in switch_map
    self.load_map(name)
  File "C:\Python27\lib\site-packages\fife_rpg\rpg_application.py", line 422, in load_map
    game_map = Map(fife_map, name, camera, regions, self)
TypeError: __init__() takes exactly 5 arguments (6 given)


Ugh. I'll just try reinstalling FIFE as a whole in a while (it isn't a problem that I'm using the latest regular FIFE release and not the source, right?).
Logged

Beliar

  • Newbie
  • Posts: 25
    • View Profile
Re: Jim's problems
« Reply #24 on: August 15, 2013, 08:28:59 am »

The first error you are getting is because i made some breaking changes in the last week, on_map_switched now should take two arguments, old_map and new_map, wich are the names of the old and new map. The second one should not happen if FIFErpg is correctly installed as it seems it uses files from two different versions.

And FIFErpg does not work the the current fife from source, only the latest fife release(0.3.4) and the current source of the upcoming release(0.3.5).

[edit]
Also, you would need to change the main function of run.py to this:

Code: [Select]
def main():
    global world
    PrintAction.register()
   
    app = RPGApplication(TDS)
    app.load_components("combined.yaml")
    app.register_components()
    app.load_actions("combined.yaml")
    app.register_actions()
    app.load_systems("combined.yaml")
    app.register_systems()
    app.load_behaviours("combined.yaml")
    app.register_behaviours();
    app.create_world()
    world = app.world
    view = GameSceneView(app)
    controller = DemoController(view, app, outliner=DemoOutliner())
    controller.listener.is_outlined = True
    controller.outliner.outline_ignore.append("PlayerCharacter")
    controller.outliner.outline_data = (173, 255, 47, 2)
    app.load_maps()
    world.read_object_db()
    world.import_agent_objects()
    world.load_and_create_entities()
    app.switch_map("Level1")
   
    script_system = getattr(world.systems, "scripting")
    statistic_system = world.systems.character_statistics
    statistic_system.load_statistics_from_file("statistics.yaml")
    player = app.current_map["PlayerCharacter"]
    player.CharacterStatistics.gender = "male"
    player.CharacterStatistics.primary_stats["ST"] = 75
    player.CharacterStatistics.primary_stats["VT"] = 60
    app.push_mode(controller)
    app.run()
« Last Edit: August 15, 2013, 08:33:03 am by Beliar »
Logged

Jim

  • Newbie
  • Posts: 24
    • View Profile
Re: Jim's problems
« Reply #25 on: August 15, 2013, 10:06:37 am »

Got it to work! Thanks immeasurably for the help and patience. I was such an idiot for forgetting that updating to the latest fiferpg version would completely mess up the outdated demo.

Edit: incidentally, if somebody could also find the patience to help out with the non-fiferpg-related widget problem, then that'd be great as well of course.  ;)

Edit: Ah, think I finally figured it out. I should have gone with the Listbox dealio.
« Last Edit: August 15, 2013, 06:03:49 pm by Jim »
Logged

Beliar

  • Newbie
  • Posts: 25
    • View Profile
Re: Jim's problems
« Reply #26 on: August 16, 2013, 03:49:23 am »

Good that its working for you.

I just noticed that i forgot, that the dialogue conditons work differently now, for the example dialogue replace the file contents with this, if you use the latest fiferpg source:


Code: [Select]
# This is an example dialogue file

Greetings:
 
  - talker: David
    text: Hey, I've seen you before, haven't I?
    conditions: Agent.knows(entities.David, "PlayerCharacter")
    responses:
      - "yes"
      - yes_bye
         
  - talker: David
    text: Hi, I don't know you, do I?
    conditions: not Agent.knows(entities.David, "PlayerCharacter")
    responses:
      - no_introduce
      - no_bye

Sections:
  no_introduce:
    talker: PlayerCharacter
    text: No. I am {DialogueTalker.Description.view_name}
    commands:
        - Name: AddKnowledge
          Args: [David, PlayerCharacter]
    responses:
      - introduce_reply
  no_bye:
    talker: PlayerCharacter
    text: No, and I don't want to change that.
  "yes":
    talker: PlayerCharacter
    text: Yes, I am {DialogueTalker.Description.view_name}. Remember?
    responses:
      - yes_reply
  yes_bye:
     talker: PlayerCharacter
     text: Yes, but I am in a hurry. Bye.
  introduce_reply:
    talker: David
    text: Nice to meet you, my name is {DialogueTalker.Description.real_name}
    commands:
      - Name: SetComponentValue
        Args: [David, Description, view_name, "{DialogueTalker.Description.real_name}"]
      - Name: AddKnowledge
        Args: [PlayerCharacter, David]
  yes_reply:
    talker: David
    text: Ah, right.

I still need to update the tutorials for the changes.
Logged

Jim

  • Newbie
  • Posts: 24
    • View Profile
Re: Jim's problems
« Reply #27 on: July 05, 2014, 12:46:30 pm »

Hey Beliar, thought I'd try and update the demo to 0.2 after almost a year long hiatus, so if you're still up for answering my stupid questions that'd be great!

Code: [Select]
Traceback (most recent call last):
  File "C:\Program Files (x86)\FIFE\demos\fiferpg demo\run.py", line 100, in <module>
    main()
  File "C:\Program Files (x86)\FIFE\demos\fiferpg demo\run.py", line 70, in main
    app.switch_map("Level1")
  File "C:\Python27\lib\site-packages\fife_rpg\rpg_application.py", line 450, in switch_map
    callback(old_map, name)
TypeError: on_map_switched() takes exactly 1 argument (3 given)

The error you are getting is because i made some breaking changes in the last week, on_map_switched now should take two arguments, old_map and new_map, wich are the names of the old and new map.

This still has me completely stumped. If this is the case, then why is the error:

Code: [Select]
TypeError: on_map_switched() takes exactly 1 argument (3 given)
shouldn't 3 arguments given be the right amount given that:

Code: [Select]
on_map_switched(self, new_map, old_map)
The demo runs fine when I remove the last two arguments required by on_map_switched and the two provided by the callback in switch_map, so I haven't a clue what's going wrong.
Logged

Beliar

  • Newbie
  • Posts: 25
    • View Profile
Re: Jim's problems
« Reply #28 on: July 06, 2014, 12:44:06 am »

Hi, i am not completely sure, but I think the problem was, that fife-rpg passes 2 arguments to the function. But the method expects None (self is automatically passed since its a class method). So the method has to be rewritten to accept the 2 additional arguments.

If that is not working then I need the source code.
Logged

Jim

  • Newbie
  • Posts: 24
    • View Profile
Re: Jim's problems
« Reply #29 on: July 06, 2014, 04:54:28 am »

Sorry, but still can't figure out for the life of me what exactly I'd have to change in the last method to make it work.

Code: (demo's run.py) [Select]

import os
from fife import fife
from fife.extensions.fife_settings import Setting
from fife_rpg import GameSceneView
from fife_rpg import RPGApplication
from fife_rpg.game_scene import SimpleOutliner
from fife_rpg.components import ComponentManager
from fife_rpg.actions import ActionManager
from demo_game_scene import DemoController
from actions import PrintAction

TDS = Setting(app_name="rpg", settings_file="./settings.xml")
world = None
   
def create_entity_dictionary(entity):
    entity_dict = {}
    components_data = entity_dict["components"] = {}
    components = ComponentManager.get_components()
    for name, component in components.iteritems():
        component_values = getattr(entity, name)
        if component_values:
            component_data = None
            for field in component.saveable_fields:               
                if not component_data:
                    component_data = components_data[name] = {}               
                component_data[field] = getattr(component_values, field)
   
    return entity_dict


class DemoOutliner(SimpleOutliner):
   
    def get_data(self, world, identifier):
        if identifier == "PlayerCharacter":
            return (0, 0, 255, 1)
        else:
            return SimpleOutliner.get_data(self, world, identifier)
   
def main():
    global world
    PrintAction.register()
   
    app = RPGApplication(TDS)
    app.load_components("combined.yaml")
    app.register_components()
    app.load_actions("combined.yaml")
    app.register_actions()
    app.load_systems("combined.yaml")
    app.register_systems()
    app.load_behaviours("combined.yaml")
    app.register_behaviours();
    app.create_world()
    world = app.world
    view = GameSceneView(app)
    controller = DemoController(view, app, outliner=DemoOutliner())
    controller.listener.is_outlined = True
    controller.outliner.outline_ignore.append("PlayerCharacter")
    controller.outliner.outline_data = (173, 255, 47, 2)
    app.load_maps()
    world.read_object_db()
    world.import_agent_objects()
    world.load_and_create_entities()
    app.switch_map("Level1")
   
    script_system = getattr(world.systems, "scripting")
    statistic_system = world.systems.character_statistics
    statistic_system.load_statistics_from_file("statistics.yaml")
    player = app.current_map["PlayerCharacter"]
    player.CharacterStatistics.gender = "male"
    player.CharacterStatistics.primary_stats["ST"] = 75
    player.CharacterStatistics.primary_stats["CO"] = 60
    app.push_mode(controller)
    app.run()

Code: (rpg_application.py) [Select]
def switch_map(self, name):
        """Switches to the given map.

        Args:
            name: The name of the map
        """
        old_map = None
        if self.__current_map:
            old_map = self.__current_map.name
            self.__current_map.deactivate()
            self.__current_map = None
        if name is None:
            return
        if name in self.__maps:
            self.load_map(name)
            self.__current_map = self.maps[name]
            self.__current_map.activate()
            for callback in self.__map_switched_callbacks:
                callback(old_map, name)
        else:
            raise LookupError("The map with the name '%s' cannot be found"
                        % (name))

Code: (scriptingsystem.py) [Select]
    def on_map_switched(self, old_map, new_map):
        """Called when the application switches to a new map

        Arguments:

            old_map: The name of the old map

            new_map: The name of the new map
        """
        if GameVariables.registered_as:
            getattr(self.world.systems, GameVariables.registered_as).step(0)
        for script in self.__scripts.itervalues():
            if not "map_switched" in script.__dict__:
                continue
            script_globals = self.prepare_globals()
            script.__dict__.update(script_globals)
            script.map_switched(old_map, new_map)
« Last Edit: July 06, 2014, 06:28:20 am by Jim »
Logged
Pages: 1 [2] 3