From 47951ea6a639203899a175e42b22d131791cad9a Mon Sep 17 00:00:00 2001 From: uniboi Date: Fri, 30 Dec 2022 21:54:52 +0100 Subject: [PATCH 1/2] initial commit --- README.md | 27 +--- mod.json | 40 +++--- mod/scripts/vscripts/example.nut | 3 - mod/scripts/vscripts/holoSprays.nut | 181 +++++++++++++++++++++++++++ mod/scripts/vscripts/playerPings.nut | 114 +++++++++++++++++ 5 files changed, 320 insertions(+), 45 deletions(-) delete mode 100644 mod/scripts/vscripts/example.nut create mode 100644 mod/scripts/vscripts/holoSprays.nut create mode 100644 mod/scripts/vscripts/playerPings.nut diff --git a/README.md b/README.md index 1b43a5e..c2347b7 100644 --- a/README.md +++ b/README.md @@ -1,26 +1 @@ -# NSModTemplate -A template repository for Northstar mods with a ~~mostly~~ pre-configured github action for publishing to Thunderstore - -## Usage -
    -
  1. Click the Use this template button on the top right of the repo's landing page (here)
  2. -
  3. Give the new repo a name and make sure it's set to public
  4. -
  5. In the settings tab, under actions -> general, set Actions permissions to Allow all actions and reusable workflows - -
  6. -
  7. Also in settings, under secrets -> actions, add your Thunderstore token as a secret named TS_KEY (Steps for getting a token can be found here) - - -
    -
  8. -
  9. Edit .github/workflows/publish.yml ~line 43 to add a description for your mod - -
    -
  10. - -
  11. Update this README and icon.png as they will be used by Thunderstore as well
  12. -
  13. Write your mod! (HINT: Find the docs here)
  14. -
  15. Before pushing large files (100mb or larger), run concat_assets.sh and commit the archives instead. Your archives will be automatically concatted and extracted when creating a github release so the mod is downloadable from thunderstore without any extra steps
  16. -
- - +#idk \ No newline at end of file diff --git a/mod.json b/mod.json index 8a9e103..5c90bb1 100644 --- a/mod.json +++ b/mod.json @@ -1,17 +1,25 @@ { - "Name": "Example.Mod", - "Description": "A cool mod that does cool stuff", - "Version": "1.0.0", - "DownloadLink": "https://northstar.thunderstore.io/package/download/Example/Mod/", - - "LoadPriority": 0, - "ConVars": [], - "Scripts": [{ - "Path": "example.nut", - "RunOn": "(CLIENT || SERVER) && MP" - "ClientCallback": { - "Before":"example_callback" - } - }], - "Localisation": [] -} + "Name": "Odd.Holosprays", + "Description": "A cool mod that does cool stuff", + "Version": "1.0.0", + "DownloadLink": "https://northstar.thunderstore.io/package/download/Example/Mod/", + "LoadPriority": 0, + "ConVars": [], + "Scripts": [ + { + "Path": "holosprays.nut", + "RunOn": "SERVER", + "ServerCallback": { + "Before": "InitHoloSpray" + } + }, + { + "Path": "playerPings.nut", + "RunOn": "SERVER", + "ServerCallback": { + "Before": "InitPlayerPings" + } + } + ], + "Localisation": [] +} \ No newline at end of file diff --git a/mod/scripts/vscripts/example.nut b/mod/scripts/vscripts/example.nut deleted file mode 100644 index 570a40a..0000000 --- a/mod/scripts/vscripts/example.nut +++ /dev/null @@ -1,3 +0,0 @@ -void function example_callback() { - print( "HEY YOU SHOULD CHANGE THIS" ) -} diff --git a/mod/scripts/vscripts/holoSprays.nut b/mod/scripts/vscripts/holoSprays.nut new file mode 100644 index 0000000..5b6cd54 --- /dev/null +++ b/mod/scripts/vscripts/holoSprays.nut @@ -0,0 +1,181 @@ +global function InitHoloSpray +global function CreateSprite +global function TraceFromEnt +struct SprayInfo { + asset material + float scale + string color + vector offset // extra position offset from the base +} + +SprayInfo function _SprayInfo( asset material, float scale = 0.75, string color = "200 200 200", vector offset = <0,0,30> ) +{ + PrecacheSprite( material ) + SprayInfo s + s.material = material + s.scale = scale + s.color = color + s.offset = offset + return s +} + + +table< entity, array > holoSpraysOfPlayer +array sprayInfos + +void function InitHoloSpray() +{ + sprayInfos = [ + _SprayInfo( $"materials/ui/scoreboard_mcorp_logo.vmt", 0.5, "200 200 200", <0,0,60> ) + _SprayInfo( $"materials/ui/scoreboard_imc_logo.vmt", 0.5, "200 200 200", <0,0,60> ) + ] + // RegisterSignal( "SprayDestroyed" ) + AddCallback_OnClientConnected(OnPlayerConnected) + AddCallback_OnClientDisconnected(OnPlayerDisconnected) +} + +void function OnPlayerConnected( entity player ) +{ + AddButtonPressedPlayerInputCallback( player, IN_USE, OnUseHoloSpray ) + holoSpraysOfPlayer[player] <- [] + thread void function() : ( player ){ + wait RandomFloatRange( 0.0, 0.5 ) + NSSendInfoMessageToPlayer( player, "You can use HOLOSPRAYS on this server, simply press %%use%% to throw yours" ) + }() + +} + +void function OnPlayerDisconnected( entity player ) +{ + foreach( entity spray in holoSpraysOfPlayer[ player ] ) + { + if(!IsValid(spray)) + continue + // spray.Signal( "SprayDestroyed" ) + spray.Destroy() + } + delete holoSpraysOfPlayer[ player ] +} + + +void function OnUseHoloSpray( entity player ) +{ + array sprays = holoSpraysOfPlayer[ player ] + if(sprays.len() >= 5) //spam is not cool + { + // sprays[0].Signal( "SprayDestroyed" ) // destroy corresponding sprites + sprays[0].Destroy() // destroy the base + holoSpraysOfPlayer[player] = sprays.slice(1) // remove the reference + } + + const float force = 500.0 // initial force of the base pad + vector origin = player.EyePosition() - <0,0,20> + entity base = CreatePropPhysics( $"models/gameplay/health_pickup_small.mdl", origin, <0,0,0> ) + base.kv.solid = 0 + base.Hide() + base.SetOwner( player ) + + entity vis = CreatePropDynamic( $"models/weapons/sentry_shield/sentry_shield_proj.mdl", origin, <0,0,0> ) + vis.SetParent( base ) + vis.kv.scale = string( 0.1 ) + + thread SpawnHoloSprite( base, vis ) + + holoSpraysOfPlayer[player].append( base ) + base.SetVelocity( ( player.GetViewVector() ) * force ) +} + +void function SpawnHoloSprite( entity base, entity vis ) +{ + // EndSignal( base, "SprayDestroyed" ) + base.EndSignal( "OnDestroy" ) + entity sprite + entity light + WaitFrame() + + while( IsValid( base ) ) + { + vector endPos = base.GetOrigin() + <0,0, -2000> + TraceResults hit = OriginToFirst( base ) + if( Length( base.GetOrigin() - hit.endPos ) <= 10 ) //is object close to the floor + { + //make sure the object doesnt roll + base.SetVelocity( <0,0,0> ) + //adjust angles to surface, <-90,0,0> is needed because we went the medkit to lie down flat + // base.SetAngles( < -90,0,0 > + AnglesOnSurface( hit.surfaceNormal, AnglesToForward( base.GetAngles() ) ) ) + base.SetAngles( < -0,0,0 > + AnglesOnSurface( hit.surfaceNormal, AnglesToForward( base.GetAngles() ) ) ) + + entity mover = CreateExpensiveScriptMover( base.GetOrigin(), base.GetAngles() ) + base.SetParent( mover ) + mover.NonPhysicsMoveTo( hit.endPos + <0,0,5.5>, 0.3, 0.0, 0.0 ) + + base.SetParent( hit.hitEnt ) + + //make sure the object doesnt rotate too much + base.StopPhysics() + + SprayInfo info = sprayInfos.getrandom() + sprite = CreateSprite( vis.GetCenter() + info.offset, <0,0,0>, info.material, "200 200 200", info.scale ) + sprite.SetParent( base ) + light = CreateSprite( vis.GetCenter() + <0,0,6.5>, <0,0,0>, $"sprites/glow_05.vmt", "200 200 200", 0.75 ) + light.SetParent( base ) + + // printt( OriginToFirst( vis ).endPos ) + // base.GetOwner().SetOrigin( OriginToFirst( vis ).endPos + <0,0,100> ) + // vis.SetOrigin( < 0,0,0 > ) + break + } + WaitFrame() + } +} + +// Trace straight down from the provided origin until the trace hits the world, a mover or a Titan (Titans break idk) +TraceResults function OriginToFirst( entity base ) +{ + entity lastHit + TraceResults traceResult + array ignore = [ base ] + vector origin = base.GetOrigin() + do + { + vector endOrigin = origin + <0,0, -2000> + traceResult = TraceLine( origin, endOrigin, ignore, TRACE_MASK_NPCWORLDSTATIC, TRACE_COLLISION_GROUP_NONE ) + lastHit = traceResult.hitEnt + if(!IsValid(lastHit)) + continue + ignore.append( traceResult.hitEnt ) + } while( IsValid( lastHit ) && !lastHit.IsWorld() && !lastHit.IsTitan() && !(lastHit.GetClassName() == "worldspawn") && !(lastHit instanceof CNPC_Titan) && !(lastHit.GetClassName() == "script_mover") ) + return traceResult +} + +// Create a 2D sprite at position +entity function CreateSprite( vector origin, vector angles, asset sprite, string lightcolor = "255 0 0", float scale = 0.5, int rendermode = 9 ) +{ + // attach a light so we can see it + entity env_sprite = CreateEntity( "env_sprite" ) + env_sprite.SetScriptName( UniqueString( "molotov_sprite" ) ) + env_sprite.kv.rendermode = rendermode //these do NOT follow any pattern, trial an error is your friend, as you dont have any others anyway (they go from like 1 to 10 or sth, I hontely dont know) + env_sprite.kv.origin = origin + env_sprite.kv.angles = angles + env_sprite.kv.rendercolor = lightcolor + env_sprite.kv.renderamt = 255 + env_sprite.kv.framerate = "10.0" + env_sprite.SetValueForModelKey( sprite ) + env_sprite.kv.scale = string( scale ) + env_sprite.kv.spawnflags = 1 + env_sprite.kv.GlowProxySize = 16.0 + env_sprite.kv.HDRColorScale = 1.0 + DispatchSpawn( env_sprite ) + EntFireByHandle( env_sprite, "ShowSprite", "", 0, null, null ) + + return env_sprite +} + +// Trace to the point an entity looks at +TraceResults function TraceFromEnt( entity p ) +{ + TraceResults traceResults = TraceLineHighDetail( p.EyePosition(), + p.EyePosition() + p.GetViewVector() * 10000, + p, TRACE_MASK_SHOT, TRACE_COLLISION_GROUP_NONE ) + return traceResults +} diff --git a/mod/scripts/vscripts/playerPings.nut b/mod/scripts/vscripts/playerPings.nut new file mode 100644 index 0000000..ac5de0b --- /dev/null +++ b/mod/scripts/vscripts/playerPings.nut @@ -0,0 +1,114 @@ +global function InitPlayerPings + +struct Ping { + entity sprite + float time +} + +table< entity, array > playerPings +const PING_DURATION = 15.0 + +void function InitPlayerPings() +{ + PrecacheSprite($"materials/ui/hud/attacker_offscreen.vmt") + PrecacheSprite($"materials/vgui/hud/weapons/target_ring_arc_tool_inner.vmt") + RegisterSignal( "PingDestroyed" ) + + AddCallback_OnClientConnected(OnPlayerConnected) + AddCallback_OnClientDisconnected(OnPlayerDisconnected) +} + +void function OnPlayerConnected( entity player ) +{ + AddButtonPressedPlayerInputCallback( player, IN_DUCKTOGGLE, OnUsePing ) + playerPings[ player ] <- [] +} + +void function OnPlayerDisconnected( entity player ) +{ + //avoid a crash by removing their pings + delete playerPings[player] +} + +string function GenerateRGBValueByIndex( int index ) +{ + //if somehow the player was not found in the array of his team it doesnt crash + if( index == -1 ) + return "100 100 100" + + int[3] RGBValue + + //rotates the columns around for each index + int changeRGBindex = index % 3 + + int potentialNewColour = RGBValue[ changeRGBindex ] + index * 50 + RGBValue[ changeRGBindex ] = potentialNewColour > 255 ? potentialNewColour % 255 : potentialNewColour + + //following column of the first one LOL + changeRGBindex = (index+1) % 3 + RGBValue[ changeRGBindex ] = 200 // fix value for RGB that constantly roates infront of the changine value + + return format( "%i %i %i", RGBValue[0], RGBValue[1], RGBValue[2] ) +} + + +void function OnUsePing( entity player ) +{ + thread SpawnPing( player ) +} + +bool function isEnemyPing( entity player, vector newPing ) +{ + foreach( Ping p in playerPings[ player ] ) + { + if( Time() - p.time <= 1.0 && LengthSqr( p.sprite.GetOrigin() - newPing ) <= 2000.0 ) + { + Signal( p, "PingDestroyed" ) + p.sprite.Destroy() + playerPings[ player ].fastremovebyvalue( p ) + return true + } + } + return false +} + +void function SpawnPing( entity player ) +{ + //all pings for a player so far + array pings = playerPings[player] + if(pings.len() >= 5) //spam is not cool + { + Signal( pings[0], "PingDestroyed" ) + if( IsValid( pings[0].sprite ) ) + pings[0].sprite.Destroy() + playerPings[player] = pings.slice(1) + } + + TraceResults trace = TraceFromEnt( player ) + bool enemyPing = isEnemyPing( player, trace.endPos ) + entity sprite = CreateSprite( trace.endPos, <0,0,0>, enemyPing ? $"materials/ui/hud/attacker_offscreen.vmt" : $"materials/vgui/hud/weapons/target_ring_arc_tool_inner.vmt", enemyPing ? "255 0 0" : GenerateRGBValueByIndex( GetPlayerArrayOfTeam( player.GetTeam( ) ).find(player) ), enemyPing ? 0.6 :0.3 , 5 ) // 5 + SetTeam( sprite, player.GetTeam() ) + //set it so only you can your team can see them + sprite.kv.VisibilityFlags = ENTITY_VISIBLE_TO_FRIENDLY | ENTITY_VISIBLE_TO_OWNER + // + sprite.SetOwner( player ) + //makes the ping attach to the object that moves + sprite.SetParent( trace.hitEnt ) + //track the time a ping was send + Ping p + p.sprite = sprite + p.time = Time() + playerPings[player].append( p ) + + //ping gets detroyed after a set time + thread DestroyPingDelayed( p, PING_DURATION ) +} + +void function DestroyPingDelayed( Ping p, float duration ) +{ + EndSignal( p, "PingDestroyed" ) + wait duration + if( IsValid( p.sprite ) ) + p.sprite.Destroy() + playerPings[ p.sprite.GetOwner() ].slice( 1 ) +} \ No newline at end of file From 9d30f3733b3d39faf9496068aa9c1af39fccaafa Mon Sep 17 00:00:00 2001 From: uniboi Date: Fri, 30 Dec 2022 21:57:06 +0100 Subject: [PATCH 2/2] Revert "initial commit" This reverts commit 47951ea6a639203899a175e42b22d131791cad9a. --- README.md | 27 +++- mod.json | 40 +++--- mod/scripts/vscripts/example.nut | 3 + mod/scripts/vscripts/holoSprays.nut | 181 --------------------------- mod/scripts/vscripts/playerPings.nut | 114 ----------------- 5 files changed, 45 insertions(+), 320 deletions(-) create mode 100644 mod/scripts/vscripts/example.nut delete mode 100644 mod/scripts/vscripts/holoSprays.nut delete mode 100644 mod/scripts/vscripts/playerPings.nut diff --git a/README.md b/README.md index c2347b7..1b43a5e 100644 --- a/README.md +++ b/README.md @@ -1 +1,26 @@ -#idk \ No newline at end of file +# NSModTemplate +A template repository for Northstar mods with a ~~mostly~~ pre-configured github action for publishing to Thunderstore + +## Usage +
    +
  1. Click the Use this template button on the top right of the repo's landing page (here)
  2. +
  3. Give the new repo a name and make sure it's set to public
  4. +
  5. In the settings tab, under actions -> general, set Actions permissions to Allow all actions and reusable workflows + +
  6. +
  7. Also in settings, under secrets -> actions, add your Thunderstore token as a secret named TS_KEY (Steps for getting a token can be found here) + + +
    +
  8. +
  9. Edit .github/workflows/publish.yml ~line 43 to add a description for your mod + +
    +
  10. + +
  11. Update this README and icon.png as they will be used by Thunderstore as well
  12. +
  13. Write your mod! (HINT: Find the docs here)
  14. +
  15. Before pushing large files (100mb or larger), run concat_assets.sh and commit the archives instead. Your archives will be automatically concatted and extracted when creating a github release so the mod is downloadable from thunderstore without any extra steps
  16. +
+ + diff --git a/mod.json b/mod.json index 5c90bb1..8a9e103 100644 --- a/mod.json +++ b/mod.json @@ -1,25 +1,17 @@ { - "Name": "Odd.Holosprays", - "Description": "A cool mod that does cool stuff", - "Version": "1.0.0", - "DownloadLink": "https://northstar.thunderstore.io/package/download/Example/Mod/", - "LoadPriority": 0, - "ConVars": [], - "Scripts": [ - { - "Path": "holosprays.nut", - "RunOn": "SERVER", - "ServerCallback": { - "Before": "InitHoloSpray" - } - }, - { - "Path": "playerPings.nut", - "RunOn": "SERVER", - "ServerCallback": { - "Before": "InitPlayerPings" - } - } - ], - "Localisation": [] -} \ No newline at end of file + "Name": "Example.Mod", + "Description": "A cool mod that does cool stuff", + "Version": "1.0.0", + "DownloadLink": "https://northstar.thunderstore.io/package/download/Example/Mod/", + + "LoadPriority": 0, + "ConVars": [], + "Scripts": [{ + "Path": "example.nut", + "RunOn": "(CLIENT || SERVER) && MP" + "ClientCallback": { + "Before":"example_callback" + } + }], + "Localisation": [] +} diff --git a/mod/scripts/vscripts/example.nut b/mod/scripts/vscripts/example.nut new file mode 100644 index 0000000..570a40a --- /dev/null +++ b/mod/scripts/vscripts/example.nut @@ -0,0 +1,3 @@ +void function example_callback() { + print( "HEY YOU SHOULD CHANGE THIS" ) +} diff --git a/mod/scripts/vscripts/holoSprays.nut b/mod/scripts/vscripts/holoSprays.nut deleted file mode 100644 index 5b6cd54..0000000 --- a/mod/scripts/vscripts/holoSprays.nut +++ /dev/null @@ -1,181 +0,0 @@ -global function InitHoloSpray -global function CreateSprite -global function TraceFromEnt -struct SprayInfo { - asset material - float scale - string color - vector offset // extra position offset from the base -} - -SprayInfo function _SprayInfo( asset material, float scale = 0.75, string color = "200 200 200", vector offset = <0,0,30> ) -{ - PrecacheSprite( material ) - SprayInfo s - s.material = material - s.scale = scale - s.color = color - s.offset = offset - return s -} - - -table< entity, array > holoSpraysOfPlayer -array sprayInfos - -void function InitHoloSpray() -{ - sprayInfos = [ - _SprayInfo( $"materials/ui/scoreboard_mcorp_logo.vmt", 0.5, "200 200 200", <0,0,60> ) - _SprayInfo( $"materials/ui/scoreboard_imc_logo.vmt", 0.5, "200 200 200", <0,0,60> ) - ] - // RegisterSignal( "SprayDestroyed" ) - AddCallback_OnClientConnected(OnPlayerConnected) - AddCallback_OnClientDisconnected(OnPlayerDisconnected) -} - -void function OnPlayerConnected( entity player ) -{ - AddButtonPressedPlayerInputCallback( player, IN_USE, OnUseHoloSpray ) - holoSpraysOfPlayer[player] <- [] - thread void function() : ( player ){ - wait RandomFloatRange( 0.0, 0.5 ) - NSSendInfoMessageToPlayer( player, "You can use HOLOSPRAYS on this server, simply press %%use%% to throw yours" ) - }() - -} - -void function OnPlayerDisconnected( entity player ) -{ - foreach( entity spray in holoSpraysOfPlayer[ player ] ) - { - if(!IsValid(spray)) - continue - // spray.Signal( "SprayDestroyed" ) - spray.Destroy() - } - delete holoSpraysOfPlayer[ player ] -} - - -void function OnUseHoloSpray( entity player ) -{ - array sprays = holoSpraysOfPlayer[ player ] - if(sprays.len() >= 5) //spam is not cool - { - // sprays[0].Signal( "SprayDestroyed" ) // destroy corresponding sprites - sprays[0].Destroy() // destroy the base - holoSpraysOfPlayer[player] = sprays.slice(1) // remove the reference - } - - const float force = 500.0 // initial force of the base pad - vector origin = player.EyePosition() - <0,0,20> - entity base = CreatePropPhysics( $"models/gameplay/health_pickup_small.mdl", origin, <0,0,0> ) - base.kv.solid = 0 - base.Hide() - base.SetOwner( player ) - - entity vis = CreatePropDynamic( $"models/weapons/sentry_shield/sentry_shield_proj.mdl", origin, <0,0,0> ) - vis.SetParent( base ) - vis.kv.scale = string( 0.1 ) - - thread SpawnHoloSprite( base, vis ) - - holoSpraysOfPlayer[player].append( base ) - base.SetVelocity( ( player.GetViewVector() ) * force ) -} - -void function SpawnHoloSprite( entity base, entity vis ) -{ - // EndSignal( base, "SprayDestroyed" ) - base.EndSignal( "OnDestroy" ) - entity sprite - entity light - WaitFrame() - - while( IsValid( base ) ) - { - vector endPos = base.GetOrigin() + <0,0, -2000> - TraceResults hit = OriginToFirst( base ) - if( Length( base.GetOrigin() - hit.endPos ) <= 10 ) //is object close to the floor - { - //make sure the object doesnt roll - base.SetVelocity( <0,0,0> ) - //adjust angles to surface, <-90,0,0> is needed because we went the medkit to lie down flat - // base.SetAngles( < -90,0,0 > + AnglesOnSurface( hit.surfaceNormal, AnglesToForward( base.GetAngles() ) ) ) - base.SetAngles( < -0,0,0 > + AnglesOnSurface( hit.surfaceNormal, AnglesToForward( base.GetAngles() ) ) ) - - entity mover = CreateExpensiveScriptMover( base.GetOrigin(), base.GetAngles() ) - base.SetParent( mover ) - mover.NonPhysicsMoveTo( hit.endPos + <0,0,5.5>, 0.3, 0.0, 0.0 ) - - base.SetParent( hit.hitEnt ) - - //make sure the object doesnt rotate too much - base.StopPhysics() - - SprayInfo info = sprayInfos.getrandom() - sprite = CreateSprite( vis.GetCenter() + info.offset, <0,0,0>, info.material, "200 200 200", info.scale ) - sprite.SetParent( base ) - light = CreateSprite( vis.GetCenter() + <0,0,6.5>, <0,0,0>, $"sprites/glow_05.vmt", "200 200 200", 0.75 ) - light.SetParent( base ) - - // printt( OriginToFirst( vis ).endPos ) - // base.GetOwner().SetOrigin( OriginToFirst( vis ).endPos + <0,0,100> ) - // vis.SetOrigin( < 0,0,0 > ) - break - } - WaitFrame() - } -} - -// Trace straight down from the provided origin until the trace hits the world, a mover or a Titan (Titans break idk) -TraceResults function OriginToFirst( entity base ) -{ - entity lastHit - TraceResults traceResult - array ignore = [ base ] - vector origin = base.GetOrigin() - do - { - vector endOrigin = origin + <0,0, -2000> - traceResult = TraceLine( origin, endOrigin, ignore, TRACE_MASK_NPCWORLDSTATIC, TRACE_COLLISION_GROUP_NONE ) - lastHit = traceResult.hitEnt - if(!IsValid(lastHit)) - continue - ignore.append( traceResult.hitEnt ) - } while( IsValid( lastHit ) && !lastHit.IsWorld() && !lastHit.IsTitan() && !(lastHit.GetClassName() == "worldspawn") && !(lastHit instanceof CNPC_Titan) && !(lastHit.GetClassName() == "script_mover") ) - return traceResult -} - -// Create a 2D sprite at position -entity function CreateSprite( vector origin, vector angles, asset sprite, string lightcolor = "255 0 0", float scale = 0.5, int rendermode = 9 ) -{ - // attach a light so we can see it - entity env_sprite = CreateEntity( "env_sprite" ) - env_sprite.SetScriptName( UniqueString( "molotov_sprite" ) ) - env_sprite.kv.rendermode = rendermode //these do NOT follow any pattern, trial an error is your friend, as you dont have any others anyway (they go from like 1 to 10 or sth, I hontely dont know) - env_sprite.kv.origin = origin - env_sprite.kv.angles = angles - env_sprite.kv.rendercolor = lightcolor - env_sprite.kv.renderamt = 255 - env_sprite.kv.framerate = "10.0" - env_sprite.SetValueForModelKey( sprite ) - env_sprite.kv.scale = string( scale ) - env_sprite.kv.spawnflags = 1 - env_sprite.kv.GlowProxySize = 16.0 - env_sprite.kv.HDRColorScale = 1.0 - DispatchSpawn( env_sprite ) - EntFireByHandle( env_sprite, "ShowSprite", "", 0, null, null ) - - return env_sprite -} - -// Trace to the point an entity looks at -TraceResults function TraceFromEnt( entity p ) -{ - TraceResults traceResults = TraceLineHighDetail( p.EyePosition(), - p.EyePosition() + p.GetViewVector() * 10000, - p, TRACE_MASK_SHOT, TRACE_COLLISION_GROUP_NONE ) - return traceResults -} diff --git a/mod/scripts/vscripts/playerPings.nut b/mod/scripts/vscripts/playerPings.nut deleted file mode 100644 index ac5de0b..0000000 --- a/mod/scripts/vscripts/playerPings.nut +++ /dev/null @@ -1,114 +0,0 @@ -global function InitPlayerPings - -struct Ping { - entity sprite - float time -} - -table< entity, array > playerPings -const PING_DURATION = 15.0 - -void function InitPlayerPings() -{ - PrecacheSprite($"materials/ui/hud/attacker_offscreen.vmt") - PrecacheSprite($"materials/vgui/hud/weapons/target_ring_arc_tool_inner.vmt") - RegisterSignal( "PingDestroyed" ) - - AddCallback_OnClientConnected(OnPlayerConnected) - AddCallback_OnClientDisconnected(OnPlayerDisconnected) -} - -void function OnPlayerConnected( entity player ) -{ - AddButtonPressedPlayerInputCallback( player, IN_DUCKTOGGLE, OnUsePing ) - playerPings[ player ] <- [] -} - -void function OnPlayerDisconnected( entity player ) -{ - //avoid a crash by removing their pings - delete playerPings[player] -} - -string function GenerateRGBValueByIndex( int index ) -{ - //if somehow the player was not found in the array of his team it doesnt crash - if( index == -1 ) - return "100 100 100" - - int[3] RGBValue - - //rotates the columns around for each index - int changeRGBindex = index % 3 - - int potentialNewColour = RGBValue[ changeRGBindex ] + index * 50 - RGBValue[ changeRGBindex ] = potentialNewColour > 255 ? potentialNewColour % 255 : potentialNewColour - - //following column of the first one LOL - changeRGBindex = (index+1) % 3 - RGBValue[ changeRGBindex ] = 200 // fix value for RGB that constantly roates infront of the changine value - - return format( "%i %i %i", RGBValue[0], RGBValue[1], RGBValue[2] ) -} - - -void function OnUsePing( entity player ) -{ - thread SpawnPing( player ) -} - -bool function isEnemyPing( entity player, vector newPing ) -{ - foreach( Ping p in playerPings[ player ] ) - { - if( Time() - p.time <= 1.0 && LengthSqr( p.sprite.GetOrigin() - newPing ) <= 2000.0 ) - { - Signal( p, "PingDestroyed" ) - p.sprite.Destroy() - playerPings[ player ].fastremovebyvalue( p ) - return true - } - } - return false -} - -void function SpawnPing( entity player ) -{ - //all pings for a player so far - array pings = playerPings[player] - if(pings.len() >= 5) //spam is not cool - { - Signal( pings[0], "PingDestroyed" ) - if( IsValid( pings[0].sprite ) ) - pings[0].sprite.Destroy() - playerPings[player] = pings.slice(1) - } - - TraceResults trace = TraceFromEnt( player ) - bool enemyPing = isEnemyPing( player, trace.endPos ) - entity sprite = CreateSprite( trace.endPos, <0,0,0>, enemyPing ? $"materials/ui/hud/attacker_offscreen.vmt" : $"materials/vgui/hud/weapons/target_ring_arc_tool_inner.vmt", enemyPing ? "255 0 0" : GenerateRGBValueByIndex( GetPlayerArrayOfTeam( player.GetTeam( ) ).find(player) ), enemyPing ? 0.6 :0.3 , 5 ) // 5 - SetTeam( sprite, player.GetTeam() ) - //set it so only you can your team can see them - sprite.kv.VisibilityFlags = ENTITY_VISIBLE_TO_FRIENDLY | ENTITY_VISIBLE_TO_OWNER - // - sprite.SetOwner( player ) - //makes the ping attach to the object that moves - sprite.SetParent( trace.hitEnt ) - //track the time a ping was send - Ping p - p.sprite = sprite - p.time = Time() - playerPings[player].append( p ) - - //ping gets detroyed after a set time - thread DestroyPingDelayed( p, PING_DURATION ) -} - -void function DestroyPingDelayed( Ping p, float duration ) -{ - EndSignal( p, "PingDestroyed" ) - wait duration - if( IsValid( p.sprite ) ) - p.sprite.Destroy() - playerPings[ p.sprite.GetOwner() ].slice( 1 ) -} \ No newline at end of file