Jump to content
Official BF Editor Forums
Sign in to follow this  
PiratePlunder

Triggerables On Objects

Recommended Posts

Just checking, before i need to do it tomorrow, can you just template a trigger onto an object like you would template anything else. I remember people talking about attaching triggers to vehicles to prevent non driver kits from using them? Any examples of it being done - does the SF elevator do it?

I know its lazy, but if someone can help off the top of their head then it will free up more time tomorrow - time i really need.

Share this post


Link to post
Share on other sites

Ok, so i added this code to a vehicle...


ObjectTemplate.addTemplate Frigate_Trigger
ObjectTemplate.setPosition -4.2/0.62/-2.1

and then....

ObjectTemplate.create Triggerable Frigate_Trigger
ObjectTemplate.activeSafe Triggerable Frigate_Trigger
ObjectTemplate.modifiedByUser "Martyn Jones"
ObjectTemplate.setNetworkableInfo BasicInfo
ObjectTemplate.isNotSaveable 1
ObjectTemplate.hasMobilePhysics 0
ObjectTemplate.hasCollisionPhysics 1
ObjectTemplate.triggerId 200
rem events are 0=none, 1=use, 2=shoot, 3=move, 4=explosion, 5=cp changed
ObjectTemplate.events 3
ObjectTemplate.minimumTimeBetweenTriggering 0.5
ObjectTemplate.radius 10.0
ObjectTemplate.hasPartner 0

That doesnt do anything, but it doesn't crash either. Looking at the python Im thinking i need to physically convert the above to a trigger radius with something like...

bf2.triggerManager.createRadiusTrigger(obj, onCPTrigger, '<<PCO>>', radius, (1, 2, 3))

However, how can i get hold of a list of all triggers so that i can create the triggerradius - thought something like

for trigObj in bf2.objectManager.getObjectsOfType('dice.hfe.world.ObjectTemplate.Triggerable'):

blar blar blar

might work, but nothing, nor with dice.hfe.world.ObjectTemplate.Trigger

Now i'm compltely stuck.

Just to recap, i want to attach a trigger radius to a vehicle and then handle the event of a player entering that radius in python. I've seen lots of guys mention doing the same thing to prevent non-drivers / pilots from using vehicles but i cant find any example code. Please please help if you can.

Share this post


Link to post
Share on other sites

Ok, a couple more questions now.

1. I really need to add a trigger to each vehicle, the easiest way would be as it spawns using something like onVehicleSpawn. I know its in BF2142, but i tired my luck and tried it in BF2 but it didn't seem to do anything. Does anyone know if this function does work - or more likely not. Is there a simple way to achieve the same thing that avoids repeatedly cycling through all the PCO's or object of a particular type to find new ones?

2. Is there a way to get an objects children... i tried this:

ships= bf2.objectManager.getObjectsOfTemplate('frigate')

for obj in ships:

prnt("Object: " + str ( obj.TemplateName ) )

objChildren = obj.getChildren()

for objChild in objChildren:

prnt("Child: " + str ( objChild.TemplateName ) )

but it just hung.

3. Is there a way to tell if a vehicle that enters a trigger is a player or not. I tired if vehicle.getVehicle() == vehicle.getDefaultVehicle() but that didn't work - i guess it would work if vehicle as a player object, but for triggers its a vehicle object. Is there a method that could use vehicle.rootParent() or do i just need to create an array of all player types or all vehcile types and search for the TemplateName in there?

Share this post


Link to post
Share on other sites

Check this site:

http://bf2tech.org/index.php/Object_Reference

The good guys there gathered a lot of methods . The most interesting for your problem will possibly be

host.omgr_getObjectsOfTemplate(template)

host.omgr_getObjectsOfType(type)

and for the array of children for a given object:

physicalObject.getChildren()

Share this post


Link to post
Share on other sites

OK, so the triggers are working, i'm adding them ok. Now the only (i hope) problem is getting a hook to add the trigger to the frigate when i need to - i.e. almost as soon as its spawned... I had hoped that there would be something like onVehicleSpawn - but there isn't. Bugger. So i set up a timer and and then on the timers function add the triggers with this code.

        frigates = bf2.objectManager.getObjectsOfTemplate('frigate')
       index = len(frigates)
       if index > 0:
               for obj in frigates:
                       objChildren = obj.getChildren()
                       for objChild in objChildren:
                               if str ( objChild.templateName ) == 'frigate_Trigger':
                                       bf2.triggerManager.createHemiSphericalTrigger(objChild, onBFP2Trigger, '<<PCO>>', 9.7, (1, 2, 3))

This works in that it adds a trigger (to a child object (frigate_trigger) of the frigate) first time around, but then it kills the timer. Not sure how or why - i guess when it comes around to add another trigger onto a vehicle with a trigger already attached.

I had tried to add a bool to the obj object when a tirgger was added and check for that before adding a trigger (so it would only try to add a trigger once) but that just killed the function straight away - guess you cant do that to vehicle objects like you can player classes, which makes sense. Trouble is this leaves me banging my head against a wall without a clue what to do.

Share this post


Link to post
Share on other sites

Can your timer go and first destroy all the existing triggers and re-add them back?

Share this post


Link to post
Share on other sites

I don't think you have to check for the existence of the trigger if its only added 'onVehicleSpawn' , which occurs only once during the life of that vehicle. You should kill it on the destruction of the vehicle, though and any timers associated with it.

The timers can be set to either an automatic recurring ( calling a function once it runs out and then restarting by itself ) or to a manual restart once it runs out.

Hope that helps. As idk what you're planning i can't be more specific atm :unsure:

Share this post


Link to post
Share on other sites

The trouble is the onVehicleSpawn doesnt do anything in BF2, infact im not sure that it exists in python at all although there surely must be something internally.

The timer itself is working fine, it repeats every three seconds at the moment, if i get it to output some text then I can see its working ok and it is.

However, once the first frigate is spawned on the map it obviously runs through that code ok becasue the trigger is created, but then the timer stops working (actually thinking about it perhaps it doesnt - cant remember what i was testing, text output before or after that code???). At the very least though its getting stuck the second time it tries to run though that code - maybe when it tries to add a trigger to an object that alreadyt has a trigger attached?

As for what im trying to do - add a ship boarding mechanism so that you can enter a stationary enemy boat (easily) or a slowly moving one (harder). So the processes are:

- add trigger to boats of certain class when it spawns

- when player (not other vehicles) enters trigger, beam up to give access to deck.

Identifying the boat class, adding trigger is ok, trigger postion is great the only problem is getting the triggers to be automatically added as new vehicles are spawned. The second part, beaming the player is all done.

1/2 - i could remove all the triggers each time, but as we need the process to run every few seconds its a last resort - would need to rebuild all the CP triggers as well.

There is another option of storing the object ID and perhaps corresponding Trigger ID in an array and then working with that. But its messier than i would have hoped.

Share this post


Link to post
Share on other sites

Ahh, yeah, you're of course right - there's no onVehicleSpawn event in the whole bunch of events , my bad. Where are those python gurus when you need them , lol

Ok, different approach:

Create a recurring timer on Gamestart and use it to iterate through all objects of the frigate type. Check if a boolean for that frigate exists and is true and skip it if it is. ( lets call it "hasTrigger" ) If the boolean is false or not-existent, attach it to the frigate, set it to 'true' , create the Trigger for the frigate and exit.

Don't forget to kill the timer on endGame.

Share this post


Link to post
Share on other sites

Im very pleased that i think the same way as you msch, unfortunately adding a bool didnt seem to work... i may try it again in a different context and see if adding a bool to a vehicle obj works at all, just in case it was something else causing the problem.

I had tried to add a bool to the obj object when a tirgger was added and check for that before adding a trigger (so it would only try to add a trigger once) but that just killed the function straight away - guess you cant do that to vehicle objects like you can player classes, which makes sense. Trouble is this leaves me banging my head against a wall without a clue what to do.

Share this post


Link to post
Share on other sites

Ok, i was able to test that now and i succeeded in adding a boolean to a vehicle in the same way i do it for soldiers - by adding it on my first iteration run through my objects. For the soldiers it was easier as we always have the 'OnPlayerSpawn' event. For a quick test with vehicles i added it in 'EnterVehicle' and reset it in 'exitVehicle' :

def myEnterVehicle(player, vehicle, freeSoldier = False):
		markVehicle(vehicle)

def myExitVehicle(player, vehicle, freeSoldier = False ):
	unmarkVehicle(vehicle)


#vehicle found guilty
def markVehicle(p):
p.isMarked = True
#vehicle unmark
def unmarkVehicle(p):
p.isMarked = False

Hope that helps

Edited by mschoeldgen[Xww2]

Share this post


Link to post
Share on other sites

Yeah, the trouble is you mustn't test it if it isn't existent. That was my problem, too when i thought about a routine to display the state of the boolean.

It would be cool to first check for the existence of that boolean before evaluating it but i'm afraid we need a python guru to help us out with that one ;)

Share this post


Link to post
Share on other sites
Yeah, the trouble is you mustn't test it if it isn't existent. That was my problem, too when i thought about a routine to display the state of the boolean.

It would be cool to first check for the existence of that boolean before evaluating it but i'm afraid we need a python guru to help us out with that one ;)

instead of

def somefunction(player):
 if player.isMarked:
pass # ... do stuff

you'd do

def somefunction(player):
 if hasattr(player, 'isMarked') and player.isMarked:
pass # ... do stuff

or even

def somefunction(player):
 if player.__dict__.get('isMarked', False):
pass # ... do stuff

Edited by [FH]ctz

Share this post


Link to post
Share on other sites

Awesome, thanks for that CTZ.

So this should work - run on a timer, every 4 seconds?

               #Routine to add triggers to Frigates
               frigates = bf2.objectManager.getObjectsOfTemplate('frigate')
               index = len(frigates)
               if index > 0:
                       for obj in frigates:
                               if hasattr(obj, 'isMarked') and obj.isMarked:
                                       objChildren = obj.getChildren()
                                       for objChild in objChildren:
                                               if str ( objChild.templateName ) == 'frigate_Trigger':
                                                       bf2.triggerManager.createHemiSphericalTrigger(objChild, onBFP2Trigger, '<<PCO>>', 9.7, (1, 2, 3))
                                                       prnt("Trigger Added")
                                                       obj.isMarked = True
                                                       prnt("Frigate Marked")

Share this post


Link to post
Share on other sites

Thanks ctz ! That helps a lot :lol:

I wonder if its possible with this new knowledge to simply ask for the existence of the trigger itself to spare the hassle with the boolean ?

Perhaps its easier then to include the creation of the trigger in the exception routine ( when the hasattr check fails )

The check for a boolean is probably much faster, though. Ow, i think you could add an 'else' section to the above routine with a

frigate.isMarked = False

so you have that boolean attached to the frigate in any case and only need to check if its true or false in the next iteration. If its false, add the trigger.

Edited by mschoeldgen[Xww2]

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
Sign in to follow this  

×
×
  • Create New...