Announcement

Collapse
No announcement yet.

More SLIC Problems

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • 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) &#0124; &#0124; tmpUnit == UnitDB(UNIT_SEA_ENGINEER) &#0124; &#0124; tmpUnit == UnitDB(UNIT_URBAN_PLANNER)){ 
    			if (tmpUnit.Location == Dummy &#0124; &#0124; 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 &#0124; &#0124; tmpArmy.Location == Dummy2 &#0124; &#0124; tmpArmy.Location == Dummy3){
    				// Tell the player to settle here now!
    				Message (g.player, 'WWSettleNow');
    				DisableTrigger('WWMoveUnits_F');
    			}
    					
    		}
    		elseif(isCityThere == 0){
    			if(tmpArmy.Location == Dummy &#0124; &#0124; tmpArmy.Location == Dummy2 &#0124; &#0124; 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!


  • #2
    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).]

    Comment


    • #3
      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 ;
                   }
           }            
      }

      Comment


      • #4
        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.

        Comment


        • #5
          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).]
          Administrator of WePlayCiv -- Civ5 Info Centre | Forum | Gallery

          Comment


          • #6
            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).]

            Comment


            • #7
              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 )

              Comment


              • #8
                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!)

                Comment


                • #9
                  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...
                  Administrator of WePlayCiv -- Civ5 Info Centre | Forum | Gallery

                  Comment

                  Working...
                  X