Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # This module enhances the vanilla "area trigger system":
- # 1. Ignoring wounded players.
- # 2. Ignoring vehicles, instead handling the players inside.
- # 3. Works using "Player Objects" rather than "Physical Objects"
- import host
- import bf2
- import realitydebug as rdebug
- # Public method - Call to create a new trigger.
- # Returns a unique ID belonging to the trigger.
- def createTrigger(obj, callback, radius, data, isHemisphere=False):
- # Create vanilla bf2 trigger
- if isHemisphere:
- trigid = bf2.triggerManager.createHemiSphericalTrigger(obj, onTrigger, '<<PCO>>', radius, data)
- else:
- trigid = bf2.triggerManager.createRadiusTrigger(obj, onTrigger, '<<PCO>>', radius, data)
- # Create an object for it (Also adds it to a list)
- trigger(trigid, obj, callback)
- # Return the ID
- return trigid
- # Public method - Destroy a trigger that was created here by its id
- def destroyTrigger(id, trigerPlayersInsideLeave=True):
- if id not in trigger.allTriggers:
- rdebug.debugMessage('Triggers: Cannot destroy unknown trigger %s' % id)
- # Tell callback that players left the destroyed trigger
- if trigerPlayersInsideLeave:
- for p in trigger.allTriggers[id].playersInside:
- fireTrigger(id,p,0)
- # For each player in the game, remove the trig id from his list
- for p in bf2.playerManager.getPlayers():
- p.areaList.discard(id)
- del trigger.allTriggers[id]
- bf2.triggerManager.destroy(id)
- # Public method - Returns a reference of the set of players inside the trigger area.
- # The set is kept up to date at all times.
- def getPlayersInArea(id):
- if id not in trigger.allTriggers:
- rdebug.debugMessage('GetPlayersInArea - Triggers: Unknown trigger %s requested' % id)
- return None
- return trigger.allTriggers[id].playersInside
- def init():
- host.registerHandler('PlayerRevived', onRevive, 1)
- host.registerHandler('PlayerKilled', onWound, 1)
- host.registerHandler('PlayerConnect', onConnect, 1)
- host.registerHandler('PlayerDeath', onDeath, 1)
- ###### PRIVATE METHODS DO NOT CALL FROM OUTSDIDE
- # Initialize the area list set
- # The area list is the list of trigger areas the player's physical object is in.
- def onConnect(playerObject):
- playerObject.areaList = set()
- # On death, Player is nowhere, clear the list.
- def onDeath(playerObject, soldierObject):
- playerObject.areaList.clear()
- # On revive, report that player has entered the areas his physical object is in
- def onRevive(revivedPlayerObject, medicPlayerObject):
- for triggerID in revivedPlayerObject.areaList:
- fireTrigger(triggerID, revivedPlayerObject, 1)
- # On wounded, report that player has left the areas he's in
- def onWound(victimPlayerObject, attackerPlayerObject, weaponObject, assists, victimSoldierObject):
- for triggerID in victimPlayerObject.areaList:
- fireTrigger(triggerID, victimPlayerObject, 0)
- # Called when the vanilla trigger fires, filters it
- def onTrigger(triggerID, triggerObj, vehicleObj, entered):
- # Here's the tricky part: if the vehicle has a parent it should be ignored,
- # the parent will also fire the events and we can get the list of players through occupying players of the parent
- if vehicleObj.getParent():
- return
- for playerObj in vehicleObj.getOccupyingPlayers():
- if entered:
- playerObj.areaList.add(triggerID)
- else:
- playerObj.areaList.discard(triggerID)
- # Only fire events if player is not wounded
- if playerObj.isAlive() and not playerObj.isManDown():
- fireTrigger(triggerID, playerObj, entered)
- # Calls trigger's Callback function
- def fireTrigger(id, Player, Entered):
- if id not in trigger.allTriggers:
- rdebug.debugMessage('fireTrigger: Unknown trigger %s requested' % id)
- return
- trig = trigger.allTriggers[id]
- # If Entered, but player is already inside, don't fire the event (Happens when player changes seats while in radius)
- if Entered:
- if Player in trig.playersInside:
- return
- trig.playersInside.add(Player)
- trig.callback(id, Player, 1)
- # If leaving, but player is not inside, don't fire the event (TODO can this ever happen?)
- else:
- if Player not in trig.playersInside:
- rdebug.debugMessage('player %s left something hes not inside' % Player.getName())
- return
- trig.playersInside.discard(Player)
- trig.callback(id, Player, 0)
- class trigger(object):
- # Static, Dictionary of all the active triggers created by this module by ID
- allTriggers = {}
- def __init__(self, id, triggerobj, callback):
- self.triggerobj = triggerobj
- self.callback = callback
- self.triggerid = id
- self.playersInside = set()
- trigger.allTrigger[id] = self
- # Experiments:
- # Entering empty vehicle while in radius:
- # Vehicle Driver seat Object Enter area
- # Soldier Object leave area
- # Changing from driver seat while in radius:
- # Soldier Object enter area
- # Vehicle new Seat enter area
- # Soldier Object leave area
- # Changing to driver seat while in radius:
- # Soldier Object enter area
- # Vehicle new Seat leave area
- # Soldier Object leave area
- # Leave vehicle (now empty) while in radius:
- # Soldier Enter area
- # Vehicle Leave area
- # Trigger's object is destroyed:
- # No events are called anymore
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement