So thanks to Hoomans help, and a light bulb nudge from g2 (if he shows up, I think he wanted to help out with this, or try something on his own) I am trying to make a Colony Game myself.
A lot of this is from help by everyone else around here (SirBomber's tutorials mostly) and the resident coding Monk Hooman (it was either that description or a robot ie: knows everything, always helpful, no emotion, like zero) , I prefer a Monk, stoic, relaxed, knowledgeable, but easily distracted, anyways I digress...
However, this would be using an entirely newly structured Tech Tree. Providing a favorable response I am hoping to take this new tree and cut it down into something easier to use for multiplayer games. (Also, I hope to add some thievery tech and coding in as well!)
What I am stuck on is how wildly different should the tech tree be?
- I want something that feels more linear**, uses all three lab buildings (which incurs consequences for losing the Basic Lab as you only get to build it once, it's immediately replaced with the Standard Lab once it becomes available per OP2 coding)
- It can't be so foreign that switching back to the regular tech tree is frustrating, all though I may not entirely care so much as change should be good
- I am stuck on weapons balancing, is it types of weapons, when there available or distance/damage inflicted that seems to be the problem?
- More tech to research, like a lot more or just a little?
Here's the code that allows some of the tech tree to function ie: you can choose to follow two different broad scope Weapons Research paths
//Create Research Triggers for the different paths of weapons tech
CreateResearchTrigger(1, 1, 6101, 0, "VisibleAResearched");
CreateResearchTrigger(1, 1, 6102, 0, "VisibleBResearched");
//This saves the research choice for Weapons Tech and exports the
//saved variable when in a colony game
struct ScriptGlobal
{
int researchChoice;
} scriptGlobal;
ExportSaveLoadData(scriptGlobal);
Hooman could give me crap for this one as I haven't changed it yet, It's simpler for me to read even if the code itself could be cleaner.
But...whatever, that's me.
Export void VisibleAResearched()
{
// Exit if a choice has already been made
if (scriptGlobal.researchChoice != 0) return;
// Mark the choice as having been made, never to be changed again
scriptGlobal.researchChoice = 1;
// Make visible tech B disappear as a research option
// because tech 'A' was chosen
Player[0].MarkResearchComplete(6102);
// Unlock the chosen tech tree
Player[0].MarkResearchComplete(6103);
};
Export void VisibleBResearched()
{
// Exit if a choice has already been made
if (scriptGlobal.researchChoice != 0) return;
// Mark the choice as having been made, never to be changed again
scriptGlobal.researchChoice = 2;
// Make visible tech A disappear as a research option
// because tech 'B' was chosen
Player[0].MarkResearchComplete(6101);
// Unlock the chosen tech tree
Player[0].MarkResearchComplete(6104);
};
** when I say linear, some of the way tech tree direction is in the current multitek file makes it more of a headache rather than usable, for instance I felt Efficiency Engineering should be done BEFORE Advanced structure and unit designs ie: Advanced Res, Advanced Armoring, etc etc, but that's me.
Anywho... thoughts?
p.s. - I now realize I posted this in the coding section, it's part Colony game, part tech tree rewriting, part coding. If there is a better place for it please throw it in there.
I'm having trouble with randomizing Player Start Colony, c++ and OP2 coding are not cooperating
add this to top of main.cpp
#include <cstdlib>
and then use this code
//Set player base type ie: random pick eden or plymouth
{ int colonyStart = rand() % 2;
if (colonyStart != 0)
{ Player[0].GoEden; }
else
{ Player[0].GoPlymouth; }
return 0;
}
regardless of what I do, as soon as I put the Player[0].GoEden statement in anything or based off something I keep getting error statements
1>Main.cpp(81): error C3867: '_Player::GoEden': non-standard syntax; use '&' to create a pointer to member
1>Main.cpp(85): error C3867: '_Player::GoPlymouth': non-standard syntax; use '&' to create a pointer to member
The hell am I doing wrong?
//Set player base type ie: random pick eden or plymouth
{
srand (time(NULL));
int colonyStart = rand() % 2;
if (colonyStart != 0)
{
Player[0].GoEden();
}
else
{
Player[0].GoPlymouth();
}
return 0;
}
Should stick with typical C++ code design paradigms.
Alternatively this code could be reduced to this:
//Set player base type ie: random pick eden or plymouth
{
srand (time(NULL));
int colonyStart = rand() % 2;
colonyStart != 0 ? Player[0].GoEden() : Player[0].GoPlymouth();
return 0;
}
Note that I am seeding the random number generator (RNG) from within what appears to be a smaller code block. Generally I wouldn't do this, I'm simply illustrating why you're getting the same result time and time again.
I would instead seed the RNG from the entry point function (the first function/method called in your program). I don't remember which one that is in the OP2 SDK.
Also make sure you're including the time.h library at the beginning of your code (usually top of the file) if it hasn't already been included:
Done and done. Works mint.
Code I currently got in int InitProc()
//Set player, random as either Eden or Plymouth
{ srand(time(NULL));
int colonyStart = rand() % 2;
if (colonyStart != 0)
Player[0].GoEden();
else
Player[0].GoPlymouth();
}
though I do get this error message
1>Main.cpp(81): warning C4244: 'argument': conversion from 'time_t' to 'unsigned int', possible loss of data
Builds and plays fine. Oh well. On to the next problem...which will be Hooman might kill me if I don't at least start to help with the parser. I get distracted...
Thanks @Leeor and @SirBomber!
Use TethysGame::GetRand for random numbers.
int colonyStart = TethysGame::GetRand(2);
Details can be found in the Outpost2DLL SDK package in TethysGame.h:
static int __fastcall GetRand(int range); // Returns a number from 0..(range-1)
Using the built in pseudo random number generator has a few benefits:
- The built-in generator is already seeded before DLL code is called, so you don't need to seed it yourself.
- The state of the built-in generator is saved to saved game files, so results are consistent when you load.
- The seed is shared between all clients in a multiplayer game, ensuring consistent results between machines.
That last point is really the key one. Do not use srand(time(NULL)) and rand() in a multiplayer game DLL. The game will almost certainly desync. You might get away with it in single player, but you should just stick to using the built in random number generator in all cases.
As for that error message, it's confusing the first and last cases when you give it the middle case:
Player[0].GoEden() // Function call
Player[0].GoEden // Name of a function, useless on it's own, grammatically incomplete
&Player[0].GoEden // Address of a function