Thread Tools
Old January 16, 2001, 07:46   #1
heardie
Prince
 
heardie's Avatar
 
Local Time: 20:50
Local Date: October 31, 2010
Join Date: Aug 1999
Posts: 684
More SLIC Problems
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!

heardie is offline  
Old January 16, 2001, 17:01   #2
Jerk
Chieftain
 
Jerk's Avatar
 
Local Time: 03:50
Local Date: October 31, 2010
Join Date: Nov 2000
Location: Green Bay, WI USA
Posts: 81
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).]
Jerk is offline  
Old January 17, 2001, 05:01   #3
Jerk
Chieftain
 
Jerk's Avatar
 
Local Time: 03:50
Local Date: October 31, 2010
Join Date: Nov 2000
Location: Green Bay, WI USA
Posts: 81
Part 2) I think the main problem is your turncount if statements have nothing for turns under 101. I assume you have another trigger somewhere that increases your turncount variable (I don't think it's a built in variable). If not you can simply use g.year that is built in. Here is untested example code
Code:
HandleEvent(CreateCity) 'WWCreateCity2_F' post {
     if(CityIsValid(city[0])) {
             if(city0].location == Dummy3){                 
                     if(turnCount <= 203 ){
                             playerScore = playerScore + 1000;  // Max Score!!
                             Message (g.player, 'WWCityBuilt');
                     }
                     elseif(turnCount > 204){
                             playerScore = playerScore + 750;
                             Message (g.player, 'WWCityBuilt2');
                     }
                     elseif(turnCount > 307){
                             playerScore = playerScore + 500;
                             Message (g.player, 'WWCityBuilt3');
                     }
                     hasCity = 1 ;
             }
     }            
}
Jerk is offline  
Old January 17, 2001, 05:20   #4
Jerk
Chieftain
 
Jerk's Avatar
 
Local Time: 03:50
Local Date: October 31, 2010
Join Date: Nov 2000
Location: Green Bay, WI USA
Posts: 81
I need a little more info for a fix on part 3. It appears you want to tell the player to settle on locations dummy, dummy2, and dummy3 yet in your first part you indicated you wanted to keep players from settling cities in spots dummy and dummy2. I am also unsure what you mean by 'isCityThere'. Do you want to tell the player to settle there if there isnt a city, or tell them to destroy the city if one is already there and start it over? I guess I need to understand the intent of the senario and these 3 pieces of land. If an objective of the senario is to settle this spot then you need pieces of code to handle the city possibly changing hands, getting disbanded, or destroyed.
Jerk is offline  
Old January 17, 2001, 06:39   #5
Locutus
Apolytoners Hall of FameCiv4 SP Democracy GameCiv4 InterSite DG: Apolyton TeamBtS Tri-LeagueC4BtSDG TemplarsC4WDG Team ApolytonCivilization IV CreatorsCTP2 Source Code ProjectPolyCast Team
Deity
 
Locutus's Avatar
 
Local Time: 11:50
Local Date: October 31, 2010
Join Date: Nov 1999
Location: De Hel van Enschede
Posts: 11,702
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).]
Locutus is offline  
Old January 17, 2001, 07:04   #6
Jerk
Chieftain
 
Jerk's Avatar
 
Local Time: 03:50
Local Date: October 31, 2010
Join Date: Nov 2000
Location: Green Bay, WI USA
Posts: 81
Well, we contradict a little cause I screwed up the turncount ordering and only sort of half fixed it. I also forgot to remove the return 0's. I'd go with Locutus' code on part 2. I am not sure if you want it to have any benifit before turn 101 though. If you do then simply change the last elseif to " } elseif (g.year > 0) {". I assume that getting it even earlier than turn 101 should still grant max points.

When I tested stopping createcity it did kill the settler on me, I left it open (removed the comparing of the locations so it would work on every createcity) and quickly ended my game since it was the first turn and my only unit (the settler) was dead
To add the unit back after you can change it to something like:
Code:
HandleEvent(CreateCity) 'WWCreateCity_F' pre {
        if (location[0] == Dummy | | location[0] == Dummy2){
                Message (player[0], 'WWTerrainRecommend');
                // Since returning STOP will kill the unit attempting to create the city
                // You must recreate the unit (i suppose this can be a nifty way of healing 
                // the settler but oh well)
                if (value[0] == 1 && value[1] > -1) {
                     CreateUnit(player[0], value[1], location[0], 0);
                }
                return STOP;
        }
}
[This message has been edited by Jerk (edited January 17, 2001).]
Jerk is offline  
Old January 17, 2001, 20:38   #7
heardie
Prince
 
heardie's Avatar
 
Local Time: 20:50
Local Date: October 31, 2010
Join Date: Aug 1999
Posts: 684
Thanks both of you, and it is so good to know I don't have to cyclle through every unit

quote:


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.


When the player lands on Dummy, Dummy2, or Dummy3 he gets a message saying to settle on Dummy3, but if he is dumb enough to try and settle on Dummy or Dummy2 then I tell him no, because it will soon be underwater (which is a part of my code that actually works )
heardie is offline  
Old January 18, 2001, 02:28   #8
heardie
Prince
 
heardie's Avatar
 
Local Time: 20:50
Local Date: October 31, 2010
Join Date: Aug 1999
Posts: 684
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!)
heardie is offline  
Old January 18, 2001, 09:09   #9
Locutus
Apolytoners Hall of FameCiv4 SP Democracy GameCiv4 InterSite DG: Apolyton TeamBtS Tri-LeagueC4BtSDG TemplarsC4WDG Team ApolytonCivilization IV CreatorsCTP2 Source Code ProjectPolyCast Team
Deity
 
Locutus's Avatar
 
Local Time: 11:50
Local Date: October 31, 2010
Join Date: Nov 1999
Location: De Hel van Enschede
Posts: 11,702
Hmm, odd. Maybe you can only use player[2] if it already contains a value or something. Try replacing player[2] with player[0]. As far as I can see that should cause any problems here, though it seems rather odd that this would be a problem...
Locutus is offline  
 

Bookmarks

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is On

Forum Jump


All times are GMT -4. The time now is 05:50.


Design by Vjacheslav Trushkin, color scheme by ColorizeIt!.
Powered by vBulletin® Version 3.8.2
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.
Apolyton Civilization Site | Copyright © The Apolyton Team