Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- @name Recursive Total Armor 8
- @model models/bull/gates/processor.mdl
- @inputs [Console]:wirelink
- @outputs [Effective_Armor Total_Armor Total_Contraption_Mass Total_Impact_Mass]:number
- @persist [EffString TotString Critical]:string
- @persist [VoidThreshold MaxDepth GetMass CCount Count InitialAng Idx]:number
- @persist [Criticals]:table [Ar]:array
- @persist [LastEntity]:entity
- #[ New/different things:
- Runs faster
- Respect visclip, like ACF
- Displays CURRENT armor values, not maximum (full HP) values
- Can handle any number of props when counting mass
- Vars up top to make it easier to modify
- Updated critical entities list
- Comments, so you can learn
- Slightly different color holos so people notice it's different. Marketing, son
- ]#
- if ( first() | duped() ) {
- MaxDepth = 30 # Most props we'll dig through
- VoidThreshold = 50 # Amount of empty space we'll travel through before stopping
- Criticals = table( # Entity types that'll stop the trace
- "acf_ammo" = "Ammo",
- "acf_gun" = "Gun",
- "acf_ammo" = "Ammunition",
- "acf_engine" = "Engine",
- "acf_gearbox" = "Transmission",
- "acf_gun" = "Weapon",
- "prop_vehicle_prisoner_pod" = "Pod",
- "gmod_wire_expression2" = "E2",
- "gmod_wire_egp" = "EGP Screen",
- "gmod_wire_egp_hud" = "EGP Hud",
- "gmod_wire_egp_emitter" = "EGP Emitter",
- "gmod_wire_adv_pod" = "Pod Controller",
- "gmod_wire_pod" = "Pod Controller",
- "gmod_wire_cameracontroller" = "Camera",
- "gmod_wire_adv_hudindicator" = "Adv HUD",
- "gmod_wire_emarker" = "Ent Marker",
- "gmod_wire_latch" = "Weld Latch",
- "gmod_cameraprop" = "Camera",
- "expadv_gate" = "EA2 Gate",
- "expadv_screen" = "EA2 Screen"
- )
- holoCreate(1)
- holoColor(1,vec(0, 255, 0))
- holoScaleUnits(1, vec())
- holoCreate(2)
- holoScaleUnits(2, vec(3))
- holoModel(2, "plane")
- holoCreate(3)
- holoColor(3, vec(0, 255, 100))
- holoScaleUnits(3, vec(40, 0.25, 0.25))
- holoCreate(4)
- holoScaleUnits(4, vec(3))
- holoModel(4, "plane")
- for( I = 1, 4 ) { holoDisableShading(I, 1), holoParent(I, entity()) }
- function ranger acfTrace(From:vector, To:vector) { # Emulating what ACF does, so we respect visclips just like ACF
- local R = rangerOffset(From, To)
- if ( R:hit() & R:entity():acfHitClip(R:pos()) ) { rangerFilter(R:entity()), return acfTrace(From, To) }
- return R
- }
- function void drawScreen() {
- Console:writeCell(2041,1) # Reset
- Console:writeString("Total Contraption Mass",2,0,vec(255))
- Console:writeString(round(Total_Contraption_Mass, 1)+" kg ("+CCount+" Ents)", 4, 1, vec(0, 255, 0))
- Console:writeString("Total Impact Entity Mass",2,2,vec(255))
- Console:writeString(round(Total_Impact_Mass,1)+" kg ("+Count+" Layers)",4,3,vec(0,255,0))
- Console:writeString("Impact Angle",2,4,vec(255) )
- Console:writeString(round(InitialAng,3):toString()+" deg",4,5,vec(0,255,0))
- Console:writeString("Total Nominal Armor",2,6, vec(255))
- Console:writeString(round(Total_Armor,3)+" mm",4,7,vec(0,255,0))
- Console:writeString(TotString,4,8,vec(0,255,0))
- Console:writeString("Total Effective Armor",2,9,vec(255))
- Console:writeString(round(Effective_Armor,3)+" mm",4,10,vec(0,255,0))
- Console:writeString(EffString,4,11,vec(0,255,0))
- Console:writeString("Increased Effectiveness",2,12,vec(255))
- Console:writeString(round(((Effective_Armor/Total_Armor)*100)-100,3):toString()+" %",4,13,vec(0,255,0))
- Console:writeString("Critical Entity Hit",2,14,vec(255))
- Console:writeString(Critical,4,15,vec(0,255,0))
- }
- }
- if ( GetMass ) { # Counting up our total mass over several cycles so we dont crash the e2
- while ( perf(50) & Idx < CCount ) {
- Total_Contraption_Mass += Ar[Idx, entity]:mass()
- Idx++
- }
- if ( Idx >= CCount ) { drawScreen(), GetMass = 0 }
- interval(15)
- }
- else {
- R = ranger(450)
- if ( changed(R:pos()) ) { # E2 was moved or ranger hit something, and it's been at least 250ms
- if ( R:hit() ) { # Moving doesn't mean we're hitting something
- if ( R:entity() ) {
- Ent = R:entity()
- if ( Ent:isPlayer() ) { rangerFilter(Ent) } # We don't measure players
- elseif ( Ent:owner() == owner() ) { # Hit a prop that we own
- Origin = entity():pos()
- Forward = entity():up()
- End = Origin + Forward * 450
- R = acfTrace(Origin, End) # Trace again to see if ACF will still hit something
- if ( R:entity():owner() == owner() ) { # ACF will see an entity
- Ent = R:entity()
- Count = 1
- Normal = R:hitNormal()
- InitialAng = acos(Normal:dot(-Forward)) # Impact angle
- Bounce = Forward - 2 * (Normal:dot(Forward) * Normal) # Actual bounce ang depends on projectile velocity, this is the highest it could bounce from the surface
- Total_Impact_Mass = Ent:mass()
- Total_Armor = Ent:acfPropArmor()
- Effective_Armor = Total_Armor / clamp(abs(Normal:dot(-Forward)), 0, 1) # Effective Armor = Nominal Armor / cos(Angle)
- TotString = "("+round(Total_Armor)
- EffString = "("+round(Effective_Armor)
- holoPos(2, R:pos() + R:hitNormal()*0.1)
- holoAng(2, Normal:toAngle() + ang(90, 0, 0))
- holoPos(3, R:pos()+ Bounce*20)
- holoAng(3, Bounce:toAngle())
- if ( LastEntity != Ent ) { # Only count contraption mass whenever we hit a new entity
- LastEntity = Ent
- GetMass = Idx = 1
- Ar = Ent:getConstraints() # Constraint array to count contraption mass
- CCount = Ar:count()+1
- Total_Contraption_Mass = Total_Impact_Mass
- }
- rangerFilter(Ent) # Don't want to hit the same entity
- Origin = R:pos() # Setting up for next cycle
- End = Origin + Forward * VoidThreshold
- for ( I = 1, MaxDepth ) {
- R = acfTrace(Origin, End)
- Ent = R:entity()
- if ( Ent:type() != "prop_physics" ) { # Stopping if we hit non-props
- Critical = Criticals[Ent:type(), string] ?: "None"
- End = Origin
- TotString += ")"
- EffString += ")"
- break
- }
- Count++
- Armor = Ent:acfPropArmor()
- Total_Armor += Armor
- Total_Impact_Mass += Ent:mass()
- Effective = Armor / clamp(abs(R:hitNormal():dot(-Forward)), 0, 1)
- Effective_Armor += Effective
- TotString += "+"+round(Armor)
- EffString += "+"+round(Effective)
- rangerFilter(Ent) # Don't want to hit the same entity
- Origin = R:pos() # Setting up for next cycle
- End = Origin + Forward * VoidThreshold
- }
- drawScreen()
- Dist = entity():toLocal(End)[3]
- holoPos(1, entity():toWorld(vec(0, 0, Dist/2)))
- holoScaleUnits(1,vec(0.25, 0.25, Dist))
- holoColor(2, mix(vec(255, 0, 0), vec(0, 255, 0), clamp(Effective_Armor, 1, 1000)/1000))
- rangerReset()
- rangerFilter(players())
- rangerFilter(entity())
- }
- }
- }
- }
- else { Console:writeCell(2041, 1), Console:writeString("No target", 10, 9, vec(255, 0, 0)) } # Air
- }
- interval(250)
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement