 |
|  |
 |
|
Locutus
|
|
ACS CTP1/2 Manager & Civ4 Co-Manager
|
 |
Hengelo, The Netherlands
Nov 1999 time: 06:20
|
|
Well, for one thing, this line is a little messed up:
code: for (i=0;i if (IsPlayerAlive(i)){
I think you meant to say:
code: for (i=0; i <= CTC_PLAYER_COUNT; i = i + 1){
if (IsPlayerAlive(i)){
You probably hit the delete key a couple of times without realizing it I'm not sure if this was a mistake you made when writing this code or just when posting it here (I suspect the latter), but it certainly wouldn't run like this.
Another mistake you made is this:
tmpPlayer = player[i];
player[4] is NOT the 4th player in your current game, which I think you assumed. Player[4] is just a variable that needs to be given a value before it can be used. Player[0] is always given a value by the BeginTurn event: it's filled with the player who's turn it is. Player[1], player[2], etc... are all empty and meaningless in case of a BeginTurn event (actually, they're not empty as SLIC doesn't support 'empty' players, they're 0 -- the Barbarian player), though you can put a value in it yourself if you want to, just like you can with tmpPlayer or any other variable. If you want to access player 4, you can just use '4'. So this:
tmpPlayer = i;
would get the job done (or you could just use 'i' and get rid of 'tmpPlayer' altogether). So the working code should look like this:
code: int_t CTC_PLAYER_COUNT;
HandleEvent(BeginTurn) 'AOM_CivTraits' pre {
int_t livePlayers;
int_t i;
int_t j;
int_t tmpPlayer;
city_t tmpCity;
if (g.year == 10){
CTC_PLAYER_COUNT= preference("NumPlayers");
for (i=0; i <= CTC_PLAYER_COUNT; i = i + 1){
if (IsPlayerAlive(i)){
tmpPlayer = i;
if (PlayerCivilization(i)==CivlizationIndex("AMERICANS")){
for(j = 0; j < PlayerCityCount(tmpPlayer); j = j + 1){
GetCitybyIndex(tmpPlayer,j, tmpCity);
if(CityHasBuilding(tmpCity,"IMPROVE_CAPITOL")){
Event:CreateWonder(tmpCity, WonderDB(Wonder_SCIENCE_A));
}
} elseif (PlayerCivilization(i)==CivlizationIndex("JAPANESE")){
for(j = 0; j < PlayerCityCount(tmpPlayer); j = j + 1){
GetCitybyIndex(tmpPlayer,j, tmpCity);
if(CityHasBuilding(tmpCity,"IMPROVE_CAPITOL")){
Event:CreateWonder(tmpCity, WonderDB(Wonder_MILITARY_A));
}
}
}
}
}
}
}
That being said, your code can probably be simpified so that you don't even need to do that. I suspect you didn't realize that there's already a variable player.capital, so you don't really have to manually scan all cities for a capitol building. Using the player.capital variable saves a lot of work and also makes the execution of the code much more efficient. The only possible downside would be that I'm not sure what would happen in case a player doesn't have a capital (probably nothing, as in your code). So a more efficient version of the code would be this:
code: int_t CTC_PLAYER_COUNT;
HandleEvent(BeginTurn) 'AOM_CivTraits' pre {
int_t livePlayers;
int_t i;
int_t j;
int_t tmpPlayer;
city_t tmpCity;
if (g.year == 10){
CTC_PLAYER_COUNT= preference("NumPlayers");
for (i=0; i <= CTC_PLAYER_COUNT; i = i + 1){
if (IsPlayerAlive(i)){
if (PlayerCivilization(i)==CivlizationIndex("AMERICANS")){
Event:CreateWonder(player[i].capital, WonderDB(Wonder_SCIENCE_A));
} elseif (PlayerCivilization(i)==CivlizationIndex("JAPANESE")){
Event:CreateWonder(player[i].capital, WonderDB(Wonder_MILITARY_A));
}
}
}
}
}
Yet there might be even more we can do to improve your code: if I understand correctly, this code should give a unique wonder to each civ (or at least a number of civs) at the start of the game. To make sure every civs gets its wonder, you wait until turn 10 before giving these wonders, as not everyone founds their city in the first turn. However, what if by some freak accident some civ doesn't found their first city within the first 10 turns? They'll miss their wonder... Also, now players will have to go 10 turns without their wonder (which might be just what you want, but odds are you don't).
A more elegant way to do the same thing, would be to run the code when a city is founded, not at the begin of the turn. That would simplify things even further:
code: int_t AOM_TRAITS_GIVEN[]; // keep track of to which players traits have been given (index is player)
HandleEvent(CreateCity) 'AOM_CivTraits' post {
int_t tmpPlayer;
city_t tmpCity;
tmpPlayer = player[0]; // the player who created the city
tmpCity = city[0]; // the city that was just created
if (AOM_TRAITS_GIVEN[tmpPlayer] == 0) { // if traits have not been given yet...
if (PlayerCivilization(tmpPlayer)==CivlizationIndex("AMERICANS")){
Event:CreateWonder(tmpCity, WonderDB(Wonder_SCIENCE_A));
} elseif (PlayerCivilization(tmpPlayer)==CivlizationIndex("JAPANESE")){
Event:CreateWonder(tmpCity, WonderDB(Wonder_MILITARY_A));
}
AOM_TRAITS_GIVEN[tmpPlayer] = 1; // only do this for the first city of each player
}
}
(Disclaimer: all of this code is untested, no guarantees given)
BTW, next time you post SLIC code, please put it between [ code ], [ /code ] tags (without the spaces), that makes it a little easier to read
Last edited by Locutus on 29-10-2004 at 17:56
|
|
|  |
 |
|
stankarp
|
|
australia
Feb 2002 time: 05:20
|
|
Many thanks Locutus, from an amateur to a professsional.
Currently working with two fingers and a thumb on my right hand bandaged due to a freak accident last Tuesday, sometimes don't notice the typos and it was a copy and paste error.
I was wondering about the createcity event instead, partly for the reason you said but mainly because I expect the createWonder line will delete accrued production in that city at turn 10. Thats what happened with the createBuilding command.
Now just need a DestroyWonder Code if a capital is captured otherwise the capturing civ will become far too powerful.
I have already created and loaded the wonders.txt with 44 extra wonders (1 for each player) and the game did not reject it. I am sure I read somewhere that there appears to be no limit to wonders. I can refine it further by having a wonder specific for each player, e.g. ROMAN_A for the Romans that may give a couple of traits.
One complaint I have seen is that every player is the same in CTP2. Same units, governments, techs etc.
code:
HandleEvent(CaptureCity) 'MM2_DestroyBuildsOnCapture' pre {
city_t tmpcity;
Just checking to see if this is what you meant. Aha, thats it, it works.
I think this would do the job.
code:
HandleEvent(CaptureCity) 'AOM_DestroyWondersOnCapture' pre {
city_t tmpcity;
int_t i;
int_t j;
tmpcity = city[0];
if(CityIsValid(tmpcity)) {
for(i = 0; i < 44; i = i + 1) {
j= i + 46;
DestroyWonder(tmpcity, j);
}
}
}
46 being the number of normal wonders.
|
|
|  |
 |
|
stankarp
|
|
australia
Feb 2002 time: 05:20
|
|
Thanks muchely again.
|
|
|  |
 |
|
Locutus
|
|
ACS CTP1/2 Manager & Civ4 Co-Manager
|
 |
Hengelo, The Netherlands
Nov 1999 time: 06:20
|
|
quote: Originally posted by stankarp
Currently working with two fingers and a thumb on my right hand bandaged due to a freak accident last Tuesday, sometimes don't notice the typos and it was a copy and paste error. |
Ouch, I'm sorry to hear that, I hope it's nothing serious.
quote: I was wondering about the createcity event instead, partly for the reason you said but mainly because I expect the createWonder line will delete accrued production in that city at turn 10. Thats what happened with the createBuilding command. |
Interesting, that's new for me, will have to remember that...
quote: I have already created and loaded the wonders.txt with 44 extra wonders (1 for each player) and the game did not reject it. I am sure I read somewhere that there appears to be no limit to wonders. |
Hmm, in theory CtP2 is only supposed to support 64 wonders, I'm surprised to hear you didn't have any trouble with that. You should certainly test all wonders carefully (especially those near the end of your wonders.txt file).
Maybe it went okay because you only call the extra wonders through SLIC, you can't actually build them the regular way.
quote: I think this would do the job. |
Yeah, in theory that looks fine, but I think there may actually not be a DestroyWonder function. I could be wrong, but I can't find it anywhere in the docs. Never realized that until now...
|
|
|  |
 |
|  |
 |
|  |
 |
|  |
 |
|
stankarp
|
|
australia
Feb 2002 time: 05:20
|
|
Phew, havn't seen this sort of activity in slic land for a long time.
With a bit of luck, the Wonders will be created by slic on the turn the player capital is founded, and prevented by "enableadvance SUBNEURAL_ADVANCE" from being available to other players. So the net effect is that players only get one new wonder each, and if there were 12 players, thats 12 new wonders which takes me up to a total of 58.
quote:
Yeah, in theory that looks fine, but I think there may actually not be a DestroyWonder function. I could be wrong, but I can't find it anywhere in the docs. Never realized that until now...
|
In a quick look I also could not find the destroybuilding function either, but it is there in the capturecity.slc. So I am taking a punt.
Tested it, the punt did not work. No function as you said. I gather "WonderRemoved" triggers on a Wonder becoming obsolete?
So it has to be the DisbandCity function. This could be a bit tricky. The code would have to-
-Record the size of the city, its name, what buildings survived capturecity.slc and what wonders were there lower than wonder no 47.
-Reduce city size, disband city(disband size is 6 but slic may override this).
-recreate city, add pops, createbuildings, create wonders.
The use of arrays is where I fall down with my lack of experience as I assume the details would have to be saved in a temporary array.
Any chance of some help on this one?
Thanks in advance if anyone can help.
The other choice would be to just disband the city, give the capturing player a blob of gold and a couple of nomads as compensation.
One thing I am not sure of, if you capture a wonder does the effect of that wonder transfer to you. I rarely capture wonders but I do seem to recall that the ownership details in the wonderlist in rankings do not change. ie, the player name. The city changes colour to your blue, but the player name doesnt. Suppose a quick check would be to capture Lighthouse of Alexandria and see if your ships move faster. Shall do that report back.
Also, a wonder given through cheat mode does not show up on the wonderlist, it does in city inventory.
|
|
|  |
 |
|
stankarp
|
|
australia
Feb 2002 time: 05:20
|
|
Further testing has established the following.
1) Wonders given in cheat mode do not appear in the wonder list in the rankings section, however, the effect is given to the player.
2) Wonders captured by capturing the enemy city, the name of the city where the wonder is built changes to the new player but the player (player who built it) remains as per the builder.
3) Captured wonders DO extend effects to the new owner.
|
|
|  |
 |
|
stankarp
|
|
australia
Feb 2002 time: 05:20
|
|
Made some progress.
CreateWonder will create a wonder even without the enable advance.
CreateWonder will not work in a city if it was built on that turn (I should have realised this as CreateBuilding did not work in the same circumstances).
CreateWonder allows you to create the same wonder for more than one person.
Wonders over number 64 do not extend an effect. They show up in rankings/wonder but have no home city and extend no effect.
code:
if(IsHumanPlayer(player[0])) {
CTC_PLAYER_COUNT= preference("NumPlayers");
for (i=0; i <= CTC_PLAYER_COUNT; i = i + 1){
if (IsPlayerAlive(i)){
tmpPlayer = i;
if (PlayerCivilization(i)==CivilizationIndex("ROMAN")){
for(j = 0; j < PlayerCityCount(tmpPlayer); j = j + 1){
GetCitybyIndex(tmpPlayer,j, tmpCity);
if(CityHasBuilding(tmpCity,"IMPROVE_CAPITOL")){
Event:CreateWonder(tmpCity, WonderDB(WONDER_COMMERCE_A ));
}
}
} elseif (PlayerCivilization(i)==CivilizationIndex("JAPANESE")){
for(j = 0; j < PlayerCityCount(tmpPlayer); j = j + 1){
GetCitybyIndex(tmpPlayer,j, tmpCity);
if(CityHasBuilding(tmpCity,"IMPROVE_CAPITOL")){
Event:CreateWonder(tmpCity, WonderDB(WONDER_COMMERCE_A ));
}
}
}
}
}
}
}
This code works except, both wonders appear as Rome home city, but one is player Roman and the other Japanese. However, they each only get the effect once, so even though Rome is shown as home city for both, the Romans and the Japanese get the benefit once each (in this case +100 boat movement). I cant see why they both end up as home city ROME.
code:
if (AOM_TRAITS_GIVEN[tmpPlayer] == 0)
................................................................
AOM_TRAITS_GIVEN[tmpPlayer] = 1;
If I changed the above 2 lines from Locutus' last example to
code:
if (AOM_TRAITS_GIVEN[tmpPlayer] == 1)
................................
AOM_TRAITS_GIVEN[tmpPlayer] = AOM_TRAITS_GIVEN[tmpPlayer] +1;
Would this mean it fires on the building of the second city for a player? Meaning I simply use the getcitybyindex/has building capital bits to place the wonder in city 1.
|
|
|  |
 |
|
stankarp
|
|
australia
Feb 2002 time: 05:20
|
|
A curious development. I have checked it twice with different games and the outcome was the same.
1) Wonders created using CreateWonder extend their effect in the normal way.
2) Wonders created using CreateWonder do not appear to extend their effect to a new owner.
This is the weird bit.
I checked number (2 twice in different games. Set up a game with 2 players that would get the civtrait wonder on turn 5. In each case it was the Commerce one which allowed +100 boat movement so its easy to check. Each player got the increased movement after their wonder was created. I then capture the home city of the other player. The City name changed colour to blue in the wonder list, the wonder appeared in the inventory of the captured enemy capital, but the benefit did not extend to me as the conquering player. That is, my coracle still only moved 300, not 400, an extra 100 for the second civtrait wonder I acquired.
As a further check, I waited several turns, I then let the other play rush buy Lighthouse of Alex, then capture it off them. Hey presto, my coracle now moves 4. 2 plus 1 for my civtrait wonder and 1 for the Lighthouse.
So a wonder created by CreateWonder appears to be non transferrable, maybe something to do with the wrong city appearing in the wonder list.
So therefore, at this satge I do not need a code to get rid of the wonder out of a newly captured enemy capital.
Weird but handy in this case.
|
|
|  |
 |
|  |
 |
|
stankarp
|
|
australia
Feb 2002 time: 05:20
|
|
Its a bit a pity but I have run into a snag with the CreateWonder Code. Initially it was working, now I get a CTD on the turn the wonders appear. It appears to be crashing when the message about the wonder appears, because if I reload autosave, the wonders are there and I can continue the game. Bit weird.
I thought I had made an error in wonders.txt but I went back to an old copy and tried to create an existing wonder(Stonehenge), and it still crashes. Tried it just creating one wonder with the humanplayer and it still crashes. It is as if the game had just decided to crash when I use the CreateWonder code. I even loaded an older copy of the game which had never seen the CreateWonder code in a slic file and it still does it.
So I am out of ideas.
Hex suggested trying a feat for each player with a fixed time limit. However, I cannot find a code to give a player a feat. I tried AccomplishFeat, tmpPlayer,Feat(name) but nothing happened and if I reversed it as per the slic mod list (AccomplishFeat(int_t,t)), I got a syntax error.
Has anyone used a code to give a feat?
Thanks.
|
|
|  |
 |
|
stankarp
|
|
australia
Feb 2002 time: 05:20
|
|
That should have been AccomplishFeat(int_t,), stupid bandaged thumb:-)))
|
|
|  |
 |
|
stankarp
|
|
australia
Feb 2002 time: 05:20
|
|
Argh!!!
HTML tages dont appear, so take it the AccomplishFeat bit is correct.
|
|
|  |
 |
|
stankarp
|
|
australia
Feb 2002 time: 05:20
|
|
OK, managed to find the syntax error, now have the feat working. Now to see how far I can push feats.
|
|
|  |
All times are GMT. The time now is 05:20. Apolyton Time is 00:20. |
top of page
|
|
|
Forum Rules:
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
|
HTML code is ON
vB code is ON
Smilies are ON
[IMG] code is ON
|
|
|
|
|
|