 |
|  |
 |
|
Rulke
|
|
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.
|
|
|  |
 |
|
The Big Mc
|
 |
Of the universe / England
Oct 2001 time: 05:16
|
|
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.
|
|
|  |
 |
|
stankarp
|
|
australia
Feb 2002 time: 05:16
|
|
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.
|
|
|  |
 |
|
stankarp
|
|
australia
Feb 2002 time: 05:16
|
|
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");
}
}
}
}
}
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.
|
|
|  |
 |
|
stankarp
|
|
australia
Feb 2002 time: 05:16
|
|
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)){
|
|
|  |
 |
|
stankarp
|
|
australia
Feb 2002 time: 05:16
|
|
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;
}
}
}
|
|
|  |
 |
|
Martin Gühmann
|
 |
Berlin, Germany
Mar 2001 time: 06:16
|
|
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
|
|
|  |
 |
|
stankarp
|
|
australia
Feb 2002 time: 05:16
|
|
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.
|
|
|  |
All times are GMT. The time now is 05:16. Apolyton Time is 00:16. |
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
|
|
|
|
|
|