Compare commits
1 Commits
master
..
buildtools
| Author | SHA1 | Date | |
|---|---|---|---|
| 194b2c6553 |
@@ -1,7 +0,0 @@
|
||||
*.jpg merge=binary -diff
|
||||
*.png merge=bianry -diff
|
||||
*.gif merge=binary -diff
|
||||
*.tiff merge=bianry -diff
|
||||
*.tga merge=binary -diff
|
||||
*.psd merge=binary -diff
|
||||
*.psb merge=binary -diff
|
||||
@@ -1,3 +0,0 @@
|
||||
issuehunt: xaymar
|
||||
patreon: xaymar
|
||||
custom: https://www.paypal.me/xaymar
|
||||
@@ -1,20 +0,0 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Want a new feature implemented?
|
||||
|
||||
---
|
||||
|
||||
<!--- Please fill out the following template, which will help other contributors review your Issue. -->
|
||||
<!--- Make sure you’ve read the contribution guidelines -->
|
||||
|
||||
### Description
|
||||
<!-- Describe the feature (and behavior) in as much detail as possible (yes, that means write an essay if you have to) -->
|
||||
<!-- Include images of what you expect from the feature -->
|
||||
|
||||
### Checklist:
|
||||
<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->
|
||||
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->
|
||||
- [ ] I have read the contribution guidelines.
|
||||
- [ ] This feature is necessary and can't be done through other means.
|
||||
- [ ] This feature does not break existing functionality.
|
||||
- [ ] I am willing to hire/pay someone to implement this.
|
||||
@@ -1,27 +0,0 @@
|
||||
---
|
||||
name: Question/Feedback
|
||||
about: Submit a question or some feedback! (Not for bugs, issues or crashes!)
|
||||
|
||||
---
|
||||
|
||||
<!--- Please fill out the following template, which will help other contributors review your Issue. -->
|
||||
<!--- Make sure you’ve read the contribution guidelines -->
|
||||
|
||||
### Description
|
||||
<!-- Describe the feature (and behavior) in as much detail as possible (yes, that means write an essay if you have to) -->
|
||||
<!-- Include images of what you expect from the feature -->
|
||||
|
||||
### System Information
|
||||
<!-- Include as much information about the system you're using as possible. -->
|
||||
- Software Version: [e. g. 1.0.0, 1.2.1, ... - NEVER LATEST]
|
||||
- Operating System: [e. g. Windows, Debian, Ubuntu, RedHat, FreeBSD, ...]
|
||||
- Kernel Version: [e. g. 1903/1809 (Windows), 4.12 (Linux), ...]
|
||||
- CPU: [e. g. Intel i7, AMD Zen2, Qualcomm, ...]
|
||||
- GPU: [e. g. Nvidia RTX 2xxx Series, AMD Radeone 5xxx Series, ...]
|
||||
- RAM: [e. g. 16GB, 32GB, 64GB, ...]
|
||||
|
||||
### Checklist:
|
||||
<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->
|
||||
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->
|
||||
- [ ] I have read the contribution guidelines.
|
||||
- [ ] This is not a bug, crash or generic issue.
|
||||
@@ -1,38 +0,0 @@
|
||||
---
|
||||
name: Issue/Bug report
|
||||
about: Encountered a problem, a bug or a crash?
|
||||
|
||||
---
|
||||
|
||||
<!--- Please fill out the following template, which will help other contributors review your Issue. -->
|
||||
<!--- Make sure you’ve read the contribution guidelines -->
|
||||
|
||||
### Description
|
||||
<!-- Describe the bug (and behavior) in as much detail as necessary -->
|
||||
<!-- Include screenshots and attach (crash) logs if possible -->
|
||||
|
||||
### Expected Behavior
|
||||
<!-- What is the expected behavior in this case? -->
|
||||
|
||||
### Reproduction Steps
|
||||
<!-- Describe the steps required to get this to happen from a cleanly installed obs-studio -->
|
||||
<!-- Leave out detail that is not relevant to -->
|
||||
1. Open a portal to the Infinite Void
|
||||
2. Summon an ancient God
|
||||
3. Realize your mistake
|
||||
|
||||
### System Information
|
||||
<!-- Include as much information about the system you're using as possible. -->
|
||||
- Software Version: [e. g. 1.0.0, 1.2.1, ... - NEVER LATEST]
|
||||
- Operating System: [e. g. Windows, Debian, Ubuntu, RedHat, FreeBSD, ...]
|
||||
- Kernel Version: [e. g. 1903/1809 (Windows), 4.12 (Linux), ...]
|
||||
- CPU: [e. g. Intel i7, AMD Zen2, Qualcomm, ...]
|
||||
- GPU: [e. g. Nvidia RTX 2xxx Series, AMD Radeone 5xxx Series, ...]
|
||||
- RAM: [e. g. 16GB, 32GB, 64GB, ...]
|
||||
|
||||
### Checklist:
|
||||
<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->
|
||||
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->
|
||||
- [ ] I have read the contribution guidelines.
|
||||
- [ ] I can reproduce the issue with the exact reproduction steps I have provided.
|
||||
- [ ] The issue appears on all of my systems that can run this software.
|
||||
@@ -1,35 +0,0 @@
|
||||
<!--- Please fill out the following template, which will help other contributors review your Pull Request. -->
|
||||
|
||||
<!--- Make sure you’ve read the contribution guidelines -->
|
||||
|
||||
### Description
|
||||
<!--- Describe your changes in detail. -->
|
||||
<!--- If this change includes UI elements, please include screenshots. -->
|
||||
|
||||
### Motivation and Context
|
||||
<!--- Why is this change required? What problem does it solve? -->
|
||||
<!--- If it fixes an open Mantis issue, or implements feature request -->
|
||||
<!--- from the Ideas page, please link to the issue here. -->
|
||||
|
||||
### How Has This Been Tested?
|
||||
<!--- Please describe in detail how you tested your changes. -->
|
||||
<!--- Include details of your testing environment (hardware, OS version, etc.),-->
|
||||
<!--- and the tests you ran, including how it may affect other areas of code. -->
|
||||
|
||||
### Types of changes
|
||||
<!--- What types of changes does your PR introduce? Uncomment all that apply -->
|
||||
<!--- - Bug fix (non-breaking change which fixes an issue) -->
|
||||
<!--- - New feature (non-breaking change which adds functionality) -->
|
||||
<!--- - Performance enhancement (non-breaking change which improves efficiency) -->
|
||||
<!--- - Code cleanup (non-breaking change which makes code smaller or more readable) -->
|
||||
<!--- - Breaking change (fix or feature that would cause existing functionality to change) -->
|
||||
<!--- - Documentation (a change to documentation pages) -->
|
||||
|
||||
### Checklist:
|
||||
<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->
|
||||
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->
|
||||
- [ ] My code has been run through [clang-format](https://github.com/obsproject/obs-studio/blob/master/.clang-format).
|
||||
- [ ] I have read the [**contributing** document](https://github.com/obsproject/obs-studio/blob/master/CONTRIBUTING.rst).
|
||||
- [ ] My code is not on the master branch.
|
||||
- [ ] The code has been tested.
|
||||
- [ ] All commit messages are properly formatted and commits squashed where appropriate.
|
||||
@@ -1,3 +1 @@
|
||||
/media/rendered/*
|
||||
*.gma
|
||||
desktop.ini
|
||||
Pack.gma
|
||||
@@ -0,0 +1,15 @@
|
||||
Changelist
|
||||
-
|
||||
|
||||
ToDo:
|
||||
- Replace all createconvar with getconvar?
|
||||
- Other game modes
|
||||
- UI stuff
|
||||
- Scoreboard
|
||||
- Custom Collisions for Hiders? Allows to copy the prop geometry/align with rotation
|
||||
- Spectator: Spectate players(team only), first & third person
|
||||
- UI: Proper Scoreboard replacement
|
||||
- UI: Proper Team Selection replacement
|
||||
- PostMatch: Implement Round Limit & Map Time Limit checking.
|
||||
- PostMatch: Implement MapVoting? Or add support for MapVote addon?
|
||||
- Seekers, Hiders: Taunts! And custom Taunts. And everything that belongs to that.
|
||||
@@ -1,11 +1,22 @@
|
||||
Copyright 2015-2020 Michael Fabian 'Xaymar' Dirks <info@xaymar.com>
|
||||
The MIT License (MIT)
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||
Copyright (c) 2016 Michael Fabian Dirks
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
After Width: | Height: | Size: 269 KiB |
@@ -1,58 +0,0 @@
|
||||
# Prop Hunt Extended
|
||||
Hide n Seek with a twist - Hiders can turn into anything on the map! From bottles, to vending machines and all the way to huge cars - what you become depends on how you want to play. Do you want to blend in with your surroundings, or do you want to make a fool of the Seekers? And how will you deal with finding (and killing) all hiders as a Seeker?
|
||||
|
||||
## Features and Improvements
|
||||
* **Prop Rotation**: Rotate your prop into the correct orientation to fool Seekers even more.
|
||||
* **Correct Hitboxes**: All hitboxes now compensate for lag, making shots that should have hit actually hit.
|
||||
* **Better Camera**: First- & Third-Person modes, world collision, proper world origin to support small hiding spaces without making the world disappear.
|
||||
* **Custom Player Models**: Customize yourself to the best of your abilities.
|
||||
* **Taunt Packs**: All taunt packs compatible with Tsukasas Taunt Pack Loader will work and load.
|
||||
* **Name Plates and Selection Halo**: Know who is what, and what you're going to select!
|
||||
* **Proper Scoreboard**: The gamemode comes with a proper Scoreboard instead of the default one.
|
||||
* **Better Configuration**: Everything can be configured during gameplay using CVars.
|
||||
* **Improved Networking Performance**: Only necessary information is shared.
|
||||
|
||||
## Compatibility with other Addons
|
||||
* **[MapVote](https://steamcommunity.com/sharedfiles/filedetails/?id=151583504)**: Full support
|
||||
* **Tsukasas Taunt Pack Loader**: Compatibility layer included, not compatible due to this.
|
||||
* **LiteGibs**: Breaks literally everything somehow.
|
||||
|
||||
# How To Play
|
||||
## Seekers
|
||||
Your primary goal is to find hiders by any means possible. But watch out, you might lose health if you shoot an object that isn't actually a hider! Pick things up before shooting them, or simply remember the layout of the maps you are playing on. And remember: You lose if only a single hider is still alive at the end of the round.
|
||||
|
||||
## Hiders
|
||||
Stay alive as long as possible and make Seekers look like a fool. Dance around their feet, hide in plain sight or be that huge car that nobody though you could become! What you do is entirely up to you.
|
||||
|
||||
## Spectators
|
||||
You get to watch the whole thing go down live! Sit back, grab some popcorn or any other snack and relax.
|
||||
|
||||
## Controls
|
||||
* ShowHelp (Default F1): Show Help and client Settings menu.
|
||||
* ShowTeam (Default F2): Show Team Selection menu.
|
||||
* ShowSpare1 (Default F3): Taunt everything and everyone.
|
||||
* ShowContextMenu (Default C): Toggle between First- and Thirdperson camera.
|
||||
* ShowSpawnMenu (Default Q): (Hider only) Hold to enable prop rotation, let go to disable prop rotation.
|
||||
* Prop Hunt SMG Reload (Default R): If ammo is full switches between single and burst fire.
|
||||
|
||||
# Other Stuff
|
||||
## Help and Community
|
||||
All help is provided through [Discord (preferred, channel #gmod-prop-hunt-extended)](https://discord.gg/tbqhAxr) and [Steam Workshop Discussions](https://steamcommunity.com/sharedfiles/filedetails/discussions/468149739). Please read the [FAQ](https://steamcommunity.com/workshop/filedetails/discussion/468149739/358415206095321277/) as it can often answer your question.
|
||||
|
||||
## Spread the Word
|
||||
It is always appreciated to see the word about this Gamemode being spread, especially to content creators that are still uploading Prop Hunt content. If you want to tag me, my Twitter username is [@Xaymar](https://twitter.com/Xaymar), my Twitch username is [Xaymar](https://twitch.tv/Xaymar), my YouTube custom url is [Xaymar](https://youtube.com/c/Xaymar) and my Patreon is also [Xaymar](https://patreon.com/Xaymar).
|
||||
|
||||
## Donations to help the cause
|
||||
The development of this and other projects is funded through [Patreon](https://www.patreon.com/Xaymar). My dream is to eventually be able to do this full time without requiring a full-time job, perhaps even streaming this to YouTube and Twitch.
|
||||
|
||||
## Official Servers
|
||||
### Central Europe
|
||||
* Primary: steam://connect/xaymar.com:27015
|
||||
* Secondary: steam://connect/xaymar.com:27016
|
||||
|
||||
## Links
|
||||
* [Workshop page](https://steamcommunity.com/sharedfiles/filedetails/?id=468149739)
|
||||
* [Facepunch Thread](https://forum.facepunch.com/f/gmodgames/osvi/Prop-Hunt-Extended/1/)
|
||||
|
||||
# License
|
||||
For the license, see the file `LICENSE`. This file overrides any headers written in files.
|
||||
@@ -3,6 +3,5 @@
|
||||
"type" : "gamemode",
|
||||
"tags" : [ "fun" ],
|
||||
"ignore" : [
|
||||
"addon.txt"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
"TableToKeyValues"
|
||||
{
|
||||
"1" "models/props/cs_assault/dollar.mdl"
|
||||
"2" "models/props/cs_assault/money.mdl"
|
||||
"3" "models/props/cs_office/snowman_arm.mdl"
|
||||
"4" "models/props_junk/garbage_plasticbottle001a.mdl"
|
||||
"5" "models/props/cs_office/projector_remote.mdl"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
"TableToKeyValues"
|
||||
{
|
||||
"TAUNT_DELAY" "0.1"
|
||||
"ROUNDS_PER_MAP" "20"
|
||||
"ROUND_TIME" "240"
|
||||
"SWAP_TEAM_EVERY_ROUND" "1"
|
||||
"GAME_TIME" "20"
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
"TableToKeyValues"
|
||||
{
|
||||
"1" "bot/aw_hell.wav"
|
||||
"2" "bot/aww_man.wav"
|
||||
"3" "bot/anyone_see_anything.wav"
|
||||
"4" "bot/anyone_see_them.wav"
|
||||
"5" "bot/come_out_and_fight_like_a_man.wav"
|
||||
"6" "bot/come_out_wherever_you_are.wav"
|
||||
"7" "bot/he_got_away.wav"
|
||||
"8" "bot/he_got_away2.wav"
|
||||
"9" "bot/i_dont_know_where_he_went.wav"
|
||||
"10" "bot/i_got_nothing.wav"
|
||||
"11" "bot/nothing_happening_over_here.wav"
|
||||
"12" "bot/nothing_here.wav"
|
||||
"13" "bot/nothing_moving_over_here.wav"
|
||||
"14" "bot/thats_not_good.wav"
|
||||
"15" "bot/theres_too_many.wav"
|
||||
"16" "bot/theres_too_many_of_them.wav"
|
||||
"17" "bot/theyre_all_over_the_place2.wav"
|
||||
"18" "bot/theyre_everywhere2.wav"
|
||||
"19" "bot/too_many2.wav"
|
||||
"20" "bot/what_happened.wav"
|
||||
"21" "bot/what_have_you_done.wav"
|
||||
"22" "bot/where_are_they.wav"
|
||||
"23" "bot/where_are_you_hiding.wav"
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
"TableToKeyValues"
|
||||
{
|
||||
"1" "bot/a_bunch_of_them.wav"
|
||||
"2" "bot/come_out_and_fight_like_a_man.wav"
|
||||
"3" "bot/come_out_wherever_you_are.wav"
|
||||
"4" "bot/come_to_papa.wav"
|
||||
"5" "bot/dont_worry_hell_get_it.wav"
|
||||
"6" "bot/hang_on_i_heard_something.wav"
|
||||
"7" "bot/hang_on_im_coming.wav"
|
||||
"8" "bot/i_dont_think_so.wav"
|
||||
"9" "bot/i_have_the_hostages.wav"
|
||||
"10" "bot/i_see_our_target.wav"
|
||||
"11" "bot/im_waiting_here.wav"
|
||||
"12" "bot/keeping_an_eye_on_the_hostages.wav"
|
||||
"13" "bot/nnno_sir.wav"
|
||||
"14" "bot/spotted_the_delivery_boy.wav"
|
||||
"15" "bot/target_acquired.wav"
|
||||
"16" "bot/target_spotted.wav"
|
||||
"17" "bot/you_heard_the_man_lets_go.wav"
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
"TableToKeyValues"
|
||||
{
|
||||
"1" "ambient/alarms/apc_alarm_pass1.wav"
|
||||
"2" "ambient/alarms/manhack_alert_pass1.wav"
|
||||
"3" "ambient/alarms/razortrain_horn1.wav"
|
||||
"4" "ambient/alarms/scanner_alert_pass1.wav"
|
||||
"5" "ambient/alarms/train_horn2.wav"
|
||||
"6" "ambient/alarms/train_horn_distant1.wav"
|
||||
"7" "ambient/alarms/warningbell1.wav"
|
||||
"8" "ambient/energy/whiteflash.wav"
|
||||
"9" "ambient/intro/alyxremove.wav"
|
||||
"10" "ambient/intro/logosfx.wav"
|
||||
"11" "ambient/levels/launch/1stfiringwarning.wav"
|
||||
"12" "ambient/levels/launch/rockettakeoffblast.wav"
|
||||
"13" "ambient/misc/ambulance1.wav"
|
||||
"14" "ambient/misc/carhonk1.wav"
|
||||
"15" "ambient/misc/carhonk2.wav"
|
||||
"16" "ambient/misc/carhonk3.wav"
|
||||
"17" "ambient/outro/gunshipcrash.wav"
|
||||
"18" "ambient/3dmeagle.wav"
|
||||
"19" "beams/beamstart5.wav"
|
||||
"20" "buttons/bell1.wav"
|
||||
"21" "buttons/weapon_cant_buy.wav"
|
||||
"22" "common/bass.wav"
|
||||
"23" "common/bugreporter_failed.wav"
|
||||
"24" "common/warning.wav"
|
||||
"25" "doors/door_squeek1.wav"
|
||||
"26" "friends/friend_join.wav"
|
||||
"27" "friends/friend_online.wav"
|
||||
"28" "friends/message.wav"
|
||||
"29" "hostage/hunuse/comeback.wav"
|
||||
"30" "hostage/hunuse/dontleaveme.wav"
|
||||
"31" "hostage/hunuse/yeahillstay.wav"
|
||||
"32" "items/gift_drop.wav"
|
||||
"33" "music/radio1.mp3"
|
||||
"34" "phx/eggcrack.wav"
|
||||
"35" "plats/elevbell1.wav"
|
||||
"36" "player/headshot1.wav"
|
||||
"37" "player/headshot2.wav"
|
||||
"38" "player/sprayer.wav"
|
||||
"39" "radio/enemydown.wav"
|
||||
"40" "radio/go.wav"
|
||||
"41" "radio/locknload.wav"
|
||||
"42" "radio/negative.wav"
|
||||
"43" "radio/rounddraw.wav"
|
||||
"44" "radio/takepoint.wav"
|
||||
"45" "resource/warning.wav"
|
||||
"46" "ui/achievement_earned.wav"
|
||||
"47" "ui/freeze_cam.wav"
|
||||
"48" "vehicles/junker/radar_ping_friendly1.wav"
|
||||
"49" "weapons/c4/c4_beep1.wav"
|
||||
"50" "weapons/c4/c4_click.wav"
|
||||
"51" "weapons/awp/awp1.wav"
|
||||
"52" "vo/canals/female01/gunboat_giveemhell.wav"
|
||||
"53" "vo/canals/female01/gunboat_justintime.wav"
|
||||
"54" "vo/canals/female01/stn6_incoming.wav"
|
||||
"55" "vo/canals/male01/gunboat_giveemhell.wav"
|
||||
"56" "vo/canals/male01/gunboat_justintime.wav"
|
||||
"57" "vo/canals/male01/stn6_incoming.wav"
|
||||
"58" "vo/canals/al_radio_stn6.wav"
|
||||
"59" "vo/canals/arrest_getgoing.wav"
|
||||
"60" "vo/canals/arrest_helpme.wav"
|
||||
"61" "vo/canals/arrest_lookingforyou.wav"
|
||||
"62" "vo/canals/boxcar_lethimhelp.wav"
|
||||
"63" "vo/canals/matt_closecall.wav"
|
||||
"64" "vo/canals/premassacre.wav"
|
||||
"65" "vo/ravenholm/aimforhead.wav"
|
||||
"66" "vo/ravenholm/bucket_patience.wav"
|
||||
"67" "vo/ravenholm/madlaugh01.wav"
|
||||
"68" "vo/ravenholm/madlaugh02.wav"
|
||||
"69" "vo/ravenholm/madlaugh03.wav"
|
||||
"70" "vo/ravenholm/madlaugh04.wav"
|
||||
"71" "weapons/strider_buster/ol12_stickybombcreator.wav"
|
||||
"72" "weapons/c4/c4_explode1.wav"
|
||||
"73" "weapons/357/357_fire2.wav"
|
||||
"74" "weapons/357/357_fire3.wav"
|
||||
"75" "weapons/scout/scout_fire-1.wav"
|
||||
"76" "weapons/smokegrenade/sg_explode.wav"
|
||||
"77" "weapons/grenade_launcher1.wav"
|
||||
"78" "weapons/explode3.wav"
|
||||
"79" "weapons/underwater_explode3.wav"
|
||||
"80" "items/nvg_on.wav"
|
||||
"81" "hostage/huse/letsdoit.wav"
|
||||
"82" "hostage/huse/illfollow.wav"
|
||||
"83" "hostage/huse/getouttahere.wav"
|
||||
"84" "doors/door_screen_move1.wav"
|
||||
"85" "doors/heavy_metal_stop1.wav"
|
||||
"86" "doors/default_move.wav"
|
||||
"87" "common/stuck2.wav"
|
||||
"88" "ambient/water_splash1.wav"
|
||||
"89" "ambient/water_splash2.wav"
|
||||
"90" "ambient/water_splash3.wav"
|
||||
"91" "ambient/weather/thunder1.wav"
|
||||
"92" "ambient/weather/thunder2.wav"
|
||||
"93" "ambient/weather/thunder3.wav"
|
||||
"94" "ambient/weather/thunder4.wav"
|
||||
"95" "ambient/weather/thunder5.wav"
|
||||
"96" "ambient/weather/thunder6.wav"
|
||||
"97" "ambient/outro/thunder7.wav"
|
||||
"98" "ambient/voices/crying_loop1.wav"
|
||||
"99" "ambient/voices/playground_memory.wav"
|
||||
"100" "ambient/voices/f_scream1.wav"
|
||||
"101" "ambient/voices/m_scream1.wav"
|
||||
"102" "ambient/voices/cough1.wav"
|
||||
"103" "ambient/voices/cough2.wav"
|
||||
"104" "ambient/voices/cough3.wav"
|
||||
"105" "ambient/voices/cough4.wav"
|
||||
"106" "ambient/overhead/plane1.wav"
|
||||
"107" "ambient/overhead/plane2.wav"
|
||||
"108" "ambient/overhead/plane3.wav"
|
||||
"109" "ambient/overhead/hel1.wav"
|
||||
"110" "ambient/overhead/hel2.wav"
|
||||
"111" "ambient/misc/truck_backup1.wav"
|
||||
"112" "ambient/misc/truck_drive1.wav"
|
||||
"113" "ambient/misc/truck_drive2.wav"
|
||||
"114" "ambient/machines/pneumatic_drill_1.wav"
|
||||
"115" "ambient/machines/pneumatic_drill_2.wav"
|
||||
"116" "ambient/machines/pneumatic_drill_3.wav"
|
||||
"117" "ambient/machines/pneumatic_drill_4.wav"
|
||||
"118" "ambient/machines/station_train_squeel.wav"
|
||||
"119" "ambient/machines/ticktock.wav"
|
||||
"120" "ambient/creatures/teddy.wav"
|
||||
"121" "ambient/creatures/town_child_scream1.wav"
|
||||
"122" "ambient/creatures/town_moan1.wav"
|
||||
"123" "ambient/creatures/town_muffled_cry1.wav"
|
||||
"124" "ambient/creatures/town_scared_breathing1.wav"
|
||||
"125" "ambient/creatures/town_scared_breathing2.wav"
|
||||
"126" "ambient/creatures/town_scared_sob1.wav"
|
||||
"127" "ambient/creatures/town_scared_sob2.wav"
|
||||
"128" "ambient/creatures/town_zombie_call1.wav"
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
"TableToKeyValues"
|
||||
{
|
||||
"1" "bot/and_thats_how_its_done.wav"
|
||||
"2" "bot/come_to_papa.wav"
|
||||
"3" "bot/do_not_mess_with_me.wav"
|
||||
"4" "bot/dropped_him.wav"
|
||||
"5" "bot/enemy_down.wav"
|
||||
"6" "bot/enemy_down2.wav"
|
||||
"7" "bot/good_job_team.wav"
|
||||
"8" "bot/got_him.wav"
|
||||
"9" "bot/hes_broken.wav"
|
||||
"10" "bot/hes_dead.wav"
|
||||
"11" "bot/hes_done.wav"
|
||||
"12" "bot/hes_down.wav"
|
||||
"13" "bot/its_a_party.wav"
|
||||
"14" "bot/i_am_dangerous.wav"
|
||||
"15" "bot/i_am_on_fire.wav"
|
||||
"16" "bot/i_got_more_where_that_came_from.wav"
|
||||
"17" "bot/i_wasnt_worried_for_a_minute.wav"
|
||||
"18" "bot/killed_him.wav"
|
||||
"19" "bot/look_out_brag.wav"
|
||||
"20" "bot/made_him_cry.wav"
|
||||
"21" "bot/oh_yea.wav"
|
||||
"22" "bot/oh_yea2.wav"
|
||||
"23" "bot/owned.wav"
|
||||
"24" "bot/ruined_his_day.wav"
|
||||
"25" "bot/tag_them_and_bag_them.wav"
|
||||
"26" "bot/thats_the_way_this_is_done.wav"
|
||||
"27" "bot/that_was_a_close_one.wav"
|
||||
"28" "bot/that_was_it.wav"
|
||||
"29" "bot/that_was_the_last_guy.wav"
|
||||
"30" "bot/that_was_the_last_one.wav"
|
||||
"31" "bot/they_never_knew_what_hit_them.wav"
|
||||
"32" "bot/they_will_not_escape.wav"
|
||||
"33" "bot/they_wont_get_away.wav"
|
||||
"34" "bot/they_wont_get_away2.wav"
|
||||
"35" "bot/this_is_my_house.wav"
|
||||
"36" "bot/took_him_down.wav"
|
||||
"37" "bot/took_him_out.wav"
|
||||
"38" "bot/took_him_out2.wav"
|
||||
"39" "bot/wasted_him.wav"
|
||||
"40" "bot/way_to_be_team.wav"
|
||||
"41" "bot/well_done.wav"
|
||||
"42" "bot/we_owned_them.wav"
|
||||
"43" "bot/whew_that_was_close.wav"
|
||||
"44" "bot/whoo.wav"
|
||||
"45" "bot/whoo2.wav"
|
||||
"46" "bot/whos_the_man.wav"
|
||||
"47" "bot/who_wants_some_more.wav"
|
||||
"48" "bot/yesss.wav"
|
||||
"49" "bot/yesss2.wav"
|
||||
}
|
||||
@@ -23,15 +23,7 @@ function ENT:Think()
|
||||
|
||||
-- Angles
|
||||
if (self.Owner:GetNWBool("PropRotation")) then
|
||||
self:ApplyRotation(self.Owner:EyeAngles())
|
||||
self:SetAngles(self.Owner:EyeAngles())
|
||||
end
|
||||
end
|
||||
|
||||
function ENT:ApplyRotation(ang)
|
||||
if !(GAMEMODE.Config.Hider:AllowFullRotation()) then
|
||||
ang.p = 0
|
||||
ang.r = 0
|
||||
end
|
||||
self:SetAngles(ang)
|
||||
end
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
-- SWEP Information
|
||||
SWEP.Author = "Michael 'Xaymar' Dirks"
|
||||
SWEP.Contact = "info@xaymar.com"
|
||||
SWEP.Contact = "info@project-kube.de"
|
||||
SWEP.PrintName = "PH Submachine Gun"
|
||||
SWEP.Purpose = "More accurate SMG for Prop Hunt."
|
||||
SWEP.Instructions = "Fire away! Alternative fire to fire a grenade."
|
||||
@@ -30,8 +30,8 @@ SWEP.Primary.ClipSize = 45
|
||||
SWEP.Primary.DefaultClip = 45
|
||||
SWEP.Primary.Automatic = true
|
||||
SWEP.Primary.Ammo = "SMG1"
|
||||
SWEP.Primary.Damage = 4
|
||||
SWEP.Primary.RefireTime = 0.075
|
||||
SWEP.Primary.Damage = 5
|
||||
SWEP.Primary.RefireTime = 0.1
|
||||
|
||||
-- Secondary Ammunition: SMG Grenades
|
||||
SWEP.Secondary.ClipSize = 1
|
||||
@@ -25,21 +25,11 @@
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Includes
|
||||
-- ------------------------------------------------------------------------- --
|
||||
-- Early Init
|
||||
include("sh_init.lua")
|
||||
include("vgui/dlabeldpi.lua")
|
||||
include("vgui/dframedpi.lua")
|
||||
include("vgui/fontmanager.lua")
|
||||
include("vgui/uimanager.lua")
|
||||
include("client/roundmanager.lua")
|
||||
|
||||
-- Late Init
|
||||
GM.UI = {}
|
||||
include("client/cl_ui_help.lua")
|
||||
include("client/cl_ui_teamselection.lua")
|
||||
include("client/hud/gamestatedisplay.lua")
|
||||
include("client/ui/scoreboard.lua")
|
||||
include("client/ui/help.lua")
|
||||
include("client/ui/settings.lua")
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Code
|
||||
@@ -48,27 +38,20 @@ function GM:Initialize()
|
||||
print("-------------------------------------------------------------------------")
|
||||
print("Prop Hunt CL: Initializing...")
|
||||
|
||||
print("Prop Hunt CL: Preparing data...")
|
||||
print("Prop Hunt CL: Initializing Gamemode Data...")
|
||||
self.Data = {}
|
||||
|
||||
print("Prop Hunt CL: Creating User Interface...")
|
||||
FontManager:Request("RobotoBoldCondensed160", {font="Roboto Bold Condensed", extended=true, size=160, weight=800, antialias=true})
|
||||
self.UI = {}
|
||||
self.UI.Help = vgui.Create("PHE_HelpUI")
|
||||
self.UI.Scoreboard = vgui.Create("DScoreBoard")
|
||||
self.UI.GameStateDisplay = vgui.Create("PHE_GameState")
|
||||
self.UI.GameStateDisplay:Show()
|
||||
print("Prop Hunt CL: Creating Huge Ass Font...")
|
||||
surface.CreateFont("PHHugeAssFont", {font="Roboto Bold Condensed", extended=true, size=160, weight=800, antialias=true})
|
||||
|
||||
print("Prop Hunt CL: Complete.")
|
||||
print("-------------------------------------------------------------------------")
|
||||
end
|
||||
|
||||
function GM:Think()
|
||||
UIManager:Tick()
|
||||
end
|
||||
function GM:Think() end
|
||||
|
||||
function GM:InitialPlayerSpawn()
|
||||
if GAMEMODE.Config:DebugLog() then print("Prop Hunt CL: InitialPlayerSpawn") end
|
||||
print("Prop Hunt CL: InitialPlayerSpawn")
|
||||
|
||||
-- Delay execution until LocalPlayer() is valid.
|
||||
if (!LocalPlayer()) || (!IsValid(LocalPlayer())) then
|
||||
@@ -76,13 +59,13 @@ function GM:InitialPlayerSpawn()
|
||||
return
|
||||
end
|
||||
|
||||
if GAMEMODE.Config:DebugLog() then print("Prop Hunt CL: InitialPlayerSpawn Valid") end
|
||||
print("Prop Hunt CL: InitialPlayerSpawn Valid")
|
||||
|
||||
player_manager.RunClass(LocalPlayer(), "InitialClientSpawn")
|
||||
end
|
||||
|
||||
function GM:PlayerSpawn()
|
||||
if GAMEMODE.Config:DebugLog() then print("Prop Hunt CL: PlayerSpawn") end
|
||||
print("Prop Hunt CL: PlayerSpawn")
|
||||
|
||||
-- Delay execution until LocalPlayer() is valid.
|
||||
if (!LocalPlayer()) || (!IsValid(LocalPlayer())) then
|
||||
@@ -90,7 +73,7 @@ function GM:PlayerSpawn()
|
||||
return
|
||||
end
|
||||
|
||||
if GAMEMODE.Config:DebugLog() then print("Prop Hunt CL: PlayerSpawn Valid") end
|
||||
print("Prop Hunt CL: PlayerSpawn Valid")
|
||||
|
||||
if !(LocalPlayer().Data) then
|
||||
LocalPlayer().Data = {}
|
||||
@@ -123,9 +106,8 @@ function GM:PlayerSetViewOffset(vo, voduck)
|
||||
if !(GAMEMODE.TempData) then GAMEMODE.TempData = {} end
|
||||
GAMEMODE.TempData.ViewOffset = vo
|
||||
GAMEMODE.TempData.ViewOffsetDuck = voduck
|
||||
timer.Simple(.1, function()
|
||||
GAMEMODE:PlayerSetViewOffset(GAMEMODE.TempData.ViewOffset, GAMEMODE.TempData.ViewOffsetDuck)
|
||||
end)
|
||||
|
||||
timer.Simple(.1, function() GAMEMODE:PlayerSetViewOffset(GAMEMODE.TempData.ViewOffset, GAMEMODE.TempData.ViewOffsetDuck) end)
|
||||
return
|
||||
end
|
||||
|
||||
@@ -144,8 +126,8 @@ function GM:PlayerSetHull(hullMin, hullMax)
|
||||
if !(GAMEMODE.TempData) then GAMEMODE.TempData = {} end
|
||||
GAMEMODE.TempData.HullMin = hullMin
|
||||
GAMEMODE.TempData.HullMax = hullMax
|
||||
timer.Simple(.1, function()
|
||||
GAMEMODE:PlayerSetHull(GAMEMODE.TempData.HullMin, GAMEMODE.TempData.HullMax) end)
|
||||
|
||||
timer.Simple(.1, function() GAMEMODE:PlayerSetHull(GAMEMODE.TempData.HullMin, GAMEMODE.TempData.HullMax) end)
|
||||
return
|
||||
end
|
||||
|
||||
@@ -164,32 +146,20 @@ function GM:OnContextMenuOpen()
|
||||
end
|
||||
|
||||
function GM:OnContextMenuClose()
|
||||
if GAMEMODE.Config:DebugLog() then print("Prop Hunt CL: Toggled View Mode") end
|
||||
print("Prop Hunt CL: Toggled View Mode")
|
||||
LocalPlayer().Data.ThirdPerson = !LocalPlayer().Data.ThirdPerson
|
||||
end
|
||||
|
||||
function GM:OnSpawnMenuOpen()
|
||||
if GAMEMODE.Config:DebugLog() then print("Prop Hunt CL: Enabling Prop Rotation") end
|
||||
print("Prop Hunt CL: Enabling Prop Rotation")
|
||||
LocalPlayer():SetNWBool("PropRotation", true)
|
||||
net.Start("PlayerEnablePropRotation")
|
||||
net.WriteAngle(LocalPlayer():EyeAngles())
|
||||
net.SendToServer()
|
||||
net.Start("PlayerEnablePropRotation");net.SendToServer()
|
||||
end
|
||||
|
||||
function GM:OnSpawnMenuClose()
|
||||
if GAMEMODE.Config:DebugLog() then print("Prop Hunt CL: Disabling Prop Rotation") end
|
||||
print("Prop Hunt CL: Disabling Prop Rotation")
|
||||
LocalPlayer():SetNWBool("PropRotation", false)
|
||||
net.Start("PlayerDisablePropRotation")
|
||||
net.WriteAngle(LocalPlayer():EyeAngles())
|
||||
net.SendToServer()
|
||||
end
|
||||
|
||||
function GM:ScoreboardShow()
|
||||
self.UI.Scoreboard:Show()
|
||||
end
|
||||
|
||||
function GM:ScoreboardHide()
|
||||
self.UI.Scoreboard:Hide()
|
||||
net.Start("PlayerDisablePropRotation");net.SendToServer()
|
||||
end
|
||||
|
||||
function GM:ShowHelpUI()
|
||||
@@ -217,95 +187,45 @@ net.Receive( "PlayerViewOffset", function(len, pl)
|
||||
GAMEMODE:PlayerSetViewOffset(vo, voduck)
|
||||
end)
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Special Drawing
|
||||
-- ------------------------------------------------------------------------- --
|
||||
function DrawNamePlates(bDrawingDepth, bDrawingSkybox)
|
||||
if (!GAMEMODE.Config.NamePlates:Show()) then
|
||||
return
|
||||
end
|
||||
|
||||
local scale = GAMEMODE.Config.NamePlates:Scale()
|
||||
local pls = team.GetPlayers(GAMEMODE.Teams.Seekers)
|
||||
if (LocalPlayer():Team() == GAMEMODE.Teams.Hiders) then
|
||||
pls = table.Add(pls, team.GetPlayers(GAMEMODE.Teams.Hiders))
|
||||
end
|
||||
|
||||
for i,v in ipairs(pls) do
|
||||
if (v:Alive() && v != LocalPlayer()) then
|
||||
if (player_manager.GetPlayerClass(v) != "Spectator") then
|
||||
local color = HSVToColor(GAMEMODE.Config.NamePlates:TintHue(),
|
||||
GAMEMODE.Config.NamePlates:TintSaturation(),
|
||||
GAMEMODE.Config.NamePlates:TintValue())
|
||||
if GAMEMODE.Config.NamePlates:TintHealth() then
|
||||
local healthPrc = v:Health() / v:GetMaxHealth()
|
||||
color = HSVToColor(120 * healthPrc, 1.0, 1.0)
|
||||
elseif GAMEMODE.Config.NamePlates:TintTeam() then
|
||||
color = team.GetColor(v:Team())
|
||||
end
|
||||
|
||||
local pos = v:GetPos() + v:GetViewOffset() + Vector(0, 0, GAMEMODE.Config.NamePlates:Height())
|
||||
local ang = Angle(0, LocalPlayer():EyeAngles().y - 90, 90 - LocalPlayer():EyeAngles().x)
|
||||
cam.Start3D2D(pos, ang, scale)
|
||||
draw.DrawText(v:GetName(), "RobotoBoldCondensed160", 0, -draw.GetFontHeight("RobotoBoldCondensed160") / 2, color, TEXT_ALIGN_CENTER)
|
||||
cam.End3D2D()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
hook.Add("PostDrawTranslucentRenderables", "PHDrawNamePlates", DrawNamePlates)
|
||||
|
||||
function DrawSelectionHalo(bDrawingDepth, bDrawingSkybox)
|
||||
if (!GAMEMODE.Config.SelectionHalo:Enabled()) then return end
|
||||
if ((LocalPlayer():Team() == GAMEMODE.Teams.Hiders)
|
||||
&& (player_manager.GetPlayerClass(LocalPlayer()) == "Hider")) then
|
||||
local ent = nil
|
||||
if (GAMEMODE.Config.SelectionHalo:Approximate()) then
|
||||
local trace = {
|
||||
start = LocalPlayer():EyePos(),
|
||||
endpos = LocalPlayer():EyePos() + LocalPlayer():EyeAngles():Forward() * 80,
|
||||
mins = Vector(-16, -16, -16),
|
||||
maxs = Vector( 16, 16, 16),
|
||||
mask = MASK_SOLID + CONTENTS_DEBRIS + CONTENTS_PLAYERCLIP,
|
||||
filter = function(ent)
|
||||
-- Ensure that we don't actually hit ourselves by accident, or our "hands" model.
|
||||
if (!IsValid(ent)
|
||||
|| (ent == LocalPlayer())
|
||||
|| (ent == LocalPlayer():GetHands())) then
|
||||
return false
|
||||
end
|
||||
if table.HasValue(GAMEMODE.Config.Lists:ClassWhitelist(), ent:GetClass()) then return true end
|
||||
return false
|
||||
end,
|
||||
output = {}
|
||||
}
|
||||
util.TraceLine(trace)
|
||||
if !IsValid(trace.output.Entity) then util.TraceHull(trace) end
|
||||
if IsValid(trace.output.Entity) then
|
||||
if (!table.HasValue(GAMEMODE.Config.Lists:ModelBlacklist(), trace.output.Entity:GetModel())) then
|
||||
ent = trace.output.Entity
|
||||
end
|
||||
end
|
||||
else
|
||||
ent = LocalPlayer():GetNWEntity("SelectionHalo")
|
||||
end
|
||||
if IsValid(ent) then
|
||||
local color = HSVToColor(
|
||||
GAMEMODE.Config.SelectionHalo:TintHue(),
|
||||
GAMEMODE.Config.SelectionHalo:TintSaturation(),
|
||||
GAMEMODE.Config.SelectionHalo:TintValue()
|
||||
)
|
||||
halo.Add({ ent }, color,
|
||||
GAMEMODE.Config.SelectionHalo:BlurX(), GAMEMODE.Config.SelectionHalo:BlurY(), GAMEMODE.Config.SelectionHalo:Passes(),
|
||||
GAMEMODE.Config.SelectionHalo:Additive(), GAMEMODE.Config.SelectionHalo:IgnoreZ())
|
||||
end
|
||||
end
|
||||
end
|
||||
hook.Add("PostDrawEffects", "PHDrawSelectionHalo", DrawSelectionHalo)
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Old Code
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--[[
|
||||
-- Render halos and player names.
|
||||
function DrawPlayerNames(bDrawingDepth, bDrawingSkybox)
|
||||
for i,v in ipairs(player.GetAll()) do
|
||||
if v:Alive() && v != LocalPlayer() then
|
||||
local pos = v:GetPos() + v:GetViewOffset() + Vector(0, 0, 5)
|
||||
local ang = Angle(0, LocalPlayer():EyeAngles().y - 90, 90 - LocalPlayer():EyeAngles().x)
|
||||
local healthPrc = v:Health() / v:GetMaxHealth()
|
||||
local healthCol = HSVToColor(120 * healthPrc, 1.0, 1.0)
|
||||
|
||||
if v:Team() == TEAM_HUNTERS || LocalPlayer():Team() == TEAM_PROPS then
|
||||
cam.Start3D2D(pos, ang, 0.15)
|
||||
draw.DrawText(v:GetName(), "Trebuchet24", 0, -draw.GetFontHeight("Trebuchet24"), healthCol, TEXT_ALIGN_CENTER)
|
||||
cam.End3D2D()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
hook.Add("PostDrawTranslucentRenderables", "PH_DrawPlayerNames", DrawPlayerNames)
|
||||
|
||||
function DrawPlayerHalos(bDrawingDepth, bDrawingSkybox)
|
||||
for i,v in ipairs(player.GetAll()) do
|
||||
if v:Alive() then
|
||||
local pos = v:GetPos() + Vector(0, 0, 1) * (v:OBBMaxs().z - v:OBBMins().z + 5)
|
||||
local ang = Angle(0, LocalPlayer():EyeAngles().y - 90, 90 - LocalPlayer():EyeAngles().x)
|
||||
local healthPrc = v:Health() / v:GetMaxHealth()
|
||||
local healthCol = HSVToColor(120 * healthPrc, 1.0, 1.0)
|
||||
|
||||
if v:Team() == TEAM_HUNTERS || LocalPlayer():Team() == TEAM_PROPS then
|
||||
local ent = v
|
||||
if v.ph_prop && v.ph_prop:IsValid() then ent = v.ph_prop end
|
||||
|
||||
halo.Add({ent}, healthCol, 2, 2, 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
--hook.Add("PostDrawEffects", "PH_DrawPlayerHalos", DrawPlayerHalos)
|
||||
]]
|
||||
@@ -1,25 +1,61 @@
|
||||
--[[
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Xaymar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
--]]
|
||||
|
||||
include("sh_init.lua")
|
||||
--[[
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Xaymar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
--]]
|
||||
|
||||
local PANEL = vgui.Create("DFrame")
|
||||
PANEL:SetSize(400, 300)
|
||||
PANEL:SetTitle("Help")
|
||||
PANEL:SetDraggable(true)
|
||||
PANEL:SetVisible(false)
|
||||
PANEL:SetDraggable(true)
|
||||
PANEL:SetSizable(true)
|
||||
PANEL:ShowCloseButton(true)
|
||||
PANEL:SetDeleteOnClose(false)
|
||||
|
||||
function PANEL:Init()
|
||||
DFrame.Init(self)
|
||||
|
||||
-- Sheets
|
||||
self.Sheets = vgui.Create("DPropertySheet", self)
|
||||
self.Sheets:Dock(FILL)
|
||||
|
||||
-- Basic Info
|
||||
self.BasicInfoSheet = vgui.Create("DPanel", self.Sheets)
|
||||
function self.BasicInfoSheet:Paint(w, h)
|
||||
draw.RoundedBox(4, 0, 0, 100, 100, Color(0,128,255))
|
||||
end
|
||||
self.Sheets:AddSheet("The Gamemode", self.BasicInfoSheet)
|
||||
|
||||
|
||||
end
|
||||
|
||||
function PANEL:Show()
|
||||
self:SetSize(ScrW(), ScrH())
|
||||
self:Center()
|
||||
self:SetVisible(true)
|
||||
self:SetFocusTopLevel(true)
|
||||
self:SlideDown(.5)
|
||||
self:MakePopup()
|
||||
end
|
||||
|
||||
GAMEMODE.UI.Help = PANEL
|
||||
@@ -22,19 +22,6 @@
|
||||
SOFTWARE.
|
||||
--]]
|
||||
|
||||
local PANEL = vgui.Create("DFrame")
|
||||
PANEL:SetSize(400, 300)
|
||||
PANEL:SetTitle("Select a Team")
|
||||
PANEL:SetDraggable(true)
|
||||
PANEL:SetVisible(false)
|
||||
PANEL:SetDraggable(true)
|
||||
PANEL:SetSizable(true)
|
||||
PANEL:ShowCloseButton(true)
|
||||
PANEL:SetDeleteOnClose(false)
|
||||
|
||||
|
||||
|
||||
|
||||
TeamSelectionUI = {}
|
||||
TeamSelectionUI.Frame = vgui.Create("DFrame")
|
||||
TeamSelectionUI.Frame:SetPos(0, 0)
|
||||
@@ -33,30 +33,17 @@ function CompatTauntPackLoader()
|
||||
-- Run the old hook name.
|
||||
hook.Run("ph_AddTaunts", nil)
|
||||
|
||||
-- Insert the taunts into the new structure (cvar).
|
||||
Taunts = {}
|
||||
for i,t in ipairs(GAMEMODE.Prop_Taunts) do
|
||||
ty = type(t)
|
||||
if (ty == "string") then
|
||||
Taunts[#Taunts+1] = t
|
||||
elseif (ty == "table") then
|
||||
Taunts[#Taunts+1] = t[1]
|
||||
end
|
||||
-- Insert the taunts into the new structure.
|
||||
for k,v in ipairs(GAMEMODE.Hunter_Taunts) do
|
||||
-- ToDo: string.GetFileFromFilename is broken!
|
||||
--pcall(GAMEMODE.Config.Taunts.Add("TauntPackLoader."..string.GetFileFromFilename(v), v, TEAM_SEEKERES, nil))
|
||||
end
|
||||
GAMEMODE.Config.Taunt.HidersCacheStatic = Taunts
|
||||
Taunts = {}
|
||||
for i,t in ipairs(GAMEMODE.Hunter_Taunts) do
|
||||
ty = type(t)
|
||||
if (ty == "string") then
|
||||
Taunts[#Taunts+1] = t
|
||||
elseif (ty == "table") then
|
||||
Taunts[#Taunts+1] = t[1]
|
||||
end
|
||||
for k,v in ipairs(GAMEMODE.Prop_Taunts) do
|
||||
--pcall(GAMEMODE.Config.Taunts.Add("TauntPackLoader."..string.GetFileFromFilename(v), v, TEAM_HIDERS, nil))
|
||||
end
|
||||
GAMEMODE.Config.Taunt.SeekersCacheStatic = Taunts
|
||||
|
||||
-- Clean up after ourselves
|
||||
GAMEMODE.Prop_Taunts = nil
|
||||
GAMEMODE.Hunter_Taunts = nil
|
||||
end
|
||||
hook.Add("Initialize", "CompatTauntPackLoader", CompatTauntPackLoader)
|
||||
hook.Add("OnPropHuntInitialized", "CompatTauntPackLoader", CompatTauntPackLoader)
|
||||
@@ -27,30 +27,18 @@
|
||||
-- ------------------------------------------------------------------------- --
|
||||
-- Shared
|
||||
AddCSLuaFile("sh_init.lua")
|
||||
AddCSLuaFile("sh_defines.lua")
|
||||
AddCSLuaFile("sh_config.lua")
|
||||
AddCSLuaFile("meta/player.lua")
|
||||
AddCSLuaFile("sh_player.lua")
|
||||
AddCSLuaFile("player_class/class_default.lua")
|
||||
AddCSLuaFile("player_class/class_spectator.lua")
|
||||
AddCSLuaFile("player_class/class_seeker.lua")
|
||||
AddCSLuaFile("player_class/class_hider.lua")
|
||||
|
||||
-- Client-Only
|
||||
AddCSLuaFile("vgui/fontmanager.lua")
|
||||
AddCSLuaFile("vgui/uimanager.lua")
|
||||
AddCSLuaFile("vgui/dlabeldpi.lua")
|
||||
AddCSLuaFile("vgui/dframedpi.lua")
|
||||
AddCSLuaFile("client/ui/help.lua")
|
||||
AddCSLuaFile("client/ui/settings.lua")
|
||||
AddCSLuaFile("client/ui/scoreboard.lua")
|
||||
AddCSLuaFile("client/hud/gamestatedisplay.lua")
|
||||
AddCSLuaFile("client/roundmanager.lua")
|
||||
AddCSLuaFile("cl_init.lua")
|
||||
AddCSLuaFile("client/cl_ui_help.lua")
|
||||
AddCSLuaFile("client/cl_ui_teamselection.lua")
|
||||
|
||||
-- Client Init
|
||||
AddCSLuaFile("cl_init.lua") -- Immediately executed when downloaded, weird behavior.
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Code
|
||||
-- ------------------------------------------------------------------------- --
|
||||
@@ -58,6 +46,7 @@ AddCSLuaFile("cl_init.lua") -- Immediately executed when downloaded, weird behav
|
||||
include "sh_init.lua"
|
||||
|
||||
-- Server Only
|
||||
include "server/config.lua"
|
||||
include "compat/compat_tauntpackloader.lua"
|
||||
include "server/roundmanager.lua"
|
||||
include "server/states/state_prematch.lua"
|
||||
@@ -74,6 +63,7 @@ function GM:Initialize()
|
||||
print("Prop Hunt: Registering Networked Messages...")
|
||||
util.AddNetworkString("PlayerManagerInitialClientSpawn")
|
||||
util.AddNetworkString("PlayerManagerClientSpawn")
|
||||
|
||||
util.AddNetworkString("PlayerSetHull")
|
||||
util.AddNetworkString("PlayerResetHull")
|
||||
util.AddNetworkString("PlayerViewOffset")
|
||||
@@ -83,46 +73,42 @@ function GM:Initialize()
|
||||
|
||||
print("Prop Hunt: Initializing Gamemode Data...")
|
||||
self.Data = {}
|
||||
self.Data.RoundTime = 0
|
||||
self.Data.RoundStartTime = 0
|
||||
self.Data.StateTime = 0
|
||||
|
||||
print("Prop Hunt: Initializing Round Manager")
|
||||
RoundManager:SetState(StatePreRound)
|
||||
|
||||
print("Prop Hunt: Precaching...")
|
||||
GAMEMODE.Config.Taunt:Seekers()
|
||||
GAMEMODE.Config.Taunt:Hiders()
|
||||
print("Prop Hunt: Setting initial RoundManager State...")
|
||||
self.RoundManager:SetState(StatePreMatch)
|
||||
|
||||
print("Prop Hunt: Complete.")
|
||||
print("-------------------------------------------------------------------------")
|
||||
end
|
||||
|
||||
function GM:Think()
|
||||
self.RoundManager:Tick()
|
||||
end
|
||||
|
||||
-- Player Connected
|
||||
function GM:PlayerConnect(name, ip)
|
||||
if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Player '"..name.."' connecting from IP '"..ip.."'.") end
|
||||
print("Prop Hunt: Player '"..name.."' connecting from IP '"..ip.."'.")
|
||||
end
|
||||
|
||||
-- Player Authenticated
|
||||
function GM:PlayerAuthed(ply, steamid, uniqueid)
|
||||
if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Player '"..ply:GetName().."' (SteamID: "..ply:SteamID()..") authenticated.") end
|
||||
print("Prop Hunt: Player '"..ply:GetName().."' (SteamID: "..ply:SteamID()..") authenticated.")
|
||||
end
|
||||
|
||||
-- Player Disconnected
|
||||
function GM:PlayerDisconnected(ply)
|
||||
if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Player '"..ply:GetName().."' (SteamID: "..ply:SteamID()..") disconnected.") end
|
||||
print("Prop Hunt: Player '"..ply:GetName().."' (SteamID: "..ply:SteamID()..") disconnected.")
|
||||
end
|
||||
|
||||
-- Player Spawn (Initial)
|
||||
function GM:PlayerInitialSpawn(ply)
|
||||
if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Player '"..ply:GetName().."' (SteamID: "..ply:SteamID()..") spawned for the first time, applying defaults...") end
|
||||
print("Prop Hunt: Player '"..ply:GetName().."' (SteamID: "..ply:SteamID()..") spawned for the first time, applying defaults...")
|
||||
|
||||
if (!ply.Data) then
|
||||
-- Initialize Data Structure
|
||||
ply.Data = {}
|
||||
ply.Data.Alive = false
|
||||
ply.Data.AliveTime = 0
|
||||
ply.Data.RandomWeight = 0 -- Higher means higher chance of becoming Seeker instead of Hider.
|
||||
end
|
||||
|
||||
-- Kill Silently
|
||||
@@ -135,10 +121,10 @@ function GM:PlayerInitialSpawn(ply)
|
||||
-- Bot: Auto Assign to Team
|
||||
if (ply:IsBot()) then
|
||||
if team.NumPlayers(self.Teams.Hiders) > team.NumPlayers(self.Teams.Seekers) then
|
||||
if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Bot '"..ply:GetName().."' assigned to Seekers.") end
|
||||
print("Prop Hunt: Bot '"..ply:GetName().."' assigned to Seekers.")
|
||||
ply:SetTeam(self.Teams.Seekers)
|
||||
else
|
||||
if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Bot '"..ply:GetName().."' assigned to Hiders.") end
|
||||
print("Prop Hunt: Bot '"..ply:GetName().."' assigned to Hiders.")
|
||||
ply:SetTeam(self.Teams.Hiders)
|
||||
end
|
||||
end
|
||||
@@ -152,7 +138,7 @@ end
|
||||
|
||||
-- Player Spawn
|
||||
function GM:PlayerSpawn(ply)
|
||||
if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Player '"..ply:GetName().."' (SteamID: "..ply:SteamID()..") spawned in.") end
|
||||
print("Prop Hunt: Player '"..ply:GetName().."' (SteamID: "..ply:SteamID()..") spawned in.")
|
||||
|
||||
-- Player Manager: Assign Player Class
|
||||
local class = team.GetClass(ply:Team())
|
||||
@@ -181,7 +167,7 @@ end
|
||||
-- Player requests Team Change
|
||||
function GM:PlayerRequestTeam(ply, teamId)
|
||||
if self:PlayerCanJoinTeam(ply, teamId) then
|
||||
if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Player '"..ply:GetName().."' (SteamID: "..ply:SteamID()..") requested to join Team "..team.GetName(teamId)..".") end
|
||||
print("Prop Hunt: Player '"..ply:GetName().."' (SteamID: "..ply:SteamID()..") requested to join Team "..team.GetName(teamId)..".")
|
||||
|
||||
if (ply:Team() != teamId) then
|
||||
ply:KillSilent()
|
||||
@@ -192,7 +178,7 @@ function GM:PlayerRequestTeam(ply, teamId)
|
||||
ply.AliveTime = CurTime()
|
||||
end
|
||||
else
|
||||
if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Player '"..ply:GetName().."' (SteamID: "..ply:SteamID()..") attempted to rejoin the Team it is already in.") end
|
||||
print("Prop Hunt: Player '"..ply:GetName().."' (SteamID: "..ply:SteamID()..") attempted to rejoin the Team it is already in.")
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -201,38 +187,7 @@ end
|
||||
--! Player Manager Binding
|
||||
-- ------------------------------------------------------------------------- --
|
||||
function GM:PlayerLoadout(ply) player_manager.RunClass(ply, "Loadout") end
|
||||
function GM:PlayerDeath(ply, inflictor, attacker)
|
||||
player_manager.RunClass(ply, "Death", inflictor, attacker)
|
||||
|
||||
-- Signal Client Stuff
|
||||
if IsValid(attacker) then
|
||||
if attacker:IsPlayer() then
|
||||
if (attacker == ply) then
|
||||
net.Start("PlayerKilledSelf")
|
||||
net.WriteEntity(ply)
|
||||
net.Broadcast()
|
||||
else
|
||||
net.Start("PlayerKilledByPlayer")
|
||||
net.WriteEntity(ply)
|
||||
net.WriteString(inflictor:GetName())
|
||||
net.WriteEntity(attacker)
|
||||
net.Broadcast()
|
||||
end
|
||||
else
|
||||
net.Start("PlayerKilled")
|
||||
net.WriteEntity(ply)
|
||||
net.WriteString(inflictor:GetName())
|
||||
net.WriteString(attacker:GetClass())
|
||||
net.Broadcast()
|
||||
end
|
||||
else
|
||||
net.Start("PlayerKilled")
|
||||
net.WriteEntity(ply)
|
||||
net.WriteString(inflictor:GetName())
|
||||
net.WriteString("World")
|
||||
net.Broadcast()
|
||||
end
|
||||
end
|
||||
function GM:PlayerDeath(ply, inflictor, attacker) player_manager.RunClass(ply, "Death", inflictor, attacker) end
|
||||
function GM:PlayerSilentDeath(ply) player_manager.RunClass(ply, "SilentDeath") end
|
||||
function GM:PostPlayerDeath(ply)
|
||||
player_manager.RunClass(ply, "PostDeath")
|
||||
@@ -240,10 +195,10 @@ function GM:PostPlayerDeath(ply)
|
||||
-- Debug Mode: Respawn after Death
|
||||
if (GAMEMODE.Config:Debug()) then
|
||||
ply.Data.Alive = true
|
||||
if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Debug Mode active, Player "..ply:GetName().." was respawned.") end
|
||||
print("Prop Hunt: Debug Mode active, Player "..ply:GetName().." was respawned.")
|
||||
end
|
||||
end
|
||||
function GM:DoPlayerDeath(ply, attacker, dmg) player_manager.RunClass(ply, "DoDeath", attacker, dmg) end
|
||||
--function GM:DoPlayerDeath(ply, attacker, dmg) player_manager.RunClass(ply, "DoDeath", attacker, dmg) end
|
||||
function GM:PlayerDeathThink(ply) return player_manager.RunClass(ply, "DeathThink") end
|
||||
function GM:CanPlayerSuicide(ply) return player_manager.RunClass(ply, "CanSuicide") end
|
||||
function GM:PlayerCanPickupWeapon(ply, weapon) return player_manager.RunClass(ply, "CanPickupWeapon", weapon) end
|
||||
@@ -252,19 +207,7 @@ function GM:PlayerUse(ply, ent) return player_manager.RunClass(ply, "Use", ent)
|
||||
function GM:AllowPlayerPickup(ply, ent) return player_manager.RunClass(ply, "AllowPickup", ent) end
|
||||
function GM:PlayerSetModel(ply) return player_manager.RunClass(ply, "SetModel") end
|
||||
|
||||
-- Damage
|
||||
function GM:PlayerShouldTakeDamage(victim, attacker)
|
||||
return player_manager.RunClass(victim, "ShouldTakeDamage", attacker)
|
||||
end
|
||||
|
||||
function GM:PlayerHurt(victim, attacker, healthRemaining, damageTaken)
|
||||
player_manager.RunClass(victim, "Hurt", victim, attacker, healthRemaining, damageTaken)
|
||||
|
||||
if (IsValid(attacker) && attacker:IsPlayer()) then
|
||||
player_manager.RunClass(attacker, "Damage", victim, attacker, healthRemaining, damageTaken)
|
||||
end
|
||||
end
|
||||
|
||||
-- Called when an entity takes damage
|
||||
function GM:EntityTakeDamage(ent, dmg)
|
||||
local att = dmg:GetAttacker()
|
||||
|
||||
@@ -276,20 +219,12 @@ end
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Gamemode Functionality
|
||||
-- ------------------------------------------------------------------------- --
|
||||
function GM:SetRound(Round)
|
||||
SetGlobalInt("Round", Round)
|
||||
end
|
||||
|
||||
function GM:SetRoundTime(Time)
|
||||
SetGlobalInt("RoundTime", Time)
|
||||
end
|
||||
|
||||
function GM:SetRoundState(State)
|
||||
SetGlobalInt("RoundState", State)
|
||||
end
|
||||
|
||||
function GM:SetRoundStateTime(Time)
|
||||
SetGlobalInt("RoundStateTime", Time)
|
||||
function GM:SetRoundTime(Time)
|
||||
SetGlobalInt("RoundTime", Time)
|
||||
end
|
||||
|
||||
function GM:SetRoundWinner(Winner)
|
||||
@@ -306,7 +241,6 @@ function GM:PlayerHullFromEntity(ply, ent)
|
||||
hull.x = hull.y
|
||||
end
|
||||
hull:Mul(0.5)
|
||||
hull:Mul(0.95) -- Reduce size slightly
|
||||
|
||||
local hullmin = Vector(-hull.x, -hull.y, 0)
|
||||
local hullmax = Vector(hull.x, hull.y, hull.z * 2)
|
||||
@@ -355,73 +289,153 @@ function GM:ShowTeam(ply)
|
||||
ply:ConCommand("ph_select_team")
|
||||
end
|
||||
|
||||
function GM:ShowSpare1(ply) player_manager.RunClass(ply, "ShowSpare1") end -- F3/ShowSpare1
|
||||
function GM:ShowSpare2(ply) player_manager.RunClass(ply, "ShowSpare2") end -- F4/ShowSpare2
|
||||
-- F3/ShowSpare1
|
||||
function GM:ShowSpare1(ply) end
|
||||
|
||||
-- F4/ShowSpare2
|
||||
function GM:ShowSpare2(ply) end
|
||||
|
||||
-- Debug Command: Print All Players
|
||||
concommand.Add("ph_debug_printplayers", function(ply, cmd, args, argStr)
|
||||
if GAMEMODE.Config:DebugLog() then
|
||||
print ("All Players:")
|
||||
for i,ply in ipairs(player.GetAll()) do
|
||||
print(" "..ply:GetName().." (SteamID: "..ply:SteamID()..") - Team "..team.GetName(ply:Team()).. " - Alive "..tostring(ply.Data.Alive))
|
||||
end
|
||||
|
||||
print ("Spectators:")
|
||||
for i,ply in ipairs(team.GetPlayers(GAMEMODE.Teams.Spectators)) do
|
||||
print(" "..ply:GetName().." (SteamID: "..ply:SteamID()..")")
|
||||
end
|
||||
|
||||
print ("Seekers:")
|
||||
for i,ply in ipairs(team.GetPlayers(GAMEMODE.Teams.Seekers)) do
|
||||
print(" "..ply:GetName().." (SteamID: "..ply:SteamID()..")")
|
||||
end
|
||||
|
||||
print ("Hiders:")
|
||||
for i,ply in ipairs(team.GetPlayers(GAMEMODE.Teams.Hiders)) do
|
||||
print(" "..ply:GetName().." (SteamID: "..ply:SteamID()..")")
|
||||
end
|
||||
print ("All Players:")
|
||||
for i,ply in ipairs(player.GetAll()) do
|
||||
print(" "..ply:GetName().." (SteamID: "..ply:SteamID()..") - Team "..team.GetName(ply:Team()).. " - Alive "..tostring(ply.Data.Alive))
|
||||
end
|
||||
end, nil, nil, FCVAR_CLIENTCMD_CAN_EXECUTE + FCVAR_CHEAT)
|
||||
|
||||
-- Debug Command: Print All Players
|
||||
concommand.Add("ph_debug_stats", function(ply, cmd, args, argStr)
|
||||
if GAMEMODE.Config:DebugLog() then
|
||||
for i,ply in ipairs(player.GetAll()) do
|
||||
print(ply:GetName().." (SteamID: "..ply:SteamID()..")")
|
||||
print(" Team: "..team.GetName(ply:Team()))
|
||||
print(" Alive: "..tostring(ply.Data.Alive))
|
||||
print(" AliveTime: "..tostring(ply.Data.AliveTime))
|
||||
print(" Score: "..tostring(ply.Data.RandomWeight))
|
||||
end
|
||||
|
||||
print ("Spectators:")
|
||||
for i,ply in ipairs(team.GetPlayers(GAMEMODE.Teams.Spectators)) do
|
||||
print(" "..ply:GetName().." (SteamID: "..ply:SteamID()..")")
|
||||
end
|
||||
|
||||
print ("Seekers:")
|
||||
for i,ply in ipairs(team.GetPlayers(GAMEMODE.Teams.Seekers)) do
|
||||
print(" "..ply:GetName().." (SteamID: "..ply:SteamID()..")")
|
||||
end
|
||||
|
||||
print ("Hiders:")
|
||||
for i,ply in ipairs(team.GetPlayers(GAMEMODE.Teams.Hiders)) do
|
||||
print(" "..ply:GetName().." (SteamID: "..ply:SteamID()..")")
|
||||
end
|
||||
|
||||
end, nil, nil, FCVAR_CLIENTCMD_CAN_EXECUTE + FCVAR_CHEAT)
|
||||
|
||||
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Network Messages
|
||||
-- ------------------------------------------------------------------------- --
|
||||
net.Receive("PlayerEnablePropRotation", function(len, ply)
|
||||
if (ply:Team() != GAMEMODE.Teams.Hiders) then
|
||||
return
|
||||
end
|
||||
|
||||
angle = net.ReadAngle()
|
||||
|
||||
print("Prop Hunt: Enabling Prop Rotation")
|
||||
ply:SetNWBool("PropRotation", true)
|
||||
ply.Data.Prop:ApplyRotation(angle)
|
||||
|
||||
if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Player '"..ply:GetName().."' (SteamID: "..ply:SteamID()..") enabled prop rotation with angle ["..tostring(angle).."].") end
|
||||
end)
|
||||
net.Receive("PlayerDisablePropRotation", function(len, ply)
|
||||
if (ply:Team() != GAMEMODE.Teams.Hiders) then
|
||||
print("Prop Hunt: Disabling Prop Rotation")
|
||||
ply:SetNWBool("PropRotation", false)
|
||||
end)
|
||||
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! LEGACY CODE - TO BE REPLACED SOON
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--[[
|
||||
function AnnounceVictory(players, force)
|
||||
for i,pl in ipairs(players) do
|
||||
if pl:Alive() || force || pl:Team() == TEAM_SPECTATOR then
|
||||
announcer = table.Random(VICTORY_SOUNDS);
|
||||
print("Prop Hunt: '"..pl:GetName().."' announcing victory with '"..announcer.."'.")
|
||||
pl:EmitSound(announcer, 200, 100, 0.5, CHAN_VOICE2)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function AnnounceLoss(players, force)
|
||||
for i,pl in ipairs(players) do
|
||||
if pl:Alive() || force || pl:Team() == TEAM_SPECTATOR then
|
||||
announcer = table.Random(LOSS_SOUNDS);
|
||||
print("Prop Hunt: '"..pl:GetName().."' announcing loss with '"..announcer.."'.")
|
||||
pl:EmitSound(announcer, 100, 100, 0.5, CHAN_VOICE2)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- If there is a mapfile send it to the client (sometimes servers want to change settings for certain maps)
|
||||
if file.Exists("maps/"..game.GetMap()..".lua", "LUA") then
|
||||
AddCSLuaFile("maps/"..game.GetMap()..".lua")
|
||||
end
|
||||
|
||||
-- Send the required resources to the client
|
||||
for _, announcer in pairs(LOSS_SOUNDS) do resource.AddFile("sound/"..announcer) end
|
||||
for _, announcer in pairs(VICTORY_SOUNDS) do resource.AddFile("source/"..announcer) end
|
||||
for _, taunt in pairs(HUNTER_TAUNTS) do resource.AddFile("sound/"..taunt) end
|
||||
for _, taunt in pairs(PROP_TAUNTS) do resource.AddFile("sound/"..taunt) end
|
||||
|
||||
-- Called alot
|
||||
function GM:CheckPlayerDeathRoundEnd()
|
||||
if !GAMEMODE.RoundBased || !GAMEMODE:InRound() then
|
||||
return
|
||||
end
|
||||
|
||||
local Teams = GAMEMODE:GetTeamAliveCounts()
|
||||
|
||||
if table.Count(Teams) == 0 then
|
||||
GAMEMODE:RoundEndWithResult(1001, "Draw, everyone loses!")
|
||||
AnnounceLoss(player.GetAll(), true)
|
||||
return
|
||||
end
|
||||
|
||||
if table.Count(Teams) == 1 then
|
||||
-- Play victory and loss sounds.
|
||||
if Teams[0] == TEAM_HUNTERS then
|
||||
AnnounceVictory(team.GetPlayers(TEAM_HUNTERS))
|
||||
AnnounceLoss(team.GetPlayers(TEAM_PROPS))
|
||||
elseif Teams[0] == TEAM_PROPS then
|
||||
AnnounceLoss(team.GetPlayers(TEAM_HUNTERS))
|
||||
AnnounceVictory(team.GetPlayers(TEAM_PROPS))
|
||||
end
|
||||
|
||||
local TeamID = table.GetFirstKey(Teams)
|
||||
GAMEMODE:RoundEndWithResult(TeamID, team.GetName(TeamID).." win!")
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
-- Called when player presses [F3]. Plays a taunt for their team
|
||||
function GM:ShowSpare1(pl)
|
||||
if GAMEMODE:InRound() && pl:Alive() && (pl:Team() == TEAM_HUNTERS || pl:Team() == TEAM_PROPS) && pl.last_taunt_time + TAUNT_DELAY <= CurTime() && #PROP_TAUNTS > 1 && #HUNTER_TAUNTS > 1 then
|
||||
-- repeat
|
||||
if pl:Team() == TEAM_HUNTERS then
|
||||
rand_taunt = table.Random(HUNTER_TAUNTS)
|
||||
else
|
||||
rand_taunt = table.Random(PROP_TAUNTS)
|
||||
end
|
||||
-- until rand_taunt != pl.last_taunt
|
||||
|
||||
pl.last_taunt_time = CurTime()
|
||||
pl.last_taunt = rand_taunt
|
||||
|
||||
print("Prop Hunt: '"..pl:GetName().."' taunting with '"..rand_taunt.."'.")
|
||||
local vol = 1.0
|
||||
if pl:Team() == TEAM_HUNTERS then vol = vol * 0.5 end
|
||||
pl:EmitSound(rand_taunt, 100, 100, vol, CHAN_VOICE2)
|
||||
end
|
||||
end
|
||||
|
||||
-- Allow player to rotate the prop. (Either F4 or ducking)
|
||||
function GM:ShowSpare2(pl)
|
||||
if pl:Alive() && (pl:Team() == TEAM_PROPS) then
|
||||
pl.ph_prop:SetApplyNewAngles(!pl.ph_prop:GetApplyNewAngles())
|
||||
-- pl.ph_prop:SetNewAngles(pl:GetAngles())
|
||||
end
|
||||
end
|
||||
|
||||
-- Removes all weapons on a map
|
||||
function RemoveWeaponsAndItems()
|
||||
for _, wep in pairs(ents.FindByClass("weapon_*")) do
|
||||
wep:Remove()
|
||||
end
|
||||
|
||||
angle = net.ReadAngle()
|
||||
|
||||
ply:SetNWBool("PropRotation", false)
|
||||
ply.Data.Prop:ApplyRotation(angle)
|
||||
|
||||
if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Player '"..ply:GetName().."' (SteamID: "..ply:SteamID()..") enabled prop rotation with angle ["..tostring(angle).."].") end
|
||||
end)
|
||||
for _, item in pairs(ents.FindByClass("item_*")) do
|
||||
item:Remove()
|
||||
end
|
||||
end
|
||||
hook.Add("InitPostEntity", "PH_RemoveWeaponsAndItems", RemoveWeaponsAndItems)
|
||||
|
||||
]]
|
||||
@@ -44,15 +44,11 @@ CLASS.UseVMHands = true -- Uses viewmodel hands
|
||||
--! Server-Side
|
||||
-- ------------------------------------------------------------------------- --
|
||||
-- Spawn
|
||||
function CLASS:InitialSpawn()
|
||||
self.Player.Data = {}
|
||||
self.Player.Data.SelectionHaloTime = CurTime()
|
||||
end
|
||||
function CLASS:InitialSpawn() end
|
||||
function CLASS:Spawn() end
|
||||
function CLASS:Loadout() end
|
||||
|
||||
-- Damage
|
||||
function CLASS:ShouldTakeDamage(attacker) return true end -- Should take damage from attacker?
|
||||
function CLASS:Hurt(victim, attacker, healthRemaining, damageTaken) end -- Damage Taken
|
||||
function CLASS:Damage(victim, attacker, healthRemaining, damageDealt) end -- Damage Dealt
|
||||
function CLASS:DamageEntity(ent, attacker, dmginfo) end -- Damage Dealt To Entity
|
||||
@@ -61,21 +57,15 @@ function CLASS:DamageEntity(ent, attacker, dmginfo) end -- Damage Dealt To Entit
|
||||
function CLASS:Death(inflictor, attacker)
|
||||
self.Player.Data.Alive = false
|
||||
self.Player.Data.AliveTime = CurTime()
|
||||
-- Score support
|
||||
self.Player:AddDeaths(1)
|
||||
if IsValid(attacker) && attacker:IsPlayer() then
|
||||
if ((attacker == self.Player)
|
||||
|| (attacker:Team() == self.Player:Team())) then
|
||||
self.Player:AddFrags(-1)
|
||||
end
|
||||
end
|
||||
end
|
||||
function CLASS:SilentDeath()
|
||||
self.Player.Data.Alive = false
|
||||
self.Player.Data.AliveTime = CurTime()
|
||||
end
|
||||
function CLASS:PostDeath() end
|
||||
|
||||
function CLASS:DoDeath() end
|
||||
|
||||
function CLASS:DeathThink()
|
||||
if (CurTime() - self.Player.Data.AliveTime) > 5 then
|
||||
self.Player:Spawn()
|
||||
@@ -83,6 +73,7 @@ function CLASS:DeathThink()
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function CLASS:CanSuicide() return true end
|
||||
|
||||
-- Visible Stuff
|
||||
@@ -91,14 +82,14 @@ function CLASS:SetModel() BaseClass.SetModel( self ) end
|
||||
-- Interaction
|
||||
function CLASS:Use(ent)
|
||||
-- Entity must be valid and not a player.
|
||||
if (!ent || !ent:IsValid()) then
|
||||
if (!ent) || (!ent:IsValid()) || (ent:IsPlayer()) then
|
||||
return false
|
||||
end
|
||||
|
||||
-- Cool Down
|
||||
if (self.Player.Data.UseTime) then
|
||||
local timeSinceUse = (CurTime() - self.Player.Data.UseTime)
|
||||
if (0.5 > timeSinceUse) then
|
||||
if (0.2 > timeSinceUse) then
|
||||
return false
|
||||
end
|
||||
|
||||
@@ -118,23 +109,11 @@ function CLASS:AllowPickup(ent) return false end
|
||||
function CLASS:CanPickupWeapon(ent) return false end
|
||||
function CLASS:CanPickupItem(ent) return false end
|
||||
|
||||
-- Menu (Always Server)
|
||||
function CLASS:ShowSpare1()
|
||||
local lastTaunt = (self.Player.Data.LastTaunt or 0)
|
||||
if ((CurTime() - lastTaunt) <= GAMEMODE.Config.Taunt:Cooldown()) then
|
||||
return true
|
||||
end
|
||||
self.Player.Data.LastTaunt = CurTime()
|
||||
end
|
||||
function CLASS:ShowSpare2() end
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Shared
|
||||
-- ------------------------------------------------------------------------- --
|
||||
function CLASS:PostThink() end
|
||||
function CLASS:Tick(mv) end
|
||||
function CLASS:FindUseEntity(defEnt) return defEnt end
|
||||
function CLASS:Alive() return false end
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Client-Side
|
||||
@@ -150,60 +129,91 @@ function CLASS:ClientSpawn() end
|
||||
function CLASS:GetHandsModel() return BaseClass.GetHandsModel(self) end
|
||||
function CLASS:ShouldDrawLocal() return false end
|
||||
function CLASS:HUDPaint()
|
||||
-- Death Notices
|
||||
GAMEMODE:DrawDeathNotice((ScrW() - 192) / ScrW() , 24 / ScrH())
|
||||
end
|
||||
function CLASS:CalcView(camdata)
|
||||
-- Config
|
||||
local cameraCollision = GAMEMODE.Config.Camera:Collisions()
|
||||
local cameraDistance = GAMEMODE.Config.Camera:Distance()
|
||||
local cameraDistanceRight = GAMEMODE.Config.Camera:DistanceRight()
|
||||
local cameraDistanceUp = GAMEMODE.Config.Camera:DistanceUp()
|
||||
local cameraLag = GAMEMODE.Config.Camera:Lag()
|
||||
local cameraLagInv = 1 - cameraLag
|
||||
local State = GetGlobalInt("RoundState", GAMEMODE.States.PreMatch)
|
||||
|
||||
-- First/Third Person Target Distance
|
||||
local targetDistance = 0
|
||||
if (self.Player.Data.ThirdPerson) then -- Incremental Distance instead of instant.
|
||||
targetDistance = cameraDistance
|
||||
-- Show Status at the top center
|
||||
local statusX, statusY, statusW, statusH
|
||||
statusW = 192
|
||||
statusH = 64
|
||||
statusX = ScrW() / 2 - statusW / 2
|
||||
statusY = 16
|
||||
|
||||
-- Status
|
||||
if (State == GAMEMODE.States.PreMatch) then -- Pre Match
|
||||
draw.RoundedBox(16, statusX, statusY, statusW, statusH, Color(0, 0, 0, 204))
|
||||
surface.SetFont( "Trebuchet24" )
|
||||
surface.SetTextColor( 255, 255, 255, 255 )
|
||||
local w,h = surface.GetTextSize("Waiting for Players")
|
||||
surface.SetTextPos( statusX + statusW/2 - w / 2, statusY + statusH/2 - h / 2)
|
||||
surface.DrawText("Waiting for Players")
|
||||
elseif (State == GAMEMODE.States.PreRound) then -- Pre Round
|
||||
draw.RoundedBox(16, statusX, statusY, statusW, statusH, Color(0, 0, 0, 204))
|
||||
surface.SetFont( "Trebuchet24" )
|
||||
surface.SetTextColor( 255, 255, 255, 255 )
|
||||
local w,h = surface.GetTextSize("Preparing...")
|
||||
surface.SetTextPos( statusX + statusW/2 - w / 2, statusY + statusH/2 - h / 2)
|
||||
surface.DrawText( "Preparing..." )
|
||||
elseif (State == GAMEMODE.States.Hide) then -- Hide
|
||||
local strTime = tostring(math.ceil(GetGlobalInt("RoundTime")))
|
||||
|
||||
if (cameraCollision == true) then
|
||||
-- Trace from Player to would-be camera position
|
||||
local trace = {
|
||||
start = camdata.origin,
|
||||
endpos = camdata.origin - (camdata.angles:Forward() * cameraDistance),
|
||||
--filter = { "worldspawn", "ph_prop", "player" },
|
||||
--[-[
|
||||
filter = function(ent)
|
||||
local filter = { "worldspawn", "ph_prop", "player" }
|
||||
|
||||
if (ent:IsPlayer())
|
||||
|| (table.HasValue(filter, ent:GetClass()))
|
||||
|| (ent == LocalPlayer()) || (ent == LocalPlayer():GetHands()) then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end,
|
||||
--]]
|
||||
}
|
||||
local result = util.TraceLine(trace)
|
||||
|
||||
-- The Camera has a Sphere radius of 10.
|
||||
if (result.Hit) then -- Configurable?
|
||||
targetDistance = math.Clamp(result.HitPos:Distance(camdata.origin), 0, cameraDistance)
|
||||
end
|
||||
-- Show Status at the top center
|
||||
draw.RoundedBox(16, statusX, statusY, statusW, statusH, Color(0, 0, 0, 204))
|
||||
surface.SetTextColor(255,255,255,255)
|
||||
surface.SetFont("Trebuchet18")
|
||||
local w,h = surface.GetTextSize("Seekers unblinded in:")
|
||||
surface.SetTextPos(statusX + statusW/2 - w / 2, statusY + statusH/4 - h / 2)
|
||||
surface.DrawText("Seekers unblinded in:")
|
||||
|
||||
surface.SetFont( "Trebuchet24" )
|
||||
local w,h = surface.GetTextSize(strTime.." Seconds!")
|
||||
surface.SetTextPos( statusX + statusW/2 - w / 2, statusY + statusH/1.5 - h / 2)
|
||||
surface.DrawText(strTime.." Seconds!")
|
||||
elseif (State == GAMEMODE.States.Seek) then -- Seek
|
||||
local intTime = math.ceil(GetGlobalInt("RoundTime"))
|
||||
local strTime = string.format("%d:%02d", math.floor(intTime / 60), math.ceil(intTime % 60))
|
||||
|
||||
-- Show Status at the top center
|
||||
draw.RoundedBox(16, statusX, statusY, statusW, statusH, Color(0, 0, 0, 204))
|
||||
surface.SetTextColor(255,255,255,255)
|
||||
surface.SetFont("Trebuchet18")
|
||||
local w,h = surface.GetTextSize("Hunting Time!")
|
||||
surface.SetTextPos(statusX + statusW/2 - w / 2, statusY + statusH/4 - h / 2)
|
||||
surface.DrawText("Hunting Time!")
|
||||
|
||||
surface.SetFont( "Trebuchet24" )
|
||||
local w,h = surface.GetTextSize(strTime)
|
||||
surface.SetTextPos( statusX + statusW/2 - w / 2, statusY + statusH/1.5 - h / 2)
|
||||
surface.DrawText(strTime)
|
||||
|
||||
elseif (State == GAMEMODE.States.PostRound) then -- Post Round
|
||||
-- Show Status at the top center
|
||||
draw.RoundedBox(16, statusX, statusY, statusW, statusH, Color(0, 0, 0, 204))
|
||||
surface.SetTextColor(255,255,255,255)
|
||||
surface.SetFont("Trebuchet18")
|
||||
local w,h = surface.GetTextSize("Match Result")
|
||||
surface.SetTextPos(statusX + statusW/2 - w / 2, statusY + statusH/4 - h / 2)
|
||||
surface.DrawText("Match Result")
|
||||
|
||||
local victor = GAMEMODE:GetRoundWinner()
|
||||
local victorName = "Unknown"
|
||||
if (victor == GAMEMODE.Teams.Spectator) then
|
||||
victorName = "Draw"
|
||||
elseif (victor == GAMEMODE.Teams.Hiders) then
|
||||
victorName = "Hiders Win"
|
||||
elseif (victor == GAMEMODE.Teams.Seekers) then
|
||||
victorName = "Seekers Win"
|
||||
end
|
||||
else
|
||||
targetDistance = 0
|
||||
surface.SetTextColor(team.GetColor(victor))
|
||||
|
||||
surface.SetFont( "Trebuchet24" )
|
||||
local w,h = surface.GetTextSize(victorName)
|
||||
surface.SetTextPos( statusX + statusW/2 - w / 2, statusY + statusH/1.5 - h / 2)
|
||||
surface.DrawText(victorName)
|
||||
elseif (State == GAMEMODE.States.PostMatch) then -- Post Match
|
||||
|
||||
end
|
||||
|
||||
-- Fade between Target and Current Distance
|
||||
self.Player.Data.ViewDistance = math.Clamp(((self.Player.Data.ViewDistance or targetDistance) * cameraLag) + (targetDistance * cameraLagInv), 0, GAMEMODE.Config.Camera:DistanceMax())
|
||||
|
||||
-- Adjust CamData and return
|
||||
camdata.origin = camdata.origin - (camdata.angles:Forward() * math.Clamp(self.Player.Data.ViewDistance - 10, 0, self.Player.Data.ViewDistance)) + (camdata.angles:Right() * cameraDistanceRight) + (camdata.angles:Up() * cameraDistanceUp)
|
||||
return camdata
|
||||
end
|
||||
function CLASS:CalcView(camdata) return camdata end
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Register
|
||||
@@ -35,38 +35,32 @@ CLASS.UseVMHands = false -- Uses viewmodel hands
|
||||
-- ------------------------------------------------------------------------- --
|
||||
-- Spawn
|
||||
function CLASS:Spawn()
|
||||
if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Hider '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") spawned.") end
|
||||
print("Prop Hunt: Hider '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") spawned.")
|
||||
BaseClass.Spawn(self, self.Player)
|
||||
|
||||
|
||||
-- Sprinting
|
||||
if (!GAMEMODE.Config:Sprinting()) then
|
||||
self.Player:SetRunSpeed(self.WalkSpeed)
|
||||
end
|
||||
|
||||
-- Settings
|
||||
self.Player:SetMaxHealth(GAMEMODE.Config.Hider:HealthMax())
|
||||
self.Player:SetHealth(GAMEMODE.Config.Hider:Health())
|
||||
self.Player:SetRenderMode(RENDERMODE_TRANSALPHA)
|
||||
self.Player:SetColor(Color(0,0,0,0))
|
||||
|
||||
-- Speed and Jump Power
|
||||
self.Player:SetWalkSpeed(GAMEMODE.Config.Hider:WalkSpeed())
|
||||
if (GAMEMODE.Config.Hider:Sprint()) then
|
||||
self.Player:SetRunSpeed(GAMEMODE.Config.Hider:SprintSpeed())
|
||||
else
|
||||
self.Player:SetRunSpeed(GAMEMODE.Config.Hider:WalkSpeed())
|
||||
end
|
||||
self.Player:SetJumpPower(GAMEMODE.Config.Hider:JumpPower())
|
||||
|
||||
-- Hull & View Offset
|
||||
GAMEMODE:PlayerHullFromEntity(self.Player, nil)
|
||||
GAMEMODE:PlayerSetViewOffset(self.Player, Vector(0,0,72), Vector(0,0,72))
|
||||
|
||||
-- Collision Group
|
||||
self.Player:SetCollisionGroup(COLLISION_GROUP_PLAYER)
|
||||
self.Player:SetSolid(SOLID_VPHYSICS)
|
||||
|
||||
-- Prop Stuff
|
||||
self.Player.Data.Prop = ents.Create("ph_prop")
|
||||
self.Player.Data.Prop:SetOwner(self.Player)
|
||||
self.Player.Data.Prop:Spawn()
|
||||
self.Player:DeleteOnRemove(self.Player.Data.Prop)
|
||||
self.Player.Data.PropContraint = constraint.NoCollide(self.Player, self.Player.Data.Prop, 0, 0)
|
||||
|
||||
-- Assign Hands (Auto Networked Sync!)
|
||||
local oldhands = self.Player:GetHands()
|
||||
@@ -75,35 +69,11 @@ function CLASS:Spawn()
|
||||
end
|
||||
|
||||
-- Death
|
||||
function CLASS:DoDeath(attacker, dmginfo)
|
||||
BaseClass.DoDeath(self, attacker, dmginfo)
|
||||
if GAMEMODE.Config:DebugLog() then
|
||||
if (IsValid(attacker) && attacker:IsPlayer() && attacker != self.Player) then
|
||||
print("Prop Hunt: Hider '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") killed by '"..attacker:GetName().."' (SteamID: "..attacker:SteamID()..").")
|
||||
end
|
||||
end
|
||||
|
||||
if (!IsValid(attacker)) then return end
|
||||
if (!attacker:IsPlayer()) then return end
|
||||
if (attacker:Team() == self.Player:Team()) then return end
|
||||
if (attacker:Team() == GAMEMODE.Teams.Seekers) then
|
||||
if GAMEMODE.Config:DebugLog() then
|
||||
print("Prop Hunt: Seeker '"..attacker:GetName().."' (SteamID: "..attacker:SteamID()..") gained "..GAMEMODE.Config.Seeker:HealthBonus().." health for killing Hider '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..").")
|
||||
end
|
||||
local newhealth = attacker:Health() + GAMEMODE.Config.Seeker:HealthBonus()
|
||||
if (newhealth > attacker:GetMaxHealth()) then newhealth = attacker:GetMaxHealth() end
|
||||
attacker:SetHealth(newhealth)
|
||||
end
|
||||
end
|
||||
|
||||
function CLASS:PostDeath()
|
||||
if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Hider '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") died.") end
|
||||
function CLASS:PostDeath(attacker, dmginfo)
|
||||
print("Prop Hunt: Hider '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") died.")
|
||||
BaseClass.PostDeath(self, inflictor, attacker)
|
||||
|
||||
-- Delete Hands Model
|
||||
if IsValid(self.Player.Data.PropConstraint) then
|
||||
self.Player.Data.PropConstraint:Remove()
|
||||
end
|
||||
if IsValid(self.Player:GetHands()) then
|
||||
self.Player:GetHands():Remove()
|
||||
end
|
||||
@@ -136,9 +106,7 @@ function CLASS:DeathThink()
|
||||
end
|
||||
|
||||
-- Visible Stuff
|
||||
function CLASS:SetModel()
|
||||
self.Player:SetModel("models/Gibs/Antlion_gib_small_3.mdl")
|
||||
end
|
||||
function CLASS:SetModel() self.Player:SetModel("models/Gibs/Antlion_gib_small_3.mdl") end -- does "" even work?
|
||||
|
||||
-- Interaction
|
||||
function CLASS:Use(ent)
|
||||
@@ -147,17 +115,16 @@ function CLASS:Use(ent)
|
||||
end
|
||||
|
||||
-- Allow interacting while crouched instead of turning into the prop.
|
||||
if (self.Player:Crouching()) then
|
||||
if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Hider '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") interacted with "..ent:GetClass().." ("..ent:GetModel()..").") end
|
||||
if (self.Player:Crouching()) then
|
||||
return true
|
||||
end
|
||||
|
||||
-- Check Lists and other Parameters
|
||||
if (!table.HasValue(GAMEMODE.Config.Lists:ClassWhitelist(), ent:GetClass())) -- Class is not Whitelisted
|
||||
|| (table.HasValue(GAMEMODE.Config.Lists:ModelBlacklist(), ent:GetModel())) -- Model is Blacklisted
|
||||
|| !((ent:GetPhysicsObject()) && (ent:GetPhysicsObject():IsValid())) -- Entity doesn't have Physics
|
||||
if (!table.HasValue(GAMEMODE.Config.Lists:ClassWhitelist(), ent:GetClass()))-- Class is not Whitelisted
|
||||
|| (GAMEMODE.Config.Lists.ModelBlacklist[ent:GetModel()]) -- Model is Blacklisted
|
||||
|| !((ent:GetPhysicsObject()) && (ent:GetPhysicsObject():IsValid())) -- Entity doesn't have Physics
|
||||
then
|
||||
if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Hider '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") attempted to turn into "..ent:GetClass().." ("..ent:GetModel()..").") end
|
||||
print("Prop Hunt: Hider '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") attempted to turn into "..ent:GetClass().." ("..ent:GetModel()..").")
|
||||
return true -- Use instead of erroring.
|
||||
end
|
||||
|
||||
@@ -188,77 +155,84 @@ function CLASS:Use(ent)
|
||||
self.Player:SetMaxHealth(maxhealth)
|
||||
end
|
||||
|
||||
if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Hider '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") turned into "..ent:GetClass().." ("..ent:GetModel()..").") end
|
||||
print("Prop Hunt: Hider '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") turned into "..ent:GetClass().." ("..ent:GetModel()..").")
|
||||
end
|
||||
|
||||
function CLASS:AllowPickup(ent) return true end
|
||||
|
||||
-- Menu Buttons
|
||||
function CLASS:ShowSpare1()
|
||||
if BaseClass.ShowSpare1(self) then return end
|
||||
|
||||
-- Play a taunt
|
||||
local tauntList = GAMEMODE.Config.Taunt:Hiders()
|
||||
local index = math.random(#tauntList)
|
||||
self.Player:EmitSound(tauntList[index], SNDLVL_NORM, 100, 1, CHAN_VOICE)
|
||||
if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Hider '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") taunted with sound '"..tauntList[index].."'.") end
|
||||
end
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Shared
|
||||
-- ------------------------------------------------------------------------- --
|
||||
if SERVER then
|
||||
function CLASS:FindUseEntity(defEnt)
|
||||
return self.Player:FindUseEntity()
|
||||
end
|
||||
|
||||
function CLASS:Tick(mv)
|
||||
if (self.Player.Data == nil) then return end
|
||||
|
||||
-- Selection Halo
|
||||
if (GAMEMODE.Config.SelectionHalo:Allow()) && (!GAMEMODE.Config.SelectionHalo:Approximate()) then
|
||||
if (self.Player.Data.SelectionHaloTime == nil) then
|
||||
self.Player.Data.SelectionHaloTime = CurTime()
|
||||
elseif ((CurTime() - self.Player.Data.SelectionHaloTime) > GAMEMODE.Config.SelectionHalo:Interval()) then
|
||||
self.Player.Data.SelectionHaloTime = CurTime()
|
||||
local ent = self.Player:FindUseEntity()
|
||||
if (IsValid(ent)
|
||||
&& table.HasValue(GAMEMODE.Config.Lists:ClassWhitelist(), ent:GetClass())
|
||||
&& !table.HasValue(GAMEMODE.Config.Lists:ModelBlacklist(), ent:GetModel())) then
|
||||
self.Player:SetNWEntity("SelectionHalo", ent)
|
||||
else
|
||||
self.Player:SetNWBool("SelectionHalo", false)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
function CLASS:Alive() return true end
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Client-Side
|
||||
-- ------------------------------------------------------------------------- --
|
||||
function CLASS:ClientSpawn()
|
||||
if GAMEMODE.Config:DebugLog() then print("Prop Hunt CL: Hider '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") spawned.") end
|
||||
print("Prop Hunt CL: Hider '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") spawned.")
|
||||
BaseClass.ClientSpawn(self, self.Player)
|
||||
|
||||
self.Player:SetRenderMode(RENDERMODE_TRANSALPHA)
|
||||
end
|
||||
|
||||
function CLASS:ShouldDrawLocal()
|
||||
if (self.Player.Data.ViewDistance or 0) >= 10 then
|
||||
return false
|
||||
end
|
||||
|
||||
function CLASS:CalcView(camdata)
|
||||
-- ThirdPerson Settings (ToDo: client config maybe?)
|
||||
local maxViewDist = 100
|
||||
local viewDist = self.Player.Data.ViewDistance or 0
|
||||
|
||||
-- First/Third
|
||||
if (self.Player.Data.ThirdPerson) then
|
||||
if (IsValid(self.Player:GetHands())) then
|
||||
self.Player:GetHands():SetRenderMode(RENDERMODE_TRANSALPHA)
|
||||
self.Player:GetHands():SetColor(Color(255, 255, 255, 127))
|
||||
end
|
||||
|
||||
-- Incremental Distance instead of instant.
|
||||
viewDist = math.Clamp(viewDist * 0.95 + maxViewDist * 0.05, 0, maxViewDist) -- Zoom Out
|
||||
else
|
||||
if (IsValid(self.Player:GetHands())) then
|
||||
self.Player:GetHands():SetRenderMode(RENDERMODE_TRANSALPHA)
|
||||
self.Player:GetHands():SetColor(Color(255, 255, 255, 0))
|
||||
end
|
||||
|
||||
viewDist = math.Clamp(viewDist * 0.95, 0, maxViewDist) -- Zoom In
|
||||
end
|
||||
|
||||
return (self.Player.Data.ViewDistance or 0) >= 10
|
||||
-- Trace from Player to would-be camera position
|
||||
local trace = {
|
||||
start = camdata.origin,
|
||||
endpos = camdata.origin - (camdata.angles:Forward() * viewDist),
|
||||
--filter = { "worldspawn", "ph_prop" },
|
||||
filter = function(ent)
|
||||
local filter = { "worldspawn", "ph_prop" }
|
||||
|
||||
if (ent:IsPlayer())
|
||||
|| (table.HasValue(filter, ent:GetClass()))
|
||||
|| (ent == LocalPlayer()) || (ent == LocalPlayer():GetHands()) then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
}
|
||||
local result = util.TraceLine(trace)
|
||||
|
||||
-- The Camera has a Sphere radius of 10.
|
||||
if (result.Hit) then -- Configurable?
|
||||
viewDist = math.Clamp(result.HitPos:Distance(camdata.origin), 0, maxViewDist)
|
||||
end
|
||||
|
||||
-- Store ViewDistance
|
||||
self.Player.Data.ViewDistance = viewDist
|
||||
|
||||
-- Adjust CamData
|
||||
camdata.origin = camdata.origin - (camdata.angles:Forward() * math.Clamp(viewDist - 10, 0, maxViewDist))
|
||||
camdata.drawviewer = false
|
||||
|
||||
-- Return
|
||||
return camdata
|
||||
end
|
||||
|
||||
-- Register
|
||||
@@ -44,24 +44,20 @@ CLASS.DropWeaponOnDie = true
|
||||
-- ------------------------------------------------------------------------- --
|
||||
-- Spawn
|
||||
function CLASS:Spawn()
|
||||
if (GAMEMODE.Config:DebugLog()) then print("Prop Hunt: Seeker '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") spawned.") end
|
||||
print("Prop Hunt: Seeker '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") spawned.")
|
||||
BaseClass.Spawn(self)
|
||||
|
||||
|
||||
-- Sprinting
|
||||
if (GAMEMODE.Config:Sprinting()) then
|
||||
self.Player:SetRunSpeed(self.WalkSpeed)
|
||||
end
|
||||
|
||||
-- Settings
|
||||
self.Player:SetMaxHealth(GAMEMODE.Config.Seeker:HealthMax())
|
||||
self.Player:SetHealth(GAMEMODE.Config.Seeker:Health())
|
||||
self.Player:SetRenderMode(RENDERMODE_NORMAL)
|
||||
self.Player:SetColor(Color(255,255,255,255))
|
||||
|
||||
-- Speed and Jump Power
|
||||
self.Player:SetWalkSpeed(GAMEMODE.Config.Seeker:WalkSpeed())
|
||||
if (GAMEMODE.Config.Seeker:Sprint()) then
|
||||
self.Player:SetRunSpeed(GAMEMODE.Config.Seeker:SprintSpeed())
|
||||
else
|
||||
self.Player:SetRunSpeed(GAMEMODE.Config.Seeker:WalkSpeed())
|
||||
end
|
||||
self.Player:SetJumpPower(GAMEMODE.Config.Seeker:JumpPower())
|
||||
|
||||
-- Hull & View Offset
|
||||
GAMEMODE:PlayerHullFromEntity(self.Player, nil)
|
||||
GAMEMODE:PlayerSetViewOffset(self.Player, Vector(0,0,64), Vector(0,0,32))
|
||||
@@ -89,79 +85,32 @@ function CLASS:Loadout()
|
||||
end
|
||||
|
||||
-- Damage
|
||||
function CLASS:ShouldTakeDamage(attacker)
|
||||
if (IsValid(attacker)) then
|
||||
if (attacker:IsPlayer()) then
|
||||
if (attacker:Team() == self.Player:Team()) then
|
||||
local ffmode = GetConVarNumber("mp_friendlyfire")
|
||||
if (ffmode == 0) then -- Not Allowed
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function CLASS:Damage(victim, attacker, healthRemaining, damageDealt)
|
||||
if ((victim != attacker) && victim:IsPlayer() && attacker:IsPlayer() && (attacker:Team() == victim:Team())) then
|
||||
if (GAMEMODE.Config:DebugLog()) then
|
||||
print("Prop Hunt: Seeker '"..attacker:GetName().."' (SteamID: "..attacker:SteamID()..") damaged seeker '"..victim:GetName().."' (SteamID: "..victim:SteamID()..") with "..damageDealt.." damage.")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function CLASS:Hurt(victim, attacker, healthRemaining, damageTaken)
|
||||
if ((victim != attacker) && victim:IsPlayer() && attacker:IsPlayer() && (attacker:Team() == victim:Team())) then
|
||||
if (GAMEMODE.Config:DebugLog()) then
|
||||
print("Prop Hunt: Seeker '"..victim:GetName().."' (SteamID: "..victim:SteamID()..") was hurt by seeker '"..attacker:GetName().."' (SteamID: "..attacker:SteamID()..") with "..damageTaken.." damage.")
|
||||
end
|
||||
|
||||
if (GetConVarNumber("mp_friendlyfire") == 2) then
|
||||
victim:SetHealth(healthRemaining + damageTaken)
|
||||
attacker:TakeDamage(damageTaken, attacker, attacker)
|
||||
print("Prop Hunt: Seeker '"..victim:GetName().."' (SteamID: "..victim:SteamID()..") reflected "..damageTaken.." to seeker '"..attacker:GetName().."' (SteamID: "..attacker:SteamID()..").")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function CLASS:Damage(victim, attacker, healthRemaining, damageDealt) end
|
||||
function CLASS:DamageEntity(ent, att, dmg)
|
||||
if (GAMEMODE.Config:DebugLog()) then print("Prop Hunt: Seeker '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") damaged entity "..ent:GetClass()..".") end
|
||||
|
||||
if (GAMEMODE:GetRoundState() != GAMEMODE.States.Seek) then return end
|
||||
if (!IsValid(ent) || !IsValid(att)) then return end
|
||||
if (att == ent) then return end
|
||||
print("Prop Hunt: Seeker '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") damaged entity "..ent:GetClass()..".")
|
||||
|
||||
-- Only take damage during this phase.
|
||||
if IsValid(ent) && (!(ent:IsPlayer())) then
|
||||
if (ent:GetClass() == "ph_prop") then
|
||||
ent:GetOwner():TakeDamageInfo(dmg)
|
||||
self.Player.Data.RandomWeight = self.Player.Data.RandomWeight - 1
|
||||
elseif (ent:GetClass() == "func_breakable") then
|
||||
elseif (ent:GetClass() == "prop_ragdoll") then
|
||||
else
|
||||
att:TakeDamage(GAMEMODE.Config.Seeker:HealthPenalty(), ent, ent)
|
||||
if (GAMEMODE:GetRoundState() == GAMEMODE.States.Seek) then
|
||||
if IsValid(ent) && (!(ent:IsPlayer())) then
|
||||
if (ent:GetClass() == "ph_prop") then
|
||||
ent:GetOwner():TakeDamageInfo(dmg)
|
||||
elseif (ent:GetClass() == "func_breakable") then -- ToDo: Make Configurable which entities don't hurt?
|
||||
else
|
||||
att:TakeDamage(GAMEMODE.Config.Seeker:HealthPenalty(), ent, ent)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Death
|
||||
function CLASS:DoDeath(attacker, dmginfo)
|
||||
BaseClass.DoDeath(self, attacker, dmginfo)
|
||||
if GAMEMODE.Config:DebugLog() then
|
||||
if (IsValid(attacker) && attacker:IsPlayer() && attacker != self.Player) then
|
||||
print("Prop Hunt: Seeker '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") killed by '"..attacker:GetName().."' (SteamID: "..attacker:SteamID()..").")
|
||||
end
|
||||
end
|
||||
function CLASS:Death(inflictor, attacker)
|
||||
BaseClass.Death(self, inflictor, attacker)
|
||||
|
||||
if SERVER then
|
||||
self.Player:SetShouldServerRagdoll(true)
|
||||
--self.Player:CreateRagdoll()
|
||||
end
|
||||
self.Player:CreateRagdoll()
|
||||
end
|
||||
|
||||
function CLASS:PostDeath()
|
||||
if (GAMEMODE.Config:DebugLog()) then print("Prop Hunt: Seeker '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") died.") end
|
||||
print("Prop Hunt: Seeker '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") died.")
|
||||
BaseClass.PostDeath(self, inflictor, attacker)
|
||||
|
||||
self.Player:UnLock()
|
||||
@@ -199,27 +148,11 @@ function CLASS:AllowPickup(ent) return true end
|
||||
function CLASS:CanPickupItem(ent) return true end
|
||||
function CLASS:CanPickupWeapon(ent) return true end
|
||||
|
||||
-- Menu Buttons
|
||||
function CLASS:ShowSpare1()
|
||||
if BaseClass.ShowSpare1(self) then return end
|
||||
|
||||
-- Play a taunt
|
||||
local tauntList = GAMEMODE.Config.Taunt:Seekers()
|
||||
local index = math.random(#tauntList)
|
||||
self.Player:EmitSound(tauntList[index], SNDLVL_NORM, 100, 1, CHAN_VOICE)
|
||||
if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Seeker '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") taunted with sound '"..tauntList[index].."'.") end
|
||||
end
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Shared
|
||||
-- ------------------------------------------------------------------------- --
|
||||
function CLASS:Alive() return true end
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Client-Side
|
||||
-- ------------------------------------------------------------------------- --
|
||||
function CLASS:ClientSpawn()
|
||||
if (GAMEMODE.Config:DebugLog()) then print("Prop Hunt CL: Seeker '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") spawned.") end
|
||||
print("Prop Hunt CL: Seeker '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") spawned.")
|
||||
BaseClass.ClientSpawn(self)
|
||||
end
|
||||
|
||||
@@ -248,7 +181,53 @@ function CLASS:HUDPaint()
|
||||
end
|
||||
|
||||
function CLASS:ShouldDrawLocal()
|
||||
return (self.Player.Data.ViewDistance or 0) >= 10
|
||||
return self.Player.Data.ThirdPerson
|
||||
end
|
||||
|
||||
function CLASS:CalcView(camdata)
|
||||
-- ThirdPerson Settings (ToDo: client config maybe?)
|
||||
local maxViewDist = 100
|
||||
local viewDist = self.Player.Data.ViewDistance or 0
|
||||
|
||||
-- First/Third
|
||||
if (self.Player.Data.ThirdPerson) then
|
||||
viewDist = math.Clamp(viewDist * 0.95 + maxViewDist * 0.05, 0, maxViewDist) -- Zoom Out
|
||||
else
|
||||
viewDist = math.Clamp(viewDist * 0.95, 0, maxViewDist) -- Zoom In
|
||||
end
|
||||
|
||||
-- Trace from Player to would-be camera position
|
||||
local trace = {
|
||||
start = camdata.origin,
|
||||
endpos = camdata.origin - (camdata.angles:Forward() * viewDist),
|
||||
--filter = { "worldspawn", "ph_prop" },
|
||||
filter = function(ent)
|
||||
local filter = { "worldspawn", "ph_prop" }
|
||||
|
||||
if (ent:IsPlayer())
|
||||
|| (table.HasValue(filter, ent:GetClass()))
|
||||
|| (ent == LocalPlayer()) || (ent == LocalPlayer():GetHands()) then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
}
|
||||
local result = util.TraceLine(trace)
|
||||
|
||||
-- The Camera has a Sphere radius of 10.
|
||||
if (result.Hit) then -- Configurable?
|
||||
viewDist = math.Clamp(result.HitPos:Distance(camdata.origin), 0, maxViewDist)
|
||||
end
|
||||
|
||||
-- Store ViewDistance
|
||||
self.Player.Data.ViewDistance = viewDist
|
||||
|
||||
-- Adjust CamData
|
||||
camdata.origin = camdata.origin - (camdata.angles:Forward() * math.Clamp(viewDist - 10, 0, maxViewDist))
|
||||
--camdata.drawviewer = false
|
||||
|
||||
-- Return
|
||||
return camdata
|
||||
end
|
||||
|
||||
-- Register
|
||||
@@ -35,7 +35,7 @@ CLASS.UseVMHands = false -- Uses viewmodel hands
|
||||
-- ------------------------------------------------------------------------- --
|
||||
-- Spawn
|
||||
function CLASS:Spawn()
|
||||
if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Spectator '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") spawned.") end
|
||||
print("Prop Hunt: Spectator '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") spawned.")
|
||||
BaseClass.Spawn(self)
|
||||
|
||||
self.Player:Spectate(OBS_MODE_ROAMING)
|
||||
@@ -48,7 +48,7 @@ end
|
||||
|
||||
-- Death
|
||||
function CLASS:PostDeath(inflictor, attacker)
|
||||
if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Spectator '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") died.") end
|
||||
print("Prop Hunt: Spectator '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") died.")
|
||||
BaseClass.PostDeath(self, inflictor, attacker)
|
||||
|
||||
self.Player:Spectate(OBS_MODE_NONE)
|
||||
@@ -77,10 +77,9 @@ function CLASS:CanPickupItem(ent) return false end
|
||||
--! Client-Side
|
||||
-- ------------------------------------------------------------------------- --
|
||||
function CLASS:ClientSpawn()
|
||||
if GAMEMODE.Config:DebugLog() then print("Prop Hunt CL: Spectator '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") spawned.") end
|
||||
print("Prop Hunt CL: Spectator '"..self.Player:GetName().."' (SteamID: "..self.Player:SteamID()..") spawned.")
|
||||
end
|
||||
|
||||
function CLASS:ShouldDrawLocal() return false end
|
||||
function CLASS:CalcView(camdata) return camdata end
|
||||
|
||||
player_manager.RegisterClass( "Spectator", CLASS, "Default")
|
||||
@@ -0,0 +1,549 @@
|
||||
--[[
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Xaymar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
--]]
|
||||
|
||||
--! Initialize configuration table.
|
||||
GM.Config = { }
|
||||
GM.Config.ConVars = {}
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Basic Settings
|
||||
-- ------------------------------------------------------------------------- --
|
||||
-- Debug Mode
|
||||
GM.Config.ConVars.Debug = CreateConVar("ph_debug", 0, FCVAR_CHEAT + FCVAR_REPLICATED)
|
||||
function GM.Config:Debug()
|
||||
return self.ConVars.Debug:GetBool()
|
||||
end
|
||||
|
||||
-- Game Mode (See sh_init.lua)
|
||||
GM.Config.ConVars.GameMode = CreateConVar("ph_gamemode", GM.Modes.Original, FCVAR_REPLICATED)
|
||||
function GM.Config:GameMode()
|
||||
return self.ConVars.GameMode:GetInt()
|
||||
end
|
||||
|
||||
-- Timelimit in minutes
|
||||
GM.Config.ConVars.TimeLimit = GetConVar("mp_timelimit")
|
||||
function GM.Config:TimeLimit()
|
||||
return self.ConVars.TimeLimit:GetFloat()
|
||||
end
|
||||
|
||||
-- Enable Sprinting?
|
||||
GM.Config.ConVars.Sprinting = CreateConVar("ph_sprinting", 0, FCVAR_REPLICATED)
|
||||
function GM.Config:Sprinting()
|
||||
return self.ConVars.Sprinting:GetBool()
|
||||
end
|
||||
|
||||
-- Taunt Cooldown (Seconds)
|
||||
GM.Config.ConVars.TauntCoolDown = CreateConVar("ph_tauntcooldown", 5, FCVAR_REPLICATED)
|
||||
function GM.Config:TauntCoolDown()
|
||||
return self.ConVars.TauntCoolDown:GetFloat()
|
||||
end
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Round Settings
|
||||
-- ------------------------------------------------------------------------- --
|
||||
GM.Config.Round = {}
|
||||
GM.Config.Round.ConVars = {}
|
||||
|
||||
-- How many rounds should the gamemode attempt to fit into the map timelimit, if there is any?
|
||||
GM.Config.Round.ConVars.Amount = CreateConVar("ph_round_limit", 10, FCVAR_REPLICATED)
|
||||
function GM.Config.Round:Amount()
|
||||
return self.ConVars.Amount:GetInt()
|
||||
end
|
||||
|
||||
-- Round Time Limit (Seconds, Default 3 minutes)
|
||||
GM.Config.Round.ConVars.Time = CreateConVar("ph_round_timelimit", 180, FCVAR_REPLICATED)
|
||||
function GM.Config.Round:Time()
|
||||
return self.ConVars.Time:GetInt() - GAMEMODE.Config.Round:BlindTime()
|
||||
end
|
||||
|
||||
-- For how many seconds are the Seekers blinded? (Seconds)
|
||||
GM.Config.Round.ConVars.BlindTime = CreateConVar("ph_round_blindtime", 30, FCVAR_REPLICATED, "How long are hunters blinded? (positive values will be inside the round time limit, negative will add to the round time limit)")
|
||||
function GM.Config.Round:BlindTime()
|
||||
return self.ConVars.BlindTime:GetInt()
|
||||
end
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Seeker Settings
|
||||
-- ------------------------------------------------------------------------- --
|
||||
GM.Config.Seeker = {}
|
||||
GM.Config.Seeker.ConVars = {}
|
||||
|
||||
GM.Config.Seeker.ConVars.Health = CreateConVar("ph_seeker_health", 100, FCVAR_REPLICATED)
|
||||
function GM.Config.Seeker:Health()
|
||||
return self.ConVars.Health:GetInt()
|
||||
end
|
||||
|
||||
GM.Config.Seeker.ConVars.HealthMax = CreateConVar("ph_seeker_health_max", 100, FCVAR_REPLICATED)
|
||||
function GM.Config.Seeker:HealthMax()
|
||||
return self.ConVars.HealthMax:GetInt()
|
||||
end
|
||||
|
||||
GM.Config.Seeker.ConVars.HealthBonus = CreateConVar("ph_seeker_health_bonus", 20, FCVAR_REPLICATED)
|
||||
function GM.Config.Seeker:HealthBonus()
|
||||
return self.ConVars.HealthBonus:GetInt()
|
||||
end
|
||||
|
||||
GM.Config.Seeker.ConVars.HealthPenalty = CreateConVar("ph_seeker_health_penalty", 5, FCVAR_REPLICATED)
|
||||
function GM.Config.Seeker:HealthPenalty()
|
||||
return self.ConVars.HealthPenalty:GetInt()
|
||||
end
|
||||
|
||||
GM.Config.Seeker.ConVars.Weapons = CreateConVar("ph_seeker_weapons", "weapon_crowbar,weapon_pistol,weapon_ph_smg,weapon_shotgun", FCVAR_REPLICATED)
|
||||
function GM.Config.Seeker:Weapons()
|
||||
return string.Split(self.ConVars.Weapons:GetString(), ",")
|
||||
end
|
||||
|
||||
GM.Config.Seeker.ConVars.Ammo = CreateConVar("ph_seeker_ammo", "Pistol:100,SMG1:300,SMG1_Grenade:1,Buckshot:64", FCVAR_REPLICATED)
|
||||
function GM.Config.Seeker:Ammo()
|
||||
return string.Split(self.ConVars.Ammo:GetString(), ",")
|
||||
end
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Hider Settings
|
||||
-- ------------------------------------------------------------------------- --
|
||||
GM.Config.Hider = {}
|
||||
GM.Config.Hider.ConVars = {}
|
||||
|
||||
GM.Config.Hider.ConVars.Health = CreateConVar("ph_hider_health", 100, FCVAR_REPLICATED)
|
||||
function GM.Config.Hider:Health()
|
||||
return self.ConVars.Health:GetInt()
|
||||
end
|
||||
|
||||
GM.Config.Hider.ConVars.HealthMax = CreateConVar("ph_hider_health_max", 100, FCVAR_REPLICATED)
|
||||
function GM.Config.Hider:HealthMax()
|
||||
return self.ConVars.HealthMax:GetInt()
|
||||
end
|
||||
|
||||
GM.Config.Hider.ConVars.HealthScaling = CreateConVar("ph_hider_health_scaling", 100, FCVAR_REPLICATED)
|
||||
function GM.Config.Hider:HealthScaling()
|
||||
return self.ConVars.HealthScaling:GetBool()
|
||||
end
|
||||
|
||||
GM.Config.Hider.ConVars.HealthScalingMax = CreateConVar("ph_hider_health_scaling_max", 200, FCVAR_REPLICATED)
|
||||
function GM.Config.Hider:HealthScalingMax()
|
||||
return self.ConVars.HealthScalingMax:GetInt()
|
||||
end
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Whitelist & Blacklist
|
||||
-- ------------------------------------------------------------------------- --
|
||||
GM.Config.Lists = {}
|
||||
GM.Config.Lists.ConVars = {}
|
||||
GM.Config.Lists.ConCmds = {}
|
||||
|
||||
GM.Config.Lists.ConVars.ClassWhitelist = CreateConVar("ph_list_class_whitelist", "prop_physics,prop_physics_multiplayer,prop_physics_respawnable", FCVAR_REPLICATED)
|
||||
function GM.Config.Lists:ClassWhitelist()
|
||||
return string.Split(self.ConVars.ClassWhitelist:GetString(), ",")
|
||||
end
|
||||
|
||||
-- Use Abuse Blacklist
|
||||
GM.Config.Lists.ConVars.AbuseBlacklist = CreateConVar("ph_list_abuse_blacklist", "func_button,func_door,func_door_rotation,prop_door_rotation,func_tracktrain,func_tanktrain,func_breakable", FCVAR_REPLICATED)
|
||||
function GM.Config.Lists:AbuseBlacklist()
|
||||
return string.Split(self.ConVars.AbuseBlacklist:GetString(), ",")
|
||||
end
|
||||
|
||||
-- Model Blacklist
|
||||
GM.Config.Lists.ModelBlacklist = {}
|
||||
GM.Config.Lists.ModelBlacklist["models/props/cs_assault/dollar.mdl"] = true
|
||||
GM.Config.Lists.ModelBlacklist["models/props/cs_assault/money.mdl"] = true
|
||||
GM.Config.Lists.ModelBlacklist["models/props/cs_office/snowman_arm.mdl"] = true
|
||||
GM.Config.Lists.ModelBlacklist["models/props/cs_office/projector_remote.mdl"] = true
|
||||
--GM.Config.Lists.ModelBlacklist["models/props_junk/garbage_plasticbottle001a.mdl"] = true
|
||||
|
||||
GM.Config.Lists.ConCmds.ModelBlacklistList = concommand.Add("ph_list_model_blacklist_list", function(ply, cmd, args, argStr)
|
||||
print("Model Blacklist:")
|
||||
for k,v in pairs(GAMEMODE.Config.Lists.ModelBlacklist) do
|
||||
print(" "..k)
|
||||
end
|
||||
end, "List all blacklisted models.")
|
||||
|
||||
GM.Config.Lists.ConCmds.ModelBlacklistClear = concommand.Add("ph_list_model_blacklist_list", function(ply, cmd, args, argStr)
|
||||
GM.Config.Lists.ModelBlacklist = {}
|
||||
end, "Clear blacklisted models.")
|
||||
|
||||
GM.Config.Lists.ConCmds.ModelBlacklistAdd = concommand.Add("ph_list_model_blacklist_add", function(ply, cmd, args, argStr)
|
||||
if (table.count(args) > 0) then
|
||||
GAMEMODE.Config.Lists.ModelBlacklist[args[1]] = true
|
||||
else
|
||||
print("Missing model name")
|
||||
end
|
||||
end, "Add a new blacklisted model.")
|
||||
|
||||
GM.Config.Lists.ConCmds.ModelBlacklistRemove = concommand.Add("ph_list_model_blacklist_remove", function(ply, cmd, args, argStr)
|
||||
if (table.count(args) > 0) then
|
||||
GAMEMODE.Config.Lists.ModelBlacklist[args[1]] = nil
|
||||
else
|
||||
print("Missing model name")
|
||||
end
|
||||
end, "Removes a blacklisted model.")
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Taunts
|
||||
-- ------------------------------------------------------------------------- --
|
||||
-- GM.Config.Taunts = {
|
||||
-- Seeker = { },
|
||||
-- Hider = { },
|
||||
-- }
|
||||
|
||||
-- -- Taunts.Clear()
|
||||
-- --@desc: Clears the current taunt list.
|
||||
-- GM.Config.Taunts.Clear = function()
|
||||
-- this.Seeker = {}
|
||||
-- this.Hider = {}
|
||||
-- end
|
||||
|
||||
-- -- Taunts.Load(sTauntListFile)
|
||||
-- --@desc: Loads the taunt list from disk.
|
||||
-- --@param:
|
||||
-- -- sTauntListFile - A string containing the path to the taunt list to load.
|
||||
-- --@return: true or false depending on success.
|
||||
-- GM.Config.Taunts.Load = function(sTauntListFile)
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Load: Loading taunt list from file '"..sTauntListFile.."'...") end
|
||||
|
||||
-- -- Safeguard against idiots.
|
||||
-- if type(sTauntListFile) != "string" then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Load: <sTauntListFile> is not a string.") end
|
||||
-- return false
|
||||
-- end
|
||||
|
||||
-- -- Given file must exist for us to continue.
|
||||
-- if ! file.Exists(sTauntListFile, "GAME") then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Load: File not found.") end
|
||||
-- return false
|
||||
-- end
|
||||
|
||||
-- -- Read the file and check if it's empty.
|
||||
-- sTauntListData = file.Read(sTauntListFile, "GAME")
|
||||
-- if sTauntListData == "" then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Load: File is empty.") end
|
||||
-- return false
|
||||
-- end
|
||||
|
||||
-- -- Convert JSON to a table for us to use.
|
||||
-- sTauntList = util.JSONToTable(sTauntListData)
|
||||
|
||||
-- -- Is it nil? Then it's not valid JSON
|
||||
-- if sTauntList == nil then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Load: File contains invalid JSON.") end
|
||||
-- return false
|
||||
-- end
|
||||
|
||||
-- -- Finally, append the taunt lists.
|
||||
-- if sTauntList.Seeker != nil then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Load: Adding Seeker taunts...") end
|
||||
-- for k,v in pairs(sTauntList.Seeker) do
|
||||
-- GAMEMODE.Taunts.Seeker[k] = v
|
||||
-- end
|
||||
-- end
|
||||
-- if sTauntList.Hider != nil then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Load: Adding Hider taunts...") end
|
||||
-- for k,v in pairs(sTauntList.Hider) do
|
||||
-- GAMEMODE.Taunts.Hider[k] = v
|
||||
-- end
|
||||
-- end
|
||||
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Load: Complete.") end
|
||||
-- return true
|
||||
-- end
|
||||
|
||||
-- -- Taunts.Save(sTauntListFile)
|
||||
-- --@desc: Saves the current taunt list to disk.
|
||||
-- --@param:
|
||||
-- -- sTauntListFile - A string containing the path to the file to save to.
|
||||
-- --@return: true or false depending on success.
|
||||
-- GM.Config.Taunts.Save = function(sTauntListFile)
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Save: Saving taunt list to file '"..sTauntListFile.."'...") end
|
||||
|
||||
-- -- Safeguard against idiots.
|
||||
-- if type(sTauntListFile) != "string" then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Save: <sTauntListFile> is not a string.") end
|
||||
-- return false
|
||||
-- end
|
||||
|
||||
-- -- File must not be nil, otherwise we can't write to it.
|
||||
-- if sTauntListFile == nil then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Save: No file given.") end
|
||||
-- return false
|
||||
-- end
|
||||
|
||||
-- -- Convert our taunt table to JSON.
|
||||
-- sTauntListData = util.TableToJSON(GAMEMODE.Taunts);
|
||||
-- if sTauntListData == nil then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Save: Corrupted GAMEMODE table.") end
|
||||
-- return false
|
||||
-- end
|
||||
|
||||
-- -- Write out JSON out to file
|
||||
-- if ! file.Write(sTauntListFile, sTauntListData) then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Save: Failed to write to file.") end
|
||||
-- return false
|
||||
-- end
|
||||
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Save: Complete.") end
|
||||
-- return true
|
||||
-- end
|
||||
|
||||
-- -- Taunts.Add(sTauntName, sSoundFile, iTeamID, mPropFilter)
|
||||
-- --@desc: Registers a new taunt with the given name, file, team and filter.
|
||||
-- --@param:
|
||||
-- -- sTauntName - The unique name of the taunt.
|
||||
-- -- sSoundFile - A sound file to play when this taunt is selected.
|
||||
-- -- iTeamID - The team that should receive the taunt or nil for all teams.
|
||||
-- -- mPropFilter - A string or a table containing strings for props that should be able to use this taunt.
|
||||
-- --@return: true or false depending on success.
|
||||
-- GM.Config.Taunts.Add = function(sTauntName, sSoundFile, iTeamID, mPropFilter)
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Add: Adding new taunt '"..sTauntName.."'...") end
|
||||
|
||||
-- -- Safeguard against idiots.
|
||||
-- if type(sTauntName) != "string" then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Add: <sTauntName> is not a string.") end
|
||||
-- return false
|
||||
-- end
|
||||
-- if type(sSoundFile) != "string" then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Add: <sSoundFile> is not a string.") end
|
||||
-- return false
|
||||
-- end
|
||||
-- if (type(iTeamID) != "number" && iTeamID != nil) then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Add: <iTeamID> is not a number or nil.") end
|
||||
-- return false
|
||||
-- end
|
||||
-- if (type(mPropFilter) != "string" && type(mPropFilter) != "table" && mPropFilter != nil) then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Add: <mPropFilter> is not a string, table or nil.") end
|
||||
-- return false
|
||||
-- end
|
||||
|
||||
-- -- Check if the sound file actually exists
|
||||
-- if !file.Exists("sound/"..sSoundFile, "GAME") then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Add: File '"..sSoundFile.."' does not exist.") end
|
||||
-- return false
|
||||
-- end
|
||||
|
||||
-- -- Make sure that our prop filter is a table listing the props it's supposed to work for.
|
||||
-- if (mPropFilter == nil) then
|
||||
-- mPropFilter = { }
|
||||
-- elseif type(mPropFilter) == "string" then
|
||||
-- mPropFilter = { mPropFilter }
|
||||
-- end
|
||||
|
||||
-- -- Prepare Taunt table
|
||||
-- Taunt = {
|
||||
-- File = sSoundFile,
|
||||
-- Filter = mPropFilter
|
||||
-- }
|
||||
|
||||
-- -- If iTeamID is nil, both teams will receive the taunt.
|
||||
-- if iTeamID == nil then
|
||||
-- GAMEMODE.Taunts.Seeker[sTauntName] = Taunt
|
||||
-- GAMEMODE.Taunts.Hider[sTauntName] = Taunt
|
||||
-- else
|
||||
-- -- Make sure that the team is valid.
|
||||
-- if ! team.Valid(iTeamID) then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Add: Team "..iTeamID.."' does not exist.") end
|
||||
-- return false
|
||||
-- end
|
||||
|
||||
-- if (iTeamID == TEAM_SEEKERS) then
|
||||
-- GAMEMODE.Taunts.Seeker[sTauntName] = Taunt
|
||||
-- elseif (iTeamID == TEAM_HIDERS) then
|
||||
-- GAMEMODE.Taunts.Hider[sTauntName] = Taunt
|
||||
-- else
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Add: Team "..iTeamID.."' can't have taunts.") end
|
||||
-- return false
|
||||
-- end
|
||||
-- end
|
||||
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Add: Complete.") end
|
||||
-- return true
|
||||
-- end
|
||||
|
||||
-- -- Taunts.Remove(sTauntName, iTeamID)
|
||||
-- --@desc: Removes a registered taunt with the given name and team.
|
||||
-- --@param:
|
||||
-- -- sTauntName - The unique name of the taunt.
|
||||
-- -- iTeamID - The team that the taunt should be removed from or nil for all teams.
|
||||
-- --@return: true or false depending on success.
|
||||
-- GM.Config.Taunts.Remove = function(sTauntName, iTeamID)
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Remove: Removing taunt '"..sTauntName.."'...") end
|
||||
|
||||
-- -- Safeguard against idiots.
|
||||
-- if type(sTauntName) != "string" then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Remove: <sTauntName> is not a string.") end
|
||||
-- return false
|
||||
-- end
|
||||
-- if (type(iTeamID) != "number" && iTeamID != nil) then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Remove: <iTeamID> is not a number or nil.") end
|
||||
-- return false
|
||||
-- end
|
||||
|
||||
-- -- if iTeamID is nil, both teams will have the taunt removed.
|
||||
-- if (iTeamID == nil) then
|
||||
-- GAMEMODE.Taunts.Seeker[sTauntName] = nil
|
||||
-- GAMEMODE.Taunts.Hider[sTauntName] = nil
|
||||
-- else
|
||||
-- -- Make sure we have a valid Team.
|
||||
-- if ! team.Valid(iTeamID) then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Remove: Team "..iTeamID.."' does not exist.") end
|
||||
-- return false
|
||||
-- end
|
||||
|
||||
-- if iTeamID == TEAM_SEEKERS then
|
||||
-- GAMEMODE.Taunts.Seeker[sTauntName] = nil
|
||||
-- elseif iTeamID == TEAM_HIDERS then
|
||||
-- GAMEMODE.Taunts.Hider[sTauntName] = nil
|
||||
-- else
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Remove: Team "..iTeamID.."' can't have taunts.") end
|
||||
-- return false
|
||||
-- end
|
||||
-- end
|
||||
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Taunts.Remove: Complete.") end
|
||||
-- return true
|
||||
-- end
|
||||
|
||||
-- -- ToDo: Taunts.Get(iTeamID, sPropName)
|
||||
|
||||
-- --! Announcers (Round Start, Unblind, Win, Loss)
|
||||
-- GM.Config.Announcers = {
|
||||
-- Start = { },
|
||||
-- Unblind = { },
|
||||
-- Win = { },
|
||||
-- Loss = { }
|
||||
-- }
|
||||
|
||||
-- -- Announcers.Clear()
|
||||
-- --@desc: Clears the current announcer list.
|
||||
-- GM.Config.Announcers.Clear = function()
|
||||
-- Announcers.Start = { }
|
||||
-- Announcers.Unblind = { }
|
||||
-- Announcers.Win = { }
|
||||
-- Announcers.Loss = { }
|
||||
-- end
|
||||
|
||||
-- -- Announcers.Load(sAnnouncerListFile)
|
||||
-- --@desc: Tries to load the given announcer list.
|
||||
-- --@param:
|
||||
-- -- sAnnouncerListFile - A string containing the path to the announcer list to load.
|
||||
-- --@return: true or false depending on success.
|
||||
-- GM.Config.Announcers.Load = function(sAnnouncerListFile)
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Announcers.Load: Loading announcer list from file '"..sAnnouncerListFile.."'...") end
|
||||
|
||||
-- -- Safeguard against idiots.
|
||||
-- if type(sAnnouncerListFile) != "string" then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Announcers.Load: <sAnnouncerListFile> is not a string.") end
|
||||
-- return false
|
||||
-- end
|
||||
|
||||
-- -- Given file must exist for us to continue.
|
||||
-- if ! file.Exists(sAnnouncerListFile, "GAME") then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Announcers.Load: File not found.") end
|
||||
-- return false
|
||||
-- end
|
||||
|
||||
-- -- Read the file and check if it's empty.
|
||||
-- sAnnouncerListData = file.Read(sAnnouncerListFile, "GAME")
|
||||
-- if sAnnouncerListData == "" then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Announcers.Load: File is empty.") end
|
||||
-- return false
|
||||
-- end
|
||||
|
||||
-- -- Convert JSON to a table for us to use.
|
||||
-- sAnnouncerList = util.JSONToTable(sAnnouncerListData)
|
||||
|
||||
-- -- Is it nil? Then it's not valid JSON
|
||||
-- if sAnnouncerList == nil then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Announcers.Load: File contains invalid JSON.") end
|
||||
-- return false
|
||||
-- end
|
||||
|
||||
-- -- Finally, insert the announcer lists.
|
||||
-- if sAnnouncerList.Start != nil then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Announcers.Load: Adding Start announcers...") end
|
||||
-- for k,v in pairs(sAnnouncerList.Start) do
|
||||
-- GAMEMODE.Announcers.Start[k] = v
|
||||
-- end
|
||||
-- end
|
||||
-- if sAnnouncerList.Unblind != nil then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Announcers.Load: Adding Unblind announcers...") end
|
||||
-- for k,v in pairs(sAnnouncerList.Unblind) do
|
||||
-- GAMEMODE.Announcers.Unblind[k] = v
|
||||
-- end
|
||||
-- end
|
||||
-- if sAnnouncerList.Win != nil then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Announcers.Load: Adding Win announcers...") end
|
||||
-- for k,v in pairs(sAnnouncerList.Win) do
|
||||
-- GAMEMODE.Announcers.Win[k] = v
|
||||
-- end
|
||||
-- end
|
||||
-- if sAnnouncerList.Loss != nil then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Announcers.Load: Adding Loss announcers...") end
|
||||
-- for k,v in pairs(sAnnouncerList.Loss) do
|
||||
-- GAMEMODE.Announcers.Loss[k] = v
|
||||
-- end
|
||||
-- end
|
||||
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Announcers.Load: Complete.") end
|
||||
-- return true
|
||||
-- end
|
||||
|
||||
-- -- Announcers.Save(sAnnouncerListFile)
|
||||
-- --@desc: Saves the current taunt list to disk.
|
||||
-- --@param:
|
||||
-- -- sAnnouncerListFile - A string containing the path to the file to save to.
|
||||
-- --@return: true or false depending on success.
|
||||
-- GM.Config.Announcers.Save = function(sAnnouncerListFile)
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Announcers.Save: Saving announcer list to file '"..sAnnouncerListFile.."'...") end
|
||||
|
||||
-- -- Safeguard against idiots.
|
||||
-- if type(sAnnouncerListFile) != "string" then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Announcers.Save: <sAnnouncerListFile> is not a string.") end
|
||||
-- return false
|
||||
-- end
|
||||
|
||||
-- -- File must not be nil, otherwise we can't write to it.
|
||||
-- if sAnnouncerListFile == nil then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Announcers.Save: No file given.") end
|
||||
-- return false
|
||||
-- end
|
||||
|
||||
-- -- Convert our taunt table to JSON.
|
||||
-- sAnnouncerListData = util.TableToJSON(GAMEMODE.Announcers);
|
||||
-- if sAnnouncerListData == nil then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Announcers.Save: Corrupted GAMEMODE table.") end
|
||||
-- return false
|
||||
-- end
|
||||
|
||||
-- -- Write out JSON out to file
|
||||
-- if ! file.Write(sAnnouncerListFile, sAnnouncerListData) then
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Announcers.Save: Failed to write to file.") end
|
||||
-- return false
|
||||
-- end
|
||||
|
||||
|
||||
-- if GAMEMODE.Config:Debug() then print("Prop Hunt.Announcers.Save: Complete.") end
|
||||
-- return true
|
||||
-- end
|
||||
|
||||
-- -- ToDo: Announcers.Add
|
||||
-- -- ToDo: Announcers.Remove
|
||||
-- -- ToDo: Announcers.Get(iType)
|
||||
@@ -22,6 +22,42 @@
|
||||
SOFTWARE.
|
||||
--]]
|
||||
|
||||
AddCSLuaFile("sh_init.lua")
|
||||
AddCSLuaFile("cl_init.lua")
|
||||
include "sh_init.lua"
|
||||
GM.RoundManager = {}
|
||||
GM.RoundManager.State = nil;
|
||||
GM.RoundManager.NextState = nil;
|
||||
|
||||
function GM.RoundManager:Tick(...)
|
||||
if (self.State != nil) then
|
||||
if (self.State.Tick != nil) then
|
||||
self.State:Tick(...)
|
||||
end
|
||||
end
|
||||
|
||||
-- Advance States
|
||||
if (self.NextState != self.State) then
|
||||
-- Call OnLeave(NewState)
|
||||
if (self.State != nil) then
|
||||
if (self.State.OnLeave != nil) then
|
||||
self.State:OnLeave(self.NextState)
|
||||
end
|
||||
end
|
||||
|
||||
-- Call OnEnter(OldState)
|
||||
if (self.NextState != nil) then
|
||||
if (self.NextState.OnEnter != nil) then
|
||||
self.NextState:OnEnter(self.State)
|
||||
end
|
||||
end
|
||||
|
||||
-- Set State
|
||||
self.State = self.NextState
|
||||
end
|
||||
end
|
||||
|
||||
function GM.RoundManager:GetState()
|
||||
return self.State
|
||||
end
|
||||
|
||||
function GM.RoundManager:SetState(State)
|
||||
self.NextState = State
|
||||
end
|
||||
@@ -1,7 +1,7 @@
|
||||
--[[
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015-2018 Xaymar
|
||||
Copyright (c) 2015 Xaymar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -22,28 +22,29 @@
|
||||
SOFTWARE.
|
||||
--]]
|
||||
|
||||
include "base.lua"
|
||||
StateHide = {}
|
||||
|
||||
local CLASS = state("Hide", GM.States.Hide)
|
||||
|
||||
function CLASS:OnEnter(OldState)
|
||||
if GAMEMODE.Config:DebugLog() then print("StateHide: OnEnter") end
|
||||
function StateHide:OnEnter(OldState)
|
||||
if GAMEMODE.Config:Debug() then print("StateHide: OnEnter") end
|
||||
GAMEMODE:SetRoundState(GAMEMODE.States.Hide)
|
||||
|
||||
-- Round Data
|
||||
GAMEMODE.Data.RoundTime = math.abs(GAMEMODE.Config.Round:BlindTime())
|
||||
GAMEMODE.Data.RoundStartTime = CurTime()
|
||||
|
||||
GAMEMODE:SetRoundTime(GAMEMODE.Data.RoundTime)
|
||||
end
|
||||
|
||||
function CLASS:Tick()
|
||||
function StateHide:Tick()
|
||||
-- Update Game Time
|
||||
local deltaTime = (CurTime() - GAMEMODE.Data.RoundStartTime)
|
||||
GAMEMODE.Data.RoundTime = GAMEMODE.Config.Round:Time() - deltaTime
|
||||
GAMEMODE.Data.StateTime = math.abs(GAMEMODE.Config.Round:BlindTime()) - deltaTime
|
||||
GAMEMODE.Data.RoundTime = math.abs(GAMEMODE.Config.Round:BlindTime()) - (CurTime() - GAMEMODE.Data.RoundStartTime)
|
||||
GAMEMODE:SetRoundTime(GAMEMODE.Data.RoundTime)
|
||||
GAMEMODE:SetRoundStateTime(GAMEMODE.Data.StateTime)
|
||||
|
||||
-- Advance to Seeking State
|
||||
if (GAMEMODE.Data.StateTime <= 0) then
|
||||
if (GAMEMODE.Data.RoundTime <= 0) then
|
||||
if GAMEMODE.Config:Debug() then print("StateHide: Advancing to Seek stage.") end
|
||||
|
||||
RoundManager:SetState(StateSeek)
|
||||
GAMEMODE.RoundManager:SetState(StateSeek)
|
||||
end
|
||||
|
||||
-- Freeze Seekers
|
||||
@@ -56,11 +57,6 @@ function CLASS:Tick()
|
||||
-- ToDo: Logic for more game modes here?
|
||||
end
|
||||
|
||||
function CLASS:OnLeave(NewState)
|
||||
function StateHide:OnLeave(NewState)
|
||||
if GAMEMODE.Config:Debug() then print("StateHide: OnLeave") end
|
||||
|
||||
-- Fretta Hooks
|
||||
hook.Run("PropHuntUnblind")
|
||||
end
|
||||
|
||||
_G["StateHide"] = CLASS
|
||||
end
|
||||
@@ -1,37 +1,39 @@
|
||||
--[[
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Xaymar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
--]]
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Gamemode Information
|
||||
-- ------------------------------------------------------------------------- --
|
||||
GM.Name = "Prop Hunt Extended"
|
||||
GM.Author = "Michael Fabian 'Xaymar' Dirks"
|
||||
GM.Email = "info@xaymar.com"
|
||||
GM.Website = "http://xaymar.com/"
|
||||
|
||||
GM.TeamBased = true
|
||||
GM.AllowAutoTeam = true
|
||||
GM.SecondsBetweenTeamSwitches = 10
|
||||
|
||||
DeriveGamemode("prophuntextended")
|
||||
--[[
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Xaymar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
--]]
|
||||
|
||||
StatePostMatch = {}
|
||||
|
||||
function StatePostMatch:OnEnter(OldState)
|
||||
if GAMEMODE.Config:Debug() then print("StatePostMatch: OnEnter") end
|
||||
GAMEMODE:SetRoundState(GAMEMODE.States.PostMatch)
|
||||
end
|
||||
|
||||
function StatePostMatch:Tick()
|
||||
-- Advance State
|
||||
GAMEMODE.RoundManager:SetState(StatePreMatch)
|
||||
end
|
||||
|
||||
function StatePostMatch:OnLeave(NewState)
|
||||
if GAMEMODE.Config:Debug() then print("StatePostMatch: OnLeave") end
|
||||
end
|
||||
@@ -1,7 +1,7 @@
|
||||
--[[
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015-2018 Xaymar
|
||||
Copyright (c) 2015 Xaymar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -22,37 +22,38 @@
|
||||
SOFTWARE.
|
||||
--]]
|
||||
|
||||
include "base.lua"
|
||||
StatePostRound = {}
|
||||
|
||||
local CLASS = state("PostMatch", GM.States.PostMatch)
|
||||
function StatePostRound:OnEnter(OldState)
|
||||
if GAMEMODE.Config:Debug() then print("StatePostRound: OnEnter") end
|
||||
GAMEMODE:SetRoundState(GAMEMODE.States.PostRound)
|
||||
|
||||
GAMEMODE.Data.RoundStartTime = CurTime()
|
||||
end
|
||||
|
||||
function CLASS:OnEnter(OldState)
|
||||
if GAMEMODE.Config:DebugLog() then print("StatePostMatch: OnEnter") end
|
||||
GAMEMODE:SetRoundState(GAMEMODE.States.PostMatch)
|
||||
|
||||
self.NextState = StatePreMatch
|
||||
|
||||
-- Check Change map conditions.
|
||||
if ((GAMEMODE.Config:TimeLimit() > 0) && ((CurTime() - GAMEMODE.Data.StartTime) >= (GAMEMODE.Config:TimeLimit() * 60))) -- Over Time
|
||||
|| ((GAMEMODE.Config.Round:Limit() > 0) && (GAMEMODE:GetRound() >= GAMEMODE.Config.Round:Limit())) -- Over Round Limit
|
||||
then
|
||||
|
||||
-- Advance to nothing
|
||||
GAMEMODE:SetRoundState(-1)
|
||||
self.NextState = nil
|
||||
|
||||
-- MapVote
|
||||
if (MapVote != nil) then MapVote.Start(30, true, 30, "ph_") return end
|
||||
function StatePostRound:Tick()
|
||||
-- Advance State
|
||||
if (CurTime() - GAMEMODE.Data.RoundStartTime) >= 5 then -- ToDo: configureable time?
|
||||
GAMEMODE.RoundManager:SetState(StatePostMatch)
|
||||
end
|
||||
end
|
||||
|
||||
function CLASS:Tick()
|
||||
-- Advance State
|
||||
RoundManager:SetState(self.NextState)
|
||||
end
|
||||
|
||||
function CLASS:OnLeave(NewState)
|
||||
if GAMEMODE.Config:DebugLog() then print("StatePostMatch: OnLeave") end
|
||||
end
|
||||
|
||||
_G["StatePostMatch"] = CLASS
|
||||
function StatePostRound:OnLeave(NewState)
|
||||
if GAMEMODE.Config:Debug() then print("StatePostRound: OnLeave") end
|
||||
|
||||
-- Game Mode: Basic
|
||||
if (GAMEMODE.Config:GameMode() == GAMEMODE.Modes.Original) then
|
||||
-- Swap Teams
|
||||
local hiders, seekers = team.GetPlayers(GAMEMODE.Teams.Hiders), team.GetPlayers(GAMEMODE.Teams.Seekers)
|
||||
for i, ply in ipairs(hiders) do
|
||||
ply:KillSilent()
|
||||
ply:SetTeam(GAMEMODE.Teams.Seekers)
|
||||
end
|
||||
for i, ply in ipairs(seekers) do
|
||||
ply:KillSilent()
|
||||
ply:SetTeam(GAMEMODE.Teams.Hiders)
|
||||
end
|
||||
|
||||
-- TODO: Other Gamemodes
|
||||
end
|
||||
end
|
||||
@@ -1,7 +1,7 @@
|
||||
--[[
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015-2018 Xaymar
|
||||
Copyright (c) 2015 Xaymar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -22,33 +22,33 @@
|
||||
SOFTWARE.
|
||||
--]]
|
||||
|
||||
include "base.lua"
|
||||
-- Precache Network Message
|
||||
StatePreMatch = {}
|
||||
|
||||
local CLASS = state("PreMatch", GM.States.PreMatch)
|
||||
|
||||
function CLASS:OnEnter(OldState)
|
||||
if GAMEMODE.Config:DebugLog() then print("StatePreMatch: OnEnter") end
|
||||
function StatePreMatch:OnEnter(OldState)
|
||||
if GAMEMODE.Config:Debug() then print("StatePreMatch: OnEnter") end
|
||||
GAMEMODE:SetRoundState(GAMEMODE.States.PreMatch)
|
||||
|
||||
math.randomseed(CurTime())
|
||||
SetGlobalInt("Round", GetGlobalInt("Round", 0) + 1)
|
||||
end
|
||||
|
||||
function CLASS:Tick()
|
||||
function StatePreMatch:Tick()
|
||||
-- Debug: Auto Advance to PreRound State
|
||||
if (GAMEMODE.Config:Debug()) then
|
||||
if GAMEMODE.Config:DebugLog() then print("StatePreMatch: Advancing to StatePreRound") end
|
||||
RoundManager:SetState(StatePreRound)
|
||||
print("StatePreMatch: Advancing to StatePreRound")
|
||||
GAMEMODE.RoundManager:SetState(StatePreRound)
|
||||
end
|
||||
|
||||
-- Both Teams must have at least 1 player.
|
||||
if ((team.NumPlayers(GAMEMODE.Teams.Seekers) >= 1) && (team.NumPlayers(GAMEMODE.Teams.Hiders) >= 1)) then
|
||||
RoundManager:SetState(StatePreRound)
|
||||
if GAMEMODE.Config:DebugLog() then print("StatePreMatch: <Original> Have enough players to start match.") end
|
||||
-- Game Mode: Basic
|
||||
if (GAMEMODE.Config:GameMode() == GAMEMODE.Modes.Original) then
|
||||
-- Both Teams must have at least 1 player.
|
||||
if ((team.NumPlayers(GAMEMODE.Teams.Seekers) >= 1) && (team.NumPlayers(GAMEMODE.Teams.Hiders) >= 1)) then
|
||||
GAMEMODE.RoundManager:SetState(StatePreRound)
|
||||
end
|
||||
-- TODO: Other Gamemodes
|
||||
end
|
||||
end
|
||||
|
||||
function CLASS:OnLeave(NewState)
|
||||
if GAMEMODE.Config:DebugLog() then print("StatePreMatch: OnLeave") end
|
||||
end
|
||||
|
||||
_G["StatePreMatch"] = CLASS
|
||||
function StatePreMatch:OnLeave(NewState)
|
||||
if GAMEMODE.Config:Debug() then print("StatePreMatch: OnLeave") end
|
||||
end
|
||||
@@ -1,7 +1,7 @@
|
||||
--[[
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015-2018 Xaymar
|
||||
Copyright (c) 2015 Xaymar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -22,30 +22,22 @@
|
||||
SOFTWARE.
|
||||
--]]
|
||||
|
||||
include "base.lua"
|
||||
StatePreRound = {}
|
||||
|
||||
local CLASS = state("PreRound", GM.States.PreRound)
|
||||
|
||||
function CLASS:OnEnter(OldState)
|
||||
if GAMEMODE.Config:DebugLog() then print("StatePreRound: OnEnter") end
|
||||
function StatePreRound:OnEnter(OldState)
|
||||
if GAMEMODE.Config:Debug() then print("StatePreRound: OnEnter") end
|
||||
GAMEMODE:SetRoundState(GAMEMODE.States.PreRound)
|
||||
GAMEMODE:SetRound(GAMEMODE:GetRound() + 1)
|
||||
|
||||
-- Clean Up the Map
|
||||
game.CleanUpMap()
|
||||
|
||||
-- Set Round Start Time
|
||||
GAMEMODE.Data.RoundStartTime = CurTime()
|
||||
|
||||
end
|
||||
|
||||
function CLASS:Tick()
|
||||
function StatePreRound:Tick()
|
||||
-- Advance State
|
||||
RoundManager:SetState(StateHide)
|
||||
GAMEMODE.RoundManager:SetState(StateHide)
|
||||
end
|
||||
|
||||
function CLASS:OnLeave(NewState)
|
||||
if GAMEMODE.Config:DebugLog() then print("StatePreRound: OnLeave") end
|
||||
function StatePreRound:OnLeave(NewState)
|
||||
if GAMEMODE.Config:Debug() then print("StatePreRound: OnLeave") end
|
||||
|
||||
-- Respawn Everyone
|
||||
for i, ply in ipairs(player.GetAll()) do
|
||||
@@ -54,17 +46,5 @@ function CLASS:OnLeave(NewState)
|
||||
ply:Spawn()
|
||||
ply:ScreenFade(SCREENFADE.PURGE, color_black, 0, 0)
|
||||
ply:ScreenFade(SCREENFADE.IN, color_black, 1, 0)
|
||||
|
||||
-- Weighted Score: Adjust towards other Team.
|
||||
if (ply:Team() == GAMEMODE.Teams.Hiders) then
|
||||
ply.Data.RandomWeight = ply.Data.RandomWeight + 1
|
||||
elseif (ply:Team() == GAMEMODE.Teams.Seekers) then
|
||||
ply.Data.RandomWeight = ply.Data.RandomWeight - 1
|
||||
end
|
||||
end
|
||||
|
||||
-- Fretta Hooks
|
||||
hook.Run("RoundStart")
|
||||
end
|
||||
|
||||
_G["StatePreRound"] = CLASS
|
||||
end
|
||||
@@ -1,7 +1,7 @@
|
||||
--[[
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015-2018 Xaymar
|
||||
Copyright (c) 2015 Xaymar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -22,14 +22,15 @@
|
||||
SOFTWARE.
|
||||
--]]
|
||||
|
||||
include "base.lua"
|
||||
StateSeek = {}
|
||||
|
||||
local CLASS = state("Seek", GM.States.Seek)
|
||||
|
||||
function CLASS:OnEnter(OldState)
|
||||
if GAMEMODE.Config:DebugLog() then print("StateSeek: OnEnter") end
|
||||
function StateSeek:OnEnter(OldState)
|
||||
if GAMEMODE.Config:Debug() then print("StateSeek: OnEnter") end
|
||||
GAMEMODE:SetRoundState(GAMEMODE.States.Seek)
|
||||
|
||||
-- Round Data
|
||||
GAMEMODE.Data.RoundTime = GAMEMODE.Config.Round:Time()
|
||||
|
||||
-- Unfreeze Seekers
|
||||
for i, ply in ipairs(team.GetPlayers(GAMEMODE.Teams.Seekers)) do
|
||||
ply:Freeze(false)
|
||||
@@ -39,13 +40,10 @@ function CLASS:OnEnter(OldState)
|
||||
end
|
||||
end
|
||||
|
||||
function CLASS:Tick()
|
||||
function StateSeek:Tick()
|
||||
-- Update Game Time
|
||||
local deltaTime = (CurTime() - GAMEMODE.Data.RoundStartTime)
|
||||
GAMEMODE.Data.RoundTime = GAMEMODE.Config.Round:Time() - deltaTime
|
||||
GAMEMODE.Data.StateTime = GAMEMODE.Config.Round:Time() - deltaTime
|
||||
GAMEMODE.Data.RoundTime = GAMEMODE.Config.Round:Time() - (CurTime() - GAMEMODE.Data.RoundStartTime)
|
||||
GAMEMODE:SetRoundTime(GAMEMODE.Data.RoundTime)
|
||||
GAMEMODE:SetRoundStateTime(GAMEMODE.Data.StateTime)
|
||||
|
||||
-- Victory Conditions
|
||||
local hiders, seekers = team.GetPlayers(GAMEMODE.Teams.Hiders), team.GetPlayers(GAMEMODE.Teams.Seekers)
|
||||
@@ -60,49 +58,30 @@ function CLASS:Tick()
|
||||
end
|
||||
for i,ply in ipairs(seekers) do
|
||||
if (ply.Data.Alive) then
|
||||
seekerAlive = truew
|
||||
seekerAlive = true
|
||||
end
|
||||
end
|
||||
if (hiderAlive == false) then
|
||||
if (seekerAlive == false) then -- Draw, both teams dead.
|
||||
GAMEMODE:SetRoundWinner(GAMEMODE.Teams.Spectators)
|
||||
RoundManager:SetState(StatePostRound)
|
||||
GAMEMODE.RoundManager:SetState(StatePostRound)
|
||||
else -- Seeker victory, Hiders dead
|
||||
GAMEMODE:SetRoundWinner(GAMEMODE.Teams.Seekers)
|
||||
RoundManager:SetState(StatePostRound)
|
||||
GAMEMODE.RoundManager:SetState(StatePostRound)
|
||||
end
|
||||
else
|
||||
if (seekerAlive == false) then -- Hider Victory, Seeker dead.
|
||||
GAMEMODE:SetRoundWinner(GAMEMODE.Teams.Hiders)
|
||||
RoundManager:SetState(StatePostRound)
|
||||
GAMEMODE.RoundManager:SetState(StatePostRound)
|
||||
else
|
||||
if (GAMEMODE.Data.StateTime <= 0) then -- No Time remaining
|
||||
GAMEMODE:SetRoundWinner(GAMEMODE.Teams.Hiders)
|
||||
RoundManager:SetState(StatePostRound)
|
||||
if (GAMEMODE.Data.RoundTime <= 0) then -- No Time remaining
|
||||
GAMEMODE:SetRoundWinner(GAMEMODE.Teams.Hiders)
|
||||
GAMEMODE.RoundManager:SetState(StatePostRound)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function CLASS:OnLeave(NewState)
|
||||
if GAMEMODE.Config:DebugLog() then print("StateSeek: OnLeave") end
|
||||
|
||||
if GAMEMODE:GetRoundWinner() == GAMEMODE.Teams.Seekers then
|
||||
-- Run external Hooks
|
||||
hook.Run("RoundVictorySeeker")
|
||||
|
||||
-- Assign Team Points
|
||||
team.SetScore(GAMEMODE.Teams.Seekers, team.GetScore(GAMEMODE.Teams.Seekers) + 1)
|
||||
elseif GAMEMODE:GetRoundWinner() == GAMEMODE.Teams.Hiders then
|
||||
-- Run external Hooks
|
||||
hook.Run("RoundVictoryHider")
|
||||
|
||||
-- Assign Team Points
|
||||
team.SetScore(GAMEMODE.Teams.Hiders, team.GetScore(GAMEMODE.Teams.Hiders) + 1)
|
||||
else
|
||||
-- Run external Hooks
|
||||
hook.Run("RoundVictoryDraw")
|
||||
end
|
||||
end
|
||||
|
||||
_G["StateSeek"] = CLASS
|
||||
function StateSeek:OnLeave(NewState)
|
||||
if GAMEMODE.Config:Debug() then print("StateSeek: OnLeave") end
|
||||
end
|
||||
@@ -0,0 +1,294 @@
|
||||
-- Sounds played by members of the losing team at the end of the round.
|
||||
LOSS_SOUNDS = {
|
||||
"bot/aw_hell.wav",
|
||||
"bot/aww_man.wav",
|
||||
"bot/anyone_see_anything.wav",
|
||||
"bot/anyone_see_them.wav",
|
||||
"bot/come_out_and_fight_like_a_man.wav",
|
||||
"bot/come_out_wherever_you_are.wav",
|
||||
"bot/he_got_away.wav",
|
||||
"bot/he_got_away2.wav",
|
||||
"bot/i_dont_know_where_he_went.wav",
|
||||
"bot/i_got_nothing.wav",
|
||||
"bot/nothing_happening_over_here.wav",
|
||||
"bot/nothing_here.wav",
|
||||
"bot/nothing_moving_over_here.wav",
|
||||
"bot/thats_not_good.wav",
|
||||
"bot/theres_too_many.wav",
|
||||
"bot/theres_too_many_of_them.wav",
|
||||
"bot/theyre_all_over_the_place2.wav",
|
||||
"bot/theyre_everywhere2.wav",
|
||||
"bot/too_many2.wav",
|
||||
"bot/what_happened.wav",
|
||||
"bot/what_have_you_done.wav",
|
||||
"bot/where_are_they.wav",
|
||||
"bot/where_are_you_hiding.wav"
|
||||
}
|
||||
if (! file.Exists("prop_hunt/sounds_loss.txt", "DATA")) then
|
||||
file.Write("prop_hunt/sounds_loss.txt", util.TableToKeyValues(LOSS_SOUNDS))
|
||||
end
|
||||
local fileContent = file.Read("prop_hunt/sounds_loss.txt", "DATA");
|
||||
if fileContent then
|
||||
local fileTable = util.KeyValuesToTable(fileContent)
|
||||
if fileTable then LOSS_SOUNDS = fileTable end
|
||||
end
|
||||
|
||||
-- Sounds played by members of the winning team at the end of the round.
|
||||
VICTORY_SOUNDS = {
|
||||
"bot/and_thats_how_its_done.wav",
|
||||
"bot/come_to_papa.wav",
|
||||
"bot/do_not_mess_with_me.wav",
|
||||
"bot/dropped_him.wav",
|
||||
"bot/enemy_down.wav",
|
||||
"bot/enemy_down2.wav",
|
||||
"bot/good_job_team.wav",
|
||||
"bot/got_him.wav",
|
||||
"bot/hes_broken.wav",
|
||||
"bot/hes_dead.wav",
|
||||
"bot/hes_done.wav",
|
||||
"bot/hes_down.wav",
|
||||
"bot/its_a_party.wav",
|
||||
"bot/i_am_dangerous.wav",
|
||||
"bot/i_am_on_fire.wav",
|
||||
"bot/i_got_more_where_that_came_from.wav",
|
||||
"bot/i_wasnt_worried_for_a_minute.wav",
|
||||
"bot/killed_him.wav",
|
||||
"bot/look_out_brag.wav",
|
||||
"bot/made_him_cry.wav",
|
||||
"bot/oh_yea.wav",
|
||||
"bot/oh_yea2.wav",
|
||||
"bot/owned.wav",
|
||||
"bot/ruined_his_day.wav",
|
||||
"bot/tag_them_and_bag_them.wav",
|
||||
"bot/thats_the_way_this_is_done.wav",
|
||||
"bot/that_was_a_close_one.wav",
|
||||
"bot/that_was_it.wav",
|
||||
"bot/that_was_the_last_guy.wav",
|
||||
"bot/that_was_the_last_one.wav",
|
||||
"bot/they_never_knew_what_hit_them.wav",
|
||||
"bot/they_will_not_escape.wav",
|
||||
"bot/they_wont_get_away.wav",
|
||||
"bot/they_wont_get_away2.wav",
|
||||
"bot/this_is_my_house.wav",
|
||||
"bot/took_him_down.wav",
|
||||
"bot/took_him_out.wav",
|
||||
"bot/took_him_out2.wav",
|
||||
"bot/wasted_him.wav",
|
||||
"bot/way_to_be_team.wav",
|
||||
"bot/well_done.wav",
|
||||
"bot/we_owned_them.wav",
|
||||
"bot/whew_that_was_close.wav",
|
||||
"bot/whoo.wav",
|
||||
"bot/whoo2.wav",
|
||||
"bot/whos_the_man.wav",
|
||||
"bot/who_wants_some_more.wav",
|
||||
"bot/yesss.wav",
|
||||
"bot/yesss2.wav"
|
||||
}
|
||||
if (! file.Exists("prop_hunt/sounds_victory.txt", "DATA")) then
|
||||
file.Write("prop_hunt/sounds_victory.txt", util.TableToKeyValues(VICTORY_SOUNDS))
|
||||
end
|
||||
local fileContent = file.Read("prop_hunt/sounds_victory.txt", "DATA");
|
||||
if fileContent then
|
||||
local fileTable = util.KeyValuesToTable(fileContent)
|
||||
if fileTable then VICTORY_SOUNDS = fileTable end
|
||||
end
|
||||
|
||||
-- Taunts played when Hunters hit their Spare1 binding.
|
||||
HUNTER_TAUNTS = {
|
||||
"bot/a_bunch_of_them.wav",
|
||||
"bot/come_out_and_fight_like_a_man.wav",
|
||||
"bot/come_out_wherever_you_are.wav",
|
||||
"bot/come_to_papa.wav",
|
||||
"bot/dont_worry_hell_get_it.wav",
|
||||
"bot/hang_on_i_heard_something.wav",
|
||||
"bot/hang_on_im_coming.wav",
|
||||
"bot/i_dont_think_so.wav",
|
||||
"bot/i_have_the_hostages.wav",
|
||||
"bot/i_see_our_target.wav",
|
||||
"bot/im_waiting_here.wav",
|
||||
"bot/keeping_an_eye_on_the_hostages.wav",
|
||||
"bot/nnno_sir.wav",
|
||||
"bot/spotted_the_delivery_boy.wav",
|
||||
"bot/target_acquired.wav",
|
||||
"bot/target_spotted.wav",
|
||||
"bot/you_heard_the_man_lets_go.wav"
|
||||
}
|
||||
if (! file.Exists("prop_hunt/sounds_taunt_hunter.txt", "DATA")) then
|
||||
file.Write("prop_hunt/sounds_taunt_hunter.txt", util.TableToKeyValues(HUNTER_TAUNTS))
|
||||
end
|
||||
local fileContent = file.Read("prop_hunt/sounds_taunt_hunter.txt", "DATA");
|
||||
if fileContent then
|
||||
local fileTable = util.KeyValuesToTable(fileContent)
|
||||
if fileTable then HUNTER_TAUNTS = fileTable end
|
||||
end
|
||||
|
||||
-- Taunts played when Props hit their Spare1 binding.
|
||||
PROP_TAUNTS = {
|
||||
-- "ambient/alarms/apc_alarm_loop1.wav",
|
||||
"ambient/alarms/apc_alarm_pass1.wav",
|
||||
-- "ambient/alarms/citadel_alert_loop2.wav",
|
||||
-- "ambient/alarms/city_firebell_loop1.wav",
|
||||
-- "ambient/alarms/city_siren_loop2.wav",
|
||||
-- "ambient/alarms/combine_bank_alarm_loop1.wav",
|
||||
-- "ambient/alarms/combine_bank_alarm_loop4.wav",
|
||||
-- "ambient/alarms/klaxon1.wav",
|
||||
"ambient/alarms/manhack_alert_pass1.wav",
|
||||
"ambient/alarms/razortrain_horn1.wav",
|
||||
"ambient/alarms/scanner_alert_pass1.wav",
|
||||
-- "ambient/alarms/siren.wav",
|
||||
-- "ambient/alarms/train_crossing_bell_loop1.wav",
|
||||
"ambient/alarms/train_horn2.wav",
|
||||
"ambient/alarms/train_horn_distant1.wav",
|
||||
"ambient/alarms/warningbell1.wav",
|
||||
-- "ambient/chatter/cb_radio_chatter_1.wav",
|
||||
-- "ambient/chatter/cb_radio_chatter_2.wav",
|
||||
-- "ambient/chatter/cb_radio_chatter_3.wav",
|
||||
"ambient/energy/whiteflash.wav",
|
||||
"ambient/intro/alyxremove.wav",
|
||||
"ambient/intro/logosfx.wav",
|
||||
-- "ambient/levels/labs/teleport_alarm_loop1.wav",
|
||||
"ambient/levels/launch/1stfiringwarning.wav",
|
||||
"ambient/levels/launch/rockettakeoffblast.wav",
|
||||
-- "ambient/levels/outland/basealarmloop.wav",
|
||||
-- "ambient/machines/60hzhum.wav",
|
||||
"ambient/misc/ambulance1.wav",
|
||||
"ambient/misc/carhonk1.wav",
|
||||
"ambient/misc/carhonk2.wav",
|
||||
"ambient/misc/carhonk3.wav",
|
||||
-- "ambient/music/bongo.wav",
|
||||
-- "ambient/music/country_rock_am_radio_loop.wav",
|
||||
-- "ambient/music/cubanmusic1.wav",
|
||||
-- "ambient/music/dustmusic1.wav",
|
||||
-- "ambient/music/dustmusic2.wav",
|
||||
-- "ambient/music/dustmusic3.wav",
|
||||
-- "ambient/music/flamenco.wav",
|
||||
-- "ambient/music/latin.wav",
|
||||
-- "ambient/music/mirame_radio_thru_wall.wav",
|
||||
-- "ambient/music/piano1.wav",
|
||||
-- "ambient/music/piano2.wav",
|
||||
"ambient/outro/gunshipcrash.wav",
|
||||
"ambient/3dmeagle.wav",
|
||||
-- "ambient/guit1.wav",
|
||||
-- "ambient/opera.wav",
|
||||
-- "ambient/sheep.wav",
|
||||
"beams/beamstart5.wav",
|
||||
"buttons/bell1.wav",
|
||||
"buttons/weapon_cant_buy.wav",
|
||||
"common/bass.wav",
|
||||
"common/bugreporter_failed.wav",
|
||||
"common/warning.wav",
|
||||
"doors/door_squeek1.wav",
|
||||
"friends/friend_join.wav",
|
||||
"friends/friend_online.wav",
|
||||
"friends/message.wav",
|
||||
"hostage/hunuse/comeback.wav",
|
||||
"hostage/hunuse/dontleaveme.wav",
|
||||
"hostage/hunuse/yeahillstay.wav",
|
||||
"items/gift_drop.wav",
|
||||
"music/radio1.mp3",
|
||||
"phx/eggcrack.wav",
|
||||
"plats/elevbell1.wav",
|
||||
"player/headshot1.wav",
|
||||
"player/headshot2.wav",
|
||||
"player/sprayer.wav",
|
||||
"radio/enemydown.wav",
|
||||
"radio/go.wav",
|
||||
"radio/locknload.wav",
|
||||
"radio/negative.wav",
|
||||
"radio/rounddraw.wav",
|
||||
"radio/takepoint.wav",
|
||||
"resource/warning.wav",
|
||||
-- "test/temp/soundscape_test/tv_music.wav",
|
||||
"ui/achievement_earned.wav",
|
||||
"ui/freeze_cam.wav",
|
||||
"vehicles/junker/radar_ping_friendly1.wav",
|
||||
"weapons/c4/c4_beep1.wav",
|
||||
"weapons/c4/c4_click.wav",
|
||||
"weapons/awp/awp1.wav",
|
||||
"vo/canals/female01/gunboat_giveemhell.wav",
|
||||
"vo/canals/female01/gunboat_justintime.wav",
|
||||
"vo/canals/female01/stn6_incoming.wav",
|
||||
"vo/canals/male01/gunboat_giveemhell.wav",
|
||||
"vo/canals/male01/gunboat_justintime.wav",
|
||||
"vo/canals/male01/stn6_incoming.wav",
|
||||
"vo/canals/al_radio_stn6.wav",
|
||||
"vo/canals/arrest_getgoing.wav",
|
||||
"vo/canals/arrest_helpme.wav",
|
||||
"vo/canals/arrest_lookingforyou.wav",
|
||||
"vo/canals/boxcar_lethimhelp.wav",
|
||||
"vo/canals/matt_closecall.wav",
|
||||
"vo/canals/premassacre.wav",
|
||||
"vo/ravenholm/aimforhead.wav",
|
||||
"vo/ravenholm/bucket_patience.wav",
|
||||
"vo/ravenholm/madlaugh01.wav",
|
||||
"vo/ravenholm/madlaugh02.wav",
|
||||
"vo/ravenholm/madlaugh03.wav",
|
||||
"vo/ravenholm/madlaugh04.wav",
|
||||
"weapons/strider_buster/ol12_stickybombcreator.wav",
|
||||
"weapons/c4/c4_explode1.wav",
|
||||
"weapons/357/357_fire2.wav",
|
||||
"weapons/357/357_fire3.wav",
|
||||
"weapons/scout/scout_fire-1.wav",
|
||||
"weapons/smokegrenade/sg_explode.wav",
|
||||
"weapons/grenade_launcher1.wav",
|
||||
"weapons/explode3.wav",
|
||||
"weapons/underwater_explode3.wav",
|
||||
"items/nvg_on.wav",
|
||||
"hostage/huse/letsdoit.wav",
|
||||
"hostage/huse/illfollow.wav",
|
||||
"hostage/huse/getouttahere.wav",
|
||||
"doors/door_screen_move1.wav",
|
||||
"doors/heavy_metal_stop1.wav",
|
||||
"doors/default_move.wav",
|
||||
"common/stuck2.wav",
|
||||
"ambient/water_splash1.wav",
|
||||
"ambient/water_splash2.wav",
|
||||
"ambient/water_splash3.wav",
|
||||
"ambient/weather/thunder1.wav",
|
||||
"ambient/weather/thunder2.wav",
|
||||
"ambient/weather/thunder3.wav",
|
||||
"ambient/weather/thunder4.wav",
|
||||
"ambient/weather/thunder5.wav",
|
||||
"ambient/weather/thunder6.wav",
|
||||
"ambient/outro/thunder7.wav",
|
||||
"ambient/voices/crying_loop1.wav",
|
||||
"ambient/voices/playground_memory.wav",
|
||||
"ambient/voices/f_scream1.wav",
|
||||
"ambient/voices/m_scream1.wav",
|
||||
"ambient/voices/cough1.wav",
|
||||
"ambient/voices/cough2.wav",
|
||||
"ambient/voices/cough3.wav",
|
||||
"ambient/voices/cough4.wav",
|
||||
"ambient/overhead/plane1.wav",
|
||||
"ambient/overhead/plane2.wav",
|
||||
"ambient/overhead/plane3.wav",
|
||||
"ambient/overhead/hel1.wav",
|
||||
"ambient/overhead/hel2.wav",
|
||||
"ambient/misc/truck_backup1.wav",
|
||||
"ambient/misc/truck_drive1.wav",
|
||||
"ambient/misc/truck_drive2.wav",
|
||||
"ambient/machines/pneumatic_drill_1.wav",
|
||||
"ambient/machines/pneumatic_drill_2.wav",
|
||||
"ambient/machines/pneumatic_drill_3.wav",
|
||||
"ambient/machines/pneumatic_drill_4.wav",
|
||||
"ambient/machines/station_train_squeel.wav",
|
||||
"ambient/machines/ticktock.wav",
|
||||
"ambient/creatures/teddy.wav",
|
||||
"ambient/creatures/town_child_scream1.wav",
|
||||
"ambient/creatures/town_moan1.wav",
|
||||
"ambient/creatures/town_muffled_cry1.wav",
|
||||
"ambient/creatures/town_scared_breathing1.wav",
|
||||
"ambient/creatures/town_scared_breathing2.wav",
|
||||
"ambient/creatures/town_scared_sob1.wav",
|
||||
"ambient/creatures/town_scared_sob2.wav",
|
||||
"ambient/creatures/town_zombie_call1.wav"
|
||||
}
|
||||
if (! file.Exists("prop_hunt/sounds_taunt_prop.txt", "DATA")) then
|
||||
file.Write("prop_hunt/sounds_taunt_prop.txt", util.TableToKeyValues(PROP_TAUNTS))
|
||||
end
|
||||
local fileContent = file.Read("prop_hunt/sounds_taunt_prop.txt", "DATA");
|
||||
if fileContent then
|
||||
local fileTable = util.KeyValuesToTable(fileContent)
|
||||
if fileTable then PROP_TAUNTS = fileTable end
|
||||
end
|
||||
@@ -26,14 +26,23 @@
|
||||
--! Gamemode Information
|
||||
-- ------------------------------------------------------------------------- --
|
||||
GM.Name = "Prop Hunt Extended"
|
||||
GM.Author = "Michael Fabian 'Xaymar' Dirks"
|
||||
GM.Email = "info@xaymar.com"
|
||||
GM.Author = "Michael 'Xaymar' Dirks (Based on Kow@lskis Version, Original by AMT)"
|
||||
GM.Email = "michael.fabian.dirks@gmail.com"
|
||||
GM.Website = "http://xaymar.com/"
|
||||
|
||||
GM.TeamBased = true
|
||||
GM.AllowAutoTeam = true
|
||||
GM.SecondsBetweenTeamSwitches = 10
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Includes
|
||||
-- ------------------------------------------------------------------------- --
|
||||
-- Player Classes
|
||||
include "player_class/class_default.lua"
|
||||
include "player_class/class_spectator.lua"
|
||||
include "player_class/class_seeker.lua"
|
||||
include "player_class/class_hider.lua"
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Code
|
||||
-- ------------------------------------------------------------------------- --
|
||||
@@ -46,6 +55,12 @@ GM.States.Seek = 3
|
||||
GM.States.PostRound = 4
|
||||
GM.States.PostMatch = 5
|
||||
|
||||
-- Game Modes
|
||||
GM.Modes = {}
|
||||
GM.Modes.Original = 0
|
||||
GM.Modes.SwizzleEffect = 1 -- Randomizes Teams each Round
|
||||
GM.Modes.TheDeadHunt = 2 -- One Hunter, Dead Prop become Hunter, Props can't see each other.
|
||||
|
||||
-- Teams
|
||||
GM.Teams = {}
|
||||
GM.Teams.Spectators = 0
|
||||
@@ -56,8 +71,6 @@ function GM:CreateTeams()
|
||||
-- Specators
|
||||
team.SetUp(self.Teams.Spectators, "Spectators", Color(127, 127, 127, 255))
|
||||
team.SetSpawnPoint(self.Teams.Spectators, {
|
||||
"info_player_start",
|
||||
"info_player_spawn",
|
||||
"info_player_deathmatch",
|
||||
"info_player_combine",
|
||||
"info_player_counterterrorist",
|
||||
@@ -69,7 +82,6 @@ function GM:CreateTeams()
|
||||
-- Seekers: "Hunters"
|
||||
team.SetUp(self.Teams.Seekers, "Seekers", Color(0, 128, 255, 255))
|
||||
team.SetSpawnPoint(self.Teams.Seekers, {
|
||||
"info_player_start",
|
||||
"info_player_spawn",
|
||||
"info_player_deathmatch",
|
||||
"info_player_combine",
|
||||
@@ -80,7 +92,6 @@ function GM:CreateTeams()
|
||||
-- Hiders: "Props"
|
||||
team.SetUp(self.Teams.Hiders, "Hiders", Color(255, 128, 0, 255))
|
||||
team.SetSpawnPoint(self.Teams.Hiders, {
|
||||
"info_player_start",
|
||||
"info_player_spawn",
|
||||
"info_player_deathmatch",
|
||||
"info_player_allies",
|
||||
@@ -100,47 +111,26 @@ function GM:PlayerTick(ply, mv)
|
||||
return player_manager.RunClass(ply, "Tick", mv)
|
||||
end
|
||||
|
||||
function GM:FindUseEntity(ply, defaultEnt)
|
||||
return player_manager.RunClass(ply, "FindUseEntity", defaultEnt)
|
||||
function GM:PlayerHurt(victim, attacker, healthRemaining, damageTaken)
|
||||
if (victim != nil && victim:IsPlayer()) then
|
||||
player_manager.RunClass(victim, "Hurt", victim, attacker, healthRemaining, damageTaken)
|
||||
end
|
||||
if (attacker != nil && attacker:IsPlayer()) then
|
||||
player_manager.RunClass(attacker, "Damage", victim, attacker, healthRemaining, damageTaken)
|
||||
end
|
||||
end
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Gamemode Functionality
|
||||
-- ------------------------------------------------------------------------- --
|
||||
function GM:GetRound()
|
||||
return GetGlobalInt("Round", 0)
|
||||
function GM:GetRoundState()
|
||||
return GetGlobalInt("RoundState", self.States.PreMatch)
|
||||
end
|
||||
|
||||
function GM:GetRoundTime()
|
||||
return GetGlobalInt("RoundTime", 0)
|
||||
end
|
||||
|
||||
function GM:GetRoundState()
|
||||
return GetGlobalInt("RoundState", self.States.PreMatch)
|
||||
end
|
||||
|
||||
function GM:GetRoundStateTime()
|
||||
return GetGlobalInt("RoundStateTime", 0)
|
||||
end
|
||||
|
||||
function GM:GetRoundWinner()
|
||||
return GetGlobalInt("RoundWinner", GAMEMODE.Teams.Spectator)
|
||||
end
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Includes
|
||||
-- ------------------------------------------------------------------------- --
|
||||
-- Defines
|
||||
include "sh_defines.lua"
|
||||
|
||||
-- Meta
|
||||
include "meta/player.lua"
|
||||
|
||||
-- Configuration
|
||||
include "sh_config.lua"
|
||||
|
||||
-- Player Classes
|
||||
include "player_class/class_default.lua"
|
||||
include "player_class/class_spectator.lua"
|
||||
include "player_class/class_seeker.lua"
|
||||
include "player_class/class_hider.lua"
|
||||
end
|
||||
@@ -0,0 +1,49 @@
|
||||
-- Finds the player meta table or terminates
|
||||
local meta = FindMetaTable("Player")
|
||||
if !meta then return end
|
||||
|
||||
-- Blinds the player by setting view out into the void
|
||||
function meta:Blind(bool)
|
||||
if !self:IsValid() then return end
|
||||
|
||||
if SERVER then
|
||||
umsg.Start("SetBlind", self)
|
||||
if bool then
|
||||
umsg.Bool(true)
|
||||
else
|
||||
umsg.Bool(false)
|
||||
end
|
||||
umsg.End()
|
||||
elseif CLIENT then
|
||||
blind = bool
|
||||
end
|
||||
end
|
||||
|
||||
-- Blinds the player by setting view out into the void
|
||||
function meta:RemoveProp()
|
||||
if CLIENT || !self:IsValid() then return end
|
||||
|
||||
if self.ph_prop && self.ph_prop:IsValid() then
|
||||
self.ph_prop:Remove()
|
||||
self.ph_prop = nil
|
||||
end
|
||||
end
|
||||
|
||||
-- Sets a new Hull for a player.
|
||||
function meta:NewHull(hullOBBMin, hullOBBMax)
|
||||
if !self:IsValid() then return end
|
||||
if hullOBBMax == nil then return end
|
||||
if hullOBBMin == nil then return end
|
||||
|
||||
local hullOBB = hullOBBMax - hullOBBMin
|
||||
local hullOBBXY = math.max(hullOBB.x, hullOBB.y)
|
||||
|
||||
local xyMul = 0.5
|
||||
local hullMin = Vector(-hullOBBXY * xyMul, -hullOBBXY * xyMul, 0)
|
||||
local hullMax = Vector( hullOBBXY * xyMul, hullOBBXY * xyMul, hullOBB.z)
|
||||
|
||||
self:SetHull(hullMin, hullMax)
|
||||
self:SetHullDuck(hullMin, hullMax)
|
||||
self:SetViewOffset(Vector(0, 0, hullOBB.z))
|
||||
self:SetViewOffsetDucked(Vector(0, 0, hullOBB.z / 2.0))
|
||||
end
|
||||
|
After Width: | Height: | Size: 52 KiB |
|
After Width: | Height: | Size: 152 KiB |
@@ -0,0 +1,182 @@
|
||||
"prophuntextended"
|
||||
{
|
||||
"base" "base"
|
||||
"title" "Prop Hunt Extended"
|
||||
"maps" "^ph_|^cs_|^de_|^ttt_"
|
||||
"menusystem" "1"
|
||||
"workshopid" "468149739"
|
||||
|
||||
"settings"
|
||||
{
|
||||
// Game Settings
|
||||
1
|
||||
{
|
||||
"name" "ph_gamemode"
|
||||
"text" "G: Game Mode"
|
||||
"help" "0: Basic, 1: Swizzle Effect (Random Teams), 2: The Dead Hunt (One Hunter, Dead Props become Hunters)"
|
||||
"type" "Numeric"
|
||||
"default" "0"
|
||||
}
|
||||
|
||||
2
|
||||
{
|
||||
"name" "mp_timelimit"
|
||||
"text" "G: Time Limit"
|
||||
"help" "Time Limit in Minutes for how long should we stay on one map. (0 to disable)"
|
||||
"type" "Numeric"
|
||||
"default" "20"
|
||||
}
|
||||
|
||||
3
|
||||
{
|
||||
"name" "ph_sprinting"
|
||||
"text" "G: Enable Sprinting"
|
||||
"help" "Should sprinting be possible?"
|
||||
"type" "CheckBox"
|
||||
"default" "0"
|
||||
}
|
||||
|
||||
4
|
||||
{
|
||||
"name" "ph_tauntcooldown"
|
||||
"text" "G: Taunt Cooldown"
|
||||
"help" "How much time must pass before another taunt may be played."
|
||||
"type" "Numeric"
|
||||
"default" "5"
|
||||
}
|
||||
|
||||
// Round Settings
|
||||
10
|
||||
{
|
||||
"name" "ph_round_limit"
|
||||
"text" "R: Rounds per Map"
|
||||
"help" "How many rounds are played per map."
|
||||
"type" "Numeric"
|
||||
"default" "10"
|
||||
}
|
||||
|
||||
11
|
||||
{
|
||||
"name" "ph_round_timelimit"
|
||||
"text" "R: Round Duration (Seconds)"
|
||||
"help" "How long is each round going to last?"
|
||||
"type" "Numeric"
|
||||
"default" "300"
|
||||
}
|
||||
|
||||
12
|
||||
{
|
||||
"name" "ph_round_blindtime"
|
||||
"text" "R: Hiding Time (Seconds)"
|
||||
"help" "How long are hunters blinded? (positive values will be inside the round time limit, negative will add to the round time limit)"
|
||||
"type" "Numeric"
|
||||
"default" "30"
|
||||
}
|
||||
|
||||
// Seeker Settings
|
||||
20
|
||||
{
|
||||
"name" "ph_seeker_health"
|
||||
"text" "S: Health"
|
||||
"type" "Numeric"
|
||||
"default" "100"
|
||||
}
|
||||
|
||||
21
|
||||
{
|
||||
"name" "ph_seeker_health_max"
|
||||
"text" "S: Max Health"
|
||||
"type" "Numeric"
|
||||
"default" "100"
|
||||
}
|
||||
|
||||
22
|
||||
{
|
||||
"name" "ph_seeker_health_bonus"
|
||||
"text" "S: Health Kill-Bonus"
|
||||
"help" "Health gained on kill."
|
||||
"type" "Numeric"
|
||||
"default" "20"
|
||||
}
|
||||
|
||||
23
|
||||
{
|
||||
"name" "ph_seeker_health_penalty"
|
||||
"text" "S: Health Penalty"
|
||||
"help" "Health lost on wrong shot."
|
||||
"type" "Numeric"
|
||||
"default" "5"
|
||||
}
|
||||
|
||||
24
|
||||
{
|
||||
"name" "ph_seeker_weapons"
|
||||
"text" "S: Weapons to be given to Seekers"
|
||||
"help" "Format: Weapon,Weapon,..."
|
||||
"type" "Text"
|
||||
"default" "weapon_crowbar,weapon_pistol,weapon_ph_smg,weapon_shotgun,weapon_physcannon"
|
||||
}
|
||||
|
||||
25
|
||||
{
|
||||
"name" "ph_seeker_ammo"
|
||||
"text" "S: Ammo to give to Seekers"
|
||||
"help" "Format: Name:Amount,Name:Amount,..."
|
||||
"type" "Text"
|
||||
"default" "Pistol:100,SMG1:300,SMG1_Grenade:1,Buckshot:64"
|
||||
}
|
||||
|
||||
// Hider Settings
|
||||
30
|
||||
{
|
||||
"name" "ph_hider_health"
|
||||
"text" "H: Health"
|
||||
"type" "Numeric"
|
||||
"default" "100"
|
||||
}
|
||||
|
||||
31
|
||||
{
|
||||
"name" "ph_hider_health_max"
|
||||
"text" "H: Max Health"
|
||||
"type" "Numeric"
|
||||
"default" "100"
|
||||
}
|
||||
|
||||
32
|
||||
{
|
||||
"name" "ph_hider_health_scaling"
|
||||
"text" "H: Enable Health Scaling"
|
||||
"help" "Larger & heavier objects have more health, smaller less."
|
||||
"type" "CheckBox"
|
||||
"default" "1"
|
||||
}
|
||||
|
||||
33
|
||||
{
|
||||
"name" "ph_hider_health_scaling_max"
|
||||
"text" "H: Scaled Max Health"
|
||||
"type" "Numeric"
|
||||
"default" "200"
|
||||
}
|
||||
|
||||
// Whitelist & Blacklist
|
||||
40
|
||||
{
|
||||
"name" "ph_list_class_whitelist"
|
||||
"text" "L: Allowed Entity Classes"
|
||||
"help" "Hiders can only use these for changing model and skin."
|
||||
"type" "Text"
|
||||
"default" "ph_prop,prop_physics,prop_physics_multiplayer,prop_physics_respawnable"
|
||||
}
|
||||
|
||||
41
|
||||
{
|
||||
"name" "ph_list_abuse_blacklist"
|
||||
"text" "L: Abuse Blacklist"
|
||||
"help" "Fix interact spam with certain entities so that all areas stay accessible."
|
||||
"type" "Text"
|
||||
"default" ""func_button,func_door,func_door_rotation,prop_door_rotation,func_tracktrain,func_tanktrain,func_breakable""
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
@ECHO OFF
|
||||
:: Retrieve Garry's Mod path from Regristry
|
||||
:: FOR /F "tokens=2* delims= " %%A IN ('REG QUERY "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 4000" /v InstallLocation') DO SET "GARRYSMODPATH=%%B"
|
||||
SET "GARRYSMODPATH=C:\Program Files (x86)\Steam\steamapps\common\GarrysMod"
|
||||
|
||||
SET "PATH=%CD%;%GARRYSMODPATH%\bin;%PATH%"
|
||||
CMD
|
||||
@@ -0,0 +1,6 @@
|
||||
@ECHO OFF
|
||||
SET "PWD=%~dp0"
|
||||
CALL build-env.bat
|
||||
|
||||
"%TOOLPATH%\bin\gmad.exe" create -folder "%PWD%\Source" -out "%PWD%\Pack.gma"
|
||||
PAUSE
|
||||
@@ -0,0 +1,6 @@
|
||||
@ECHO OFF
|
||||
SET "PWD=%~dp0"
|
||||
CALL build-env.bat
|
||||
|
||||
"%GARRYSMODPATH%\bin\gmpublish.exe" update -id %WORKSHOPID% -icon "Logo.jpg" -addon "Pack.gma" -changes ""
|
||||
PAUSE
|
||||
@@ -0,0 +1,2 @@
|
||||
SET "WORKSHOPID=468149739"
|
||||
FOR /F "tokens=2* delims= " %%A IN ('REG QUERY "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 4000" /v InstallLocation') DO SET "TOOLPATH=%%B"
|
||||
@@ -1,11 +0,0 @@
|
||||
[h1]Version: 1.4.0[/h1]
|
||||
The round manager has been rewritten to improve code quality and reusability and is now using meta-classes, which slightly improves overall performance. For addons that hook into the gamemode, this means that GAMEMODE.RoundManager is only valid after GM:Initialize() has been run.
|
||||
|
||||
Additionally the Prop Hunt SMG has been slightly changed and now fires at a rate of 0.075 (from 0.1), but deals only 4 damage (from 5), which makes it near identical to the standard Half Life 2 SMG. It will now deal 53.33 DPS instead of 50 DPS like before, while keeping the accuracy and extra features as is.
|
||||
|
||||
[b]Changelog:[/b]
|
||||
[list][*]Changed Prop Hunt SMD Refire Time from 0.1 to 0.075.
|
||||
[*]Fixed Seekers not gaining health back after killing a Hider.
|
||||
[*]Fixed some debug log messages by Prop Rotation appearing without debug log being enabled.
|
||||
[*]Rewrote the round manager to use a class based system.
|
||||
[list]
|
||||
@@ -1,102 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="32"
|
||||
height="32"
|
||||
viewBox="0 0 8.4666667 8.4666667"
|
||||
version="1.1"
|
||||
id="svg8"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)"
|
||||
sodipodi:docname="icon.svg"
|
||||
inkscape:export-filename="D:\Projects\GarrysMod\PropHuntExtended\media\rendered\icon.png"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96">
|
||||
<defs
|
||||
id="defs2" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="32"
|
||||
inkscape:cx="22.42927"
|
||||
inkscape:cy="16.716875"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer3"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
inkscape:window-width="2880"
|
||||
inkscape:window-height="1620"
|
||||
inkscape:window-x="4068"
|
||||
inkscape:window-y="228"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-288.53332)">
|
||||
<rect
|
||||
style="display:inline;fill:#433a35;fill-opacity:1;stroke-width:0.0073266"
|
||||
id="rect4532"
|
||||
width="8.4666662"
|
||||
height="8.4666662"
|
||||
x="0"
|
||||
y="288.53333" />
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer2"
|
||||
inkscape:label="Layer 2"
|
||||
style="display:inline">
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:9.64581013px;line-height:1.25;font-family:Impact;-inkscape-font-specification:Impact;letter-spacing:0px;word-spacing:0px;fill:#f2722b;fill-opacity:1;stroke:none;stroke-width:1.80858934"
|
||||
x="-0.39562893"
|
||||
y="267.48511"
|
||||
id="text817"
|
||||
transform="matrix(0.90062328,0,0,1.1103422,0,-288.53331)"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan815"
|
||||
x="-0.39562893"
|
||||
y="267.48511"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Impact;-inkscape-font-specification:Impact;fill:#f2722b;fill-opacity:1;stroke-width:1.80858934">PH</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer3"
|
||||
inkscape:label="Layer 3">
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:6.02445936px;line-height:1.25;font-family:Impact;-inkscape-font-specification:Impact;letter-spacing:0px;word-spacing:0px;fill:#fffff7;fill-opacity:1;stroke:none;stroke-width:1.12958598"
|
||||
x="1.3681852"
|
||||
y="8.4666901"
|
||||
id="text821"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan819"
|
||||
x="1.3681852"
|
||||
y="8.4666901"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Impact;-inkscape-font-specification:Impact;fill:#fffff7;fill-opacity:1;stroke-width:1.12958598">EX</tspan></text>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 120 KiB |
@@ -1,213 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="8192"
|
||||
height="1024"
|
||||
viewBox="0 0 2167.4666 270.93334"
|
||||
version="1.1"
|
||||
id="svg4530"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)"
|
||||
sodipodi:docname="logo-wide-transparent.svg"
|
||||
style="enable-background:new"
|
||||
inkscape:export-filename="D:\Projects\GarrysMod\PropHuntExtended\source\gamemodes\prophuntextended\logo.png"
|
||||
inkscape:export-xdpi="24"
|
||||
inkscape:export-ydpi="24">
|
||||
<defs
|
||||
id="defs4524">
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Sstart"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow1Sstart"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path6765"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 Z"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt"
|
||||
transform="matrix(0.2,0,0,0.2,1.2,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Lstart"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow1Lstart"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path6753"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 Z"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt"
|
||||
transform="matrix(0.8,0,0,0.8,10,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<linearGradient
|
||||
id="linearGradient6153"
|
||||
osb:paint="solid">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop6151" />
|
||||
</linearGradient>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB"
|
||||
id="filter7370"
|
||||
inkscape:label="text-extended-filter"
|
||||
x="-0.02"
|
||||
width="1.04">
|
||||
<feGaussianBlur
|
||||
stdDeviation="1"
|
||||
id="feGaussianBlur7374"
|
||||
result="result4" />
|
||||
<feGaussianBlur
|
||||
stdDeviation="2"
|
||||
id="feGaussianBlur7376"
|
||||
in="SourceGraphic"
|
||||
result="result2" />
|
||||
<feGaussianBlur
|
||||
stdDeviation="4"
|
||||
id="feGaussianBlur7378"
|
||||
in="SourceGraphic"
|
||||
result="result1" />
|
||||
<feBlend
|
||||
mode="screen"
|
||||
in2="result2"
|
||||
id="feBlend7380"
|
||||
result="result3"
|
||||
in="result1" />
|
||||
<feBlend
|
||||
mode="screen"
|
||||
in2="result4"
|
||||
id="feBlend7382"
|
||||
result="result5" />
|
||||
<feBlend
|
||||
mode="screen"
|
||||
in2="SourceGraphic"
|
||||
id="feBlend7384"
|
||||
result="result7" />
|
||||
</filter>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.27854414"
|
||||
inkscape:cx="4871.459"
|
||||
inkscape:cy="1967.7857"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer3"
|
||||
showgrid="false"
|
||||
showborder="true"
|
||||
inkscape:pagecheckerboard="true"
|
||||
units="px"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2080"
|
||||
inkscape:window-x="3829"
|
||||
inkscape:window-y="-11"
|
||||
inkscape:window-maximized="1"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true">
|
||||
<sodipodi:guide
|
||||
position="541.86667,270.93333"
|
||||
orientation="0,1"
|
||||
id="guide4543"
|
||||
inkscape:locked="false"
|
||||
inkscape:label=""
|
||||
inkscape:color="rgb(0,0,255)" />
|
||||
<sodipodi:guide
|
||||
position="541.86667,270.93334"
|
||||
orientation="1,0"
|
||||
id="guide4545"
|
||||
inkscape:locked="false"
|
||||
inkscape:label=""
|
||||
inkscape:color="rgb(0,0,255)" />
|
||||
<sodipodi:guide
|
||||
position="541.86667,406.4"
|
||||
orientation="0,1"
|
||||
id="guide4547"
|
||||
inkscape:locked="false"
|
||||
inkscape:label=""
|
||||
inkscape:color="rgb(0,0,255)" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata4527">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Text EXTENDED"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-26.066643)"
|
||||
style="display:inline">
|
||||
<g
|
||||
style="display:inline;stroke:#f2722b;stroke-width:14.74307919;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal;filter:url(#filter7370)"
|
||||
transform="matrix(0.82040111,0,0,0.82040111,1119.0696,23.456852)"
|
||||
inkscape:label="Layer 1"
|
||||
id="g7255">
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:316.34109497px;line-height:1.25;font-family:Impact;-inkscape-font-specification:Impact;letter-spacing:0px;word-spacing:0px;fill:none;fill-opacity:1;stroke:#f2722b;stroke-width:14.57606602;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal"
|
||||
x="-10.334827"
|
||||
y="293.34174"
|
||||
id="text7253"><tspan
|
||||
dx="0"
|
||||
sodipodi:role="line"
|
||||
id="tspan7251"
|
||||
x="-10.334827"
|
||||
y="293.34174"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:273.42272949px;font-family:Impact;-inkscape-font-specification:Impact;letter-spacing:4.85868835px;fill:none;fill-opacity:1;stroke:#f2722b;stroke-width:14.57606602;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal">EXTENDED</tspan></text>
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer2"
|
||||
inkscape:label="Text PROP HUNT"
|
||||
style="display:inline"
|
||||
transform="translate(0,-270.93333)">
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer3"
|
||||
inkscape:label="Background"
|
||||
style="display:inline" />
|
||||
<g
|
||||
transform="matrix(0.95541658,0,0,0.99515462,383.45565,251.14939)"
|
||||
id="layer1-9"
|
||||
inkscape:label="Ebene 1"
|
||||
style="fill:#f2722b;fill-opacity:1;fill-rule:nonzero">
|
||||
<text
|
||||
id="text3715"
|
||||
y="255.2442"
|
||||
x="-387.08383"
|
||||
style="font-style:normal;font-weight:normal;font-size:251.06704712px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#f2722b;fill-opacity:1;fill-rule:nonzero"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Impact;-inkscape-font-specification:Impact;fill:#f2722b;fill-opacity:1;fill-rule:nonzero"
|
||||
y="255.2442"
|
||||
x="-387.08383"
|
||||
id="tspan3713"
|
||||
sodipodi:role="line">PROP HUNT</tspan></text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 7.2 KiB |
@@ -1,221 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="8192"
|
||||
height="1024"
|
||||
viewBox="0 0 2167.4666 270.93334"
|
||||
version="1.1"
|
||||
id="svg4530"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)"
|
||||
sodipodi:docname="logo-wide.svg"
|
||||
style="enable-background:new"
|
||||
inkscape:export-filename="D:\Projects\GarrysMod\PropHuntExtended\media\rendered\logo-wide.png"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96">
|
||||
<defs
|
||||
id="defs4524">
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Sstart"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow1Sstart"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path6765"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 Z"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt"
|
||||
transform="matrix(0.2,0,0,0.2,1.2,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Lstart"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow1Lstart"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path6753"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 Z"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt"
|
||||
transform="matrix(0.8,0,0,0.8,10,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<linearGradient
|
||||
id="linearGradient6153"
|
||||
osb:paint="solid">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop6151" />
|
||||
</linearGradient>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB"
|
||||
id="filter7370"
|
||||
inkscape:label="text-extended-filter"
|
||||
x="-0.02"
|
||||
width="1.04">
|
||||
<feGaussianBlur
|
||||
stdDeviation="1"
|
||||
id="feGaussianBlur7374"
|
||||
result="result4" />
|
||||
<feGaussianBlur
|
||||
stdDeviation="2"
|
||||
id="feGaussianBlur7376"
|
||||
in="SourceGraphic"
|
||||
result="result2" />
|
||||
<feGaussianBlur
|
||||
stdDeviation="4"
|
||||
id="feGaussianBlur7378"
|
||||
in="SourceGraphic"
|
||||
result="result1" />
|
||||
<feBlend
|
||||
mode="screen"
|
||||
in2="result2"
|
||||
id="feBlend7380"
|
||||
result="result3"
|
||||
in="result1" />
|
||||
<feBlend
|
||||
mode="screen"
|
||||
in2="result4"
|
||||
id="feBlend7382"
|
||||
result="result5" />
|
||||
<feBlend
|
||||
mode="screen"
|
||||
in2="SourceGraphic"
|
||||
id="feBlend7384"
|
||||
result="result7" />
|
||||
</filter>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.27854414"
|
||||
inkscape:cx="5596.6582"
|
||||
inkscape:cy="1967.7857"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
showborder="true"
|
||||
inkscape:pagecheckerboard="true"
|
||||
units="px"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2080"
|
||||
inkscape:window-x="3829"
|
||||
inkscape:window-y="-11"
|
||||
inkscape:window-maximized="1"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true">
|
||||
<sodipodi:guide
|
||||
position="541.86667,270.93333"
|
||||
orientation="0,1"
|
||||
id="guide4543"
|
||||
inkscape:locked="false"
|
||||
inkscape:label=""
|
||||
inkscape:color="rgb(0,0,255)" />
|
||||
<sodipodi:guide
|
||||
position="541.86667,270.93334"
|
||||
orientation="1,0"
|
||||
id="guide4545"
|
||||
inkscape:locked="false"
|
||||
inkscape:label=""
|
||||
inkscape:color="rgb(0,0,255)" />
|
||||
<sodipodi:guide
|
||||
position="541.86667,406.4"
|
||||
orientation="0,1"
|
||||
id="guide4547"
|
||||
inkscape:locked="false"
|
||||
inkscape:label=""
|
||||
inkscape:color="rgb(0,0,255)" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata4527">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Text EXTENDED"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-26.066643)"
|
||||
style="display:inline">
|
||||
<g
|
||||
style="display:inline;stroke:#f2722b;stroke-width:14.74307919;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal;filter:url(#filter7370)"
|
||||
transform="matrix(0.82040111,0,0,0.82040111,1119.0696,23.456852)"
|
||||
inkscape:label="Layer 1"
|
||||
id="g7255">
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:316.34109497px;line-height:1.25;font-family:Impact;-inkscape-font-specification:Impact;letter-spacing:0px;word-spacing:0px;fill:none;fill-opacity:1;stroke:#f2722b;stroke-width:14.57606602;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal"
|
||||
x="-10.334827"
|
||||
y="293.34174"
|
||||
id="text7253"><tspan
|
||||
dx="0"
|
||||
sodipodi:role="line"
|
||||
id="tspan7251"
|
||||
x="-10.334827"
|
||||
y="293.34174"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:273.42272949px;font-family:Impact;-inkscape-font-specification:Impact;letter-spacing:4.85868835px;fill:none;fill-opacity:1;stroke:#f2722b;stroke-width:14.57606602;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal">EXTENDED</tspan></text>
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer2"
|
||||
inkscape:label="Text PROP HUNT"
|
||||
style="display:inline"
|
||||
transform="translate(0,-270.93333)">
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer3"
|
||||
inkscape:label="Background"
|
||||
style="display:inline">
|
||||
<rect
|
||||
style="display:inline;fill:#433a35;fill-opacity:1;stroke-width:0.46890202"
|
||||
id="rect4532"
|
||||
width="1083.7333"
|
||||
height="270.93332"
|
||||
x="1.110223e-016"
|
||||
y="270.93335" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(0.95541658,0,0,0.99515462,383.45565,251.14939)"
|
||||
id="layer1-9"
|
||||
inkscape:label="Ebene 1"
|
||||
style="fill:#f2722b;fill-opacity:1;fill-rule:nonzero">
|
||||
<text
|
||||
id="text3715"
|
||||
y="255.2442"
|
||||
x="-387.08383"
|
||||
style="font-style:normal;font-weight:normal;font-size:251.06704712px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#f2722b;fill-opacity:1;fill-rule:nonzero"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Impact;-inkscape-font-specification:Impact;fill:#f2722b;fill-opacity:1;fill-rule:nonzero"
|
||||
y="255.2442"
|
||||
x="-387.08383"
|
||||
id="tspan3713"
|
||||
sodipodi:role="line">PROP HUNT</tspan></text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 7.4 KiB |
@@ -1,219 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="4096"
|
||||
height="2048"
|
||||
viewBox="0 0 1083.7333 541.86668"
|
||||
version="1.1"
|
||||
id="svg4530"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)"
|
||||
sodipodi:docname="logo.svg"
|
||||
enable-background="new"
|
||||
inkscape:export-filename="D:\Projects\GarrysMod\PropHuntExtended\media\rendered\logo.png"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96">
|
||||
<defs
|
||||
id="defs4524">
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Sstart"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="Arrow1Sstart"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path6765"
|
||||
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt"
|
||||
transform="scale(0.2) translate(6,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Lstart"
|
||||
orient="auto"
|
||||
refY="0.0"
|
||||
refX="0.0"
|
||||
id="Arrow1Lstart"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path6753"
|
||||
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt"
|
||||
transform="scale(0.8) translate(12.5,0)" />
|
||||
</marker>
|
||||
<linearGradient
|
||||
id="linearGradient6153"
|
||||
osb:paint="solid">
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop6151" />
|
||||
</linearGradient>
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB"
|
||||
id="filter7370"
|
||||
inkscape:label="text-extended-filter"
|
||||
x="-0.02"
|
||||
width="1.04">
|
||||
<feGaussianBlur
|
||||
stdDeviation="1"
|
||||
id="feGaussianBlur7374"
|
||||
result="result4" />
|
||||
<feGaussianBlur
|
||||
stdDeviation="2"
|
||||
id="feGaussianBlur7376"
|
||||
in="SourceGraphic"
|
||||
result="result2" />
|
||||
<feGaussianBlur
|
||||
stdDeviation="4"
|
||||
id="feGaussianBlur7378"
|
||||
in="SourceGraphic"
|
||||
result="result1" />
|
||||
<feBlend
|
||||
mode="screen"
|
||||
in2="result2"
|
||||
id="feBlend7380"
|
||||
result="result3"
|
||||
in="result1" />
|
||||
<feBlend
|
||||
mode="screen"
|
||||
in2="result4"
|
||||
id="feBlend7382"
|
||||
result="result5" />
|
||||
<feBlend
|
||||
mode="screen"
|
||||
in2="SourceGraphic"
|
||||
id="feBlend7384"
|
||||
result="result7" />
|
||||
</filter>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.7878418"
|
||||
inkscape:cx="1533.9593"
|
||||
inkscape:cy="1030.2533"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
showborder="true"
|
||||
inkscape:pagecheckerboard="true"
|
||||
units="px"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2080"
|
||||
inkscape:window-x="3829"
|
||||
inkscape:window-y="-11"
|
||||
inkscape:window-maximized="1"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true">
|
||||
<sodipodi:guide
|
||||
position="541.86667,270.93333"
|
||||
orientation="0,1"
|
||||
id="guide4543"
|
||||
inkscape:locked="false"
|
||||
inkscape:label=""
|
||||
inkscape:color="rgb(0,0,255)" />
|
||||
<sodipodi:guide
|
||||
position="541.86667,270.93334"
|
||||
orientation="1,0"
|
||||
id="guide4545"
|
||||
inkscape:locked="false"
|
||||
inkscape:label=""
|
||||
inkscape:color="rgb(0,0,255)" />
|
||||
<sodipodi:guide
|
||||
position="541.86667,406.4"
|
||||
orientation="0,1"
|
||||
id="guide4547"
|
||||
inkscape:locked="false"
|
||||
inkscape:label=""
|
||||
inkscape:color="rgb(0,0,255)" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata4527">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Text EXTENDED"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,244.86669)"
|
||||
style="display:inline;">
|
||||
<g
|
||||
style="display:inline;stroke:#f2722b;stroke-width:14.74307919;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal;filter:url(#filter7370)"
|
||||
transform="matrix(0.82040111,0,0,0.82040111,37.679834,22.343453)"
|
||||
inkscape:label="Layer 1"
|
||||
id="g7255">
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:316.34109497px;line-height:1.25;font-family:Impact;-inkscape-font-specification:Impact;letter-spacing:0px;word-spacing:0px;fill:none;fill-opacity:1;stroke:#f2722b;stroke-width:14.57606602;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal"
|
||||
x="-10.334827"
|
||||
y="293.34174"
|
||||
id="text7253"><tspan
|
||||
dx="0"
|
||||
sodipodi:role="line"
|
||||
id="tspan7251"
|
||||
x="-10.334827"
|
||||
y="293.34174"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:273.42272949px;font-family:Impact;-inkscape-font-specification:Impact;letter-spacing:4.85868835px;fill:none;fill-opacity:1;stroke:#f2722b;stroke-width:14.57606602;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal">EXTENDED</tspan></text>
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer2"
|
||||
inkscape:label="Text PROP HUNT"
|
||||
style="display:inline">
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer3"
|
||||
inkscape:label="Background"
|
||||
style="display:inline">
|
||||
<rect
|
||||
transform="translate(0,244.86669)"
|
||||
style="display:inline;fill:#433a35;fill-opacity:1;stroke-width:0.46890202"
|
||||
id="rect4532"
|
||||
width="1083.7333"
|
||||
height="270.93332"
|
||||
x="1.110223e-016"
|
||||
y="-244.86668" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(0.95541658,0,0,0.99515462,383.45565,-19.78395)"
|
||||
id="layer1-9"
|
||||
inkscape:label="Ebene 1"
|
||||
style="fill:#f2722b;fill-opacity:1;fill-rule:nonzero">
|
||||
<text
|
||||
id="text3715"
|
||||
y="255.2442"
|
||||
x="-387.08383"
|
||||
style="font-style:normal;font-weight:normal;font-size:251.06704712px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#f2722b;fill-opacity:1;fill-rule:nonzero"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Impact;-inkscape-font-specification:Impact;fill:#f2722b;fill-opacity:1;fill-rule:nonzero"
|
||||
y="255.2442"
|
||||
x="-387.08383"
|
||||
id="tspan3713"
|
||||
sodipodi:role="line">PROP HUNT</tspan></text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 7.4 KiB |
@@ -1,110 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="210mm"
|
||||
height="297mm"
|
||||
viewBox="0 0 210 297"
|
||||
version="1.1"
|
||||
id="svg6163"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)"
|
||||
sodipodi:docname="title-extended.svg">
|
||||
<defs
|
||||
id="defs6157">
|
||||
<filter
|
||||
style="color-interpolation-filters:sRGB"
|
||||
id="filter7370"
|
||||
inkscape:label="text-extended-filter">
|
||||
<feGaussianBlur
|
||||
stdDeviation="1"
|
||||
id="feGaussianBlur7374"
|
||||
result="result4" />
|
||||
<feGaussianBlur
|
||||
stdDeviation="2"
|
||||
id="feGaussianBlur7376"
|
||||
in="SourceGraphic"
|
||||
result="result2" />
|
||||
<feGaussianBlur
|
||||
stdDeviation="4"
|
||||
id="feGaussianBlur7378"
|
||||
in="SourceGraphic"
|
||||
result="result1" />
|
||||
<feBlend
|
||||
mode="screen"
|
||||
in2="result2"
|
||||
id="feBlend7380"
|
||||
result="result3"
|
||||
in="result1" />
|
||||
<feBlend
|
||||
mode="screen"
|
||||
in2="result4"
|
||||
id="feBlend7382"
|
||||
result="result5" />
|
||||
<feBlend
|
||||
mode="screen"
|
||||
in2="SourceGraphic"
|
||||
id="feBlend7384"
|
||||
result="result7" />
|
||||
</filter>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.35"
|
||||
inkscape:cx="-77.142857"
|
||||
inkscape:cy="560"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2080"
|
||||
inkscape:window-x="3829"
|
||||
inkscape:window-y="-11"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata6160">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<g
|
||||
style="display:inline;stroke:#f2722b;stroke-width:14.74307919;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal;filter:url(#filter7370)"
|
||||
transform="matrix(0.82040111,0,0,0.82040111,98.238237,35.82582)"
|
||||
inkscape:label="Layer 1"
|
||||
id="g7255">
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:316.34109497px;line-height:1.25;font-family:Impact;-inkscape-font-specification:Impact;letter-spacing:0px;word-spacing:0px;fill:none;fill-opacity:1;stroke:#f2722b;stroke-width:14.57606602;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal"
|
||||
x="-10.334827"
|
||||
y="293.34174"
|
||||
id="text7253"><tspan
|
||||
dx="0"
|
||||
sodipodi:role="line"
|
||||
id="tspan7251"
|
||||
x="-10.334827"
|
||||
y="293.34174"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:273.42272949px;font-family:Impact;-inkscape-font-specification:Impact;letter-spacing:4.85868835px;fill:none;fill-opacity:1;stroke:#f2722b;stroke-width:14.57606602;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal">EXTENDED</tspan></text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 3.9 KiB |
@@ -1,88 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="4101.4619"
|
||||
height="781.65002"
|
||||
viewBox="0 0 1085.1785 206.81157"
|
||||
version="1.1"
|
||||
id="svg8"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)"
|
||||
sodipodi:docname="title-text.svg">
|
||||
<title
|
||||
id="title3717">Prop Hunt Title Text</title>
|
||||
<defs
|
||||
id="defs2" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.35"
|
||||
inkscape:cx="1186.9308"
|
||||
inkscape:cy="417.93638"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:pagecheckerboard="true"
|
||||
showborder="false"
|
||||
units="px"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="2080"
|
||||
inkscape:window-x="3829"
|
||||
inkscape:window-y="-11"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title>Prop Hunt Title Text</dc:title>
|
||||
<dc:creator>
|
||||
<cc:Agent>
|
||||
<dc:title>Michael Fabian Dirks <info@xaymar.com></dc:title>
|
||||
</cc:Agent>
|
||||
</dc:creator>
|
||||
<dc:rights>
|
||||
<cc:Agent>
|
||||
<dc:title></dc:title>
|
||||
</cc:Agent>
|
||||
</dc:rights>
|
||||
<dc:language>English</dc:language>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Ebene 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(376.78616,-52.600731)">
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:251.06704712px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#f2722b;fill-opacity:1;stroke:none;stroke-width:6.27667618;"
|
||||
x="-387.08383"
|
||||
y="255.2442"
|
||||
id="text3715"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3713"
|
||||
x="-387.08383"
|
||||
y="255.2442"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:Impact;-inkscape-font-specification:Impact;stroke-width:6.27667618;fill:#f2722b;fill-opacity:1;">PROP HUNT</tspan></text>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 140 KiB |
|
Before Width: | Height: | Size: 177 KiB |
@@ -1,31 +0,0 @@
|
||||
Hide n Seek with a twist - Hiders can turn into anything on the map! From bottles, to vending machines and all the way to huge cars - what you become depends on how you want to play. Do you want to blend in with your surroundings, or do you want to make a fool of the Seekers? And how will you deal with finding (and killing) all hiders as a Seeker?
|
||||
|
||||
The Gamemode comes with out of the box support for console configuration (ph_*), custom taunt support, prop rotation, an improved code base for modders and better integration and some other fixes. Support for [url=https://steamcommunity.com/sharedfiles/filedetails/?id=151583504]MapVote[/url] is also built in, so as long as you have a compatible addon installed you will get a map voting menu at the end of a match.
|
||||
|
||||
[h1]How To Play[/h1]
|
||||
[b]Seekers[/b]
|
||||
Your primary goal is to find hiders by any means possible. But watch out, you might lose health if you shoot an object that isn't actually a hider! Pick things up before shooting them, or simply remember the layout of the maps you are playing on. And remember: You lose if only a single hider is still alive at the end of the round.
|
||||
|
||||
[b]Hiders[/b]
|
||||
Stay alive as long as possible and make Seekers look like a fool. Dance around their feet, hide in plain sight or be that huge car that nobody though you could become! What you do is entirely up to you.
|
||||
|
||||
[b]Spectators[/b]
|
||||
You get to watch the whole thing go down live! Sit back, grab some popcorn or any other snack and relax.
|
||||
|
||||
[h1]Controls[/h1]
|
||||
[list][*]F2 (ShowTeam): Select A Team or Change Current Team.
|
||||
[*]F3 (ShowSpare1): Play a Taunt.
|
||||
[*]C (ShowContextMenu): Toggle between first and third person camera.
|
||||
[*]Q (ShowSpawnMenu): Hold to rotate your object (Hider only).
|
||||
[*]Ctrl (Duck, Crouch): Interact with objects instead of turning into them, allowing you to pick things up (Hiders only, Seekers always interact with things).
|
||||
[*]R with the Prop Hunt SMG (Reload): On full magazine, switch between auto and burst fire.
|
||||
[/list]
|
||||
|
||||
[h1]Support the Gamemode[/h1]
|
||||
Spreading the word that Prop Hunt Extended exists, work together with others on the gamemode or just play it on your favourite server. Every single thing helps! You can also join our [url=https://discord.gg/tbqhAxr]Discord[/url] and perhaps find additional people to play with that way.
|
||||
|
||||
[h1]Need support?[/h1]
|
||||
Please consider reading the [url=http://steamcommunity.com/workshop/filedetails/discussion/468149739/358415206095321277/]Frequently Asked Questions[/url] first. If nothing of that helped, either write a comment below or try asking your question in #gmod-prop-hunt-extended on [url=https://discord.gg/tbqhAxr]Discord[/url].
|
||||
|
||||
[h1]Want to join development?[/h1]
|
||||
The entire source code is available under the MIT License [url=https://github.com/Xaymar/PropHuntExtended]on GitHub[/url].
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"title" : "Prop Hunt Extended (Proxy Gamemode)",
|
||||
"type" : "gamemode",
|
||||
"tags" : [ ],
|
||||
"ignore" : [
|
||||
"addon.txt"
|
||||
]
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
"AddonInfo"
|
||||
{
|
||||
"name" "Prop Hunt"
|
||||
"version" "1.0.0"
|
||||
"up_date" "00/00/00"
|
||||
"author_name" "Xaymar"
|
||||
"author_email" "info@xaymar.com"
|
||||
"author_url" "https://xaymar.com/"
|
||||
}
|
||||
@@ -1,401 +0,0 @@
|
||||
"prop_hunt"
|
||||
{
|
||||
"base" "prophuntextended"
|
||||
"title" "Prop Hunt Extended"
|
||||
"maps" "^ph_"
|
||||
"menusystem" "1"
|
||||
"workshopid" "468149739"
|
||||
|
||||
"settings"
|
||||
{
|
||||
// Debug Settings
|
||||
1
|
||||
{
|
||||
"name" "ph_debug"
|
||||
"text" "Enable Debug Mode"
|
||||
"type" "CheckBox"
|
||||
"default" "0"
|
||||
"help" "Prop Hunt: Enable Debug Mode"
|
||||
}
|
||||
|
||||
2
|
||||
{
|
||||
"name" "ph_debug_log"
|
||||
"text" "Enable Debug Logging"
|
||||
"type" "CheckBox"
|
||||
"default" "1"
|
||||
"help" "Prop Hunt: Enable Debug Logging"
|
||||
}
|
||||
|
||||
// Basic Settings
|
||||
100
|
||||
{
|
||||
"name" "ph_gametype"
|
||||
"text" "Game Type to use"
|
||||
"type" "Numeric"
|
||||
"default" "0"
|
||||
"help" "Prop Hunt: Which Game Type should be played?"
|
||||
}
|
||||
101
|
||||
{
|
||||
"name" "mp_timelimit"
|
||||
"text" "Map Time Limit"
|
||||
"type" "Numeric"
|
||||
"default" "0"
|
||||
"help" "Map Time Limit (in Minutes)"
|
||||
}
|
||||
102
|
||||
{
|
||||
"name" "mp_friendlyfire"
|
||||
"text" "Friendly fire"
|
||||
"type" "Numeric"
|
||||
"default" "0"
|
||||
"help" "Allow friendly fire? (0 = No, 1 = Yes, 2 = Reflect)"
|
||||
}
|
||||
|
||||
// Round Settings
|
||||
200
|
||||
{
|
||||
"name" "ph_round_limit"
|
||||
"text" "Maximum Rounds Played"
|
||||
"type" "Numeric"
|
||||
"default" "10"
|
||||
"help" "Round Manager: Maximum Rounds to Play on a single Map"
|
||||
}
|
||||
201
|
||||
{
|
||||
"name" "ph_round_timelimit"
|
||||
"text" "Time Limit per Round"
|
||||
"type" "Numeric"
|
||||
"default" "180"
|
||||
"help" "Round Manager: Time Limit per Round (in Seconds)"
|
||||
}
|
||||
202
|
||||
{
|
||||
"name" "ph_round_blindtime"
|
||||
"text" "Seeker Blind time per Round"
|
||||
"type" "Numeric"
|
||||
"default" "-30"
|
||||
"help" "Round Manager: Blind Time for Seekers (in Seconds, positive takes away from ph_round_timelimit, negative adds extra time to ph_round_timelimit)"
|
||||
}
|
||||
|
||||
// Team Settings
|
||||
300
|
||||
{
|
||||
"name" "ph_teams_randomize"
|
||||
"text" "Randomize Teams"
|
||||
"type" "CheckBox"
|
||||
"default" "1"
|
||||
"help" "Teams: Randomize Teams instead of swapping each round"
|
||||
}
|
||||
301
|
||||
{
|
||||
"name" "ph_teams_weighted"
|
||||
"text" "Randomize with weighted Score"
|
||||
"type" "CheckBox"
|
||||
"default" "1"
|
||||
"help" "Teams: Use Weighted Randomization"
|
||||
}
|
||||
302
|
||||
{
|
||||
"name" "ph_teams_seekerpct"
|
||||
"text" "Pct of Pl. becoming Seeker"
|
||||
"type" "Numeric"
|
||||
"default" "25"
|
||||
"help" "Teams: Initial percentage of Seekers in Dead Hunt Game Type"
|
||||
}
|
||||
|
||||
// Seeker Settings
|
||||
400
|
||||
{
|
||||
"name" "ph_seeker_health"
|
||||
"text" "Seeker Health"
|
||||
"type" "Numeric"
|
||||
"default" "100"
|
||||
"help" "Seekers: Initial Health"
|
||||
}
|
||||
401
|
||||
{
|
||||
"name" "ph_seeker_health_max"
|
||||
"text" "Seeker Max Health"
|
||||
"type" "Numeric"
|
||||
"default" "100"
|
||||
"help" "Seekers: Maximum Health"
|
||||
}
|
||||
402
|
||||
{
|
||||
"name" "ph_seeker_health_bonus"
|
||||
"text" "Seeker Health Kill-Bonus"
|
||||
"type" "Numeric"
|
||||
"default" "20"
|
||||
"help" "Seekers: Health Bonus per Kill"
|
||||
}
|
||||
403
|
||||
{
|
||||
"name" "ph_seeker_health_penalty"
|
||||
"text" "Seeker Health Penalty"
|
||||
"type" "Numeric"
|
||||
"default" "5"
|
||||
"help" "Seekers: Health Penalty per wrong Shot"
|
||||
}
|
||||
404
|
||||
{
|
||||
"name" "ph_seeker_weapons"
|
||||
"text" "Seeker Weapons"
|
||||
"type" "Text"
|
||||
"default" "weapon_crowbar,weapon_pistol,weapon_ph_smg,weapon_shotgun"
|
||||
"help" "Seekers: Initial Weapons (Weapon,Weapon,...)"
|
||||
}
|
||||
405
|
||||
{
|
||||
"name" "ph_seeker_ammo"
|
||||
"text" "Seeker Ammo"
|
||||
"type" "Text"
|
||||
"default" "Pistol:100,SMG1:300,SMG1_Grenade:1,Buckshot:64"
|
||||
"help" "Seekers: Initial Ammo (Ammo:Amount,Ammo:Amount,...)"
|
||||
}
|
||||
406
|
||||
{
|
||||
"name" "ph_seeker_walk_speed"
|
||||
"text" "Seeker Walk Speed"
|
||||
"type" "Numeric"
|
||||
"default" "250"
|
||||
"help" "Seekers: Walk Speed"
|
||||
}
|
||||
407
|
||||
{
|
||||
"name" "ph_seeker_sprint"
|
||||
"text" "Seeker Sprint Allowed"
|
||||
"type" "CheckBox"
|
||||
"default" "1"
|
||||
"help" "Seekers: Allow Sprinting"
|
||||
}
|
||||
408
|
||||
{
|
||||
"name" "ph_seeker_sprint_speed"
|
||||
"text" "Seeker Sprint Speed"
|
||||
"type" "Numeric"
|
||||
"default" "500"
|
||||
"help" "Seekers: Sprint Speed"
|
||||
}
|
||||
409
|
||||
{
|
||||
"name" "ph_seeker_jump_power"
|
||||
"text" "Seeker Jump Power"
|
||||
"type" "Numeric"
|
||||
"default" "200"
|
||||
"help" "Seekers: Jump Power"
|
||||
}
|
||||
|
||||
// Hider Settings
|
||||
500
|
||||
{
|
||||
"name" "ph_hider_health"
|
||||
"text" "Hider Health"
|
||||
"type" "Numeric"
|
||||
"default" "100"
|
||||
"help" "Hiders: Initial Health"
|
||||
}
|
||||
501
|
||||
{
|
||||
"name" "ph_hider_health_max"
|
||||
"text" "Hider Max Health"
|
||||
"type" "Numeric"
|
||||
"default" "100"
|
||||
"help" "Hiders: Maximum Health"
|
||||
}
|
||||
502
|
||||
{
|
||||
"name" "ph_hider_health_scaling"
|
||||
"text" "Hider Enable Health Scaling"
|
||||
"type" "CheckBox"
|
||||
"default" "1"
|
||||
"help" "Hiders: Enable Health Scaling"
|
||||
}
|
||||
503
|
||||
{
|
||||
"name" "ph_hider_health_scaling_max"
|
||||
"text" "Hider Scaled Max Health"
|
||||
"type" "Numeric"
|
||||
"default" "200"
|
||||
"help" "Hiders: Maximum scaled Health"
|
||||
}
|
||||
504
|
||||
{
|
||||
"name" "ph_hider_allow_full_rotation"
|
||||
"text" "Hider 3-Dimensional Rotation"
|
||||
"type" "CheckBox"
|
||||
"default" "0"
|
||||
"help" "Hiders: Enable full 3D Rotation"
|
||||
}
|
||||
505
|
||||
{
|
||||
"name" "ph_hider_walk_speed"
|
||||
"text" "Hider Walk Speed"
|
||||
"type" "Numeric"
|
||||
"default" "250"
|
||||
"help" "Hiders: Walk Speed"
|
||||
}
|
||||
506
|
||||
{
|
||||
"name" "ph_hider_sprint"
|
||||
"text" "Hider Sprint Allowed"
|
||||
"type" "CheckBox"
|
||||
"default" "0"
|
||||
"help" "Hiders: Allow Sprinting"
|
||||
}
|
||||
507
|
||||
{
|
||||
"name" "ph_hider_sprint_speed"
|
||||
"text" "Hider Sprint Speed"
|
||||
"type" "Numeric"
|
||||
"default" "500"
|
||||
"help" "Hiders: Sprint Speed"
|
||||
}
|
||||
507
|
||||
{
|
||||
"name" "ph_hider_jump_power"
|
||||
"text" "Hider Jump Power"
|
||||
"type" "Numeric"
|
||||
"default" "200"
|
||||
"help" "Hiders: Jump Power"
|
||||
}
|
||||
|
||||
// Whitelist & Blacklist
|
||||
600
|
||||
{
|
||||
"name" "ph_list_class_whitelist"
|
||||
"text" "Allowed Entity Classes"
|
||||
"type" "Text"
|
||||
"default" "ph_prop,prop_physics,prop_physics_multiplayer,prop_physics_respawnable"
|
||||
"help" "Anti-Cheat: Whitelisted Hider Classes"
|
||||
}
|
||||
601
|
||||
{
|
||||
"name" "ph_list_abuse_blacklist"
|
||||
"text" "Abuse Blacklist"
|
||||
"type" "Text"
|
||||
"default" "func_button,func_door,func_door_rotation,prop_door_rotation,func_tracktrain,func_tanktrain,func_breakable"
|
||||
"help" "Anti-Cheat: Entity Abuse Blacklist"
|
||||
}
|
||||
602
|
||||
{
|
||||
"name" "ph_list_model_blacklist"
|
||||
"text" "Model Blacklist"
|
||||
"type" "Text"
|
||||
"default" "models/props/cs_assault/dollar.mdl,models/props/cs_assault/money.mdl,models/props/cs_office/snowman_arm.mdl,models/props/cs_office/projector_remote.mdl"
|
||||
"help" "Anti-Cheat: Model Abuse Blacklist"
|
||||
}
|
||||
|
||||
// Taunts
|
||||
700
|
||||
{
|
||||
"name" "ph_taunt_cooldown"
|
||||
"text" "Cooldown for Taunts"
|
||||
"type" "Numeric"
|
||||
"default" "5"
|
||||
"help" "Prop Hunt: Cooldown between Taunts"
|
||||
}
|
||||
701
|
||||
{
|
||||
"name" "ph_taunt_seekers"
|
||||
"text" "Seeker Taunts"
|
||||
"type" "Text"
|
||||
"default" "bot/a_bunch_of_them.wav,bot/come_out_and_fight_like_a_man.wav,bot/come_out_wherever_you_are.wav,bot/come_to_papa.wav,bot/dont_worry_hell_get_it.wav,bot/hang_on_i_heard_something.wav,bot/hang_on_im_coming.wav,bot/i_dont_think_so.wav,bot/i_have_the_hostages.wav,bot/i_see_our_target.wav,bot/im_waiting_here.wav,bot/keeping_an_eye_on_the_hostages.wav,bot/nnno_sir.wav,bot/spotted_the_delivery_boy.wav,bot/target_acquired.wav,bot/target_spotted.wav,bot/you_heard_the_man_lets_go.wav"
|
||||
"help" "Prop Hunt: Seeker Taunts"
|
||||
}
|
||||
702
|
||||
{
|
||||
"name" "ph_taunt_hiders"
|
||||
"text" "Hider Taunts"
|
||||
"type" "Text"
|
||||
"default" "ambient/alarms/apc_alarm_pass1.wav,ambient/alarms/manhack_alert_pass1.wav,ambient/alarms/razortrain_horn1.wav,ambient/alarms/scanner_alert_pass1.wav,ambient/alarms/train_horn2.wav,ambient/alarms/train_horn_distant1.wav,ambient/alarms/warningbell1.wav,ambient/energy/whiteflash.wav,ambient/intro/alyxremove.wav,ambient/intro/logosfx.wav,ambient/levels/launch/1stfiringwarning.wav,ambient/levels/launch/rockettakeoffblast.wav,ambient/misc/ambulance1.wav,ambient/misc/carhonk1.wav,ambient/misc/carhonk2.wav,ambient/misc/carhonk3.wav,ambient/outro/gunshipcrash.wav,ambient/3dmeagle.wav,beams/beamstart5.wav,buttons/bell1.wav,buttons/weapon_cant_buy.wav,common/bass.wav,common/bugreporter_failed.wav,common/warning.wav,doors/door_squeek1.wav,friends/friend_join.wav,friends/friend_online.wav,friends/message.wav,hostage/hunuse/comeback.wav,hostage/hunuse/dontleaveme.wav,hostage/hunuse/yeahillstay.wav,items/gift_drop.wav,music/radio1.mp3,phx/eggcrack.wav,plats/elevbell1.wav,player/headshot1.wav,player/headshot2.wav,player/sprayer.wav,radio/enemydown.wav,radio/go.wav,radio/locknload.wav,radio/negative.wav,radio/rounddraw.wav,radio/takepoint.wav,resource/warning.wav,ui/achievement_earned.wav,ui/freeze_cam.wav,vehicles/junker/radar_ping_friendly1.wav,weapons/c4/c4_beep1.wav,weapons/c4/c4_click.wav,weapons/awp/awp1.wav,vo/canals/female01/gunboat_giveemhell.wav,vo/canals/female01/gunboat_justintime.wav,vo/canals/female01/stn6_incoming.wav,vo/canals/male01/gunboat_giveemhell.wav,vo/canals/male01/gunboat_justintime.wav,vo/canals/male01/stn6_incoming.wav,vo/canals/al_radio_stn6.wav,vo/canals/arrest_getgoing.wav,vo/canals/arrest_helpme.wav,vo/canals/arrest_lookingforyou.wav,vo/canals/boxcar_lethimhelp.wav,vo/canals/matt_closecall.wav,vo/canals/premassacre.wav,vo/ravenholm/aimforhead.wav,vo/ravenholm/bucket_patience.wav,vo/ravenholm/madlaugh01.wav,vo/ravenholm/madlaugh02.wav,vo/ravenholm/madlaugh03.wav,vo/ravenholm/madlaugh04.wav,weapons/strider_buster/ol12_stickybombcreator.wav,weapons/c4/c4_explode1.wav,weapons/357/357_fire2.wav,weapons/357/357_fire3.wav,weapons/scout/scout_fire-1.wav,weapons/smokegrenade/sg_explode.wav,weapons/grenade_launcher1.wav,weapons/explode3.wav,weapons/underwater_explode3.wav,items/nvg_on.wav,hostage/huse/letsdoit.wav,hostage/huse/illfollow.wav,hostage/huse/getouttahere.wav,doors/door_screen_move1.wav,doors/heavy_metal_stop1.wav,doors/default_move.wav,common/stuck2.wav,ambient/water_splash1.wav,ambient/water_splash2.wav,ambient/water_splash3.wav,ambient/weather/thunder1.wav,ambient/weather/thunder2.wav,ambient/weather/thunder3.wav,ambient/weather/thunder4.wav,ambient/weather/thunder5.wav,ambient/weather/thunder6.wav,ambient/outro/thunder7.wav,ambient/voices/crying_loop1.wav,ambient/voices/playground_memory.wav,ambient/voices/f_scream1.wav,ambient/voices/m_scream1.wav,ambient/voices/cough1.wav,ambient/voices/cough2.wav,ambient/voices/cough3.wav,ambient/voices/cough4.wav,ambient/overhead/plane1.wav,ambient/overhead/plane2.wav,ambient/overhead/plane3.wav,ambient/overhead/hel1.wav,ambient/overhead/hel2.wav,ambient/misc/truck_backup1.wav,ambient/misc/truck_drive1.wav,ambient/misc/truck_drive2.wav,ambient/machines/pneumatic_drill_1.wav,ambient/machines/pneumatic_drill_2.wav,ambient/machines/pneumatic_drill_3.wav,ambient/machines/pneumatic_drill_4.wav,ambient/machines/station_train_squeel.wav,ambient/machines/ticktock.wav,ambient/creatures/teddy.wav,ambient/creatures/town_child_scream1.wav,ambient/creatures/town_moan1.wav,ambient/creatures/town_muffled_cry1.wav,ambient/creatures/town_scared_breathing1.wav,ambient/creatures/town_scared_breathing2.wav,ambient/creatures/town_scared_sob1.wav,ambient/creatures/town_scared_sob2.wav,ambient/creatures/town_zombie_call1.wav"
|
||||
"help" "Prop Hunt: Hider Taunts"
|
||||
}
|
||||
|
||||
// Camera
|
||||
800
|
||||
{
|
||||
"name" "ph_camera_allow_noclip"
|
||||
"text" "Camera Noclip Allowed"
|
||||
"type" "CheckBox"
|
||||
"default" "0"
|
||||
"help" "Camera: Allow clients to disable camera collision"
|
||||
}
|
||||
801
|
||||
{
|
||||
"name" "ph_camera_distance_max"
|
||||
"text" "Camera Distance Max."
|
||||
"type" "Numeric"
|
||||
"default" "150"
|
||||
"help" "Camera: Maximum allowed distance to player."
|
||||
}
|
||||
802
|
||||
{
|
||||
"name" "ph_camera_distance_min"
|
||||
"text" "Camera Distance Min."
|
||||
"type" "Numeric"
|
||||
"default" "30"
|
||||
"help" "Camera: Minimum allowed distance to player."
|
||||
}
|
||||
803
|
||||
{
|
||||
"name" "ph_camera_distance_right_range"
|
||||
"text" "Camera Horizontal Offset Range"
|
||||
"type" "Numeric"
|
||||
"default" "20"
|
||||
"help" "Camera: Horizontal allowed camera distance range."
|
||||
}
|
||||
804
|
||||
{
|
||||
"name" "ph_camera_distance_up_range"
|
||||
"text" "Camera Vertical Offset Range"
|
||||
"type" "Numeric"
|
||||
"default" "20"
|
||||
"help" "Camera: Vertical allowed camera distance range."
|
||||
}
|
||||
805
|
||||
{
|
||||
"name" "ph_camera_lag_min"
|
||||
"text" "Camera Lag Min."
|
||||
"type" "Numeric"
|
||||
"default" "0"
|
||||
"help" "Camera: Minimum Camera Lag."
|
||||
}
|
||||
806
|
||||
{
|
||||
"name" "ph_camera_lag_max"
|
||||
"text" "Camera Lag Max."
|
||||
"type" "Numeric"
|
||||
"default" "0.95"
|
||||
"help" "Camera: Maximum Camera Lag."
|
||||
}
|
||||
|
||||
// Selection Halo
|
||||
900
|
||||
{
|
||||
"name" "ph_selectionhalo_allow"
|
||||
"text" "Selection Halo Allowed"
|
||||
"type" "CheckBox"
|
||||
"default" "1"
|
||||
"help" "Selection Halo: Allow clients to enable halo around the currently looked at prop?"
|
||||
}
|
||||
901
|
||||
{
|
||||
"name" "ph_selectionhalo_approximate"
|
||||
"text" "Selection Approximate Mode"
|
||||
"type" "CheckBox"
|
||||
"default" "1"
|
||||
"help" "Selection Halo: Enable approximate selection halo, which only checks the forward vector on the client."
|
||||
}
|
||||
902
|
||||
{
|
||||
"name" "ph_selectionhalo_interval"
|
||||
"text" "Selection Halo Allowed"
|
||||
"type" "Numeric"
|
||||
"default" "0.05"
|
||||
"help" "Selection Halo: Interval for updates of the accuracte selection halo in seconds."
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
"AddonInfo"
|
||||
{
|
||||
"name" "Prop Hunt Extended"
|
||||
"version" "1.4.0"
|
||||
"up_date" "00/00/00"
|
||||
"author_name" "Xaymar"
|
||||
"author_email" "info@xaymar.com"
|
||||
"author_url" "https://xaymar.com/"
|
||||
}
|
||||
|
Before Width: | Height: | Size: 135 KiB |
|
Before Width: | Height: | Size: 1003 KiB |
|
Before Width: | Height: | Size: 1.0 MiB |
@@ -1,79 +0,0 @@
|
||||
--[[
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Xaymar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
--]]
|
||||
|
||||
local UI = {}
|
||||
|
||||
function UI:Init()
|
||||
-- Initialize
|
||||
self:SetVisible(false)
|
||||
self:SetSize(1280, 720)
|
||||
self:SetScreenLock(true)
|
||||
self:SetTitle("Help & Settings")
|
||||
self:SetDraggable(true)
|
||||
self:SetSizable(true)
|
||||
self:ShowCloseButton(true)
|
||||
self:SetDeleteOnClose(false)
|
||||
|
||||
self.scale = 1.0
|
||||
|
||||
self.psh = vgui.Create("DPropertySheet", self)
|
||||
self.psh:Dock(FILL)
|
||||
self.psh:AddSheet("Help", vgui.Create("PHE_HelpUI_Help", self.psh))
|
||||
self.psh:AddSheet("Settings", vgui.Create("PHE_HelpUI_Settings", self.psh))
|
||||
|
||||
-- Listen to DPI Updates
|
||||
UIManager:Listen("UpdateDPI", self, function(dpi) self:UpdateDPI(dpi) end)
|
||||
self:UpdateDPI(UIManager:GetDPIScale())
|
||||
end
|
||||
|
||||
function UI:OnRemove()
|
||||
UIManager:Silence("UpdateDPI", self)
|
||||
|
||||
self.psh:Remove()
|
||||
end
|
||||
|
||||
function UI:Show()
|
||||
self:Center()
|
||||
self:SetVisible(true)
|
||||
self:SetFocusTopLevel(true)
|
||||
self:MakePopup()
|
||||
end
|
||||
|
||||
function UI:Paint(w, h)
|
||||
draw.RoundedBox(0, 0, 0, w, h, Color(0,0,0,240))
|
||||
end
|
||||
|
||||
function UI:UpdateDPI(dpi)
|
||||
local mult = dpi / self.scale
|
||||
self.scale = dpi
|
||||
|
||||
local x, y = self:GetPos()
|
||||
local w, h = self:GetSize()
|
||||
local nw, nh = w * mult, h * mult
|
||||
local ox, oy = (nw - w) / 2, (nh - h) / 2
|
||||
self:SetSize(w * mult, h * mult)
|
||||
self:SetPos(x - ox, y - oy)
|
||||
end
|
||||
|
||||
derma.DefineControl("PHE_HelpUI", "Show Help UI Element", UI, "DFrameDPI");
|
||||
@@ -1,235 +0,0 @@
|
||||
--[[
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015-2018 Xaymar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
--]]
|
||||
|
||||
local UI = {}
|
||||
|
||||
function UI:Init()
|
||||
self.time = CurTime() - 0.5
|
||||
|
||||
self.padding = 3
|
||||
self.size = Vector(320, 30 + self.padding * 2)
|
||||
self.size2 = Vector(60, self.size.y)
|
||||
self.colors = {}
|
||||
self.colors.background = Color(0, 0, 0, 204)
|
||||
self.colors.title = Color(204, 204, 204, 255)
|
||||
self.colors.text = Color(255, 255, 255, 255)
|
||||
self.state = {}
|
||||
self.state.name = ""
|
||||
|
||||
self.ui = {}
|
||||
self:DockPadding(self.padding, self.padding, self.padding, self.padding)
|
||||
|
||||
self.ui.bar = vgui.Create("DShape", self)
|
||||
self.ui.bar:SetType("Rect")
|
||||
self.ui.bar:SetSize(0, 5)
|
||||
self.ui.bar:Dock(BOTTOM)
|
||||
|
||||
self.ui.round = vgui.Create("Panel", self)
|
||||
self.ui.round:Dock(LEFT)
|
||||
self.ui.round:SetSize(100, self.size.y)
|
||||
|
||||
self.ui.round_title = vgui.Create("DLabelDPI", self.ui.round)
|
||||
self.ui.round_title:SetFontEx({ size = 10 })
|
||||
self.ui.round_title:SetText("Round")
|
||||
self.ui.round_title:SetColor(self.colors.title)
|
||||
self.ui.round_title:SetContentAlignment(2)
|
||||
self.ui.round_title:SizeToContents()
|
||||
self.ui.round_title:Dock(TOP)
|
||||
|
||||
self.ui.round_text = vgui.Create("DLabelDPI", self.ui.round)
|
||||
self.ui.round_text:SetFontEx({ size = 14 })
|
||||
self.ui.round_text:SetText("0 / 10")
|
||||
self.ui.round_text:SetColor(self.colors.text)
|
||||
self.ui.round_text:SetContentAlignment(8)
|
||||
self.ui.round_text:Dock(FILL)
|
||||
|
||||
self.ui.time = vgui.Create("Panel", self)
|
||||
self.ui.time:Dock(RIGHT)
|
||||
self.ui.time:SetSize(100, self.size.y)
|
||||
|
||||
self.ui.time_title = vgui.Create("DLabelDPI", self.ui.time)
|
||||
self.ui.time_title:SetFontEx({ size = 10 })
|
||||
self.ui.time_title:SetText("Time")
|
||||
self.ui.time_title:SetColor(self.colors.title)
|
||||
self.ui.time_title:SetContentAlignment(2)
|
||||
self.ui.time_title:SizeToContents()
|
||||
self.ui.time_title:Dock(TOP)
|
||||
|
||||
self.ui.time_text = vgui.Create("DLabelDPI", self.ui.time)
|
||||
self.ui.time_text:SetFontEx({ size = 14 })
|
||||
self.ui.time_text:SetText("00:00")
|
||||
self.ui.time_text:SetColor(self.colors.text)
|
||||
self.ui.time_text:SetContentAlignment(8)
|
||||
self.ui.time_text:Dock(FILL)
|
||||
|
||||
self.ui.state = vgui.Create("Panel", self)
|
||||
self.ui.state:Dock(FILL)
|
||||
|
||||
self.ui.state_title = vgui.Create("DLabelDPI", self.ui.state)
|
||||
self.ui.state_title:SetFontEx({ size = 14 })
|
||||
self.ui.state_title:SetText("Waiting for Server...")
|
||||
self.ui.state_title:SetColor(self.colors.title)
|
||||
self.ui.state_title:SetContentAlignment(2)
|
||||
self.ui.state_title:SizeToContents()
|
||||
self.ui.state_title:Dock(TOP)
|
||||
|
||||
self.ui.state_text = vgui.Create("DLabelDPI", self.ui.state)
|
||||
self.ui.state_text:SetFontEx({ size = 10 })
|
||||
self.ui.state_text:SetText("Waiting for Server...")
|
||||
self.ui.state_text:SetColor(self.colors.text)
|
||||
self.ui.state_text:SetContentAlignment(8)
|
||||
self.ui.state_text:Dock(FILL)
|
||||
|
||||
hook.Add("RoundManagerEnterState", self, self.HandleEnterState);
|
||||
|
||||
UIManager:Listen("UpdateDPI", self, function(dpi) self:UpdateDPI(dpi) end)
|
||||
self:UpdateDPI(UIManager:GetDPIScale())
|
||||
end
|
||||
|
||||
function UI:OnRemove()
|
||||
UIManager:Silence("UpdateDPI", self)
|
||||
end
|
||||
|
||||
function UI:Think()
|
||||
-- Only update once every 1/20th of a second.
|
||||
if ((CurTime() - self.time) < 0.05) then
|
||||
return
|
||||
end
|
||||
self.time = CurTime()
|
||||
|
||||
-- Update Time
|
||||
self.ui.time_text:SetText(string.format("%02d:%02d",
|
||||
math.floor(GAMEMODE:GetRoundTime() / 60),
|
||||
math.floor(GAMEMODE:GetRoundTime() % 60)))
|
||||
|
||||
-- Update State Text
|
||||
local round_time = GAMEMODE:GetRoundStateTime()
|
||||
local team_id = GAMEMODE.Teams.Spectator
|
||||
if (LocalPlayer() && LocalPlayer():IsPlayer()) then
|
||||
team_id = LocalPlayer():Team()
|
||||
end
|
||||
|
||||
if (self.state.name == "Hide") then
|
||||
if (team_id == GAMEMODE.Teams.Seekers) then
|
||||
self.ui.state_text:SetText(string.format("You will be unblinded in %02d:%02d",
|
||||
math.floor(round_time / 60), math.floor(round_time % 60)))
|
||||
else
|
||||
self.ui.state_text:SetText(string.format("Seekers unblinded in %02d:%02d...",
|
||||
math.floor(round_time / 60), math.floor(round_time % 60)))
|
||||
end
|
||||
elseif (self.state.name == "Seek") then
|
||||
if (team_id == GAMEMODE.Teams.Seekers) then
|
||||
self.ui.state_text:SetText(string.format("You have %02d:%02d left to kill all Hiders.",
|
||||
math.floor(round_time / 60), math.floor(round_time % 60)))
|
||||
else
|
||||
self.ui.state_text:SetText(string.format("You have %02d:%02d left to annoy all Seekers.",
|
||||
math.floor(round_time / 60), math.floor(round_time % 60)))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function UI:Paint()
|
||||
local w,h = self:GetSize()
|
||||
draw.RoundedBox(0, 0, 0, w, h, self.colors.background)
|
||||
end
|
||||
|
||||
function UI:PerformLayout(w, h)
|
||||
end
|
||||
|
||||
function UI:UpdateDPI(dpi)
|
||||
local w, h = self.size.x * dpi, self.size.y * dpi
|
||||
local w2, h2 = self.size2.x * dpi, self.size2.y * dpi
|
||||
|
||||
self.ui.round:SetSize(w2, h2)
|
||||
self.ui.time:SetSize(w2, h2)
|
||||
|
||||
self:DockPadding(self.padding * dpi, self.padding * dpi, self.padding * dpi, self.padding * dpi)
|
||||
self:SetSize(w, h)
|
||||
self:CenterHorizontal()
|
||||
self:AlignTop(20 * dpi)
|
||||
|
||||
self.ui.round:InvalidateLayout()
|
||||
self.ui.time:InvalidateLayout()
|
||||
self:InvalidateLayout()
|
||||
end
|
||||
|
||||
function UI:UpdateStateDisplay()
|
||||
local team_id = GAMEMODE.Teams.Spectator
|
||||
if (LocalPlayer() && LocalPlayer():IsPlayer()) then
|
||||
team_id = LocalPlayer():Team()
|
||||
end
|
||||
|
||||
-- Update Team Color
|
||||
self.ui.bar:SetColor(team.GetColor(team_id))
|
||||
|
||||
-- Update State itself
|
||||
if (self.state.name == "PreMatch") then
|
||||
self.ui.state_title:SetText(team.GetName(team_id))
|
||||
self.ui.state_text:SetText(string.format("Waiting for players..."))
|
||||
elseif (self.state.name == "PreRound") then
|
||||
self.ui.state_title:SetText(team.GetName(team_id))
|
||||
self.ui.state_text:SetText(string.format("Round starts soon..."))
|
||||
elseif (self.state.name == "Hide") then
|
||||
local round_time = GAMEMODE:GetRoundStateTime()
|
||||
if (team_id == GAMEMODE.Teams.Seekers) then
|
||||
self.ui.state_title:SetText("Blinded! Get ready to seek.")
|
||||
else
|
||||
self.ui.state_title:SetText("Hiding Time!")
|
||||
end
|
||||
elseif (self.state.name == "Seek") then
|
||||
local round_time = GAMEMODE:GetRoundStateTime()
|
||||
if (team_id == GAMEMODE.Teams.Seekers) then
|
||||
self.ui.state_title:SetText("Seek & Destroy!")
|
||||
else
|
||||
self.ui.state_title:SetText("Hide & Avoid!")
|
||||
end
|
||||
elseif (self.state.name == "PostRound") then
|
||||
self.ui.state_text:SetText("Next Round starting soon...")
|
||||
local winner = GAMEMODE:GetRoundWinner()
|
||||
if (winner == GAMEMODE.Teams.Spectators) then
|
||||
self.ui.state_title:SetText("Draw! Everybody lost.")
|
||||
elseif (winner == GAMEMODE.Teams.Seekers) then
|
||||
self.ui.state_title:SetText("Seekers Win!")
|
||||
elseif (winner == GAMEMODE.Teams.Hiders) then
|
||||
self.ui.state_title:SetText("Hiders Win!")
|
||||
end
|
||||
elseif (self.state.name == "PostMatch") then
|
||||
self.ui.state_title:SetText(team.GetName(team_id))
|
||||
end
|
||||
end
|
||||
|
||||
function UI:HandleEnterState(id, name)
|
||||
self.state.name = name
|
||||
|
||||
-- Update Round
|
||||
if (GAMEMODE.Config.Round:Limit() > 0) then
|
||||
self.ui.round_text:SetText(string.format("%d / %d", GAMEMODE:GetRound(), GAMEMODE.Config.Round:Limit()))
|
||||
else
|
||||
self.ui.round_text:SetText(string.format("%d / ∞", GAMEMODE:GetRound()))
|
||||
end
|
||||
|
||||
self:UpdateStateDisplay()
|
||||
end
|
||||
|
||||
vgui.Register("PHE_GameState", UI, "Panel")
|
||||
@@ -1,75 +0,0 @@
|
||||
--[[
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2019 Xaymar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
--]]
|
||||
|
||||
local CLASS = {}
|
||||
CLASS.__index = CLASS
|
||||
|
||||
local netmsg = { -- Keep in sync with server table.
|
||||
refresh = "RoundManagerUpdate",
|
||||
winner = "RoundManagerWinner"
|
||||
}
|
||||
|
||||
function CLASS:__construct()
|
||||
self.state = nil
|
||||
self.state_name = ""
|
||||
|
||||
net.Receive(netmsg.refresh, function(len, pl) self:__netRefresh(len, pl) end)
|
||||
net.Receive(netmsg.winner, function(len, pl) self:__netWinner(len, pl) end)
|
||||
end
|
||||
|
||||
function CLASS:GetStateId()
|
||||
return self.state
|
||||
end
|
||||
|
||||
function CLASS:GetStateName()
|
||||
return self.state_name
|
||||
end
|
||||
|
||||
function CLASS:CanJoinTeam(team)
|
||||
if (LocalPlayer():Team() == team) then
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
function CLASS:__netRefresh(len, pl)
|
||||
local data = net.ReadTable()
|
||||
if (self.state != data.state) then
|
||||
hook.Run("RoundManagerLeaveState", self.state, self.state_name)
|
||||
self.state = data.state
|
||||
self.state_name = data.state_name
|
||||
hook.Run("RoundManagerEnterState", self.state, self.state_name)
|
||||
end
|
||||
end
|
||||
|
||||
function CreateRoundManager()
|
||||
local obj = {}
|
||||
obj.__index = obj
|
||||
setmetatable(obj, CLASS)
|
||||
obj:__construct()
|
||||
return obj
|
||||
end
|
||||
|
||||
_G["RoundManager"] = CreateRoundManager()
|
||||
@@ -1,107 +0,0 @@
|
||||
--[[
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015-2018 Xaymar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
--]]
|
||||
|
||||
local FontManagerMeta = {}
|
||||
FontManagerMeta.__index = FontManagerMeta
|
||||
|
||||
-- Global Constructor
|
||||
function FontManager()
|
||||
local obj = {}
|
||||
obj.__index = obj
|
||||
setmetatable(obj, FontManagerMeta)
|
||||
obj:__construct()
|
||||
return obj
|
||||
end
|
||||
|
||||
-- Constructor
|
||||
function FontManagerMeta:__construct()
|
||||
self.fonts = {}
|
||||
end
|
||||
|
||||
function FontManagerMeta:Exists(name)
|
||||
if (self.fonts[name] != nil) then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function FontManagerMeta:CreateFontData(settings)
|
||||
local base = {}
|
||||
base.font = "Roboto"
|
||||
base.extended = true
|
||||
base.size = 13
|
||||
base.weight = 500
|
||||
base.blursize = 0
|
||||
base.scanlines = 0
|
||||
base.antialias = true
|
||||
base.underline = false
|
||||
base.italic = false
|
||||
base.strikeout = false
|
||||
base.symbol = false
|
||||
base.rotary = false
|
||||
base.shadow = false
|
||||
base.additive = false
|
||||
base.outline = false
|
||||
local final = table.Merge(base, settings)
|
||||
return final
|
||||
end
|
||||
|
||||
function FontManagerMeta:CreateFont(settings)
|
||||
local final = self:CreateFontData(settings)
|
||||
local name = self:ToName(final)
|
||||
return self:Request(name, final)
|
||||
end
|
||||
|
||||
function FontManagerMeta:ToName(settings)
|
||||
local name = settings.font
|
||||
name = name .. "[S" .. settings.size
|
||||
name = name .. "W" .. settings.weight
|
||||
if (settings.blursize > 0) then name = name .. "B" .. settings.blursize end
|
||||
if (settings.scanlines > 0) then name = name .. "L" .. settings.scanlines end
|
||||
if (settings.antialias) then name = name .. "A" end
|
||||
if (settings.extended) then name = name .. "E" end
|
||||
if (settings.underline) then name = name .. "U" end
|
||||
if (settings.italic) then name = name .. "I" end
|
||||
if (settings.strikeout) then name = name .. "-" end
|
||||
if (settings.shadow) then name = name .. "S" end
|
||||
if (settings.outline) then name = name .. "O" end
|
||||
if (settings.additive) then name = name .. "+" end
|
||||
if (settings.rotary) then name = name .. "R" end
|
||||
if (settings.symbol) then name = name .. "#" end
|
||||
name = name .. "]"
|
||||
return name
|
||||
end
|
||||
|
||||
function FontManagerMeta:Request(name, settings)
|
||||
if (self.fonts[name] != nil) then
|
||||
--print("[Prop Hunt Font Manager] Request for font '"..name.."' received and cached.")
|
||||
return name
|
||||
end
|
||||
|
||||
print("[Font Manager] Creating new Font '"..name.."'...")
|
||||
self.fonts[name] = surface.CreateFont(name, settings)
|
||||
return name
|
||||
end
|
||||
|
||||
_G["FontManager"] = FontManager()
|
||||
@@ -1,148 +0,0 @@
|
||||
--[[
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015-2019 Xaymar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
--]]
|
||||
|
||||
-- Help Panel
|
||||
|
||||
local UI = {}
|
||||
|
||||
local HTML = [[
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
body {
|
||||
font-family: Roboto;
|
||||
font-size: 18pt;
|
||||
color: rgba(255, 255, 255, 1.0);
|
||||
background: rgba(51, 51, 51, 1.0);
|
||||
}
|
||||
|
||||
div, p {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
p + p {
|
||||
margin-top: 10pt;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="about">
|
||||
<h1>About Prop Hunt Extended</h1>
|
||||
<p>
|
||||
Hide n Seek with a twist: Hiders can turn into anything on the map! From bottles, to vending machines and all the way to huge cars, what you become depends on how you want to play. Do you want to blend in with your surroundings, or do you want to make a fool of the Seekers? And how will you deal with finding (and killing) all hiders as a Seeker?
|
||||
</p>
|
||||
<p>
|
||||
The Gamemode comes with out of the box support for console configuration (ph_*), custom taunt support, prop rotation, an improved code base for modders and better integration and some other fixes. Support for MapVote is also built in, so as long as you have a compatible addon installed you will get a map voting menu at the end of a match.
|
||||
</p>
|
||||
<p>
|
||||
<h2>Help Develop:</h2>
|
||||
The Gamemode is Open Source under the MIT License <a href="https://github.com/xaymar/prophuntextended" target="_blank">on Github</a>.
|
||||
</p>
|
||||
</div>
|
||||
<div id="howto">
|
||||
<h2>How To Play</h2>
|
||||
<p>
|
||||
<h3>Seekers</h3>
|
||||
Your primary goal is to find hiders by any means possible. But watch out, you might lose health if you shoot an object that isn't actually a hider! Pick things up before shooting them, or simply remember the layout of the maps you are playing on. And remember: You lose if only a single hider is still alive at the end of the round.
|
||||
</p>
|
||||
<p>
|
||||
<h3>Hiders</h3>
|
||||
Stay alive as long as possible and make Seekers look like a fool. Dance around their feet, hide in plain sight or be that huge car that nobody though you could become! What you do is entirely up to you.
|
||||
</p>
|
||||
<p>
|
||||
<h3>Spectators</h3>
|
||||
You get to watch the whole thing go down live! Sit back, grab some popcorn or any other snack and relax.
|
||||
</p>
|
||||
</div>
|
||||
<div id="controls">
|
||||
<h2>Controls</h2>
|
||||
<table>
|
||||
<tr>
|
||||
<th>Key/Button</th>
|
||||
<th>Control Name</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>F1</td>
|
||||
<td>ShowHelp</td>
|
||||
<td>Opens the Help and Settings window for this gamemode.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>F2</td>
|
||||
<td>ShowTeam</td>
|
||||
<td>Change the team.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>F3</td>
|
||||
<td>ShowSpare1</td>
|
||||
<td>Play a random Taunt, if it is not currently on cooldown.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>C</td>
|
||||
<td>ShowContextMenu</td>
|
||||
<td>Toggle between 1st and 3rd Person Camera.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Q</td>
|
||||
<td>ShowSpawnMenu</td>
|
||||
<td>Tap to rotate the prop towards your current view angle, hold to continue rotating.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Ctrl + E</td>
|
||||
<td>Duck + Use</td>
|
||||
<td>Interact with objects, such as picking them up, opening doors, or pushing buttons, instead of turning into the object you are targeting.</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
]]
|
||||
|
||||
function UI:Init()
|
||||
self.content = vgui.Create("DHTML", self)
|
||||
self.content:Dock(FILL)
|
||||
self.content:SetHTML(HTML)
|
||||
self.content.OnChildViewCreated = function(source, target, isPopup)
|
||||
gui.OpenURL(target)
|
||||
print(source)
|
||||
print(target)
|
||||
print(isPopup)
|
||||
end
|
||||
self.content.OnChangeTargetURL = function(url)
|
||||
print(url)
|
||||
end
|
||||
|
||||
|
||||
-- GAMEMODE.UIManager:Listen("UpdateDPI", self, function(dpi) self:UpdateDPI(dpi) end)
|
||||
-- self:UpdateDPI(GAMEMODE.UIManager:GetDPIScale())
|
||||
end
|
||||
|
||||
function UI:OnRemove()
|
||||
self.content:Remove()
|
||||
-- GAMEMODE.UIManager:Silence("UpdateDPI", self)
|
||||
end
|
||||
|
||||
derma.DefineControl("PHE_HelpUI_Help", "Help Page for Prop Hunt Extended", UI, "DPanel");
|
||||
@@ -1,340 +0,0 @@
|
||||
--[[
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Xaymar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
--]]
|
||||
|
||||
local DPlayerEntry = {}
|
||||
function DPlayerEntry:Init()
|
||||
self.Data = {}
|
||||
self.Data.Margin = {
|
||||
left = 0,
|
||||
top = 0,
|
||||
right = 0,
|
||||
bottom = 0
|
||||
}
|
||||
self.Data.LastUpdate = CurTime() - 10
|
||||
self.Data.Player = nil
|
||||
|
||||
self:SetMinimumSize(100, 40)
|
||||
|
||||
self.Container = vgui.Create("DPanel", self)
|
||||
self.Container:SetBackgroundColor(Color(127,127,127,255))
|
||||
self.Container:SetPaintBackground(true)
|
||||
self.Container:Dock(FILL)
|
||||
self.Container:DockMargin(0, 0, 0, 0)
|
||||
|
||||
self.Avatar = vgui.Create("AvatarImage", self.Container)
|
||||
self.Avatar:Dock(LEFT)
|
||||
|
||||
self.Name = vgui.Create("DLabel", self.Container)
|
||||
self.Name:SetText("Unknown")
|
||||
self.Name:SetFont("Roboto24")
|
||||
self.Name:SetContentAlignment(4)
|
||||
self.Name:Dock(FILL)
|
||||
self.Name:DockMargin(10, 5, 10, 5)
|
||||
|
||||
self.Deaths = vgui.Create("DLabel", self.Container)
|
||||
self.Deaths:SetSize(80, 30)
|
||||
self.Deaths:SetText("N/A")
|
||||
self.Deaths:SetFont("Roboto24")
|
||||
self.Deaths:SetContentAlignment(6)
|
||||
self.Deaths:Dock(RIGHT)
|
||||
self.Deaths:DockMargin(10, 5, 10, 5)
|
||||
|
||||
self.Kills = vgui.Create("DLabel", self.Container)
|
||||
self.Kills:SetSize(80, 30)
|
||||
self.Kills:SetText("N/A")
|
||||
self.Kills:SetFont("Roboto24")
|
||||
self.Kills:SetContentAlignment(6)
|
||||
self.Kills:Dock(RIGHT)
|
||||
self.Kills:DockMargin(10, 5, 10, 5)
|
||||
end
|
||||
|
||||
function DPlayerEntry:PerformLayout(w, h)
|
||||
self:SetMinimumSize(
|
||||
100 + self.Data.Margin.left + self.Data.Margin.right,
|
||||
40 + self.Data.Margin.top + self.Data.Margin.bottom
|
||||
)
|
||||
|
||||
-- Docked Content
|
||||
local containerX, containerY, containerW, containerH = self.Container:GetBounds()
|
||||
self.Avatar:SetSize(containerH, containerH)
|
||||
self.Kills:SetSize(80, containerH - 10)
|
||||
self.Deaths:SetSize(80, containerH - 10)
|
||||
end
|
||||
|
||||
function DPlayerEntry:Think()
|
||||
if (CurTime() - self.Data.LastUpdate) < 0.25 then return end
|
||||
if IsValid(self.Data.Player) then
|
||||
self.Avatar:SetPlayer(self.Data.Player, 184)
|
||||
self.Name:SetText(self.Data.Player:GetName())
|
||||
self.Kills:SetText(self.Data.Player:Frags())
|
||||
self.Deaths:SetText(self.Data.Player:Deaths())
|
||||
end
|
||||
end
|
||||
|
||||
function DPlayerEntry:SetMargin(left, top, right, bottom)
|
||||
local uleft = left or 0
|
||||
local utop = top or uleft
|
||||
local uright = right or uleft
|
||||
local ubottom = bottom or utop
|
||||
self.Container:DockMargin(uleft, utop, uright, ubottom)
|
||||
self:InvalidateLayout()
|
||||
end
|
||||
|
||||
function DPlayerEntry:SetBackgroundColor(clr)
|
||||
self.Container:SetBackgroundColor(clr)
|
||||
end
|
||||
|
||||
function DPlayerEntry:SetForegroundColor(clr)
|
||||
self.Name:SetColor(clr)
|
||||
self.Kills:SetColor(clr)
|
||||
self.Deaths:SetColor(clr)
|
||||
end
|
||||
|
||||
function DPlayerEntry:SetPlayer(ply)
|
||||
self.Data.Player = ply
|
||||
end
|
||||
|
||||
function DPlayerEntry:ShowFlags(kills, deaths)
|
||||
self.Kills:SetVisible(kills)
|
||||
self.Deaths:SetVisible(deaths)
|
||||
self.Container:InvalidateLayout()
|
||||
end
|
||||
|
||||
vgui.Register("DPlayerEntry", DPlayerEntry, "Panel")
|
||||
|
||||
local DPlayerList = {}
|
||||
function DPlayerList:Init()
|
||||
self.Data = {}
|
||||
self.Data.Time = CurTime() - 1
|
||||
self.Data.Team = nil
|
||||
self.Data.Players = {}
|
||||
self.Data.ShowKills = true
|
||||
self.Data.ShowDeaths = true
|
||||
|
||||
self.Container = vgui.Create("DPanel", self)
|
||||
self.Container:SetPaintBackground(true)
|
||||
self.Container:SetBackgroundColor(Color(51, 51, 51, 102))
|
||||
self.Container:Dock(FILL)
|
||||
|
||||
self.Title = vgui.Create("DPanel", self.Container)
|
||||
self.Title:SetSize(1, 40)
|
||||
self.Title:Dock(TOP)
|
||||
self.Title:DockMargin(0, 0, 0, 5)
|
||||
|
||||
self.Title.Name = vgui.Create("DLabel", self.Title)
|
||||
self.Title.Name:SetText("Unknown")
|
||||
self.Title.Name:SetFont("Roboto32Bold")
|
||||
self.Title.Name:SetContentAlignment(5)
|
||||
self.Title.Name:Dock(FILL)
|
||||
self.Title.Name:DockMargin(10, 5, 10, 5)
|
||||
|
||||
self.Title.Deaths = vgui.Create("DLabel", self.Title)
|
||||
self.Title.Deaths:SetText("Deaths")
|
||||
self.Title.Deaths:SetFont("Roboto24")
|
||||
self.Title.Deaths:SetContentAlignment(6)
|
||||
self.Title.Deaths:SetSize(80, 40)
|
||||
self.Title.Deaths:Dock(RIGHT)
|
||||
self.Title.Deaths:DockMargin(10, 5, 10, 5)
|
||||
|
||||
self.Title.Kills = vgui.Create("DLabel", self.Title)
|
||||
self.Title.Kills:SetText("Kills")
|
||||
self.Title.Kills:SetFont("Roboto24")
|
||||
self.Title.Kills:SetContentAlignment(6)
|
||||
self.Title.Kills:SetSize(80, 40)
|
||||
self.Title.Kills:Dock(RIGHT)
|
||||
self.Title.Kills:DockMargin(10, 5, 10, 5)
|
||||
|
||||
self.Scroll = vgui.Create("DScrollPanel", self.Container)
|
||||
self.Scroll:Dock(FILL)
|
||||
self.Layout = vgui.Create("DListLayout", self.Scroll)
|
||||
self.Layout:Dock(FILL)
|
||||
end
|
||||
|
||||
function DPlayerList:PerformLayout(w, h)
|
||||
--self.Container:SetSize(w, h)
|
||||
end
|
||||
|
||||
function DPlayerList:Think()
|
||||
if (self.Data.Team == -1) then return end
|
||||
if ((CurTime() - self.Data.Time) < 0.1) then return end
|
||||
|
||||
self.Data.Time = CurTime()
|
||||
|
||||
-- Update Team Information
|
||||
if (self.Data.Team != nil) then
|
||||
self.Title:SetBackgroundColor(team.GetColor(self.Data.Team))
|
||||
|
||||
-- Name
|
||||
self.Title.Name:SetText(team.GetName(self.Data.Team))
|
||||
|
||||
-- Text Color
|
||||
local hue,sat,val = ColorToHSV(team.GetColor(self.Data.Team))
|
||||
sat = sat * 0.1
|
||||
val = val * 0.1
|
||||
local col = HSVToColor(hue,sat,val)
|
||||
self.Title.Name:SetColor(col)
|
||||
self.Title.Kills:SetColor(col)
|
||||
self.Title.Deaths:SetColor(col)
|
||||
end
|
||||
|
||||
-- Update living players
|
||||
local pls = team.GetPlayers(self.Data.Team)
|
||||
for i,v in ipairs(pls) do
|
||||
local alive = player_manager.RunClass(v, "Alive")
|
||||
local gui = self.Data.Players[v]
|
||||
if (gui == nil) then
|
||||
gui = vgui.Create("DPlayerEntry")
|
||||
gui:SetPlayer(v)
|
||||
gui:SetMargin(0, 0, 0, 5)
|
||||
gui:Stop()
|
||||
gui:SetAlpha(0)
|
||||
gui:AlphaTo(255, 1)
|
||||
self.Data.Players[v] = gui
|
||||
self.Layout:Add(gui)
|
||||
end
|
||||
if (alive) then
|
||||
local hue,sat,val = ColorToHSV(team.GetColor(self.Data.Team))
|
||||
local sat2,val2 = sat * 0.8, val * 0.8
|
||||
gui:SetBackgroundColor(HSVToColor(hue, sat2, val2))
|
||||
local sat3,val3 = sat * 0.1, val
|
||||
gui:SetForegroundColor(HSVToColor(hue, sat3, val3))
|
||||
else
|
||||
local hue,sat,val = ColorToHSV(team.GetColor(self.Data.Team))
|
||||
local sat2,val2 = sat * 0.8, val * 0.1
|
||||
gui:SetBackgroundColor(HSVToColor(hue, sat2, val2))
|
||||
local sat3,val3 = sat * 0.1, val
|
||||
gui:SetForegroundColor(HSVToColor(hue, sat3, val3))
|
||||
end
|
||||
gui:ShowFlags(self.Data.ShowKills, self.Data.ShowDeaths)
|
||||
end
|
||||
|
||||
-- Find dead players
|
||||
for ply,gui in pairs(self.Data.Players) do
|
||||
if (!table.HasValue(pls, ply)) then
|
||||
self.Data.Players[ply] = nil
|
||||
gui:Stop()
|
||||
gui:AlphaTo(0, 1)
|
||||
gui:SetTerm(1)
|
||||
end
|
||||
end
|
||||
|
||||
self.Layout:InvalidateLayout()
|
||||
self.Scroll:InvalidateLayout()
|
||||
end
|
||||
|
||||
function DPlayerList:SetTeam(team)
|
||||
self.Data.Team = team
|
||||
end
|
||||
|
||||
function DPlayerList:ShowFlags(kills, deaths)
|
||||
self.Data.ShowKills = kills
|
||||
self.Data.ShowDeaths = deaths
|
||||
self.Title.Kills:SetVisible(self.Data.ShowKills)
|
||||
self.Title.Deaths:SetVisible(self.Data.ShowDeaths)
|
||||
self.Title:InvalidateLayout()
|
||||
end
|
||||
|
||||
vgui.Register("DPlayerList", DPlayerList, "Panel")
|
||||
|
||||
local DScoreBoard = {}
|
||||
function DScoreBoard:Init()
|
||||
self.Container = vgui.Create("DPanel", self)
|
||||
self.Container:SetPaintBackground(true)
|
||||
self.Container:SetBackgroundColor(Color(0, 0, 0, 240))
|
||||
self.Container:Dock(FILL)
|
||||
self.Container:DockMargin(0, 35, 0, 0)
|
||||
|
||||
self.Logo = vgui.Create("DImage", self)
|
||||
self.Logo:SetImage("prophuntextended/scoreboard_logo.png")
|
||||
self.Logo:SetKeepAspect(true)
|
||||
self.Logo:SetSize(580, 70)
|
||||
self.Logo:SetPos(10, 0)
|
||||
|
||||
self.Frame = vgui.Create("DPanel", self.Container)
|
||||
self.Frame:SetPaintBackground(false)
|
||||
self.Frame:Dock(FILL)
|
||||
self.Frame:DockMargin(5, 40, 5, 5)
|
||||
|
||||
self.Teams = {}
|
||||
self.Teams.Seekers = vgui.Create("DPlayerList", self.Frame)
|
||||
self.Teams.Seekers:SetTeam(GAMEMODE.Teams.Seekers)
|
||||
self.Teams.Seekers:Dock(LEFT)
|
||||
self.Teams.Seekers:DockMargin(5, 5, 5, 5)
|
||||
|
||||
self.Teams.Hiders = vgui.Create("DPlayerList", self.Frame)
|
||||
self.Teams.Hiders:SetTeam(GAMEMODE.Teams.Hiders)
|
||||
self.Teams.Hiders:Dock(RIGHT)
|
||||
self.Teams.Hiders:DockMargin(5, 5, 5, 5)
|
||||
|
||||
self.Teams.Spectators = vgui.Create("DPlayerList", self.Container)
|
||||
self.Teams.Spectators:SetSize(100, 100)
|
||||
self.Teams.Spectators:SetTeam(GAMEMODE.Teams.Spectators)
|
||||
self.Teams.Spectators:ShowFlags(false, false)
|
||||
self.Teams.Spectators:Dock(BOTTOM)
|
||||
self.Teams.Spectators:DockMargin(10, 0, 10, 10)
|
||||
|
||||
self:SetVisible(false)
|
||||
self:SetAlpha(0)
|
||||
end
|
||||
|
||||
function DScoreBoard:PerformLayout(w, h)
|
||||
local frameW, frameH = self.Frame:GetSize()
|
||||
local contW, contH = self.Container:GetSize()
|
||||
|
||||
-- Update Team Lists
|
||||
self.Teams.Seekers:SetSize(frameW / 2 - 10, 0)
|
||||
self.Teams.Hiders:SetSize(frameW / 2 - 10, 0)
|
||||
self.Teams.Spectators:SetSize(100, contH / 5)
|
||||
|
||||
self.Frame:InvalidateLayout()
|
||||
self.Container:InvalidateLayout()
|
||||
end
|
||||
|
||||
function DScoreBoard:Show()
|
||||
-- Size and Position
|
||||
local w, h = ScrW() / 2, ScrH() / 4 * 3
|
||||
if (w < 600) then w = 600 end
|
||||
if (h < 400) then h = 400 end
|
||||
self:SetSize(w, h)
|
||||
self:Center()
|
||||
|
||||
-- Visibility
|
||||
self:Stop()
|
||||
self:AlphaTo(255, 0.1)
|
||||
self:SetVisible(true)
|
||||
|
||||
-- Focus
|
||||
self:SetPopupStayAtBack(true)
|
||||
self:SetFocusTopLevel(true)
|
||||
self:RequestFocus()
|
||||
end
|
||||
|
||||
function DScoreBoard:Hide()
|
||||
-- Visibility
|
||||
self:Stop()
|
||||
self:AlphaTo(0, 0.1, 0, function(animData, pnl)
|
||||
pnl:SetVisible(false)
|
||||
end)
|
||||
end
|
||||
vgui.Register("DScoreBoard", DScoreBoard, "EditablePanel")
|
||||
@@ -1,43 +0,0 @@
|
||||
--[[
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015-2019 Xaymar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
--]]
|
||||
|
||||
local UI = {}
|
||||
|
||||
function UI:Init()
|
||||
self.text = vgui.Create("DLabelDPI", self)
|
||||
self.text:SetText("Hello World")
|
||||
|
||||
UIManager:Listen("UpdateDPI", self, function(dpi) self:UpdateDPI(dpi) end)
|
||||
self:UpdateDPI(UIManager:GetDPIScale())
|
||||
end
|
||||
|
||||
function UI:OnRemove()
|
||||
UIManager:Silence("UpdateDPI", self)
|
||||
end
|
||||
|
||||
function UI:UpdateDPI(dpi)
|
||||
|
||||
end
|
||||
|
||||
derma.DefineControl("PHE_HelpUI_Settings", "Settings Page for Prop Hunt Extended", UI, "DPanel");
|
||||
@@ -1,182 +0,0 @@
|
||||
--[[
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015-2018 Xaymar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
--]]
|
||||
|
||||
--[[
|
||||
|
||||
# Class UIManager
|
||||
UIManager is used to simplify the logic required to keep the GameMode's UI looking
|
||||
good by simply moving all the logic into a single class and then handing off
|
||||
the UI control to the windows themselves.
|
||||
|
||||
# Events
|
||||
Events must be explicitly listened to by the client object. A client must first call
|
||||
UIManager:Listen(string event, any uniqueId, function callback)
|
||||
to listen to an event and call
|
||||
UIManager:Silence(string event, any uniqueId)
|
||||
to stop listening to an event.
|
||||
|
||||
## UpdateDPI(float DPIPercent)
|
||||
Called whenever a change is made to the DPI, such as a change in the screen resolution,
|
||||
or an update from the user of this class. Only parameter is DPI, which is a float.
|
||||
1.0 designates 100%, 2.0 designates 200% and so on.
|
||||
|
||||
--]]
|
||||
|
||||
local UIManagerMeta = {}
|
||||
UIManagerMeta.__index = UIManagerMeta
|
||||
|
||||
-- Global Constructor
|
||||
function UIManager()
|
||||
local obj = {}
|
||||
obj.__index = obj
|
||||
setmetatable(obj, UIManagerMeta)
|
||||
obj:__construct()
|
||||
return obj
|
||||
end
|
||||
|
||||
-- Constructor
|
||||
function UIManagerMeta:__construct()
|
||||
self:InitializeEvents()
|
||||
self:UpdateScreen()
|
||||
self:InitializeDPI()
|
||||
end
|
||||
|
||||
-- Events
|
||||
function UIManagerMeta:InitializeEvents()
|
||||
self.events = {}
|
||||
end
|
||||
|
||||
function UIManagerMeta:Listen(event, uniqueName, callback)
|
||||
assert(type(event) == "string", "UIManager:Listen(event<string>, uniqueName<any>, callback<function>): event must be a string")
|
||||
assert(type(callback) == "function", "UIManager:Listen(event<string>, uniqueName<any>, callback<function>): callback must be a function")
|
||||
|
||||
if (self.events[event] == nil) then
|
||||
self.events[event] = {}
|
||||
end
|
||||
|
||||
self.events[event][uniqueName] = callback
|
||||
return true
|
||||
end
|
||||
|
||||
function UIManagerMeta:Silence(event, uniqueName)
|
||||
assert(type(event) == "string", "UIManager:Silence(event<string>, uniqueName<any>): event must be a string")
|
||||
|
||||
if (self.events[event] == nil) then
|
||||
return false
|
||||
end
|
||||
|
||||
if (self.events[event][uniqueName] == nil) then
|
||||
return false
|
||||
end
|
||||
|
||||
self.events[event][uniqueName] = nil
|
||||
return true
|
||||
end
|
||||
|
||||
function UIManagerMeta:Call(event, ...)
|
||||
if (self.events[event] == nil) then
|
||||
return
|
||||
end
|
||||
|
||||
for k,v in pairs(self.events[event]) do
|
||||
v(...)
|
||||
end
|
||||
end
|
||||
|
||||
-- Screen
|
||||
function UIManagerMeta:UpdateScreen()
|
||||
if (self.screen == nil) then
|
||||
self.screen = {}
|
||||
end
|
||||
if ((self.screen.width != ScrW()) || (self.screen.height != ScrH())) then
|
||||
self.screen.width = ScrW()
|
||||
self.screen.height = ScrH()
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- Tick
|
||||
function UIManagerMeta:Tick()
|
||||
if (self:UpdateScreen() == true) then
|
||||
self.dpi.calculated = self:CalculateDPI()
|
||||
self:SetDPIScale(self.dpi.override)
|
||||
end
|
||||
end
|
||||
|
||||
-- DPI Scaling
|
||||
function UIManagerMeta:InitializeDPI()
|
||||
self.dpi = {}
|
||||
-- Calculate DPI using these base sizes.
|
||||
self.dpi.base = {}
|
||||
self.dpi.base.width = 1280
|
||||
self.dpi.base.height = 720
|
||||
-- Limits
|
||||
self.dpi.limits = {}
|
||||
self.dpi.limits.min = 0.25
|
||||
self.dpi.limits.max = 10.00
|
||||
-- Final Value
|
||||
self.dpi.override = nil
|
||||
self.dpi.calculated = self:CalculateDPI()
|
||||
end
|
||||
|
||||
function UIManagerMeta:CalculateDPI()
|
||||
--[[
|
||||
DPI Scaling is linear in respect to the base resolution.
|
||||
That means that at 50% of the Base resolution, the output is 0.5,
|
||||
and at 200% of the Base resolution, the output is 2.0.
|
||||
--]]
|
||||
|
||||
-- Shortest Edge scaling
|
||||
local wScale, hScale = self.screen.width / self.dpi.base.width, self.screen.height / self.dpi.base.height
|
||||
|
||||
if (wScale < hScale) then
|
||||
return wScale
|
||||
end
|
||||
return hScale
|
||||
end
|
||||
|
||||
function UIManagerMeta:GetDPIScale()
|
||||
if (self.dpi.override != nil) then
|
||||
return self.dpi.override
|
||||
end
|
||||
return self.dpi.calculated
|
||||
end
|
||||
|
||||
function UIManagerMeta:SetDPIScale(newDPIScale)
|
||||
self.dpi.override = newDPIScale
|
||||
if (self.dpi.override == nil) then
|
||||
self:Call("UpdateDPI", self.dpi.calculated)
|
||||
else
|
||||
if (self.dpi.override < self.dpi.limits.min) then
|
||||
self.dpi.override = self.dpi.limits.min
|
||||
end
|
||||
if (self.dpi.override > self.dpi.limits.max) then
|
||||
self.dpi.override = self.dpi.limits.max
|
||||
end
|
||||
self:Call("UpdateDPI", self.dpi.override)
|
||||
end
|
||||
end
|
||||
|
||||
_G["UIManager"] = UIManager()
|
||||
@@ -1,64 +0,0 @@
|
||||
--[[
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015-2019 Xaymar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
--]]
|
||||
|
||||
-- DPI Aware Frame
|
||||
|
||||
local UI = {}
|
||||
|
||||
function UI:Init()
|
||||
self.scale = 1.0
|
||||
self.fontdata = FontManager:CreateFontData({})
|
||||
|
||||
UIManager:Listen("UpdateDPI", self, function(dpi) self:UpdateDPI(dpi) end)
|
||||
self:UpdateDPI(UIManager:GetDPIScale())
|
||||
end
|
||||
|
||||
function UI:OnRemove()
|
||||
UIManager:Silence("UpdateDPI", self)
|
||||
end
|
||||
|
||||
function UI:SetFontEx(fontData)
|
||||
self.fontdata = FontManager:CreateFontData(fontData)
|
||||
|
||||
local scaled = table.Merge({}, self.fontdata)
|
||||
scaled.size = math.Round(self.fontdata.size * self.scale)
|
||||
scaled.blursize = math.Round(self.fontdata.blursize * self.scale)
|
||||
self.font = FontManager:Request(FontManager:ToName(scaled), scaled)
|
||||
|
||||
self.lblTitle:SetFont(self.font)
|
||||
self.lblTitle:InvalidateLayout()
|
||||
self.lblTitle:InvalidateParent()
|
||||
--self.btnClose:SetFont(self.font)
|
||||
--self.btnMinim:SetFont(self.font)
|
||||
--self.btnMaxim:SetFont(self.font)
|
||||
end
|
||||
|
||||
function UI:UpdateDPI(dpi)
|
||||
self.scale = dpi
|
||||
self:SetFontEx(self.fontdata)
|
||||
--self:InvalidateLayout()
|
||||
--self:InvalidateParent()
|
||||
end
|
||||
|
||||
derma.DefineControl("DFrameDPI", "DPI Aware DFrame (requires UIManager)", UI, "DFrame");
|
||||
@@ -1,58 +0,0 @@
|
||||
--[[
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015-2019 Xaymar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
--]]
|
||||
|
||||
-- DPI Aware Label
|
||||
|
||||
local UI = {}
|
||||
|
||||
function UI:Init()
|
||||
self.scale = 1.0
|
||||
self.fontdata = FontManager:CreateFontData({})
|
||||
|
||||
UIManager:Listen("UpdateDPI", self, function(dpi) self:UpdateDPI(dpi) end)
|
||||
self:UpdateDPI(UIManager:GetDPIScale())
|
||||
end
|
||||
|
||||
function UI:OnRemove()
|
||||
UIManager:Silence("UpdateDPI", self)
|
||||
end
|
||||
|
||||
function UI:SetFontEx(fontData)
|
||||
self.fontdata = FontManager:CreateFontData(fontData)
|
||||
|
||||
local scaled = table.Merge({}, self.fontdata)
|
||||
scaled.size = math.Round(self.fontdata.size * self.scale)
|
||||
scaled.blursize = math.Round(self.fontdata.blursize * self.scale)
|
||||
|
||||
self:SetFont(FontManager:Request(FontManager:ToName(scaled), scaled))
|
||||
end
|
||||
|
||||
function UI:UpdateDPI(dpi)
|
||||
self.scale = dpi
|
||||
self:SetFontEx(self.fontdata)
|
||||
self:InvalidateLayout()
|
||||
self:InvalidateParent()
|
||||
end
|
||||
|
||||
derma.DefineControl("DLabelDPI", "DPI Aware DLabel (requires UIManager)", UI, "DLabel");
|
||||
@@ -1,259 +0,0 @@
|
||||
--[[
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2017 Xaymar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
--]]
|
||||
|
||||
-- Finds the player meta table or terminates
|
||||
local meta = FindMetaTable("Player")
|
||||
if !meta then print("FAILED TO FIND PLAYER META") return end
|
||||
|
||||
-- Blinds the player by setting view out into the void
|
||||
function meta:Blind(bool)
|
||||
if !self:IsValid() then return end
|
||||
|
||||
if SERVER then
|
||||
umsg.Start("SetBlind", self)
|
||||
if bool then
|
||||
umsg.Bool(true)
|
||||
else
|
||||
umsg.Bool(false)
|
||||
end
|
||||
umsg.End()
|
||||
elseif CLIENT then
|
||||
blind = bool
|
||||
end
|
||||
end
|
||||
|
||||
-- Blinds the player by setting view out into the void
|
||||
function meta:RemoveProp()
|
||||
if CLIENT || !self:IsValid() then return end
|
||||
|
||||
if self.ph_prop && self.ph_prop:IsValid() then
|
||||
self.ph_prop:Remove()
|
||||
self.ph_prop = nil
|
||||
end
|
||||
end
|
||||
|
||||
-- Sets a new Hull for a player.
|
||||
function meta:NewHull(hullOBBMin, hullOBBMax)
|
||||
if !self:IsValid() then return end
|
||||
if hullOBBMax == nil then return end
|
||||
if hullOBBMin == nil then return end
|
||||
|
||||
local hullOBB = hullOBBMax - hullOBBMin
|
||||
local hullOBBXY = math.max(hullOBB.x, hullOBB.y)
|
||||
|
||||
local xyMul = 0.5
|
||||
local hullMin = Vector(-hullOBBXY * xyMul, -hullOBBXY * xyMul, 0)
|
||||
local hullMax = Vector( hullOBBXY * xyMul, hullOBBXY * xyMul, hullOBB.z)
|
||||
|
||||
self:SetHull(hullMin, hullMax)
|
||||
self:SetHullDuck(hullMin, hullMax)
|
||||
self:SetViewOffset(Vector(0, 0, hullOBB.z))
|
||||
self:SetViewOffsetDucked(Vector(0, 0, hullOBB.z / 2.0))
|
||||
end
|
||||
|
||||
-- Can the passed entity be used by the player?
|
||||
function testflag(set, flag)
|
||||
if (flag == 0) then return true end -- Mod(%) by 0 is nan.
|
||||
return (set % (2 * flag)) >= flag
|
||||
end
|
||||
|
||||
function meta:IsUseableEntity(ent, requiredCaps)
|
||||
if ((ent != nil) && (ent:IsValid())) then
|
||||
local caps = ent:ObjectCaps()
|
||||
local capsmask = 16 + 32 + 64 + 128
|
||||
if (testflag(caps, 16)
|
||||
|| testflag(caps, 32)
|
||||
|| testflag(caps, 64)
|
||||
|| testflag(caps, 128)
|
||||
) && testflag(caps, requiredCaps) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function IntervalDistance(x, x0, x1)
|
||||
-- swap so x0 < x1
|
||||
if ( x0 > x1 ) then
|
||||
local tmp = x0
|
||||
x0 = x1
|
||||
x1 = tmp
|
||||
end
|
||||
|
||||
if ( x < x0 ) then
|
||||
return x0-x
|
||||
elseif ( x > x1 ) then
|
||||
return x - x1
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
-- Find useable entity (Lua version of CBasePlayer:FindUseEntity)
|
||||
function meta:FindUseEntity()
|
||||
-- https://raw.githubusercontent.com/ValveSoftware/source-sdk-2013/0d8dceea4310fde5706b3ce1c70609d72a38efdf/mp/src/game/shared/baseplayer_shared.cpp
|
||||
local PLAYER_USE_RADIUS = 80
|
||||
|
||||
-- Vectors
|
||||
local forward = self:EyeAngles():Forward()
|
||||
local up = self:EyeAngles():Up()
|
||||
local center = self:EyePos()
|
||||
|
||||
local trace = {
|
||||
start = center,
|
||||
endpos = center,
|
||||
mins = Vector(-16, -16, -16),
|
||||
maxs = Vector( 16, 16, 16),
|
||||
mask = MASK_SOLID + CONTENTS_DEBRIS + CONTENTS_PLAYERCLIP,
|
||||
filter = function(ent)
|
||||
if (ent == self) then return false end
|
||||
if (!ent:IsValid()) then return false end
|
||||
if (ent:IsPlayer()) then return false end
|
||||
if (ent == self:GetHands()) then return false end
|
||||
return true
|
||||
end,
|
||||
output = {}
|
||||
}
|
||||
|
||||
local foundEnt = nil
|
||||
local nearestDist = 16777216
|
||||
local nearestEnt = nil
|
||||
|
||||
local tangents_num = 8
|
||||
local tangents = {}
|
||||
tangents[1] = 0
|
||||
tangents[2] = 1
|
||||
tangents[3] = 0.57735026919
|
||||
tangents[4] = 0.3639702342
|
||||
tangents[5] = 0.267949192431
|
||||
tangents[6] = 0.1763269807
|
||||
tangents[7] = -0.1763269807
|
||||
tangents[8] = -0.267949192431
|
||||
for idx=1,tangents_num,1 do
|
||||
if (idx == 1) then
|
||||
trace.endpos = center + forward * 1024
|
||||
util.TraceLine(trace)
|
||||
else
|
||||
local down = forward - (Vector(tangents[idx], tangents[idx], tangents[idx]) * up)
|
||||
down:Normalize()
|
||||
trace.endpos = center + down * 72
|
||||
util.TraceHull(trace)
|
||||
end
|
||||
foundEnt = trace.output.Entity
|
||||
|
||||
local useable = self:IsUseableEntity(foundEnt, 0)
|
||||
while ((foundEnt:IsValid()) && !useable && (foundEnt:GetMoveParent():IsValid())) do
|
||||
foundEnt = foundEnt:GetMoveParent()
|
||||
useable = self:IsUseableEntity(foundEnt, 0)
|
||||
end
|
||||
|
||||
if (useable) then
|
||||
local delta = trace.output.HitPos - trace.output.StartPos
|
||||
local centerZ = foundEnt:WorldSpaceCenter().z
|
||||
delta.z = IntervalDistance(trace.output.HitPos.z, centerZ + foundEnt:OBBMins().z, centerZ + foundEnt:OBBMaxs().z)
|
||||
local dist = delta:Length()
|
||||
if (dist < PLAYER_USE_RADIUS) then
|
||||
if (foundEnt:IsNPC() && (foundEnt:Team() == self:Team())) then
|
||||
foundEnt = self:DoubleCheckUseNPC(foundEnt, center, forward)
|
||||
end
|
||||
--if (dist < nearestDist) then -- Not identical to CBasePlayer
|
||||
--nearestDist = dist
|
||||
nearestEnt = foundEnt
|
||||
--end
|
||||
if (idx == 1) then return foundEnt end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- check ground entity first
|
||||
-- if you've got a useable ground entity, then shrink the cone of this search to 45 degrees
|
||||
-- otherwise, search out in a 90 degree cone (hemisphere)
|
||||
if (self:GetGroundEntity():IsValid() && self:IsUseableEntity(self:GetGroundEntity(), 256)) then
|
||||
nearestEnt = self:GetGroundEntity()
|
||||
end
|
||||
if (nearestEnt) then
|
||||
local point = self:NearestPoint(center)
|
||||
nearestDist = util.DistanceToLine(point, center, forward)
|
||||
end
|
||||
|
||||
local search = ents.FindInSphere(center, PLAYER_USE_RADIUS)
|
||||
for k,v in ipairs(search) do
|
||||
if (v) && (v:IsValid()) && (self:IsUseableEntity(v, 512)) then
|
||||
local point = v:NearestPoint(center)
|
||||
local dir = (point - center):GetNormalized()
|
||||
local dot = dir:Dot(forward)
|
||||
if (dot >= 0.8) then
|
||||
local dist = util.DistanceToLine(point, center, forward)
|
||||
if (dist < nearestDist) then
|
||||
trace.endpos = point
|
||||
util.TraceLine(trace)
|
||||
if ((trace.output.Fraction == 1.0) || (trace.output.Entity == v)) then
|
||||
nearestEnt = v
|
||||
nearestDist = dist
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if (!nearestEnt) then
|
||||
trace.endpos = center + forward * PLAYER_USE_RADIUS
|
||||
trace.mask = MASK_OPAQUE_AND_NPCS
|
||||
util.TraceLine(trace)
|
||||
if (trace.output.Entity
|
||||
&& trace.output.Entity:IsValid()
|
||||
&& self:IsUseableEntity(trace.output.Entity, 0)
|
||||
&& trace.output.Entity:IsNPC()
|
||||
&& (trace.output.Entity:Team() == self:Team())) then
|
||||
nearestEnt = trace.output.Entity
|
||||
end
|
||||
end
|
||||
if (foundEnt:IsNPC() && (foundEnt:Team() == self:Team())) then
|
||||
foundEnt = self:DoubleCheckUseNPC(foundEnt, center, forward)
|
||||
end
|
||||
|
||||
return nearestEnt
|
||||
end
|
||||
|
||||
-- Double Check NPC
|
||||
-- Perhaps a poorly-named function. This function traces against the supplied
|
||||
-- NPC's hitboxes (instead of hull). If the trace hits a different NPC, the
|
||||
-- new NPC is selected. Otherwise, the supplied NPC is determined to be the
|
||||
-- one the citizen wants. This function allows the selection of a citizen over
|
||||
-- another citizen's shoulder, which is impossible without tracing against
|
||||
-- hitboxes instead of the hull (sjb)
|
||||
function meta:DoubleCheckUseNPC(npc, src, dir)
|
||||
local trace = {
|
||||
start = src,
|
||||
endpos = src + dir * 1024,
|
||||
mask = MASK_SHOT,
|
||||
result = {}
|
||||
}
|
||||
util.TraceLine(trace)
|
||||
if ((trace.result.Entity != nil) && (trace.result.Entity:IsValid()) && (trace.result.Entity:IsNPC()) && (trace.result.Entity != npc)) then
|
||||
-- Player is selecting a different NPC through some negative space
|
||||
-- in the first NPC's hitboxes (between legs, over shoulder, etc).
|
||||
return trace.result.Entity
|
||||
end
|
||||
return npc
|
||||
end
|
||||
@@ -1,152 +0,0 @@
|
||||
--[[
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015-2018 Xaymar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
--]]
|
||||
|
||||
local CLASS = {}
|
||||
CLASS.__index = CLASS
|
||||
|
||||
local netmsg = {
|
||||
refresh = "RoundManagerUpdate",
|
||||
winner = "RoundManagerWinner"
|
||||
}
|
||||
|
||||
function CLASS:__construct()
|
||||
self.state = nil
|
||||
self.next_state = nil
|
||||
|
||||
-- Custom Timer Stuff
|
||||
self.timers = {}
|
||||
self.timers.funcs = {}
|
||||
self.timers.times = {}
|
||||
self.timers.delay = {}
|
||||
|
||||
-- Register all network string
|
||||
for k, v in pairs(netmsg) do
|
||||
util.AddNetworkString(v)
|
||||
end
|
||||
|
||||
-- And some more Timers based functionality.
|
||||
self:_RegisterTimer("refresh", 2.0, function() self:RefreshAll() end)
|
||||
|
||||
-- We need a Think hook.
|
||||
hook.Add("Think", "RoundManagerThink", function(...) self:Tick(...) end)
|
||||
end
|
||||
|
||||
function CLASS:_RegisterTimer(name, delay, func)
|
||||
self.timers.funcs[name] = func
|
||||
self.timers.delay[name] = delay
|
||||
self.timers.times[name] = CurTime()
|
||||
end
|
||||
|
||||
function CLASS:GetState()
|
||||
return self.state
|
||||
end
|
||||
|
||||
function CLASS:GetNextState()
|
||||
return self.next_state
|
||||
end
|
||||
|
||||
function CLASS:SetState(state)
|
||||
self.next_state = state
|
||||
end
|
||||
|
||||
function CLASS:Tick(...)
|
||||
-- Tick State
|
||||
if (self.state != nil) then
|
||||
if (self.state.Tick != nil) then
|
||||
self.state:Tick(...)
|
||||
end
|
||||
end
|
||||
|
||||
-- Advance States
|
||||
if (self.next_state != self.state) then
|
||||
local to_id = -1
|
||||
local to_name = ""
|
||||
|
||||
-- Call OnLeave
|
||||
if (self.state != nil) then
|
||||
if (self.state.OnLeave != nil) then
|
||||
self.state:OnLeave(self.next_state)
|
||||
end
|
||||
|
||||
-- Run Hook
|
||||
hook.Run("RoundManagerLeaveState", self.state:GetId(), self.state:GetName())
|
||||
end
|
||||
|
||||
-- Call OnEnter
|
||||
if (self.next_state != nil) then
|
||||
if (self.next_state.OnEnter != nil) then
|
||||
self.next_state:OnEnter(self.state)
|
||||
end
|
||||
|
||||
to_id = self.next_state:GetId()
|
||||
to_name = self.next_state:GetName()
|
||||
|
||||
-- Run Hook
|
||||
hook.Run("RoundManagerEnterState", self.next_state:GetId(), self.next_state:GetName())
|
||||
end
|
||||
|
||||
-- Send Network Message
|
||||
self:RefreshAll()
|
||||
|
||||
-- Set State
|
||||
self.state = self.next_state
|
||||
end
|
||||
|
||||
-- Run all timers.
|
||||
for k, v in pairs(self.timers.times) do
|
||||
if ((CurTime() - self.timers.times[k]) >= self.timers.delay[k]) then
|
||||
self.timers.funcs[k]()
|
||||
self.timers.times[k] = CurTime()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function CLASS:RefreshAll()
|
||||
local data = {}
|
||||
if (self.state != nil) then
|
||||
data.state = self.state:GetId()
|
||||
data.state_name = self.state:GetName()
|
||||
else
|
||||
data.state = -1
|
||||
data.state_name = "Unknown"
|
||||
end
|
||||
|
||||
net.Start(netmsg.refresh)
|
||||
net.WriteTable(data)
|
||||
net.Broadcast()
|
||||
end
|
||||
|
||||
function CLASS:AnnounceWinner(team)
|
||||
|
||||
end
|
||||
|
||||
function CreateRoundManager()
|
||||
local obj = {}
|
||||
obj.__index = obj
|
||||
setmetatable(obj, CLASS)
|
||||
obj:__construct()
|
||||
return obj
|
||||
end
|
||||
|
||||
_G["RoundManager"] = CreateRoundManager()
|
||||
@@ -1,59 +0,0 @@
|
||||
--[[
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2018 Xaymar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
--]]
|
||||
|
||||
local CLASS = {}
|
||||
CLASS.__index = CLASS
|
||||
|
||||
function CLASS:__construct()
|
||||
self.name = "Unnamed"
|
||||
self.id = 0
|
||||
end
|
||||
|
||||
function CLASS:GetName()
|
||||
return self.name
|
||||
end
|
||||
|
||||
function CLASS:GetId()
|
||||
return self.id
|
||||
end
|
||||
|
||||
function CLASS:OnEnter() end
|
||||
|
||||
function CLASS:Tick() end
|
||||
|
||||
function CLASS:OnLeave() end
|
||||
|
||||
function state(name, id)
|
||||
local obj = {}
|
||||
obj.__index = obj
|
||||
setmetatable(obj, CLASS)
|
||||
obj:__construct()
|
||||
if (name != nil) then
|
||||
obj.name = name
|
||||
end
|
||||
if (id != nil) then
|
||||
obj.id = id
|
||||
end
|
||||
return obj;
|
||||
end
|
||||
@@ -1,136 +0,0 @@
|
||||
--[[
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015-2018 Xaymar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
--]]
|
||||
|
||||
include "base.lua"
|
||||
|
||||
local CLASS = state("PostRound", GM.States.PostRound)
|
||||
|
||||
function CLASS:OnEnter(OldState)
|
||||
if GAMEMODE.Config:DebugLog() then print("StatePostRound: OnEnter") end
|
||||
GAMEMODE:SetRoundState(GAMEMODE.States.PostRound)
|
||||
|
||||
GAMEMODE.Data.RoundStartTime = CurTime()
|
||||
|
||||
-- Fretta Hooks
|
||||
hook.Run("RoundEnd")
|
||||
end
|
||||
|
||||
function CLASS:Tick()
|
||||
-- Advance State
|
||||
if (CurTime() - GAMEMODE.Data.RoundStartTime) >= 5 then -- ToDo: configureable time?
|
||||
RoundManager:SetState(StatePostMatch)
|
||||
local players = team.GetPlayers(GAMEMODE.Teams.Seekers)
|
||||
table.Add(players, team.GetPlayers(GAMEMODE.Teams.Hiders))
|
||||
|
||||
-- Assign end of round weighted points.
|
||||
local aliveSeekers = 0
|
||||
local aliveHiders = 0
|
||||
for i,ply in ipairs(players) do
|
||||
if ply:Alive() then
|
||||
if (ply:Team() == GAMEMODE.Teams.Hiders) then
|
||||
aliveHiders = aliveHiders + 1
|
||||
elseif (ply:Team() == GAMEMODE.Teams.Seekers) then
|
||||
aliveSeekers = aliveSeekers + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
for i,ply in ipairs(players) do
|
||||
local score = 0
|
||||
if (ply:Team() == GAMEMODE:GetRoundWinner()) then
|
||||
if (ply:Alive()) then
|
||||
score = 2
|
||||
else
|
||||
score = 1
|
||||
end
|
||||
if (ply:Team() == GAMEMODE.Teams.Hiders) then
|
||||
score = score * aliveHiders
|
||||
elseif (ply:Team() == GAMEMODE.Teams.Seekers) then
|
||||
score = -1 * score * aliveSeekers
|
||||
end
|
||||
end
|
||||
ply.Data.RandomWeight = ply.Data.RandomWeight + score
|
||||
end
|
||||
|
||||
-- Team Distribution
|
||||
if (GAMEMODE.Config.Teams:Weighted() == true) then
|
||||
-- Weighted Teams
|
||||
if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Randomizing Teams using weighted Score.") end
|
||||
|
||||
-- table.sort function returns true if it should a should be before b.
|
||||
table.sort(players, function(a, b)
|
||||
if (a.Data.RandomWeight == b.Data.RandomWeight) then
|
||||
return math.random(100) > 50
|
||||
else
|
||||
return a.Data.RandomWeight > b.Data.RandomWeight
|
||||
end
|
||||
end)
|
||||
elseif (GAMEMODE.Config.Teams:Randomize() == true) then
|
||||
-- Randomize Teams
|
||||
if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Randomizing Teams.") end
|
||||
|
||||
table.sort(players, function(a,b)
|
||||
return math.random(100) > 50
|
||||
end)
|
||||
else
|
||||
-- Swap Teams
|
||||
if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Swapping Teams.") end
|
||||
|
||||
table.sort(players, function(a,b)
|
||||
return (math.random(100) > 50)
|
||||
end)
|
||||
table.sort(players, function(a,b)
|
||||
if (b:Team() == GAMEMODE.Teams.Seekers) then
|
||||
return (a:Team() == GAMEMODE.Teams.Hiders)
|
||||
end
|
||||
return false
|
||||
end)
|
||||
end
|
||||
|
||||
-- Team Distribution Logic
|
||||
local hiders, seekers = {}, {}
|
||||
local plyCount, finalPlyCount = #players, math.max(math.ceil(#players / 2), 1)
|
||||
for c = 1,finalPlyCount do
|
||||
seekers[c] = table.remove(players, 1)
|
||||
end
|
||||
hiders = players
|
||||
|
||||
-- Kill & Assign Teams
|
||||
for i, ply in ipairs(hiders) do
|
||||
if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Assigned '"..ply:GetName().."' (SteamID: "..ply:SteamID()..") to Team Hiders.") end
|
||||
ply:KillSilent()
|
||||
ply:SetTeam(GAMEMODE.Teams.Hiders)
|
||||
end
|
||||
for i, ply in ipairs(seekers) do
|
||||
if GAMEMODE.Config:DebugLog() then print("Prop Hunt: Assigned '"..ply:GetName().."' (SteamID: "..ply:SteamID()..") to Team Seekers.") end
|
||||
ply:KillSilent()
|
||||
ply:SetTeam(GAMEMODE.Teams.Seekers)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function CLASS:OnLeave(NewState)
|
||||
if GAMEMODE.Config:DebugLog() then print("StatePostRound: OnLeave") end
|
||||
end
|
||||
|
||||
_G["StatePostRound"] = CLASS
|
||||
@@ -1,556 +0,0 @@
|
||||
--[[
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Xaymar
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
--]]
|
||||
|
||||
--! Initialize configuration table.
|
||||
GM.Config = { }
|
||||
GM.Config.ConVars = {}
|
||||
|
||||
function CreateConVarIfNotExists(name, value, flags, helptext)
|
||||
cv = GetConVar(name)
|
||||
if (cv == nil) then
|
||||
cv = CreateConVar(name, value, flags, helptext)
|
||||
-- else
|
||||
-- ncv = CreateConVar(name, value, flags, helptext)
|
||||
end
|
||||
return cv
|
||||
end
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Options
|
||||
-- ------------------------------------------------------------------------- --
|
||||
GM.Options = { }
|
||||
|
||||
-- Friendly Fire
|
||||
GM.Options.FriendlyFire = { }
|
||||
GM.Options.FriendlyFire.Off = 0
|
||||
GM.Options.FriendlyFire.On = 1
|
||||
GM.Options.FriendlyFire.Reflect = 2
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Debug Settings
|
||||
-- ------------------------------------------------------------------------- --
|
||||
-- Debug Mode
|
||||
GM.Config.ConVars.Debug = CreateConVarIfNotExists("ph_debug", "0", FCVAR_CHEAT + FCVAR_REPLICATED, "Prop Hunt: Enable Debug Mode")
|
||||
function GM.Config:Debug()
|
||||
return self.ConVars.Debug:GetBool()
|
||||
end
|
||||
|
||||
-- Debug Log
|
||||
GM.Config.ConVars.DebugLog = CreateConVarIfNotExists("ph_debug_log", "0", FCVAR_REPLICATED, "Prop Hunt: Enable Debug Logging")
|
||||
function GM.Config:DebugLog()
|
||||
return self.ConVars.DebugLog:GetBool()
|
||||
end
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Basic Settings
|
||||
-- ------------------------------------------------------------------------- --
|
||||
-- Timelimit in minutes
|
||||
GM.Config.ConVars.TimeLimit = CreateConVarIfNotExists("mp_timelimit", "20", FCVAR_REPLICATED, "Map Time Limit (in Minutes)")
|
||||
function GM.Config:TimeLimit()
|
||||
return self.ConVars.TimeLimit:GetFloat()
|
||||
end
|
||||
|
||||
-- Friendly Fire
|
||||
GM.Config.ConVars.FriendlyFire = CreateConVarIfNotExists(
|
||||
"mp_friendlyfire",
|
||||
GM.Options.FriendlyFire.Off,
|
||||
FCVAR_REPLICATED,
|
||||
"Enable Friendly Fire? (0 = Off, 1 = On, 2 = Reflect)"
|
||||
)
|
||||
function GM.Config:FriendlyFire()
|
||||
return self.ConVars.FriendlyFire:GetInt()
|
||||
end
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Round Settings
|
||||
-- ------------------------------------------------------------------------- --
|
||||
GM.Config.Round = {}
|
||||
GM.Config.Round.ConVars = {}
|
||||
|
||||
-- How many rounds should the GM attempt to fit into the map timelimit, if there is any?
|
||||
GM.Config.Round.ConVars.Limit = CreateConVarIfNotExists("ph_round_limit", "10", FCVAR_REPLICATED, "Round Manager: Maximum Rounds to Play on a single Map")
|
||||
function GM.Config.Round:Limit()
|
||||
return self.ConVars.Limit:GetInt()
|
||||
end
|
||||
|
||||
-- Round Time Limit (Seconds, Default 3 minutes)
|
||||
GM.Config.Round.ConVars.Time = CreateConVarIfNotExists("ph_round_timelimit", "180", FCVAR_REPLICATED, "Round Manager: Time Limit per Round (in Seconds)")
|
||||
function GM.Config.Round:Time()
|
||||
return math.max(self.ConVars.Time:GetFloat() - math.min(self:BlindTime(),0),0)
|
||||
end
|
||||
|
||||
-- For how many seconds are the Seekers blinded? (Seconds)
|
||||
GM.Config.Round.ConVars.BlindTime = CreateConVarIfNotExists("ph_round_blindtime", "-30", FCVAR_REPLICATED, "Round Manager: Blind Time for Seekers (in Seconds, positive takes away from ph_round_timelimit, negative adds extra time to ph_round_timelimit)")
|
||||
function GM.Config.Round:BlindTime()
|
||||
return self.ConVars.BlindTime:GetFloat()
|
||||
end
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Team Settings
|
||||
-- ------------------------------------------------------------------------- --
|
||||
GM.Config.Teams = {}
|
||||
GM.Config.Teams.ConVars = {}
|
||||
|
||||
-- Should teams be ranomized each round?
|
||||
GM.Config.Teams.ConVars.Randomize = CreateConVarIfNotExists("ph_teams_randomize", "0", FCVAR_REPLICATED, "Teams: Randomize Teams instead of swapping each round")
|
||||
function GM.Config.Teams:Randomize()
|
||||
return self.ConVars.Randomize:GetBool()
|
||||
end
|
||||
|
||||
-- Should teams be using weighted randomization?
|
||||
-- Weighted randomization works by using a score calculated over the entire session.
|
||||
-- * Round Start: Adjust Score towards the other Team by 1 (Positive = Seeker, Negative = Hider)
|
||||
-- * Round Win: Adjust score by how many players are still alive on the winning team towards the other team.
|
||||
-- * Alive players get double the score.
|
||||
GM.Config.Teams.ConVars.Weighted = CreateConVarIfNotExists("ph_teams_weighted", "1", FCVAR_REPLICATED, "Teams: Use Weighted Randomization")
|
||||
function GM.Config.Teams:Weighted()
|
||||
return self.ConVars.Weighted:GetBool()
|
||||
end
|
||||
|
||||
-- The Dead Hunt: Percent of players to assign to seeker.
|
||||
GM.Config.Teams.ConVars.SeekerPercentage = CreateConVarIfNotExists("ph_teams_seekerpct", "25", FCVAR_REPLICATED, "Teams: Initial percentage of Seekers in Dead Hunt Game Type")
|
||||
function GM.Config.Teams:SeekerPercentage()
|
||||
return self.ConVars.SeekerPercentage:GetFloat() / 100
|
||||
end
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Seeker Settings
|
||||
-- ------------------------------------------------------------------------- --
|
||||
GM.Config.Seeker = {}
|
||||
GM.Config.Seeker.ConVars = {}
|
||||
|
||||
GM.Config.Seeker.ConVars.Health = CreateConVarIfNotExists("ph_seeker_health", "100", FCVAR_REPLICATED, "Seekers: Initial Health")
|
||||
function GM.Config.Seeker:Health()
|
||||
return self.ConVars.Health:GetInt()
|
||||
end
|
||||
|
||||
GM.Config.Seeker.ConVars.HealthMax = CreateConVarIfNotExists("ph_seeker_health_max", "100", FCVAR_REPLICATED, "Seekers: Maximum Health")
|
||||
function GM.Config.Seeker:HealthMax()
|
||||
return self.ConVars.HealthMax:GetInt()
|
||||
end
|
||||
|
||||
GM.Config.Seeker.ConVars.HealthBonus = CreateConVarIfNotExists("ph_seeker_health_bonus", "20", FCVAR_REPLICATED, "Seekers: Health Bonus per Kill")
|
||||
function GM.Config.Seeker:HealthBonus()
|
||||
return self.ConVars.HealthBonus:GetInt()
|
||||
end
|
||||
|
||||
GM.Config.Seeker.ConVars.HealthPenalty = CreateConVarIfNotExists("ph_seeker_health_penalty", "5", FCVAR_REPLICATED, "Seekers: Health Penalty per wrong Shot")
|
||||
function GM.Config.Seeker:HealthPenalty()
|
||||
return self.ConVars.HealthPenalty:GetInt()
|
||||
end
|
||||
|
||||
GM.Config.Seeker.ConVars.Weapons = CreateConVarIfNotExists("ph_seeker_weapons", "weapon_crowbar,weapon_pistol,weapon_ph_smg,weapon_shotgun", FCVAR_REPLICATED, "Seekers: Initial Weapons (Weapon,Weapon,...)")
|
||||
function GM.Config.Seeker:Weapons()
|
||||
return string.Split(self.ConVars.Weapons:GetString(), ",")
|
||||
end
|
||||
|
||||
GM.Config.Seeker.ConVars.Ammo = CreateConVarIfNotExists("ph_seeker_ammo", "Pistol:100,SMG1:300,SMG1_Grenade:1,Buckshot:64", FCVAR_REPLICATED, "Seekers: Initial Ammo (Ammo:Amount,Ammo:Amount,...)")
|
||||
function GM.Config.Seeker:Ammo()
|
||||
return string.Split(self.ConVars.Ammo:GetString(), ",")
|
||||
end
|
||||
|
||||
GM.Config.Seeker.ConVars.WalkSpeed = CreateConVarIfNotExists("ph_seeker_walk_speed", "250", 0, "Seekers: Walk Speed")
|
||||
function GM.Config.Seeker:WalkSpeed()
|
||||
return self.ConVars.WalkSpeed:GetFloat()
|
||||
end
|
||||
|
||||
GM.Config.Seeker.ConVars.Sprint = CreateConVarIfNotExists("ph_seeker_sprint", "1", FCVAR_REPLICATED, "Seekers: Allow Sprinting")
|
||||
function GM.Config.Seeker:Sprint()
|
||||
return self.ConVars.Sprint:GetBool()
|
||||
end
|
||||
|
||||
GM.Config.Seeker.ConVars.SprintSpeed = CreateConVarIfNotExists("ph_seeker_sprint_speed", "500", 0, "Seekers: Sprint Speed")
|
||||
function GM.Config.Seeker:SprintSpeed()
|
||||
return self.ConVars.SprintSpeed:GetFloat()
|
||||
end
|
||||
|
||||
GM.Config.Seeker.ConVars.JumpPower = CreateConVarIfNotExists("ph_seeker_jump_power", "200", 0, "Seekers: Jump Power")
|
||||
function GM.Config.Seeker:JumpPower()
|
||||
return self.ConVars.JumpPower:GetFloat()
|
||||
end
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Hider Settings
|
||||
-- ------------------------------------------------------------------------- --
|
||||
GM.Config.Hider = {}
|
||||
GM.Config.Hider.ConVars = {}
|
||||
|
||||
GM.Config.Hider.ConVars.Health = CreateConVarIfNotExists("ph_hider_health", "100", FCVAR_REPLICATED, "Hiders: Initial Health")
|
||||
function GM.Config.Hider:Health()
|
||||
return self.ConVars.Health:GetInt()
|
||||
end
|
||||
|
||||
GM.Config.Hider.ConVars.HealthMax = CreateConVarIfNotExists("ph_hider_health_max", "100", FCVAR_REPLICATED, "Hiders: Maximum Health")
|
||||
function GM.Config.Hider:HealthMax()
|
||||
return self.ConVars.HealthMax:GetInt()
|
||||
end
|
||||
|
||||
GM.Config.Hider.ConVars.HealthScaling = CreateConVarIfNotExists("ph_hider_health_scaling", "1", FCVAR_REPLICATED, "Hiders: Enable Health Scaling")
|
||||
function GM.Config.Hider:HealthScaling()
|
||||
return self.ConVars.HealthScaling:GetBool()
|
||||
end
|
||||
|
||||
GM.Config.Hider.ConVars.HealthScalingMax = CreateConVarIfNotExists("ph_hider_health_scaling_max", "200", FCVAR_REPLICATED, "Hiders: Maximum scaled Health")
|
||||
function GM.Config.Hider:HealthScalingMax()
|
||||
return self.ConVars.HealthScalingMax:GetInt()
|
||||
end
|
||||
|
||||
GM.Config.Hider.ConVars.AllowFullRotation = CreateConVarIfNotExists("ph_hider_allow_full_rotation", "0", FCVAR_REPLICATED, "Hiders: Enable full 3D Rotation")
|
||||
function GM.Config.Hider:AllowFullRotation()
|
||||
return self.ConVars.AllowFullRotation:GetBool()
|
||||
end
|
||||
|
||||
GM.Config.Hider.ConVars.WalkSpeed = CreateConVarIfNotExists("ph_hider_walk_speed", "250", 0, "Hiders: Walk Speed")
|
||||
function GM.Config.Hider:WalkSpeed()
|
||||
return self.ConVars.WalkSpeed:GetFloat()
|
||||
end
|
||||
|
||||
GM.Config.Hider.ConVars.Sprint = CreateConVarIfNotExists("ph_hider_sprint", "0", FCVAR_REPLICATED, "Hiders: Allow Sprinting")
|
||||
function GM.Config.Hider:Sprint()
|
||||
return self.ConVars.Sprint:GetBool()
|
||||
end
|
||||
|
||||
GM.Config.Hider.ConVars.SprintSpeed = CreateConVarIfNotExists("ph_hider_sprint_speed", "500", 0, "Hiders: Sprint Speed")
|
||||
function GM.Config.Hider:SprintSpeed()
|
||||
return self.ConVars.SprintSpeed:GetFloat()
|
||||
end
|
||||
|
||||
GM.Config.Hider.ConVars.JumpPower = CreateConVarIfNotExists("ph_hider_jump_power", "200", 0, "Hiders: Jump Power")
|
||||
function GM.Config.Hider:JumpPower()
|
||||
return self.ConVars.JumpPower:GetFloat()
|
||||
end
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Whitelist & Blacklist
|
||||
-- ------------------------------------------------------------------------- --
|
||||
GM.Config.Lists = {}
|
||||
GM.Config.Lists.ConVars = {}
|
||||
|
||||
-- Class Whitelist
|
||||
GM.Config.Lists.ConVars.ClassWhitelist = CreateConVarIfNotExists("ph_list_class_whitelist", "prop_physics,prop_physics_multiplayer,prop_physics_respawnable", FCVAR_REPLICATED, "Anti-Cheat: Whitelisted Hider Classes")
|
||||
function GM.Config.Lists:ClassWhitelist()
|
||||
local str = self.ConVars.ClassWhitelist:GetString()
|
||||
if (self.ClassWhitelistCache != str) then
|
||||
self.ClassWhitelistCache = str
|
||||
self.ClassWhitelistCacheTbl = string.Split(self.ClassWhitelistCache, ",")
|
||||
end
|
||||
return self.ClassWhitelistCacheTbl
|
||||
end
|
||||
|
||||
-- Abuse Blacklist
|
||||
GM.Config.Lists.ConVars.AbuseBlacklist = CreateConVarIfNotExists("ph_list_abuse_blacklist", "func_button,func_door,func_door_rotation,prop_door_rotation,func_tracktrain,func_tanktrain,func_breakable", FCVAR_REPLICATED, "Anti-Cheat: Entity Abuse Blacklist")
|
||||
function GM.Config.Lists:AbuseBlacklist()
|
||||
local str = self.ConVars.AbuseBlacklist:GetString()
|
||||
if (self.AbuseBlacklistCache != str) then
|
||||
self.AbuseBlacklistCache = str
|
||||
self.AbuseBlacklistCacheTbl = string.Split(self.AbuseBlacklistCache, ",")
|
||||
end
|
||||
return self.AbuseBlacklistCacheTbl
|
||||
end
|
||||
|
||||
-- Model Blacklist
|
||||
GM.Config.Lists.ConVars.ModelBlacklist = CreateConVarIfNotExists("ph_list_model_blacklist", "models/props/cs_assault/dollar.mdl,models/props/cs_assault/money.mdl,models/props/cs_office/snowman_arm.mdl,models/props/cs_office/projector_remote.mdl", FCVAR_REPLICATED, "Anti-Cheat: Model Abuse Blacklist")
|
||||
function GM.Config.Lists:ModelBlacklist()
|
||||
local str = self.ConVars.ModelBlacklist:GetString()
|
||||
if (self.ModelBlacklistCache != str) then
|
||||
self.ModelBlacklistCache = str
|
||||
self.ModelBlacklistCacheTbl = string.Split(self.ModelBlacklistCache, ",")
|
||||
end
|
||||
return self.ModelBlacklistCacheTbl
|
||||
end
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Taunts
|
||||
-- ------------------------------------------------------------------------- --
|
||||
GM.Config.Taunt = {}
|
||||
GM.Config.Taunt.ConVars = {}
|
||||
|
||||
-- Cooldown (Seconds)
|
||||
GM.Config.Taunt.ConVars.Cooldown = CreateConVarIfNotExists("ph_taunt_cooldown", 5, FCVAR_REPLICATED, "Prop Hunt: Cooldown between Taunts")
|
||||
function GM.Config.Taunt:Cooldown()
|
||||
return self.ConVars.Cooldown:GetFloat()
|
||||
end
|
||||
|
||||
-- Seeker
|
||||
GM.Config.Taunt.SeekersCache = ""
|
||||
GM.Config.Taunt.SeekersCacheDynamic = nil
|
||||
GM.Config.Taunt.SeekersCacheStatic = nil
|
||||
GM.Config.Taunt.SeekersCacheFull = nil
|
||||
GM.Config.Taunt.ConVars.Seekers = CreateConVarIfNotExists("ph_taunt_seekers", "bot/a_bunch_of_them.wav,bot/come_out_and_fight_like_a_man.wav,bot/come_out_wherever_you_are.wav,bot/come_to_papa.wav,bot/dont_worry_hell_get_it.wav,bot/hang_on_i_heard_something.wav,bot/hang_on_im_coming.wav,bot/i_dont_think_so.wav,bot/i_have_the_hostages.wav,bot/i_see_our_target.wav,bot/im_waiting_here.wav,bot/keeping_an_eye_on_the_hostages.wav,bot/nnno_sir.wav,bot/spotted_the_delivery_boy.wav,bot/target_acquired.wav,bot/target_spotted.wav,bot/you_heard_the_man_lets_go.wav", 0, "Prop Hunt: Seeker Taunts")
|
||||
function GM.Config.Taunt:Seekers()
|
||||
local str = self.ConVars.Seekers:GetString()
|
||||
if (self.SeekersCache != str) then
|
||||
self.SeekersCache = str
|
||||
self.SeekersCacheDynamic = string.Split(self.SeekersCache, ",")
|
||||
self.SeekersCacheFull = table.Add(self.SeekersCacheDynamic, self.SeekersCacheStatic)
|
||||
for i,snd in ipairs(self.SeekersCacheFull) do
|
||||
util.PrecacheSound(snd)
|
||||
end
|
||||
end
|
||||
return self.SeekersCacheFull
|
||||
end
|
||||
|
||||
-- Hider
|
||||
GM.Config.Taunt.HidersCache = ""
|
||||
GM.Config.Taunt.HidersCacheDynamic = nil
|
||||
GM.Config.Taunt.HidersCacheStatic = nil
|
||||
GM.Config.Taunt.HidersCacheFull = nil
|
||||
GM.Config.Taunt.ConVars.Hiders = CreateConVarIfNotExists("ph_taunt_hiders", "ambient/alarms/apc_alarm_pass1.wav,ambient/alarms/manhack_alert_pass1.wav,ambient/alarms/razortrain_horn1.wav,ambient/alarms/scanner_alert_pass1.wav,ambient/alarms/train_horn2.wav,ambient/alarms/train_horn_distant1.wav,ambient/alarms/warningbell1.wav,ambient/energy/whiteflash.wav,ambient/intro/alyxremove.wav,ambient/intro/logosfx.wav,ambient/levels/launch/1stfiringwarning.wav,ambient/levels/launch/rockettakeoffblast.wav,ambient/misc/ambulance1.wav,ambient/misc/carhonk1.wav,ambient/misc/carhonk2.wav,ambient/misc/carhonk3.wav,ambient/outro/gunshipcrash.wav,ambient/3dmeagle.wav,beams/beamstart5.wav,buttons/bell1.wav,buttons/weapon_cant_buy.wav,common/bass.wav,common/bugreporter_failed.wav,common/warning.wav,doors/door_squeek1.wav,friends/friend_join.wav,friends/friend_online.wav,friends/message.wav,hostage/hunuse/comeback.wav,hostage/hunuse/dontleaveme.wav,hostage/hunuse/yeahillstay.wav,items/gift_drop.wav,music/radio1.mp3,phx/eggcrack.wav,plats/elevbell1.wav,player/headshot1.wav,player/headshot2.wav,player/sprayer.wav,radio/enemydown.wav,radio/go.wav,radio/locknload.wav,radio/negative.wav,radio/rounddraw.wav,radio/takepoint.wav,resource/warning.wav,ui/achievement_earned.wav,ui/freeze_cam.wav,vehicles/junker/radar_ping_friendly1.wav,weapons/c4/c4_beep1.wav,weapons/c4/c4_click.wav,weapons/awp/awp1.wav,vo/canals/female01/gunboat_giveemhell.wav,vo/canals/female01/gunboat_justintime.wav,vo/canals/female01/stn6_incoming.wav,vo/canals/male01/gunboat_giveemhell.wav,vo/canals/male01/gunboat_justintime.wav,vo/canals/male01/stn6_incoming.wav,vo/canals/al_radio_stn6.wav,vo/canals/arrest_getgoing.wav,vo/canals/arrest_helpme.wav,vo/canals/arrest_lookingforyou.wav,vo/canals/boxcar_lethimhelp.wav,vo/canals/matt_closecall.wav,vo/canals/premassacre.wav,vo/ravenholm/aimforhead.wav,vo/ravenholm/bucket_patience.wav,vo/ravenholm/madlaugh01.wav,vo/ravenholm/madlaugh02.wav,vo/ravenholm/madlaugh03.wav,vo/ravenholm/madlaugh04.wav,weapons/strider_buster/ol12_stickybombcreator.wav,weapons/c4/c4_explode1.wav,weapons/357/357_fire2.wav,weapons/357/357_fire3.wav,weapons/scout/scout_fire-1.wav,weapons/smokegrenade/sg_explode.wav,weapons/grenade_launcher1.wav,weapons/explode3.wav,weapons/underwater_explode3.wav,items/nvg_on.wav,hostage/huse/letsdoit.wav,hostage/huse/illfollow.wav,hostage/huse/getouttahere.wav,doors/door_screen_move1.wav,doors/heavy_metal_stop1.wav,doors/default_move.wav,common/stuck2.wav,ambient/water_splash1.wav,ambient/water_splash2.wav,ambient/water_splash3.wav,ambient/weather/thunder1.wav,ambient/weather/thunder2.wav,ambient/weather/thunder3.wav,ambient/weather/thunder4.wav,ambient/weather/thunder5.wav,ambient/weather/thunder6.wav,ambient/outro/thunder7.wav,ambient/voices/crying_loop1.wav,ambient/voices/playground_memory.wav,ambient/voices/f_scream1.wav,ambient/voices/m_scream1.wav,ambient/voices/cough1.wav,ambient/voices/cough2.wav,ambient/voices/cough3.wav,ambient/voices/cough4.wav,ambient/overhead/plane1.wav,ambient/overhead/plane2.wav,ambient/overhead/plane3.wav,ambient/overhead/hel1.wav,ambient/overhead/hel2.wav,ambient/misc/truck_backup1.wav,ambient/misc/truck_drive1.wav,ambient/misc/truck_drive2.wav,ambient/machines/pneumatic_drill_1.wav,ambient/machines/pneumatic_drill_2.wav,ambient/machines/pneumatic_drill_3.wav,ambient/machines/pneumatic_drill_4.wav,ambient/machines/station_train_squeel.wav,ambient/machines/ticktock.wav,ambient/creatures/teddy.wav,ambient/creatures/town_child_scream1.wav,ambient/creatures/town_moan1.wav,ambient/creatures/town_muffled_cry1.wav,ambient/creatures/town_scared_breathing1.wav,ambient/creatures/town_scared_breathing2.wav,ambient/creatures/town_scared_sob1.wav,ambient/creatures/town_scared_sob2.wav,ambient/creatures/town_zombie_call1.wav", 0, "Prop Hunt: Hider Taunts")
|
||||
function GM.Config.Taunt:Hiders()
|
||||
local str = self.ConVars.Hiders:GetString()
|
||||
if (self.HidersCacheDynamic == nil)
|
||||
|| (self.HidersCache != str) then
|
||||
self.HidersCache = str
|
||||
self.HidersCacheDynamic = string.Split(self.HidersCache, ",")
|
||||
self.HidersCacheFull = table.Add(self.HidersCacheDynamic, self.HidersCacheStatic)
|
||||
for i,snd in ipairs(self.HidersCacheFull) do
|
||||
util.PrecacheSound(snd)
|
||||
end
|
||||
end
|
||||
return self.HidersCacheFull
|
||||
end
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Announcers
|
||||
-- ------------------------------------------------------------------------- --
|
||||
|
||||
-- --! Announcers (Round Start, Unblind, Win, Loss)
|
||||
-- GM.Config.Announcers = {
|
||||
-- Start = { },
|
||||
-- Unblind = { },
|
||||
-- Win = { },
|
||||
-- Loss = { }
|
||||
-- }
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Camera
|
||||
-- ------------------------------------------------------------------------- --
|
||||
GM.Config.Camera = {}
|
||||
GM.Config.Camera.ConVars = {}
|
||||
|
||||
-- Allow Camera No Clip
|
||||
GM.Config.Camera.ConVars.AllowNoClip = CreateConVarIfNotExists("ph_camera_allow_noclip", "0", FCVAR_REPLICATED, "Camera: Allow clients to disable camera collision.")
|
||||
function GM.Config.Camera:AllowNoClip()
|
||||
return self.ConVars.AllowNoClip:GetBool()
|
||||
end
|
||||
|
||||
-- Camera Distance Maximum
|
||||
GM.Config.Camera.ConVars.DistanceMax = CreateConVarIfNotExists("ph_camera_distance_max", "150", FCVAR_REPLICATED, "Camera: Maximum allowed distance to player.")
|
||||
function GM.Config.Camera:DistanceMax()
|
||||
return self.ConVars.DistanceMax:GetFloat()
|
||||
end
|
||||
|
||||
-- Camera Distance Minimum
|
||||
GM.Config.Camera.ConVars.DistanceMin = CreateConVarIfNotExists("ph_camera_distance_min", "30", FCVAR_REPLICATED, "Camera: Minimum allowed distance to player.")
|
||||
function GM.Config.Camera:DistanceMin()
|
||||
return self.ConVars.DistanceMin:GetFloat()
|
||||
end
|
||||
|
||||
-- Camera Distance Right Maximum
|
||||
GM.Config.Camera.ConVars.DistanceRightRange = CreateConVarIfNotExists("ph_camera_distance_right_range", "20", FCVAR_REPLICATED, "Camera: Horizontal allowed camera distance range.")
|
||||
function GM.Config.Camera:DistanceRightRange()
|
||||
return self.ConVars.DistanceRightRange:GetFloat()
|
||||
end
|
||||
|
||||
-- Camera Distance Up Maximum
|
||||
GM.Config.Camera.ConVars.DistanceUpRange = CreateConVarIfNotExists("ph_camera_distance_up_range", "20", FCVAR_REPLICATED, "Camera: Vertical allowed camera distance range.")
|
||||
function GM.Config.Camera:DistanceUpRange()
|
||||
return self.ConVars.DistanceUpRange:GetFloat()
|
||||
end
|
||||
|
||||
-- Lag Minimum
|
||||
GM.Config.Camera.ConVars.LagMinimum = CreateConVarIfNotExists("ph_camera_lag_min", "0.01", FCVAR_REPLICATED, "Camera: Minimum Camera Lag.")
|
||||
function GM.Config.Camera:LagMinimum()
|
||||
return self.ConVars.LagMinimum:GetFloat()
|
||||
end
|
||||
|
||||
-- Lag Maximum
|
||||
GM.Config.Camera.ConVars.LagMaximum = CreateConVarIfNotExists("ph_camera_lag_max", "0.95", FCVAR_REPLICATED, "Camera: Maximum Camera Lag.")
|
||||
function GM.Config.Camera:LagMaximum()
|
||||
return self.ConVars.LagMaximum:GetFloat()
|
||||
end
|
||||
|
||||
if CLIENT then
|
||||
-- Collisions
|
||||
GM.Config.Camera.ConVars.Collisions = CreateConVarIfNotExists("ph_camera_collisions", "1", FCVAR_ARCHIVE + FCVAR_CLIENTDLL, "Camera: Enable collisions with the world and objects in it.")
|
||||
function GM.Config.Camera:Collisions()
|
||||
if self:AllowNoClip() then
|
||||
return self.ConVars.Collisions:GetBool()
|
||||
else
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
-- Distance
|
||||
GM.Config.Camera.ConVars.Distance = CreateConVarIfNotExists("ph_camera_distance", "100", FCVAR_ARCHIVE + FCVAR_CLIENTDLL, "Camera: Ideal Distance to player.")
|
||||
function GM.Config.Camera:Distance()
|
||||
return math.Clamp(self.ConVars.Distance:GetFloat(), self:DistanceMin(), self:DistanceMax())
|
||||
end
|
||||
|
||||
-- Distance Right
|
||||
GM.Config.Camera.ConVars.DistanceRight = CreateConVarIfNotExists("ph_camera_distance_right", "0", FCVAR_ARCHIVE + FCVAR_CLIENTDLL, "Camera: Ideal Distance to player horizontally.")
|
||||
function GM.Config.Camera:DistanceRight()
|
||||
return math.Clamp(self.ConVars.DistanceRight:GetFloat(), -self:DistanceRightRange(), self:DistanceRightRange())
|
||||
end
|
||||
|
||||
-- Distance Up
|
||||
GM.Config.Camera.ConVars.DistanceUp = CreateConVarIfNotExists("ph_camera_distance_up", "0", FCVAR_ARCHIVE + FCVAR_CLIENTDLL, "Camera: Ideal Distance to player vertically.")
|
||||
function GM.Config.Camera:DistanceUp()
|
||||
return math.Clamp(self.ConVars.DistanceUp:GetFloat(), -self:DistanceUpRange(), self:DistanceUpRange())
|
||||
end
|
||||
|
||||
-- Lag
|
||||
GM.Config.Camera.ConVars.Lag = CreateConVarIfNotExists("ph_camera_lag", "0.95", FCVAR_ARCHIVE + FCVAR_CLIENTDLL, "Camera: Percentage of camera lag (higher = slower, lower = faster).")
|
||||
function GM.Config.Camera:Lag()
|
||||
return math.Clamp(self.ConVars.Lag:GetFloat(), self:LagMinimum(), self:LagMaximum())
|
||||
end
|
||||
end
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Name Plates
|
||||
-- ------------------------------------------------------------------------- --
|
||||
GM.Config.NamePlates = {}
|
||||
GM.Config.NamePlates.ConVars = {}
|
||||
|
||||
if CLIENT then
|
||||
-- Show
|
||||
GM.Config.NamePlates.ConVars.Show = CreateConVarIfNotExists("ph_nameplates_show", "1", FCVAR_ARCHIVE + FCVAR_CLIENTDLL, "Nameplates: Show a name plate above each player in your team (or all players if spectating).")
|
||||
function GM.Config.NamePlates:Show()
|
||||
return self.ConVars.Show:GetBool()
|
||||
end
|
||||
|
||||
-- Scale
|
||||
GM.Config.NamePlates.ConVars.Scale = CreateConVarIfNotExists("ph_nameplates_scale", "0.05", FCVAR_ARCHIVE + FCVAR_CLIENTDLL, "Nameplates: World scale of name plate, a setting of 1 means 1px = 1unit.")
|
||||
function GM.Config.NamePlates:Scale()
|
||||
return self.ConVars.Scale:GetFloat()
|
||||
end
|
||||
|
||||
-- Height
|
||||
GM.Config.NamePlates.ConVars.Height = CreateConVarIfNotExists("ph_nameplates_height", "10", FCVAR_ARCHIVE + FCVAR_CLIENTDLL, "Nameplates: Height above player.")
|
||||
function GM.Config.NamePlates:Height()
|
||||
return self.ConVars.Height:GetFloat()
|
||||
end
|
||||
|
||||
-- Tint Color
|
||||
GM.Config.NamePlates.ConVars.TintHue = CreateConVarIfNotExists("ph_nameplates_tint_hue", "0", FCVAR_ARCHIVE + FCVAR_CLIENTDLL, "Nameplates: Tint hue.")
|
||||
function GM.Config.NamePlates:TintHue()
|
||||
return self.ConVars.TintHue:GetFloat()
|
||||
end
|
||||
GM.Config.NamePlates.ConVars.TintSaturation = CreateConVarIfNotExists("ph_nameplates_tint_saturation", "0", FCVAR_ARCHIVE + FCVAR_CLIENTDLL, "Nameplates: Tint saturation.")
|
||||
function GM.Config.NamePlates:TintSaturation()
|
||||
return self.ConVars.TintSaturation:GetFloat()
|
||||
end
|
||||
GM.Config.NamePlates.ConVars.TintValue = CreateConVarIfNotExists("ph_nameplates_tint_value", "1", FCVAR_ARCHIVE + FCVAR_CLIENTDLL, "Nameplates: Tint value.")
|
||||
function GM.Config.NamePlates:TintValue()
|
||||
return self.ConVars.TintValue:GetFloat()
|
||||
end
|
||||
|
||||
-- Tint By Health
|
||||
GM.Config.NamePlates.ConVars.TintHealth = CreateConVarIfNotExists("ph_nameplates_tint_health", "0", FCVAR_ARCHIVE + FCVAR_CLIENTDLL, "Nameplates: Tint the nameplate using their health percent.")
|
||||
function GM.Config.NamePlates:TintHealth()
|
||||
return self.ConVars.TintHealth:GetBool()
|
||||
end
|
||||
|
||||
-- Tint By Team
|
||||
GM.Config.NamePlates.ConVars.TintTeam = CreateConVarIfNotExists("ph_nameplates_tint_team", "0", FCVAR_ARCHIVE + FCVAR_CLIENTDLL, "Nameplates: Tint the nameplate with the team colors.")
|
||||
function GM.Config.NamePlates:TintTeam()
|
||||
return self.ConVars.TintTeam:GetBool()
|
||||
end
|
||||
end
|
||||
|
||||
-- ------------------------------------------------------------------------- --
|
||||
--! Selection Halo
|
||||
-- ------------------------------------------------------------------------- --
|
||||
GM.Config.SelectionHalo = {}
|
||||
GM.Config.SelectionHalo.ConVars = {}
|
||||
|
||||
-- Allow
|
||||
GM.Config.SelectionHalo.ConVars.Allow = CreateConVarIfNotExists("ph_selectionhalo_allow", "1", FCVAR_REPLICATED, "Selection Halo: Allow clients to enable halo around the currently looked at prop?")
|
||||
function GM.Config.SelectionHalo:Allow()
|
||||
return self.ConVars.Allow:GetBool()
|
||||
end
|
||||
|
||||
-- Approximate
|
||||
GM.Config.SelectionHalo.ConVars.Approximate = CreateConVarIfNotExists("ph_selectionhalo_approximate", "1", FCVAR_REPLICATED, "Selection Halo: Enable approximate selection halo, which only checks the forward vector on the client.")
|
||||
function GM.Config.SelectionHalo:Approximate()
|
||||
return self.ConVars.Approximate:GetBool()
|
||||
end
|
||||
|
||||
if SERVER then
|
||||
-- Update Interval
|
||||
GM.Config.SelectionHalo.ConVars.Interval = CreateConVarIfNotExists("ph_selectionhalo_interval", "0.05", FCVAR_ARCHIVE, "Selection Halo: Interval for updates of the accuracte selection halo in seconds.")
|
||||
function GM.Config.SelectionHalo:Interval()
|
||||
return self.ConVars.Interval:GetFloat()
|
||||
end
|
||||
end
|
||||
|
||||
if CLIENT then
|
||||
-- Enabled
|
||||
GM.Config.SelectionHalo.ConVars.Enabled = CreateConVarIfNotExists("ph_selectionhalo_enabled", "1", FCVAR_ARCHIVE, "Selection Halo: Enable halo around prop you might become.")
|
||||
function GM.Config.SelectionHalo:Enabled()
|
||||
if (self:Allow()) then
|
||||
return self.ConVars.Enabled:GetBool()
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
-- Settings
|
||||
GM.Config.SelectionHalo.ConVars.Passes = CreateConVarIfNotExists("ph_selectionhalo_passes", "1", FCVAR_ARCHIVE + FCVAR_CLIENTDLL, "Selection Halo: Passes")
|
||||
function GM.Config.SelectionHalo:Passes()
|
||||
return self.ConVars.Passes:GetInt()
|
||||
end
|
||||
GM.Config.SelectionHalo.ConVars.Additive = CreateConVarIfNotExists("ph_selectionhalo_additive", "1", FCVAR_ARCHIVE + FCVAR_CLIENTDLL, "Selection Halo: Additive")
|
||||
function GM.Config.SelectionHalo:Additive()
|
||||
return self.ConVars.Additive:GetBool()
|
||||
end
|
||||
GM.Config.SelectionHalo.ConVars.IgnoreZ = CreateConVarIfNotExists("ph_selectionhalo_ignorez", "0", FCVAR_ARCHIVE + FCVAR_CLIENTDLL, "Selection Halo: Ignore Z")
|
||||
function GM.Config.SelectionHalo:IgnoreZ()
|
||||
return self.ConVars.IgnoreZ:GetBool()
|
||||
end
|
||||
|
||||
-- Blur
|
||||
GM.Config.SelectionHalo.ConVars.BlurX = CreateConVarIfNotExists("ph_selectionhalo_blur_x", "2", FCVAR_ARCHIVE + FCVAR_CLIENTDLL, "Selection Halo: Blur X")
|
||||
function GM.Config.SelectionHalo:BlurX()
|
||||
return self.ConVars.BlurX:GetFloat()
|
||||
end
|
||||
GM.Config.SelectionHalo.ConVars.BlurY = CreateConVarIfNotExists("ph_selectionhalo_blur_y", "2", FCVAR_ARCHIVE + FCVAR_CLIENTDLL, "Selection Halo: Blur Y")
|
||||
function GM.Config.SelectionHalo:BlurY()
|
||||
return self.ConVars.BlurY:GetFloat()
|
||||
end
|
||||
|
||||
-- Tint Color
|
||||
GM.Config.SelectionHalo.ConVars.TintHue = CreateConVarIfNotExists("ph_selectionhalo_tint_hue", "0", FCVAR_ARCHIVE + FCVAR_CLIENTDLL, "Selection Halo: Tint Hue")
|
||||
function GM.Config.SelectionHalo:TintHue()
|
||||
return self.ConVars.TintHue:GetFloat()
|
||||
end
|
||||
GM.Config.SelectionHalo.ConVars.TintSaturation = CreateConVarIfNotExists("ph_selectionhalo_tint_saturation", "0", FCVAR_ARCHIVE + FCVAR_CLIENTDLL, "Selection Halo: Tint Saturation")
|
||||
function GM.Config.SelectionHalo:TintSaturation()
|
||||
return self.ConVars.TintSaturation:GetFloat()
|
||||
end
|
||||
GM.Config.SelectionHalo.ConVars.TintValue = CreateConVarIfNotExists("ph_selectionhalo_tint_value", "1", FCVAR_ARCHIVE + FCVAR_CLIENTDLL, "Selection Halo: Tint Value")
|
||||
function GM.Config.SelectionHalo:TintValue()
|
||||
return self.ConVars.TintValue:GetFloat()
|
||||
end
|
||||
end
|
||||
|
Before Width: | Height: | Size: 920 B |
|
Before Width: | Height: | Size: 134 KiB |
@@ -1,84 +0,0 @@
|
||||
"prophuntextended"
|
||||
{
|
||||
"base" "base"
|
||||
"title" "Prop Hunt Extended"
|
||||
"maps" "^ph_"
|
||||
"menusystem" "1"
|
||||
"workshopid" "468149739"
|
||||
|
||||
"settings"
|
||||
{
|
||||
// Basic Settings
|
||||
100
|
||||
{
|
||||
"name" "mp_timelimit"
|
||||
"text" "Core: Time Limit for the entire Map"
|
||||
"type" "Numeric"
|
||||
"default" "0"
|
||||
"help" "Map Time Limit (in Minutes)"
|
||||
}
|
||||
|
||||
101
|
||||
{
|
||||
"name" "mp_friendlyfire"
|
||||
"text" "Core: Friendly fire"
|
||||
"type" "Numeric"
|
||||
"default" "0"
|
||||
"help" "Allow friendly fire? (0 = No, 1 = Yes, 2 = Reflect)"
|
||||
}
|
||||
|
||||
// Round Settings
|
||||
200
|
||||
{
|
||||
"name" "ph_round_limit"
|
||||
"text" "Rounds: Limit"
|
||||
"type" "Numeric"
|
||||
"default" "10"
|
||||
"help" "Round Manager: Maximum Rounds to Play on a single Map"
|
||||
}
|
||||
201
|
||||
{
|
||||
"name" "ph_round_timelimit"
|
||||
"text" "Rounds: Time Limit per Round"
|
||||
"type" "Numeric"
|
||||
"default" "180"
|
||||
"help" "Round Manager: Time Limit per Round (in Seconds)"
|
||||
}
|
||||
202
|
||||
{
|
||||
"name" "ph_round_blindtime"
|
||||
"text" "Rounds: Blind Time per Round"
|
||||
"type" "Numeric"
|
||||
"default" "-30"
|
||||
"help" "Round Manager: Blind Time for Seekers (in Seconds, positive takes away from ph_round_timelimit, negative adds extra time to ph_round_timelimit)"
|
||||
}
|
||||
|
||||
// Team Settings
|
||||
300
|
||||
{
|
||||
"name" "ph_teams_randomize"
|
||||
"text" "Teams: Randomize instead of Swap"
|
||||
"type" "CheckBox"
|
||||
"default" "0"
|
||||
"help" "Teams: Randomize Teams instead of swapping each round"
|
||||
}
|
||||
301
|
||||
{
|
||||
"name" "ph_teams_weighted"
|
||||
"text" "Teams: Weighted Randomization"
|
||||
"type" "CheckBox"
|
||||
"default" "0"
|
||||
"help" "Teams: Use Weighted Randomization, which may seem more fair towards players."
|
||||
}
|
||||
|
||||
// Taunts
|
||||
700
|
||||
{
|
||||
"name" "ph_taunt_cooldown"
|
||||
"text" "Cooldown for Taunts"
|
||||
"type" "Numeric"
|
||||
"default" "5"
|
||||
"help" "Prop Hunt: Cooldown between Taunts"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
@ECHO OFF
|
||||
ECHO This script must be run as administrator, or will fail with unknown results.
|
||||
|
||||
ECHO I've been run from "%CD%", and am in "%~dp0", switching directory to set up environment.
|
||||
PUSHD "%~dp0"
|
||||
CALL "%~dp0\env.win.bat"
|
||||
|
||||
SET "PATH_GMOD=%GARRYSMODPATH%"
|
||||
SET "PATH_REPO=%ROOT%\.."
|
||||
|
||||
PUSHD "%PATH_GMOD%\garrysmod\addons"
|
||||
MKLINK /J prophuntextended "%PATH_REPO%\source"
|
||||
MKLINK /J prophunt "%PATH_REPO%\proxy"
|
||||
POPD
|
||||
|
||||
POPD
|
||||
PAUSE
|
||||
@@ -1,14 +0,0 @@
|
||||
@ECHO OFF
|
||||
|
||||
:: Root and repo
|
||||
SET "ROOT=%~dp0"
|
||||
|
||||
:: Garry's Mod
|
||||
SET "GARRYSMODPATH="
|
||||
FOR /F "tokens=2* delims= " %%A IN ('REG QUERY "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 4000" /v InstallLocation') DO SET "GARRYSMODPATH=%%B"
|
||||
IF "%GARRYSMODPATH%" == "" (
|
||||
FOR /F "tokens=2* delims= " %%A IN ('REG QUERY "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 4000" /v InstallLocation') DO SET "GARRYSMODPATH=%%B"
|
||||
)
|
||||
IF "%GARRYSMODPATH%" == "" (
|
||||
ECHO Failed to figure out where Garry's Mod is installed.
|
||||
)
|
||||
@@ -1,10 +0,0 @@
|
||||
@ECHO OFF
|
||||
CALL "env.win.bat"
|
||||
|
||||
SET "GMANAME=%TMP%\prophuntextended-%RANDOM%-%RANDOM%-%RANDOM%-%RANDOM%.gma"
|
||||
|
||||
PUSHD "%REPO%"
|
||||
"%GARRYSMODPATH%\bin\gmad.exe" create -folder "%REPO%source" -out "%GMANAME%"
|
||||
"%GARRYSMODPATH%\bin\gmpublish.exe" update -id 468149739 -icon "media\workshop-gamemode.jpg" -addon "%GMANAME%" -changes "To be added (see Github in the mean time)"
|
||||
POPD
|
||||
PAUSE
|
||||
@@ -1,10 +0,0 @@
|
||||
@ECHO OFF
|
||||
CALL "env.win.bat"
|
||||
|
||||
SET "GMANAME=%TMP%\prophuntproxy-%RANDOM%-%RANDOM%-%RANDOM%-%RANDOM%.gma"
|
||||
|
||||
PUSHD "%REPO%"
|
||||
"%GARRYSMODPATH%\bin\gmad.exe" create -folder "%REPO%source" -out "%GMANAME%"
|
||||
"%GARRYSMODPATH%\bin\gmpublish.exe" update -id 1327985306 -icon "media\workshop-gamemode.jpg" -addon "%GMANAME%" -changes "To be added (see Github in the mean time)"
|
||||
POPD
|
||||
PAUSE
|
||||
@@ -1,4 +0,0 @@
|
||||
@ECHO OFF
|
||||
call env.win.bat
|
||||
SET "PATH=%CD%;%GARRYSMODPATH%\bin;%PATH%"
|
||||
CMD
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"folders": [
|
||||
{
|
||||
"path": "."
|
||||
}
|
||||
],
|
||||
"settings": {}
|
||||
}
|
||||