Guest PurpleOnyx Posted October 13, 2005 Report Posted October 13, 2005 On cloud nine after getting one of my plugins to function nearly perfectly. Only problem is I want to make it multi-functional across several arenas. So, I need to learn of a way to extract the current arena name. Maybe it's simply due to the lack of sleep, but I can't seem to come up with anything. Second, I am interested in learning how to interpret additional parameters following the dll file in Spawns.txt. (eg: myBot.dll -abc=xyz). If I can find how to go about doing it this way, I don't need to know how to pull the arena name as mentioned above. But ofcourse learning about both methods would be educational. Thanks!
»Maverick Posted October 13, 2005 Report Posted October 13, 2005 On the EVEN_ArenaEnter you will see://////// Arena //////// case EVENT_ArenaEnter: { arena = (char*)event.p[0]; me = (Player*)event.p[1]; // if(me) {/*we are in the arena*/} bool biller_online = *(bool*)&event.p[2]; } break; Thus the global variable 'arena' is filled there and contains the arena name the bot currently is in. I don't believe additional parameters for DLLs are possible, instead use a .ini file and read the values from that. The windows.h library has ready-to-use methods available for .ini files: const int BUFFER_LEN = 256; static char buffer[BUFFER_LEN]; static char INIPath[BUFFER_LEN]; GetCurrentDirectory(192, INIPath); strcat(INIPath, "\\pluginName.ini"); WritePrivateProfileString("Section", "KeyName", "KeyValue", INIPath); GetPrivateProfileString("Section", "KeyName", "DefaultValue", buffer, BUFFER_LEN, INIPath); sendPublic("Value = "+String(buffer));Be aware that the buffer is large enough to contain the data (and for the path).
Guest PurpleOnyx Posted October 13, 2005 Report Posted October 13, 2005 On the EVEN_ArenaEnter you will see://////// Arena //////// case EVENT_ArenaEnter: { arena = (char*)event.p[0]; me = (Player*)event.p[1]; // if(me) {/*we are in the arena*/} bool biller_online = *(bool*)&event.p[2]; } break; Thus the global variable 'arena' is filled there and contains the arena name the bot currently is in. Fully aware of that, been trying to use that in my func call though and wont work. Unless I need to move my function completely from the "DLL Import" section, to the EVENT_ArenaEnter case block. Example of what I've got: under DLL import section: #include <fstream> using namespace std; void readINI() { // char *arenaname = "["; <-- where I am wanting it to come in at. // A quick fix is probably just to allow for readINI(char *arenaname) and drop that in // the event handler for ArenaEnter, eh? Any way to just make it global, or do I need // simply drop in extern arena ? int current = false; ifstream file("audio.ini"); if (file) { char line[256]; while (file.getline(line,256)) { // ... parsing ini file, searching for "[arenaname]", stop when we come // to the next "[", as that will be the start of the next arena name } } } // Then I just have readINI() running directly after the void func.
»Maverick Posted October 13, 2005 Report Posted October 13, 2005 your function isn't part of the botInfo class. Making it part of it by doingvoid botInfo::readINI() { will save you alot of work and makes things easier. If you make the function part of it you can use the variable 'arena' with no problems. Nonetheless, in your function I would recommend you to try usingbotInfo.arena. However, you have to move the char *arena; from Spawn.h into the public section first.
Guest Guest Posted October 13, 2005 Report Posted October 13, 2005 Got that working so far, thanks Mav. Not done too much in c++, far more fluent in c, but I'm managing so far. Last question for you, since you seem to be the phenom when it comes to this (re: comments in code regarding reading in [blah] vs. [ blah ] vs. [ blah ] from .ini) String s = "["; s += arena; s += "]"; while (file.getline(line,256)) { if (!current && CMPSTART(s, trim(line))) { // // Trying to remove white space with trim, but may require regex? // this way if its put in as [arenaname] or [ arenaname ] it wont matter. // is there an easier way to accomplish this? // current = true; } else if (current && CMPSTART("[", line)) { current = false; break; } if (current) { // run all my line checks to see if string matches param... } }
»D1st0rt Posted October 13, 2005 Report Posted October 13, 2005 It is sooooo much easier to use GetPrivateProfileString() and/or GetPrivateProfileInt() to do that
Guest PurpleOnyx Posted October 14, 2005 Report Posted October 14, 2005 It is sooooo much easier to use GetPrivateProfileString() and/or GetPrivateProfileInt() to do that Is it? I'm going off of your tutorial d1st0rt I ended up resolving my matters on my own, got it all to parse nicely. then later realized hey, why not just simply pull audio_ARENA.ini so that each arena i want to use the same plugin for, has it's own .ini file. Now I face a new problem, which I have no f'ng idea how to get around. I have 2 arenas I want to use the same plugin for. Problem is, when the first .ini params are read, when the 2nd instance runs, it overwrites the first instance..for BOTH arenas. (audio bot, basically to do the same thing as dj.dll was intended to, though I could never get it to work). Uses RangeStart, RangeEnd and Interval. So in a nuts!@#$%^&*, it sorta works..but overwrites settings. How do I keep the settings apart? I thought hey, that counter function, maybe I need 2 separate counters for this thing to work. So i modified spawn.h to include: // in botInfo class int countdown[4]; int rangestart[4]; int rangeend[4]; int interval[4]; // in public countdown[0] = 0; countdown[1] = 0; countdown[2] = 0; countdown[3] = 0; rangestart[0] = 1; rangestart[1] = 1; rangestart[2] = 1; rangestart[3] = 1; rangeend[0] = 1; rangeend[1] = 1; rangeend[2] = 1; rangeend[3] = 1; interval[0] = 10; interval[1] = 10; interval[2] = 10; interval[3] = 10; audiofailed[0] = 0; audiofailed[1] = 0; audiofailed[2] = 0; audiofailed[3] = 0; // And set a static int audioNum, auto incrementing per startup instance (max 4 obviously with this config). Unfortunately, I still run into the same problem. someone, please, just put me out of my misery. I got the code to work perfectly using a single instance. But it needs to work for multiple instances.
Guest PurpleOnyx Posted October 14, 2005 Report Posted October 14, 2005 Okay..sooo i didnt read enough in your tut. I got to the part where you mentioned using GetPrivateProfileString. And I have a workaround completed. Maybe someone can tell me the 'proper' way to make it work. But for all intents and purposes, the current method is fine for my needs. Scenario: Plays bongs within a given range, at a given interval. So lets say we play bongs 160-169 (i like that number) once every 10 seconds (just to be absolutely annoying! lets also say that bongs 160-169 are sounds of animals copulating). [ audio ]RangeStart=160RangeEnd=169Interval=10 Add audio.dll to Spawns.txt. No problem. Now we want to run the plugin a second time. Due to my incompetence, and lack of worldly knowledge when it comes to c++, you simply rename both the dll and the ini in the following format: audio_ARENA.[dll|ini]. eg: arena name is private, #AnimalSex. You would rename to audio_#AnimalSex.dll and audio_#AnimalSex.ini. (It's sex-panther...there are real bits of panther in it, so you know its good.) I'm sure neither Mav nor d1st0rt required the example, a simple syntax/format would work...but I am sure that more dullards such as myself, will come to read this thread, so I figured I might as well spell it out for them too! But anyhow, if either of you (Mav or d1st0rt, my new idols, absolut phenoms) can provide me with the building blocks to achieve absolute victory in this endevour, there might be a cookie in it for you (and ofcourse my gra!@#$%^&*ude). Thanks to both!
»D1st0rt Posted October 15, 2005 Report Posted October 15, 2005 This is how SOS used GetPrivateProfileString in TM_MER, and I used it in my LVZ toggler because I liked it://Load Functions, Courtesy of SOS #define G(name) ZeroMemory(buffer, 192);\ GetPrivateProfileString(!@#$%^&*le.msg, name, "-1", buffer, 192, Path) #define G2(a) if (isNumeric(buffer))\ a = getInteger(buffer, 10);\ else\ a = 0 #define G3(a) if (isNumeric(buffer))\ a = getLong(buffer, 10);\ else\ a = 0 void botInfo::load() { char Path[520]; GetCurrentDirectory(520, Path); strcat(Path, "\\lvztoggle.ini"); char buffer[192]; String !@#$%^&*le = "Objects"; G("TimeInterval"); G2(interval); ... } where interval is an int defined in spawn.hCyan prefers to use GetPrivateProfileInt, which you can certainly also use. Another thing you might want to look for is the INIAccess class that Dustpuppy wrote for the old EXPLBot
Guest Guest Posted October 16, 2005 Report Posted October 16, 2005 Thanks d1st0rt, will give something like that a try. It works fine for me now, (the current method) but for a release, I'd prefer it be done the 'right way'. Thanks again!
»SOS Posted October 16, 2005 Report Posted October 16, 2005 I should note that I do not approve of code like this setting reading code I once wrote Not good coding style, IMO. But I guess it gets the job done.
purpleonyx Posted October 16, 2005 Report Posted October 16, 2005 I should note that I do not approve of code like this setting reading code I once wrote Not good coding style, IMO. But I guess it gets the job done. Well then SOS, how about I send you my code, you fix it all up nice and neat how 'you' prefer it to be done, and send it back, and release to public. Kill 2 birds with one stone, right?
»D1st0rt Posted October 17, 2005 Report Posted October 17, 2005 Here's that INIAccess stuff I was talking about earlier This demonstrates how you can do basically everything you would need to iniaccess.zip
Recommended Posts