• Print

Author Topic: UCause v1.0  (Read 13891 times)

0 Members and 1 Guest are viewing this topic.

Offline Megiddo

  • Ulysses Team Member
  • Hero Member
  • *****
  • Posts: 6214
  • Karma: 394
  • Project Lead
UCause v1.0
« on: September 12, 2006, 10:19:04 pm »
Code: Lua
  1. --[[
  2. UCause v1.0
  3. by Brett "Megiddo" Smith
  4. Part of the Spirit of UGM collection.
  5.  
  6. This script will let you chain events between entities in creative ways.
  7. For example, you could chain a health change in a player to ignite a wooden bench,
  8. and when the bench breaks, triggers a bowling ball to fall on a vehicle,
  9. causing the vehicle to start and take off, hitting a trigger to turn player one purple.
  10.  
  11. Requirements:
  12. This script requires ULib version 1.1 or higher. You can download ULib from ulyssesmod.net
  13.  
  14. Usage:
  15. Let's say you want a crate to ignite when you pickup a bathtub with the physcannon.
  16. Type 'ucause_start' in console or say '!ucause_start',
  17. pick the 'causer' (the bathtub) by looking at it and pressing fire (mouse button),
  18. pick the effected (the crate) by looking at it and pressing fire,
  19. pick the cause (OnPhysGunPickup) from the menu,
  20. pick the effect (Ignite) from the menu,
  21. choose whether you want it to repeat or not (IE, will this only happen once?),
  22. and you're done! Try it out!
  23.  
  24. UGM's cause and effect story:
  25. Cause and effect was implemented around UGM v4.2. Sadly, the usage was complicated
  26. and very few truly understood its full potential. This script aims to rectify that.
  27. While this script may not be understood by someone playing GMod for the first time,
  28. even mild novices should be able to pick up the basics of this script.
  29.  
  30. A warning:
  31. Cause and effect is what spawned ULM, the first GMod "virus". The source engine's
  32. input/output system is POWERFUL. Please be careful!
  33.  
  34. Changelog:
  35. v1.0 *(09/12/06)*
  36.         * Initial version.
  37.        
  38. Known Problems:
  39. The 'OnPlayerUse' cause can't target the activator very well.
  40. ]]
  41.  
  42. --TODO: Player addhealth input and patterns
  43.  
  44. local access = ACCESS_ALL
  45.  
  46. assert( _file.Exists( "lua/ULib/init.lua" ), "CauseAndEffect needs ULib to run!" )
  47. _OpenScript( "ULib/init.lua" )
  48. assert( ULib.ULIB_VERSION >= 1.1, "CauseAndEffect requires ULib version 1.1 or higher to run!" )
  49.  
  50. ioinf = {} -- I/O Information
  51.  
  52. ioinf.prop_physics = {}
  53. ioinf.prop_physics.o = { "OnPlayerUse", "OnBreak", "OnHealthChanged", "OnIgnite", "OnPhysCannonDetach", "OnMotionEnabled",
  54.                 "OnAwakened", "OnPhysGunPickup", "OnPhysGunDrop", "OnUser1", "OnUser2", "OnUser3", "OnUser4", }
  55. ioinf.prop_physics.i = { "Break", "SetHealth", "AddHealth", "RemoveHealth", "Ignite", "Kill", "Alpha", "Color", "Sleep",
  56.                 "Wake", "EnableMotion", "DisableMotion", "EnablePhyscannonPickup", "DisablePhyscannonPickup",
  57.                 "DisableFloating", "physdamagescale", "EnableDamageForces", "DisableDamageForces", "DisableShadow",
  58.                 "EnableShadow", "FireUser1", "FireUser2", "FireUser3", "FireUser4", }
  59.                
  60. ioinf.prop_ragdoll = ioinf.prop_physics -- Exactly the same
  61.  
  62. ioinf.prop_vehicle_airboat = {}
  63. ioinf.prop_vehicle_airboat.o = { "PlayerOn", "PlayerOff", "PressedAttack", "PressedAttack2", "AttackAxis", "Attack2Axis",
  64.                 "OnIgnite", "OnUser1", "OnUser2", "OnUser3", "OnUser4", }
  65. ioinf.prop_vehicle_airboat.i = { "EnableGun", "ExitVehicle", "Lock", "Unlock", "TurnOn", "TurnOff", "Throttle", "Steer",
  66.                 "HandBrakeOn", "HandBrakeOff", "Ignite", "Kill", "Alpha", "Color", "EnableShadow", "DisableShadow",
  67.                 "FireUser1", "FireUser2", "FireUser3", "FireUser4", }
  68.                
  69. ioinf.prop_vehicle_jeep = {}
  70. ioinf.prop_vehicle_jeep.o = { "PlayerOn", "PlayerOff", "PressedAttack", "PressedAttack2", "AttackAxis", "Attack2Axis",
  71.                 "OnIgnite", "OnUser1", "OnUser2", "OnUser3", "OnUser4", }
  72. ioinf.prop_vehicle_jeep.i = { "StartRemoveTauCannon", "FinishRemoveTauCannon", "Lock", "Unlock", "TurnOn", "TurnOff",
  73.                 "Throttle", "Steer", "HandBrakeOn", "HandBrakeOff", "Ignite", "Kill", "Alpha", "Color", "EnableShadow",
  74.                 "DisableShadow", "FireUser1", "FireUser2", "FireUser3", "FireUser4", }
  75.  
  76. ioinf.player = {}
  77. ioinf.player.o = { "OnIgnite", "OnUser1", "OnUser2", "OnUser3", "OnUser4", }
  78. ioinf.player.i = { "IgnoreFallDamage", "SetHealth", "physdamagescale", "Ignite", "Alpha", "Color", "EnableShadow",
  79.                 "DisableShadow", "FireUser1", "FireUser2", "FireUser3", "FireUser4", }
  80.                
  81. ioinf.phys_thruster = {}
  82. ioinf.phys_thruster.o = { "OnUser1", "OnUser2", "OnUser3", "OnUser4", }
  83. ioinf.phys_thruster.i = { "Activate", "Deactivate", "scale", "Kill", "Alpha", "Color", "EnableShadow",  "DisableShadow",
  84.                 "FireUser1", "FireUser2", "FireUser3", "FireUser4", }
  85.  
  86.  
  87.                
  88. iospec = {} -- Special IO inputs
  89.  
  90. iospec.SetHealth = { 0, 1, 5, 10, 25, 50, 100, 500, 1000, 99999 }
  91. iospec.AddHealth = iospec.SetHealth
  92. iospec.RemoveHealth = iospec.SetHealth
  93. iospec.Color = { "red", "blue", "green", "clear", "black", "tan", "grey", "brown", "purple", "pink", "teal", "orange", "hotpink", "gold", "yellow" }
  94. iospec.Alpha = { 0, 50, 100, 128, 150, 200, 250, 255 }
  95. iospec.Throttle = { 0, 0.25, 0.5, 0.75, 1, 5, 10, 100 }
  96. iospec.Steer = { "Right", "Left" }
  97.  
  98. local users = {} -- This will hold some user information
  99.  
  100. local function chooseRepeat( userid, id, time, text )
  101.         if id == ULib.ID_EXIT then
  102.                 users[ userid ] = nil
  103.                 return
  104.         end
  105.  
  106.         users[ userid ].menu = nil
  107.         users[ userid ].stage = 7
  108.         users[ userid ].rep = id
  109.  
  110.         local t = users[ userid ]
  111.         ULib.applyColorToEnt( t.causer, "white" )
  112.         ULib.applyColorToEnt( t.effected, "white" )
  113.         ULib.addOutput( t.causer, t.cause, t.effected, t.effect, t.param, 0, t.rep )
  114.         if t.effect == "Break" then
  115.                 ULib.addOutput( t.causer, t.cause, t.effected, "kill", t.param, 0.01, t.rep ) -- This removes the shell
  116.         end
  117.         if t.effect == "Alpha" then
  118.                 _EntFire( t.effected, "addoutput", "rendermode 1", 0 ) -- Allows it to change alpha
  119.         end
  120.         --ULib.debugFunctionCall( "ULib.addOutput", t.causer, t.cause, t.effected, t.effect, t.param, 0, t.rep )
  121.        
  122.         users[ userid ] = nil
  123. end
  124.  
  125. local function chooseEffect( userid, id, time, text )
  126.         if id == ULib.ID_EXIT then
  127.                 ULib.applyColorToEnt( users[ userid ].causer, "white" )
  128.                 ULib.applyColorToEnt( users[ userid ].effected, "white" )
  129.                 users[ userid ] = nil
  130.                 return
  131.         end
  132.  
  133.         if iospec[ text ] and users[ userid ].stage < 5 then -- They have a special step and they haven't done it yet
  134.                 users[ userid ].menu = nil
  135.                 users[ userid ].stage = 5
  136.                 users[ userid ].effect = text
  137.  
  138.                 local menu = ULib.Menu:new( text .. "?", chooseEffect )
  139.                 users[ userid ].menu = menu
  140.                 for _, v in ipairs( iospec[ text ] ) do
  141.                         menu:addOption( tostring( v ) )
  142.                 end
  143.                 menu:showMenu( userid )
  144.                 return -- We need to wait to be processed again
  145.  
  146.         elseif users[ userid ].stage == 5 then -- They just handled the special step
  147.                 users[ userid ].param = text
  148.                 if users[ userid ].effect == "Color" then
  149.                         users[ userid ].param = "\"" .. ULib.getColorString( users[ userid ].param ) .. "\""
  150.                 end
  151.  
  152.                 if users[ userid ].effect == "Steer" then
  153.                         if users[ userid ].param == "Right" then
  154.                                 users[ userid ].param = 1
  155.                         else
  156.                                 users[ userid ].param = -1
  157.                         end
  158.                 end
  159.  
  160.         else -- No special step
  161.                 users[ userid ].menu = nil
  162.                 users[ userid ].effect = text
  163.         end
  164.        
  165.         users[ userid ].stage = 6
  166.  
  167.         local menu = ULib.Menu:new( "Repeat?", chooseRepeat )
  168.         users[ userid ].menu = menu
  169.         menu:addOption( "Yes", 999 )
  170.         menu:addOption( "No", 1 )
  171.         menu:showMenu( userid )
  172. end
  173.  
  174.  
  175. local function chooseCause( userid, id, time, text )
  176.         if id == ULib.ID_EXIT then
  177.                 ULib.applyColorToEnt( users[ userid ].causer, "white" )
  178.                 ULib.applyColorToEnt( users[ userid ].effected, "white" )
  179.                 users[ userid ] = nil
  180.                 return
  181.         end
  182.  
  183.         users[ userid ].menu = nil
  184.         users[ userid ].stage = 4
  185.         users[ userid ].cause = text
  186.  
  187.         local effectedt
  188.         if users[ userid ].effected ~= "!activator" then
  189.                 local effectedtype = _EntGetType( users[ userid ].effected )
  190.                 effectedt = ioinf[ effectedtype ].i
  191.         else
  192.                 effectedt = ioinf[ "player" ].i -- We'll just assume the activator's going to be a player
  193.         end
  194.        
  195.         if users[ userid ].cause == "OnPlayerUse" then
  196.                 if users[ userid ].effected == "!activator" then
  197.                         users[ userid ].effected = "!player" -- HACK: For some reason, OnPlayerUse does not agree with !activator but will work with !player.
  198.                 end
  199.                 _EntFire( users[ userid ].causer, "addoutput", "spawnflags 256", 0 ) -- If we don't do this, it won't call the output on use.
  200.         end
  201.  
  202.         local menu = ULib.Menu:new( "Effect?", chooseEffect )
  203.         users[ userid ].menu = menu
  204.         for _, v in ipairs( effectedt ) do
  205.                 menu:addOption( v )
  206.         end
  207.         menu:showMenu( userid )
  208. end
  209.  
  210. local function chooseEffected( userid, in_key )
  211.         if in_key ~= IN_ATTACK and in_key ~= IN_ATTACK2 then return end -- Not listening for this
  212.         if not users[ userid ] then return end -- ERROR!
  213.         UnHookEvent( users[ userid ].hookpress )
  214.         HaltTimer( users[ userid ].reminder )
  215.         users[ userid ].hookpress = nil
  216.         users[ userid ].reminder = nil
  217.         users[ userid ].stage = 3
  218.        
  219.         local entid
  220.         if in_key == IN_ATTACK then
  221.                 PlayerLookTrace( userid, 4096 )
  222.                 entid = _TraceGetEnt()
  223.                 if entid <= 0 then
  224.                         ULib.tsay( userid, "[IO] Error! Invalid or no ent chosen!" )
  225.        
  226.                         -- Previous Step
  227.                         users[ userid ].hookpress = HookEvent( "eventKeyPressed", chooseEffected )
  228.                         users[ userid ].reminder = AddTimer( 10, 0, ULib.csay, userid, "[IO] Point your gun at the effected ent and press fire. Use 'ucause_end' to cancel." )
  229.                         ULib.csay( userid, "[IO] Point your gun at the effected ent and press fire.\nPress secondary fire for the activator (ent causing output) to be the effected." )
  230.                         _PlayerSelectWeapon( userid, "weapon_physgun" ) -- Don't want to kill the ent
  231.                         users[ userid ].stage = 2
  232.                         return -- Will call this again
  233.                 end
  234.         else -- They chose activator
  235.                 entid = "!activator"
  236.         end
  237.         users[ userid ].effected = entid
  238.        
  239.         ULib.applyColorToEnt( entid, "red" )
  240.  
  241.         local causertype = _EntGetType( users[ userid ].causer )
  242.         local causert = ioinf[ causertype ].o
  243.  
  244.         local menu = ULib.Menu:new( "Fire on?", chooseCause )
  245.         users[ userid ].menu = menu
  246.         for _, v in ipairs( causert ) do
  247.                 menu:addOption( v )
  248.         end
  249.         menu:showMenu( userid )
  250. end
  251.  
  252. local function chooseCauser( userid, in_key )
  253.         if in_key ~= IN_ATTACK then return end -- Not listening for this
  254.         if not users[ userid ] then return end -- ERROR!
  255.         UnHookEvent( users[ userid ].hookpress )
  256.         HaltTimer( users[ userid ].reminder )
  257.         users[ userid ].hookpress = nil
  258.         users[ userid ].reminder = nil
  259.         users[ userid ].stage = 2
  260.        
  261.         PlayerLookTrace( userid, 4096 )
  262.         local entid = _TraceGetEnt()
  263.         if entid <= 0 then
  264.                 ULib.tsay( userid, "[IO] Error! Invalid or no ent chosen!" )
  265.                
  266.                 -- Previous Step
  267.                 users[ userid ].hookpress = HookEvent( "eventKeyPressed", chooseCauser )
  268.                 users[ userid ].reminder = AddTimer( 10, 0, ULib.csay, userid, "[IO] Point your gun at the 'causer' ent and press fire. Use 'ucause_end' to cancel." )
  269.                 ULib.csay( userid, "[IO] Point your gun at the 'causer' ent and press fire." )
  270.                 _PlayerSelectWeapon( userid, "weapon_physgun" ) -- Don't want to kill the ent
  271.                 users[ userid ].stage = 1
  272.                 return -- Will call this again
  273.         end
  274.         users[ userid ].causer = entid
  275.  
  276.         ULib.applyColorToEnt( entid, "black" )
  277.        
  278.         users[ userid ].hookpress = HookEvent( "eventKeyPressed", chooseEffected )
  279.         users[ userid ].reminder = AddTimer( 10, 0, ULib.csay, userid, "[IO] Point your gun at the effected ent and press fire. Use 'ucause_end' to cancel." )
  280.         ULib.csay( userid, "[IO] Point your gun at the effected ent and press fire.\nPress secondary fire for the activator (ent causing output) to be the effected." )
  281.         _PlayerSelectWeapon( userid, "weapon_physgun" ) -- Don't want to kill the ent
  282. end
  283.  
  284. local function cc_ucause_end( userid, args )
  285.         local stage = users[ userid ].stage
  286.  
  287.         if stage >= 2 then
  288.                 ULib.applyColorToEnt( users[ userid ].causer, "white" )
  289.         end
  290.        
  291.         if stage >= 3 then
  292.                 ULib.applyColorToEnt( users[ userid ].effected, "white" )
  293.         end
  294.        
  295.         if stage < 3 then
  296.                 UnHookEvent( users[ userid ].hookpress )
  297.                 HaltTimer( users[ userid ].reminder )
  298.         end
  299.        
  300.         users[ userid ] = nil
  301. end
  302. ULib.CONCOMMAND( "ucause_end", cc_ucause_end, "", access )
  303.  
  304. local function cc_ucause_start( userid, args )
  305.         if users[ userid ] then cc_ucause_end( userid ) end -- Clear crap
  306.  
  307.         users[ userid ] = {}
  308.         users[ userid ].stage = 1
  309.         users[ userid ].hookpress = HookEvent( "eventKeyPressed", chooseCauser )
  310.         users[ userid ].reminder = AddTimer( 10, 0, ULib.csay, userid, "[IO] Point your gun at the 'causer' ent and press fire. Use 'ucause_end' to cancel." )
  311.         ULib.csay( userid, "[IO] Point your gun at the 'causer' ent and press fire." )
  312.         _PlayerSelectWeapon( userid, "weapon_physgun" ) -- Don't want to kill the ent
  313. end
  314. ULib.CONCOMMAND( "ucause_start", cc_ucause_start, "", access )

UCause v1.0
by Brett "Megiddo" Smith
Part of the Spirit of UGM collection.

This script will let you chain events between entities in creative ways.
For example, you could chain a health change in a player to ignite a wooden bench,
and when the bench breaks, triggers a bowling ball to fall on a vehicle,
causing the vehicle to start and take off, hitting a trigger to turn player one purple.

Requirements:
This script requires ULib version 1.1 or higher. You can download ULib from ulyssesmod.net

Usage:
Let's say you want a crate to ignite when you pickup a bathtub with the physcannon.
Type 'ucause_start' in console or say '!ucause_start',
pick the 'causer' (the bathtub) by looking at it and pressing fire (mouse button),
pick the effected (the crate) by looking at it and pressing fire,
pick the cause (OnPhysGunPickup) from the menu,
pick the effect (Ignite) from the menu,
choose whether you want it to repeat or not (IE, will this only happen once?),
and you're done! Try it out!

UGM's cause and effect story:
Cause and effect was implemented around UGM v4.2. Sadly, the usage was complicated
and very few truly understood its full potential. This script aims to rectify that.
While this script may not be understood by someone playing GMod for the first time,
even mild novices should be able to pick up the basics of this script.

Download from: http://ulyssesmod.net/archive/UCause-v1_0.zip
« Last Edit: September 12, 2006, 10:22:47 pm by Megiddo »
Experiencing God's grace one day at a time.

Offline Terminal58

  • Newbie
  • *
  • Posts: 41
  • Karma: 1
Re: UCause v1.0
« Reply #1 on: September 14, 2006, 12:59:33 pm »
Rube goldberg >_>

Offline JamminR

  • Ulysses Team Member
  • Hero Member
  • *****
  • Posts: 8096
  • Karma: 390
  • Sertafide Ulysses Jenius
    • Team Ulysses [ULib/ULX, other fine releases]
Re: UCause v1.0
« Reply #2 on: September 14, 2006, 03:31:13 pm »
Rube! Absolutely.
I've been testing this for about a week before he released it, and haven't even touched the surface of all that it can do.
I guess part of my challenge is that I don't know what all the inputs/outputs mean/do.

Megiddo, if possible, in version 1.1+, I think you should write in an 'add' health option. Or did you already and I just don't remember.
What about suit energy? Is that there?
Geez, long work week, I don't remember parts of it now.

*goes off to his favorite server to play with it some more)
"Though a program be but three lines long, someday it will have to be maintained." -- The Tao of Programming

  • Print