Page 1 of 1

Smoke Mod ... Pip ?

Posted: Tue Jul 12, 2011 12:58 am
by Merr
Pip,

Well, I figured out how to add smoke to the game but I was at a loss when trying to remove the "blocking" objects when removing smoke.
I did, however, solve my problem but there has to be a better approach.

I spent hours trying to write scripts using all the object related functions, and I just couldn't get them to work correctly.
The biggest problem is that object ID's are not constant across game runs (as you know).
The ID's start at 0 and end at the last object placed, which can be in the hundreds.
I discovered that if you delete an object, that ID is now available and will be reused if you place another object.

I'm trying to retreive the ID of an object on the map ... but to no avail.

Below is the script that I'm using to currently remove the smoke "blocking" objects. You'll note that I'm just running a loop to look for ID's from 40-100. I set this range of values because I know that I have ~46 objects on the map. This technique works great, and it's very fast compared to running a loop across the map to look for objects. When I tried using other functions to run loops across the map it took 5-10 seconds to run it ... perhaps it was bad code because I never could get that to work right!

Also, you'll note that I'm calling the function ... SetObjectPosition(id, x, y) ... before I deleted the smoke object. Believe it or not, moving the object to the "trash can" at X/Y coordinates 0,0 was necessary to update the LOS at the beginning of the turn. Without this move, the game engine (LOS) would still think an object is on the tile, despite being physically removed. :shock:

Anyway ... can you think of a better approach (script wise) that I can use to locate and remove an object on the map?

Thanks!

Code: Select all

FUNCTION StartTurn(side)
{
int id ;
int x ;
int y ;
int i ;

	if( side == 0 )
	{		
		for (id=40; id<=100;id++)
		{
			if( IsObjectName(id, "smoke_allied") == 1 )		
			{
				SetObjectPosition(id, 0, 0) ;
				DeleteObject(id) ;
			}
		}		
		AddVizFunctionCall("HideEffectMarker", -9000) ;
	}
}

Posted: Tue Jul 12, 2011 5:07 pm
by pipfromslitherine
Can you not use GetObjectFromName? It is designed to do this internally, which is somewhat faster.

Deleting an object might not update the LOS calcs - I would need to check the internals. I think it's designed not to break where all the other units on the map can see. So there would need to be some logic to only affect those tiles directly made visible/invisible by the object being altered.

Cheers

Pip

Posted: Tue Jul 12, 2011 8:56 pm
by Merr
pipfromslitherine wrote:Can you not use GetObjectFromName? It is designed to do this internally, which is somewhat faster.
That was one of the functions I tried ....

//return the id of the Nth object on the map of the described type. If objectSet is an empty string then any object matching the objectName will be returned. Returns -1 if no more are found. Not case sensitive
GetObjectFromName(objectSet, objectName, index)


But, whats the index parameter? I think I still needed to run a loop through possible index values to find the right object because the "index" was the ID number. How would I use that function in a script?
Deleting an object might not update the LOS calcs - I would need to check the internals. I think it's designed not to break where all the other units on the map can see. So there would need to be some logic to only affect those tiles directly made visible/invisible by the object being altered.
It updated the LOS ... but only when I moved the object first, then deleted it. If I didn't move the object and just deleted it, the LOS wouldn't update.

Posted: Tue Jul 12, 2011 9:46 pm
by pipfromslitherine
No - basically you do something like:

for(i=0;i<999999;i++)
{
id = GetObjectFromName(....
if(id == -1)
{
i = 999999 ; // end the loop
}
else
{
// do something with the object id
}
}

It's less elegant because there isn't a while construct in the scripting currently, but basically you just walk through, passing in the N to get the Nth object of that type, and it returns the object id, or -1 if there are no more. Note that N begins at zero.

Hope that helps!

Cheers

Pip

Posted: Tue Jul 12, 2011 9:54 pm
by Merr
Ok ... I think I see ... So, "i" is the loop you're using for the index parameter in the function, eh?

I'll give it a shot .... I don't think I tried a flow like the one you wrote, thanks ...

Posted: Tue Jul 12, 2011 10:43 pm
by pipfromslitherine
Yeah - it's not a great pattern for the scripting language as is, so you do end up with somewhat inelegant code. But it was the simplest way to allow me to implement this - which as you say is a ton faster than trying to parse the whole map looking for objects.

Giving the language some richer features is on my list - but not really very near the top...

Cheers

Pip

Posted: Tue Jul 12, 2011 11:18 pm
by Merr
pipfromslitherine wrote:Yeah - it's not a great pattern for the scripting language as is, so you do end up with somewhat inelegant code. But it was the simplest way to allow me to implement this - which as you say is a ton faster than trying to parse the whole map looking for objects.

Giving the language some richer features is on my list - but not really very near the top...

Cheers

Pip

Ok .... Good news/Bad news .... :)

Bad News ... If I use your script with "i" replacing the "index" parameter it only removes one object, sometimes two, but not all the objects.

Good News ... I changed your script slightly ...
- The "index" parameter must be a hard value of 0.
- I ran a loop through the ID's instead of running it through i.

This script below works beutifully!! It's fast and no delay!
And this is what I was looking for, and I can use this in my Random B.O.C., thanks to you!
I don't know why running a loop through the "index" didn't work. It appears that index is always a value of 0?

Note ... I'm using the "tree_blocking" as my test object (so I can see it!).

Code: Select all

	if ( side == 0)
	{
		for(id=0;id<999999;id++) 
		{ 
			id = GetObjectFromName("test", "tree_blocking", 0) ;
			
			if(id == -1) 
			{ 
				id = 999999 ; // end the loop 
			} 
			else 
			{ 
				SetObjectPosition(id, 0, 0) ;
				DeleteObject(id) ;
			} 
		}
		AddVizFunctionCall("HideEffectMarker", -9000) ;
	}

Posted: Wed Jul 13, 2011 12:55 am
by pipfromslitherine
Hmmm - let me check the code. The reason your one is working is that you are finding the 1st object, deleting it, and then the next object becomes the first one :).

Thanks for letting me know - it could well be a bug.

Cheers

Pip

Posted: Wed Jul 13, 2011 1:09 am
by Merr
pipfromslitherine wrote:Hmmm - let me check the code. The reason your one is working is that you are finding the 1st object, deleting it, and then the next object becomes the first one :).

Thanks for letting me know - it could well be a bug.

Cheers

Pip
ok cool ....Also, I just realized my over usage of the "id" ... As you can see, it works but it's a dumb script ...
So, I went back to using "i" in the loop.

Now I understand what's going on, like you said ... So, by running a loop I'm checking if the object exists, then deleting it, then checking again, and so forth until there are no longer any object types, then ending the loop.

I'm going to post my little Smoke Mod in the scenario section.
Here's the ammended script ... I don't expect more than 998 smoke objects on the map!

Code: Select all

	if ( side == 0)
	{
		for(i=0;i<999;i++) 
		{ 
			id = GetObjectFromName("merr_objects", "SMOKE_ALLIED", 0) ;
			
			if(id == -1) 
			{ 
				i = 999 ; // end the loop 
			} 
			else 
			{ 
				SetObjectPosition(id, 0, 0) ;
				DeleteObject(id) ;
			} 
		}
		AddVizFunctionCall("HideEffectMarker", -9000) ;
	}

Posted: Wed Jul 13, 2011 1:43 am
by pipfromslitherine
Heh - we got there in the end for sure! So it's working as intended, you were just skipping some objects.

Glad we got it sorted. Had a confused moment looking at the code, because it all seemed fine :).

Cheers

Pip

Posted: Wed Jul 13, 2011 2:31 am
by Merr
Pip,

Thanks again for taking a moment of your time to sort this out! .... I know you're busy playing with fruit (Apples) and I hope that someday you'll get that out the door so you can get back to looking at more cool stuff to add to BA.

Oh ... When you get a moment, I did have trouble with this function ... GetTileObject(x, y, index) ... so, it's probably related. I thought that the index parameter dealt with the object data that can be set for an object, but it wasn't the case.

Anyway, I need to draw an "action_smoke" button before I can post the mod .... :roll: I hate drawing stuff.

Posted: Wed Jul 13, 2011 2:57 am
by junk2drive
Anyway, I need to draw an "action_smoke" button before I can post the mod .... I hate drawing stuff.
Why don't you ask somebody?

Posted: Wed Jul 13, 2011 3:34 am
by Merr
junk2drive wrote: Why don't you ask somebody?
It's faster if I make a quick ugly one ... If anyone can make a better or logical one they can just replace the DDS.

Ok .... I'm done .... It should be ready to go in the scenario thread as soon as I upload the zip and the screenshot and type up quick explaination.

Posted: Wed Jul 13, 2011 3:40 am
by junk2drive
Sounds like I'm too late but what about the flame thrower fire button modified?

Posted: Wed Jul 13, 2011 4:46 am
by Merr
junk2drive wrote:Sounds like I'm too late but what about the flame thrower fire button modified?
I saw that, but I just did the bombard action and made it with a white background.

Just something quick and clear ... If it was for my personal use I wouldn't even bother ...

I'd be just as happy with using the "Emoticons" for buttons !

:D ... Morale is 100%
:) ... Morale is above 50%
:( ... Morale is below 50%
:o ... Unit spotted!
:shock: ... "Halo Tiger!"
:oops: ... Unit retreating.

Posted: Wed Jul 13, 2011 3:15 pm
by pipfromslitherine
That made me laugh at 9am. Which is a feat!

Cheers

Pip

Posted: Thu Jan 26, 2012 2:55 pm
by pk867
I have not tried any modding, but have ideas.

Why is it we can not have just grenades, anti personnel and smoke? I guess that is what the TNT represents?

So we know that during the animations that the attacks use grenades. can we have them as a separate object.

Attacks can be rifles and grenades, but what about grenades only? It should not give away your position and used to soften up the target

or cause retreats. So if we have a new option or command when clicking on a target hex either a spotted unit or question mark, we can throw grenades, suppression fire, or perform a full attack.

To lay smoke in an adjacent tile we would need a new target icon to appear on the map (ie suggestion an 's') which would allow INF or Tanks to attack the hex with smoke. So smoke would last about turns, your turn who laid the smoke and the opponents turn. Vehicular smoke could last longer.

This would set up an unknown location for the opposing player to suppress or reduce movement of the opponent.

Why remove the object when it would basically self repair into the previous terrain state where LOS / no LOS is restored?

INF would have a range of 1 whereas vehicles could be greater

These are my 2 cents and have no idea if this could be done simply .