bar and bartender conversation

Talk among developers, and propose and discuss general development planning/tackling/etc... feature in this forum.
Post Reply
rockstar
Bounty Hunter
Bounty Hunter
Posts: 164
Joined: Tue Nov 01, 2005 8:19 am
Location: germany
Contact:

bar and bartender conversation

Post by rockstar »

I hope I catched the right forum here.

At the moment I'm working on a german translation of the bartender.py. In association with this work I had a look on how's the conversation text is displayed in the current version of VS. The text small displayed on the screen top only turned up quite unsatisfying to me . I was wondering if it might be more advantageous when the text would be displayed in a similar window like the ones used for mission terminal or upgrade and so on. A window overlaying the bar background image. Like this:

Image
Be lenient with my english skills... still using a dictonary. http://dict.tu-chemnitz.de/
charlieg
Elite Mercenary
Elite Mercenary
Posts: 1329
Joined: Thu Mar 27, 2003 11:51 pm
Location: Manchester, UK
Contact:

Post by charlieg »

Or maybe even a pretty speech bubble.

I'd focus on the 0.5x version for feature requests.
Free Gamer - free software games compendium and commentary!
FreeGameDev forum - open source game development community
klauss
Elite
Elite
Posts: 7243
Joined: Mon Apr 18, 2005 2:40 pm
Location: LS87, Buenos Aires, República Argentina

Post by klauss »

It's quite possible with the current framework.
Sadly I have little time to try stuff.

Basically, you'd add a textbox in the right location through python scripting, and set the text there. I think you can give transparent backgrounds to text boxes, but even if you can't, you can add a transparent sprite.

Have a look at how PR's guilds work.
I'll try to work up something like that for the python GUI framework I'm working on, but that won't happen soon - I have this week pretty much eaten by school stuff, even though we're officially on "vacation" ("between semesters", northern people would say).
Oíd mortales, el grito sagrado...
Call me "Menes, lord of Cats"
Wing Commander Universe
Oblivion
Artisan Extraordinaire
Artisan Extraordinaire
Posts: 1269
Joined: Tue Mar 21, 2006 10:55 am
Location: Philippines

Post by Oblivion »

I proposed something similar once as replacement for thw awkward Bar interface.

I dont speak python. hisss. :lol: But I'll try to see if I too could help out here.

The mock-up by rockstar looks way better than the current interface. If it's not too difficult, i'll try it. :wink:
A Step Into Oblivion

Dreams of things that will never be,
Songs of thoughts only I can hear,
Leave me be to sleep forever,
To dream my dreams,
And sing my hymns,
Of things that will never be...
ace123
Lead Network Developer
Lead Network Developer
Posts: 2560
Joined: Sun Jan 12, 2003 9:13 am
Location: Palo Alto CA
Contact:

Post by ace123 »

So basically you can modify the function Speak() in bases/bartender.py

Then, replace the Base.Message calls to instead call a new function like DisplayBarMessage, or even move it into a common library that could also be used by fixers.

The DisplayBarMessage would make a call to a function:

Code: Select all

void TextBox (int room, std::string ind, std::string text, float x, float y, Vector widheimult, Vector backcol, float backalp, Vector forecol)
Then, it could make a link and display an OK button picture in the same place.

Alternatively, the C code could replace the void Message(std::string text) function with something a little bit more advanced, but I would go with a simple and easy python solution for now.
Oblivion
Artisan Extraordinaire
Artisan Extraordinaire
Posts: 1269
Joined: Tue Mar 21, 2006 10:55 am
Location: Philippines

Post by Oblivion »

oof. That looks too much like greek.

I speak pidgin C so maybe I'll take a look at bases/bartender.py

I doubt I could change it tho

:(
A Step Into Oblivion

Dreams of things that will never be,
Songs of thoughts only I can hear,
Leave me be to sleep forever,
To dream my dreams,
And sing my hymns,
Of things that will never be...
ace123
Lead Network Developer
Lead Network Developer
Posts: 2560
Joined: Sun Jan 12, 2003 9:13 am
Location: Palo Alto CA
Contact:

Post by ace123 »

That C++ code is exported directly to python.
So when I say:

Code: Select all

void TextBox (int room, std::string ind, std::string text, float x, float y, Vector widheimult, Vector backcol, float backalp, Vector forecol)
I mean the same thing in python:

Code: Select all

Base.TextBox(roomNumber, "textbox1", "Hello, young traveler...",
xCoord, yCoord, (width, height, 1.0), (.2,.2,.2), .6, (.2,.8,.4))
so the difference is that instead of calling the function:

Code: Select all

Base.Message(myBarText)
you would create a textbox like above, except replace the "Hello young traveler" with the variable passed in, and replace the roomNumber with "Base.GetCurRoom()" or something like that.

Of course you would have to experiment with x, y, width and height to make the box the right size.
geoscope
Bounty Hunter
Bounty Hunter
Posts: 205
Joined: Thu Jun 29, 2006 1:58 am
Contact:

Post by geoscope »

I'm just gettting up to speed on Python, with a few small scripts. But, I might take a crack at it, over the next 2-3 days.

Edit: Granted I'm new to the Python, but as I understood it, a python import statement can import a file that is in the current directory or in PYTHONPATH.
But for "import Base" I can't find the Base.py file. In fact using "find | grep Base" I couldn't find any file named Base with any extension, in either of the SVN data4.x or vegastrike directories. Am I missing something? Is the "import Base" statement importing from a C Class by some means I don't understand?
Oblivion
Artisan Extraordinaire
Artisan Extraordinaire
Posts: 1269
Joined: Tue Mar 21, 2006 10:55 am
Location: Philippines

Post by Oblivion »

:oops: when I say pidgin. I meant pidgin. :wink:

Tho I'm CS, education here is not that intensive. :( We concentrate more on Java and VisualC which I won't be taking up extensively until next sem.

But it looks vaguely doable to me. I'll play with the .py's if I have some time.
A Step Into Oblivion

Dreams of things that will never be,
Songs of thoughts only I can hear,
Leave me be to sleep forever,
To dream my dreams,
And sing my hymns,
Of things that will never be...
ace123
Lead Network Developer
Lead Network Developer
Posts: 2560
Joined: Sun Jan 12, 2003 9:13 am
Location: Palo Alto CA
Contact:

Post by ace123 »

that's right... the Base and VS modules are implented in the C++ source code. That's why there is no VS.py or Base.py (actually we used to have stub modules for outside-VS testing... but that became impossible to maintain over time).

That's why I pasted that segment of C++ code--that was the Python Base API.

If you want to look at the python function definitions, look at base_util.cpp (full implentations) or base_util.h (only has definitions) source code in the vegastrike/src/cmd directory
geoscope
Bounty Hunter
Bounty Hunter
Posts: 205
Joined: Thu Jun 29, 2006 1:58 am
Contact:

Post by geoscope »

@ace123
That's why there is no VS.py or Base.py (actually we used to have stub modules for outside-VS testing... but that became impossible to maintain over time).
I found the vs.py while hunting through the data directories, and was wondering if it was used.
If you want to look at the python function definitions, look at base_util.cpp (full implentations) or base_util.h (only has definitions) source code in the vegastrike/src/cmd directory
Thanks, I do want to see them, before making any changes to the python code itself. Somewhere in the fixer code, I forget right now where, I did find a function for a textbox... not sure if it's used, but maybe there is already something to work with there.

I've condensed your suggestions to the following:
1. modify the function Speak() in bases/bartender.py
2. change Base.Message(myBarText) calls to DisplayBarMessage,
or
move it into a common library that could also be used by fixers.
3. Have DisplayBarMessage call
4. Base.TextBox(roomNumber=Base.GetCurRoom(), "textbox1", MessageTextString, xCoord, yCoord, (width, height, 1.0), (.2,.2,.2), .6, (.2,.8,.4))
5. Then, it could make a link and display an OK button picture in the same place.

Is there a common library already? If not, do you have a suggestion for naming convention? ...and about that button pic.... nevermind, I'll saddle that horse when I get to it.
geoscope
Bounty Hunter
Bounty Hunter
Posts: 205
Joined: Thu Jun 29, 2006 1:58 am
Contact:

Post by geoscope »

One more thing I was looking at... the lengthy strings stored in the python files... examples, the entire tender dictionary in bartender.py, and the mission strings in campaign.py. I was thinking think it might make sense to rework them to use message.txt, for a twofold gain... It would aid the internationalization projects, and also separate story-telling from code, for those that want to work on writing dialog, without looking at the code. Something like file with the structure:

[Bartender]
[General]
string1
string2
string3
[/General]
[University]
string1
string2
string3
[/University]
[Wisdom]
string ...
[/Wisdom]
[/Bartender]


I know VS has been moving away from XML, and more important, XML wouldn't simplify the structure as much as I was thinking would benefit story-tellers. I see the above being easy to add/modify for non-coders, and also easy to search from the code...

LangDict "English: ("Bartender.txt"), French: ("YouTellMeIDontSpeakFrench")
Language = "English"
MessageFile = file(Langdict{"English"}, "r")

SearchBlock="[General]"
while (MessageFile.readline().find(SearchBlock) == -1):
pass # to get to starting string location

Then read lines until another "[" is encountered. Loop if necessary to read more than one Block, then close the file when done. It just looks like more work is needed to separate game content from game code.
Oblivion
Artisan Extraordinaire
Artisan Extraordinaire
Posts: 1269
Joined: Tue Mar 21, 2006 10:55 am
Location: Philippines

Post by Oblivion »

to use message.txt
Makes sense. Maybe it should be what Dan would be doing to simplify mission making. Ask Dandandaman first if he has done this already/planning to do it.

Separating the story parts from code will help the translation efforts, I agree. As well as help budding mission scripters (which I hope I will be before I start wilting... lol).

If you can do it, I think you should go ahead. It doesn't affect any of the code right? It's just a bit of transplantation. :D
A Step Into Oblivion

Dreams of things that will never be,
Songs of thoughts only I can hear,
Leave me be to sleep forever,
To dream my dreams,
And sing my hymns,
Of things that will never be...
geoscope
Bounty Hunter
Bounty Hunter
Posts: 205
Joined: Thu Jun 29, 2006 1:58 am
Contact:

Post by geoscope »

Since separating message texts from the code does require coding changes, and a structure would need to be implemented for the text files, I'll wait to get further comments from developers before doing anything on this idea.
Zeog
ISO Party Member
ISO Party Member
Posts: 453
Joined: Fri Jun 03, 2005 10:30 am
Location: Europe

Post by Zeog »

We were already discussing this a great while ago. (Internationalization and message handling support)
Then and now I think gettext is the best way to go. It has support for many programming languages, e.g. Python, C++.
geoscope
Bounty Hunter
Bounty Hunter
Posts: 205
Joined: Thu Jun 29, 2006 1:58 am
Contact:

Post by geoscope »

I'm running into some complications changing the bartender text display.
Changing Base.Message to Base.TextBox isn't producing any errors, but also isn't displaying text in the game.

It would seem that the TextBox is created, but not displayed. I'm still trying to track down the problem.

Meanwhile I have some questions for ace123:

Code: Select all

Base.TextBox(roomNumber, "textbox1", "Hello, young traveler...",
xCoord, yCoord, (width, height, 1.0), (.2,.2,.2), .6, (.2,.8,.4))
xCoord, yCoord, (width, height, mult,) and the rest are all float values...

1.But what I need to know is, in what measurements?

2. xCoord, yCoord: are those pixel offsets from the upper left corner of the game window?

3. width, height: seem to be used to set the size of the textplane. Again, is that pixels?

4. BGcol, and FGcol: I'm guessing that's RGB values in the range .0-1.0

5. backalp: (the float value between the BGcol FGcol Vectors), what does it do? I can't imagine that it is a transparency color, it would need to be an RGB value too. From reading the C code, I see it is later grouped with the BGcol when TextBox passes the values to BaseText.

Here is how I modified the bartender.py Speak function. Perhaps someone else can catch why it isn't displaying.

Code: Select all

def Speak(thingstosay):
    (text,sound)=Base.GetRandomBarMessage()
    rndnum=vsrandom.randrange(0,2)
    roomNumber=Base.GetCurRoom()
    textBox = "textbox1"
    # positional info is going to need testing
    # Are the X and Y coords pixels, from the main screen Upper/Left?
    # These MAY have default values
    xCoord=.5			#float 
    yCoord=.5			#float
    WidHeiMult=(12, 10, 1.0)	 	#Tuple of values, (Width, Height, float Multiplier)
    BGColor=(.0, .0, .0)		# textbox background color Vector? Are those RGB values?
    BackAlp=.6				 #
    FGColor=(.9, .9, .9)		# Text color Vector? Are those RGB values?
    #Base.TextBox(int, std::string, std::string, float, float, Vector, Vector, float, Vector)
    
    if (rndnum==1 or text==''):
        mylen=len(thingstosay)
        if (mylen>0):
            # replace this line
            #Base.Message (thingstosay[vsrandom.randrange(0,mylen)])
	    Base.TextBox(roomNumber, textBox, thingstosay[vsrandom.randrange(0,mylen)], xCoord, yCoord, WidHeiMult, BGColor, BackAlp, FGColor)
        else:
            # replace this line
            #Base.Message ('Hello!')
	    Base.TextBox(roomNumber, textBox, 'Hello!', xCoord, yCoord, WidHeiMult, BGColor, BackAlp, FGColor)
    else:
        # replace this line
        #Base.Message (text)
	Base.TextBox(roomNumber, textBox, text, xCoord, yCoord, WidHeiMult, BGColor, BackAlp, FGColor)
        if (sound!=''):
            VS.playSound (sound)
I got the following error, until I figured out that a C Vector is like a Python tuple, rather than a list.

Boost.Python.ArgumentError: Python argument types in

Base.TextBox(int, str, str, float, float, list, list, float, list)

did not match C++ signature:
TextBox(int, std::string, std::string, float, float, Vector, Vector, float, Vector)

After, that no more errors or output showed up in the terminal when clicking the bartender.
ace123
Lead Network Developer
Lead Network Developer
Posts: 2560
Joined: Sun Jan 12, 2003 9:13 am
Location: Palo Alto CA
Contact:

Post by ace123 »

I'm not sure about what your problem might be. An invalid size or something may cause this, so you may want to flip around negative signs if it is a problem.

Here is a paste from a working example I have;

Code: Select all

Base.TextBox(roomNumber, 'textbox1', 'Hello, young traveler...', -0.3395, 0.7275, (0.5, -0.7954, 1), (0,0,0), 0, (1,1,1))
You may want to look at where that is placing the text box... it looks like the "height" value on mine is negative while yours is positive... maybe try making the height negative and see if that helps.

Also, that type error may be if you used an integer instead of a float, or a float instead of an integer... Boost can be pretty nasty about having exactly the correct types at times.


About translations, it may be easier to move all actual code out of bartender.py, and use only arrays of strings there... then it would be possible to have bartender_en and partender_de.py that each hold a set of strings that may or may not directly translate.
Of course using gettext would be overall a better solution if you can get it working.
geoscope
Bounty Hunter
Bounty Hunter
Posts: 205
Joined: Thu Jun 29, 2006 1:58 am
Contact:

Post by geoscope »

Lol, with some values in valid range the textbox now displays... I hadn't expected some of the values to be negative. However, now I've have to figure out how to make the TextBox destroy or clear so that speaking to the bartender multiple times doesn't overlay multiple text.

That should be easier to figure out than the valid ranges for a series of floats.
geoscope
Bounty Hunter
Bounty Hunter
Posts: 205
Joined: Thu Jun 29, 2006 1:58 am
Contact:

Post by geoscope »

Ok, I've commited a change that uses the Base.TextBox instead of Base.Message.... However, it TextBox really uses a textplane, so it doesn't generate a window with an ok or close button... I might try looking at the code for the Save/Load screen later, to see how that works.

I've used variables in the call the Base.TextBox function, and liberally applied comments so that anyone that wants to modify the postion, size or color of the the Bartender text can do so easily.

One thing I didn't figure out was how to clear or delete the TextBox when you leave the bar, so if you leave and come back the last message is still displayed, I haven't gotten the fixers to use the same TextBox yet. I am not sure how to fetch the Base.TextBox instance's name, to acess it from another module.

I can't resolve those two issues because I don't know how to call a C++ destructor or reference a C++ object by name within C++, or from a python module. If it was just python and wxPython, I could do both.
ace123
Lead Network Developer
Lead Network Developer
Posts: 2560
Joined: Sun Jan 12, 2003 9:13 am
Location: Palo Alto CA
Contact:

Post by ace123 »

I don't think there is an easy way to delete messages when you leave, since it simply hides/shows when you leave or enter the rooms.

About having buttons, look at the fixer scripts.
Basically you will want to create an "OK" texture in a certain place. Then, create a Base.Python, which runs a python script when you click "OK". That python script will essentially delete the Textbox, the OK python script and the OK texture.

To delete the OK texture and the textbox, call (the "#" means inline)
Base.Python(room, 'myTextOkLink', x, y, width, height, 'Close Message' """#inline
import Base
Base.EraseObj(room, 'myTextBox')
Base.EraseObj(room, 'myTextOkButton')
Base.EraseLink(room, 'myTextOkLink')""", True)

Also, don't do SetTextBoxText()... that will still slow it down since it has to draw it,
Instead call that erase function above.

Kind of complicated/annoying, so you may want to look at how the fixer scripts do the buttons since you will want to copy that.

If you are wondering why the textbox is negative, it's because TextBox was implemented in the engine but never tested much :-P

Maybe I'll add a check in the code to flip the sign if it's positive to allow for both ranges (since it is in fact nowhere documented that it has to be negative).

I also recommend that you make a function that does Base.TextBox() so that can be use d eventually with fixers and other objects that need to talk.
geoscope
Bounty Hunter
Bounty Hunter
Posts: 205
Joined: Thu Jun 29, 2006 1:58 am
Contact:

Post by geoscope »

ace123 wrote:I don't think there is an easy way to delete messages when you leave, since it simply hides/shows when you leave or enter the rooms.
I noticed while testing (mostly because of errors, which prevented me from entering the concourse) that the scripts are preloaded when you land on a base. I was wondering if there was a mainbase.py or some such (besides the mere creation of the base), or perhaps I might work on one, that could be event triggered, when you leave/enter a room, or whether something like that might exist in the C++ code..

OT
I know the room is discovered/tested when you call the TextBox, so what I'm looking for would be perhaps an event generator that could trap when the room state changes) I recall some threads about work on more interactive bases. Was anything on the way in that regard? Anyone remember WC III and IV, might be interesting to have a system that allowed for instance, hallway encounters.
/OT
About having buttons, look at the fixer scripts.
Basically you will want to create an "OK" texture in a certain place. Then, create a Base.Python, which runs a python script when you click "OK". That python script will essentially delete the Textbox, the OK python script and the OK texture.
Was going to check that next. But the yes/no buttons are a bit plain, and doesn't fit the rest of the base screens very nicely. I was wondering if it would be possible to grab button textures or objects like are used on the Cargo Ship and Computer screens. In any case, I'll work on at least getting an ok button in to remove the dialog from the screen.
Also, don't do SetTextBoxText()... that will still slow it down since it has to draw it, Instead call that erase function above.
I don't see how erasing the TextBox would be any faster than Setting the Text to "" (and creating a new TextBox, if you happen to be diplaying another message). The major issue I see it that the TextBox needs to be erased (destructed) eventually, or it is a memory leak.

If it's only going to be text overlayed with transparent background to show the room behind, I think the smart way to go would be to create an empty TextBox in the bar, the first time a text event takes place there, and then just reuse it until done (no more dialog with either the bartender or fixers), and destroy the TextBox on leaving the base.

In fact, one thing that has me a bit puzzled what why bartenders and fixers aren't related. Fixer ought to be a base class of bartender. the things that differentiate them, There is only ever one (but always one) bartender in every bar, instead of 0-2 as for fixers. The bartender doesn't offer missions with a yes/no proposal, but do still have messages to players. Certain aspects of bartenders could be extended over time, if they inherited from the fixer. Such as multiline messages, interactive response, for branching dialogues, campaign gossip would be more easily supported , and the possiblitly of missions could even be added eventually. Example:

Code: Select all

"I have this customer, who just loves this one very rare wine... it's only available on <planet> in <sector>. Trouble is, I'm running low and can't seem to get any shipments in with all the trouble that going on lately. I'd make it worth your while to go pick up a few cases and bring them back here. What do you say?"
Of course, I'm getting off-topic again... But I think the fixers and bartender scripts do need a bit of a rethink. For now, I'm just going to look into copying the button code and erasing function over from fixers, to make sure the TextBox gets destroyed. I'd also like to know whether anyone thinks the new text display is an improvement on the old, since it's not what was originally proposed. I too, though a real textbox with intregated buttons -- transluscent like on the base cargo and computer screens, but overlaying the bar -- would have been very cool.
I also recommend that you make a function that does Base.TextBox() so that can be use d eventually with fixers and other objects that need to talk.
That doesn't make much sense... Base.TextBox() already exists. it can be called from any of the bartender or fixer scripts. What would be the point of a python script that further encapsulated the the C++ Base.TextBox() that is provide through the python integration? What is needed in the long run, is to unite the various bartender scripts (and possibly integrate with the fixers module a bit more)... they are redundant and odd.

Bartenter-*.py all have the same function named in them, same format. That function calls on a function (in bartender.py) to retrieve a list of strings from a dictionary (also in bartender.py) then passes that info on (to yet another function in bartender.py). That is not an example of good modularization. It's redundancy. the only thing they do different is the list arguement, varies... that is easier to maintain if it were just an assigned variable modified and passed entirely within bartender.py.

Anyhow, I've taken on 3 projects now in the VS world.

1. The bartender/fixer code.
2. Code for editing csv.
3. A script for spam control on the forums.

I also want to look at the campaign writing (not code, not yet anyway).

I'll get the ok button in within the next 36 hours. After that, I'm going to wait for feedback from users, here in this thread.
ace123
Lead Network Developer
Lead Network Developer
Posts: 2560
Joined: Sun Jan 12, 2003 9:13 am
Location: Palo Alto CA
Contact:

Post by ace123 »

Campaign writing is fairly simple and doesn't require too much code to work out.

You should look at the campaign.py in the Privateer Remake mod... that has the entire campaign in the Python campaign system.

Also, when you say "Base.TextBox() already exists", it does, but no function that positions it in the right place, adds buttons and sets the buttons to do something exists.

Anyway, the campaigns may be a better starting place, since the buttons are a little complicated to get working.

campaigns are basically nodes pointing to other nodes, and some nodes do things as soon as you get to them (reward credits), and others do something when you click on a guy, and some nodes start a mission.
Post Reply