Hello!
I know a Smaug-based MUD where there is a skill that show-me the mob's life in a bar.. it's something like this:
[>>>>>>>---]
The same bar appears in the player's score screen, in the hp, mn and mv information.
I am trying to make the same thing in my smaug here..
I know php, delphi, vb6, etc, but this is my first time using c++. Is that any default function that draw this bar? How can I use this in a skill??
I'd made a function to the score command, but it doesn't work..
This is the function, the variables are portuguese words (barra = bar; porcento = percent; desenho = draw):
//-----------------
char barra(int A, int B)
{
int porcento;
char desenho;
int i;
porcento = (A*100)/B;
desenho = '[';
for (i = 1; i < 11; ++i){
if (porcento >= (i*10))
desenho += '>';
else
desenho += '-';
}
desenho += ']';
return (desenho);
}
//-----------------
So in the moment I need to use the bar, I use the caracter's hit & max_hit information to return the bar, but I doesn't understand how to use the print functions..
Oh yes, I believe this is relevant: I am using Microsoft Visual C++ 6.
The problem is that 'char' is not a string type, it is just a character. So you are taking a character, and adding other characters to it, resulting in a new, single character.
There are two ways to do this:
1. build up the string and return it as a char*, keeping in mind that you will have to free it.
2. pass the CHAR_DATA *ch variable into your function, and use the ch_printf or send_to_char functions to send data to the character. This is the easier solution.
For examples of these, look at any of the functions that send to the character, such as do_mstat, do_time, or even do_score which you are already looking at.
I'm sorry, I realize this is really stupid, but I really never used a string this way..
Ok. I am trying now to print the result inside the function..
This is my idea.. of course it doesn't work, but I am trying to make it fit..
//--------------------------
int bar_draw(int A, int B)
{
int percent;
char bar [20];
int i;
percent = (A*100)/B;
for (i = 1; i < 11; ++i){
if (percent >= (i*10))
bar += '>';
else
bar += '-';
}
send_to_pager("["+bar+"]\n\r", ch); //this is not right..
return 0;
}
//--------------------------
Now I get two errors:
The most common is "'+=' : left operand must be l-value"
The function to print I believe I will find a way.. but why the "+=" doesn't work?
I think it's nicer without the if checks, but that's just me:
[david@thebalrog:~]$ cat test.c
#include <stdio.h>
#include <stdlib.h>
void PrintBar(int cur, int max)
{
int perdec = (10*cur)/max;
int decade;
printf("[");
for (decade = 1; decade <= 10; decade++)
{
if (decade <= perdec) {
printf(">");
}
else {
printf("-");
}
}
printf("]\n");
}
int main(int argc, char** argv)
{
int i;
for (i = 0; i <= 100; i += 5) {
PrintBar(i, 100);
}
}
[david@thebalrog:~]$ gcc test.c -o tester
[david@thebalrog:~]$ ./tester
[----------]
[----------]
[>---------]
[>---------]
[>>--------]
[>>--------]
[>>>-------]
[>>>-------]
[>>>>------]
[>>>>------]
[>>>>>-----]
[>>>>>-----]
[>>>>>>----]
[>>>>>>----]
[>>>>>>>---]
[>>>>>>>---]
[>>>>>>>>--]
[>>>>>>>>--]
[>>>>>>>>>-]
[>>>>>>>>>-]
[>>>>>>>>>>]
Having it handled logically like that makes it easier to adapt to different formats, for instance, instead of doing tenths you could do fifteenths, hundredths, fifths, etc. In fact, you could even have the resolution as another parameter of the function. It would be very easy. I'll leave it as an exercise to the reader. (*chortle* I've always wanted to say that. :-P)
int bar_draw(int A, int B)
{
char *bar[MIL];
int percent;
percent = (A*100)/B;
if( percent >= 100 ) bar = "[>>>>>>>>>>]";
Technically bar here is declared as an array of char*, which is probably not what you want. It is enough to define it as just a char*, that is, "char * bar;".
In fact to be somewhat obsessive about it you would do const char *, because you are not writing into the string but rather assigning to it from the data segment of the program (the string constants "[........]".
Oh, I like the way you've proposed, David, that's slick.
I'm not sure what the difference is between char *bar [MIL]; and char *bar; and const char *bar;
I suggested the way I had because I knew it'd work (from my own experience dealing with a similiar snippet having to do with putting a bar like that into the prompt), though your way without the multiple if checks is much nicer. I didn't know how to do that myself, but now that I can see what you'd done, I'll use your way if I should find myself doing something like this in the future. :)
A pointer (that can be changed) to a character (that cannot be changed). So bar++ is legal, but bar[0] = 'a' is not.
Contrast with: char * const bar
In this case the pointer cannot be changed to point to another location (bar++ is illegal) but you can change the contents in the address it points to (bar[0] = '\0', for example, is legal).
The rule for arrays is that when you have the brackets, you are creating an array of the type before the name. So,
char bar[100]
is an array of 100 characters. 'bar' is a pointer to the beginning of that array.
char * bar
A pointer, that for now points nowhere;
char * bar[100]
One hundred pointers to characters, none of which point anywhere.
How much it helps, I can't say yet.. I may have to read through that a few times (or even play with it in some code a bit) to fully grasp what you've explained, but it does look like a pretty helpful explaination in general that I suspect I'll be coming back to reference for awhile before I've got it all down myself. ;)
Well, yes, but only a fool thinks he knows it all and refuses an opportunity to further his education when presented rather than blunder blindly. ;)
Yes, C++ and C will both get upset at you when you try to compile if you don't declare a variable to start with, but I didn't notice any variables in his example that weren't declared, I take it that you did? (I also hadn't actually tried it myself either yet.)
I hope that you'll remember to let us know the results of your trial. ;)
Quote: but recently I find out that if you do not declare the variables in the top of the function, c++ will get an error.
No; strict C will get upset, but C++ won't. But as Conner says, in any case you need to declare the variable somewhere. (I much prefer C++'s flexibility of letting you declare it where it's relevant.)
If the code I gave you doesn't compile I'd be curious to hear what compiler you're using. I'm using gcc 4.1.2 and it compiles fine; if anything the newer versions are more strict and if it compiles here it should compile on previous versions too.
I use Microsoft Visual C++ 6.
I doesn't mean to say that the variables were not declared. I said that in my C++ compiler it *must* be declared in the top! I don't know why! But all the time I declare a variable in the middle of the function, it returns me an error.
For example:
//--
int value(int A, int B){
int C; //in the top
C = A+A;
int D; //in the middle (here is the problem)
D = C+B;
return D;}
//--
It doesn't work.
//--
int value(int A, int B){
int C;
int D;
C = A+A;
D = C+B;
return D;}
//--
Work!
That's seriously odd because I just compiled your code with D in the middle without a hitch. Are you absolutely certain you don't have strict/explicit declaration options enabled?
C++ even in MSVS6 does not require variables to be declared at the top by default. I know that for a fact because I have done it over and over again.
It is possible that it is entering C mode in MSVS6 because it sees that your file is .c. Try making it .cpp and seeing what it does. Or tell it to compile in C++ mode -- that's in the options somewhere.
David, I think you're right!
I will reinstall MSVS6, my system is having problems because of a virus. Then I will do it. But I believe it is the file as you said!
Hi everyone!
Here is the last code I've done.
It's optimized and it's working!
Enjoy!
//--------------------------
/*
Bar Drawning by Alkarindil
Example to print a life bar:
bar_draw(ch->hit,ch->max_hit,ch);
*/
void bar_draw(int A, int B, CHAR_DATA * ch)
{
int percent;
int C;
percent = (A*100)/B;
send_to_pager("[", ch);
for (C = 0; C < 10; C++){
if( percent >= (C*10) ) send_to_pager(">", ch);
else send_to_pager("-", ch);
}
send_to_pager("]", ch);
return;
}
//--------------------------