Author Topic: Outpost Monopoly Download  (Read 33060 times)

Offline Vagabond

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1015
Outpost Monopoly Download
« on: April 04, 2016, 05:08:45 PM »
I'd like to give Outpost Monopoly a try, but I the download link is broken in the main project here: http://forum.outpost2.net/index.php/topic,4914.0.html

Does someone have the final build available that they could post?

Offline Vagabond

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1015
Re: Outpost Monopoly Download
« Reply #1 on: April 12, 2016, 12:08:12 PM »
If no one has a compiled DLL of Outpost Monopoly, I'd like to look at recompiling it from the source code in the repository so it is available to play again. Don't know if the creator, Hidiot, is still around.

Offline Vagabond

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1015
Re: Outpost Monopoly Download
« Reply #2 on: April 24, 2016, 11:54:29 AM »
Hey everyone,

I built up a new Visual Studio project for Outpost Monopoly.

Unfortunately, the repository is missing the MAP file and tech tree file. If someone can search the bowels of the site/personal archives for the following 2 files it would be much appreciated. Otherwise rebuilding the DLL won't matter.

atwmon.map
monoptech.txt

I'm having difficulty getting the Outpost Monopoly Project to reference IUnit properly. I think it is related to how IUnit itself references HFL. I think with some more head bashing I could figure it out, but it is a moot point unless someone has the tech tree and map file available.

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4955
Re: Outpost Monopoly Download
« Reply #3 on: April 27, 2016, 06:52:39 AM »
Any specific details on the IUnit issue?

If anyone has a copy of those missing files, they should probably be added to SVN. They are valid source files.

I haven't been able to find an archive for that project.

Offline leeor_net

  • Administrator
  • Hero Member
  • *****
  • Posts: 2352
  • OPHD Lead Developer
    • LairWorks Entertainment
Re: Outpost Monopoly Download
« Reply #4 on: August 25, 2016, 02:21:02 PM »
Going to have to take a look at this. Bugging me that we've been unable to come up with anything. And, also, I kinda never played this and would like to see some additions to Outpost 2 that are easy to find.

Offline Vagabond

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1015
Re: Outpost Monopoly Download
« Reply #5 on: August 27, 2016, 09:43:51 AM »
Leeor_net,

Unless we can locate the tech tree and the map file, these would have to be reproduced by guesswork? Since I think most everything in game is represented by buildings/vehicles/walls, you could probably put a generic map down to get the game working without issue. What I don't know is what all is contained in the tech tree file. If the tech tree is very generic and just contains the info to get the scenario working, perhaps it could be recreated without too much hassle....

Money is common ore.
A dice area if set aside from the rest of the map using tubes.
Various buildings from Outpost 2 represent different property (Garages are railroads).
Residences are houses and advanced residences are hotels.

Offline leeor_net

  • Administrator
  • Hero Member
  • *****
  • Posts: 2352
  • OPHD Lead Developer
    • LairWorks Entertainment
Re: Outpost Monopoly Download
« Reply #6 on: August 27, 2016, 01:13:06 PM »
This sounds like a really cool mod... I wish I'd known about it before now. -_-

Offline Sirbomber

  • Hero Member
  • *****
  • Posts: 3238
Re: Outpost Monopoly Download
« Reply #7 on: August 27, 2016, 03:16:10 PM »
Absolutely no idea what condition this is in.  I don't think it represents the final product.  I don't even know if there ever was a final product, actually.  Anyways, have fun.
"As usual, colonist opinion is split between those who think the plague is a good idea, and those who are dying from it." - Outpost Evening Star

Outpost 2 Coding 101 Tutorials

Offline Vagabond

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1015
Re: Outpost Monopoly Download
« Reply #8 on: August 28, 2016, 05:53:02 PM »
Sirbomber,

Thank you for posting! It looks like the files you posted were last edited in 2009. I think HiIdiot made his last updates in 2010, so maybe not newest code file? But hopefully the repository has the newest cpp/h files.

I'll push the research text file and map file into the repository, so it can be compiled again.

Offline Vagabond

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1015
Re: Outpost Monopoly Download
« Reply #9 on: August 30, 2016, 10:20:19 PM »
Outpost Monopoly's Tech File and Map File are now in the repository.

State of Outpost Monopoly Repository Code
I checked the Outpost Repository log of the Outpost Monopoly code files against the Outpost Monopoly forum post dates. It looks like the last upload was June 13, 2010. The forum has a small update posted on 10 July, 2010:

Quote
Have added another little check in the commands system, and added a new command for hosts to alter starting money.

Besides that small update, I think we have the newest source code in the repository, with all the bug fixes.

Path Forward
1. Build up a solution in Visual Studio 2015 that plays nicely with Outpost legacy code (http://wiki.outpost2.net/doku.php?id=op2_sdk:projectcreation).
2. Properly add references to IUnit (and I think HFL).
3. Recompile and playtest!

I'm busy finishing up a project unrelated to Outpost. When it is done, I'd be willing to come back and get a VS2015 solution built up for the project. It would probably be a couple of weeks. I would need major assistance with referencing IUnit though. If Leeor_Net or someone else wants to work on/finish it before then, that would be cool too!
« Last Edit: October 12, 2016, 04:53:31 PM by leeor_net »

Offline Sirbomber

  • Hero Member
  • *****
  • Posts: 3238
Re: Outpost Monopoly Download
« Reply #10 on: September 01, 2016, 04:12:34 PM »
Don't use Iunit.
"As usual, colonist opinion is split between those who think the plague is a good idea, and those who are dying from it." - Outpost Evening Star

Outpost 2 Coding 101 Tutorials

Offline dave_erald

  • Sr. Member
  • ****
  • Posts: 262
Re: Outpost Monopoly Download
« Reply #11 on: September 01, 2016, 06:35:07 PM »
Boooooommmmmmbbbeeeerrrrrrr, no one was present for the conversation in your head explaining why we can't use Iunit.

We love you man but you are thick some days.
-David R.V.

-GMT400 fan
-OPU Influencer

Offline Sirbomber

  • Hero Member
  • *****
  • Posts: 3238
Re: Outpost Monopoly Download
« Reply #12 on: September 01, 2016, 08:11:24 PM »
Why?  I could literally say anything and you'd believe it.  :P

Iunit code will only work if you have the Iunit.dll in your OP2 folder; it will crash otherwise.  HFL has no such restriction.
"As usual, colonist opinion is split between those who think the plague is a good idea, and those who are dying from it." - Outpost Evening Star

Outpost 2 Coding 101 Tutorials

Offline dave_erald

  • Sr. Member
  • ****
  • Posts: 262
Re: Outpost Monopoly Download
« Reply #13 on: September 01, 2016, 08:20:48 PM »
Yeah probably....but that's only because you have all the answers, we just need to poke you to get them all out
-David R.V.

-GMT400 fan
-OPU Influencer

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4955
Re: Outpost Monopoly Download
« Reply #14 on: September 03, 2016, 08:47:27 PM »
+1 @dave_erald for calling Sirbomber on that. :P

Of course the next question is, what "IUnit" project? There was more than one. It was too obvious and generic of a name.

Offline Vagabond

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1015
Re: Outpost Monopoly Download
« Reply #15 on: September 04, 2016, 10:40:34 AM »
I was referring to #include <IUnit.h> in Outpost Monopoly's Main.cpp. I assumed it was a reference to IUnit.h in the repository under API/HFL-IUnit, but perhaps that is a bad assumption?

I poked around the .cbp, .depend, and .layout files by loading them into a text editor, but didn't recognize anything showing where in the file structure it was pulling IUnit.h from. I was hoping to see it being referenced from another location in the repository. I have never used Codeblocks, so I'm not familiar with it.

Perhaps, if IUnit is not deeply integrated into the Monopoly project, the reference could just be deleted. I haven't checked how often functions from IUnit are used or how difficult they would be to replace.

@Sirbomber,
I am curious why you recommend not using IUnit.

Offline Sirbomber

  • Hero Member
  • *****
  • Posts: 3238
Re: Outpost Monopoly Download
« Reply #16 on: September 04, 2016, 11:55:13 AM »
As I said earlier, Iunit requires Iunit.dll, which I'm noticing is missing from my fresh install of OP2.  So that's an issue right there.  Things can be complicated even further if there are different versions of Iunit.dll.  On top of that, you can do everything with HFL that you could do with Iunit, and more.
"As usual, colonist opinion is split between those who think the plague is a good idea, and those who are dying from it." - Outpost Evening Star

Outpost 2 Coding 101 Tutorials

Offline Arklon

  • Administrator
  • Hero Member
  • *****
  • Posts: 1269
Re: Outpost Monopoly Download
« Reply #17 on: September 04, 2016, 02:33:54 PM »
As I said earlier, Iunit requires Iunit.dll, which I'm noticing is missing from my fresh install of OP2.  So that's an issue right there.  Things can be complicated even further if there are different versions of Iunit.dll.  On top of that, you can do everything with HFL that you could do with Iunit, and more.
It's op2extra.dll, not Iunit.dll. It's still dumb that Eddy-B made it a dynamic library rather than a static one like HFL.

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4955
Re: Outpost Monopoly Download
« Reply #18 on: September 05, 2016, 05:07:11 AM »
Quote
I was referring to #include <IUnit.h> in Outpost Monopoly's Main.cpp. I assumed it was a reference to IUnit.h in the repository under API/HFL-IUnit, but perhaps that is a bad assumption?
Not really a bad assumption, but there were about 3 projects floating about using the name IUnit. I suspect you can get things working with the version from HFL. They all had sort of the same goals, with many shared or similar functions. It's possible you'll have to rename some calls or make minor adaptations.

I think it's unlikely the project will work without some kind of IUnit dependency. It was almost certainly added for a reason. There are many neat things you can do with direct access to the unit class, that are not possible using only the regular exported functions.

Removing the #include should get the compiler to tell you where IUnit was used. Changing the import to a different IUnit library will (likely) tell you where (most of) the differences are. (It's possible two libraries could provide identically name functions, but with subtly different semantics).

Offline Vagabond

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1015
Re: Outpost Monopoly Download
« Reply #19 on: October 07, 2016, 01:27:45 AM »
I finally got around to working on this after a longer then expected 2 weeks.  ???

I built up a Visual Studio 2015 solution for the project with all the proper project/linker settings. I added references to the Outpost2DLL, OP2Helper, and HFL.

For IUnit, I added an additional include directory for the C++ compiler to the IUnit folder in the repository. With this, the linker (or compiler, not sure the right term here?) managed to find IUnit.h. However, I get a compiler error C2504 'UnitEx': base class UnitEx undefined.

I'm guessing that the C++ compiler/linker is unable to find the definition for UnitEx from HFL before it attempts to define the IUnit class. 

The HFL-IUnit project is built with VC++ 6. I'm guessing to make this work, we have to add a Visual Studio 2015 project for HFL-IUnit and references to Outpost2.DLL and HFL. Then we reference the new project from Outpost Monopoly.

Looking for a little direction before I try to create new projects for established API... If someone else wants to set it up, that would be cool too.

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4955
Re: Outpost Monopoly Download
« Reply #20 on: October 07, 2016, 07:03:59 AM »
Sounds like you're on the right track here. Visual Studio 6 is too old to just upgrade the project files, so you'll have to create a new project, re-add all the sources files, and configure any needed project settings or dependencies. The existing project files are text based though, so you can open them in a text editor if you need a reminder of what things likely need to be configured.

In regards to the compiler error "C2504 'UnitEx': base class UnitEx undefined", this happens if the header for UnitEx is not included in a file that references UnitEx. This might be caused by a missing #include line, or missing project settings needed to find the proper header for a #include (in which case you should see an error about the #include line earlier in the error output). For the later, fixing up the project file may solve the issue. For the former, it might be caused by stale code after a project reorganization, and would need an appropriate #include line added.

Offline Vagabond

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1015
Re: Outpost Monopoly Download
« Reply #21 on: October 08, 2016, 03:18:46 AM »
Hooman, Thank you for the verification!

I successfully created a VS2015 project for HFL-IUNIT and got it compiling. I also successfully managed to compile and run a copy of Outpost Monopoly after this! So most everything came together after only a little bashing my head against the wall. I haven't uploaded the new code to the repository yet. It looks like she is using a modified version of the map Around The World.

To compile Outpost Monopoly, I was forced to add 2 preprocessor definitions due to what Microsoft is calling deprecated function calls.



Added Preprocessor Directives
  • _CRT_SECURE_NO_WARNINGS
  • _CRT_NONSTDC_NO_WARNINGS

Error Codes Requiring Preprocessor Directives
Error   C4996   
'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

Error   C4996
'strncpy': This function or variable may be unsafe. Consider using strncpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

Error   C4996
'itoa': The POSIX name for this item is deprecated. Instead, use the ISO C and C++ conformant name: _itoa. See online help for details.   

For more details on C4996, see https://msdn.microsoft.com/query/dev14.query?appId=Dev14IDEF1&l=EN-US&k=k(C4996)&rd=true.



Soliciting Advice
I haven't looked into how much work replacing all the function calls would be. There are about 68 total deprecated function calls of these 3 functions. I'm guessing it would be best to replace them for forward compatibility, but not sure if this is a Microsoftism or actually a good thing to do?

I'm currently compiling IUnit into a static library that folds the Outpost Monopoly DLL as opposed to relying on OP2Extra.DLL. I'm doing this based on what Arklon mentioned and because it is easier for me (I have no experience dealing with linking to DLLs in C++ projects since I've been doing static libraries so far). Just want to make sure using IUnit as a static library is the choice before assuming.

Challenge of the day, does anyone have an idea on how to read the attached dice roll? See attached pic. (I haven't the foggiest idea)

« Last Edit: October 08, 2016, 03:28:23 AM by Vagabond »

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4955
Re: Outpost Monopoly Download
« Reply #22 on: October 09, 2016, 02:16:17 PM »
Good job.

Disabling the warnings seems like a good first step to get the project working. Ideally you'd want to make changes to avoid warnings. Those new function are an attempt to reduce problems with buffer overflow bugs (which often lead to remote code execution vulnerabilities). I believe those replacement functions were initially made by Microsoft, and eventually adopted into the C11 standard. I'm not sure how portable they are currently. The new functions don't seem to exist on Linux for me, and I remember portability being an issue for them back in the day. There are a number of functions available to copy and concatenate strings, so you may have a choice of functions to use as a replacement.

It might help to read the strcpy Documentation.

Perhaps an easy to use alternative is snprintf.

Security note for snprintf: Don't pass arbitrary strings as the format parameter for safety and security reasons. The format string will be scanned for special characters that can affect output. Example:

Code: [Select]
snprintf(dest, destSize, "Hello World"); // Works, but beware of this form. The string is scanned for special characters.
snprintf(dest, destSize, source); // Bad idea if source comes from an untrusted source
snprintf(dest, destSize, "Hello World %x %x %x %x %x ..."); // Not a simple string copy. This will do a hex dump of your call stack
snprintf(dest, destSize, "%s", source); // This is fine. The format string says insert a string here from the following parameters. The following parameter is a data string which is not scanned for special characters.

Feel free to post some sample code changes if you like. It never hurts to get a second set of eyes to look over C string processing code. C string processing is kind of simple stupid in how it works, yet at the same time can have many subtle implications that are not obvious. Things tend to work for the expected design case, but can fail for unexpected edge cases. It's not the nicest language to do string processing in, particularly if you don't trust your input. Granted there are many cases where these concerns simply don't matter.

With that said, I'm pretty sure you can find something that works.


The static library part sounds like a good idea.

No idea about the dice roll.

Offline Vagabond

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1015
Re: Outpost Monopoly Download
« Reply #23 on: October 09, 2016, 09:32:07 PM »
Hooman, I'll look some of the options you pointed out for replacing the functions.

I roped my wife into playing Outpost Monopoly with me to test it out. After making it around the board about 2-3 time, the game crashed due to a divide by zero error. So, there is currently at least one crashing bug.

After playing for a while, we thing the dice is rolling multiple times per turn and just using the final roll. Hopefully it won't be too far to fix this.

I'm having difficulty modifying the code due to the colorful formatting practices of the previous author. See the Hook function below for an example (the entire code block is one function).  :-\

Code: [Select]
void Hook (char* chatText, int sourcePlayerNum)
{
    char string[10] = "", argument1[10] = "", argument2[10] = "";;
    int wordLength;
    bool errored = false, targetPlayerFound = false, cardFound = false;
    if (strncmp (chatText, "/trade", 6) == false) //If the message starts with the trade command
    {
        //Skip the /trade tag from the message string
        wordLength = strcspn(chatText, " .,?!");
        strncpy(string, chatText, wordLength);
        strcpy (chatText, chatText + wordLength + 1);
        //Store the first argument, be it the words "lot" or "goojf" or the amount of money to be traded.
        wordLength = strcspn(chatText, " .,?!");
        strncpy(string, chatText, wordLength);
        strcpy (chatText, chatText + wordLength + 1);

        if (strncmp (string, "lot", 3) == false) //If lot trading has been called
        {
            //Store the number of the lot to be traded
            wordLength = strcspn(chatText, " .,?!");
            strncpy(argument1, chatText, wordLength);
            strcpy (chatText, chatText + wordLength + 1);
            //Skip the intermediate word, formally "to"
            wordLength = strcspn(chatText, " .,?!");
            strncpy(argument2, chatText, wordLength);
            strcpy (chatText, chatText + wordLength + 1);
            //Store the target player, who will receive the lot
            wordLength = strcspn(chatText, " .,?!");
            strncpy(argument2, chatText, wordLength);
            if (isdigit(argument2[0]) != false)
                if (atoi(argument2) > 0 && atoi(argument2) <= TethysGame::NoPlayers()) //If the target player exists
                {
                    for (i = 0; i < noActivePlayers; i++)
                        if (PlayerOrder[i].IsPlayerNo == atoi(argument2) - 1)
                        {
                            if (atoi(argument2) != Lands[atoi(argument1)].Owner + 1) //If the target is not the sender
                                if (Lands[atoi(argument1)].Owner == sourcePlayerNum) //If the sender owns the lot to be traded
                                    if (isdigit(argument1[0]) != false)
                                        if (atoi(argument1) > 0 && atoi(argument1) < 40) //If in the list
                                            if (atoi(argument1) == 5 || atoi(argument1) == 12 || atoi(argument1) == 15 || atoi(argument1) == 25 || atoi(argument1) == 28 || atoi(argument1) == 35) //If Utility/Railroad, simply trade
                                                TradeLot(atoi(argument1), atoi(argument2) - 1, sourcePlayerNum, chatText);
                                                else if (Lands[atoi(argument1)].Housing == 0) TradeLot(atoi(argument1), atoi(argument2) - 1, sourcePlayerNum, chatText); //If upgradable lot, check for 0 houses and trade
                                                        else {strcpy(chatText, "Can't trade upgraded lots."); TethysGame::AddGameSound (sndBld_not, -1);}
                                            else {strcpy(chatText, "Not a lot."); TethysGame::AddGameSound (sndBld_not, -1);}
                                        else {strcpy(chatText, "Must input a lot &n&u&m&b&e&r."); TethysGame::AddGameSound (sndBld_not, -1);}
                                    else {strcpy(chatText, "You don't own that lot."); TethysGame::AddGameSound (sndBld_not, -1);}
                                else {strcpy(chatText, "Can't trade to yourself."); TethysGame::AddGameSound (sndBld_not, -1);}
                            targetPlayerFound = true;
                            break;
                        } else;
                if (targetPlayerFound == false) {strcpy (chatText, "Player is no longer active."); TethysGame::AddGameSound (sndBld_not, -1);}
                }
                    else {strcpy (chatText, "No such player."); TethysGame::AddGameSound (sndBld_not, -1);}
                else {strcpy(chatText, "Must input a player &n&u&m&b&e&r."); TethysGame::AddGameSound (sndBld_not, -1);}
        }
            else if (strncmp (string, "goojf", 5) == false) // If GOoJF card trading is called
                {
                    //Skip the intermediate word, formally "to"
                    wordLength = strcspn(chatText, " .,?!");
                    strncpy(argument1, chatText, wordLength);
                    strcpy (chatText, chatText + wordLength + 1);
                    //Store the target player, who will receive the card
                    wordLength = strcspn(chatText, " .,?!");
                    strncpy(argument1, chatText, wordLength);

                    for (j = 2; j >= 0; j--) //Find an owned GOoJF card
                        if (GOOJF[j] == sourcePlayerNum) //Make sure it's owned by the sender
                        {
                            if (isdigit(argument1[0]) != false)
                                if (atoi(argument1) > 0 && atoi(argument1) <= TethysGame::NoPlayers()) // If the target player exists
                                {
                                    for (i = 0; i < noActivePlayers; i++)
                                        if (PlayerOrder[i].IsPlayerNo == atoi(argument1) - 1)
                                        {
                                            if (atoi(argument1) != sourcePlayerNum + 1) TradeGOoJF(j, atoi(argument1) - 1, sourcePlayerNum, chatText); //If the target is not the sender, send card
                                                else {strcpy(chatText, "Can't trade to yourself."); TethysGame::AddGameSound (sndBld_not, -1);}
                                            targetPlayerFound = true;
                                            break;
                                        }
                                    if (targetPlayerFound == false) {strcpy (chatText, "Player is no longer active."); TethysGame::AddGameSound (sndBld_not, -1);}
                                }
                                else {strcpy(chatText, "No such player."); TethysGame::AddGameSound (sndBld_not, -1);}
                            else {strcpy(chatText, "Must input a player &n&u&m&b&e&r."); TethysGame::AddGameSound (sndBld_not, -1);}
                            cardFound = true;
                            break;
                        }
                    if (cardFound == false) {strcpy (chatText, "You don't own a GOoJF card."); TethysGame::AddGameSound (sndBld_not, -1);}
                }
                    else if (atoi(string) > 0) //If ore trading is called
                        {
                            //Skip the intermediate word, formally "to"
                            wordLength = strcspn(chatText, " .,?!");
                            strncpy(argument1, chatText, wordLength);
                            strcpy (chatText, chatText + wordLength + 1);
                            //Store the target player, who will receive the ore
                            wordLength = strcspn(chatText, " .,?!");
                            strncpy(argument1, chatText, wordLength);

                            if (isdigit(argument1[0]) != false)
                                if (atoi(argument1) > 0 && atoi(argument1) <= TethysGame::NoPlayers()) // If the target player exists
                                {
                                    for (i = 0; i < noActivePlayers; i++)
                                        if (PlayerOrder[i].IsPlayerNo == atoi(argument1) - 1)
                                        {
                                            if (atoi(argument1) != sourcePlayerNum + 1) //If the target is not the sender
                                                if (Player[sourcePlayerNum].Ore() >= atoi(string)) TradeOre(atoi(string), atoi(argument1) - 1, sourcePlayerNum, chatText); //If the sender has enough ore, trade
                                                    else {strcpy (chatText, "You do not have enough ore!"); TethysGame::AddGameSound (sndBld_not, -1);} //Errors
                                                else {strcpy(chatText, "Can't trade to yourself."); TethysGame::AddGameSound (sndBld_not, -1);}
                                            targetPlayerFound = true;
                                            break;
                                        }
                                    if (targetPlayerFound == false) {strcpy (chatText, "Player is no longer active."); TethysGame::AddGameSound (sndBld_not, -1);}
                                }
                                    else {strcpy(chatText, "No such player."); TethysGame::AddGameSound (sndBld_not, -1);}
                                else {strcpy(chatText, "Must input a player &n&u&m&b&e&r."); TethysGame::AddGameSound (sndBld_not, -1);}
                        }
                else errored = true; //Worst error possible
    }
        else if (strncmp (chatText, "/pay jail", 9) == false)
                if (PlayerOrder[playerTurn].IsPlayerNo == sourcePlayerNum)
                    if (Jail[sourcePlayerNum].Jailed == true)
                    {
                        for (i = 0; i < 3; i++)
                            if (GOOJF[i] == sourcePlayerNum)
                            {
                                GOOJF[i] = -1;
                                Jail[sourcePlayerNum].Jailed = false;
                                strcpy (chatText, "Released from jail with a GOoJF.");
                                TethysGame::AddGameSound (sndSavnt277, -1);
                                break;
                            }
                                else {strcpy (chatText, "You don't own a GOoJF."); TethysGame::AddGameSound (sndBld_not, -1);}
                        if (Player[sourcePlayerNum].Ore() >= 50 && Jail[sourcePlayerNum].Jailed == true)
                        {
                            Player[sourcePlayerNum].SetOre(Player[sourcePlayerNum].Ore()-50);
                            Jail[sourcePlayerNum].Jailed = false;
                            strcpy (chatText, "Released from jail on bail of 50.");
                            TethysGame::AddGameSound (sndSavnt277, -1);
                        }
                    }
                        else {strcpy(chatText, "Not Jailed."); TethysGame::AddGameSound (sndBld_not, -1);}
                    else {strcpy(chatText, "Not your turn."); TethysGame::AddGameSound (sndBld_not, -1);}
                else if (strncmp (chatText, "/kick", 5) == false)
                        if (sourcePlayerNum == 0)
                        {
                            //Skip the /kick tag
                            wordLength = strcspn(chatText, " .,?!");
                            strncpy(argument1, chatText, wordLength);
                            strcpy (chatText, chatText + wordLength + 1);
                            //Store the target player, who will be kicked
                            wordLength = strcspn(chatText, " .,?!");
                            strncpy(argument1, chatText, wordLength);
                            if (atoi(argument1) > 0 && atoi(argument1) <= TethysGame::NoPlayers())
                                if (atoi(argument1) != sourcePlayerNum + 1)
                                {
                                    RemovePlayer (atoi(argument1) - 1);
                                    if (leavingPlayerFound == true)
                                    {
                                        strcpy (chatText, "Player ");
                                        char dumpstring[8] = "";
                                        strcat (chatText, argument1); strcat (chatText, " has been kicked from the game.");
                                    }
                                        else {strcpy(chatText, "Already left the game."); TethysGame::AddGameSound (sndBld_not, -1);}
                                }
                                    else {strcpy(chatText, "Can't kick yourself."); TethysGame::AddGameSound (sndBld_not, -1);}
                                else {strcpy(chatText, "No such player."); TethysGame::AddGameSound (sndBld_not, -1);}
                        }
                            else {strcpy(chatText, "Only the host can kick."); TethysGame::AddGameSound (sndBld_not, -1);}
                            else if (strncmp (chatText, "/quit", 5) == false)
                                {
                                    RemovePlayer (sourcePlayerNum);
                                    if (leavingPlayerFound == true)
                                    {
                                        strcpy (chatText, "Player ");
                                        char dumpstring[8] = "";
                                        strcat (chatText, itoa(sourcePlayerNum + 1, dumpstring, 10)); strcat (chatText, " has quit the game.");
                                    }
                                        else {strcpy(chatText, "Already left the game."); TethysGame::AddGameSound (sndBld_not, -1);}
                                }
                                    else if (strncmp (chatText, "/start", 6) == false)
                                        {
                                            //Skip the /start tag
                                            wordLength = strcspn(chatText, " .,?!");
                                            strncpy(argument1, chatText, wordLength);
                                            strcpy (chatText, chatText + wordLength + 1);
                                            //Store the multiplier
                                            wordLength = strcspn(chatText, " .,?!");
                                            strncpy(argument1, chatText, wordLength);
                                            if (sourcePlayerNum == 0)
                                                if (isdigit(argument1[0]) != false)
                                                    if (boolMustInsert == true)
                                                    {
                                                        for (i = 0; i < noActivePlayers; i++)
                                                            Player[i].SetOre(Player[i].Ore() * atoi(argument1) / 10);
                                                        strcpy(chatText, "Starting ore altered by host.");
                                                    }
                                                        else {strcpy(chatText, "Can no longer alter starting money."); TethysGame::AddGameSound (sndBld_not, -1);}
                                                    else {strcpy(chatText, "Must input a &n&u&m&b&e&r."); TethysGame::AddGameSound (sndBld_not, -1);}
                                                else {strcpy(chatText, "Only host can alter starting money."); TethysGame::AddGameSound (sndBld_not, -1);}
                                        }
    if (errored == true) {strcpy(chatText, "Unrecognized trade command."); TethysGame::AddGameSound (sndBld_not, -1);}//Send the worst error psossible
}

Offline Hooman

  • Administrator
  • Hero Member
  • *****
  • Posts: 4955
Re: Outpost Monopoly Download
« Reply #24 on: October 10, 2016, 11:06:42 AM »
Good to hear you're still working on this.


That's a rather large function. I'm glad you didn't ask me anything specific about it. ;) I generally recommend refactoring code to keep functions down to one screen of code. It's easier to understand code when you can read it in its entirety without having to scroll.

It looks like there is some repetition in the code. That's usually a good sign something can be refactored into a separate function. For instance, there a few cases where a string is checked for a given prefix, and then the prefixed is skipped over, with processing continuing on the remaining part of the string. You can make a function that checks for a given prefix and returns the substring following that prefix if found, or null if not found. That would make it easy to write code such as:
Code: [Select]
if (remainingString = hasPrefix(originalString, "HardCodedPrefixToCheckFor")) {
  // Use remainingString ...
}

This will probably cut down on the number of occurrences of string processing functions that need to be updated. You should also be able to do without copying the string, just using pointer adjustments.

It might also be reasonable to move the bodies of the if statements into their own functions.

A further step might be to process string data without copying it. You shouldn't need to copy a numeric substring just to convert it to an integer (atoi). Pointer adjustments and possibly bounding can work here. I'll comment on this more if you want to look into this.