Advertisement
Guest User

ContourExt.lua

a guest
Jan 26th, 2014
757
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 10.16 KB | None | 0 0
  1. ContourExt = ContourExt or class()
  2.  
  3. local idstr_material = Idstring( "material" )
  4. local idstr_contour_color = Idstring( "contour_color" )
  5. local idstr_contour_opacity = Idstring( "contour_opacity" )
  6.  
  7. ContourExt._types = {
  8.         teammate = {
  9.                 priority = 3,
  10.                 player = true,
  11.                 color = tweak_data.contour.character.standard_color,
  12.                 color_downed = tweak_data.contour.character.downed_color,
  13.                 color_dead = tweak_data.contour.character.dead_color,
  14.                 opacity = 0,
  15.                 fadeout = 6
  16.         },
  17.         friendly = {
  18.                 priority = 1,
  19.                 character = true,
  20.                 color = tweak_data.contour.character.friendly_color
  21.         },
  22.         mark_unit = {
  23.                 priority = 2,
  24.                 color = tweak_data.contour.character.dangerous_color,
  25.                 opacity = 1.5,
  26.                 fadeout = 0.3
  27.         },
  28.         mark_enemy = {
  29.                 priority = 2,
  30.                 character = true,
  31.                 color = tweak_data.contour.character.dangerous_color,
  32.                 color_strength = tweak_data.contour.character.more_dangerous_color,
  33.                 opacity = 1.5,
  34.                 opacity_silent = 4.5,
  35.                 fadeout = 0.3
  36.         },
  37.         highlight = {
  38.                 priority = 3,
  39.                 color = tweak_data.contour.interactable.standard_color
  40.         }
  41. }
  42.  
  43. function ContourExt:init( unit )
  44.         self._unit = unit
  45.         self._materials = nil
  46.        
  47.         self._contour_list = nil
  48.         self._current = nil
  49.        
  50.         self._slotmask_world_geometry = managers.slot:get_mask( "world_geometry" )
  51. end
  52.  
  53. function ContourExt:add( type, marking_strength, time_multiplier )
  54.         local data = self._types[ type ]
  55.         local opacity = data.opacity
  56.        
  57.         if data.opacity_silent and data.character and tweak_data.character[ self._unit:base()._tweak_table ].silent_priority_shout then
  58.                 opacity = data.opacity_silent
  59.         end
  60.        
  61.         if time_multiplier then
  62.                 opacity = opacity * ( time_multiplier or 1 )
  63.         end
  64.        
  65.         self._contour_list = self._contour_list or {}
  66.        
  67.         for _, setup in ipairs( self._contour_list ) do
  68.                 if setup.type == type then
  69.                         setup.marking_strength = marking_strength
  70.                         setup.opacity = opacity
  71.                         setup.target_opacity = opacity and 0
  72.                        
  73.                         return
  74.                 end
  75.         end
  76.        
  77.         table.insert( self._contour_list, { type = type, marking_strength = marking_strength, opacity = opacity, target_opacity = opacity and 0 } )
  78.         self:_change()
  79. end
  80.  
  81. function ContourExt:remove( type )
  82.         for id, setup in ipairs( self._contour_list ) do
  83.                 if setup.type == type then
  84.                         self:_remove( id )
  85.                         return
  86.                 end
  87.         end
  88. end
  89.  
  90. function ContourExt:update_materials()
  91.         if self._materials then
  92.                 self._materials = self._unit:get_objects_by_type( idstr_material )
  93.         end
  94. end
  95.  
  96. function ContourExt:clear()
  97.         self._contour_list = nil
  98.         self._materials = nil
  99. end
  100.  
  101. function ContourExt:_change()
  102.         if not self._contour_list then
  103.                 return
  104.         end
  105.        
  106.         local id, priority
  107.         for key, data in ipairs( self._contour_list ) do
  108.                 if not id or self._types[ data.type ].priority < priority then
  109.                         id = key
  110.                         priority = self._types[ data.type ].priority
  111.                 end
  112.         end
  113.        
  114.         if id == self._current then
  115.                 return
  116.         end
  117.        
  118.         local setup = self._contour_list[ id ]
  119.         local data = self._types[ setup.type ]
  120.        
  121.         if data.character then
  122.                 if not self._current then
  123.                         self._unit:base():swap_material_config()
  124.                         managers.occlusion:remove_occlusion( self._unit )
  125.                         self._unit:base():set_allow_invisible( false )
  126.                 elseif self._unit:base():is_in_original_material() then
  127.                         self._unit:base():swap_material_config()
  128.                 end
  129.         else
  130.                 if not self._current then
  131.                         managers.occlusion:remove_occlusion( self._unit )
  132.                 end
  133.         end
  134.        
  135.         if setup.marking_strength then
  136.                 self._unit:character_damage():on_marked_state( setup.marking_strength )
  137.         end
  138.        
  139.         local color = setup.marking_strength and data.color_strength or data.color
  140.        
  141.         self._materials = self._materials or self._unit:get_objects_by_type( idstr_material )
  142.         for _, material in ipairs( self._materials ) do
  143.                 material:set_variable( idstr_contour_color, color )
  144.                 material:set_variable( idstr_contour_opacity, setup.opacity and 0 or 1 )
  145.         end
  146.        
  147.         self._current = id
  148. end
  149.  
  150. function ContourExt:_remove( id )
  151.         if #self._contour_list == 1 then
  152.                 local setup = self._contour_list[ id ]
  153.                 local data = self._types[ setup.type ]
  154.                
  155.                 managers.occlusion:add_occlusion( self._unit )
  156.                
  157.                 if data.character then
  158.                         self._unit:base():swap_material_config()
  159.                         self._unit:base():set_allow_invisible( true )
  160.                 end
  161.                
  162.                 if setup.marking_strength then
  163.                         self._unit:character_damage():on_marked_state( false )
  164.                 end
  165.                
  166.                 self._current = nil
  167.         end
  168.        
  169.         table.remove( self._contour_list, id )
  170.        
  171.         if #self._contour_list == 0 then
  172.                 self:clear()
  173.         end
  174. end
  175.  
  176. function ContourExt:update( unit, t, dt )
  177.         local id = 1
  178.         while self._contour_list and id <= #self._contour_list do
  179.                 local remove = nil
  180.                 local setup = self._contour_list[ id ]
  181.                 local data = self._types[ setup.type ]
  182.                 local is_current = self._current == id
  183.                
  184.                 if data.player then
  185.                         local cam_pos = managers.viewport:get_current_camera_position()
  186.                         if cam_pos then
  187.                                 local anim_data = unit:anim_data()
  188.                                 local downed = anim_data.bleedout or anim_data.fatal
  189.                                 local dead = anim_data.death
  190.                                 local hands_tied = anim_data.hands_tied
  191.                                
  192.                                 if downed or dead or hands_tied then
  193.                                         setup.target_opacity = 1
  194.                                 else
  195.                                         setup.target_opacity = 0
  196.                                         if mvector3.distance_sq( cam_pos, unit:movement():m_com() ) > 16000000 then
  197.                                                 setup.target_opacity = 0.65
  198.                                         else
  199.                                                 setup.target_opacity = unit:raycast( "ray", unit:movement():m_com(), cam_pos, "slot_mask", self._slotmask_world_geometry, "report" ) and 0.65 or 0
  200.                                         end
  201.                                 end
  202.                                
  203.                                 local color_id = managers.criminals:character_color_id_by_unit( unit )
  204.                                 setup.target_color = ( dead and data.color_dead ) or ( ( hands_tied or downed ) and data.color_downed ) or ( color_id and tweak_data.peer_vector_colors[ color_id ] or data.color )
  205.                         end
  206.                 end
  207.                
  208.                 if setup.color ~= setup.target_color then
  209.                         setup.color = math.step( setup.color or data.color, setup.target_color, data.fadeout * dt )
  210.                        
  211.                         if is_current then
  212.                                 for _, material in ipairs( self._materials ) do
  213.                                         material:set_variable( idstr_contour_color, setup.color )
  214.                                 end
  215.                         end
  216.                 end
  217.                
  218.                 if setup.opacity then
  219.                         if setup.opacity ~= setup.target_opacity then
  220.                                 setup.opacity = math.step( setup.opacity, setup.target_opacity, data.fadeout * dt )
  221.                                
  222.                                 if is_current then
  223.                                         for _, material in ipairs( self._materials ) do
  224.                                                 material:set_variable( idstr_contour_opacity, math.min( 1.5, setup.opacity ) )
  225.                                         end
  226.                                 end
  227.                         end
  228.                        
  229.                         if not data.player and ( setup.opacity == setup.target_opacity ) then
  230.                                 remove = true
  231.                                 if is_current then
  232.                                         self:_change()
  233.                                 end
  234.                         end
  235.                 end
  236.                
  237.                 if ( not remove ) and data.character and unit:character_damage() and unit:character_damage():dead() then
  238.                         remove = true
  239.                 end
  240.                
  241.                 if remove then
  242.                         self:_remove( id )
  243.                 else
  244.                         id = id + 1
  245.                 end
  246.         end
  247. end
  248.  
  249. function ContourExt:save( data )
  250.         if self._contour_list then
  251.                 data.contour_list = deep_clone( self._contour_list )
  252.         end
  253. end
  254.  
  255. function ContourExt:load( data )
  256.         if data.contour_list then
  257.                 self._contour_list = deep_clone( data.contour_list )
  258.                 self:_change()
  259.         end
  260. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement