January 8, 2001, 10:41
|
#61
|
Chieftain
Local Time: 09:52
Local Date: October 31, 2010
Join Date: Dec 2000
Location: Maryland, USA
Posts: 80
|
Heardie and AW, if you try to run my code remember that it only works on a specific tile at the moment. Locutus said he'd take a look at it to add random locations.
AW when you get the error about EQ_func.slc...did you create the EQ_func.slc file and enter the code? It was near the bottom of the code posting. Counting up from the bottom }, go up 19 lines including blanks. Everything below that line (EQ_func.slc) goes in EQ_func.slc. I probably should have made it more clear that you need 2 files.
I would have liked to use a for loop for the buildings but didn't see numbers for them anywhere. I didn't look real hard though. That wasn't the part that took long to do and I don't know whether it would make the game run slower. Maybe if the random number was for the bldg near the end of the list???
Random - I was assuming that Random(8) would give me a chance at 0,1,2,3,4,5,6,7,8. From this site:
· INT Random(range)
Return a random number from 0 to range.
I didn't think I'd get something like 2.37 and have it rounded. I'm pretty sure I got an 8 on my 18th turn in one test. I can't say for sure since I felt pressured and didn't get to make the message I had intended "reports of a magnitude 8 earthquake have come in from sector 3, 47". Anyway, I think random(any number) gives you "any number" + 1 (for zero).
On the last Heardie msg about structures - I found that sometimes you have to use your own variable instead of the built-in variables. In this case tmpPlayer.cities or something. I have no idea when or whatever, I just experiment when I get errors.
I'm stepping away from this for a few days. I'm helping playtest the Alex scenario and I need to play. I also wanted to look more closely to see if any of the other stuff in scenario.slc can be put into functions. When I get the msg or any other changes to the EQ mod I'll post them. Probably before Friday, shouldn't take long for the msg.
|
|
|
|
January 8, 2001, 17:11
|
#62
|
Deity
Local Time: 11:52
Local Date: October 31, 2010
Join Date: Nov 1999
Location: De Hel van Enschede
Posts: 11,702
|
Heardie,
Use player[0] instead of player. Don't use tmpPlayer or whatever, that won't work, SLIC will think it's a number instead of a player.
AW,
An Eyepointer is better than AddCenter, 'cause another AddCenter event might occur and you loose the center on the earthquake. An eyepointer is that button with an eye on it you sometimes see. Clicking on it centers on a location (or unit or city).
Using SLIC to improve AI will prove extremely difficult in practive (though a little 'push in the back' here and there will be possible). Checking if a units are in the same army is simple: cycle through all units in an army (using a for loop and army.size and GetUnitFromArmy) and compare.
Radical,
Random(x) should work from 0 to x-1. I tried Random(3) a couple of dozen times and never got anything but 0, 1, 2. Are you sure you got an 8 once? We should both try again if you are to double check our findings.
Here's fixed code from Radical. The weird thing is, it basicly works but a call to a random function seems to crash the game without an error message. I'm fairly sure it's the Random fuction causing the problem, but I have no idea what the problem is. This is very weird 'cause I've used it often enough in the past without problems. Maybe it can't handle values larger then 60 or something? I tested it on a 48x96 maps and I think Random(52) isn't causing any problems, so if there is a problem with large numbers, the critical number is between 52 and 96. AW, you're an expert now, could you figure this out? I'm gonna be very busy for the next two days at least, so I won't have time to figure it out, but I will ASAP, this affects everyone working with SLIC and the Random code including yours truly.
Note that there are no comments with this code, it crews up the thread so I just left them out. Shouldn't be too hard to understand anyway (all code can go in 1 file).
Code:
|
int_t humanPlayer;
int_t turnCount;
int_t turnMax;
location_t disasterLoc;
location_t disasterLoc2;
int_t maxX;
int_t maxY;
void_f QuakeDamage (location_t tmpLoc, int_t theNum, int_t theNum2) {
int_t i;
int_t tmpNum;
int_t tmpNum2;
unit_t tmpUnit;
tmpNum = theNum;
tmpNum2 = theNum2;
for (i = 0; i < tmpNum; i = i + 1) {
GetUnitFromCell(tmpLoc, i, tmpUnit);
if (tmpUnit.hp > 8) {
DamageUnit(tmpunit, tmpNum2);
}
}
}
HandleEvent(BeginTurn) 'EQStart_F' pre {
if(IsHumanPlayer(player[0])) {
humanPlayer = player[0];
}
turnMax = 600;
turnCount = 0;
DisableTrigger('EQStart_F');
maxX = GetMapWidth();
maxY = GetMapheight();
}
HandleEvent(BeginTurn) 'EQEachTurn2_F' post {
city_t tmpCity;
int_t i;
int_t tmpPlayer;
int_t tmpRichter;
int_t tmpDestroy;
int_t tmpnumberUnits;
int_t tmpXloc;
int_t tmpYloc;
tmpPlayer = player[0];
if (tmpPlayer == 0) { // && Random(2) == 1
tmpXloc = Random(maxX);
tmpYloc = Random(maxY);
// value[0] = tmpXloc;
// value[1] = tmpYloc;
// Message(1, 'EQTest');
turnCount = turnCount + 1;
if (turnCount > turnMax) {
if (humanPlayer == 1) {
Event:GiveMap(2,1);
}
}
MakeLocation(disasterLoc, tmpXloc, tmpYloc);
tmpRichter = Random(8);
tmpDestroy = Random(52);
GetCityByLocation(disasterLoc, tmpCity);
if (CityIsValid(tmpCity)) {
tmpnumberUnits = UnitsInCell(disasterLoc);
if (tmpnumberUnits > 0) {
QuakeDamage (disasterLoc, tmpnumberUnits, tmpRichter);
}
for (i = 0; i < tmpRichter; i = i + 1) {
GetRandomNeighbor(disasterLoc, disasterLoc2);
Event:CutImprovements(disasterLoc2);
tmpnumberUnits = UnitsInCell(disasterLoc2);
if (tmpnumberUnits > 0) {
QuakeDamage (disasterLoc2, tmpnumberUnits, tmpRichter);
}
}
if (tmpRichter > 5) {
if (tmpDestroy <= 50) {
DestroyBuilding(tmpCity, tmpDestroy);
}
if (tmpRichter == 8) {
DestroyBuilding(tmpCity, BuildingDB(IMPROVE_CITY_WALLS));
}
}
if (tmpCity.owner == 1) {
value[0] = tmpRichter;
city[0] = tmpCity;
location[0] = disasterLoc;
Message(1, 'EQCityHit');
}
} else {
Event:CutImprovements(disasterLoc);
tmpnumberUnits = UnitsInCell(disasterLoc);
if (tmpnumberUnits > 0) {
QuakeDamage (disasterLoc, tmpnumberUnits, tmpRichter);
}
for (i = 0; i < tmpRichter; i = i + 1) {
GetRandomNeighbor(disasterLoc, disasterLoc2);
Event:CutImprovements(disasterLoc2);
tmpnumberUnits = UnitsInCell(disasterLoc2);
if (tmpnumberUnits > 0) {
QuakeDamage (disasterLoc2, tmpnumberUnits, tmpRichter);
}
}
if (CellOwner(disasterLoc) == 1) {
value[0] = tmpRichter;
location[0] = disasterLoc;
Message(1, 'EQNoCityHit');
}
}
}
}
Messagebox 'EQCityHit' {
Show();
Text(ID_EQ_CITY_HIT);
EyePoint(location[0]);
}
// in textfiles: EQ_CITY_HIT "Sire, a horrible thing has happened! An earthquake of size {value[0]} on the scale
// of Richter struck in the center of the city of {city[0].name}. People are hiding or fleeing in panic
// and the damage is enormous!"
Messagebox 'EQNoCityHit' {
Show();
Text(ID_EQ_NO_CITY_HIT);
EyePoint(location[0]);
}
Messagebox 'EQTest' {
Show();
Text(ID_TEST_EQ);
}
// in textfiles: EQ_NO_CITY_HIT "Sire, a report just came in. An earthquake of size {value[0]} on the scale
// of Richter struck our empire. Luckily no large cities were at the epicenter, so damage is limited." |
[This message has been edited by Locutus (edited January 08, 2001).]
[This message has been edited by Locutus (edited January 08, 2001).]
|
|
|
|
January 8, 2001, 18:53
|
#63
|
Prince
Local Time: 20:52
Local Date: October 31, 2010
Join Date: Aug 1999
Posts: 684
|
Thats right player[0]! I did figure that out after looking inn the ND Slic!
Now I have yet another problem. It doesn't seem to read any of the code in thee 'If's' after the message, because no buildings get created. This is what should work
Code:
|
if (DisasterType == 1)
{
Message (g.player, 'DroughtBegin'); //doesn't read after here
for(m = 0; m <= player[0].cities; m = m + 1)
{
Event:CreateBuilding(city[0], BuildingDB(IMPROVE_DROUGHT));
}
isDrought = 3; //Three turns of drought
} |
I'm sure it doesnt read after the message because isDrought never gets set to 3, because it never goes back to zero witht the code up the top
Uggh!
[This message has been edited by heardie (edited January 08, 2001).]
|
|
|
|
January 9, 2001, 01:24
|
#64
|
Chieftain
Local Time: 09:52
Local Date: October 31, 2010
Join Date: Feb 2001
Location: Prince of the Barbarians
Posts: 0
|
Thanks for all the help. I hadnt realized at first that it was 2 files. I tried leave it all as one and took out the reference to eq_func, but it didnt like that so I'll try 2 files tonight. I think we have enough of a start to be able to work it all out including the randomized location. I was reading the SLIC doc last night so now I'm an expert And tomorrow I will win the lottery....LOL
I'm going to try to swipe the "general" code from the shipped scenarios and see if i can get that too work too.
------------------
History is written by the victor.
|
|
|
|
January 10, 2001, 19:58
|
#65
|
Local Time: 01:52
Local Date: October 31, 2010
Join Date: Aug 2005
Location: Berkeley, CA, USA
Posts: 1,053
|
Here's a break from posting code to posting an article on disasters. Science is only beginning to realize that, in recorded history, the earth has been hit by some natural disasters that make an ordinary earthquake or volcano small potatoes in comparison. Below is an article about one such disaster. I've looked into this alot, and the prime culprit generally seems to be comets, which in turn can trigger large earthquakes or volcanoes. The article below doesn't mention it, but odds are good based on other evidence that the volcanic explosion mentioned below was triggered by a comet.
So I think having the occasional mega disaster that effects the whole world some and one part of it alot would be a good thing to have in the game. I'll try to dig up more info on mega-disasters, if people are interested. I highly recommend reading the book Catastophe mentioned below, btw. Lots of eyewitness accounts and records from just about every culture on major natural upheaval in the 500s AD, yet history books have completely overlooked this and other such episodes so far. Only in the past few years with greater advancement in the study of tree rings and ice core samples, plus the hitting of Jupiter by a large comet, has science found these ideas acceptable and really gotten into researching them. Before Shoemaker-Levy hitting Jupiter, the common wisdom was that it was impossible for a comet to hit a planet, even though there can be no other explanation for the large impact in Siberia in 1908. Its literally just in the last year or two that a flood of books and reseach has been finished on this, with Catastophe being one example, so we're all still learning a lot about history.
The Dark Ages May Have Really Been Dimmer
LOS ALAMOS, N.M., Dec. 17, 2000 -- The beginning of the Dark Ages may have been literal, as well as figurative, as the result of a massive volcanic eruption in the 6th century, according to a volcanologist at the Department of Energy's Los Alamos National Laboratory.
Ken Wohletz said an eruption in the Indonesian archipelago could have produced a 150-meter-thick cloud layer over the entire Earth, triggering a chain of climatic, agricultural, political and social changes that ushered in the Dark Ages.
Evidence supporting the catastrophe includes tree-ring and ice-core measurements, indications of a huge underwater caldera, and ash and pumice in the same area, said Wohletz, who discusses his work modeling such an eruption today (Dec. 17) at the fall meeting of the American Geophysical Union.
The 6th century was a turbulent, unsettling period in human history. The Roman Empire began to fall; nomads of central Asia migrated to Europe and the Near East; civilizations in Persia, Indonesia and South America collapsed; major religions experienced considerable change as natural events were viewed as omens.
Many of these social transformations resulted from widespread crop failures and the explosion of plague around the globe, which in turn were caused by major climatic changes, Wohletz said. Beginning in about the year 535, according to historical and archeological records, the weather was colder and drier, sunlight diminished, snow fell in summer and regions of persistent drought suffered floods.
Wohletz was a resource for a book postulating that the climate changes resulted from a huge volcanic eruption. The book, "Catastrophe: A Quest for the Origins of the Modern World" by David Keys, was published earlier this year.
Wohletz said he worked with Keys to try to identify a volcano that could produce such dramatic climate change. "We came up with an eruption that would certainly be the largest in recorded history, some four or five times bigger than the (1815) eruption of Tambora, which is usually considered the biggest eruption in the past few millennia," he said.
Such an explosion, he said, would eject some 200 cubic kilometers of material, and one-third to one-half of it would be lofted into the stratosphere, where it would remain suspended for months to years while being carried around the globe.
"It would have produced enough dust and water vapor (in the form of ice crystals) to form a cloud layer 150 meters thick over the entire globe, and that's a conservative estimate," he said, adding that a cloud of particles that thick may have diminished the transmission of sunlight by as much as 50 percent.
Wohletz said tree-ring data collected around the world and ice-core measurements in Greenland and Antarctica support the possibility of a huge eruption in the 6th century. Ocean depth measurements between Sumatra and Java * where Krakatoa exploded in a well known 1883 eruption * indicate the presence of a caldera up to 50 kilometers in diameter, and a recent survey uncovered evidence of ash and pumice layers formed in the area during the appropriate time frame.
Under a likely scenario, a large volcano, which Wohletz calls proto-Krakatoa, connected the islands of Sumatra and Java. When it erupted and then subsided, it created the Sundra Strait and left a ring of smaller volcanoes, including the present day Krakatoa. The ash, dust and water vapor blown into the stratosphere would disperse across both the Northern and Southern Hemispheres.
"This volcano would have had the potential to be a major player in destabilizing the climate around the world," he said. "An eruption that could produce a caldera 50 kilometers across would have been big enough."
Although definitive evidence for such a catastrophic eruption has not been discovered, the possibility deserves a full-scale field study, Wohletz said, in part because of the potential impact on the world if another such catastrophe happens.
"(Key's book) is the first detailed account of how closely humanity is linked to the natural world," he said. "If the natural world goes through some large upheaval, we'll all be affected."
|
|
|
|
January 11, 2001, 14:22
|
#66
|
Deity
Local Time: 11:52
Local Date: October 31, 2010
Join Date: Nov 1999
Location: De Hel van Enschede
Posts: 11,702
|
Heardie,
Well, that's because you have a variable m, you make it zero, you create a building in city[0] (let's say city[0] happens to be Rome at that point), then you make m one, then you create another building in Rome, then you make m two, make another building in Rome, etc. You create all the buildings in the same city. city[0] is not much different from a regular variable, it stores a values and stays the same until you manually change it. The only catch is that these built-in variables might change if a certain event happens (or another eventhandler executed at the same time changes it), but you can't control those events. The events you invoke from within an EventHandler or function are put in a queue and executed one at a time at CtP2's leasure, outside your control. So unless an event happens to occur just as you cycle through your cities, city[0] will remain the same throughout the eventhandler or function your code is in (unless you manually change it of course).
You must insert the line "GetCityByIndex(player[0], m, tmpCity);" between the for line and the CreateBuilding line and declare tmpCity higher up in the code and use it instead of city[0] in CreateBuilding (so that tmpCity actually cycles through all cities). Maybe you can use city[0] directly as well but whenever possible it's safer to use a user-defined variable like tmpCity so if another event happens that changes the value of city[0], you're screwed - I'm not sure if it's possible for this to happen in CtPII but it was in CtPI and I for one think it's better to be safe than sorry.
Harlan/wheatin,
Yeah, I'm aware of such stories, it would indeed be cool to implement, though I'll leave the details on how to do that to others, unless my help is needed for the 'technical' part of course.
|
|
|
|
January 11, 2001, 16:20
|
#67
|
Chieftain
Local Time: 03:52
Local Date: October 31, 2010
Join Date: Nov 2000
Location: Green Bay, WI USA
Posts: 81
|
Locutus,
I cut and pasted your last code in and got a delightful crash that required a reboot in order to load the game again. I broke it down to test if it was the Random() causing a crash by making my own slic file with just parts of the code posted. I was able to Random() any number I chose and display it in a message box without any crashes or errors. I included further pieces of your code and encountered a slic error (I have debugslic=yes in my profile.txt) in "object testingthis function_GetCityByLocation. Wrong type of arguement." I could close the little warning window and go back to playing though. It didn't crash the game. Anyways, from what I have seen Random() isn't causing problems.
*Edit*
Ignore the wrong type of arguement thing, I used int_t instead of city_t. Stupid me.
*Edit again*
Through trial and error (and a number of reboots) I found the troublesome part that was causing it to crash:
Event:CutImprovements(disasterLoc);
Commenting them out kept the game from crashing. Maybe we have to check if there are improvments there to pilliage first. If that doesn't work I guess we can terraform it to the same terrain type. (I think that would kill the improvements)
[This message has been edited by Jerk (edited January 11, 2001).]
[This message has been edited by Jerk (edited January 11, 2001).]
|
|
|
|
January 11, 2001, 16:40
|
#68
|
Local Time: 01:52
Local Date: October 31, 2010
Join Date: Aug 2005
Location: Berkeley, CA, USA
Posts: 1,053
|
Yeah,
The Black Sea flood is another stunning example that's just been discovered. Pretty astounding, the few things they've come across so far as they start to explore. The Black Sea is a complete biological dead zone once you get below about 100 meters, so they've already found a ship from BC times looking basically like it did when it went down, even with the mast still standing! So far they've only come across one house from pre-flood times, but if they do find whole towns, it could be some of the most astounding discoveries of all time. The theory is the flood came slowly, about a mile a day. Fast enough so that everyone had to flee, but slow enough so that the buildings would all still be standing.
Still, that was such a wierd disaster its hard to see how it could be implemented in the game. Its a good example though of how the catastophists are getting the upper hand over the gradualists (those who think that large natural disasters almost never happen) through new revelations.
A reason why the gradualists have had the upper hand is because apparently the last 1500+ years have been unusually quiet. But that's just luck: an analysis of the ice cores shows there's a big comet hit about once every 1000 years. If the comet (or pieces of it, sometimes it breaks up entering the atmosphere) hits water, the effects are very different than if it hits land. Meteor hits are apparently much less common, but that did take care of the dinosaurs.
One implementation issue I don't know if you've all addressed. In the game the years per turn is always different from one age to the next. But natural disaster occurances shoudn't speed up like technological advancement does. So the odds of a disaster occurring if there's 1 turn per 10 years should be ten times as great as if there's 1 turn per 1 year.
|
|
|
|
January 11, 2001, 18:18
|
#69
|
Prince
Local Time: 09:52
Local Date: October 31, 2010
Join Date: Apr 1999
Location: home
Posts: 601
|
Good point about the time frame. But the difference in turn length (from one to 20?) means that a disaster that might occur three or four times before 1500 (5500 years) might never occur in the rest of the game (800 years).
Note that minor disasters have been *very* regular, if only because of El Nino. Two years ago there was a book about all the El Ninos, and their effects on history, including some of the worst famines and floods in history, as well as other "unexplained" events, such as the destruction of the first colony in Virginia at Roanoke (a spectacularly severe winter they were unprepared for).
|
|
|
|
January 12, 2001, 00:51
|
#70
|
Local Time: 01:52
Local Date: October 31, 2010
Join Date: Aug 2005
Location: Berkeley, CA, USA
Posts: 1,053
|
You're right Wheathin, but that's okay. Once turns start coming 1 year per turn, things get pretty hot and heavy in other areas so I doubt people would mind not getting whacked by disasters as often. Anyways, if you do have an average of 1 major disaster per 1000 years, the odds are good it will happen in the last 800 years of play, and it would be a real doozie if it hit a fully populated and developed planet.
I think El Nino is too minor of an effect to include in the game though. Cities get 3 year starvation protection as default, and El Ninos rarely last that long. But a prolonged drought would be really interesting to play through. I wonder if SLIC can handle it well though, since Wouter says its weak in the food dept.
|
|
|
|
January 12, 2001, 01:11
|
#71
|
Prince
Local Time: 09:52
Local Date: October 31, 2010
Join Date: Apr 1999
Location: home
Posts: 601
|
Similarly, there is a lot of interesting research over the last three years or so about the "Great Flood." The flood of Noah is repeated in hundreds of other cultural myths from southern europe and the middle east, but only recently have scientists identified it: the massive expansion of the Black Sea about 7,000-9,000 years ago.
The Black Sea had been a small lake in a large depression, but the Bosporous was closed off by a large natural dam - part of the mountains in the area. Eventually, the dam broke and flooded the basin. The lake, now a sea, rose hundreds of feet, covering what had been hills, marshes, and plains that supported small early human communities. Those communities fled into Southern Europe, the Causasus, and Anatolia, taking with them an oral history of the flood, which was steadily incorporated into their origin myths and creation stories.
Linguists and Anthropologists first identified the possibility based on the prevalence of flood myths. Recent examinations of the floor of the black sea have revealed the outlines of structures and tools on the sea bed - encampments or villages.
|
|
|
|
January 12, 2001, 20:06
|
#72
|
Prince
Local Time: 20:52
Local Date: October 31, 2010
Join Date: Aug 1999
Posts: 684
|
Thanks again Locutus, but I am still having prollems
*heardie sighs and bangs head against table again!*
I did wait you said and go tthis error
In object EveryTurn, function _GetCityByIndex: Value out of bounds
What does it mean?
|
|
|
|
January 13, 2001, 05:07
|
#73
|
Prince
Local Time: 20:52
Local Date: October 31, 2010
Join Date: Aug 1999
Posts: 684
|
Okay figureed that out, just remove the '=' from the for loops. Now i problem that i cant work out because it is not flagged as an error. When the drought building is built isdrought is set to three. then each turn it is decremented by 1 and then when it gets to zero the drought building is removed yet this doesnt work!
Have a look at the code. Can you tell me why not?
|
|
|
|
January 13, 2001, 09:04
|
#74
|
Deity
Local Time: 11:52
Local Date: October 31, 2010
Join Date: Nov 1999
Location: De Hel van Enschede
Posts: 11,702
|
Guess I should have looked at the code more closely earlier, I could have picked out most of the bugs fairly quickly if I wanted to. This is the perfect example of why some people are against using a lot of comments in code, it make you loose the overview of the actual logic. I don't agree with these people, but this *is* a classic. Here's part of the code with the comments removed:
Code:
|
isDrought = -1;
if (isDrought > 0) {
isDrought = isDrought - 1;
} |
You see? isDrought is always -1! You should make it a global variable instead of local (move the declaration out of the eventhandler and place it at the very top of the file, right above '#include msg.slc') and initialize it to -1 (or 0, doesn't really matter here) in a seperate eventhandler that only gets executed once (FirstTurn will do the trick). Now the code *should* work, or at least I can't spot any other obvious bugs in the drought part of the code (the isWeather part has similar bugs but I guess you can figure those out yourself now).
[This message has been edited by Locutus (edited January 13, 2001).]
|
|
|
|
January 13, 2001, 20:20
|
#75
|
Prince
Local Time: 20:52
Local Date: October 31, 2010
Join Date: Aug 1999
Posts: 684
|
hmmm, I am a fool. It's always the simpilest errors that get you. It's the same with c++, they're a ***** to track down and when you see them, it is so obviouos.
Thanks a ton Locutus
What would have been really cool was a debug window in the game where you cacn track variable values
[This message has been edited by heardie (edited January 14, 2001).]
|
|
|
|
January 14, 2001, 07:33
|
#76
|
Deity
Local Time: 11:52
Local Date: October 31, 2010
Join Date: Nov 1999
Location: De Hel van Enschede
Posts: 11,702
|
|
|
|
|
January 14, 2001, 09:18
|
#77
|
Deity
Local Time: 11:52
Local Date: October 31, 2010
Join Date: Nov 1999
Location: De Hel van Enschede
Posts: 11,702
|
Jerk,
Sorry, I seem to have overlooked your post for some reason.
Thanks for all the hard work, it's much appreciated. But your findings are very strange and contradict my findings. I originally had it so that the Random function was performed everytime a player's turn began. This usually crashed the game after 2 or 3 players had had their turn. Then I made it so that the only time when the Random function was performed, was during the barbarian's turn. This caused the game to crash as soon as the Barbarians had their first turn, every single time. So my conclusion was that the Random function was broken. Now you're telling me it's the CutImprovements event that's broken and the Random function works fine. This sounds like a much better explanation but it doesn't explain my crashes. I will look into this in more detail when I have the chance (who's stupid idea was it to give a day only 24 hours? ) and prey that you're right and I made a mistake or whatever...
|
|
|
|
January 14, 2001, 14:27
|
#78
|
Prince
Local Time: 03:52
Local Date: October 31, 2010
Join Date: May 1999
Location: Tulsa, Oklahoma, USA
Posts: 716
|
Locutus,
I played with this a little and from what I can tell, the Random IS broken. CtP2 just abends when using it.
|
|
|
|
January 15, 2001, 00:08
|
#79
|
Chieftain
Local Time: 03:52
Local Date: October 31, 2010
Join Date: Nov 2000
Location: Green Bay, WI USA
Posts: 81
|
Well, after testing I still maintain that it's still an issue with the Effect:cuttileimprovements(disasterloc) portion of the script. I believe that the effect has a problem working in spots where nobody is at or is yet to be uncovered. I have gone through and tested this several times. If I remove the effect and replace it with Terraform(disasterloc,17) I get no crash and it replaces the random tiles with a dead tile. If I go ahead and start a game, jot down the x and y for a tile near my city, replace the randoms with those set x and y coordinates it works with cuttileimprovement. If I rig the random number so x and y will fall around my city (Random(3) + mycityY,Random(3) + mycityY) it also works without a crash. I think that is the problem. The game doesn't work when you randomly pick a spot on the map early in the game when the overwhelming odds are that the spot will be an undiscovered portion of land. Try doing what I did to test this. Replace the cuttileimprovement with terraform(disasterloc,17). Then put that back, and try rigging the random choice to fall in your original city radius. I can reproduce the error by adding this little chunk of script into script.slc:
Code:
|
HandleEvent(BeginTurn) 'IWillCrash' post {
location_t tmpLoc;
location_t disasterLoc;
if(g.year > 3) {
MakeLocation(disasterLoc, 1, 1);
Event:CutImprovements(disasterLoc);
}
} |
|
|
|
|
January 15, 2001, 01:41
|
#80
|
Chieftain
Local Time: 03:52
Local Date: October 31, 2010
Join Date: Nov 2000
Location: Green Bay, WI USA
Posts: 81
|
Locutus,
It worked last time I tested it. It no longer works. I guess it wasn't the cuttileimprovements that is causing the damage. However, removing the random parts for picking the random x and y position and the richter and damage variables still produces a crash for me when the barbarians take their first turn (after my very first turn). I can also comment out everything under the "if (CityIsValid(tmpCity)) {" and it does not crash. This is why I don't think it's Random() causing the problem.
|
|
|
|
January 16, 2001, 04:33
|
#81
|
Deity
Local Time: 11:52
Local Date: October 31, 2010
Join Date: Nov 1999
Location: De Hel van Enschede
Posts: 11,702
|
I did some testing as well last night and couldn't recreate any kind of bug with the Random function, I generated random numbers up to 1000 and even generated hundreds of locations on my map using (the relevant part of) the above mentioned algorithm without problems. I tried to use the CutImprovements on a random location only twice and the game crashed immediately both times, so it would seem that it is indeed the CutImprovements event that's causing problems. I will look into this problem again tonight, since using it on a completely explored map crashed the game just as well as using it on a unexplored map (though I used the cheat menu to set the map explored, that might be the problem).
[This message has been edited by Locutus (edited January 16, 2001).]
|
|
|
|
January 17, 2001, 02:00
|
#82
|
Chieftain
Local Time: 09:52
Local Date: October 31, 2010
Join Date: Dec 2000
Location: Maryland, USA
Posts: 80
|
Sorry, I kinda forgot all about this. I've been so busy helping on the Alex scenario.
I found two functions that might be useful. TileHasImprovement(location, imptype) and CellOwner(location). TileHasImprovement is probably the one to use. If so, just add a for and an if to check to be sure there is actually an improvement to destroy before trying to destroy it. Sorry I didn't think about that and put it in my original code. I haven't looked to see what the values are for imptype. I might try to work on this tomorrow to add TileHasImprovement.
Just an FYI, Random(500) has worked for hundreds of turns with no known problems in the Alex scenario.
|
|
|
|
January 17, 2001, 06:43
|
#83
|
Deity
Local Time: 11:52
Local Date: October 31, 2010
Join Date: Nov 1999
Location: De Hel van Enschede
Posts: 11,702
|
Yes, I'm pretty sure Random isn't the problem. I suspect that checking with TileHasImprovement first and then killing the improvements will solve the problem, but I got hold up with some personal stuff last night so I didn't get to do my final testing on this. Hopefully tonight...
|
|
|
|
January 17, 2001, 21:44
|
#84
|
Chieftain
Local Time: 09:52
Local Date: October 31, 2010
Join Date: Dec 2000
Location: Maryland, USA
Posts: 80
|
I think I have it so it won't crash anymore. I replaced
Event:CutImprovements(disasterLoc2);
with
if (CellOwner(disasterLoc2) >= 1 && CellOwner(disasterLoc2) <=8) {
Event:CutImprovements(disasterLoc2);
}
Then did the same with the other CutImprovements. Watch it. One of the CutImprovements is just disasterLoc not disasterLoc2.
Thanks Jerk, for figuring out the problem.
I ran this over 40 times with no crash. It's possible I just got lucky, so it may still crash. In the random location part, I make it so that x & y are never < 2 or greater than maxX - 2 or maxY - 2. I figure that way it won't try to do something off the edge of the map. Though I think the CellOwner addition should probably solve the problem. I was still crashing with CellOwner >= 0, so I changed it to >= 1. I don't know what CellOwner returns if there is no owner. So barbarian areas will not have earthquakes, neither will unowned areas. That stinks. I was looking forward to having units wander around and get hit by an earthquake.
I still have a problem to work out before I post the entire revised code. Anybody know how to clear a city variable? Before I end the "if" below, I need to clear tmpCity or it won't change until it happens to hit another city and it never runs the non-city earthquake code again.
GetCityByLocation(disasterLoc, tmpCity);
if (CityIsValid(tmpCity)) {
|
|
|
|
January 18, 2001, 06:23
|
#85
|
Chieftain
Local Time: 03:52
Local Date: October 31, 2010
Join Date: Nov 2000
Location: Green Bay, WI USA
Posts: 81
|
Hmm, I put in the check for cellowner and used:
tmpCellOwner = CellOwner(disasterLoc);
if (tmpCellOwner >= 0) {
Event:CutImprovements(disasterLoc);
}
I got no crashes at all after adding this in the appropriate spots (wherever just CutImprovements was). Not sure right now why I didn't crash and yours did. I have altered the orignal posted code a bit (I threw in test messageboxes and stuff). By just putting the CutImprovements in the if statement it will still damage units wandering around the epicenter. I found that CellOwner returns -1 if its unowned. I have yet to have the script land on a barbarian city radius. I assume it would return 0 (the index number for barbarians). An interesting side note, I used the cheat menu to reveal the entire map, then place a barbarian city. When you hover over a tile you will see little information on the bottom under your control panel that says the owner of the tile or units there. Barbarian cities I placed did not seem to have any owned tiles. I could see the little white dashed line around the city that indicates its resource harvest border but they had no national border and under the control panel it did not say it was owned by anyone.
[This message has been edited by Jerk (edited January 18, 2001).]
|
|
|
|
January 18, 2001, 08:37
|
#86
|
Deity
Local Time: 11:52
Local Date: October 31, 2010
Join Date: Nov 1999
Location: De Hel van Enschede
Posts: 11,702
|
Radical,
You don't have to clear the tmpCity variable. It's a local variable, right? That means that as soon as the eventhandler this variable is in stops executing, the tmpCity variable will be 'destroyed', it will no longer exist. In the next eventhandler you can't use it anymore because it won't exist anymore and when at some later point the same eventhandler is called again, it won't know the tmpCity variable either, it will declare a new variable that's also called tmpCity, but this isn't the same variable, it just happens to have the same name. Thus it won't have a valid city in it either and hence there's no need to worry about the code never not executing.
I encountered some problems with this several times with eventhandlers that were pre, but I haven't figured out the details of this yet. So whenever you can, use post instead of pre and also, test your code to verify that I'm correct, just to be sure.
BTW if you really need to, you can get an invalid city in a city-variable by taking a random neighbor of another, valid, city location and use GetCityFromLocation to assign the city at that location (which doesn't exist because cities are AFAIK always 1 tile apart minimum) to your city variable.
Jerk,
Hmm, I'd swear I've seen barbarian national borders in the past. Maybe this only happens when barbarians conquer existing cities? You could try to do that. Create a bunch of empty cities and an army of barbarians next to each of them. Then move them in (I think you can do this manually from the cheat menu when you have player 0 selected and you open the unit-section of the cheat menu). If it's not that it's probably a pre-patch or pre-release thing. The best way to test if it works for barbarians is of course to create barbarian cities all over the place so the odds that barbarians will be hit is relatively large.
|
|
|
|
January 18, 2001, 16:30
|
#87
|
Deity
Local Time: 11:52
Local Date: October 31, 2010
Join Date: Nov 1999
Location: De Hel van Enschede
Posts: 11,702
|
Jugding from the code you posted the problem seems to be in disasterLoc, not in tmpCity, but then again, you'd have to post the entire code before I can draw any conclusions about it. If you don't want to post the entire code, put it on a website (if you don't have a website, email me, I'll post them on my website for you). That way anyone that wants to figure out what the problem is, can look at the whole code. You can't draw any conclusions if you don't have all the code. It's like watching a game of football: watching only the first half isn't enough to say who will win (well, not in most cases anyway )...
Building index (as well as any other index): AFAIK it's the order in buildings.txt that determines this. So the first building is 0, the second 1, etc. For the standard game this means 0 = Academy, 1 = Airport, etc. If you're gonna use this info, double check this though, I'm fairly certain of this but not 100%.
|
|
|
|
January 18, 2001, 17:32
|
#88
|
Chieftain
Local Time: 03:52
Local Date: October 31, 2010
Join Date: Nov 2000
Location: Green Bay, WI USA
Posts: 81
|
Is it possible to access the player built in variables for a civ that is not player[0]? With this quake mod I would like to message the human player if a quake hits another civilization. Any attempts to do this so far have resulted in slic syntax or out of bounds errors. To do this I would like to use the results of CellOwner() when its >= 0 like in my previous post. If I try to use player[tmpCellOwner].country_name I get out of bounds errors. I get a syntax error if I try player.tmpCellOwner.country_name. forcing player[0] = tmpCellOwner doesnt cause a slic error when it does player[0].country_name but it also doesn't work (it's not getting set to the country name at all). I am probably overlooking something simple. Help appreciated.
|
|
|
|
January 18, 2001, 17:56
|
#89
|
Chieftain
Local Time: 09:52
Local Date: October 31, 2010
Join Date: Dec 2000
Location: Maryland, USA
Posts: 80
|
Well, I'm probably missing something or have something in the wrong place but as far as I can tell tmpCity is not cleared, reinitialized or whatever. I know that's the way it should work but it doesn't appear to be working that way.
Here's the code with most comments removed. I didn't include the QuakeDamage function since I don't believe it's causing a problem. I haven't changed that anyway. I also took out most of the buildings and elseifs to take up less space. That section has not changed. I just added the relevent stuff from my string file at the bottom so you could see what I'm displaying. Right now it's set where x is always 4 and y is set so I have a good chance of hitting 2 cities on my test map.
Everything appears to work fine until it hits a city the first time. Then the EQHitCity message displays every time with the first city name until it hits the other city. Then the 2nd city's name displays until it hits another city.
Until the first city is hit, EQWhatCity prints city[0].name. After the first city is hit EQWhatCity displays the city name that was hit the previous turn and then continues to display that name until another city is hit.
Once the first city is hit, EQNoCity never displays again.
The x and y values continue to change. In this code just y, since I have x fixed at 4 for testing. I shouldn't say never, I advanced maybe 15 turns max after hitting the first city.
Locutus, I'll send you the complete set of files.
Jerk, this is displaying a message every turn, regardless of where it hits. Very annoying really, but I won't have quakes occuring every turn in my final version. Doesn't solve your problem exactly, since you want the civ. You probably know how to display without the civ anyway.
//////////////////////
// Global variables //
//////////////////////
int_t humanPlayer;
int_t tmpYloc;
int_t tmpXloc;
int_t turnCount;
int_t turnMax;
#include "EQ_func.slc"
//---------------------------------
// Stuff to do when the game starts
//-----------------------------------
HandleEvent(BeginTurn) 'EQStart_F' pre {
int_t tmpPlayer;
if(IsHumanPlayer(player[0])) {
humanPlayer = player[0];
turnMax = 600;
turnCount = 0;
DisableTrigger('EQStart_F');
}
}
//-----------------------
// Stuff to do every turn
//-------------------------
HandleEvent(BeginTurn) 'EQEachTurn_F' post {
city_t tmpCity;
int_t i;
int_t tmpPlayer;
int_t tmpRichter;
int_t tmpDestroy;
int_t tmpnumberUnits;
location_t disasterLoc;
location_t disasterLoc2;
tmpPlayer = player[0];
//tmpXloc = Random(62);
tmpYloc = Random(10) + 87;
//if (tmpXloc < 2) {
tmpXloc = 4;
//}
if (tmpYloc < 2) {
tmpYloc = 2;
}
if (tmpPlayer == 1) {
turnCount = turnCount + 1;
if (turnCount > turnMax) {
if (humanPlayer == 1) {
Event:GiveMap(2,1);
}
} // temp for testing take out later
MakeLocation(disasterLoc, tmpXloc, tmpYloc);
tmpRichter = Random(9);
tmpDestroy = Random(53);
// value[0] = tmpRichter;
city[0] = tmpCity;
Message(1, 'EQWhatCity');
GetCityByLocation(disasterLoc, tmpCity);
if (CityIsValid(tmpCity)) {
value[0] = tmpRichter;
city[0] = tmpCity;
Message(1, 'EQHitCity');
tmpnumberUnits = UnitsInCell(disasterLoc);
if (tmpnumberUnits > 0) {
QuakeDamage (disasterLoc, tmpnumberUnits, tmpRichter);
}
for (i = 0; i < tmpRichter; i = i + 1) {
GetRandomNeighbor(disasterLoc, disasterLoc2);
if (CellOwner(disasterLoc2) >= 1 && CellOwner(disasterLoc2) <=8) {
Event:CutImprovements(disasterLoc2);
}
tmpnumberUnits = UnitsInCell(disasterLoc2);
if (tmpnumberUnits > 0) {
QuakeDamage (disasterLoc2, tmpnumberUnits, tmpRichter);
}
}
if (tmpRichter > 5) {
if (tmpDestroy == 0 | | tmpDestroy == 1) {
DestroyBuilding(tmpCity, BuildingDB(IMPROVE_VR_AMUSEMENT_PARK));
} elseif (tmpDestroy == 2) {
DestroyBuilding(tmpCity, BuildingDB(IMPROVE_ACADEMY));
// lots more elseifs and buildings between these 2 lines
} elseif (tmpDestroy == 52) {
DestroyBuilding(tmpCity, BuildingDB(IMPROVE_UNIVERSITY));
}
if (tmpRichter == 8) {
DestroyBuilding(tmpCity, BuildingDB(IMPROVE_CITY_WALLS));
}
}
} else {
value[0] = tmpRichter;
Message(1, 'EQNoCity');
if (CellOwner(disasterLoc) >= 1 && CellOwner(disasterLoc) <=8) {
Event:CutImprovements(disasterLoc);
}
tmpnumberUnits = UnitsInCell(disasterLoc);
if (tmpnumberUnits > 0) {
QuakeDamage (disasterLoc, tmpnumberUnits, tmpRichter);
}
for (i = 0; i < tmpRichter; i = i + 1) {
GetRandomNeighbor(disasterLoc, disasterLoc2);
if (CellOwner(disasterLoc2) >= 1 && CellOwner(disasterLoc2) <=8) {
Event:CutImprovements(disasterLoc2);
}
tmpnumberUnits = UnitsInCell(disasterLoc2);
if (tmpnumberUnits > 0) {
QuakeDamage (disasterLoc2, tmpnumberUnits, tmpRichter);
}
}
}
}
}
#include "EQ_msg.slc"
EQ_NO_CITY "An earthquake of magnitude {value[0]} has struck {tmpXloc}, {tmpYloc}."
EQ_HIT_CITY "An earthquake of magnitude {value[0]} has struck the city of {city[0].name} at location {tmpXloc}, {tmpYloc}."
EQ_WHAT_CITY "What! An earthquake of magnitude {value[0]} has struck the city of {city[0].name} at location {tmpXloc}, {tmpYloc}."
|
|
|
|
January 19, 2001, 01:13
|
#90
|
Chieftain
Local Time: 09:52
Local Date: October 31, 2010
Join Date: Dec 2000
Location: Maryland, USA
Posts: 80
|
I think I'll replace my fix with Jerk's fix and see if I have any problems. When I crashed I was thinking the unowned tiles might return 0, so that's why I changed it to >= 1.
I've seen the barbarian borders before but I'm sure I only saw them when they capture a city. I've never placed a barbarian city.
tmpCity is local but it seemed to stick once I hit a city. I need to do further testing and have the x,y appear in a message box so I can determine exactly what is happening. I'll have to create more messages for testing. I should have posted more of the code and explained why I think I need to clear tmpCity.
GetCityByLocation(disasterLoc, tmpCity);
if (CityIsValid(tmpCity)) {
city[0] = tmpCity;
value[0] = tmpRichter;
Message(1, 'EQHitCity');
On turn thirty-something a quake hit a city. Every turn after that I got a message that the same city was hit. It did not appear to "really" be hitting the same city since the units were not being damaged. It's very unlikely to hit a city on any given turn, so CityIsValid(tmpCity) should have been false and I should not even get the message that a city was hit. Once I display the x,y coords I'll know what is really happening and probably find I have a mistake somewhere.
I'd post the whole thing but I'm leaving the buildings the way I had them, so there's a million lines. Someone wanted (and I might want this also) to be able to give certain buildings a greater or lesser chance of being destroyed. I think leaving the buildings all listed, adjusting the random #, then adding or's for the new random #'s is the easiest way to do that.
If I knew what building was a certain index #, I might use a different method. That's a problem I've been running into a lot. What's the best way to determine index numbers for buildings, tile improvements, etc? Are they listed somewhere? I really wanted to use TileHasImprovement instead of CellOwner but one of the tileimp files I looked at had terraform stuff in it. I think that was the icon file for TI. Is it as simple as the order they are listed in in the text files?
Thanks again for the help.
|
|
|
|
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 05:52.
|
|