Advertisement
Guest User

RTA8

a guest
Feb 19th, 2019
125
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 9.36 KB | None | 0 0
  1. @name Recursive Total Armor 8
  2. @model models/bull/gates/processor.mdl
  3. @inputs [Console]:wirelink
  4. @outputs [Effective_Armor Total_Armor Total_Contraption_Mass Total_Impact_Mass]:number
  5. @persist [EffString TotString Critical]:string
  6. @persist [VoidThreshold MaxDepth GetMass CCount Count InitialAng Idx]:number
  7. @persist [Criticals]:table [Ar]:array
  8. @persist [LastEntity]:entity
  9.  
  10. #[ New/different things:
  11.     Runs faster
  12.     Respect visclip, like ACF
  13.     Displays CURRENT armor values, not maximum (full HP) values
  14.     Can handle any number of props when counting mass
  15.     Vars up top to make it easier to modify
  16.     Updated critical entities list
  17.     Comments, so you can learn
  18.    
  19.     Slightly different color holos so people notice it's different. Marketing, son
  20. ]#
  21.  
  22. if ( first() | duped() ) {
  23.    MaxDepth      = 30 # Most props we'll dig through
  24.     VoidThreshold = 50 # Amount of empty space we'll travel through before stopping
  25.    
  26.     Criticals = table( # Entity types that'll stop the trace
  27.         "acf_ammo"                   = "Ammo",
  28.         "acf_gun"                    = "Gun",
  29.         "acf_ammo"                   = "Ammunition",
  30.         "acf_engine"                 = "Engine",
  31.         "acf_gearbox"                = "Transmission",
  32.         "acf_gun"                    = "Weapon",
  33.         "prop_vehicle_prisoner_pod"  = "Pod",
  34.         "gmod_wire_expression2"      = "E2",
  35.         "gmod_wire_egp"              = "EGP Screen",
  36.         "gmod_wire_egp_hud"          = "EGP Hud",
  37.         "gmod_wire_egp_emitter"      = "EGP Emitter",
  38.         "gmod_wire_adv_pod"          = "Pod Controller",
  39.         "gmod_wire_pod"              = "Pod Controller",
  40.         "gmod_wire_cameracontroller" = "Camera",
  41.         "gmod_wire_adv_hudindicator" = "Adv HUD",
  42.         "gmod_wire_emarker"          = "Ent Marker",
  43.         "gmod_wire_latch"            = "Weld Latch",
  44.         "gmod_cameraprop"            = "Camera",
  45.         "expadv_gate"                = "EA2 Gate",
  46.         "expadv_screen"              = "EA2 Screen"
  47.     )
  48.    
  49.     holoCreate(1)
  50.         holoColor(1,vec(0, 255, 0))
  51.         holoScaleUnits(1, vec())
  52.     holoCreate(2)
  53.         holoScaleUnits(2, vec(3))
  54.         holoModel(2, "plane")
  55.     holoCreate(3)
  56.         holoColor(3, vec(0, 255, 100))
  57.         holoScaleUnits(3, vec(40, 0.25, 0.25))
  58.     holoCreate(4)
  59.         holoScaleUnits(4, vec(3))
  60.         holoModel(4, "plane")
  61.  
  62.     for( I = 1, 4 ) { holoDisableShading(I, 1), holoParent(I, entity()) }
  63.    
  64.     function ranger acfTrace(From:vector, To:vector) { # Emulating what ACF does, so we respect visclips just like ACF
  65.         local R = rangerOffset(From, To)
  66.  
  67.         if ( R:hit() & R:entity():acfHitClip(R:pos()) ) { rangerFilter(R:entity()), return acfTrace(From, To) }
  68.        
  69.         return R
  70.     }
  71.    
  72.     function void drawScreen() {
  73.         Console:writeCell(2041,1) # Reset
  74.        
  75.         Console:writeString("Total Contraption Mass",2,0,vec(255))
  76.             Console:writeString(round(Total_Contraption_Mass, 1)+" kg ("+CCount+" Ents)", 4, 1, vec(0, 255, 0))
  77.         Console:writeString("Total Impact Entity Mass",2,2,vec(255))
  78.             Console:writeString(round(Total_Impact_Mass,1)+" kg ("+Count+" Layers)",4,3,vec(0,255,0))
  79.         Console:writeString("Impact Angle",2,4,vec(255) )
  80.             Console:writeString(round(InitialAng,3):toString()+" deg",4,5,vec(0,255,0))
  81.         Console:writeString("Total Nominal Armor",2,6, vec(255))
  82.             Console:writeString(round(Total_Armor,3)+" mm",4,7,vec(0,255,0))
  83.             Console:writeString(TotString,4,8,vec(0,255,0))
  84.         Console:writeString("Total Effective Armor",2,9,vec(255))
  85.             Console:writeString(round(Effective_Armor,3)+" mm",4,10,vec(0,255,0))
  86.             Console:writeString(EffString,4,11,vec(0,255,0))
  87.         Console:writeString("Increased Effectiveness",2,12,vec(255))
  88.             Console:writeString(round(((Effective_Armor/Total_Armor)*100)-100,3):toString()+" %",4,13,vec(0,255,0))
  89.         Console:writeString("Critical Entity Hit",2,14,vec(255))
  90.         Console:writeString(Critical,4,15,vec(0,255,0))
  91.     }
  92. }
  93.    
  94. if ( GetMass ) { # Counting up our total mass over several cycles so we dont crash the e2
  95.     while ( perf(50) & Idx < CCount ) {
  96.         Total_Contraption_Mass += Ar[Idx, entity]:mass()
  97.         Idx++
  98.     }
  99.    
  100.     if ( Idx >= CCount ) { drawScreen(), GetMass = 0 }
  101.    
  102.     interval(15)  
  103. }
  104. else {
  105.     R = ranger(450)
  106.    
  107.     if ( changed(R:pos()) ) { # E2 was moved or ranger hit something, and it's been at least 250ms
  108.         if ( R:hit() ) { # Moving doesn't mean we're hitting something
  109.             if ( R:entity() ) {
  110.                 Ent = R:entity()
  111.                
  112.                 if ( Ent:isPlayer() ) { rangerFilter(Ent) } # We don't measure players
  113.                 elseif ( Ent:owner() == owner() ) { # Hit a prop that we own
  114.                     Origin  = entity():pos()
  115.                     Forward = entity():up()
  116.                     End     = Origin + Forward * 450
  117.                    
  118.                     R = acfTrace(Origin, End) # Trace again to see if ACF will still hit something
  119.                     if ( R:entity():owner() == owner() ) { # ACF will see an entity
  120.                         Ent = R:entity()
  121.                        
  122.                         Count = 1
  123.                         Normal = R:hitNormal()
  124.                         InitialAng = acos(Normal:dot(-Forward)) # Impact angle
  125.                         Bounce = Forward - 2 * (Normal:dot(Forward) * Normal) # Actual bounce ang depends on projectile velocity, this is the highest it could bounce from the surface
  126.                        
  127.                         Total_Impact_Mass = Ent:mass()
  128.                         Total_Armor       = Ent:acfPropArmor()
  129.                         Effective_Armor   = Total_Armor / clamp(abs(Normal:dot(-Forward)), 0, 1) # Effective Armor = Nominal Armor / cos(Angle)
  130.                        
  131.                        
  132.                         TotString = "("+round(Total_Armor)
  133.                         EffString = "("+round(Effective_Armor)
  134.                        
  135.                         holoPos(2, R:pos() + R:hitNormal()*0.1)
  136.                             holoAng(2, Normal:toAngle() + ang(90, 0, 0))
  137.                         holoPos(3, R:pos()+ Bounce*20)
  138.                             holoAng(3, Bounce:toAngle())                  
  139.                        
  140.                         if ( LastEntity != Ent ) { # Only count contraption mass whenever we hit a new entity
  141.                             LastEntity = Ent
  142.                             GetMass = Idx = 1
  143.                                
  144.                             Ar = Ent:getConstraints() # Constraint array to count contraption mass
  145.                             CCount = Ar:count()+1
  146.                             Total_Contraption_Mass = Total_Impact_Mass
  147.                         }
  148.                        
  149.                        
  150.                         rangerFilter(Ent) # Don't want to hit the same entity
  151.                         Origin = R:pos() # Setting up for next cycle
  152.                         End    = Origin + Forward * VoidThreshold
  153.                        
  154.                         for ( I = 1, MaxDepth ) {
  155.                             R = acfTrace(Origin, End)
  156.                                 Ent = R:entity()
  157.                                
  158.                             if ( Ent:type() != "prop_physics" ) { # Stopping if we hit non-props
  159.                                 Critical = Criticals[Ent:type(), string] ?: "None"
  160.                                 End = Origin
  161.                                
  162.                                 TotString += ")"
  163.                                 EffString += ")"
  164.                                
  165.                                 break
  166.                             }
  167.                            
  168.                             Count++
  169.                            
  170.                             Armor = Ent:acfPropArmor()
  171.                             Total_Armor += Armor
  172.                             Total_Impact_Mass += Ent:mass()
  173.                             Effective = Armor / clamp(abs(R:hitNormal():dot(-Forward)), 0, 1)
  174.                             Effective_Armor += Effective
  175.                            
  176.                             TotString += "+"+round(Armor)
  177.                             EffString += "+"+round(Effective)
  178.                            
  179.                            
  180.                             rangerFilter(Ent) # Don't want to hit the same entity
  181.                             Origin = R:pos() # Setting up for next cycle
  182.                             End    = Origin + Forward * VoidThreshold
  183.                         }
  184.    
  185.                         drawScreen()
  186.                        
  187.                         Dist = entity():toLocal(End)[3]
  188.                         holoPos(1, entity():toWorld(vec(0, 0, Dist/2)))
  189.                             holoScaleUnits(1,vec(0.25, 0.25, Dist))
  190.                         holoColor(2, mix(vec(255, 0, 0), vec(0, 255, 0), clamp(Effective_Armor, 1, 1000)/1000))
  191.    
  192.                            
  193.                         rangerReset()
  194.                             rangerFilter(players())
  195.                             rangerFilter(entity())
  196.                     }
  197.                 }
  198.             }
  199.         }
  200.         else { Console:writeCell(2041, 1), Console:writeString("No target", 10, 9, vec(255, 0, 0)) } # Air
  201.     }
  202.    
  203.     interval(250)
  204. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement