Announcement

Collapse
No announcement yet.

SLIC help please.

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

  • SLIC help please.

    Here's my problem. I'm really bad at building settlers. I just don't. So I thought I'd add a way for them to be automatically generated. However, this was unfair on the AI, so I decided it would be better to add something that will generate settlers for me, if I find it. This should be a very profitable tile improvement that is randomly placed, and can be claimed by moving a unit onto it, that will produce settlers every five turns. The problem I've got is that it's not placed. Here is the code in the SLIC:
    Code:
    int_t tmpOwner;
    location_t LocationTrue;
    int_t settTurnsPassed;
    
    // Place City Thingy on map at the beginning of the game.
    HandleEvent(BeginTurn) 'BeginGameCityPlacement' pre { 
    int_t tmpX;
    int_t tmpY;
    int_t x;
    int_t y;
    location_t tmpLoc;
    int_t successful;
    
    tmpX = GetMapWidth();
    tmpY = GetMapHeight();
    
    tmpOwner = 0;
    settTurnsPassed = 0;
    
    successful = 0;
    while (successful == 0) {
    	x = random(tmpX);
    	y = random(tmpY);
    	MakeLocation(tmpLoc, x, y);
    	if (TerrainType(tmpLoc) != TerrainDB(TERRAIN_WATER_SHALLOW) &&
    	TerrainType(tmpLoc) != TerrainDB(TERRAIN_WATER_DEEP) &&
    	TerrainType(tmpLoc) != TerrainDB(TERRAIN_WATER_VOLCANO) &&
    	TerrainType(tmpLoc) != TerrainDB(TERRAIN_WATER_BEACH) &&
    	TerrainType(tmpLoc) != TerrainDB(TERRAIN_WATER_SHELF) &&
    	TerrainType(tmpLoc) != TerrainDB(TERRAIN_WATER_TRENCH) &&
    	TerrainType(tmpLoc) != TerrainDB(TERRAIN_WATER_RIFT)) {//Well, I don't want it in the water.
    		GrantAdvance (player[0], AdvanceDB(ADVANCE_CITYTHING_PREQ));
    		Event:CreateImprovement(0, tmpLoc, TerrainImprovementDB(TIMP_CITYTHING), 0);//maybe this will get it working
    		successful = 1;
    		MakeLocation(LocationTrue, x, y);
    		RemoveAdvance(player[0], AdvanceDB(ADVANCE_CITYTHING_PREQ));
    		}
    	else { successful = 0; }
    }
    DisableTrigger('BeginGameCityPlacement');
    
    }
    
    //Now check to see when stuff moves next to it?
    HandleEvent(MoveUnits) 'TakeIt' post {
    
    if (army[0].location == LocationTrue) { 
    	tmpOwner = army[0].owner;
    	GrantAdvance (tmpOwner, AdvanceDB(ADVANCE_CITYTHING_PREQ));
    	Event:CutImprovements(LocationTrue);
    	Event:CreateImprovement(tmpOwner, LocationTrue, TerrainImprovementDB(TIMP_CITYTHING), 0);
    	RemoveAdvance(tmpOwner, AdvanceDB(ADVANCE_CITYTHING_PREQ));
    }
    }
    
    //Now make the settler?
    HandleEvent(BeginTurn) 'SettlerCheck' post {
    if (g.player == tmpOwner &&
    g.player != 0) {
    	if (settTurnsPassed == 5) {
    		settTurnsPassed = 0;
    		Event:CreateUnit(player[0], LocationTrue, 0, UnitDB(UNIT_SETTLER), 0);
    	}
    	else {
    		settTurnsPassed = settTurnsPassed + 1;
    	}
    }
    }
    Another problem I had was that everyone could build it, despite it requireing an advance that no-one should be getting (however, I've a feeling that was from the cost of the advance being 0, which I've just changed)


    Completely unrelated, but my version of the religion mod doesn't work. I've tried it on it's own and with the apolyton pack, and it keeps giving me the error: "APOL_str_loc not found in asset tree". I do have the patch, so have I done anything stupid?
    This was done via ModManager, applying the religion mod, failing, and then managing it to apply both at once, with the Apolyton pack on top, which still produced the error.

  • #2
    Right to start with two things one you can’t place tile imps outside your border (with the exception of forts) second you can’t place a fort outside the vision range of a unit.


    So


    Use something like this
    Code:
    HandleEvent(BeginTurn) 'plamtstuff' pre 
    {
    int_t ruinn;
    int_t xcord;
    int_t ycord;
    
    location_t tmplocb;
    int_t x;
    int_t xcoord;
    int_t ycoord;
    city_T doomed;
    location_t owner;
    unit_t killunit1;
    int_t ruintype;
    
    
    ruinno = random(25);
    ruinno = ruinno + 300;//20
    		for(x=0; x !=  ruinno; x = x +1)
    {
    	xcoord = Random(GetMapWidth());
    	ycoord = Random(GetMapHeight());
    		MakeLocation(tmpLocb, xcoord, ycoord); 
    SetPW(0, 99999999);
    CreateUnit(0, UnitDB(UNIT_SPY_PLANE), tmplocb, 1,killunit1);
    		event:CreateImprovement(0,tmplocb ,7,0);
    		 FinishImprovements(tmplocb);
    		Event:KillUnit(killunit1, 0, -1);
    }
    DisableTrigger('plamtstuff');
    }
    i know it's not for your code but it will help.
    "Every time I learn something new it pushes some old stuff out of my brain" Homer Jay Simpson
    The BIG MC making ctp2 a much unsafer place.
    Visit the big mc’s website

    Comment


    • #3
      BigMC

      Can you make it so that whenever a unit fortifies it plants a fortress-like unit?

      I'm thinking about making a "territory" improvement that adds no bonuses or defense (might only have a flagpole as a graphic) but lets a player seize territory.

      But I have a few questions...

      if they do it in another player territory will it just build the tile or will will change ownership?

      If it changes ownership will it cause a war?

      I basically want fortifyig to let infantry units capture territory but if its owned by a plair it lowers regard or starts a war. Of course, I hope the ai obeys boundaries better.
      Formerly known as "E" on Apolyton

      See me at Civfanatics.com

      Comment


      • #4
        Yes, however cities will mess this model up. as when a city expands if the working ring occupies your flag pole or a fort the tile is captured as well as any territory controlled by the flag pole or fort.

        as for your questions you can do what you want throw the slic need for this however you won’t be able to occupied a tile that is being worked.
        "Every time I learn something new it pushes some old stuff out of my brain" Homer Jay Simpson
        The BIG MC making ctp2 a much unsafer place.
        Visit the big mc’s website

        Comment


        • #5
          Could I get a little help please, I seem to have missed something obvious somewhere.

          This code is to get the AI to have a 33% chance of cutting a tile improvement if at war with the cell owner.

          I thought if could use ;
          if (!IsHumanPlayer(player[0])){

          to run through the ai players but the code will not work with that. If I disable that line and put

          tmpPlayer = 2;
          player[0] = tmpPlayer

          back in , the code works, but only for player 2.

          Code:
          HandleEvent(BeginTurn) 'AIPillageTest' pre {
          
          	//tmpPlayer = 2;
          	//player[0] = tmpPlayer;
          	location_t	tmpLoc;
                int_t      locOwner;
                army_t     tmpArmy;
          	if (!IsHumanPlayer(player[0])){
          			for (i = 0; i < player[0].units; i = i + 1) {
          			GetUnitByIndex(tmpPlayer, i, tmpUnit);
          			tmpLoc = tmpUnit.location;
          			locOwner=CellOwner(tmpUnit.location);   
          	         	if (AtWarWith(tmpUnit.Owner,locOwner)){
          				if (Random(12) <= 3)){
          				if(TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_OUTPOST))
          				|| TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_NETS))
          				|| TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_LATIFUNDIA))
          				|| TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_TRADING_POST))
          				|| TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_ADVANCED_FARMS))
          				|| TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_MINE_SHAFT))
          				|| TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_FARMS))
          				|| TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_MINES))) {
          					event:CutImprovements(tmpUnit.location);
          					AddCenter(tmpUnit.location);
          					AddEffect(tmpUnit.location, "SPECEFFECT_FIRES", "SOUND_ID_PILLAGE");
          					}
                      		}
          			}
          		}
          	}
          }
          Any help greatly appreciated.

          Comment


          • #6
            What you have there is fine apart from the "tmpPlayer" which you haven't defined anywhere. Either replace it with "player[0]", or put the lines "int_t tmpPlayer; tmpPlayer = player[0]" somewhere.

            Then you can save some time/space.
            Code:
            tmpLoc = tmpUnit.location;
            locOwner=CellOwner(tmpUnit.location);   
            if (AtWarWith(tmpUnit.Owner,locOwner)){
            This is silly. You define tmpLoc and then don't use it in CellOwner(). You already know that tmpPlayer is the same as tmpUnit.owner, which is already defined as player[0].

            And (Random(12) <= 3)){ is the same as (Random(3) == 0)){
            Concrete, Abstract, or Squoingy?
            "I don't believe in giving scripting languages because the only additional power they give users is the power to create bugs." - Mike Breitkreutz, Firaxis

            Comment


            • #7
              So this should work then?

              Code:
              HandleEvent(BeginTurn) 'AIPillageTest' pre {
              	location_t	     tmpLoc;
                    int_t      locOwner;
                    army_t     tmpArmy;
              	int_t tmpPlayer;
              
              	if (!IsHumanPlayer(player[0])){
              		tmpPlayer = player[0];
              			for (i = 0; i < tmpPlayer.units; i = i + 1) {
              			GetUnitByIndex(tmpPlayer, i, tmpUnit);
              			tmpLoc = tmpUnit.location;
              			locOwner=CellOwner(tmpLoc);   
              	         	if (AtWarWith(tmpUnit.location,locOwner)){
              				if(TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_OUTPOST))
              				|| TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_NETS))
              				|| TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_LATIFUNDIA))
              				|| TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_TRADING_POST))
              				|| TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_ADVANCED_FARMS))
              				|| TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_MINE_SHAFT))
              				|| TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_FARMS))
              				|| TileHasImprovement(tmpLoc, TerrainImprovementDB(TILEIMP_MINES))) {
              					event:CutImprovements(tmpUnit.location);
              					AddCenter(tmpUnit.location);
              					AddEffect(tmpUnit.location, "SPECEFFECT_FIRES", "SOUND_ID_PILLAGE");
                          		
              			}
              		}
              	}
              }
              }
              This is silly
              That is a direct copy of a peice of code from a well known programmer
              I knew it worked so I did not check it too closely.

              Comment


              • #8
                Yeah, that should work I think.
                Concrete, Abstract, or Squoingy?
                "I don't believe in giving scripting languages because the only additional power they give users is the power to create bugs." - Mike Breitkreutz, Firaxis

                Comment


                • #9
                  Thanks,

                  It is partly working now, ie, it is not firing everytime.

                  It is almost as if the code is not firing for every player for every turn.

                  Very curious.

                  Of course
                  if (AtWarWith(tmpUnit.location,locOwner)){
                  should be
                  if (AtWarWith(tmpUnit.owner,locOwner)){

                  Comment


                  • #10
                    Another quickie, think this is OK.

                    It is a simple force match used in conjunction with frenzy to make the ai more aggressive. I had to insert the terrain condition as ai were attacking into mountains with cavalry and killing themselves.

                    Thanks if you can help.

                    Code:
                    int_f SK_ForceMatch(army_t theArmy, location_t theLoc) {			
                    location_t	tmpLoc;
                    army_t	tmpArmy;
                    int_t		terrainMatch;
                    	tmpArmy = theArmy;
                    	tmpLoc = theLoc;
                    	terrainMatch = 0;
                    	if(TerrainType(tmpLoc) == TerrainDB(TERRAIN_MOUNTAIN)
                    	|| TerrainType(tmpLoc) == TerrainDB(TERRAIN_BROWN_MOUNTAIN)
                    	|| TerrainType(tmpLoc) == TerrainDB(TERRAIN_WHITE_MOUNTAIN)){
                    	terrainMatch=1;
                    			}
                    	if (terrainMatch<1){
                    	if ((GetUnitsAtLocation(tmpLoc) <= tmpArmy.size)||(tmpArmy.size>=10)) {
                    		return 1;
                    	} else {
                    		return 0;
                    		}
                    	}
                    }

                    Comment


                    • #11
                      The first thing I would do is to get the indention right, so that I can see better the structure of the code:

                      Code:
                      int_f SK_ForceMatch(army_t theArmy, location_t theLoc) {			
                      	location_t tmpLoc;
                      	army_t     tmpArmy;
                      	int_t      terrainMatch;
                      	tmpArmy = theArmy;
                      	tmpLoc = theLoc;
                      	terrainMatch = 0;
                      	
                      	if(TerrainType(tmpLoc) == TerrainDB(TERRAIN_MOUNTAIN)
                      	|| TerrainType(tmpLoc) == TerrainDB(TERRAIN_BROWN_MOUNTAIN)
                      	|| TerrainType(tmpLoc) == TerrainDB(TERRAIN_WHITE_MOUNTAIN)
                      	){
                      		terrainMatch=1;
                      	}
                      
                      	if (terrainMatch<1){
                      		if ((GetUnitsAtLocation(tmpLoc) <= tmpArmy.size)||(tmpArmy.size>=10)) {
                      			return 1;
                      		} else {
                      			return 0;
                      		}
                      	}
                      }
                      There are two things that I would do differently:

                      The first thing is this stupid terrainMatch variable. First you check some types of terrain and if there are the right terrain you set it 1. And then you check whether it is smaller one to do something else if this is the case. Well this is one variable too much. To get rid of this just use the first if, well of course you have to change the logic as you don't want to execute, if all of these tarrains aren't the locations terrain type then fine. So equal becomes unequal and or becomes and:

                      Code:
                      int_f SK_ForceMatch(army_t theArmy, location_t theLoc) {			
                      	location_t tmpLoc;
                      	army_t     tmpArmy;
                      	tmpArmy = theArmy;
                      	tmpLoc = theLoc;
                      	
                      	if(TerrainType(tmpLoc) != TerrainDB(TERRAIN_MOUNTAIN)
                      	&& TerrainType(tmpLoc) != TerrainDB(TERRAIN_BROWN_MOUNTAIN)
                      	&& TerrainType(tmpLoc) != TerrainDB(TERRAIN_WHITE_MOUNTAIN)
                      	){
                      		if ((GetUnitsAtLocation(tmpLoc) <= tmpArmy.size)||(tmpArmy.size>=10)) {
                      			return 1;
                      		} else {
                      			return 0;
                      		}
                      	}
                      }
                      The second thing is that (GetUnitsAtLocation(tmpLoc) <= tmpArmy.size)||(tmpArmy.size>=10) is a boolean expression that returns true or false itsself, and in slic this is 1 or 0 respectively. So writing it explicitely is a little bit superflous. So you can return it directly:

                      Code:
                      int_f SK_ForceMatch(army_t theArmy, location_t theLoc) {			
                      	location_t tmpLoc;
                      	army_t     tmpArmy;
                      	tmpArmy = theArmy;
                      	tmpLoc = theLoc;
                      	
                      	if(TerrainType(tmpLoc) != TerrainDB(TERRAIN_MOUNTAIN)
                      	&& TerrainType(tmpLoc) != TerrainDB(TERRAIN_BROWN_MOUNTAIN)
                      	&& TerrainType(tmpLoc) != TerrainDB(TERRAIN_WHITE_MOUNTAIN)
                      	){
                      		return((GetUnitsAtLocation(tmpLoc) <= tmpArmy.size)||(tmpArmy.size>=10));
                      	}
                      }
                      And now I see another problem, the function doesn't contain a final return statement. Well you can now combine boolean expression in the if with the one in the return. But for laziless I just add a final return 0; And another point to do like this is that slic evaluates a boolean expression until it reached its end and doesn't stop when it can't become ture or false anymore.

                      Code:
                      int_f SK_ForceMatch(army_t theArmy, location_t theLoc) {			
                      	location_t tmpLoc;
                      	army_t     tmpArmy;
                      	tmpArmy = theArmy;
                      	tmpLoc = theLoc;
                      	
                      	if(TerrainType(tmpLoc) != TerrainDB(TERRAIN_MOUNTAIN)
                      	&& TerrainType(tmpLoc) != TerrainDB(TERRAIN_BROWN_MOUNTAIN)
                      	&& TerrainType(tmpLoc) != TerrainDB(TERRAIN_WHITE_MOUNTAIN)
                      	){
                      		return((GetUnitsAtLocation(tmpLoc) <= tmpArmy.size)||(tmpArmy.size>=10));
                      	}
                      	return 0;
                      }
                      So that should it now be the only little problem with this code left is that the AI doesn't attack location in the mountain even if the stack only contain units that can move into the mountains.

                      -Martin
                      Civ2 military advisor: "No complaints, Sir!"

                      Comment


                      • #12
                        Hi Martin,

                        Thanks for the help, BTW, the main part of the code was written by a well known programmer, I added the terrain check when the problem was discovered in testing.

                        So are you going to add a check to see if the stack has any mounted units to allow such a stack (with no mounted units) to attack into the mountain?

                        Thanks if you can help.

                        Comment

                        Working...
                        X