 |
|  |
 |
|
Pedrunn
|
 |
of Natal, Brazil
Jul 2001 time: 02:19
|
|
I tried to do a code about a nuclear explosion disaster. I wrote the code but i am getting syntax errors everytime i load the game with it.
So can anyone help this unhappy slic newbie. And also point out changes to help me became a better slicer.
code:
HandleEvent(BeginTurn) 'NuclearBoom' post {
city_t tmpcity;
int_t tmpplayer;
int_t i;
int_t randomnum;
message(tmpplayer, 'NuclearBoom');
tmpcity = city[0];
tmpplayer = player[0];
GetCityByIndex(player[0], i, city[0]);
for(i=0; i< player[0].cities; i=i+1) { // Scroll over all cities
if(CityHasBuilding(city[0], "IMPROVE_NUCLEAR_PLANT")){ // if city has Nuclear Plant
randomnum = random(300); // there is a 300 Chance.
if(randomnum == 0){ // of happenning
Event: NukeCity(city[0], player[0]); // a nuclear explosion (nuke).
if(HasAdvance(player[0], ID_ADVANCE_FUSION)) { // But if player has Fusion
randomnum == randomnum - 10000; // nothing happens.
}
}
}
}
}
- Thanks in advance
Last edited by Pedrunn on 19-05-2002 at 10:48
|
|
|  |
 |
|
Peter Triggs
|
|
Gone Fishin, Canada
Jan 2000 time: 05:19
|
|
First, here's a background comment on events and builtin variable arrays. If you look at the Activision SLIC Events document you see events described as:
quote:
BeginTurn(int_t, int_t)
Begin a player's turn
CityBeginTurn(city_t)
Main city begin turn event
CreateCity(int_t, location_t, int_t, int_t [, city_t])
Create a city (first int is cause, second int is unit type that settled (-1 if not from unit)
AddGold(int_t, int_t)
Add gold to player
|
Here the "int_t", "location_t", and so on define the type of variable you have to use when you want to generate one of these events. For example, to give 100 gold to the first player in the game (usually the Human), you'd write "Event:AddGold(1,100);"
It's a bit different when events turn up in the head of an event handler. In this case the above descriptions might be better written as:
quote:
BeginTurn(player[0], value[0])
CityBeginTurn(city[0])
CreateCity(player[0], location[0], value[0], value[1] [, city[0]])
AddGold(player[0], value[0])
|
These "player[0]", "location[0]", "value[0]", and so on aren't visable in the head of the handler but are filled in when the handler is called. For example, when you write a handler:
code:
HandleEvent(BeginTurn) 'Example' pre {
stuff
}
You have a "player[0]" and "value[0]" (= the game turn) to play with. These are the only builtin variables that will automatically have values when this handler triggers. So when you write "tmpcity = city[0];" as you did above, you'll get a "Variable 0 Out of Bounds" error: there is no city[0] in this context.
This is not to say that you can't assign a value to a builtin variable. For example, one could have:
code:
GetCityByIndex(player[0],0,tmpCity);
stuff
city[0]=tmpCity
cityPop=city[0].population;
where you end up with cityPop being the population of player[0]'s 0th (=1st in ordinary language) city. This is what builtins are really useful for: they let you access the current values of their 'members', all those '.XXX's that are listed in the SLIC Built-in variable types document. (BTW, it's a pity there's never going to be another patch because we could sure use a few more, like "city.production" and "player.government".)
But, after all that, you're not using "city[0]" to access a member of the builtin city array, so you don't really need it.
As well as what Martin and Locutus said, you need to reverse the order of two of the above lines so they become:
code:
for(i=0; i< player[0].cities; i=i+1) {
GetCityByIndex(player[0], i, tmpCity);// Scroll over all cities
if(CityHasBuilding(tmpCity, "IMPROVE_NUCLEAR_PLANT")){ // if city has Nuclear Plant
randomnum = random(300); // there is a 300 Chance.
if(randomnum == 0 && !HasAdvance(player[0], ID_ADVANCE_FUSION)){ //and player does not own fusion
Event: NukeCity(tmpCity, player[0]); // a nuclear explosion (nuke).
message(tmpplayer, 'NuclearBoom');
}
}
}
But, again, I'd be surprised if that works. You're trying to get a player to nuke his own city and I don't know if the game will allow that. It will be interesting to see if you can.
Last edited by Peter Triggs on 19-05-2002 at 19:46
|
|
|  |
 |
|
Martin Gühmann
|
 |
Berlin, Germany
Mar 2001 time: 06:19
|
|
If you want that a message is not sent to AI players than I would but the message command into an if condition:
code:
if(randomnum == 0 //if randomnum equal to 0
&& !HasAdvance(player[0], ID_ADVANCE_FUSION)){ // and players doenst have fusion
Event: NukeCity(city[0], player[0]); // a nuclear explosion (nuke).
if(IsHumanPlayer(player[0])){
message(player[0], 'NuclearBoom'); // and a warning message will appear
}
}
For the message box I would use
If you code it like this:
code:
Alertbox 'NuclearBoom' {
Show();
Title(ID_NUCLEAR_BOOM_TITLE);
if (IsHumanPlayer(player[0])) {
Text(ID_NUCLEAR_BOOM_US);
Eyepoint(city[0]);
}else {
Text (ID_NUCLEAR_BOOM_THEM};
}
}
Than you want to sent this message to more than one player, than it would be better to sent it to all player, use the MessageAll instead of Message in the main event handler, of course without the if condition around. And it has only the message_id as argument.
Then I would modify the code like this:
code:
Alertbox 'NuclearBoom' {
Show();
Title(ID_NUCLEAR_BOOM_TITLE);
if (g.player == player[0]) {
Text(ID_NUCLEAR_BOOM_US);
Eyepoint(city[0]);
}else {
Text (ID_NUCLEAR_BOOM_THEM};
}
}
In this case the message boom us go to the victim, boom them goes then to every other player. In your code boom us went to all human player in a game (In SP only one persion in MP more than human players). In your version the message went only to the nuked player. If it is a human player than nuked us, if an AI player than nuked them.
BTW Peter it wouldn't surprise me if it work, you can do in slic very interesting things if you don't care, like moving units on enemy units, or make slavers to enslave themthelves.
-Martin
|
|
|  |
 |
|
Immortal Wombat
|
 |
in perpetuity
Dec 2000 time: 05:19
|
|
If its not possible to nuke yourself, then simulate it by replacing:
code: Event: NukeCity(tmpCity, player[0]);
with the effects of the nuke:
1. Dead people...
code:
city[0] = tmpCity;
AddPops(tmpCity, city[0].population/-3);
2. Visuals...
code:
AddEffect(city[0].location, “SPECEFFECT_NUKE”, “SOUND_ID_NUCLEAR_ATTACK”);
3. Dead Tiles around the city...
code:
int_t rnd;
rnd = random(5);
int_t k;
location_t DeadLoc;
for(k=0; k < rnd; k = k + 1){
GetRandomNeighbor(city[0].location, DeadLoc);
terraform(DeadLoc, TerrainDB(TERRAIN_DEAD));
}
4. KillUnits in the city...
code:
int_t j;
unit_t tmpUnit;
j = GetUnitsAtLocation (city[0].location);
for(k = 0; k < j; k = k + 1){
GetUnitFromCell(city[0].location, k, tmpunit);
Event:KillUnit(tmpunit, 0, -1);
}
Not the easiest way, but still...
|
|
|  |
 |
|  |
 |
|
Pedrunn
|
 |
of Natal, Brazil
Jul 2001 time: 02:19
|
|
I am kind of surprise because i thought the slic would read the code as a whole. But now i relize that it cross the code as a wave. Something like: it reads the line 1 first, then line 2, then line 3 ... (I hope you guys understood me)
quote: Originally posted by Peter Triggs
You have a "player[0]" and "value[0]" (= the game turn) to play with. These are the only builtin variables that will automatically have values when this handler triggers. So when you write "tmpcity = city[0];" as you did above, you'll get a "Variable 0 Out of Bounds" error: there is no city[0] in this context.
...
As well as what Martin and Locutus said, you need to reverse the order of two of the above lines so they become: |
I thought those the game just read the integer. And this integer was going to become something in the game. So its value and meaning was absolute and got shape as the slic was been written but was equal through out all code. (I hope you got that too)
quote:
But, after all that, you're not using "city[0]" to access a member of the builtin city array, so you don't really need it. |
Actually when i made a first draft of the code i used tmpcity all the time i just change after i saw the message cod could not figure out what that was. It just know what city[0] means. So i changed this integer name.
Nice words about the handler having a buit in interger. I did never think about befor. I thougth they were only read whent the event was being used as functions
quote:
But, again, I'd be surprised if that works. You're trying to get a player to nuke his own city and I don't know if the game will allow that. It will be interesting to see if you can. |
I thought the game itself was going to nuke me. Dont you think tat following that point of view this fuction was never going to work since it always meant the civ would always nuke itself.
Martin, I think just the human player is worthy have this message. Why would i send to the others. Ooop it just hit me while i was writing. Are you thinking in a multiplayer? So it is a good idea.
I will test it today. using all of you guys advices. I'll keep you informed. Any problem i can use IW codes (but it wasnt going to be my code at the end 
Last edited by Pedrunn on 20-05-2002 at 09:24
|
|
|  |
 |
|
Peter Triggs
|
|
Gone Fishin, Canada
Jan 2000 time: 05:19
|
|
Martin:
quote:
BTW Peter it wouldn't surprise me if it work,
|
Yes, you're right: it works. I generated a NukeCity event in a savegame and nuked my capitol in 5340 BC. He, He.
Pedrunn:
quote:
Something like: it reads the line 1 first, then line 2, then line 3 ... (I hope you guys understood me)
|
Yup, in the olden days programs used to have line numbers (which the programer specified). If they still did we'd be writing stuff like:
code:
600 for(i=0; i< player[0].cities; i=i+1);
610 GetCityByIndex(player[0], i, tmpCity);
620 if(CityHasBuilding(tmpCity, "IMPROVE_NUCLEAR_PLANT")) then 640;
630 goto 690;
640 randomnum = random(300);
650 if(randomnum == 0 && !HasAdvance(player[0], ID_ADVANCE_FUSION)) then 670;
660 goto 690;
670 Event: NukeCity(tmpCity, player[0]);
680 message(tmpplayer, 'NuclearBoom');
690 next i;
Someone told me that the line numbers are probably still there but we just can't see them. The above code (which I just made up) shows how the computer would be executing the statements one by one. The curley brackets we use now eliminate the "goto" and "next" statements and make things a lot easier to read.
quote:
Actually when i made a first draft of the code i used tmpcity all the time i just change after i saw the message cod could not figure out what that was. It just know what city[0] means. So i changed this integer name.
|
My bad. I was answering your first post where you didn't have the Alertbox. I should have looked more closely at your later posts where you had it in. Yes, you're right, if you're going to have an eyepoint like that you'll need to put "city[0]=tmpCity" in your "NuclearBoom" handler. Here's a couple of other points:
1) In the Alertbox, you need "Eyepoint(city[0].location); "
2) If you're going to use an Alertbox (rather than a messagebox) you have to put a button on it.
code:
Button(ID_OK){
Kill();
}
Alertboxes are described as 'modal', which means it's necessary for the player to respond in order for the game to continue. In order to respond, he's got to have a button to press. Alternately, you might just go for a Messagebox, where the buttons are optional.
3) I'm not at all sure when "g.player==player[0]" is true. You might have trouble with this, but keep on SLICing.
|
|
|  |
 |
|
Martin Gühmann
|
 |
Berlin, Germany
Mar 2001 time: 06:19
|
|
quote: Originally posted by Peter Triggs
3) I'm not at all sure when "g.player==player[0]" is true. You might have trouble with this, but keep on SLICing. |
I guess that is always true in the BeginTurn Event. So it does not do the thing that I expected.
Therefore use these two message boxes instead the one with the if condition. So the part of the code would look like this:
code:
if(randomnum == 0 //if randomnum equal to 0
&& !HasAdvance(player[0], ID_ADVANCE_FUSION)){ // and players doenst have fusion
Event: NukeCity(city[0], player[0]); // a nuclear explosion (nuke).
message(player[0], 'NuclearBoomUs'); // and a warning message will appear
MessageAllBut(player[0], 'NuclearBoomThem');
}
So it should be clear what should be in NuclearBoomThem and NuclearBoomUs. BTW Petdrun you should also vistit Locutus' Resitence is futile homepage there you can also find some Slic1 description, that contains some stuff that is not mentioned in the Slic2 documention, the message boxes are one example other interesting examples are AcceptTradeBid() and AcceptTradeOffer(index). Unfortunatly I have no idea if they work, but it is possible as they can be found in the ctp2.exe.
-Martin
Last edited by Martin Gühmann on 21-05-2002 at 19:00
|
|
|  |
 |
|  |
All times are GMT. The time now is 05:19. Apolyton Time is 00:19. |
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
|
|
|
|
|
|