January 14, 2002, 15:14
|
#1
|
King
Local Time: 19:21
Local Date: October 31, 2010
Join Date: Jan 2000
Location: Gone Fishin, Canada
Posts: 1,059
|
Getting Civs to Surrender
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.
|
|
|
|
January 14, 2002, 16:54
|
#2
|
Settler
Local Time: 13:21
Local Date: October 31, 2010
Join Date: Jan 2002
Location: Lincoln, NE
Posts: 14
|
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.
|
|
|
|
January 14, 2002, 22:12
|
#3
|
King
Local Time: 16:21
Local Date: October 31, 2010
Join Date: Jul 2001
Location: of Natal, Brazil
Posts: 2,555
|
Thats good stuff. No more endless wars finished by pity of the human player. But by a fancy request.
I am going to test it as soon as possible. The AI is stronger and stronger every day.
Cant wait others Peter Triggs improvements in diplomacy!
__________________
"Kill a man and you are a murder.
Kill thousands and you are a conquer.
Kill all and you are a God!"
-Jean Rostand
|
|
|
|
January 15, 2002, 08:17
|
#4
|
King
Local Time: 16:21
Local Date: October 31, 2010
Join Date: Jul 2001
Location: of Natal, Brazil
Posts: 2,555
|
Oh OH!
Small fix needed!
The symbols TMP_PLAYER and TMP_CITY are undefined.
Could you fix it?
__________________
"Kill a man and you are a murder.
Kill thousands and you are a conquer.
Kill all and you are a God!"
-Jean Rostand
|
|
|
|
January 15, 2002, 08:48
|
#5
|
Deity
Local Time: 21:21
Local Date: October 31, 2010
Join Date: Nov 1999
Location: De Hel van Enschede
Posts: 11,702
|
Interesting looking code, Peter, very interesting indeed. It would be a nice addition to the game once the bugs are worked out. BTW, what does MilitaryRank return? A value between 1 and 100 or something?
Pedrunn,
Edit: silly me, the variables should be global. Add this:
city_t TMP_CITY;
int_t TMP_PLAYER;
to the top of your file.
|
|
|
|
January 15, 2002, 08:51
|
#6
|
King
Local Time: 19:21
Local Date: October 31, 2010
Join Date: Oct 2001
Location: Of the universe / England
Posts: 2,061
|
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
__________________
"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
|
|
|
|
January 15, 2002, 08:55
|
#7
|
Deity
Local Time: 21:21
Local Date: October 31, 2010
Join Date: Nov 1999
Location: De Hel van Enschede
Posts: 11,702
|
The Big Mc,
What the hell? Could you perhaps indicate what you changed so I don't have to spit through the entire code? Also, if you put your code between code tags ("[ code ]" and "[ /code ]" but then without the spaces), it will look a whole lot better...
|
|
|
|
January 15, 2002, 08:55
|
#8
|
King
Local Time: 19:21
Local Date: October 31, 2010
Join Date: Oct 2001
Location: Of the universe / England
Posts: 2,061
|
looks like me and locutos responded at the same time ops
__________________
"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
|
|
|
|
January 15, 2002, 08:56
|
#9
|
Deity
Local Time: 21:21
Local Date: October 31, 2010
Join Date: Nov 1999
Location: De Hel van Enschede
Posts: 11,702
|
Two times in a row too
|
|
|
|
January 15, 2002, 08:57
|
#10
|
King
Local Time: 19:21
Local Date: October 31, 2010
Join Date: Oct 2001
Location: Of the universe / England
Posts: 2,061
|
I put the city stuff in just after the last handle event
any way it's my first attempt at putting the coding brackets on
__________________
"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
|
|
|
|
January 15, 2002, 09:07
|
#11
|
Deity
Local Time: 21:21
Local Date: October 31, 2010
Join Date: Nov 1999
Location: De Hel van Enschede
Posts: 11,702
|
Okay, I see it. That's what I had too at first (and I had it in the first handler too), then I actually looked at what the code was supposed to do and realized it probably needed to be global.
|
|
|
|
January 15, 2002, 09:10
|
#12
|
King
Local Time: 19:21
Local Date: October 31, 2010
Join Date: Oct 2001
Location: Of the universe / England
Posts: 2,061
|
poor Pedrunn. I think he expected about 1 or two post but not about fifty telling him what to do
__________________
"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
|
|
|
|
January 15, 2002, 09:14
|
#13
|
Deity
Local Time: 21:21
Local Date: October 31, 2010
Join Date: Nov 1999
Location: De Hel van Enschede
Posts: 11,702
|
And it's not over yet either, I'm sure Peter has some words to say about this too when he reads this
|
|
|
|
January 15, 2002, 09:16
|
#14
|
King
Local Time: 19:21
Local Date: October 31, 2010
Join Date: Oct 2001
Location: Of the universe / England
Posts: 2,061
|
__________________
"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
|
|
|
|
January 15, 2002, 10:26
|
#15
|
King
Local Time: 16:21
Local Date: October 31, 2010
Join Date: Jul 2001
Location: of Natal, Brazil
Posts: 2,555
|
__________________
"Kill a man and you are a murder.
Kill thousands and you are a conquer.
Kill all and you are a God!"
-Jean Rostand
|
|
|
|
January 15, 2002, 10:48
|
#16
|
King
Local Time: 19:21
Local Date: October 31, 2010
Join Date: Oct 2001
Location: Of the universe / England
Posts: 2,061
|
yes it is a ctp thread and yes you are not dreaming. it just happens wen two members find them selves on line at the same time.
Any more problems and my and locutos or somebody will be fighting to help you like me and locutos did. not twenty minutes ago
__________________
"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
|
|
|
|
January 15, 2002, 21:07
|
#17
|
King
Local Time: 19:21
Local Date: October 31, 2010
Join Date: Jan 2000
Location: Gone Fishin, Canada
Posts: 1,059
|
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?
|
|
|
|
January 15, 2002, 21:47
|
#18
|
Deity
Local Time: 21:21
Local Date: October 31, 2010
Join Date: Nov 1999
Location: De Hel van Enschede
Posts: 11,702
|
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)...
|
|
|
|
January 15, 2002, 22:50
|
#19
|
King
Local Time: 19:21
Local Date: October 31, 2010
Join Date: Jan 2000
Location: Gone Fishin, Canada
Posts: 1,059
|
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.
|
|
|
|
January 16, 2002, 05:37
|
#20
|
Deity
Local Time: 21:21
Local Date: October 31, 2010
Join Date: Nov 1999
Location: De Hel van Enschede
Posts: 11,702
|
Yes, I vaguely seem to recall that now. The quality of your code must have confused me or something...
But yes, you are right of course, if you'll check my MedMod code you'll see that the names of all the constants (or rather, the variables that don't change value, not quite the same) are in capitals. I always indicate global variables (or at least I have started to do so recently) by giving them a mod-specifc prefix (MM2_, PBEM_, etc). Helps with mod-compatibility too
|
|
|
|
January 16, 2002, 09:54
|
#21
|
Prince
Local Time: 20:21
Local Date: October 31, 2010
Join Date: Dec 2000
Location: in perpetuity
Posts: 4,962
|
Quote:
|
Originally posted by Peter Triggs
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?
|
I guess the crowd who were lpping up every review before the game are different to the ones still there. Or else they're all stupid.
|
|
|
|
January 17, 2002, 06:12
|
#22
|
King
Local Time: 19:21
Local Date: October 31, 2010
Join Date: Oct 2001
Location: Of the universe / England
Posts: 2,061
|
I was looking at your code last night when i saw this bit
Quote:
|
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
}
}
|
i did not know you could do this. I used the code in my exchange city code and it looks cool now.
__________________
"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
|
|
|
|
Posting 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
|
|
|
All times are GMT -4. The time now is 15:21.
|
|