Smoke Mod ... Pip ?

Modders can post their questions on scripting and more.

Moderators: Slitherine Core, BA Moderators

Post Reply
Merr
Captain - Heavy Cruiser
Captain - Heavy Cruiser
Posts: 903
Joined: Mon Aug 16, 2010 2:00 pm

Smoke Mod ... Pip ?

Post 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) ;
	}
}
pipfromslitherine
Site Admin
Site Admin
Posts: 9937
Joined: Wed Mar 23, 2005 10:35 pm

Post 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
Merr
Captain - Heavy Cruiser
Captain - Heavy Cruiser
Posts: 903
Joined: Mon Aug 16, 2010 2:00 pm

Post 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.
pipfromslitherine
Site Admin
Site Admin
Posts: 9937
Joined: Wed Mar 23, 2005 10:35 pm

Post 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
Merr
Captain - Heavy Cruiser
Captain - Heavy Cruiser
Posts: 903
Joined: Mon Aug 16, 2010 2:00 pm

Post 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 ...
pipfromslitherine
Site Admin
Site Admin
Posts: 9937
Joined: Wed Mar 23, 2005 10:35 pm

Post 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
Merr
Captain - Heavy Cruiser
Captain - Heavy Cruiser
Posts: 903
Joined: Mon Aug 16, 2010 2:00 pm

Post 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) ;
	}
pipfromslitherine
Site Admin
Site Admin
Posts: 9937
Joined: Wed Mar 23, 2005 10:35 pm

Post 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
Merr
Captain - Heavy Cruiser
Captain - Heavy Cruiser
Posts: 903
Joined: Mon Aug 16, 2010 2:00 pm

Post 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) ;
	}
pipfromslitherine
Site Admin
Site Admin
Posts: 9937
Joined: Wed Mar 23, 2005 10:35 pm

Post 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
Merr
Captain - Heavy Cruiser
Captain - Heavy Cruiser
Posts: 903
Joined: Mon Aug 16, 2010 2:00 pm

Post 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.
junk2drive
BA Moderator
BA Moderator
Posts: 1478
Joined: Sun May 23, 2010 4:47 pm
Location: Arizona USA -7GMT

Post 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?
You can call me junk - and type that with one hand.
Merr
Captain - Heavy Cruiser
Captain - Heavy Cruiser
Posts: 903
Joined: Mon Aug 16, 2010 2:00 pm

Post 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.
junk2drive
BA Moderator
BA Moderator
Posts: 1478
Joined: Sun May 23, 2010 4:47 pm
Location: Arizona USA -7GMT

Post by junk2drive »

Sounds like I'm too late but what about the flame thrower fire button modified?
You can call me junk - and type that with one hand.
Merr
Captain - Heavy Cruiser
Captain - Heavy Cruiser
Posts: 903
Joined: Mon Aug 16, 2010 2:00 pm

Post 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.
pipfromslitherine
Site Admin
Site Admin
Posts: 9937
Joined: Wed Mar 23, 2005 10:35 pm

Post by pipfromslitherine »

That made me laugh at 9am. Which is a feat!

Cheers

Pip
pk867
Sr. Colonel - Battleship
Sr. Colonel - Battleship
Posts: 1602
Joined: Fri May 08, 2009 3:18 pm

Post 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 .
Post Reply

Return to “Battle Academy : Modders Corner ”