Description: A prop exploder. Hitting 'use' will accumulate your props into one large bunch, and then explode them in a violent manner.
For links to my other creations, head here:
Disclaimer: What you do with this chip is not my business. Appreciate the code for what it is, not what people decide to do with it.
Merry Christmas, everyone!
Sorry, been sick with a cold, but here's what I've got so far. Prop size scaling now works fairly well, but I haven't addressed the bug with the lag (when using more than 20 or so props at a time) yet. I'll drop that fix in after Christmas.
Code:
@name PropSplosion
@inputs
@outputs
@persist Me:entity PropList:array PropPositionList:array SearchFlag PropCount Index ExplosionPosition:vector ExplosionSequenceInitiated NumPropsAtDestination AllPropsAtDestination PropsVibrating Exploding
interval(1)
# ================
# Set up constants
# ================
# These change the rate of prop movement and how quickly they slow when they reach their destination
DeltaSmoother = 5
DeltaMultiplier = 10
# The desired mass of the props being thrown around
# Higher mass generally means they will be flung further away
Mass = 50000
# ====================
# Initialize variables
# ====================
if (first()) {
# Set up the owner variable (convenience)
Me = owner()
# Initialize some variables
# Not required, but is easier to keep track of initial values
PropCount = 0
Index = 0
SearchFlag = 0
ExplosionSequenceInitiated = 0
NumPropsAtDestination = 0
AllPropsAtDestination = 0
PropsVibrating = 0
Exploding = 0
ExplosionComplete = 0
}
# Destroy the chip if it's duped
if (duped()) {
selfDestruct()
}
# ====================
# Timer Flags
# ====================
# Run a search to grab new props, if they are present
if (clk("SearchFlag")) { SearchFlag = 0 }
if (clk("PropsCoagulated")) { AllPropsAtDestination = 1 }
if (clk("Exploding")) {
Exploding = 1
Index = 0
}
# Find all the props to use in this explosion
# We run this continously during the explosion sequence in case we are using
# breakable props (which may have been destroyed during the coagulation phase)
if (!SearchFlag & ExplosionSequenceInitiated) {
SearchFlag = 1
timer("SearchFlag", 500)
findIncludePlayerProps(owner())
findByClass("prop_physics")
findSortByDistance(Me:aimPos()) # No real reason to do this, it just keeps me organized
if(PropCount!=findToArray():count()){
PropList=findToArray()
PropCount=PropList:count() # Again, for convenience
}
}
# ====================
# Activation key
# ====================
if (Me:keyUse() & !ExplosionSequenceInitiated) {
# Set the explosion position and initialize variables
ExplosionPosition = Me:aimPos() + vec(0, 0, 100)
ExplosionSequenceInitiated = 1
NumPropsAtDestination = 0
AllPropsAtDestination = 0
PropsVibrating = 0
Exploding = 0
ExplosionComplete = 0
Index = 0
}
# ============================
# ============================
# Begin the explosion sequence
# ============================
# ============================
# ============================
# If all props have arrived...
# ============================
if (AllPropsAtDestination & !PropsVibrating) {
# Store the current position of each prop
PropPositionList = array()
for(I=0, PropCount - 1, 1) {
PropPositionList:pushVector(PropList:entity(I+1):pos())
}
PropsVibrating = 1
# Set the explosion timer (to be used in a later version of this chip)
timer("Exploding", 1)
}
# ===============================
# Perform movements for the props
# ===============================
if (ExplosionSequenceInitiated) {
# Iterate over each prop while we still have ops left in our quota.
while (opcounter() < maxquota()) {
# Grab the current prop from the prop array, based on index
CurrentProp = PropList:entity(Index + 1)
# Set the mass of the prop
CurrentProp:setMass(Mass)
# Vibrations are to be used in a later version of this chip
VibrationAmount = 0
if (!PropsVibrating) {
AimPos = ExplosionPosition
} else {
VibrationVector = vec(random(-VibrationAmount, VibrationAmount), random(-VibrationAmount, VibrationAmount), random(-VibrationAmount, VibrationAmount))
AimPos = PropPositionList:vector(Index + 1) + 10
AimPos += VibrationVector
}
# If we're currently exploding, set the aim position for each prop relative to its
# position from the explosion's center
if (Exploding) {
AimPos = CurrentProp:pos() - ExplosionPosition + vec(0, 0, CurrentProp:radius())
AimPos = AimPos * 5000000
}
# Calculate the X/Y planar distance
A = (AimPos:x() - CurrentProp:pos():x())
ASquared = A * A
B = (AimPos:y() - CurrentProp:pos():y())
BSquared = B * B
PlaneDistance = sqrt(ASquared + BSquared)
# Check to see if the prop is at the explosion destination
if (PlaneDistance < CurrentProp:radius() * PropCount / 2) {
NumPropsAtDestination += 1
}
# =========================
# Thrust calculations
# =========================
# Calculate the initial thrust vector
Thrust = (AimPos - CurrentProp:pos()) + CurrentProp:massCenterL()
# Add vertical thrust based on planar distance to arc the projectile
Thrust = Thrust + vec(0, 0, PlaneDistance / 5)
# Calculate the thrust delta and apply it to the thrust vector
Delta = CurrentProp:vel() / DeltaSmoother
Thrust = (Thrust - Delta) * DeltaMultiplier
# Apply thrust multiplier based on calculated mass
Multiplier = CurrentProp:mass()/10
if (Multiplier < 1) {
Multiplier = 1
}
Thrust = Thrust * Multiplier
# Apply the final thrust to the chip
CurrentProp:applyForce(Thrust)
# Check to see if all the props have reached their destination
if (NumPropsAtDestination == PropCount & !Exploding) {
timer("PropsCoagulated", 550)
break
}
# Incremend the index number so we start working on the next prop in the array
Index++
if (Index > PropCount) {
# If we're exploding, and we've iterated over each prop, stop this explosion sequence
if (Exploding) {
ExplosionSequenceInitiated = 0
}
NumPropsAtDestination = 0
Index = 0
break
}
}
}
Bookmarks