Inightshade
Chieftain
Alright! Its possible I'm just doing something horribly wrong, but lets start anyways.
Shortened to ease people looking for possible answers. But will keep as a testament to my failures
This is about the Lua Team:Calls() and the internal oops that is their C methods.
At face value, one would assume that a call as bland as :Meet() would work like this:
pPlayerOne:Meet(pPlayerTwo); -- And poof, player 1 meets player 2.
Short answer: No. Nowhere even close.
Step One: The code--
//void meet(TeamTypes eTeam, bool bSuppressMessages);
int CvLuaTeam::lMeet(lua_State* L)
{
CvTeam* pkTeam = GetInstance(L);
TeamTypes eOtherTeam = (TeamTypes)lua_tointeger(L, 2);
const bool bSuppressMessages = lua_toboolean(L, 3);
pkTeam->meet(eOtherTeam, bSuppressMessages);
return 0;
}
Yep, straight out of the source. The lua call takes the caller (pPlayerOne:Meet(pPlayerTwo);
and the first variable (pPlayerOne:Meet(pPlayerTwo);
and a the second variable. (if its not there lua defaults null to false)
Then sends this off to the C meet method, which requires all three of these.
So? What gives?
Step B:
Why, oh gods why does this:
function(pPlayerImported)
local pTeamImported = Teams[pPlayerImported:GetTeam()];
for id, pPlayerOther in pairs(Players) do -- Cycle all civs
-- remove non-major powers and dead players!
if (pPlayerOther ~= pPlayerImported and not pPlayerOther:IsMinorCiv() and not pPlayerOther:IsBarbarian() and pPlayerOther:IsEverAlive()) then
-- meet
local pTeamOther = Teams[pPlayerOther:GetTeam()];
pTeamImported:Meet(pTeamOther, true);
--pTeamOther:Meet(pTeamImported, true);
end
end
end
not work as expected?
Well, technically it DOES work.
But
Not as one would expect...
Here is the results:
Case: Imported is the player in sp; there are no others who match the restrictions for 'Imported'
Nothing. You don't meet anyone.
Case2: Imported is NOT the player in sp; player is also not passing 'imported' filtering.
Poof! You meet the AI who pass filtering.
Case3: exchange the two different :Meet() lines; same as Case1.
Poof! You meet the AI!
Case4: same but for case2.
Um? You meet all BUT the AI who meet the conditions to start the function?
So? It can be twisted to "work" for the human in sp.
So what gives? Well lets take a look at the AI's PoV.
Case1: Nothing.
Case2: You meet ONLY the human in sp
Case3: Each AI meets ONLY the human in sp.
Case4: ? The AI who passes meets no one, the AI who fail meet ONLY the Human.
Strange...
But Multiplayer is even stranger. No matter what, the second player will NEVER meet anyone. Period.
So lets look at the C code... Maybe it'll tell us what's going on...
void CvTeam::meet(TeamTypes eTeam, bool bSuppressMessages)
{
if(!isHasMet(eTeam))
{
makeHasMet(eTeam, bSuppressMessages);
GET_TEAM(eTeam).makeHasMet(GetID(), bSuppressMessages);
ICvEngineScriptSystem1* pkScriptSystem = gDLL->GetScriptSystem();
if(pkScriptSystem)
{
CvLuaArgsHandle args(2);
args->Push(eTeam);
args->Push(GetID());
bool bResult;
LuaSupport::CallHook(pkScriptSystem, "TeamMeet", args.get(), bResult);
}
}
}
This is the first piece. Where the Lua goes with that pkTeam->meet.
So my MsVis can't discern where pkTeam->meet is suppose to go, it gets confused between CvTeam.cpp and CvTeam.h (though .h only defines) but looking at this one doesn't see any inherent flaws.
We are executed via a pkTeam, importing eTeam and a bool. A basic sterilization check at the start, (something else that is broken, btw) then make them meet. The rest sets the hook for the event.
So? Maybe makeHasMet?
void CvTeam::makeHasMet(TeamTypes eIndex, bool bSuppressMessages)
{
int iI;
CvAssertMsg(eIndex >= 0, "eIndex is expected to be non-negative (invalid Index)");
CvAssertMsg(eIndex < MAX_TEAMS, "eIndex is expected to be within maximum bounds (invalid Index)");
if(!isHasMet(eIndex))
{
m_abHasMet[eIndex] = true;
SetTurnTeamMet(eIndex, GC.getGame().getGameTurn());
updateTechShare();
//... Removed for brevity
// Report event
gDLL->GameplayMetTeam(GetID(), eIndex);
}
}
Okay, again, nothing wrong? we check again if they have met (redundant?) and perform the expected actions. The cut is just related to ALWAYS_WAR.
So, theoretically...
Shouldn't this: pPlayerOne:Meet();
And this: pPlayerOne:Meet(Firaxis Why!);
Return different results? (or throw errors?) But they don't...
Actually...
They perform the EXACT same as: pPlayerOne:Meet(pPlayerTwo, true);
So?
What gives? (EDIT: checked vs a unmodded game (just the short lua code) and same results :/ )
(sorry you'll have to either figure out your self and tell me or wait until I find it )
(but mayhaps someone has some insight to this matter.)
Shortened to ease people looking for possible answers. But will keep as a testament to my failures
Spoiler :
This is about the Lua Team:Calls() and the internal oops that is their C methods.
At face value, one would assume that a call as bland as :Meet() would work like this:
pPlayerOne:Meet(pPlayerTwo); -- And poof, player 1 meets player 2.
Short answer: No. Nowhere even close.
Step One: The code--
Spoiler :
//void meet(TeamTypes eTeam, bool bSuppressMessages);
int CvLuaTeam::lMeet(lua_State* L)
{
CvTeam* pkTeam = GetInstance(L);
TeamTypes eOtherTeam = (TeamTypes)lua_tointeger(L, 2);
const bool bSuppressMessages = lua_toboolean(L, 3);
pkTeam->meet(eOtherTeam, bSuppressMessages);
return 0;
}
Yep, straight out of the source. The lua call takes the caller (pPlayerOne:Meet(pPlayerTwo);
and the first variable (pPlayerOne:Meet(pPlayerTwo);
and a the second variable. (if its not there lua defaults null to false)
Then sends this off to the C meet method, which requires all three of these.
So? What gives?
Step B:
Why, oh gods why does this:
Spoiler :
function(pPlayerImported)
local pTeamImported = Teams[pPlayerImported:GetTeam()];
for id, pPlayerOther in pairs(Players) do -- Cycle all civs
-- remove non-major powers and dead players!
if (pPlayerOther ~= pPlayerImported and not pPlayerOther:IsMinorCiv() and not pPlayerOther:IsBarbarian() and pPlayerOther:IsEverAlive()) then
-- meet
local pTeamOther = Teams[pPlayerOther:GetTeam()];
pTeamImported:Meet(pTeamOther, true);
--pTeamOther:Meet(pTeamImported, true);
end
end
end
not work as expected?
Well, technically it DOES work.
But
Not as one would expect...
Here is the results:
Case: Imported is the player in sp; there are no others who match the restrictions for 'Imported'
Nothing. You don't meet anyone.
Case2: Imported is NOT the player in sp; player is also not passing 'imported' filtering.
Poof! You meet the AI who pass filtering.
Case3: exchange the two different :Meet() lines; same as Case1.
Poof! You meet the AI!
Case4: same but for case2.
Um? You meet all BUT the AI who meet the conditions to start the function?
So? It can be twisted to "work" for the human in sp.
So what gives? Well lets take a look at the AI's PoV.
Case1: Nothing.
Case2: You meet ONLY the human in sp
Case3: Each AI meets ONLY the human in sp.
Case4: ? The AI who passes meets no one, the AI who fail meet ONLY the Human.
Strange...
But Multiplayer is even stranger. No matter what, the second player will NEVER meet anyone. Period.
So lets look at the C code... Maybe it'll tell us what's going on...
Spoiler :
void CvTeam::meet(TeamTypes eTeam, bool bSuppressMessages)
{
if(!isHasMet(eTeam))
{
makeHasMet(eTeam, bSuppressMessages);
GET_TEAM(eTeam).makeHasMet(GetID(), bSuppressMessages);
ICvEngineScriptSystem1* pkScriptSystem = gDLL->GetScriptSystem();
if(pkScriptSystem)
{
CvLuaArgsHandle args(2);
args->Push(eTeam);
args->Push(GetID());
bool bResult;
LuaSupport::CallHook(pkScriptSystem, "TeamMeet", args.get(), bResult);
}
}
}
This is the first piece. Where the Lua goes with that pkTeam->meet.
So my MsVis can't discern where pkTeam->meet is suppose to go, it gets confused between CvTeam.cpp and CvTeam.h (though .h only defines) but looking at this one doesn't see any inherent flaws.
We are executed via a pkTeam, importing eTeam and a bool. A basic sterilization check at the start, (something else that is broken, btw) then make them meet. The rest sets the hook for the event.
So? Maybe makeHasMet?
Spoiler :
void CvTeam::makeHasMet(TeamTypes eIndex, bool bSuppressMessages)
{
int iI;
CvAssertMsg(eIndex >= 0, "eIndex is expected to be non-negative (invalid Index)");
CvAssertMsg(eIndex < MAX_TEAMS, "eIndex is expected to be within maximum bounds (invalid Index)");
if(!isHasMet(eIndex))
{
m_abHasMet[eIndex] = true;
SetTurnTeamMet(eIndex, GC.getGame().getGameTurn());
updateTechShare();
//... Removed for brevity
// Report event
gDLL->GameplayMetTeam(GetID(), eIndex);
}
}
Okay, again, nothing wrong? we check again if they have met (redundant?) and perform the expected actions. The cut is just related to ALWAYS_WAR.
So, theoretically...
Shouldn't this: pPlayerOne:Meet();
And this: pPlayerOne:Meet(Firaxis Why!);
Return different results? (or throw errors?) But they don't...
Actually...
They perform the EXACT same as: pPlayerOne:Meet(pPlayerTwo, true);
So?
What gives? (EDIT: checked vs a unmodded game (just the short lua code) and same results :/ )
(sorry you'll have to either figure out your self and tell me or wait until I find it )
(but mayhaps someone has some insight to this matter.)