 |
|  |
 |
|
heardie
|
|
Aghh, so much for no problems with my scenario. Can anyone help with a few tricky problems (real tricky because the game works fine, just not as intended).'
1. Here is my code that should stop the people from buliding in Locations Dummy and Dummy2 which are defined elsewhere. To me the code looks good. Why doesnt it stop me from building cities and show a message?
code:
HandleEvent(CreateCity) 'WWCreateCity_F' pre {
int_t m; // Used for loop
int_t tmpNum; // How many units in the civilization
unit_t tmpUnit; // Used to see if unit lands on land
player[0] = 0;
tmpNum = player[0].units;
for(m = 0; m < tmpNum; m = m + 1){
GetUnitByIndex(player[0], m, tmpUnit);
if (tmpUnit == UnitDB(UNIT_SETTLER) | | tmpUnit == UnitDB(UNIT_SEA_ENGINEER) | | tmpUnit == UnitDB(UNIT_URBAN_PLANNER)){
if (tmpUnit.Location == Dummy | | tmpUnit.Location == Dummy2){
Message (g.player, 'WWTerrainRecommend');
return STOP;
}
else {
return 0;
}
}
}
}
2. Here is some non-working code that should display a messagebox when you bulid in location Dummy3, but alas it is also not working.
code:
HandleEvent(CreateCity) 'WWCreateCity2_F' post {
location_t tmpLocation; // Used for the Dummy locations
city_t tmpCity; // Used as the variable for city index
int_t m; // Used for loop
//Use the following to check whether the player creates a land city
for(m = 0; m < player[0].cities; m = m + 1){
GetCityByIndex(player[0], m, tmpCity);
if(CityIsValid(tmpCity)) {
if(tmpCity.Location == Dummy3){
if(turnCount > 101 ){
playerScore = playerScore + 1000; // Max Score!!
hasCity = 1;
Message (g.player, 'WWCityBuilt');
}
elseif(turnCount > 204){
playerScore = playerScore + 750;
hasCity =1;
Message (g.player, 'WWCityBuilt2');
}
elseif(turnCount > 307){
playerScore = playerScore + 500;
hasCity =1;
Message (g.player, 'WWCityBuilt3');
}
}
}
}
}
3. Finally (and this one doesnt evene look like it is close to being correct) code that should display a message box when you first arrive on the 3 land tiles (dummy, dummy2 and dummy3)
code:
HandleEvent(MoveArmy) 'WWMoveUnits_F' post {
int_t m; // Used for loop
int_t tmpNum; // How many units in the civilization
army_t tmpArmy; // Used to see if unit lands on land
// If Units land on land terrain
player[0] = 0;
tmpNum = player[0].units;
for(m = 0; m < tmpNum; m = m + 1){
GetArmyByIndex(player[0], m, tmpArmy);
if(isCityThere == 1) {
if(tmpArmy.Location == Dummy | | tmpArmy.Location == Dummy2 | | tmpArmy.Location == Dummy3){
// Tell the player to settle here now!
Message (g.player, 'WWSettleNow');
DisableTrigger('WWMoveUnits_F');
}
}
elseif(isCityThere == 0){
if(tmpArmy.Location == Dummy | | tmpArmy.Location == Dummy2 | | tmpArmy.Location == Dummy3){
// Tell the player to destroy city then settle here
Message (g.player, 'WWDestroySettle');
DisableTrigger('WWMoveUnits_F');
}
}
}
}
I would be very,very,very,very,very,very,very,very,very,very,
very,very, grateful if someone could help me, as this scenario is really beginning to take shape (well the code that is )
heardie - head hurting because he has banged it against the desk so many times tonight!
|
|
|  |
 |
|
Jerk
|
 |
Green Bay, WI USA
Nov 2000 time: 23:14
|
|
Part 1) First thing I noticed is you were setting the player[0] to 0 which should be barbarians which has the effect of making the rule only apply to barbarians. Second thing is you need to compare unit.type to the UnitDB(). Another thing is that it will only trigger if its created by a settler,sea engineer,or urban planner. If by chance there is a goodie hut there, and by chance the player gets a city out of it, it won't stop the city from being there. Odds are slim that will happen anyways though. That should take care of why it is not working although I think there might be a better way of doing it rather then cycling through the unit database every time. CreateCity already has a few already defined variables.
CreateCity(int_t, location_t, int_t, int_t [, city_t]).
Create a city (first int is cause, second int is unit type that settled (-1 if not from unit).
player[0] is the player, location[0] is the location, value[0] is the first int, value[1] is the second. Just compare location[0] with your dummy locations. Using return STOP also seems to 'kill' the settler attempting to create the city. You can add a line to create the unit back at that location. The unit creating the city is stored in value[1] but you might need to test by trial and error what value[1] is set to for the various settling units. Example of simpler code:
code:
HandleEvent(CreateCity) 'WWCreateCity_F' pre {
if (location[0] == Dummy | | location[0] == Dummy2){
Message (g.player, 'WWTerrainRecommend');
return STOP;
}
else {
return 0;
}
}
An even better way although it doesnt prevent the goodie hut senario:
code:
HandleEvent(Settle) 'WWSettleCity_F' pre {
if (army[0].location == Dummy | | army[0].location == Dummy2){
Message (g.player, 'WWTerrainRecommend');
return STOP;
}
else {
return 0;
}
}
Time is short, i'll go through the others later. Briefly looking at #2, you can use the example of this post to avoid cycling through every single city. location[0] is your friend. 
[This message has been edited by Jerk (edited January 16, 2001).]
|
|
|  |
 |
|
Locutus
|
|
ACS CTP1/2 Manager & Civ4 Co-Manager
|
 |
Hengelo, The Netherlands
Nov 1999 time: 06:14
|
|
One thing first: a while ago you asked how figure out if a unit is at a location and I confirmed that the best way would be to cycle through all units and check their location. By now I realize that this can be done much smarter: cycle through all units at the location (using GetUnitFromLocation and GetUnitsFromCell) and check if one of those units is the one you're looking for. I'm still a bit stuck in my CtP1 habits sometimes (where cycling through all units *was* necessary) 
1) Basicly all Jerk said about #1, but I have a few minor additions. For one thing, a function returns values, a eventhandler can only return STOP or CONTINUE and the CONTINUE is the default return-'value', so the else-part of his code can be left out (or at least 0 should be replaced with CONTINUE). Also, the first of Jerk's solutions covers the city from goody hut scenario so I'd go for that one if there are/might be goody huts on that location. However, I'm not sure if stopping the CreateCity event will kill the settler, but I'm fairly confident that stopping the Settle event won't kill it, so if you don't care about the goody hut for some reason, that would probably be the best way to go (though I'd test to make sure it won't kill the Settler if I were you).
2) For number two the same situation applies: no need to cycle through all units, simply use the existing built-in variables, so it looks something like this:
(BTW, I assumed that turnCount is the number of turns from the beginning of the game and the game starts in turn 0; in this case g.year is exactly the same but slightly more efficient)
code:
HandleEvent(CreateCity) 'WWCreateCity2_F' post {
city_t tmpCity;
tmpCity = city[0];
if (city[0].location == Dummy3) {
if (g.year > 307) { // if g.year > 307 then it's also > 101, so order needs to be reversed
playerScore = playerScore + 500;
hasCity = 1;
Message (tmpCity.owner, 'WWCityBuilt2');
} elseif (g.year > 204) {
playerScore = playerScore + 750;
hasCity = 1;
Message (tmpCity.owner, 'WWCityBuilt2');
} elseif (g.year > 101) {
playerScore = playerScore + 1000;
hasCity = 1;
Message (tmpCity.owner, 'WWCityBuilt');
}
}
}
3) Again, don't set player[0] to 0, rather set player[2] to army[0].owner or something (some player[x] that can't possibly contain an important value at that moment). Other than that, it looks like it should work:
code:
HandleEvent(MoveUnits) 'WWMoveUnits_F' post {
int_t i;
army_t tmpArmy;
player[2] = army[0].owner;
for (i = 0; i < player[2].armies; i = i + 1) {
GetArmyByIndex(player[2], i, tmpArmy);
if (tmpArmy.location == Dummy | | tmpArmy.location == Dummy2 | | tmpArmy.location == Dummy3) {
if (isCityThere) { // 1 = true, 0 = false, so '== [1|0]' not needed
Message(player[2], 'WWSettleNow');
DisableTrigger('WWMoveUnits_F');
} else {
Message(player[2], 'WWDestroySettle');
DisableTrigger('WWMoveUnits_F');
}
}
}
}
What I find odd is that only one player gets this message on only one of the locations and and after that, the trigger is disabled (you may want to make one version for every player and add a 'if (IsHumanPlayer(player[2])) {' somewhere as well. Also strange is that you tell people to settle at Dummy or Dummy2, yet if they try this, it's not allowed. Of course I don't know what you're trying to do so I could be all wrong, but it all seems rather odd to me.
Edit: seems like Jerk posted some stuff too while I was writing my reply, we don't seem to contradict each other so that shouldn't be a problem 
[This message has been edited by Locutus (edited January 17, 2001).]
|
|
|  |
 |
|  |
 |
|  |
 |
|
heardie
|
|
Woo Hoo! It worked, and almost 100% perfect. The only problem I got was in the finally function, the one where a unit moves on dummy(x). The game goes out and has a SLIC error
"Array Index 2 out of bounds"
Now index 2 comes from the pllayer[2] bit im guessing.
What does the error mean and how do you fix it?
Are we overwriting the array (At least its not like a array using pointers in c++. Overwrite the array and there you have it: memory leak!)
|
|
|  |
All times are GMT. The time now is 05:14. Apolyton Time is 00:14. |
top of page
|
| archivepost |
|
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
|
|
|
|
|
|