 |
|  |
 |
|
Peter Triggs
|
|
Gone Fishin, Canada
Jan 2000 time: 05:17
|
|
OK, using Tony Evans's SwapCity function, I've got this little handler that makes AI civs surrender rather than fighting to the last city:
code:
// Swaps City to Player. Kills all units first if flag is set to 1.
int_f SwapCity (city_t swCity, int_t swPlayer, int_t killUnits)
{
int_t i;
int_t tmpPlayer;
int_t numUnits;
unit_t tmpUnit;
city_t tmpCity;
location_t tmpLoc;
tmpCity = swCity;
if (CityIsValid(tmpCity)) {
tmpPlayer = swPlayer;
tmpLoc = tmpCity.location;
numUnits = GetUnitsAtLocation(tmpLoc);
if (killUnits == 1) {
for (i = 0; i < numUnits; i = i + 1) { // Kill all units
GetUnitFromCell(tmpLoc, i, tmpUnit);
Event: DisbandUnit(tmpUnit);
}
}
Event:GiveCity(tmpCity, tmpPlayer);
}
else {
return -1;// Can't swap due to invalid city
}
}
HandleEvent(CaptureCity) 'CivSurrenders' pre {
city_t tmpCity;
int_t i;
int_t numCities;
int_t numUnits;
unit_t tmpUnit;
if ( IsHumanPlayer(player[0]) ){//what about AI?
player[1]=city[0].owner;
numUnits=player[1].units;
TMP_PLAYER=player[1];
TMP_CITY=city[0];
if( MilitaryRank(player[0])-MilitaryRank(player[1])>25) {
for (i=0;i< numUnits;i=i+1 ){//first, kill his civilians
GetUnitByIndex(TMP_PLAYER,i,tmpUnit);
if (tmpUnit.valid && IsCivilian(tmpUnit) ) {
Event: DisbandUnit(tmpUnit);
}
}
numCities=PlayerCityCount(TMP_PLAYER);
for (i = 0; i < numCities; i = i + 1) {//then take his cities
GetCityByIndex(TMP_PLAYER, i, tmpCity);
if (tmpCity.location != city[0].location ){
CreateUnit(player[0], UnitDB(UNIT_BOMBER), city[0].location, 1, tmpUnit);
SwapCity(tmpCity, player[0].owner, 1);
Event: DisbandUnit(tmpUnit);
}
}
}
EnableTrigger('SurrenderMessages');
}
}
HandleEvent(CaptureCity) 'SurrenderMessages' post {
player[1]=TMP_PLAYER;
city[0]=TMP_CITY;
if( MilitaryRank(player[0])-MilitaryRank(player[1])>25 ){
Message(player[0].owner, 'SurrenderMessage');
}
elseif( MilitaryRank(player[0])-MilitaryRank(player[1])>20 ){
Message(player[0].owner, 'OverwhelmingSuperiority');
}
elseif( MilitaryRank(player[0])-MilitaryRank(player[1])>15 ){
Message(player[0].owner, 'MajorSuperiority');
}
elseif (MilitaryRank(player[0])>MilitaryRank(player[1]) ){
Message(player[0].owner, 'MilitarySuperiority');
}
DisableTrigger('SurrenderMessages');
}
messagebox 'SurrenderMessage' {
show();
Text (ID_TheSurrenderMessage) ;
}
//TheSurrenderMessage "Sire! We've won! With the capture of {city[0].name}, {player[1].civ_name_singular} resistence has //totally collapsed and they have agreed to an unconditional surrender!"
messagebox 'OverwhelmingSuperiority' {
Text (ID_OverwhelmingSuperiorityM) ;
show();
}
//OverwhelmingSuperiorityM "With the capture of {city[0].name}, our generals are pleased to report that we have
//obtained overwhelming military superiority over the {player[1].civ_name_plural}. Victory is at hand!"
messagebox 'MajorSuperiority' {
show();
Text (ID_MajorSuperiorityM) ;
}
//MajorSuperiorityM "Sire, our generals report that the war is going very well.
// \n They believe that we are now significantly stronger than the {player[1].civ_name_plural}."
messagebox 'MilitarySuperiority' {
show();
Text (ID_MilitarySuperiorityM) ;
}
//MilitarySuperiorityM "Sire, our generals report that the war with the {player[1].civ_name_plural} is going well.
//We have gained the upper hand."
For one thing, I had to use Martin's technique of creating a Bomber unit to expose the city and then disbanding the unit after the city has been swapped to the human player. (Otherwise, I could only swap cities that the capturing player already knows about.) But it doesn't work as well here as it does in GoodMod. There's no real problem except that there can be 10 or 20 sec lag while the computer executes.
The other thing is the triggering condition "MilitaryRank(player[0])-MilitaryRank(player[1])>25". The MilitaryRank function is, IMO, a bit weird. I think it must take Advances into account as well as existing military units, so that although your armies can have overwhelming military superiority on the ground, your enemy's MilitaryRank may not be that much lower than yours.
So if anybody wants to play with this and try to optimize it, you're welcome to it. Cause I have to get back to Diplomacy.
|
|
|  |
 |
|
The Raptor
|
|
Lincoln, NE
Jan 2002 time: 23:17
|
|
I personally like the Alpha Centauri version where civs will surrender to you and swear loyalty. More realistic, plus it lets you work under the max city cap.
|
|
|  |
 |
|
The Big Mc
|
 |
Of the universe / England
Oct 2001 time: 05:17
|
|
hi the big mc here I think I know what the problem is but with no way of testing it I may miss it but here goes
code:--------------------------------------------------------------------------------
// Swaps City to Player. Kills all units first if flag is set to 1.
int_f SwapCity (city_t swCity, int_t swPlayer, int_t killUnits)
{
int_t i;
int_t tmpPlayer;
int_t numUnits;
unit_t tmpUnit;
city_t tmpCity;
location_t tmpLoc;
tmpCity = swCity;
if (CityIsValid(tmpCity)) {
tmpPlayer = swPlayer;
tmpLoc = tmpCity.location;
numUnits = GetUnitsAtLocation(tmpLoc);
if (killUnits == 1) {
for (i = 0; i < numUnits; i = i + 1) { // Kill all units
GetUnitFromCell(tmpLoc, i, tmpUnit);
Event: DisbandUnit(tmpUnit);
}
}
Event:GiveCity(tmpCity, tmpPlayer);
}
else {
return -1;// Can't swap due to invalid city
}
}
HandleEvent(CaptureCity) 'CivSurrenders' pre {
city_t tmpCity;
int_t i;
int_t numCities;
int_t numUnits;
unit_t tmpUnit;
if ( IsHumanPlayer(player[0]) ){//what about AI?
player[1]=city[0].owner;
numUnits=player[1].units;
TMP_PLAYER=player[1];
TMP_CITY=city[0];
if( MilitaryRank(player[0])-MilitaryRank(player[1])>25) {
for (i=0;i< numUnits;i=i+1 ){//first, kill his civilians
GetUnitByIndex(TMP_PLAYER,i,tmpUnit);
if (tmpUnit.valid && IsCivilian(tmpUnit) ) {
Event: DisbandUnit(tmpUnit);
}
}
numCities=PlayerCityCount(TMP_PLAYER);
for (i = 0; i < numCities; i = i + 1) {//then take his cities
GetCityByIndex(TMP_PLAYER, i, tmpCity);
if (tmpCity.location != city[0].location ){
CreateUnit(player[0], UnitDB(UNIT_BOMBER), city[0].location, 1, tmpUnit);
SwapCity(tmpCity, player[0].owner, 1);
Event: DisbandUnit(tmpUnit);
}
}
}
EnableTrigger('SurrenderMessages');
}
}
HandleEvent(CaptureCity) 'SurrenderMessages' post {
city_t tmp_City;
int_t TMP_PLAYER;
player[1]=TMP_PLAYER;
city[0]=TMP_CITY;
if( MilitaryRank(player[0])-MilitaryRank(player[1])>25 ){
Message(player[0].owner, 'SurrenderMessage');
}
elseif( MilitaryRank(player[0])-MilitaryRank(player[1])>20 ){
Message(player[0].owner, 'OverwhelmingSuperiority');
}
elseif( MilitaryRank(player[0])-MilitaryRank(player[1])>15 ){
Message(player[0].owner, 'MajorSuperiority');
}
elseif (MilitaryRank(player[0])>MilitaryRank(player[1]) ){
Message(player[0].owner, 'MilitarySuperiority');
}
DisableTrigger('SurrenderMessages');
}
messagebox 'SurrenderMessage' {
show();
Text (ID_TheSurrenderMessage) ;
}
//TheSurrenderMessage "Sire! We've won! With the capture of {city[0].name}, {player[1].civ_name_singular} resistence has //totally collapsed and they have agreed to an unconditional surrender!"
messagebox 'OverwhelmingSuperiority' {
Text (ID_OverwhelmingSuperiorityM) ;
show();
}
//OverwhelmingSuperiorityM "With the capture of {city[0].name}, our generals are pleased to report that we have
//obtained overwhelming military superiority over the {player[1].civ_name_plural}. Victory is at hand!"
messagebox 'MajorSuperiority' {
show();
Text (ID_MajorSuperiorityM) ;
}
//MajorSuperiorityM "Sire, our generals report that the war is going very well.
// \n They believe that we are now significantly stronger than the {player[1].civ_name_plural}."
messagebox 'MilitarySuperiority' {
show();
Text (ID_MilitarySuperiorityM) ;
}
//MilitarySuperiorityM "Sire, our generals report that the war with the {player[1].civ_name_plural} is going well.
//We have gained the upper hand."
--------------------------------------------------------------------------------
any way I look at the code and found something useful the life of a slic learner
|
|
|  |
 |
|  |
 |
|  |
 |
|  |
 |
|  |
 |
|  |
 |
|
Peter Triggs
|
|
Gone Fishin, Canada
Jan 2000 time: 05:17
|
|
Oops, my bad. When you use non-standard notational conventions, I guess you should explain them. I read somewhere that the standard convention for capitals, eg "TMP_PLAYER", is that they should stand for constants. But I've been using them for global variables so that I can see at a glance when a variable is a global.
quote:
BTW, what does MilitaryRank return? A value between 1 and 100 or something?
|
Yup, as I recall it was described someplace in CTP1 as returning a "normalized rank": the top player gets 100 and everyone else gets a "percentage" (or something like that). There was a bunch of these in CTP1; I seem to recall coming across them originally in some document you did. The others that are still usable are CitiesRank, PopulationRank, KnowledgeRank, GoldRank, and TradeRank.
There's no real bugs in it but IMO the handler doesn't trigger soon enough. I only tried it once in a proper game and by the time it triggered it was clear that any remaining Yamato resistence was totally futile. Maybe the numbers just need tweaking or maybe it needs keying on the number of military units that the two players have. Something like this might work better:
code:
if( MilitaryRank(player[0])>MilitaryRank(player[1]) && player[0].militaryunits >2* player[1].militaryunits ) {
BTW, Wombat, the article that contains the quote I posted in the 'Who Should Design Civ4 ?' thread is called "The Poor Get Richer: The Ancient Art of Game Balance <http://www.gamespy.com/devcorner/april01/reynolds/>" . Sometimes I wonder about Civ3 players: there they were going on about Brian Reynolds, and I give them this quality quote (especially if you think about it in relation to Civ3), identifying the author only as "a guy who used to post on these forums". And nobody bit! Or was it too obvious?
|
|
|  |
 |
|
Locutus
|
|
ACS CTP1/2 Manager & Civ4 Co-Manager
|
 |
Hengelo, The Netherlands
Nov 1999 time: 06:17
|
|
quote: Originally posted by Peter Triggs
Oops, my bad. When you use non-standard notational conventions, I guess you should explain them. I read somewhere that the standard convention for capitals, eg "TMP_PLAYER", is that they should stand for constants. But I've been using them for global variables so that I can see at a glance when a variable is a global. |
"You read somewhere"?! I always took you for an experienced programmer! But an experienced programmer saying such a thing is like a doctor saying "I read somewhere CPR can save lives" What *is* your pre-CtP programming background exactly, if I may be so bold to ask? 
quote: Yup, as I recall it was described someplace in CTP1 as returning a "normalized rank": the top player gets 100 and everyone else gets a "percentage" (or something like that). There was a bunch of these in CTP1; I seem to recall coming across them originally in some document you did. The others that are still usable are CitiesRank, PopulationRank, KnowledgeRank, GoldRank, and TradeRank. |
Yeah, I know about those functions (is there any function I don't know about? ), but I had no idea what they returned. I figured it would return 1 for the best player, 2 for the second player, etc. I always thought those were pretty useless functions but that changes things a bit (esp. when working with AI decision making)...
|
|
|  |
 |
|
Peter Triggs
|
|
Gone Fishin, Canada
Jan 2000 time: 05:17
|
|
I told you ages ago, Wouter, I'm not a professional programmer. My background is in logic, philosophy and, to a lesser extent, mathematics. But I did do some BASIC programming for my own use ages ago and SLIC has given me an opportunity to get back into it. So really I'm just an enthusiastic amateur.
|
|
|  |
 |
|  |
All times are GMT. The time now is 05:17. Apolyton Time is 00:17. |
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
|
|
|
|
|
|